From d695a4f5e567cf3e26106baede716fef0ececf26 Mon Sep 17 00:00:00 2001
From: Tom Sherman
Date: Thu, 8 Aug 2024 11:01:52 +0100
Subject: [PATCH 1/5] Show did history as JSON
---
packages/atproto-browser/app/at/page.tsx | 90 ++++++++++++++++--------
packages/atproto-browser/package.json | 1 +
pnpm-lock.yaml | 13 ++++
3 files changed, 74 insertions(+), 30 deletions(-)
diff --git a/packages/atproto-browser/app/at/page.tsx b/packages/atproto-browser/app/at/page.tsx
index 4d5b0ab4..8296058b 100644
--- a/packages/atproto-browser/app/at/page.tsx
+++ b/packages/atproto-browser/app/at/page.tsx
@@ -14,6 +14,7 @@ import { CollectionItems } from "./_lib/collection";
import { SWRConfig } from "swr";
import { listRecords } from "@/lib/atproto";
import { verifyRecords } from "@atproto/repo";
+import { ErrorBoundary } from "react-error-boundary";
const didResolver = new DidResolver({});
const resolveDid = cache((did: string) => didResolver.resolve(did));
@@ -57,7 +58,14 @@ export default async function AtPage({
{handle} ({didDocument.id})
-
+
+
+ Loading history...
}>
+ Failed to fetch history.}>
+ History
+
+
+
>
);
}
@@ -117,11 +125,10 @@ export default async function AtPage({
- Author: {handle} ({didStr}
- )
+ Author: {handle} ({didStr})
-
+
@@ -196,7 +203,27 @@ async function RecordVerificationBadge({
}
}
-async function Author({ did }: { did: string }) {
+async function DidSummary({ did }: { did: string }) {
+ return (
+ <>
+ Failed to fetch collections for {did}.
}
+ >
+ Collections
+
+
+ DID Doc
+
+ >
+ );
+}
+
+async function DidDoc({ did }: { did: string }) {
+ const didDocument = await resolveDid(did);
+ return ;
+}
+
+async function DidCollections({ did }: { did: string }) {
const didDocument = await resolveDid(did);
if (!didDocument) {
throw new Error(`Could not resolve DID: ${did}`);
@@ -216,11 +243,8 @@ async function Author({ did }: { did: string }) {
});
if (!response.ok) {
- return (
-
- Failed to fetch collections: {response.statusText}. URL:{" "}
- {describeRepoUrl.toString()}
-
+ throw new Error(
+ `Failed to fetch collections: ${response.statusText}. URL: ${describeRepoUrl.toString()}`,
);
}
@@ -229,29 +253,35 @@ async function Author({ did }: { did: string }) {
};
return (
- <>
- Collections
-
- {collections.length === 0 ? (
- No collections.
- ) : (
- collections.map((nsid) => {
- const collectionUri = `at://${[did, nsid].join("/")}`;
-
- return (
- -
- {nsid}
-
- );
- })
- )}
-
- DID Doc
-
- >
+
+ {collections.length === 0 ? (
+ No collections.
+ ) : (
+ collections.map((nsid) => {
+ const collectionUri = `at://${[did, nsid].join("/")}`;
+
+ return (
+ -
+ {nsid}
+
+ );
+ })
+ )}
+
);
}
+async function DidHistory({ did }: { did: string }) {
+ const response = await fetch(`https://plc.directory/${did}/log/audit`);
+ if (!response.ok) {
+ throw new Error(`Failed to fetch history: ${response.statusText}`);
+ }
+
+ const history = (await response.json()) as JSONType;
+
+ return ;
+}
+
function naiveAtUriCheck(atUri: string) {
if (!atUri.startsWith("at://")) {
return false;
diff --git a/packages/atproto-browser/package.json b/packages/atproto-browser/package.json
index ad13e943..60d5bc03 100644
--- a/packages/atproto-browser/package.json
+++ b/packages/atproto-browser/package.json
@@ -16,6 +16,7 @@
"next": "15.0.0-rc.0",
"react": "19.0.0-rc-f994737d14-20240522",
"react-dom": "19.0.0-rc-f994737d14-20240522",
+ "react-error-boundary": "^4.0.13",
"swr": "2.2.6-beta.4",
"zod": "^3.23.8"
},
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 02280c70..2552b8c9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -38,6 +38,9 @@ importers:
react-dom:
specifier: 19.0.0-rc-f994737d14-20240522
version: 19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522)
+ react-error-boundary:
+ specifier: ^4.0.13
+ version: 4.0.13(react@19.0.0-rc-f994737d14-20240522)
swr:
specifier: 2.2.6-beta.4
version: 2.2.6-beta.4(react@19.0.0-rc-f994737d14-20240522)
@@ -4702,6 +4705,11 @@ packages:
peerDependencies:
react: 19.0.0-rc-f994737d14-20240522
+ react-error-boundary@4.0.13:
+ resolution: {integrity: sha512-b6PwbdSv8XeOSYvjt8LpgpKrZ0yGdtZokYwkwV2wlcZbxgopHX/hgPl5VgpnoVOWd868n1hktM8Qm4b+02MiLQ==}
+ peerDependencies:
+ react: '>=16.13.1'
+
react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
@@ -10956,6 +10964,11 @@ snapshots:
react: 19.0.0-rc-f994737d14-20240522
scheduler: 0.25.0-rc-f994737d14-20240522
+ react-error-boundary@4.0.13(react@19.0.0-rc-f994737d14-20240522):
+ dependencies:
+ '@babel/runtime': 7.24.6
+ react: 19.0.0-rc-f994737d14-20240522
+
react-is@16.13.1: {}
react-is@17.0.2: {}
From 43badeddb2293f8455fb2b81b2ace8a814197bd7 Mon Sep 17 00:00:00 2001
From: Tom Sherman
Date: Thu, 8 Aug 2024 19:24:03 +0100
Subject: [PATCH 2/5] Trigger build
From 4b79902b42d8257868f078799e17dbd7d66e67e1 Mon Sep 17 00:00:00 2001
From: Tom Sherman
Date: Thu, 8 Aug 2024 19:25:33 +0100
Subject: [PATCH 3/5] Trigger build
From ab81323fdedc24469d37d8fda28060f6e613a89d Mon Sep 17 00:00:00 2001
From: Tom Sherman
Date: Mon, 12 Aug 2024 21:01:25 +0100
Subject: [PATCH 4/5] Show history as human readable
---
packages/atproto-browser/app/at/page.tsx | 256 ++++++++++++++++++++++-
pnpm-lock.yaml | 64 +++++-
2 files changed, 314 insertions(+), 6 deletions(-)
diff --git a/packages/atproto-browser/app/at/page.tsx b/packages/atproto-browser/app/at/page.tsx
index 8296058b..901dfa03 100644
--- a/packages/atproto-browser/app/at/page.tsx
+++ b/packages/atproto-browser/app/at/page.tsx
@@ -7,7 +7,7 @@ import {
} from "@atproto/identity";
import { AtUri, isValidHandle } from "@atproto/syntax";
import { isDid } from "@atproto/did";
-import { cache, Suspense } from "react";
+import { cache, Fragment, Suspense } from "react";
import Link from "next/link";
import { AtBlob } from "./_lib/at-blob";
import { CollectionItems } from "./_lib/collection";
@@ -15,6 +15,7 @@ import { SWRConfig } from "swr";
import { listRecords } from "@/lib/atproto";
import { verifyRecords } from "@atproto/repo";
import { ErrorBoundary } from "react-error-boundary";
+import { z } from "zod";
const didResolver = new DidResolver({});
const resolveDid = cache((did: string) => didResolver.resolve(did));
@@ -271,15 +272,264 @@ async function DidCollections({ did }: { did: string }) {
);
}
+const PlcLogAuditResponse = z.array(
+ z.object({
+ createdAt: z
+ .string()
+ .datetime()
+ .transform((x) => new Date(x)),
+ operation: z.object({
+ sig: z.string(),
+ prev: z.string().nullable(),
+ type: z.literal("plc_operation"),
+ services: z.record(
+ z.object({
+ type: z.string(),
+ endpoint: z.string(),
+ }),
+ ),
+ alsoKnownAs: z.array(z.string()),
+ rotationKeys: z.array(z.string()),
+ verificationMethods: z.record(z.string()),
+ }),
+ }),
+);
+
+const utcDateFormatter = new Intl.DateTimeFormat("en-US", {
+ dateStyle: "medium",
+ timeStyle: "short",
+ timeZone: "UTC",
+});
+
+function isNotNull(x: T | null): x is T {
+ return x !== null;
+}
+
async function DidHistory({ did }: { did: string }) {
const response = await fetch(`https://plc.directory/${did}/log/audit`);
if (!response.ok) {
throw new Error(`Failed to fetch history: ${response.statusText}`);
}
- const history = (await response.json()) as JSONType;
+ const auditLog = PlcLogAuditResponse.parse(await response.json());
- return ;
+ return (
+
+ {auditLog.map((previous, index) => {
+ const entry = auditLog[index + 1];
+ if (!entry) {
+ return null;
+ }
+
+ const alsoKnownAsAdded = entry.operation.alsoKnownAs.filter(
+ (x) => !previous.operation.alsoKnownAs.includes(x),
+ );
+ const alsoKnownAsRemoved = previous.operation.alsoKnownAs.filter(
+ (x) => !entry.operation.alsoKnownAs.includes(x),
+ );
+
+ const servicesChanged = Object.entries(entry.operation.services)
+ .map(([id, service]) => {
+ const previousService = previous.operation.services[id];
+ if (!previousService) return null;
+ return {
+ id,
+ type:
+ service.type !== previousService.type
+ ? {
+ from: previousService.type,
+ to: service.type,
+ }
+ : null,
+ endpoint:
+ service.endpoint !== previousService.endpoint
+ ? {
+ from: previousService.endpoint,
+ to: service.endpoint,
+ }
+ : null,
+ };
+ })
+ .filter(isNotNull);
+
+ const servicesAdded = Object.entries(entry.operation.services).filter(
+ ([id]) => !previous.operation.services[id],
+ );
+ const servicesRemoved = Object.entries(
+ previous.operation.services,
+ ).filter(([id]) => !entry.operation.services[id]);
+
+ const rotationKeysAdded = entry.operation.rotationKeys.filter(
+ (x) => !previous.operation.rotationKeys.includes(x),
+ );
+ const rotationKeysRemoved = previous.operation.rotationKeys.filter(
+ (x) => !entry.operation.rotationKeys.includes(x),
+ );
+
+ const verificationMethodsChanged = Object.entries(
+ entry.operation.verificationMethods,
+ )
+ .map(([id, key]) => {
+ const previousKey = previous.operation.verificationMethods[id];
+ if (!previousKey) return null;
+ if (key === previousKey) return null;
+ return {
+ id,
+ from: previousKey,
+ to: key,
+ };
+ })
+ .filter(isNotNull);
+ const verificationMethodsAdded = Object.entries(
+ entry.operation.verificationMethods,
+ ).filter(([id]) => !previous.operation.verificationMethods[id]);
+ const verificationMethodsRemoved = Object.entries(
+ previous.operation.verificationMethods,
+ ).filter(([id]) => !entry.operation.verificationMethods[id]);
+
+ return (
+ // eslint-disable-next-line react/no-array-index-key
+ -
+
+ Change created at {utcDateFormatter.format(entry.createdAt)} (UTC)
+
+
+ {alsoKnownAsAdded.length === 1 &&
+ alsoKnownAsRemoved.length === 1 ? (
+ -
+ Alias changed from{" "}
+
+ {alsoKnownAsRemoved[0]}
+ {" "}
+ to{" "}
+
+ {alsoKnownAsAdded[0]}
+
+
+ ) : (
+ <>
+ {alsoKnownAsAdded.length > 0 && (
+ -
+ Alias added:{" "}
+ {alsoKnownAsAdded.flatMap((aka) => [
+
+ {aka}
+ ,
+ ", ",
+ ])}
+
+ )}
+ {alsoKnownAsRemoved.length > 0 && (
+ -
+ Alias removed:{" "}
+ {alsoKnownAsRemoved.flatMap((aka) => [
+
+ {aka}
+ ,
+ ", ",
+ ])}
+
+ )}
+ >
+ )}
+ {servicesChanged.length > 0 &&
+ servicesChanged.map((service) => (
+
+ {!!service.type && (
+ -
+ Service "{service.id}" changed type from
+ "
+ {service.type.from}" to "{service.type.to}
+ "
+
+ )}
+ {!!service.endpoint && (
+ -
+ Service "{service.id}" changed endpoint from{" "}
+
+ {service.endpoint.from}
+ {" "}
+ to{" "}
+ {service.endpoint.to}
+
+ )}
+
+ ))}
+ {servicesAdded.length > 0 && (
+ -
+ Services added:{" "}
+ {servicesAdded.flatMap(([id, service]) => [
+
+ {id} ({service.type})
+ ,
+ ", ",
+ ])}
+
+ )}
+ {servicesRemoved.length > 0 && (
+ -
+ Services removed:{" "}
+ {servicesRemoved.flatMap(([id, service]) => [
+
+ {id} ({service.type})
+ ,
+ ", ",
+ ])}
+
+ )}
+ {rotationKeysAdded.length > 0 && (
+ -
+ Rotation keys added:{" "}
+ {rotationKeysAdded.flatMap((key) => [
+
{key}
,
+ ", ",
+ ])}
+
+ )}
+ {rotationKeysRemoved.length > 0 && (
+ -
+ Rotation keys removed:{" "}
+ {rotationKeysRemoved.flatMap((key) => [
+
{key}
,
+ ", ",
+ ])}
+
+ )}
+ {verificationMethodsChanged.length > 0 &&
+ verificationMethodsChanged.map((method) => (
+ -
+ Verification method "{method.id}" changed from{" "}
+
{method.from}
to {method.to}
+
+ ))}
+ {verificationMethodsAdded.length > 0 && (
+ -
+ Verification methods added:{" "}
+ {verificationMethodsAdded.flatMap(([id, key]) => [
+
+
{key}
("{id}")
+ ,
+ ", ",
+ ])}
+
+ )}
+ {verificationMethodsRemoved.length > 0 && (
+ -
+ Verification methods removed:{" "}
+ {verificationMethodsRemoved.flatMap(([id, key]) => [
+
+
{key}
("{id}")
+ ,
+ ", ",
+ ])}
+
+ )}
+
+
+ );
+ })}
+
+ );
}
function naiveAtUriCheck(atUri: string) {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 2552b8c9..395808c0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -31,7 +31,7 @@ importers:
version: 0.3.0
next:
specifier: 15.0.0-rc.0
- version: 15.0.0-rc.0(@babel/core@7.24.7)(babel-plugin-react-compiler@0.0.0-experimental-938cd9a-20240601)(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)
+ version: 15.0.0-rc.0(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522)
react:
specifier: 19.0.0-rc-f994737d14-20240522
version: 19.0.0-rc-f994737d14-20240522
@@ -9292,7 +9292,7 @@ snapshots:
eslint: 8.57.0
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0)
- eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0)
eslint-plugin-react: 7.34.2(eslint@8.57.0)
eslint-plugin-react-hooks: 4.6.2(eslint@8.57.0)
@@ -9363,7 +9363,7 @@ snapshots:
enhanced-resolve: 5.16.1
eslint: 8.57.0
eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
- eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
+ eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0)
fast-glob: 3.3.2
get-tsconfig: 4.7.5
is-core-module: 2.13.1
@@ -9467,6 +9467,33 @@ snapshots:
- eslint-import-resolver-webpack
- supports-color
+ eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0):
+ dependencies:
+ array-includes: 3.1.8
+ array.prototype.findlastindex: 1.2.5
+ array.prototype.flat: 1.3.2
+ array.prototype.flatmap: 1.3.2
+ debug: 3.2.7
+ doctrine: 2.1.0
+ eslint: 8.57.0
+ eslint-import-resolver-node: 0.3.9
+ eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.5.2))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0)
+ hasown: 2.0.2
+ is-core-module: 2.13.1
+ is-glob: 4.0.3
+ minimatch: 3.1.2
+ object.fromentries: 2.0.8
+ object.groupby: 1.0.3
+ object.values: 1.2.0
+ semver: 6.3.1
+ tsconfig-paths: 3.15.0
+ optionalDependencies:
+ '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.5.2)
+ transitivePeerDependencies:
+ - eslint-import-resolver-typescript
+ - eslint-import-resolver-webpack
+ - supports-color
+
eslint-plugin-jest@27.9.0(@typescript-eslint/eslint-plugin@7.14.1(@typescript-eslint/parser@7.14.1(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2))(eslint@8.57.0)(typescript@5.5.2):
dependencies:
'@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.5.2)
@@ -10553,6 +10580,32 @@ snapshots:
- '@babel/core'
- babel-plugin-macros
+ next@15.0.0-rc.0(react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522))(react@19.0.0-rc-f994737d14-20240522):
+ dependencies:
+ '@next/env': 15.0.0-rc.0
+ '@swc/helpers': 0.5.11
+ busboy: 1.6.0
+ caniuse-lite: 1.0.30001637
+ graceful-fs: 4.2.11
+ postcss: 8.4.31
+ react: 19.0.0-rc-f994737d14-20240522
+ react-dom: 19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522)
+ styled-jsx: 5.1.3(react@19.0.0-rc-f994737d14-20240522)
+ optionalDependencies:
+ '@next/swc-darwin-arm64': 15.0.0-rc.0
+ '@next/swc-darwin-x64': 15.0.0-rc.0
+ '@next/swc-linux-arm64-gnu': 15.0.0-rc.0
+ '@next/swc-linux-arm64-musl': 15.0.0-rc.0
+ '@next/swc-linux-x64-gnu': 15.0.0-rc.0
+ '@next/swc-linux-x64-musl': 15.0.0-rc.0
+ '@next/swc-win32-arm64-msvc': 15.0.0-rc.0
+ '@next/swc-win32-ia32-msvc': 15.0.0-rc.0
+ '@next/swc-win32-x64-msvc': 15.0.0-rc.0
+ sharp: 0.33.4
+ transitivePeerDependencies:
+ - '@babel/core'
+ - babel-plugin-macros
+
node-abi@3.63.0:
dependencies:
semver: 7.6.2
@@ -11462,6 +11515,11 @@ snapshots:
client-only: 0.0.1
react: 19.0.0-rc-3563387fe3-20240621
+ styled-jsx@5.1.3(react@19.0.0-rc-f994737d14-20240522):
+ dependencies:
+ client-only: 0.0.1
+ react: 19.0.0-rc-f994737d14-20240522
+
sucrase@3.35.0:
dependencies:
'@jridgewell/gen-mapping': 0.3.5
From c03878b3718f660b9a63c683c00f70a98ab5209f Mon Sep 17 00:00:00 2001
From: Tom Sherman
Date: Mon, 12 Aug 2024 21:27:08 +0100
Subject: [PATCH 5/5] Handle create and tombstone
---
packages/atproto-browser/app/at/page.tsx | 94 +++++++++++++++---------
1 file changed, 60 insertions(+), 34 deletions(-)
diff --git a/packages/atproto-browser/app/at/page.tsx b/packages/atproto-browser/app/at/page.tsx
index 901dfa03..19d51d38 100644
--- a/packages/atproto-browser/app/at/page.tsx
+++ b/packages/atproto-browser/app/at/page.tsx
@@ -278,20 +278,32 @@ const PlcLogAuditResponse = z.array(
.string()
.datetime()
.transform((x) => new Date(x)),
- operation: z.object({
- sig: z.string(),
- prev: z.string().nullable(),
- type: z.literal("plc_operation"),
- services: z.record(
- z.object({
- type: z.string(),
- endpoint: z.string(),
- }),
- ),
- alsoKnownAs: z.array(z.string()),
- rotationKeys: z.array(z.string()),
- verificationMethods: z.record(z.string()),
- }),
+ operation: z.union([
+ z.object({
+ type: z.literal("plc_operation"),
+ sig: z.string(),
+ prev: z.string().nullable(),
+ services: z.record(
+ z.object({
+ type: z.string(),
+ endpoint: z.string(),
+ }),
+ ),
+ alsoKnownAs: z.array(z.string()),
+ rotationKeys: z.array(z.string()),
+ verificationMethods: z.record(z.string()),
+ }),
+ z.object({
+ type: z.literal("create"),
+ signingKey: z.string(),
+ recoveryKey: z.string(),
+ handle: z.string(),
+ service: z.string(),
+ }),
+ z.object({
+ type: z.literal("plc_tombstone"),
+ }),
+ ]),
}),
);
@@ -316,21 +328,35 @@ async function DidHistory({ did }: { did: string }) {
return (
{auditLog.map((previous, index) => {
+ const previousOperation = previous.operation;
+ if (previousOperation.type !== "plc_operation") {
+ return (
+ // eslint-disable-next-line react/no-array-index-key
+ -
+ Change created at {utcDateFormatter.format(previous.createdAt)}{" "}
+ (UTC) of type "{previousOperation.type}".
+
+ );
+ }
const entry = auditLog[index + 1];
if (!entry) {
return null;
}
+ const entryOperation = entry.operation;
+ if (entryOperation.type !== "plc_operation") {
+ return null;
+ }
- const alsoKnownAsAdded = entry.operation.alsoKnownAs.filter(
- (x) => !previous.operation.alsoKnownAs.includes(x),
+ const alsoKnownAsAdded = entryOperation.alsoKnownAs.filter(
+ (x) => !previousOperation.alsoKnownAs.includes(x),
);
- const alsoKnownAsRemoved = previous.operation.alsoKnownAs.filter(
- (x) => !entry.operation.alsoKnownAs.includes(x),
+ const alsoKnownAsRemoved = previousOperation.alsoKnownAs.filter(
+ (x) => !entryOperation.alsoKnownAs.includes(x),
);
- const servicesChanged = Object.entries(entry.operation.services)
+ const servicesChanged = Object.entries(entryOperation.services)
.map(([id, service]) => {
- const previousService = previous.operation.services[id];
+ const previousService = previousOperation.services[id];
if (!previousService) return null;
return {
id,
@@ -352,25 +378,25 @@ async function DidHistory({ did }: { did: string }) {
})
.filter(isNotNull);
- const servicesAdded = Object.entries(entry.operation.services).filter(
- ([id]) => !previous.operation.services[id],
+ const servicesAdded = Object.entries(entryOperation.services).filter(
+ ([id]) => !previousOperation.services[id],
);
const servicesRemoved = Object.entries(
- previous.operation.services,
- ).filter(([id]) => !entry.operation.services[id]);
+ previousOperation.services,
+ ).filter(([id]) => !entryOperation.services[id]);
- const rotationKeysAdded = entry.operation.rotationKeys.filter(
- (x) => !previous.operation.rotationKeys.includes(x),
+ const rotationKeysAdded = entryOperation.rotationKeys.filter(
+ (x) => !previousOperation.rotationKeys.includes(x),
);
- const rotationKeysRemoved = previous.operation.rotationKeys.filter(
- (x) => !entry.operation.rotationKeys.includes(x),
+ const rotationKeysRemoved = previousOperation.rotationKeys.filter(
+ (x) => !entryOperation.rotationKeys.includes(x),
);
const verificationMethodsChanged = Object.entries(
- entry.operation.verificationMethods,
+ entryOperation.verificationMethods,
)
.map(([id, key]) => {
- const previousKey = previous.operation.verificationMethods[id];
+ const previousKey = previousOperation.verificationMethods[id];
if (!previousKey) return null;
if (key === previousKey) return null;
return {
@@ -381,11 +407,11 @@ async function DidHistory({ did }: { did: string }) {
})
.filter(isNotNull);
const verificationMethodsAdded = Object.entries(
- entry.operation.verificationMethods,
- ).filter(([id]) => !previous.operation.verificationMethods[id]);
+ entryOperation.verificationMethods,
+ ).filter(([id]) => !previousOperation.verificationMethods[id]);
const verificationMethodsRemoved = Object.entries(
- previous.operation.verificationMethods,
- ).filter(([id]) => !entry.operation.verificationMethods[id]);
+ previousOperation.verificationMethods,
+ ).filter(([id]) => !entryOperation.verificationMethods[id]);
return (
// eslint-disable-next-line react/no-array-index-key