From fd218a8c0f632dda6f7b96a998ff88cc662216d0 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Wed, 30 Sep 2026 15:13:11 +0900 Subject: [PATCH 001/184] Version bump [ci skip] --- CHANGES.md | 6 ++++++ changes.d/next.txt | 1 + packages/amqp/deno.json | 2 +- packages/amqp/package.json | 2 +- packages/cfworkers/deno.json | 2 +- packages/cfworkers/package.json | 2 +- packages/cli/deno.json | 2 +- packages/cli/package.json | 2 +- packages/create/package.json | 2 +- packages/debugger/deno.json | 2 +- packages/debugger/package.json | 2 +- packages/denokv/deno.json | 2 +- packages/elysia/deno.json | 2 +- packages/elysia/package.json | 2 +- packages/express/deno.json | 2 +- packages/express/package.json | 2 +- packages/fastify/deno.json | 2 +- packages/fastify/package.json | 2 +- packages/fedify/deno.json | 2 +- packages/fedify/package.json | 2 +- packages/fixture/deno.json | 2 +- packages/fresh/deno.json | 2 +- packages/h3/deno.json | 2 +- packages/h3/package.json | 2 +- packages/hono/deno.json | 2 +- packages/hono/package.json | 2 +- packages/init/deno.json | 2 +- packages/init/package.json | 2 +- packages/koa/deno.json | 2 +- packages/koa/package.json | 2 +- packages/lint/deno.json | 2 +- packages/lint/package.json | 2 +- packages/nestjs/package.json | 2 +- packages/next/package.json | 2 +- packages/postgres/deno.json | 2 +- packages/postgres/package.json | 2 +- packages/redis/deno.json | 2 +- packages/redis/package.json | 2 +- packages/relay/deno.json | 2 +- packages/relay/package.json | 2 +- packages/sqlite/deno.json | 2 +- packages/sqlite/package.json | 2 +- packages/sveltekit/deno.json | 2 +- packages/sveltekit/package.json | 2 +- packages/testing/deno.json | 2 +- packages/testing/package.json | 2 +- packages/vocab-runtime/deno.json | 2 +- packages/vocab-runtime/package.json | 2 +- packages/vocab-tools/deno.json | 2 +- packages/vocab-tools/package.json | 2 +- packages/vocab/deno.json | 2 +- packages/vocab/package.json | 2 +- packages/webfinger/deno.json | 2 +- packages/webfinger/package.json | 2 +- 54 files changed, 59 insertions(+), 52 deletions(-) create mode 100644 changes.d/next.txt diff --git a/CHANGES.md b/CHANGES.md index bce2f4fe7..c21733fd1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,12 @@ Fedify changelog ================ +Version 2.0.31 +-------------- + +To be released. + + Version 2.0.30 -------------- diff --git a/changes.d/next.txt b/changes.d/next.txt new file mode 100644 index 000000000..e2355582c --- /dev/null +++ b/changes.d/next.txt @@ -0,0 +1 @@ +2.0.31 diff --git a/packages/amqp/deno.json b/packages/amqp/deno.json index 8890d0c3c..2b9f7a480 100644 --- a/packages/amqp/deno.json +++ b/packages/amqp/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/amqp", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/amqp/package.json b/packages/amqp/package.json index f10636f35..cccb55427 100644 --- a/packages/amqp/package.json +++ b/packages/amqp/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/amqp", - "version": "2.0.30", + "version": "2.0.31", "description": "AMQP/RabbitMQ driver for Fedify", "keywords": [ "fedify", diff --git a/packages/cfworkers/deno.json b/packages/cfworkers/deno.json index 968340cb5..e5613e9e5 100644 --- a/packages/cfworkers/deno.json +++ b/packages/cfworkers/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cfworkers", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "imports": { "@cloudflare/workers-types": "npm:@cloudflare/workers-types@^4.20250906.0" diff --git a/packages/cfworkers/package.json b/packages/cfworkers/package.json index 02c948433..447ccdc6f 100644 --- a/packages/cfworkers/package.json +++ b/packages/cfworkers/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/cfworkers", - "version": "2.0.30", + "version": "2.0.31", "description": "Adapt Fedify with Cloudflare Workers", "keywords": [ "Fedify", diff --git a/packages/cli/deno.json b/packages/cli/deno.json index ecd092c01..ffd92801d 100644 --- a/packages/cli/deno.json +++ b/packages/cli/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": "./src/mod.ts", "imports": { diff --git a/packages/cli/package.json b/packages/cli/package.json index 52f2989b9..fe1178ec8 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "2.0.30", + "version": "2.0.31", "type": "module", "files": [ "README.md", diff --git a/packages/create/package.json b/packages/create/package.json index 0d1a67500..3fa926757 100644 --- a/packages/create/package.json +++ b/packages/create/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/create", - "version": "2.0.30", + "version": "2.0.31", "description": "Create a new Fedify application", "keywords": [ "fedify", diff --git a/packages/debugger/deno.json b/packages/debugger/deno.json index 3459fc746..b875e6ab9 100644 --- a/packages/debugger/deno.json +++ b/packages/debugger/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/debugger", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.tsx" diff --git a/packages/debugger/package.json b/packages/debugger/package.json index 4000ff104..a68cf018c 100644 --- a/packages/debugger/package.json +++ b/packages/debugger/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/debugger", - "version": "2.0.30", + "version": "2.0.31", "description": "Embedded ActivityPub debug dashboard for Fedify", "type": "module", "main": "./dist/mod.cjs", diff --git a/packages/denokv/deno.json b/packages/denokv/deno.json index d30413b14..2cc123ae2 100644 --- a/packages/denokv/deno.json +++ b/packages/denokv/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/denokv", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13", diff --git a/packages/elysia/deno.json b/packages/elysia/deno.json index 87e0d47d9..d334f9381 100644 --- a/packages/elysia/deno.json +++ b/packages/elysia/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/elysia", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/elysia/package.json b/packages/elysia/package.json index a178e71d5..021657f7f 100644 --- a/packages/elysia/package.json +++ b/packages/elysia/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/elysia", - "version": "2.0.30", + "version": "2.0.31", "description": "Integrate Fedify with Elysia", "keywords": [ "Fedify", diff --git a/packages/express/deno.json b/packages/express/deno.json index 67024fb95..b2ba546cb 100644 --- a/packages/express/deno.json +++ b/packages/express/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/express", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/express/package.json b/packages/express/package.json index 93f2506dc..59fc221a1 100644 --- a/packages/express/package.json +++ b/packages/express/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/express", - "version": "2.0.30", + "version": "2.0.31", "description": "Integrate Fedify with Express", "keywords": [ "Fedify", diff --git a/packages/fastify/deno.json b/packages/fastify/deno.json index d06d5ac7e..ecdb95d63 100644 --- a/packages/fastify/deno.json +++ b/packages/fastify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fastify", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/fastify/package.json b/packages/fastify/package.json index bf5bbb77c..8eaccfc1b 100644 --- a/packages/fastify/package.json +++ b/packages/fastify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/fastify", - "version": "2.0.30", + "version": "2.0.31", "description": "Integrate Fedify with Fastify", "keywords": [ "Fedify", diff --git a/packages/fedify/deno.json b/packages/fedify/deno.json index 2afaea253..c65aaee02 100644 --- a/packages/fedify/deno.json +++ b/packages/fedify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/fedify/package.json b/packages/fedify/package.json index 4d07e8703..cbd1d37c7 100644 --- a/packages/fedify/package.json +++ b/packages/fedify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "2.0.30", + "version": "2.0.31", "description": "An ActivityPub server framework", "keywords": [ "ActivityPub", diff --git a/packages/fixture/deno.json b/packages/fixture/deno.json index 8ebf96724..d7ccae0fa 100644 --- a/packages/fixture/deno.json +++ b/packages/fixture/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fixture", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/fresh/deno.json b/packages/fresh/deno.json index b5fecac97..d848279f7 100644 --- a/packages/fresh/deno.json +++ b/packages/fresh/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fresh", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "imports": { "@fresh/core": "jsr:@fresh/core@^2.1.4", diff --git a/packages/h3/deno.json b/packages/h3/deno.json index 270a7b32d..943a450a6 100644 --- a/packages/h3/deno.json +++ b/packages/h3/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/h3", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/h3/package.json b/packages/h3/package.json index 3a1360b8b..a9bf42547 100644 --- a/packages/h3/package.json +++ b/packages/h3/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/h3", - "version": "2.0.30", + "version": "2.0.31", "description": "Integrate Fedify with h3", "keywords": [ "Fedify", diff --git a/packages/hono/deno.json b/packages/hono/deno.json index 57f700d0c..49bd63984 100644 --- a/packages/hono/deno.json +++ b/packages/hono/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/hono", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13" diff --git a/packages/hono/package.json b/packages/hono/package.json index 38c199547..ea43e2772 100644 --- a/packages/hono/package.json +++ b/packages/hono/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/hono", - "version": "2.0.30", + "version": "2.0.31", "description": "Integrate Fedify with Hono", "keywords": [ "Fedify", diff --git a/packages/init/deno.json b/packages/init/deno.json index ccb181cd3..39d0eb42e 100644 --- a/packages/init/deno.json +++ b/packages/init/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/init", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": "./src/mod.ts", "imports": { diff --git a/packages/init/package.json b/packages/init/package.json index f157c0da1..0219e626c 100644 --- a/packages/init/package.json +++ b/packages/init/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/init", - "version": "2.0.30", + "version": "2.0.31", "description": "Project initializer for Fedify", "keywords": [ "fedify", diff --git a/packages/koa/deno.json b/packages/koa/deno.json index 24dc20222..574348fb6 100644 --- a/packages/koa/deno.json +++ b/packages/koa/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/koa", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/koa/package.json b/packages/koa/package.json index 95e43b245..85d0c2b48 100644 --- a/packages/koa/package.json +++ b/packages/koa/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/koa", - "version": "2.0.30", + "version": "2.0.31", "description": "Integrate Fedify with Koa", "keywords": [ "Fedify", diff --git a/packages/lint/deno.json b/packages/lint/deno.json index f2ac913b2..248242511 100644 --- a/packages/lint/deno.json +++ b/packages/lint/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/lint", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/lint/package.json b/packages/lint/package.json index 8276f9838..5002242e1 100644 --- a/packages/lint/package.json +++ b/packages/lint/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/lint", - "version": "2.0.30", + "version": "2.0.31", "description": "Fedify linting rules and plugins", "keywords": [ "Fedify", diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index a29aa68b2..d187f2623 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/nestjs", - "version": "2.0.30", + "version": "2.0.31", "description": "Integrate Fedify with Nest.js", "keywords": [ "Fedify", diff --git a/packages/next/package.json b/packages/next/package.json index 2184aabfc..61ce03c2d 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/next", - "version": "2.0.30", + "version": "2.0.31", "description": "Integrate Fedify with Next.js", "keywords": [ "Fedify", diff --git a/packages/postgres/deno.json b/packages/postgres/deno.json index 4395036e4..dd537c495 100644 --- a/packages/postgres/deno.json +++ b/packages/postgres/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/postgres", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/postgres/package.json b/packages/postgres/package.json index f78c0b10d..0add56f2e 100644 --- a/packages/postgres/package.json +++ b/packages/postgres/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/postgres", - "version": "2.0.30", + "version": "2.0.31", "description": "PostgreSQL drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/redis/deno.json b/packages/redis/deno.json index 995fff80d..76a8a3315 100644 --- a/packages/redis/deno.json +++ b/packages/redis/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/redis", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/redis/package.json b/packages/redis/package.json index b12598f17..6bccef5c8 100644 --- a/packages/redis/package.json +++ b/packages/redis/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/redis", - "version": "2.0.30", + "version": "2.0.31", "description": "Redis drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/relay/deno.json b/packages/relay/deno.json index df91b84b0..0c4e45a4e 100644 --- a/packages/relay/deno.json +++ b/packages/relay/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/relay", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13" diff --git a/packages/relay/package.json b/packages/relay/package.json index 21f21e6c4..905b11a93 100644 --- a/packages/relay/package.json +++ b/packages/relay/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/relay", - "version": "2.0.30", + "version": "2.0.31", "description": "ActivityPub relay support for Fedify", "keywords": [ "Fedify", diff --git a/packages/sqlite/deno.json b/packages/sqlite/deno.json index f5b898b03..c6f317ce6 100644 --- a/packages/sqlite/deno.json +++ b/packages/sqlite/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/sqlite", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/sqlite/package.json b/packages/sqlite/package.json index f23d267bc..92254c3a4 100644 --- a/packages/sqlite/package.json +++ b/packages/sqlite/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/sqlite", - "version": "2.0.30", + "version": "2.0.31", "description": "SQLite drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/sveltekit/deno.json b/packages/sveltekit/deno.json index ca94c1218..e87e3c282 100644 --- a/packages/sveltekit/deno.json +++ b/packages/sveltekit/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/sveltekit", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13", diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index 900e8ef81..fb34c7940 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/sveltekit", - "version": "2.0.30", + "version": "2.0.31", "description": "Integrate Fedify with SvelteKit", "keywords": [ "Fedify", diff --git a/packages/testing/deno.json b/packages/testing/deno.json index 62f7317f3..87d0b1202 100644 --- a/packages/testing/deno.json +++ b/packages/testing/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/testing", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/testing/package.json b/packages/testing/package.json index 2a97a99a1..e3eea2e7f 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/testing", - "version": "2.0.30", + "version": "2.0.31", "description": "Testing utilities for Fedify applications", "keywords": [ "fedify", diff --git a/packages/vocab-runtime/deno.json b/packages/vocab-runtime/deno.json index 59cdf15a3..5964afd83 100644 --- a/packages/vocab-runtime/deno.json +++ b/packages/vocab-runtime/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-runtime", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/vocab-runtime/package.json b/packages/vocab-runtime/package.json index ea20311db..c5f73e348 100644 --- a/packages/vocab-runtime/package.json +++ b/packages/vocab-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-runtime", - "version": "2.0.30", + "version": "2.0.31", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/vocab-tools/deno.json b/packages/vocab-tools/deno.json index b5c292788..5f62db691 100644 --- a/packages/vocab-tools/deno.json +++ b/packages/vocab-tools/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-tools", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/vocab-tools/package.json b/packages/vocab-tools/package.json index 1e0c9d44f..56c5a8a9a 100644 --- a/packages/vocab-tools/package.json +++ b/packages/vocab-tools/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-tools", - "version": "2.0.30", + "version": "2.0.31", "description": "Code generator for Activity Vocabulary APIs", "homepage": "https://fedify.dev/", "repository": { diff --git a/packages/vocab/deno.json b/packages/vocab/deno.json index 55248a9a7..e7f8365ef 100644 --- a/packages/vocab/deno.json +++ b/packages/vocab/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/vocab/package.json b/packages/vocab/package.json index ee2e35aad..b9722e35a 100644 --- a/packages/vocab/package.json +++ b/packages/vocab/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab", - "version": "2.0.30", + "version": "2.0.31", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/webfinger/deno.json b/packages/webfinger/deno.json index ae27703de..3d3e89588 100644 --- a/packages/webfinger/deno.json +++ b/packages/webfinger/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/webfinger", - "version": "2.0.30", + "version": "2.0.31", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/webfinger/package.json b/packages/webfinger/package.json index 0c0584fc4..5fb275efa 100644 --- a/packages/webfinger/package.json +++ b/packages/webfinger/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/webfinger", - "version": "2.0.30", + "version": "2.0.31", "homepage": "https://fedify.dev/", "repository": { "type": "git", From fd498467e4702d5928714b1a59dc36ce5d4548a8 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Wed, 30 Sep 2026 15:40:35 +0900 Subject: [PATCH 002/184] Version bump [ci skip] --- CHANGES.md | 6 ++++++ changes.d/next.txt | 1 + packages/amqp/deno.json | 2 +- packages/amqp/package.json | 2 +- packages/astro/deno.json | 2 +- packages/astro/package.json | 2 +- packages/cfworkers/deno.json | 2 +- packages/cfworkers/package.json | 2 +- packages/cli/deno.json | 2 +- packages/cli/package.json | 2 +- packages/create/package.json | 2 +- packages/debugger/deno.json | 2 +- packages/debugger/package.json | 2 +- packages/denokv/deno.json | 2 +- packages/elysia/deno.json | 2 +- packages/elysia/package.json | 2 +- packages/express/deno.json | 2 +- packages/express/package.json | 2 +- packages/fastify/deno.json | 2 +- packages/fastify/package.json | 2 +- packages/fedify/deno.json | 2 +- packages/fedify/package.json | 2 +- packages/fixture/deno.json | 2 +- packages/fresh/deno.json | 2 +- packages/h3/deno.json | 2 +- packages/h3/package.json | 2 +- packages/hono/deno.json | 2 +- packages/hono/package.json | 2 +- packages/init/deno.json | 2 +- packages/init/package.json | 2 +- packages/koa/deno.json | 2 +- packages/koa/package.json | 2 +- packages/lint/deno.json | 2 +- packages/lint/package.json | 2 +- packages/mysql/deno.json | 2 +- packages/mysql/package.json | 2 +- packages/nestjs/package.json | 2 +- packages/next/package.json | 2 +- packages/postgres/deno.json | 2 +- packages/postgres/package.json | 2 +- packages/redis/deno.json | 2 +- packages/redis/package.json | 2 +- packages/relay/deno.json | 2 +- packages/relay/package.json | 2 +- packages/sqlite/deno.json | 2 +- packages/sqlite/package.json | 2 +- packages/sveltekit/deno.json | 2 +- packages/sveltekit/package.json | 2 +- packages/testing/deno.json | 2 +- packages/testing/package.json | 2 +- packages/vocab-runtime/deno.json | 2 +- packages/vocab-runtime/package.json | 2 +- packages/vocab-tools/deno.json | 2 +- packages/vocab-tools/package.json | 2 +- packages/vocab/deno.json | 2 +- packages/vocab/package.json | 2 +- packages/webfinger/deno.json | 2 +- packages/webfinger/package.json | 2 +- 58 files changed, 63 insertions(+), 56 deletions(-) create mode 100644 changes.d/next.txt diff --git a/CHANGES.md b/CHANGES.md index 3f0020212..ba5543e62 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,12 @@ Fedify changelog ================ +Version 2.1.27 +-------------- + +To be released. + + Version 2.1.26 -------------- diff --git a/changes.d/next.txt b/changes.d/next.txt new file mode 100644 index 000000000..b88e1c847 --- /dev/null +++ b/changes.d/next.txt @@ -0,0 +1 @@ +2.1.27 diff --git a/packages/amqp/deno.json b/packages/amqp/deno.json index 6e3029250..4e1b37aa8 100644 --- a/packages/amqp/deno.json +++ b/packages/amqp/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/amqp", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/amqp/package.json b/packages/amqp/package.json index 69de3f7cb..914b1735f 100644 --- a/packages/amqp/package.json +++ b/packages/amqp/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/amqp", - "version": "2.1.26", + "version": "2.1.27", "description": "AMQP/RabbitMQ driver for Fedify", "keywords": [ "fedify", diff --git a/packages/astro/deno.json b/packages/astro/deno.json index 46abb4f73..036339167 100644 --- a/packages/astro/deno.json +++ b/packages/astro/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/astro", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "imports": {}, "exports": { diff --git a/packages/astro/package.json b/packages/astro/package.json index 5cacfa402..1815d60b3 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/astro", - "version": "2.1.26", + "version": "2.1.27", "description": "Integrate Fedify with Astro", "keywords": [ "Fedify", diff --git a/packages/cfworkers/deno.json b/packages/cfworkers/deno.json index 5f552271a..5c4543f13 100644 --- a/packages/cfworkers/deno.json +++ b/packages/cfworkers/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cfworkers", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "imports": { "@cloudflare/workers-types/experimental": "npm:@cloudflare/workers-types@^4.20250906.0/experimental" diff --git a/packages/cfworkers/package.json b/packages/cfworkers/package.json index 20500a672..c3708752c 100644 --- a/packages/cfworkers/package.json +++ b/packages/cfworkers/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/cfworkers", - "version": "2.1.26", + "version": "2.1.27", "description": "Adapt Fedify with Cloudflare Workers", "keywords": [ "Fedify", diff --git a/packages/cli/deno.json b/packages/cli/deno.json index 06713057a..9cf6d7fb1 100644 --- a/packages/cli/deno.json +++ b/packages/cli/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": "./src/mod.ts", "imports": { diff --git a/packages/cli/package.json b/packages/cli/package.json index d22501ecf..ca2663914 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "2.1.26", + "version": "2.1.27", "type": "module", "files": [ "README.md", diff --git a/packages/create/package.json b/packages/create/package.json index b82cb97c5..8fd688034 100644 --- a/packages/create/package.json +++ b/packages/create/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/create", - "version": "2.1.26", + "version": "2.1.27", "description": "Create a new Fedify application", "keywords": [ "fedify", diff --git a/packages/debugger/deno.json b/packages/debugger/deno.json index 4feab92eb..cb9ebe20f 100644 --- a/packages/debugger/deno.json +++ b/packages/debugger/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/debugger", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.tsx" diff --git a/packages/debugger/package.json b/packages/debugger/package.json index ae50760e7..aa09b2752 100644 --- a/packages/debugger/package.json +++ b/packages/debugger/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/debugger", - "version": "2.1.26", + "version": "2.1.27", "description": "Embedded ActivityPub debug dashboard for Fedify", "type": "module", "main": "./dist/mod.cjs", diff --git a/packages/denokv/deno.json b/packages/denokv/deno.json index f0a6b48c3..67fec364b 100644 --- a/packages/denokv/deno.json +++ b/packages/denokv/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/denokv", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13", diff --git a/packages/elysia/deno.json b/packages/elysia/deno.json index bdc20d07c..b3f553201 100644 --- a/packages/elysia/deno.json +++ b/packages/elysia/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/elysia", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/elysia/package.json b/packages/elysia/package.json index ce936f903..fc73b3adf 100644 --- a/packages/elysia/package.json +++ b/packages/elysia/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/elysia", - "version": "2.1.26", + "version": "2.1.27", "description": "Integrate Fedify with Elysia", "keywords": [ "Fedify", diff --git a/packages/express/deno.json b/packages/express/deno.json index 32141ed81..f20a1a08f 100644 --- a/packages/express/deno.json +++ b/packages/express/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/express", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/express/package.json b/packages/express/package.json index d236696f4..b3a902121 100644 --- a/packages/express/package.json +++ b/packages/express/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/express", - "version": "2.1.26", + "version": "2.1.27", "description": "Integrate Fedify with Express", "keywords": [ "Fedify", diff --git a/packages/fastify/deno.json b/packages/fastify/deno.json index 1850aede5..1cd61f1b5 100644 --- a/packages/fastify/deno.json +++ b/packages/fastify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fastify", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/fastify/package.json b/packages/fastify/package.json index 53c2a57fd..d04bca314 100644 --- a/packages/fastify/package.json +++ b/packages/fastify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/fastify", - "version": "2.1.26", + "version": "2.1.27", "description": "Integrate Fedify with Fastify", "keywords": [ "Fedify", diff --git a/packages/fedify/deno.json b/packages/fedify/deno.json index f0d27c5d2..3c2bae2ff 100644 --- a/packages/fedify/deno.json +++ b/packages/fedify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/fedify/package.json b/packages/fedify/package.json index 745577e15..b6de8e524 100644 --- a/packages/fedify/package.json +++ b/packages/fedify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "2.1.26", + "version": "2.1.27", "description": "An ActivityPub server framework", "keywords": [ "ActivityPub", diff --git a/packages/fixture/deno.json b/packages/fixture/deno.json index 2a0f25ee5..f2e78bfa2 100644 --- a/packages/fixture/deno.json +++ b/packages/fixture/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fixture", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/fresh/deno.json b/packages/fresh/deno.json index 5546433c3..e16237a54 100644 --- a/packages/fresh/deno.json +++ b/packages/fresh/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fresh", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "imports": { "@fresh/core": "jsr:@fresh/core@^2.1.4", diff --git a/packages/h3/deno.json b/packages/h3/deno.json index 48f6eca5a..6d4ed1e4c 100644 --- a/packages/h3/deno.json +++ b/packages/h3/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/h3", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/h3/package.json b/packages/h3/package.json index 8a506bd25..a6e29d1ab 100644 --- a/packages/h3/package.json +++ b/packages/h3/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/h3", - "version": "2.1.26", + "version": "2.1.27", "description": "Integrate Fedify with h3", "keywords": [ "Fedify", diff --git a/packages/hono/deno.json b/packages/hono/deno.json index 19265548e..9c59d75f8 100644 --- a/packages/hono/deno.json +++ b/packages/hono/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/hono", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13" diff --git a/packages/hono/package.json b/packages/hono/package.json index d48324afe..712f0e0b4 100644 --- a/packages/hono/package.json +++ b/packages/hono/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/hono", - "version": "2.1.26", + "version": "2.1.27", "description": "Integrate Fedify with Hono", "keywords": [ "Fedify", diff --git a/packages/init/deno.json b/packages/init/deno.json index bbd9a8e20..0ea3af8c4 100644 --- a/packages/init/deno.json +++ b/packages/init/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/init", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": "./src/mod.ts", "imports": { diff --git a/packages/init/package.json b/packages/init/package.json index 387a99c4f..75c51bc88 100644 --- a/packages/init/package.json +++ b/packages/init/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/init", - "version": "2.1.26", + "version": "2.1.27", "description": "Project initializer for Fedify", "keywords": [ "fedify", diff --git a/packages/koa/deno.json b/packages/koa/deno.json index 9d5b0639b..484ed5d1a 100644 --- a/packages/koa/deno.json +++ b/packages/koa/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/koa", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/koa/package.json b/packages/koa/package.json index 856f48272..acb33d3f7 100644 --- a/packages/koa/package.json +++ b/packages/koa/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/koa", - "version": "2.1.26", + "version": "2.1.27", "description": "Integrate Fedify with Koa", "keywords": [ "Fedify", diff --git a/packages/lint/deno.json b/packages/lint/deno.json index dc9686513..fe47f3b30 100644 --- a/packages/lint/deno.json +++ b/packages/lint/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/lint", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/lint/package.json b/packages/lint/package.json index a1b14690a..ffc666aec 100644 --- a/packages/lint/package.json +++ b/packages/lint/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/lint", - "version": "2.1.26", + "version": "2.1.27", "description": "Fedify linting rules and plugins", "keywords": [ "Fedify", diff --git a/packages/mysql/deno.json b/packages/mysql/deno.json index f2b52cd1b..5518a8153 100644 --- a/packages/mysql/deno.json +++ b/packages/mysql/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/mysql", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/mysql/package.json b/packages/mysql/package.json index 3d01b0264..6972f28d9 100644 --- a/packages/mysql/package.json +++ b/packages/mysql/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/mysql", - "version": "2.1.26", + "version": "2.1.27", "description": "MySQL/MariaDB drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index 6b4c89a9e..2847d2aff 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/nestjs", - "version": "2.1.26", + "version": "2.1.27", "description": "Integrate Fedify with Nest.js", "keywords": [ "Fedify", diff --git a/packages/next/package.json b/packages/next/package.json index c716f53cc..d01f14331 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/next", - "version": "2.1.26", + "version": "2.1.27", "description": "Integrate Fedify with Next.js", "keywords": [ "Fedify", diff --git a/packages/postgres/deno.json b/packages/postgres/deno.json index a2979e8b6..16a39903f 100644 --- a/packages/postgres/deno.json +++ b/packages/postgres/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/postgres", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/postgres/package.json b/packages/postgres/package.json index d49c4e76d..de698caf8 100644 --- a/packages/postgres/package.json +++ b/packages/postgres/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/postgres", - "version": "2.1.26", + "version": "2.1.27", "description": "PostgreSQL drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/redis/deno.json b/packages/redis/deno.json index 0111d4bfa..0d616cfb6 100644 --- a/packages/redis/deno.json +++ b/packages/redis/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/redis", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/redis/package.json b/packages/redis/package.json index 619149f89..12151ec8f 100644 --- a/packages/redis/package.json +++ b/packages/redis/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/redis", - "version": "2.1.26", + "version": "2.1.27", "description": "Redis drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/relay/deno.json b/packages/relay/deno.json index 14033d71c..c3dbb6f0e 100644 --- a/packages/relay/deno.json +++ b/packages/relay/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/relay", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13" diff --git a/packages/relay/package.json b/packages/relay/package.json index cdffd974a..4826ba3ba 100644 --- a/packages/relay/package.json +++ b/packages/relay/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/relay", - "version": "2.1.26", + "version": "2.1.27", "description": "ActivityPub relay support for Fedify", "keywords": [ "Fedify", diff --git a/packages/sqlite/deno.json b/packages/sqlite/deno.json index 2bfeb2185..3f3d52fbf 100644 --- a/packages/sqlite/deno.json +++ b/packages/sqlite/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/sqlite", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/sqlite/package.json b/packages/sqlite/package.json index 93e66b653..6ae62a21d 100644 --- a/packages/sqlite/package.json +++ b/packages/sqlite/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/sqlite", - "version": "2.1.26", + "version": "2.1.27", "description": "SQLite drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/sveltekit/deno.json b/packages/sveltekit/deno.json index 9e1e6c184..3c9776931 100644 --- a/packages/sveltekit/deno.json +++ b/packages/sveltekit/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/sveltekit", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13", diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index 84c798f85..27395a28f 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/sveltekit", - "version": "2.1.26", + "version": "2.1.27", "description": "Integrate Fedify with SvelteKit", "keywords": [ "Fedify", diff --git a/packages/testing/deno.json b/packages/testing/deno.json index 1e4643a8f..e3bc8ddab 100644 --- a/packages/testing/deno.json +++ b/packages/testing/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/testing", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/testing/package.json b/packages/testing/package.json index 037531ff2..c0a344341 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/testing", - "version": "2.1.26", + "version": "2.1.27", "description": "Testing utilities for Fedify applications", "keywords": [ "fedify", diff --git a/packages/vocab-runtime/deno.json b/packages/vocab-runtime/deno.json index c63701318..07f03f97c 100644 --- a/packages/vocab-runtime/deno.json +++ b/packages/vocab-runtime/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-runtime", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/vocab-runtime/package.json b/packages/vocab-runtime/package.json index 44785c00f..e4c59cb7c 100644 --- a/packages/vocab-runtime/package.json +++ b/packages/vocab-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-runtime", - "version": "2.1.26", + "version": "2.1.27", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/vocab-tools/deno.json b/packages/vocab-tools/deno.json index 663b3cbdf..c6d433a84 100644 --- a/packages/vocab-tools/deno.json +++ b/packages/vocab-tools/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-tools", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/vocab-tools/package.json b/packages/vocab-tools/package.json index d30987e7f..e3933d381 100644 --- a/packages/vocab-tools/package.json +++ b/packages/vocab-tools/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-tools", - "version": "2.1.26", + "version": "2.1.27", "description": "Code generator for Activity Vocabulary APIs", "homepage": "https://fedify.dev/", "repository": { diff --git a/packages/vocab/deno.json b/packages/vocab/deno.json index 4f177588c..838dc8289 100644 --- a/packages/vocab/deno.json +++ b/packages/vocab/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/vocab/package.json b/packages/vocab/package.json index e4f8a0548..d95b7bfc6 100644 --- a/packages/vocab/package.json +++ b/packages/vocab/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab", - "version": "2.1.26", + "version": "2.1.27", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/webfinger/deno.json b/packages/webfinger/deno.json index 9c98cd1ec..b61e9aa1e 100644 --- a/packages/webfinger/deno.json +++ b/packages/webfinger/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/webfinger", - "version": "2.1.26", + "version": "2.1.27", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/webfinger/package.json b/packages/webfinger/package.json index 594c6a38a..58921adda 100644 --- a/packages/webfinger/package.json +++ b/packages/webfinger/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/webfinger", - "version": "2.1.26", + "version": "2.1.27", "homepage": "https://fedify.dev/", "repository": { "type": "git", From 6845b5e31d0dda264a4ad1f6ad72441bc57c6a3b Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Wed, 30 Sep 2026 16:00:01 +0900 Subject: [PATCH 003/184] Version bump [ci skip] --- CHANGES.md | 6 ++++++ changes.d/next.txt | 1 + packages/amqp/deno.json | 2 +- packages/amqp/package.json | 2 +- packages/astro/deno.json | 2 +- packages/astro/package.json | 2 +- packages/cfworkers/deno.json | 2 +- packages/cfworkers/package.json | 2 +- packages/cli/deno.json | 2 +- packages/cli/package.json | 2 +- packages/create/package.json | 2 +- packages/debugger/deno.json | 2 +- packages/debugger/package.json | 2 +- packages/denokv/deno.json | 2 +- packages/elysia/deno.json | 2 +- packages/elysia/package.json | 2 +- packages/express/deno.json | 2 +- packages/express/package.json | 2 +- packages/fastify/deno.json | 2 +- packages/fastify/package.json | 2 +- packages/fedify/deno.json | 2 +- packages/fedify/package.json | 2 +- packages/fixture/deno.json | 2 +- packages/fresh/deno.json | 2 +- packages/h3/deno.json | 2 +- packages/h3/package.json | 2 +- packages/hono/deno.json | 2 +- packages/hono/package.json | 2 +- packages/init/deno.json | 2 +- packages/init/package.json | 2 +- packages/koa/deno.json | 2 +- packages/koa/package.json | 2 +- packages/lint/deno.json | 2 +- packages/lint/package.json | 2 +- packages/mysql/deno.json | 2 +- packages/mysql/package.json | 2 +- packages/nestjs/package.json | 2 +- packages/next/package.json | 2 +- packages/nuxt/deno.json | 2 +- packages/nuxt/package.json | 2 +- packages/postgres/deno.json | 2 +- packages/postgres/package.json | 2 +- packages/redis/deno.json | 2 +- packages/redis/package.json | 2 +- packages/relay/deno.json | 2 +- packages/relay/package.json | 2 +- packages/solidstart/deno.json | 2 +- packages/solidstart/package.json | 2 +- packages/sqlite/deno.json | 2 +- packages/sqlite/package.json | 2 +- packages/sveltekit/deno.json | 2 +- packages/sveltekit/package.json | 2 +- packages/testing/deno.json | 2 +- packages/testing/package.json | 2 +- packages/vocab-runtime/deno.json | 2 +- packages/vocab-runtime/package.json | 2 +- packages/vocab-tools/deno.json | 2 +- packages/vocab-tools/package.json | 2 +- packages/vocab/deno.json | 2 +- packages/vocab/package.json | 2 +- packages/webfinger/deno.json | 2 +- packages/webfinger/package.json | 2 +- 62 files changed, 67 insertions(+), 60 deletions(-) create mode 100644 changes.d/next.txt diff --git a/CHANGES.md b/CHANGES.md index 160b06359..f646082c9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,12 @@ Fedify changelog ================ +Version 2.2.16 +-------------- + +To be released. + + Version 2.2.15 -------------- diff --git a/changes.d/next.txt b/changes.d/next.txt new file mode 100644 index 000000000..ed1fc3528 --- /dev/null +++ b/changes.d/next.txt @@ -0,0 +1 @@ +2.2.16 diff --git a/packages/amqp/deno.json b/packages/amqp/deno.json index 97a250c19..0e68746c7 100644 --- a/packages/amqp/deno.json +++ b/packages/amqp/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/amqp", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/amqp/package.json b/packages/amqp/package.json index 396d1cbec..77f894183 100644 --- a/packages/amqp/package.json +++ b/packages/amqp/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/amqp", - "version": "2.2.15", + "version": "2.2.16", "description": "AMQP/RabbitMQ driver for Fedify", "keywords": [ "fedify", diff --git a/packages/astro/deno.json b/packages/astro/deno.json index 360f25177..13f9793fd 100644 --- a/packages/astro/deno.json +++ b/packages/astro/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/astro", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "imports": {}, "exports": { diff --git a/packages/astro/package.json b/packages/astro/package.json index 9578967e9..7c601b56c 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/astro", - "version": "2.2.15", + "version": "2.2.16", "description": "Integrate Fedify with Astro", "keywords": [ "Fedify", diff --git a/packages/cfworkers/deno.json b/packages/cfworkers/deno.json index 12cfb16de..11e7c9ffe 100644 --- a/packages/cfworkers/deno.json +++ b/packages/cfworkers/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cfworkers", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "imports": { "@cloudflare/workers-types/experimental": "npm:@cloudflare/workers-types@^4.20250906.0/experimental" diff --git a/packages/cfworkers/package.json b/packages/cfworkers/package.json index 75bf8c777..3cd8da96e 100644 --- a/packages/cfworkers/package.json +++ b/packages/cfworkers/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/cfworkers", - "version": "2.2.15", + "version": "2.2.16", "description": "Adapt Fedify with Cloudflare Workers", "keywords": [ "Fedify", diff --git a/packages/cli/deno.json b/packages/cli/deno.json index 7b12ece6f..ea37fbe2e 100644 --- a/packages/cli/deno.json +++ b/packages/cli/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": "./src/mod.ts", "imports": { diff --git a/packages/cli/package.json b/packages/cli/package.json index 3459e68de..697720db0 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "2.2.15", + "version": "2.2.16", "type": "module", "files": [ "README.md", diff --git a/packages/create/package.json b/packages/create/package.json index dfa8ab645..339a3f8e0 100644 --- a/packages/create/package.json +++ b/packages/create/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/create", - "version": "2.2.15", + "version": "2.2.16", "description": "Create a new Fedify application", "keywords": [ "fedify", diff --git a/packages/debugger/deno.json b/packages/debugger/deno.json index f9a99d3d1..52a94e323 100644 --- a/packages/debugger/deno.json +++ b/packages/debugger/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/debugger", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.tsx" diff --git a/packages/debugger/package.json b/packages/debugger/package.json index dfbe1f67d..63cf5ad0a 100644 --- a/packages/debugger/package.json +++ b/packages/debugger/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/debugger", - "version": "2.2.15", + "version": "2.2.16", "description": "Embedded ActivityPub debug dashboard for Fedify", "type": "module", "main": "./dist/mod.cjs", diff --git a/packages/denokv/deno.json b/packages/denokv/deno.json index 1cb22adb0..d65ee4abc 100644 --- a/packages/denokv/deno.json +++ b/packages/denokv/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/denokv", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13", diff --git a/packages/elysia/deno.json b/packages/elysia/deno.json index a1cee0d62..5fd49e2be 100644 --- a/packages/elysia/deno.json +++ b/packages/elysia/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/elysia", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/elysia/package.json b/packages/elysia/package.json index 2acf250d7..a3f6325bb 100644 --- a/packages/elysia/package.json +++ b/packages/elysia/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/elysia", - "version": "2.2.15", + "version": "2.2.16", "description": "Integrate Fedify with Elysia", "keywords": [ "Fedify", diff --git a/packages/express/deno.json b/packages/express/deno.json index 58671c4af..223aa7462 100644 --- a/packages/express/deno.json +++ b/packages/express/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/express", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/express/package.json b/packages/express/package.json index c90502c21..49d7c6fdd 100644 --- a/packages/express/package.json +++ b/packages/express/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/express", - "version": "2.2.15", + "version": "2.2.16", "description": "Integrate Fedify with Express", "keywords": [ "Fedify", diff --git a/packages/fastify/deno.json b/packages/fastify/deno.json index ed058a35e..53e3d91c0 100644 --- a/packages/fastify/deno.json +++ b/packages/fastify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fastify", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/fastify/package.json b/packages/fastify/package.json index b8b266683..e2b38b172 100644 --- a/packages/fastify/package.json +++ b/packages/fastify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/fastify", - "version": "2.2.15", + "version": "2.2.16", "description": "Integrate Fedify with Fastify", "keywords": [ "Fedify", diff --git a/packages/fedify/deno.json b/packages/fedify/deno.json index 73a545e48..0026d64de 100644 --- a/packages/fedify/deno.json +++ b/packages/fedify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/fedify/package.json b/packages/fedify/package.json index b9530d3bc..63d022a75 100644 --- a/packages/fedify/package.json +++ b/packages/fedify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "2.2.15", + "version": "2.2.16", "description": "An ActivityPub server framework", "keywords": [ "ActivityPub", diff --git a/packages/fixture/deno.json b/packages/fixture/deno.json index 80f810d10..bb5f873e3 100644 --- a/packages/fixture/deno.json +++ b/packages/fixture/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fixture", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/fresh/deno.json b/packages/fresh/deno.json index a9e32a251..90589538c 100644 --- a/packages/fresh/deno.json +++ b/packages/fresh/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fresh", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "imports": { "@fresh/core": "jsr:@fresh/core@^2.1.4", diff --git a/packages/h3/deno.json b/packages/h3/deno.json index 59fc4cc36..31515eae6 100644 --- a/packages/h3/deno.json +++ b/packages/h3/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/h3", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/h3/package.json b/packages/h3/package.json index 05a4297ea..f0f1de02d 100644 --- a/packages/h3/package.json +++ b/packages/h3/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/h3", - "version": "2.2.15", + "version": "2.2.16", "description": "Integrate Fedify with h3", "keywords": [ "Fedify", diff --git a/packages/hono/deno.json b/packages/hono/deno.json index 2e3a35467..b40b0bd35 100644 --- a/packages/hono/deno.json +++ b/packages/hono/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/hono", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13" diff --git a/packages/hono/package.json b/packages/hono/package.json index 276b1c06d..6ea9c960c 100644 --- a/packages/hono/package.json +++ b/packages/hono/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/hono", - "version": "2.2.15", + "version": "2.2.16", "description": "Integrate Fedify with Hono", "keywords": [ "Fedify", diff --git a/packages/init/deno.json b/packages/init/deno.json index 3c7aab83b..bc8d06e3f 100644 --- a/packages/init/deno.json +++ b/packages/init/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/init", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": "./src/mod.ts", "imports": { diff --git a/packages/init/package.json b/packages/init/package.json index 01293de37..4008cc801 100644 --- a/packages/init/package.json +++ b/packages/init/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/init", - "version": "2.2.15", + "version": "2.2.16", "description": "Project initializer for Fedify", "keywords": [ "fedify", diff --git a/packages/koa/deno.json b/packages/koa/deno.json index 4d5fb1313..6cb6a9e43 100644 --- a/packages/koa/deno.json +++ b/packages/koa/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/koa", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/koa/package.json b/packages/koa/package.json index 5d2ac7663..8d7f0b011 100644 --- a/packages/koa/package.json +++ b/packages/koa/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/koa", - "version": "2.2.15", + "version": "2.2.16", "description": "Integrate Fedify with Koa", "keywords": [ "Fedify", diff --git a/packages/lint/deno.json b/packages/lint/deno.json index 913bb1341..cce8e1181 100644 --- a/packages/lint/deno.json +++ b/packages/lint/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/lint", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/lint/package.json b/packages/lint/package.json index 0cbe2db60..35de70bc5 100644 --- a/packages/lint/package.json +++ b/packages/lint/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/lint", - "version": "2.2.15", + "version": "2.2.16", "description": "Fedify linting rules and plugins", "keywords": [ "Fedify", diff --git a/packages/mysql/deno.json b/packages/mysql/deno.json index 35faf2cbb..48725fef5 100644 --- a/packages/mysql/deno.json +++ b/packages/mysql/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/mysql", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/mysql/package.json b/packages/mysql/package.json index 7060eae8c..2107e2959 100644 --- a/packages/mysql/package.json +++ b/packages/mysql/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/mysql", - "version": "2.2.15", + "version": "2.2.16", "description": "MySQL/MariaDB drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index 8f43bb838..076c200af 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/nestjs", - "version": "2.2.15", + "version": "2.2.16", "description": "Integrate Fedify with Nest.js", "keywords": [ "Fedify", diff --git a/packages/next/package.json b/packages/next/package.json index 051119183..dd1e08816 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/next", - "version": "2.2.15", + "version": "2.2.16", "description": "Integrate Fedify with Next.js", "keywords": [ "Fedify", diff --git a/packages/nuxt/deno.json b/packages/nuxt/deno.json index 0234e0cb6..26a66c2f8 100644 --- a/packages/nuxt/deno.json +++ b/packages/nuxt/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/nuxt", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 539592a1f..6537786b0 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/nuxt", - "version": "2.2.15", + "version": "2.2.16", "description": "Integrate Fedify with Nuxt", "keywords": [ "Fedify", diff --git a/packages/postgres/deno.json b/packages/postgres/deno.json index 47837bd68..8cc6065bb 100644 --- a/packages/postgres/deno.json +++ b/packages/postgres/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/postgres", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/postgres/package.json b/packages/postgres/package.json index 34007fb01..206e0e320 100644 --- a/packages/postgres/package.json +++ b/packages/postgres/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/postgres", - "version": "2.2.15", + "version": "2.2.16", "description": "PostgreSQL drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/redis/deno.json b/packages/redis/deno.json index 68d05e188..d0b1ff9d1 100644 --- a/packages/redis/deno.json +++ b/packages/redis/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/redis", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/redis/package.json b/packages/redis/package.json index 9e951b548..af49f551f 100644 --- a/packages/redis/package.json +++ b/packages/redis/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/redis", - "version": "2.2.15", + "version": "2.2.16", "description": "Redis drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/relay/deno.json b/packages/relay/deno.json index bb9b37c75..b5aee6ac2 100644 --- a/packages/relay/deno.json +++ b/packages/relay/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/relay", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13" diff --git a/packages/relay/package.json b/packages/relay/package.json index e3187403f..a3fda21dd 100644 --- a/packages/relay/package.json +++ b/packages/relay/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/relay", - "version": "2.2.15", + "version": "2.2.16", "description": "ActivityPub relay support for Fedify", "keywords": [ "Fedify", diff --git a/packages/solidstart/deno.json b/packages/solidstart/deno.json index 3064305ff..9a84949f2 100644 --- a/packages/solidstart/deno.json +++ b/packages/solidstart/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/solidstart", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/solidstart/package.json b/packages/solidstart/package.json index e6c33c99b..c50f2b71d 100644 --- a/packages/solidstart/package.json +++ b/packages/solidstart/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/solidstart", - "version": "2.2.15", + "version": "2.2.16", "description": "Integrate Fedify with SolidStart", "keywords": [ "Fedify", diff --git a/packages/sqlite/deno.json b/packages/sqlite/deno.json index 2528a2e6a..1900bbb92 100644 --- a/packages/sqlite/deno.json +++ b/packages/sqlite/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/sqlite", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/sqlite/package.json b/packages/sqlite/package.json index 702312d69..39af4d73a 100644 --- a/packages/sqlite/package.json +++ b/packages/sqlite/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/sqlite", - "version": "2.2.15", + "version": "2.2.16", "description": "SQLite drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/sveltekit/deno.json b/packages/sveltekit/deno.json index 8f0237c4f..f83e8bfd0 100644 --- a/packages/sveltekit/deno.json +++ b/packages/sveltekit/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/sveltekit", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13", diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index a9fc7189e..05da09671 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/sveltekit", - "version": "2.2.15", + "version": "2.2.16", "description": "Integrate Fedify with SvelteKit", "keywords": [ "Fedify", diff --git a/packages/testing/deno.json b/packages/testing/deno.json index 56ff4d606..442f3d9cd 100644 --- a/packages/testing/deno.json +++ b/packages/testing/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/testing", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/testing/package.json b/packages/testing/package.json index 92447c529..e683fe343 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/testing", - "version": "2.2.15", + "version": "2.2.16", "description": "Testing utilities for Fedify applications", "keywords": [ "fedify", diff --git a/packages/vocab-runtime/deno.json b/packages/vocab-runtime/deno.json index 498db6cce..de5ac1093 100644 --- a/packages/vocab-runtime/deno.json +++ b/packages/vocab-runtime/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-runtime", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/vocab-runtime/package.json b/packages/vocab-runtime/package.json index 99828dbc6..08f261df1 100644 --- a/packages/vocab-runtime/package.json +++ b/packages/vocab-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-runtime", - "version": "2.2.15", + "version": "2.2.16", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/vocab-tools/deno.json b/packages/vocab-tools/deno.json index f850f71f1..9fbac20e5 100644 --- a/packages/vocab-tools/deno.json +++ b/packages/vocab-tools/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-tools", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/vocab-tools/package.json b/packages/vocab-tools/package.json index 2239b4c59..5e01248b8 100644 --- a/packages/vocab-tools/package.json +++ b/packages/vocab-tools/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-tools", - "version": "2.2.15", + "version": "2.2.16", "description": "Code generator for Activity Vocabulary APIs", "homepage": "https://fedify.dev/", "repository": { diff --git a/packages/vocab/deno.json b/packages/vocab/deno.json index b371511e1..694874966 100644 --- a/packages/vocab/deno.json +++ b/packages/vocab/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/vocab/package.json b/packages/vocab/package.json index da5776545..f7601ca6e 100644 --- a/packages/vocab/package.json +++ b/packages/vocab/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab", - "version": "2.2.15", + "version": "2.2.16", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/webfinger/deno.json b/packages/webfinger/deno.json index 00f1f0a7d..379134a5a 100644 --- a/packages/webfinger/deno.json +++ b/packages/webfinger/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/webfinger", - "version": "2.2.15", + "version": "2.2.16", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/webfinger/package.json b/packages/webfinger/package.json index d018d26a1..311ccb25e 100644 --- a/packages/webfinger/package.json +++ b/packages/webfinger/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/webfinger", - "version": "2.2.15", + "version": "2.2.16", "homepage": "https://fedify.dev/", "repository": { "type": "git", From 0e1fc8868170927e99c271044f8c0bc30765c780 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Wed, 30 Sep 2026 16:17:31 +0900 Subject: [PATCH 004/184] Version bump [ci skip] --- CHANGES.md | 6 ++++++ changes.d/next.txt | 1 + packages/amqp/deno.json | 2 +- packages/amqp/package.json | 2 +- packages/astro/deno.json | 2 +- packages/astro/package.json | 2 +- packages/backfill/deno.json | 2 +- packages/backfill/package.json | 2 +- packages/cfworkers/deno.json | 2 +- packages/cfworkers/package.json | 2 +- packages/cli/deno.json | 2 +- packages/cli/package.json | 2 +- packages/create/package.json | 2 +- packages/debugger/deno.json | 2 +- packages/debugger/package.json | 2 +- packages/denokv/deno.json | 2 +- packages/elysia/deno.json | 2 +- packages/elysia/package.json | 2 +- packages/express/deno.json | 2 +- packages/express/package.json | 2 +- packages/fastify/deno.json | 2 +- packages/fastify/package.json | 2 +- packages/fedify/deno.json | 2 +- packages/fedify/package.json | 2 +- packages/fixture/deno.json | 2 +- packages/fresh/deno.json | 2 +- packages/h3/deno.json | 2 +- packages/h3/package.json | 2 +- packages/hono/deno.json | 2 +- packages/hono/package.json | 2 +- packages/init/deno.json | 2 +- packages/init/package.json | 2 +- packages/koa/deno.json | 2 +- packages/koa/package.json | 2 +- packages/lint/deno.json | 2 +- packages/lint/package.json | 2 +- packages/mysql/deno.json | 2 +- packages/mysql/package.json | 2 +- packages/nestjs/package.json | 2 +- packages/next/package.json | 2 +- packages/nuxt/deno.json | 2 +- packages/nuxt/package.json | 2 +- packages/postgres/deno.json | 2 +- packages/postgres/package.json | 2 +- packages/redis/deno.json | 2 +- packages/redis/package.json | 2 +- packages/relay/deno.json | 2 +- packages/relay/package.json | 2 +- packages/solidstart/deno.json | 2 +- packages/solidstart/package.json | 2 +- packages/sqlite/deno.json | 2 +- packages/sqlite/package.json | 2 +- packages/sveltekit/deno.json | 2 +- packages/sveltekit/package.json | 2 +- packages/testing/deno.json | 2 +- packages/testing/package.json | 2 +- packages/uri-template/deno.json | 2 +- packages/uri-template/package.json | 2 +- packages/vocab-runtime/deno.json | 2 +- packages/vocab-runtime/package.json | 2 +- packages/vocab-tools/deno.json | 2 +- packages/vocab-tools/package.json | 2 +- packages/vocab/deno.json | 2 +- packages/vocab/package.json | 2 +- packages/webfinger/deno.json | 2 +- packages/webfinger/package.json | 2 +- 66 files changed, 71 insertions(+), 64 deletions(-) create mode 100644 changes.d/next.txt diff --git a/CHANGES.md b/CHANGES.md index ffbab3c5a..1023f3d58 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,12 @@ Fedify changelog ================ +Version 2.3.11 +-------------- + +To be released. + + Version 2.3.10 -------------- diff --git a/changes.d/next.txt b/changes.d/next.txt new file mode 100644 index 000000000..f470771a1 --- /dev/null +++ b/changes.d/next.txt @@ -0,0 +1 @@ +2.3.11 diff --git a/packages/amqp/deno.json b/packages/amqp/deno.json index 9bd287241..019aecdfa 100644 --- a/packages/amqp/deno.json +++ b/packages/amqp/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/amqp", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/amqp/package.json b/packages/amqp/package.json index f78e01a91..0ece8a8ee 100644 --- a/packages/amqp/package.json +++ b/packages/amqp/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/amqp", - "version": "2.3.10", + "version": "2.3.11", "description": "AMQP/RabbitMQ driver for Fedify", "keywords": [ "fedify", diff --git a/packages/astro/deno.json b/packages/astro/deno.json index b1f27f2b2..dbf33770a 100644 --- a/packages/astro/deno.json +++ b/packages/astro/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/astro", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "imports": {}, "exports": { diff --git a/packages/astro/package.json b/packages/astro/package.json index e3e3867da..da0de6225 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/astro", - "version": "2.3.10", + "version": "2.3.11", "description": "Integrate Fedify with Astro", "keywords": [ "Fedify", diff --git a/packages/backfill/deno.json b/packages/backfill/deno.json index 7ed9e60b5..fb14a9c0c 100644 --- a/packages/backfill/deno.json +++ b/packages/backfill/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/backfill", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/backfill/package.json b/packages/backfill/package.json index c86026f4a..1cdde1e57 100644 --- a/packages/backfill/package.json +++ b/packages/backfill/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/backfill", - "version": "2.3.10", + "version": "2.3.11", "description": "ActivityPub backfill support for Fedify", "keywords": [ "Fedify", diff --git a/packages/cfworkers/deno.json b/packages/cfworkers/deno.json index ee13f84da..1b06d2fa4 100644 --- a/packages/cfworkers/deno.json +++ b/packages/cfworkers/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cfworkers", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "imports": { "@cloudflare/workers-types/experimental": "npm:@cloudflare/workers-types@^4.20260511.1/experimental" diff --git a/packages/cfworkers/package.json b/packages/cfworkers/package.json index 953938737..484d3cde8 100644 --- a/packages/cfworkers/package.json +++ b/packages/cfworkers/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/cfworkers", - "version": "2.3.10", + "version": "2.3.11", "description": "Adapt Fedify with Cloudflare Workers", "keywords": [ "Fedify", diff --git a/packages/cli/deno.json b/packages/cli/deno.json index 0db107b73..bf20c6bd6 100644 --- a/packages/cli/deno.json +++ b/packages/cli/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": "./src/mod.ts", "imports": { diff --git a/packages/cli/package.json b/packages/cli/package.json index e6f580977..4b366fa77 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "2.3.10", + "version": "2.3.11", "type": "module", "files": [ "README.md", diff --git a/packages/create/package.json b/packages/create/package.json index 7ce87bcd9..4ed67621d 100644 --- a/packages/create/package.json +++ b/packages/create/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/create", - "version": "2.3.10", + "version": "2.3.11", "description": "Create a new Fedify application", "keywords": [ "fedify", diff --git a/packages/debugger/deno.json b/packages/debugger/deno.json index e31c0a0a3..99b30d75b 100644 --- a/packages/debugger/deno.json +++ b/packages/debugger/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/debugger", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.tsx" diff --git a/packages/debugger/package.json b/packages/debugger/package.json index 308e84499..85969dd32 100644 --- a/packages/debugger/package.json +++ b/packages/debugger/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/debugger", - "version": "2.3.10", + "version": "2.3.11", "description": "Embedded ActivityPub debug dashboard for Fedify", "type": "module", "main": "./dist/mod.cjs", diff --git a/packages/denokv/deno.json b/packages/denokv/deno.json index 737449d6d..ff6cd20c0 100644 --- a/packages/denokv/deno.json +++ b/packages/denokv/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/denokv", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13", diff --git a/packages/elysia/deno.json b/packages/elysia/deno.json index 021dd5152..a3544a4c4 100644 --- a/packages/elysia/deno.json +++ b/packages/elysia/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/elysia", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/elysia/package.json b/packages/elysia/package.json index 388d33428..4c902364f 100644 --- a/packages/elysia/package.json +++ b/packages/elysia/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/elysia", - "version": "2.3.10", + "version": "2.3.11", "description": "Integrate Fedify with Elysia", "keywords": [ "Fedify", diff --git a/packages/express/deno.json b/packages/express/deno.json index 17e4f505f..aa9698a87 100644 --- a/packages/express/deno.json +++ b/packages/express/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/express", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/express/package.json b/packages/express/package.json index 9613c7129..94d86db6d 100644 --- a/packages/express/package.json +++ b/packages/express/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/express", - "version": "2.3.10", + "version": "2.3.11", "description": "Integrate Fedify with Express", "keywords": [ "Fedify", diff --git a/packages/fastify/deno.json b/packages/fastify/deno.json index fce19716b..59b10555b 100644 --- a/packages/fastify/deno.json +++ b/packages/fastify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fastify", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/fastify/package.json b/packages/fastify/package.json index 6ee319ae9..019290926 100644 --- a/packages/fastify/package.json +++ b/packages/fastify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/fastify", - "version": "2.3.10", + "version": "2.3.11", "description": "Integrate Fedify with Fastify", "keywords": [ "Fedify", diff --git a/packages/fedify/deno.json b/packages/fedify/deno.json index 4aa3a3b2a..ebdfa504f 100644 --- a/packages/fedify/deno.json +++ b/packages/fedify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/fedify/package.json b/packages/fedify/package.json index e4b129814..3e3588e0f 100644 --- a/packages/fedify/package.json +++ b/packages/fedify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "2.3.10", + "version": "2.3.11", "description": "An ActivityPub server framework", "keywords": [ "ActivityPub", diff --git a/packages/fixture/deno.json b/packages/fixture/deno.json index db1480cdc..30130f5d3 100644 --- a/packages/fixture/deno.json +++ b/packages/fixture/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fixture", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/fresh/deno.json b/packages/fresh/deno.json index 53420cee7..43be547e2 100644 --- a/packages/fresh/deno.json +++ b/packages/fresh/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fresh", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "imports": { "@fresh/core": "jsr:@fresh/core@^2.1.4", diff --git a/packages/h3/deno.json b/packages/h3/deno.json index cd5a122d0..19e370752 100644 --- a/packages/h3/deno.json +++ b/packages/h3/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/h3", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/h3/package.json b/packages/h3/package.json index 8c618856c..19f19f821 100644 --- a/packages/h3/package.json +++ b/packages/h3/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/h3", - "version": "2.3.10", + "version": "2.3.11", "description": "Integrate Fedify with h3", "keywords": [ "Fedify", diff --git a/packages/hono/deno.json b/packages/hono/deno.json index 43aab431b..2926cc007 100644 --- a/packages/hono/deno.json +++ b/packages/hono/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/hono", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13" diff --git a/packages/hono/package.json b/packages/hono/package.json index 2ebb8cb47..d0701bac5 100644 --- a/packages/hono/package.json +++ b/packages/hono/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/hono", - "version": "2.3.10", + "version": "2.3.11", "description": "Integrate Fedify with Hono", "keywords": [ "Fedify", diff --git a/packages/init/deno.json b/packages/init/deno.json index 69a6e87f8..96211094f 100644 --- a/packages/init/deno.json +++ b/packages/init/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/init", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": "./src/mod.ts", "imports": { diff --git a/packages/init/package.json b/packages/init/package.json index 3d399f17d..949434672 100644 --- a/packages/init/package.json +++ b/packages/init/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/init", - "version": "2.3.10", + "version": "2.3.11", "description": "Project initializer for Fedify", "keywords": [ "fedify", diff --git a/packages/koa/deno.json b/packages/koa/deno.json index fbb3707e8..0d65ff761 100644 --- a/packages/koa/deno.json +++ b/packages/koa/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/koa", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/koa/package.json b/packages/koa/package.json index 1dbc0105a..153223b95 100644 --- a/packages/koa/package.json +++ b/packages/koa/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/koa", - "version": "2.3.10", + "version": "2.3.11", "description": "Integrate Fedify with Koa", "keywords": [ "Fedify", diff --git a/packages/lint/deno.json b/packages/lint/deno.json index 35f0cd57b..535310088 100644 --- a/packages/lint/deno.json +++ b/packages/lint/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/lint", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/lint/package.json b/packages/lint/package.json index 449a29016..e660f4744 100644 --- a/packages/lint/package.json +++ b/packages/lint/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/lint", - "version": "2.3.10", + "version": "2.3.11", "description": "Fedify linting rules and plugins", "keywords": [ "Fedify", diff --git a/packages/mysql/deno.json b/packages/mysql/deno.json index b36110088..dbc2ae3ab 100644 --- a/packages/mysql/deno.json +++ b/packages/mysql/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/mysql", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/mysql/package.json b/packages/mysql/package.json index e31e82c9e..8acab704d 100644 --- a/packages/mysql/package.json +++ b/packages/mysql/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/mysql", - "version": "2.3.10", + "version": "2.3.11", "description": "MySQL/MariaDB drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index 3f3d0d1c0..d6ba6b602 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/nestjs", - "version": "2.3.10", + "version": "2.3.11", "description": "Integrate Fedify with Nest.js", "keywords": [ "Fedify", diff --git a/packages/next/package.json b/packages/next/package.json index 9c346e647..ce93f7f81 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/next", - "version": "2.3.10", + "version": "2.3.11", "description": "Integrate Fedify with Next.js", "keywords": [ "Fedify", diff --git a/packages/nuxt/deno.json b/packages/nuxt/deno.json index c1362f82c..6cb459ce9 100644 --- a/packages/nuxt/deno.json +++ b/packages/nuxt/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/nuxt", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 8fa524792..97814a44a 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/nuxt", - "version": "2.3.10", + "version": "2.3.11", "description": "Integrate Fedify with Nuxt", "keywords": [ "Fedify", diff --git a/packages/postgres/deno.json b/packages/postgres/deno.json index cabfd3c17..2c567761b 100644 --- a/packages/postgres/deno.json +++ b/packages/postgres/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/postgres", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/postgres/package.json b/packages/postgres/package.json index f2d37225d..8ef2ba1de 100644 --- a/packages/postgres/package.json +++ b/packages/postgres/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/postgres", - "version": "2.3.10", + "version": "2.3.11", "description": "PostgreSQL drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/redis/deno.json b/packages/redis/deno.json index 65b673b78..f9dc9f5a6 100644 --- a/packages/redis/deno.json +++ b/packages/redis/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/redis", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/redis/package.json b/packages/redis/package.json index 5644ac39a..317a6c375 100644 --- a/packages/redis/package.json +++ b/packages/redis/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/redis", - "version": "2.3.10", + "version": "2.3.11", "description": "Redis drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/relay/deno.json b/packages/relay/deno.json index da50963de..ee730f556 100644 --- a/packages/relay/deno.json +++ b/packages/relay/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/relay", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13" diff --git a/packages/relay/package.json b/packages/relay/package.json index ac8a87eb1..64c32c47c 100644 --- a/packages/relay/package.json +++ b/packages/relay/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/relay", - "version": "2.3.10", + "version": "2.3.11", "description": "ActivityPub relay support for Fedify", "keywords": [ "Fedify", diff --git a/packages/solidstart/deno.json b/packages/solidstart/deno.json index 75165dc9f..18de8abc1 100644 --- a/packages/solidstart/deno.json +++ b/packages/solidstart/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/solidstart", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/solidstart/package.json b/packages/solidstart/package.json index 15243e8c2..b6c0457a9 100644 --- a/packages/solidstart/package.json +++ b/packages/solidstart/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/solidstart", - "version": "2.3.10", + "version": "2.3.11", "description": "Integrate Fedify with SolidStart", "keywords": [ "Fedify", diff --git a/packages/sqlite/deno.json b/packages/sqlite/deno.json index 409a11ca5..695dc1ba7 100644 --- a/packages/sqlite/deno.json +++ b/packages/sqlite/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/sqlite", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/sqlite/package.json b/packages/sqlite/package.json index cb78399d1..733be183e 100644 --- a/packages/sqlite/package.json +++ b/packages/sqlite/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/sqlite", - "version": "2.3.10", + "version": "2.3.11", "description": "SQLite drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/sveltekit/deno.json b/packages/sveltekit/deno.json index db43dde83..d412a776b 100644 --- a/packages/sveltekit/deno.json +++ b/packages/sveltekit/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/sveltekit", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13", diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index 595c3dc07..5e7c39288 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/sveltekit", - "version": "2.3.10", + "version": "2.3.11", "description": "Integrate Fedify with SvelteKit", "keywords": [ "Fedify", diff --git a/packages/testing/deno.json b/packages/testing/deno.json index fffa49a24..538ed3c26 100644 --- a/packages/testing/deno.json +++ b/packages/testing/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/testing", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/testing/package.json b/packages/testing/package.json index 32d363449..69ebe4fe5 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/testing", - "version": "2.3.10", + "version": "2.3.11", "description": "Testing utilities for Fedify applications", "keywords": [ "fedify", diff --git a/packages/uri-template/deno.json b/packages/uri-template/deno.json index bc66906d4..1a434fd9f 100644 --- a/packages/uri-template/deno.json +++ b/packages/uri-template/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/uri-template", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/uri-template/package.json b/packages/uri-template/package.json index c9c7b40bc..a0e20f2bd 100644 --- a/packages/uri-template/package.json +++ b/packages/uri-template/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/uri-template", - "version": "2.3.10", + "version": "2.3.11", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/vocab-runtime/deno.json b/packages/vocab-runtime/deno.json index 83a50a9c6..fafe387b2 100644 --- a/packages/vocab-runtime/deno.json +++ b/packages/vocab-runtime/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-runtime", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/vocab-runtime/package.json b/packages/vocab-runtime/package.json index 3c7cec524..5970d6439 100644 --- a/packages/vocab-runtime/package.json +++ b/packages/vocab-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-runtime", - "version": "2.3.10", + "version": "2.3.11", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/vocab-tools/deno.json b/packages/vocab-tools/deno.json index 2601bce8e..9ad8255cb 100644 --- a/packages/vocab-tools/deno.json +++ b/packages/vocab-tools/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-tools", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/vocab-tools/package.json b/packages/vocab-tools/package.json index 40a01c95b..960f88ecd 100644 --- a/packages/vocab-tools/package.json +++ b/packages/vocab-tools/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-tools", - "version": "2.3.10", + "version": "2.3.11", "description": "Code generator for Activity Vocabulary APIs", "homepage": "https://fedify.dev/", "repository": { diff --git a/packages/vocab/deno.json b/packages/vocab/deno.json index 0c7b23a8b..f29fac870 100644 --- a/packages/vocab/deno.json +++ b/packages/vocab/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/vocab/package.json b/packages/vocab/package.json index 3142089f1..26ecf5f6a 100644 --- a/packages/vocab/package.json +++ b/packages/vocab/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab", - "version": "2.3.10", + "version": "2.3.11", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/webfinger/deno.json b/packages/webfinger/deno.json index f1b7f3463..0e334fe88 100644 --- a/packages/webfinger/deno.json +++ b/packages/webfinger/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/webfinger", - "version": "2.3.10", + "version": "2.3.11", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/webfinger/package.json b/packages/webfinger/package.json index 675a94b10..8976ba734 100644 --- a/packages/webfinger/package.json +++ b/packages/webfinger/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/webfinger", - "version": "2.3.10", + "version": "2.3.11", "homepage": "https://fedify.dev/", "repository": { "type": "git", From 44ef1c68d283f7e4982351c0df64df99f91fdd9b Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Wed, 30 Sep 2026 23:54:56 +0900 Subject: [PATCH 005/184] Observe inbox request completion Add onRequestFinished() so applications can retain inbox delivery results without depending on trace sampling or reconstructing verification work. Report actual keys and signature attempts separately from the final authentication decision and processing outcome. Cover personal, shared and portable ingress, including preparation errors and final response failures. Await the observer once and isolate its errors so the existing response or exception is preserved. Keep diagnostic collection from changing verifier results or adding network fetches. Document the API and telemetry, add regression coverage, and keep mock federation configuration compatible with the new callback. Closes https://github.com/fedify-dev/fedify/issues/1191 Assisted-by: OpenCode:deepseek-flash Assisted-by: Codex:gpt-6.1-sol Assisted-by: Claude Code:claude-opus-5-5 --- CHANGES.md | 11 + changes.d/fedify/on-request-finished.md | 10 + changes.d/testing/on-request-finished.md | 8 + docs/manual/inbox.md | 80 +++ docs/manual/opentelemetry.md | 15 + packages/fedify/src/federation/builder.ts | 10 + packages/fedify/src/federation/federation.ts | 14 + .../fedify/src/federation/handler.test.ts | 11 + packages/fedify/src/federation/handler.ts | 266 +++++++- .../src/federation/inbox-observation.ts | 123 ++++ .../src/federation/inbox-report.test.ts | 631 ++++++++++++++++++ .../fedify/src/federation/inbox-report.ts | 148 ++++ packages/fedify/src/federation/metrics.ts | 13 + packages/fedify/src/federation/middleware.ts | 512 +++++++++----- packages/fedify/src/federation/mod.ts | 1 + .../src/federation/portable-inbox.test.ts | 112 +++- .../sig/compound-proof-verification.test.ts | 24 + packages/fedify/src/sig/compound-proof.ts | 35 +- packages/fedify/src/sig/http.ts | 360 ++++++---- packages/fedify/src/sig/key.ts | 46 +- packages/fedify/src/sig/ld.ts | 85 ++- packages/fedify/src/sig/proof.ts | 279 +++++++- packages/fedify/src/sig/verification.test.ts | 402 +++++++++++ packages/fedify/src/sig/verification.ts | 278 ++++++++ packages/testing/src/mock.test.ts | 7 + packages/testing/src/mock.ts | 3 + 26 files changed, 3119 insertions(+), 365 deletions(-) create mode 100644 changes.d/fedify/on-request-finished.md create mode 100644 changes.d/testing/on-request-finished.md create mode 100644 packages/fedify/src/federation/inbox-observation.ts create mode 100644 packages/fedify/src/federation/inbox-report.test.ts create mode 100644 packages/fedify/src/federation/inbox-report.ts create mode 100644 packages/fedify/src/sig/verification.test.ts create mode 100644 packages/fedify/src/sig/verification.ts diff --git a/CHANGES.md b/CHANGES.md index 4c51ebc93..7083ad98e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -105,6 +105,12 @@ To be released. portable inboxes only through the first gateway, so upgrade them before the servers that enqueue deliveries. + - Added `onRequestFinished()` to observe every inbox delivery, including + rejected requests and preparation errors, with signature/proof checks, + actual verification keys, the final authentication decision, and the + processing outcome. The callback is awaited independently of trace + sampling, and its errors do not change delivery results. [[#1191], [#1201]] + - Added serving of [FEP-ef61] portable collections through the gateway endpoint, e.g., `GET /.well-known/apgateway/did:key:z6Mk.../users/alice/outbox`, by the @@ -873,7 +879,9 @@ To be released. [#1186]: https://github.com/fedify-dev/fedify/pull/1186 [#1188]: https://github.com/fedify-dev/fedify/pull/1188 [#1189]: https://github.com/fedify-dev/fedify/pull/1189 +[#1191]: https://github.com/fedify-dev/fedify/issues/1191 [#1198]: https://github.com/fedify-dev/fedify/pull/1198 +[#1201]: https://github.com/fedify-dev/fedify/pull/1201 ### @fedify/adonisjs @@ -1185,6 +1193,9 @@ To be released. dispatchers, and hashlink media responses from mock federations. Tests can now exercise these FEP-ef61 paths without a live gateway. [[#288], [#1161], [#1196]] + - Added support for registering `onRequestFinished()` on mock federations so + applications can reuse their inbox configuration in tests. + [[#1191], [#1201]] - Added `testKvStore()`, a conformance test suite for `KvStore` implementations, complementing `testMessageQueue()`. [[#1018], [#1020] by ChanHaeng Lee\] diff --git a/changes.d/fedify/on-request-finished.md b/changes.d/fedify/on-request-finished.md new file mode 100644 index 000000000..f486a4e42 --- /dev/null +++ b/changes.d/fedify/on-request-finished.md @@ -0,0 +1,10 @@ +--- +links: + '#1191': https://github.com/fedify-dev/fedify/issues/1191 + '#1201': https://github.com/fedify-dev/fedify/pull/1201 +--- + - Added `onRequestFinished()` to observe every inbox delivery, including + rejected requests and preparation errors, with signature/proof checks, + actual verification keys, the final authentication decision, and the + processing outcome. The callback is awaited independently of trace + sampling, and its errors do not change delivery results. [[#1191], [#1201]] diff --git a/changes.d/testing/on-request-finished.md b/changes.d/testing/on-request-finished.md new file mode 100644 index 000000000..7f658529d --- /dev/null +++ b/changes.d/testing/on-request-finished.md @@ -0,0 +1,8 @@ +--- +links: + '#1191': https://github.com/fedify-dev/fedify/issues/1191 + '#1201': https://github.com/fedify-dev/fedify/pull/1201 +--- + - Added support for registering `onRequestFinished()` on mock federations so + applications can reuse their inbox configuration in tests. + [[#1191], [#1201]] diff --git a/docs/manual/inbox.md b/docs/manual/inbox.md index ab88c0bcf..05e3e9a22 100644 --- a/docs/manual/inbox.md +++ b/docs/manual/inbox.md @@ -187,6 +187,86 @@ authenticated by their [Linked Data Signatures] or Object Integrity Proofs do not rely on the request's signatures, so they are not affected. +Observing inbox requests +------------------------ + +*This API is available since Fedify 2.4.0.* + +Register `onRequestFinished()` to record the result of each inbox delivery, +including rejected requests. The callback receives a `RequestContext` and an +`InboxRequestReport`. It runs once after processing and is awaited before +`Federation.fetch()` returns a response or rethrows an exception: + +~~~~ typescript twoslash +import type { Federation, InboxRequestReport } from "@fedify/fedify"; +declare const federation: Federation; +declare function saveReport(report: InboxRequestReport): Promise; +// ---cut-before--- +federation + .setInboxListeners("/users/{identifier}/inbox", "/inbox") + .onRequestFinished(async (ctx, report) => { + await saveReport(report); + }); +~~~~ + +`report.inbox` identifies the personal, shared, or portable inbox and its local +recipient identifier. Shared inboxes have a `null` recipient. The hook also +covers failures while preparing document loaders or resolving a portable +recipient. Inbox collection requests, unmatched routes, programmatic +`routeActivity()` calls, and queue workers do not invoke it. + +`report.payload` is either `unavailable` or `parsed`, whose `value` contains the +original JSON. A parsed JSON `null` is distinct from an unavailable body. +`report.activity` contains the `Activity` obtained by the existing processing +flow, if any. Observation does not parse the body again or fetch more objects. + +`report.attempts` retains each logical evaluation of HTTP Signatures, Linked +Data Signatures, or Object Integrity Proofs. An attempt's `checks` describes +the signatures/proofs evaluated, including the declared key ID and the actual +`CryptoKey` objects used. A stale cached key and its fresh replacement are +both retained in `triedKeys`. Refresh failure retains the key already tried. +A verified check's `key` is the successful entry in `triedKeys`, and a verified +attempt's `signatures` references its successful checks directly. Attempts +can repeat a mechanism when additional portable proof policy is evaluated. +The subject includes its ID and an RFC 6901 JSON Pointer when known; the root +pointer is `""`. + +Cryptographic checks and authentication are separate. For example, valid +proofs can leave an actor attribution uncovered, or a valid HTTP Signature can +fail the actor ownership or nonce check. Such checks remain `verified` in a +rejected attempt or request. Linked Data Signature failure followed by HTTP +success retains both attempts. Consult `report.authentication` for the final +`verified`, `rejected`, `skipped`, or `notDetermined` decision. `skipped` means +processing reached the signature bypass; an earlier parse or preparation +failure leaves authentication `notDetermined`. + +Key snapshots have `URL | null` IDs and either `ownerId` for a +`cryptographicKey` or `controllerId` for a `multikey`. These URL objects are +independent of the vocabulary key objects. The declared key ID is a +`string | null`, preserving its spelling even when invalid. Keys and their +owner/controller claims remain untrusted until the final authentication +checks accept them. A readonly report does not freeze its `Activity`, +`CryptoKey`, or error objects. + +`report.outcome` records a response status and disposition (`processed`, +`enqueued`, `duplicate`, `unhandled`, `rejected`, `customResponse`, or +`failed`), or the original exception and its processing stage. An `enqueued` +result reports producer acceptance, not later worker success. A custom `202` +returned by `onUnverifiedActivity()` remains unauthenticated. The report +contains no live `Response` to consume or alter. + +Errors from the observer are logged and swallowed, preserving the delivery's +original response or exception. The callback does not make database writes +and queue acceptance atomic. Calling `onRequestFinished()` again replaces the +previous callback; a federation built from a builder retains the callback +registered when it was built. Reports and key objects are never serialized +into queue messages. + +The hook runs independently of [OpenTelemetry sampling](./opentelemetry.md). +Use it when your application needs every delivery's result or actual public +keys for later inspection. + + Handling unverified activities ------------------------------ diff --git a/docs/manual/opentelemetry.md b/docs/manual/opentelemetry.md index 44eb80f45..7adff4ac8 100644 --- a/docs/manual/opentelemetry.md +++ b/docs/manual/opentelemetry.md @@ -546,6 +546,10 @@ Fedify records the following OpenTelemetry metrics: with no signature header are reported as `activitypub.signature.result=missing` and do not carry a `http_signatures.failure_reason`. + - `activitypub.verification.failure_reason` (Linked Data and Object + Integrity Proofs, on failure rows) is one of `invalidSignature`, + `keyFetchError`, `noSignature`, `signatureVerificationFailed`, + `uncoveredAttribution`, `missingOwner`, or `proofPolicy`. - `ld_signatures.type` (Linked Data only) is recorded only for the spec-supported `RsaSignature2017` type. - `object_integrity_proofs.cryptosuite` (Object Integrity Proofs @@ -557,6 +561,17 @@ Fedify records the following OpenTelemetry metrics: (`http_signatures.verify`, `ld_signatures.verify`, `object_integrity_proofs.verify`) for trace-level investigation. +The [inbox request observer](./inbox.md#observing-inbox-requests) exposes the +same verification evidence directly to application code, independently of +trace sampling. Actual public keys stay in the report and are not emitted as +telemetry attributes. Inbox spans record `activitypub.authentication.status` +and `activitypub.inbox.disposition`. A rejected final authentication decision +also sets the bounded `activitypub.verification.failure_reason` attribute. +Linked Data Signature and individual proof measurements use this common +failure attribute as well. A cryptographically valid proof still records +`verified` when a later attribution or portable proof policy rejects its +object; the rejection belongs to the object/inbox evaluation. + `activitypub.signature.key_fetch.duration` : `activitypub.signature.kind` is always present (same values as above). `activitypub.signature.key_fetch.result` is always present and is one diff --git a/packages/fedify/src/federation/builder.ts b/packages/fedify/src/federation/builder.ts index 0767c5dc8..0ee6670f5 100644 --- a/packages/fedify/src/federation/builder.ts +++ b/packages/fedify/src/federation/builder.ts @@ -1,3 +1,4 @@ +import type { InboxRequestFinishedHandler } from "./inbox-report.ts"; import { assertPath, type Path, @@ -178,6 +179,8 @@ export class FederationBuilderImpl >; inboxListeners?: ActivityListenerSet>; outboxListeners?: ActivityListenerSet>; + inboxRequestFinishedHandler?: InboxRequestFinishedHandler; + inboxErrorHandler?: InboxErrorHandler; outboxListenerErrorHandler?: OutboxListenerErrorHandler; outboxAuthorizePredicate?: AuthorizePredicate; @@ -281,6 +284,7 @@ export class FederationBuilderImpl : { ...this.featuredTagsCallbacks }; f.inboxListeners = this.inboxListeners?.clone(); f.outboxListeners = this.outboxListeners?.clone(); + f.inboxRequestFinishedHandler = this.inboxRequestFinishedHandler; f.inboxErrorHandler = this.inboxErrorHandler; f.outboxListenerErrorHandler = this.outboxListenerErrorHandler; f.outboxAuthorizePredicate = this.outboxAuthorizePredicate; @@ -1341,6 +1345,12 @@ export class FederationBuilderImpl this.inboxErrorHandler = handler; return setters; }, + onRequestFinished: ( + handler: InboxRequestFinishedHandler, + ): InboxListenerSetters => { + this.inboxRequestFinishedHandler = handler; + return setters; + }, onUnverifiedActivity: ( handler: UnverifiedActivityHandler, ): InboxListenerSetters => { diff --git a/packages/fedify/src/federation/federation.ts b/packages/fedify/src/federation/federation.ts index 9064e6a56..2ce6e3bb3 100644 --- a/packages/fedify/src/federation/federation.ts +++ b/packages/fedify/src/federation/federation.ts @@ -1,3 +1,4 @@ +import type { InboxRequestFinishedHandler } from "./inbox-report.ts"; import type { Activity, Actor, @@ -1713,6 +1714,19 @@ export interface InboxListenerSetters { handler: InboxErrorHandler, ): InboxListenerSetters; + /** + * Observes each configured inbox delivery once, before fetch finishes. + * The callback is awaited and its errors do not alter delivery processing. + * Calling this again replaces the previous callback. Built federations + * retain the callback registered at build time. + * @param handler The request completion observer. + * @returns This setter for chaining. + * @since 2.4.0 + */ + onRequestFinished( + handler: InboxRequestFinishedHandler, + ): InboxListenerSetters; + /** * Registers a callback for incoming activities whose HTTP signatures could * not be verified. diff --git a/packages/fedify/src/federation/handler.test.ts b/packages/fedify/src/federation/handler.test.ts index 47c44df3a..8beb8344d 100644 --- a/packages/fedify/src/federation/handler.test.ts +++ b/packages/fedify/src/federation/handler.test.ts @@ -1,3 +1,4 @@ +import type { InboxRequestReport } from "./inbox-report.ts"; import { createTestMeterProvider, createTestTracerProvider, @@ -5604,7 +5605,11 @@ test("handleInbox() nonce replay prevention", async () => { if (identifier !== "someone") return null; return new Person({ name: "Someone" }); }; + let report: InboxRequestReport | undefined; const response = await handleInbox(signedRequest, { + inboxRequestFinishedHandler: (_ctx, value) => { + report = value; + }, recipient: "someone", context, inboxContextFactory(_activity) { @@ -5632,6 +5637,12 @@ test("handleInbox() nonce replay prevention", async () => { }, }); assertEquals(response.status, 401); + assert(report != null); + assertEquals(report.authentication, { + status: "rejected", + reason: { type: "invalidNonce" }, + }); + assertEquals(report.attempts.at(-1)?.status, "verified"); // Should return a fresh challenge with a new nonce const acceptSig = response.headers.get("Accept-Signature"); assert(acceptSig != null, "Must emit fresh Accept-Signature challenge"); diff --git a/packages/fedify/src/federation/handler.ts b/packages/fedify/src/federation/handler.ts index e94d1ee02..3b503b66c 100644 --- a/packages/fedify/src/federation/handler.ts +++ b/packages/fedify/src/federation/handler.ts @@ -1,3 +1,10 @@ +import { InboxObservation } from "./inbox-observation.ts"; +import type { InboxRequestFinishedHandler } from "./inbox-report.ts"; +import { + observeAttempt, + snapshotKey, + verificationObservation, +} from "../sig/verification.ts"; import type { AcceptSignatureParameters } from "@fedify/fedify/sig"; import type { Recipient } from "@fedify/vocab"; import { @@ -1698,6 +1705,10 @@ export async function handleMediaUpload( * @template TContextData The context data to pass to the context. */ export interface InboxHandlerParameters { + /** Internal ingress-owned observation. */ + observation?: InboxObservation; + /** Observer for direct handleInbox callers. */ + inboxRequestFinishedHandler?: InboxRequestFinishedHandler; recipient: string | null; context: RequestContext; inboxContextFactory( @@ -1781,6 +1792,21 @@ export async function handleInbox( request: Request, options: InboxHandlerParameters, ): Promise { + if (options.observation == null) { + const observation = new InboxObservation({ + kind: options.portableInbox != null + ? "portable" + : options.recipient == null + ? "shared" + : "personal", + recipient: options.recipient, + }); + return await observation.run( + () => options.context, + options.inboxRequestFinishedHandler, + () => handleInbox(request, { ...options, observation }), + ); + } const tracerProvider = options.tracerProvider ?? trace.getTracerProvider(); const tracer = tracerProvider.getTracer(metadata.name, metadata.version); return await tracer.startActiveSpan( @@ -1796,9 +1822,11 @@ export async function handleInbox( try { return await handleInboxInternal(request, options, span); } catch (e) { + options.observation!.hasException = true; span.setStatus({ code: SpanStatusCode.ERROR, message: String(e) }); throw e; } finally { + options.observation!.project(span); span.end(); } }, @@ -1839,6 +1867,10 @@ async function handleInboxInternal( tracerProvider, portableInbox, } = parameters; + const observation = parameters.observation!; + const signatureObservation = { + [verificationObservation]: observation.verification, + }; const logger = getLogger(["fedify", "federation", "inbox"]); if (actorDispatcher == null) { logger.error("Actor dispatcher is not set.", { recipient }); @@ -1860,6 +1892,7 @@ async function handleInboxInternal( } } if (request.bodyUsed) { + observation.result = { disposition: "failed", reason: "bodyUnavailable" }; logger.error("Request body has already been read.", { recipient }); span.setStatus({ code: SpanStatusCode.ERROR, @@ -1870,6 +1903,7 @@ async function handleInboxInternal( headers: { "Content-Type": "text/plain; charset=utf-8" }, }); } else if (request.body?.locked) { + observation.result = { disposition: "failed", reason: "bodyUnavailable" }; logger.error("Request body is locked.", { recipient }); span.setStatus({ code: SpanStatusCode.ERROR, @@ -1880,6 +1914,8 @@ async function handleInboxInternal( headers: { "Content-Type": "text/plain; charset=utf-8" }, }); } + observation.stage = "parse"; + observation.result = { disposition: "rejected", reason: "invalidJson" }; let json: unknown; try { json = JSON.parse( @@ -1891,6 +1927,7 @@ async function handleInboxInternal( ); } catch (error) { if (error instanceof BodyTooLargeError) { + observation.result = { disposition: "rejected", reason: "bodyTooLarge" }; void request.body?.cancel(error).catch(() => {}); span.setStatus({ code: SpanStatusCode.ERROR, message: String(error) }); return new Response("Inbox body too large.", { status: 413 }); @@ -1913,6 +1950,12 @@ async function handleInboxInternal( headers: { "Content-Type": "text/plain; charset=utf-8" }, }); } + observation.payload = { + status: "parsed", + value: structuredClone(json) as import("./inbox-report.ts").InboxJsonValue, + }; + observation.result = { disposition: "rejected", reason: "invalidActivity" }; + observation.stage = "verify"; const keyCache = new KvKeyCache(kv, kvPrefixes.publicKey, { documentLoader: ctx.documentLoader, contextLoader: ctx.contextLoader, @@ -1944,6 +1987,7 @@ async function handleInboxInternal( code: SpanStatusCode.ERROR, message: `Failed to parse activity:\n${error}`, }); + observation.result = { disposition: "rejected", reason: "invalidActivity" }; return new Response("Invalid activity.", { status: 400, headers: { "Content-Type": "text/plain; charset=utf-8" }, @@ -1958,11 +2002,22 @@ async function handleInboxInternal( } catch (error) { if (isInvalidJsonLdError(error)) { logger.error("Failed to parse JSON-LD:\n{error}", { recipient, error }); + observation.result = { + disposition: "rejected", + reason: "invalidJsonLd", + }; return new Response("Invalid JSON-LD.", { status: 400, headers: { "Content-Type": "text/plain; charset=utf-8" }, }); } + observation.verification.attempts.push({ + mechanism: "linkedData", + subject: { id: null, pointer: "" }, + checks: [], + status: "error", + error, + }); if (!canAttemptAlternateAuthAfterLdSignatureFailure) throw error; // The presence of a proof block or HTTP signature headers is not enough // to discard a transient LDS normalization failure. Keep that error @@ -1981,6 +2036,7 @@ async function handleInboxInternal( compactedJsonWithoutSig = detachSignature(compactedJson); try { ldSigVerified = await verifyCompactJsonLd(compactedJson, { + ...signatureObservation, contextLoader: ctx.contextLoader, documentLoader: ctx.documentLoader, keyCache, @@ -2002,6 +2058,10 @@ async function handleInboxInternal( recipient, error, }); + observation.result = { + disposition: "rejected", + reason: "invalidJsonLd", + }; return new Response("Invalid JSON-LD.", { status: 400, headers: { "Content-Type": "text/plain; charset=utf-8" }, @@ -2030,6 +2090,10 @@ async function handleInboxInternal( recipient, error: parseError, }); + observation.result = { + disposition: "rejected", + reason: "invalidJsonLd", + }; return new Response("Invalid JSON-LD.", { status: 400, headers: { "Content-Type": "text/plain; charset=utf-8" }, @@ -2056,10 +2120,13 @@ async function handleInboxInternal( if (ldSigVerified) { logger.debug("Linked Data Signatures are verified.", { recipient, json }); try { - activity = await Activity.fromJsonLd(compactedJsonWithoutSig, { - ...ctx, - contextLoader: getNormalizationContextLoader(ctx.contextLoader), - }); + activity = observation.activity = await Activity.fromJsonLd( + compactedJsonWithoutSig, + { + ...ctx, + contextLoader: getNormalizationContextLoader(ctx.contextLoader), + }, + ); } catch (error) { if ( error instanceof RangeError && @@ -2080,6 +2147,7 @@ async function handleInboxInternal( // made by its DID does: try { proofVerified = await verifyObject(Activity, jsonWithoutSig, { + ...signatureObservation, contextLoader: wrapContextLoaderForJsonLd(ctx.contextLoader), documentLoader: ctx.documentLoader, keyCache, @@ -2102,6 +2170,7 @@ async function handleInboxInternal( ); try { activity = await verifyObject(Activity, jsonWithoutSig, { + ...signatureObservation, contextLoader: wrapContextLoaderForJsonLd(ctx.contextLoader), documentLoader: ctx.documentLoader, keyCache, @@ -2148,6 +2217,10 @@ async function handleInboxInternal( code: SpanStatusCode.ERROR, message: `Failed to parse activity:\n${error}`, }); + observation.result = { + disposition: "rejected", + reason: "invalidActivity", + }; return new Response("Invalid activity.", { status: 400, headers: { "Content-Type": "text/plain; charset=utf-8" }, @@ -2174,6 +2247,7 @@ async function handleInboxInternal( if (activity == null) { if (!skipSignatureVerification) { const verification = await verifyRequestDetailed(request, { + ...signatureObservation, contextLoader: ctx.contextLoader, documentLoader: ctx.documentLoader, timeWindow: signatureTimeWindow, @@ -2184,6 +2258,14 @@ async function handleInboxInternal( }); if (verification.verified === false) { if (deferredLdSignatureError != null) throw deferredLdSignatureError; + observation.authentication = { + status: "rejected", + reason: { type: "verificationFailed" }, + }; + observation.result = { + disposition: "rejected", + reason: "authentication", + }; const reason = verification.reason; const remoteHost = "keyId" in reason && reason.keyId != null ? getRemoteHost(reason.keyId) @@ -2210,7 +2292,10 @@ async function handleInboxInternal( ); } try { - activity = await Activity.fromJsonLd(jsonWithoutSig, ctx); + activity = observation.activity = await Activity.fromJsonLd( + jsonWithoutSig, + ctx, + ); } catch (error) { logger.error("Failed to parse activity:\n{error}", { recipient, @@ -2225,6 +2310,10 @@ async function handleInboxInternal( { error, activity: json, recipient }, ); } + observation.result = { + disposition: "rejected", + reason: "invalidActivity", + }; return new Response("Invalid activity.", { status: 400, headers: { "Content-Type": "text/plain; charset=utf-8" }, @@ -2267,6 +2356,11 @@ async function handleInboxInternal( reason, ); } catch (error) { + observation.result = { + disposition: "failed", + reason: "listenerError", + error, + }; logger.error( "An unexpected error occurred in unverified activity handler:\n" + "{error}", @@ -2286,7 +2380,10 @@ async function handleInboxInternal( kvPrefixes, ); } - if (response instanceof Response) return response; + if (response instanceof Response) { + observation.result = { disposition: "customResponse" }; + return response; + } return await getFailedSignatureResponse( inboxChallengePolicy, kv, @@ -2306,15 +2403,21 @@ async function handleInboxInternal( httpSigKey = verification.key; } try { - activity = await Activity.fromJsonLd(jsonWithoutSig, { - ...ctx, - contextLoader: wrapContextLoaderForJsonLd(ctx.contextLoader), - }); + activity = observation.activity = await Activity.fromJsonLd( + jsonWithoutSig, + { + ...ctx, + contextLoader: wrapContextLoaderForJsonLd(ctx.contextLoader), + }, + ); } catch (error) { if (!isPermanentActivityParseError(error)) throw error; return await respondInvalidActivity(error); } } + observation.activity = activity; + observation.stage = "policy"; + observation.result = { disposition: "rejected", reason: "authentication" }; if (activity.id != null) { span.setAttribute("activitypub.activity.id", activity.id.href); } @@ -2340,6 +2443,10 @@ async function handleInboxInternal( // This comes before the key ownership check, which cannot change the // outcome, so that such a request costs no further fetches: if (deferredLdSignatureError != null) throw deferredLdSignatureError; + observation.authentication = { + status: "rejected", + reason: { type: "proofPolicy", policy: "portableActor" }, + }; logger.error( "The activity {activityId} of the portable actor {actorId} is not " + "authenticated by a valid Object Integrity Proof.", @@ -2374,19 +2481,42 @@ async function handleInboxInternal( // ID. The ID of a portable activity, including a compatible identifier, // has to belong to the DID that signed it, which the proof policy checks // on the same document the proofs were verified for: - const rejection = await verifyPortableActivityId( - activity.id, - jsonWithoutSig, - { - contextLoader: wrapContextLoaderForJsonLd(ctx.contextLoader), - documentLoader: ctx.documentLoader, - keyCache, - meterProvider, - tracerProvider, + const rejection = await observeAttempt( + signatureObservation, + "objectIntegrity", + async (verification) => { + const rejection = await verifyPortableActivityId( + activity.id!, + jsonWithoutSig, + { + [verificationObservation]: verification, + contextLoader: wrapContextLoaderForJsonLd(ctx.contextLoader), + documentLoader: ctx.documentLoader, + keyCache, + meterProvider, + tracerProvider, + }, + ); + if (rejection != null) { + verification.attempt!.reason = { + type: "proofPolicy", + reason: rejection, + }; + } + return rejection; }, + (value) => value == null, ); if (rejection != null) { if (deferredLdSignatureError != null) throw deferredLdSignatureError; + observation.authentication = { + status: "rejected", + reason: { + type: "proofPolicy", + policy: "portableActivity", + detail: rejection, + }, + }; logger.error( "The portable activity {activityId} is not authenticated by an " + "Object Integrity Proof of its own DID: {reason}", @@ -2394,7 +2524,7 @@ async function handleInboxInternal( activity: json, recipient, activityId: activity.id.href, - reason: rejection, + reason: rejection.type, }, ); span.setStatus({ @@ -2416,6 +2546,14 @@ async function handleInboxInternal( httpSigKey != null && !await doesActorOwnKey(activity, httpSigKey, ctx) ) { if (deferredLdSignatureError != null) throw deferredLdSignatureError; + observation.authentication = { + status: "rejected", + reason: { + type: "actorKeyMismatch", + key: snapshotKey(httpSigKey), + actorIds: activity.actorIds.map((id) => new URL(id.href)), + }, + }; getFederationMetrics(parameters.meterProvider) .recordSignatureVerificationFailure( "actorKeyMismatch", @@ -2451,17 +2589,46 @@ async function handleInboxInternal( INBOX_COMPOUND_PROOF_LIMITS, ); if (compoundApplicability !== "absent") { - const compoundProof = await verifyCompoundPortableObjectProofs( - compoundJson, - INBOX_COMPOUND_PROOF_LIMITS, - { - documentLoader: ctx.documentLoader, - keyCache, - meterProvider, - tracerProvider, + const compoundProof = await observeAttempt( + signatureObservation, + "objectIntegrity", + async (verification) => { + const result = await verifyCompoundPortableObjectProofs( + compoundJson, + INBOX_COMPOUND_PROOF_LIMITS, + { + [verificationObservation]: verification, + documentLoader: ctx.documentLoader, + keyCache, + meterProvider, + tracerProvider, + }, + ); + if (result.status === "unsupported") { + verification.attempt!.reason = { + type: "proofPolicy", + reason: result.reason, + }; + } else if (!result.verified) { + const failed = result.portableObjects.find((object) => + !object.verified + ); + verification.attempt!.reason = { + type: "proofPolicy", + reason: failed?.verified === false + ? failed.reason + : { type: "invalidProof" }, + }; + } + return result; }, + (result) => result.status === "ok" && result.verified, ); if (compoundProof.status !== "ok" || !compoundProof.verified) { + observation.authentication = { + status: "rejected", + reason: { type: "proofPolicy", policy: "compound" }, + }; logger.error( "Failed to verify compound portable Object Integrity Proofs.", { @@ -2496,6 +2663,10 @@ async function handleInboxInternal( pendingNonceLabel, ); if (!nonceValid) { + observation.authentication = { + status: "rejected", + reason: { type: "invalidNonce" }, + }; getFederationMetrics(parameters.meterProvider) .recordSignatureVerificationFailure( "invalidNonce", @@ -2512,6 +2683,17 @@ async function handleInboxInternal( ); } } + observation.authentication = skipSignatureVerification + ? { status: "skipped" } + : { + status: "verified", + attempts: observation.verification.attempts.filter(( + attempt, + ): attempt is Extract => + attempt.status === "verified" + ), + }; + observation.stage = "dispatch"; const routeResult = await routeActivity({ context: ctx, // Direct handleInbox() consumers may later forward the payload from the @@ -2544,7 +2726,14 @@ async function handleInboxInternal( [rawInboxContextFactorySymbol]?: typeof inboxContextFactory; })[rawInboxContextFactorySymbol] : undefined, - inboxErrorHandler, + inboxErrorHandler: async (context, error) => { + observation.result = { + disposition: "failed", + reason: "listenerError", + error, + }; + await inboxErrorHandler?.(context, error); + }, kv, kvPrefixes, queue, @@ -2618,6 +2807,7 @@ async function handleInboxInternal( } } if (routeResult === "alreadyProcessed") { + observation.result = { disposition: "duplicate" }; return new Response( `Activity <${activity.id}> has already been processed.`, { @@ -2626,16 +2816,19 @@ async function handleInboxInternal( }, ); } else if (routeResult === "missingActor") { + observation.result = { disposition: "rejected", reason: "missingActor" }; return new Response("Missing actor.", { status: 400, headers: { "Content-Type": "text/plain; charset=utf-8" }, }); } else if (routeResult === "enqueued") { + observation.result = { disposition: "enqueued" }; return new Response("Activity is enqueued.", { status: 202, headers: { "Content-Type": "text/plain; charset=utf-8" }, }); } else if (routeResult === "unsupportedActivity") { + observation.result = { disposition: "unhandled" }; return new Response("", { status: 202, headers: { "Content-Type": "text/plain; charset=utf-8" }, @@ -2646,6 +2839,7 @@ async function handleInboxInternal( headers: { "Content-Type": "text/plain; charset=utf-8" }, }); } else { + observation.result = { disposition: "processed" }; return new Response("", { status: 202, headers: { "Content-Type": "text/plain; charset=utf-8" }, @@ -3811,9 +4005,11 @@ async function verifyPortableActivityId( activityId: URL, jsonLd: unknown, options: Parameters[1], -): Promise { +): Promise< + import("../sig/verification.ts").InboxProofPolicyFailureReason | null +> { const expectedId = getCanonicalPortableId(activityId); - if (expectedId == null) return "malformed portable ID"; + if (expectedId == null) return { type: "invalidObjectId" }; let verification: Awaited< ReturnType >; @@ -3821,20 +4017,20 @@ async function verifyPortableActivityId( verification = await verifyPortableObjectProofWithRoot(jsonLd, options); } catch (error) { if (error instanceof InvalidPortableObjectIdError) { - return "malformed portable ID"; + return { type: "invalidObjectId" }; } if (!isPermanentActivityParseError(error)) throw error; - return "malformed document"; + return { type: "invalidDocument" }; } const { result, root } = verification; - if (!result.verified) return result.reason.type; + if (!result.verified) return result.reason; // The proof policy has already validated the ID of a verified document: const rootId = root?.["@id"]; if ( typeof rootId !== "string" || getCanonicalPortableId(parseIri(rootId)) !== expectedId ) { - return "the verified document has another ID"; + return { type: "subjectMismatch" }; } return null; } diff --git a/packages/fedify/src/federation/inbox-observation.ts b/packages/fedify/src/federation/inbox-observation.ts new file mode 100644 index 000000000..316f1763d --- /dev/null +++ b/packages/fedify/src/federation/inbox-observation.ts @@ -0,0 +1,123 @@ +import { Activity } from "@fedify/vocab"; +import { getLogger } from "@logtape/logtape"; +import type { Span } from "@opentelemetry/api"; +import type { RequestContext } from "./context.ts"; +import type { + InboxAuthentication, + InboxRequestFinishedHandler, + InboxRequestOutcome, + InboxRequestReport, +} from "./inbox-report.ts"; +import type { VerificationObservation } from "../sig/verification.ts"; + +/** Internal state owned by the ingress boundary, never serialized into queues. */ +export class InboxObservation { + payload: InboxRequestReport["payload"] = { status: "unavailable" }; + activity: Activity | null = null; + authentication: InboxAuthentication = { status: "notDetermined" }; + hasException = false; + stage: Extract["stage"] = + "prepare"; + result: + | Omit< + Extract, + "type" | "status" + > + | Omit< + Extract, + "type" | "status" + > + | { + disposition: + | "processed" + | "enqueued" + | "duplicate" + | "unhandled" + | "customResponse"; + } = { disposition: "rejected", reason: "recipientNotFound" }; + readonly verification: VerificationObservation = { + attempts: [], + subject: { id: null, pointer: "" }, + parsedObject: (object) => { + if (object instanceof Activity) { + this.activity = object; + this.verification.subject!.id = object.id == null + ? null + : new URL(object.id.href); + } + }, + }; + constructor(readonly inbox: InboxRequestReport["inbox"]) {} + + async run( + getContext: () => RequestContext, + handler: InboxRequestFinishedHandler | undefined, + operation: () => Promise, + span?: Span, + ): Promise { + let response: Response | undefined; + let outcome: InboxRequestOutcome; + let threw = false; + let originalError: unknown; + try { + response = await operation(); + outcome = { type: "response", status: response.status, ...this.result }; + } catch (error) { + threw = true; + this.hasException = true; + originalError = error; + outcome = { type: "exception", stage: this.stage, error }; + } + if (span != null) this.project(span, outcome); + await this.finish(getContext(), handler, outcome); + if (threw) throw originalError; + return response!; + } + + project(span: Span, outcome?: InboxRequestOutcome): void { + span.setAttribute( + "activitypub.authentication.status", + this.authentication.status, + ); + if (this.authentication.status === "rejected") { + span.setAttribute( + "activitypub.verification.failure_reason", + this.authentication.reason.type, + ); + } + span.setAttribute( + "activitypub.inbox.disposition", + outcome?.type === "exception" || this.hasException + ? "exception" + : this.result.disposition, + ); + } + + async finish( + context: RequestContext, + handler: InboxRequestFinishedHandler | undefined, + outcome: InboxRequestOutcome, + ): Promise { + if (handler == null) return; + const report: InboxRequestReport = { + inbox: this.inbox, + payload: this.payload, + activity: this.activity, + attempts: this.verification.attempts, + authentication: this.authentication, + outcome, + }; + try { + await handler(context, report); + } catch (error) { + try { + getLogger(["fedify", "federation", "inbox"]).error( + "An unexpected error occurred in inbox request finished handler:\n{error}", + { error }, + ); + } catch { + /* A logging sink must not replace the delivery result either. */ + } + } + } +} diff --git a/packages/fedify/src/federation/inbox-report.test.ts b/packages/fedify/src/federation/inbox-report.test.ts new file mode 100644 index 000000000..3dc3ac639 --- /dev/null +++ b/packages/fedify/src/federation/inbox-report.test.ts @@ -0,0 +1,631 @@ +import { mockDocumentLoader, test } from "@fedify/fixture"; +import { Create, Person } from "@fedify/vocab"; +import { exportDidKey, parseIri } from "@fedify/vocab-runtime"; +import { deepStrictEqual, ok, rejects, strictEqual } from "node:assert/strict"; +import { createFederationBuilder } from "./builder.ts"; +import type { InboxRequestReport } from "./inbox-report.ts"; +import { MemoryKvStore } from "./kv.ts"; +import { createFederation } from "./middleware.ts"; +import { signRequest } from "../sig/http.ts"; +import { signJsonLd } from "../sig/ld.ts"; +import { signObject } from "../sig/proof.ts"; +import { + ed25519Multikey, + ed25519PrivateKey, + rsaPrivateKey2, + rsaPrivateKey3, + rsaPublicKey2, + rsaPublicKey3, +} from "../testing/keys.ts"; + +const loaders = { + documentLoader: mockDocumentLoader, + contextLoader: mockDocumentLoader, +}; +function setup(skipSignatureVerification = false) { + const reports: InboxRequestReport[] = []; + const federation = createFederation({ + kv: new MemoryKvStore(), + skipSignatureVerification, + documentLoaderFactory: () => mockDocumentLoader, + contextLoaderFactory: () => mockDocumentLoader, + }); + federation.setActorDispatcher( + "/users/{identifier}", + (_ctx, id) => id === "missing" ? null : new Person({}), + ).setKeyPairsDispatcher(() => []); + const setters = federation.setInboxListeners( + "/users/{identifier}/inbox", + "/inbox", + ).onRequestFinished((_ctx, report) => { + reports.push(report); + }); + return { federation, setters, reports }; +} +async function payload( + id = "https://example.com/create", + actor = "https://example.com/person2", +) { + return await new Create({ id: new URL(id), actor: new URL(actor) }).toJsonLd( + loaders, + ); +} +function request(body: unknown, path = "/inbox") { + return new Request(`https://example.com${path}`, { + method: "POST", + body: JSON.stringify(body), + headers: { "Content-Type": "application/activity+json" }, + }); +} + +test("onRequestFinished classifies early rejection, JSON null, and excluded routes", async () => { + const { federation, reports } = setup(true); + strictEqual( + (await federation.fetch(request({}, "/users/missing/inbox"), { + contextData: undefined, + })).status, + 404, + ); + deepStrictEqual(reports[0].inbox, { kind: "personal", recipient: "missing" }); + deepStrictEqual(reports[0].payload, { status: "unavailable" }); + deepStrictEqual(reports[0].authentication, { status: "notDetermined" }); + deepStrictEqual(reports[0].outcome, { + type: "response", + status: 404, + disposition: "rejected", + reason: "recipientNotFound", + }); + strictEqual( + (await federation.fetch(request(null), { contextData: undefined })).status, + 400, + ); + deepStrictEqual(reports[1].payload, { status: "parsed", value: null }); + deepStrictEqual(reports[1].authentication, { status: "notDetermined" }); + await federation.fetch(new Request("https://example.com/users/alice/inbox"), { + contextData: undefined, + }); + await federation.fetch(request({}, "/unmatched"), { contextData: undefined }); + strictEqual(reports.length, 2); + await federation.fetch( + new Request("https://example.com/inbox", { method: "POST", body: "{" }), + { contextData: undefined }, + ); + deepStrictEqual(reports[2].outcome, { + type: "response", + status: 400, + disposition: "rejected", + reason: "invalidJson", + }); +}); + +test("onRequestFinished leaves deferred policy errors undetermined", async () => { + const did = await exportDidKey(ed25519Multikey.publicKey!); + const keyId = parseIri(`${did}#${did.substring("did:key:".length)}`); + const otherPair = await crypto.subtle.generateKey("Ed25519", true, [ + "sign", + "verify", + ]) as CryptoKeyPair; + const otherDid = await exportDidKey(otherPair.publicKey); + for (const withProof of [false, true]) { + const contextUrl = `https://example.com/context/deferred-${withProof}`; + const remote = { + contextUrl: null, + documentUrl: contextUrl, + document: { "@context": { ext: "https://example.com/ext" } }, + }; + const contextLoader = (url: string) => + url === contextUrl ? Promise.resolve(remote) : mockDocumentLoader(url); + const activity = new Create({ + id: parseIri( + `ap+ef61://${ + withProof ? otherDid : did + }/activities/deferred-${withProof}`, + ), + actor: parseIri(`ap+ef61://${did}/users/bob`), + }); + const context = [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/data-integrity/v1", + contextUrl, + ]; + const body = withProof + ? await (await signObject(activity, ed25519PrivateKey, keyId, { + context, + contextLoader, + })).toJsonLd({ format: "compact", context, contextLoader }) + : await activity.toJsonLd({ format: "compact", context, contextLoader }); + (body as Record).signature = { + type: "RsaSignature2017", + creator: rsaPublicKey3.id!.href, + created: "2024-01-01T00:00:00Z", + signatureValue: "bogus", + }; + let failOnce = true; + const reports: InboxRequestReport[] = []; + const federation = createFederation({ + kv: new MemoryKvStore(), + documentLoaderFactory: () => mockDocumentLoader, + contextLoaderFactory: () => async (url) => { + if (url === contextUrl && failOnce) { + failOnce = false; + throw new Error("Temporary context outage"); + } + return await contextLoader(url); + }, + }); + federation.setActorDispatcher("/users/{identifier}", () => new Person({})) + .setKeyPairsDispatcher(() => []); + federation.setInboxListeners("/users/{identifier}/inbox", "/inbox") + .on(Create, () => {}) + .onRequestFinished((_ctx, report) => { + reports.push(report); + }); + const signed = await signRequest( + request(body), + rsaPrivateKey3, + rsaPublicKey3.id!, + ); + await rejects( + federation.fetch(signed, { contextData: undefined }), + (error) => { + strictEqual(reports.length, 1); + deepStrictEqual(reports[0].authentication, { status: "notDetermined" }); + ok(reports[0].outcome.type === "exception"); + strictEqual(reports[0].outcome.stage, "policy"); + strictEqual(reports[0].outcome.error, error); + return true; + }, + ); + strictEqual( + reports[0].attempts.some((attempt) => + attempt.mechanism === "objectIntegrity" && attempt.status === "verified" + ), + withProof, + ); + } +}); + +test("onRequestFinished awaits once and isolates observer failures", async () => { + const { federation, setters } = setup(true); + setters.on(Create, () => {}); + let calls = 0; + let release!: () => void; + const gate = new Promise((resolve) => { + release = resolve; + }); + let entered!: () => void; + const started = new Promise((resolve) => { + entered = resolve; + }); + setters.onRequestFinished(async (_ctx, report) => { + calls++; + deepStrictEqual(report.authentication, { status: "skipped" }); + strictEqual( + report.outcome.type === "response" && report.outcome.disposition, + "processed", + ); + entered(); + await gate; + throw new Error("observer failed"); + }); + let finished = false; + const response = federation.fetch(request(await payload()), { + contextData: undefined, + }).then((response) => { + finished = true; + return response; + }); + await started; + strictEqual(finished, false); + release(); + strictEqual((await response).status, 202); + strictEqual(calls, 1); +}); + +test("onRequestFinished preserves preparation exceptions and callback replacement", async () => { + const { federation, setters, reports } = setup(); + const error = new Error("preparation failed"); + setters.setSharedKeyDispatcher(() => { + throw error; + }); + setters.onRequestFinished((_ctx, report) => { + reports.push(report); + throw new Error("secondary failure"); + }); + await rejects( + federation.fetch(request(await payload()), { contextData: undefined }), + (value) => value === error, + ); + strictEqual(reports.length, 1); + deepStrictEqual(reports[0].outcome, { + type: "exception", + stage: "prepare", + error, + }); + deepStrictEqual(reports[0].authentication, { status: "notDetermined" }); +}); + +test("onRequestFinished distinguishes custom responses from authentication", async () => { + const { federation, setters, reports } = setup(); + setters.onUnverifiedActivity(() => new Response(null, { status: 202 })); + const body = await payload(); + strictEqual( + (await federation.fetch(request(body), { contextData: undefined })).status, + 202, + ); + deepStrictEqual(reports[0].authentication, { + status: "rejected", + reason: { type: "verificationFailed" }, + }); + deepStrictEqual(reports[0].outcome, { + type: "response", + status: 202, + disposition: "customResponse", + }); + strictEqual(reports[0].attempts.at(-1)?.mechanism, "http"); + setters.onUnverifiedActivity(() => {}); + strictEqual( + (await federation.fetch(request(body), { contextData: undefined })).status, + 401, + ); + strictEqual( + reports[1].outcome.type === "response" && reports[1].outcome.disposition, + "rejected", + ); +}); + +test("onRequestFinished retains HTTP keys and separates ownership rejection", async () => { + const { federation, setters, reports } = setup(); + setters.on(Create, () => {}); + const body = await payload(); + const signed = await signRequest( + request(body), + rsaPrivateKey3, + new URL("https://example.com/person2#key3"), + ); + strictEqual( + (await federation.fetch(signed, { contextData: undefined })).status, + 202, + ); + const report = reports[0]; + strictEqual(report.authentication.status, "verified"); + const attempt = report.attempts.find((attempt) => + attempt.mechanism === "http" + ); + ok(attempt?.status === "verified"); + strictEqual(attempt.subject.id?.href, "https://example.com/create"); + const check = attempt.checks[0]; + ok(check.status === "verified" && check.key.type === "cryptographicKey"); + strictEqual(check.key.publicKey.algorithm.name, "RSASSA-PKCS1-v1_5"); + strictEqual(check.key.ownerId?.href, "https://example.com/person2"); + strictEqual(check.key, check.triedKeys.at(-1)); + strictEqual(attempt.signatures[0], check); + strictEqual(report.authentication.attempts[0], attempt); + // Same request ID produces a duplicate without losing authentication. + await federation.fetch(signed, { contextData: undefined }); + deepStrictEqual(reports[1].outcome, { + type: "response", + status: 202, + disposition: "duplicate", + }); + const mismatched = await signRequest( + request( + await payload("https://example.com/other", "https://example.com/person"), + ), + rsaPrivateKey3, + new URL("https://example.com/person2#key3"), + ); + strictEqual( + (await federation.fetch(mismatched, { contextData: undefined })).status, + 401, + ); + strictEqual(reports[2].authentication.status, "rejected"); + ok(reports[2].authentication.status === "rejected"); + strictEqual(reports[2].authentication.reason.type, "actorKeyMismatch"); + strictEqual(reports[2].attempts.at(-1)?.status, "verified"); +}); + +test("onRequestFinished retains LDS crypto success before HTTP fallback", async () => { + const { federation, reports } = setup(); + const body = await signJsonLd( + await payload("https://example.com/lds", "https://example.com/person"), + rsaPrivateKey3, + new URL("https://example.com/person2#key3"), + loaders, + ); + const signed = await signRequest( + request(body), + rsaPrivateKey2, + new URL("https://example.com/key2"), + ); + strictEqual( + (await federation.fetch(signed, { contextData: undefined })).status, + 202, + ); + const ld = reports[0].attempts.find((attempt) => + attempt.mechanism === "linkedData" + ); + ok(ld?.status === "rejected"); + strictEqual(ld.reason.type, "uncoveredAttribution"); + strictEqual(ld.checks[0].status, "verified"); + strictEqual(reports[0].authentication.status, "verified"); +}); + +test("onRequestFinished keeps valid OIP checks when attributions are uncovered", async () => { + const { federation, reports } = setup(); + const activity = new Create({ + id: new URL("https://example.com/proof"), + actor: new URL("https://example.com/person"), + }); + const signed = await signObject( + activity, + ed25519PrivateKey, + ed25519Multikey.id!, + loaders, + ); + strictEqual( + (await federation.fetch(request(await signed.toJsonLd(loaders)), { + contextData: undefined, + })).status, + 401, + ); + const proof = reports[0].attempts.find((attempt) => + attempt.mechanism === "objectIntegrity" + ); + ok(proof?.status === "rejected"); + strictEqual(proof.reason.type, "uncoveredAttribution"); + const check = proof.checks[0]; + ok(check.status === "verified" && check.key.type === "multikey"); + strictEqual(check.key.controllerId?.href, "https://example.com/person2"); + strictEqual(reports[0].activity?.id?.href, activity.id?.href); +}); + +test("onRequestFinished reports listener failures with original values", async () => { + const { federation, setters, reports } = setup(true); + const error = new Error("listener failed"); + setters.on(Create, () => { + throw error; + }); + strictEqual( + (await federation.fetch(request(await payload()), { + contextData: undefined, + })).status, + 500, + ); + deepStrictEqual(reports[0].outcome, { + type: "response", + status: 500, + disposition: "failed", + reason: "listenerError", + error, + }); +}); + +test("onRequestFinished builder snapshots callbacks", async () => { + const builder = createFederationBuilder(); + builder.setActorDispatcher("/users/{identifier}", () => new Person({})); + const reports: InboxRequestReport[] = []; + const setters = builder.setInboxListeners( + "/users/{identifier}/inbox", + "/inbox", + ).onRequestFinished((_ctx, report) => { + reports.push(report); + }); + const federation = await builder.build({ + kv: new MemoryKvStore(), + skipSignatureVerification: true, + documentLoaderFactory: () => mockDocumentLoader, + contextLoaderFactory: () => mockDocumentLoader, + }); + setters.onRequestFinished(() => { + throw new Error("new callback must not run"); + }); + await federation.fetch(request(await payload()), { contextData: undefined }); + strictEqual(reports.length, 1); +}); + +// The imported key objects stay intact when observers mutate their URL copies. +test("onRequestFinished key snapshots do not alias vocabulary metadata", async () => { + const { snapshotKey } = await import("../sig/verification.ts"); + const snapshot = snapshotKey(rsaPublicKey2); + snapshot.id!.pathname = "/changed"; + strictEqual(rsaPublicKey2.id!.href, "https://example.com/key2"); + const other = snapshotKey(rsaPublicKey3); + strictEqual(other.publicKey, rsaPublicKey3.publicKey); +}); + +test("onRequestFinished reports enqueue acceptance without adding queue fields", async () => { + const messages: unknown[] = []; + const reports: InboxRequestReport[] = []; + const federation = createFederation({ + kv: new MemoryKvStore(), + skipSignatureVerification: true, + manuallyStartQueue: true, + queue: { + inbox: { + enqueue: (message) => { + messages.push(message); + return Promise.resolve(); + }, + listen: () => Promise.resolve(), + }, + }, + documentLoaderFactory: () => mockDocumentLoader, + contextLoaderFactory: () => mockDocumentLoader, + }); + federation.setActorDispatcher("/users/{identifier}", () => new Person({})); + federation.setInboxListeners("/users/{identifier}/inbox", "/inbox") + .onRequestFinished((_ctx, report) => { + reports.push(report); + }); + strictEqual( + (await federation.fetch(request(await payload()), { + contextData: undefined, + })).status, + 202, + ); + deepStrictEqual(reports[0].outcome, { + type: "response", + status: 202, + disposition: "enqueued", + }); + strictEqual(messages.length, 1); + ok(!("report" in (messages[0] as Record))); + ok(!("attempts" in (messages[0] as Record))); +}); + +test("onRequestFinished preserves a non-Error value thrown during enqueue", async () => { + const reports: InboxRequestReport[] = []; + const federation = createFederation({ + kv: new MemoryKvStore(), + skipSignatureVerification: true, + manuallyStartQueue: true, + queue: { + inbox: { + enqueue: () => Promise.reject(undefined), + listen: () => Promise.resolve(), + }, + }, + documentLoaderFactory: () => mockDocumentLoader, + contextLoaderFactory: () => mockDocumentLoader, + }); + federation.setActorDispatcher("/users/{identifier}", () => new Person({})); + federation.setInboxListeners("/users/{identifier}/inbox", "/inbox") + .onRequestFinished((_ctx, report) => { + reports.push(report); + throw new Error("observer failure"); + }); + let threw = false; + try { + await federation.fetch(request(await payload()), { + contextData: undefined, + }); + } catch (error) { + threw = true; + strictEqual(error, undefined); + } + strictEqual(threw, true); + strictEqual(reports.length, 1); + deepStrictEqual(reports[0].outcome, { + type: "exception", + stage: "dispatch", + error: undefined, + }); +}); + +test("onRequestFinished runs with tracing disabled", async () => { + const { AlwaysOffSampler, BasicTracerProvider } = await import( + "@opentelemetry/sdk-trace-base" + ); + const provider = new BasicTracerProvider({ sampler: new AlwaysOffSampler() }); + const reports: InboxRequestReport[] = []; + const federation = createFederation({ + kv: new MemoryKvStore(), + tracerProvider: provider, + skipSignatureVerification: true, + documentLoaderFactory: () => mockDocumentLoader, + contextLoaderFactory: () => mockDocumentLoader, + }); + federation.setActorDispatcher("/users/{identifier}", () => new Person({})); + federation.setInboxListeners("/users/{identifier}/inbox", "/inbox") + .onRequestFinished((_ctx, report) => { + reports.push(report); + }); + await federation.fetch(request(await payload()), { contextData: undefined }); + strictEqual(reports.length, 1); + await provider.shutdown(); +}); + +test("onRequestFinished preserves non-POST shared inbox behavior without reports", async () => { + const { federation, reports } = setup(true); + strictEqual( + (await federation.fetch( + new Request("https://example.com/inbox", { + headers: { Accept: "application/activity+json" }, + }), + { contextData: undefined }, + )).status, + 400, + ); + strictEqual(reports.length, 0); + strictEqual( + (await federation.fetch( + new Request("https://example.com/inbox", { + method: "PUT", + body: JSON.stringify(await payload()), + headers: { Accept: "application/activity+json" }, + }), + { contextData: undefined }, + )).status, + 202, + ); + strictEqual(reports.length, 0); +}); + +test("onRequestFinished covers errors constructing the initial request context", async () => { + const reports: InboxRequestReport[] = []; + const error = new Error("loader factory failed"); + const federation = createFederation({ + kv: new MemoryKvStore(), + documentLoaderFactory: () => { + throw error; + }, + contextLoaderFactory: () => mockDocumentLoader, + }); + federation.setActorDispatcher("/users/{identifier}", () => new Person({})); + federation.setInboxListeners("/users/{identifier}/inbox", "/inbox") + .onRequestFinished((ctx, report) => { + strictEqual(ctx.data, "data"); + strictEqual(ctx.request.url, "https://example.com/inbox"); + reports.push(report); + }); + await rejects( + federation.fetch(request({}), { contextData: "data" }), + (value) => value === error, + ); + strictEqual(reports.length, 1); + deepStrictEqual(reports[0].outcome, { + type: "exception", + stage: "prepare", + error, + }); +}); + +test("onRequestFinished observes the final response decoration result", async () => { + const { federation, setters, reports } = setup(); + const redirect = Response.redirect("https://example.com/redirect", 302); + // Bun permits mutations here; Deno and Node.js use immutable headers. + let immutable = false; + try { + redirect.headers.set("X-Header-Probe", "probe"); + } catch { + immutable = true; + } + setters.onUnverifiedActivity(() => redirect); + const delivery = request(await payload()); + delivery.headers.set("Accept", "application/activity+json"); + let thrown: unknown; + let response: Response | undefined; + try { + response = await federation.fetch(delivery, { contextData: undefined }); + } catch (error) { + thrown = error; + } + strictEqual(reports.length, 1); + if (immutable) { + ok(thrown instanceof TypeError); + deepStrictEqual(reports[0].outcome, { + type: "exception", + stage: "respond", + error: thrown, + }); + } else { + strictEqual(thrown, undefined); + strictEqual(response?.status, 302); + deepStrictEqual(reports[0].outcome, { + type: "response", + status: 302, + disposition: "customResponse", + }); + } +}); diff --git a/packages/fedify/src/federation/inbox-report.ts b/packages/fedify/src/federation/inbox-report.ts new file mode 100644 index 000000000..7f1865f38 --- /dev/null +++ b/packages/fedify/src/federation/inbox-report.ts @@ -0,0 +1,148 @@ +import type { Activity } from "@fedify/vocab"; +import type { RequestContext } from "./context.ts"; +import type { + InboxVerificationAttempt, + InboxVerificationKey, +} from "../sig/verification.ts"; +export type { + InboxProofPolicyFailureReason, + InboxSignatureCheck, + InboxSignatureFailureReason, + InboxSignatureIdentity, + InboxVerificationAttempt, + InboxVerificationFailureReason, + InboxVerificationKey, +} from "../sig/verification.ts"; + +/** + * A JSON value retained from the incoming request. + * @since 2.4.0 + */ +export type InboxJsonValue = + | null + | boolean + | number + | string + | readonly InboxJsonValue[] + | { readonly [key: string]: InboxJsonValue }; + +/** + * The final inbox authentication decision. + * @since 2.4.0 + */ +export type InboxAuthentication = + | { + readonly status: "verified"; + /** Direct references to the attempts that authenticated this delivery. */ + readonly attempts: readonly Extract< + InboxVerificationAttempt, + { status: "verified" } + >[]; + } + | { + readonly status: "rejected"; + readonly reason: + | { readonly type: "verificationFailed" } + | { + readonly type: "actorKeyMismatch"; + readonly key: InboxVerificationKey; + readonly actorIds: readonly URL[]; + } + | { + readonly type: "proofPolicy"; + readonly policy: "portableActor" | "portableActivity" | "compound"; + readonly detail?: + import("../sig/verification.ts").InboxProofPolicyFailureReason; + } + | { readonly type: "invalidNonce" }; + } + | { readonly status: "skipped" } + | { readonly status: "notDetermined" }; + +/** + * How an inbox request finished. + * @since 2.4.0 + */ +export type InboxRequestOutcome = + | { + readonly type: "response"; + readonly status: number; + readonly disposition: + | "processed" + | "enqueued" + | "duplicate" + | "unhandled" + | "customResponse"; + } + | { + readonly type: "response"; + readonly status: number; + readonly disposition: "rejected"; + readonly reason: + | "recipientNotFound" + | "invalidJson" + | "invalidJsonLd" + | "invalidActivity" + | "bodyTooLarge" + | "missingActor" + | "authentication"; + } + | { + readonly type: "response"; + readonly status: number; + readonly disposition: "failed"; + readonly reason: "bodyUnavailable" | "enqueueError" | "listenerError"; + readonly error?: unknown; + } + | { + readonly type: "exception"; + readonly stage: + | "prepare" + | "parse" + | "verify" + | "policy" + | "dispatch" + | "respond"; + /** The original thrown value, including null/undefined. */ + readonly error: unknown; + }; + +/** + * Observations of a single inbox delivery request. + * @since 2.4.0 + */ +export interface InboxRequestReport { + /** The delivery route, including a portable gateway route. */ + readonly inbox: { + readonly kind: "personal" | "shared" | "portable"; + readonly recipient: string | null; + }; + /** Unavailable differs from a successfully parsed JSON null. */ + readonly payload: { readonly status: "unavailable" } | { + readonly status: "parsed"; + readonly value: InboxJsonValue; + }; + /** The Activity obtained by the normal processing flow, if any. */ + readonly activity: Activity | null; + /** Logical evaluations, including unsuccessful fallback paths. */ + readonly attempts: readonly InboxVerificationAttempt[]; + /** Cryptographic success alone does not imply this decision is verified. */ + readonly authentication: InboxAuthentication; + /** Response status snapshot or the original exception. */ + readonly outcome: InboxRequestOutcome; +} + +/** + * Observes an inbox delivery after processing, before fetch resolves/rethrows. + * The callback is awaited. Its errors are logged and swallowed, preserving + * the original response/exception. The last registered callback replaces the + * previous one. It excludes inbox collection GETs, unmatched routes, + * programmatic routing, and queue workers. This is not an atomic persistence + * guarantee. Keys/owner/controller declarations remain untrusted unless the + * final authentication decision verifies them. + * @since 2.4.0 + */ +export type InboxRequestFinishedHandler = ( + context: RequestContext, + report: InboxRequestReport, +) => void | Promise; diff --git a/packages/fedify/src/federation/metrics.ts b/packages/fedify/src/federation/metrics.ts index 248e1977b..4542b749a 100644 --- a/packages/fedify/src/federation/metrics.ts +++ b/packages/fedify/src/federation/metrics.ts @@ -411,6 +411,15 @@ export interface SignatureVerificationExtraAttributes { * cardinality on success rows. */ failureReason?: HttpSignatureMetricFailureReason; + /** Bounded diagnostic shared by signature mechanisms. */ + verificationFailureReason?: + | "invalidSignature" + | "keyFetchError" + | "noSignature" + | "signatureVerificationFailed" + | "uncoveredAttribution" + | "missingOwner" + | "proofPolicy"; } /** @@ -963,6 +972,10 @@ class FederationMetrics { if (extra.failureReason != null) { attributes["http_signatures.failure_reason"] = extra.failureReason; } + if (extra.verificationFailureReason != null) { + attributes["activitypub.verification.failure_reason"] = + extra.verificationFailureReason; + } if (extra.ldType != null) { attributes["ld_signatures.type"] = extra.ldType; } diff --git a/packages/fedify/src/federation/middleware.ts b/packages/fedify/src/federation/middleware.ts index 74a916afd..57e243919 100644 --- a/packages/fedify/src/federation/middleware.ts +++ b/packages/fedify/src/federation/middleware.ts @@ -1,3 +1,4 @@ +import { InboxObservation } from "./inbox-observation.ts"; import { type Path, RouterError } from "@fedify/uri-template"; import type { Actor, @@ -3215,88 +3216,97 @@ export class FederationImpl const spanCtx = span.spanContext(); return await withContext( { traceId: spanCtx.traceId, spanId: spanCtx.spanId }, - async () => { - const logger = getLogger(["fedify", "federation", "http"]); - if (span.isRecording()) { - for (const [k, v] of request.headers) { - span.setAttribute(ATTR_HTTP_REQUEST_HEADER(k), [v]); + () => + this.#observeInboxFetch(metricState, async () => { + const logger = getLogger(["fedify", "federation", "http"]); + if (span.isRecording()) { + for (const [k, v] of request.headers) { + span.setAttribute(ATTR_HTTP_REQUEST_HEADER(k), [v]); + } } - } - let response: Response; - try { - response = await this.#fetch(request, { - ...options, - span, - tracer, - metricState, - }); - // Hashlink media responses are not negotiated, and they are - // sent as the application returns them, whose headers may - // even be immutable: - if ( - metricState.endpoint !== "hashlink_media" && - acceptsJsonLd(request) - ) { - response.headers.set("Vary", "Accept"); - } - } catch (error) { - this.metrics - .recordHttpServerRequest( - request.method, - metricState.endpoint ?? "error", - getDurationMs(metricStart), - { routeTemplate: metricState.routeTemplate }, + let response: Response; + try { + response = await this.#fetch(request, { + ...options, + span, + tracer, + metricState, + }); + if (metricState.inboxCompletion != null) { + metricState.inboxCompletion.observation.stage = "respond"; + } + // Hashlink media responses are not negotiated, and they are + // sent as the application returns them, whose headers may + // even be immutable: + if ( + metricState.endpoint !== "hashlink_media" && + acceptsJsonLd(request) + ) { + response.headers.set("Vary", "Accept"); + } + } catch (error) { + metricState.inboxCompletion?.observation.project(span, { + type: "exception", + stage: metricState.inboxCompletion.observation.stage, + error, + }); + this.metrics + .recordHttpServerRequest( + request.method, + metricState.endpoint ?? "error", + getDurationMs(metricStart), + { routeTemplate: metricState.routeTemplate }, + ); + span.setStatus({ + code: SpanStatusCode.ERROR, + message: `${error}`, + }); + span.end(); + logger.error( + "An error occurred while serving request " + + "{method} {url}: {error}", + { method: request.method, url: request.url, error }, ); - span.setStatus({ - code: SpanStatusCode.ERROR, - message: `${error}`, - }); - span.end(); - logger.error( - "An error occurred while serving request " + - "{method} {url}: {error}", - { method: request.method, url: request.url, error }, - ); - throw error; - } - this.metrics.recordHttpServerRequest( - request.method, - metricState.endpoint ?? "error", - getDurationMs(metricStart), - { - statusCode: response.status, - routeTemplate: metricState.routeTemplate, - }, - ); - if (span.isRecording()) { - span.setAttribute( - ATTR_HTTP_RESPONSE_STATUS_CODE, - response.status, + throw error; + } + this.metrics.recordHttpServerRequest( + request.method, + metricState.endpoint ?? "error", + getDurationMs(metricStart), + { + statusCode: response.status, + routeTemplate: metricState.routeTemplate, + }, ); - for (const [k, v] of response.headers) { - span.setAttribute(ATTR_HTTP_RESPONSE_HEADER(k), [v]); + if (span.isRecording()) { + span.setAttribute( + ATTR_HTTP_RESPONSE_STATUS_CODE, + response.status, + ); + for (const [k, v] of response.headers) { + span.setAttribute(ATTR_HTTP_RESPONSE_HEADER(k), [v]); + } + span.setStatus({ + code: response.status >= 500 + ? SpanStatusCode.ERROR + : SpanStatusCode.UNSET, + message: response.statusText, + }); } - span.setStatus({ - code: response.status >= 500 - ? SpanStatusCode.ERROR - : SpanStatusCode.UNSET, - message: response.statusText, - }); - } - span.end(); - const url = new URL(request.url); - const logTpl = "{method} {path}: {status}"; - const values = { - method: request.method, - path: `${url.pathname}${url.search}`, - url: request.url, - status: response.status, - }; - if (response.status >= 500) logger.error(logTpl, values); - else if (response.status >= 400) logger.warn(logTpl, values); - else logger.info(logTpl, values); - return response; - }, + span.end(); + const url = new URL(request.url); + const logTpl = "{method} {path}: {status}"; + const values = { + method: request.method, + path: `${url.pathname}${url.search}`, + url: request.url, + status: response.status, + }; + if (response.status >= 500) logger.error(logTpl, values); + else if (response.status >= 400) logger.warn(logTpl, values); + else logger.info(logTpl, values); + return response; + }), ); }, ); @@ -3370,8 +3380,27 @@ export class FederationImpl metricState.routeTemplate = route.template; metricState.endpoint = getEndpointCategory(route.name); span.updateName(`${request.method} ${route.template}`); - let context = this.#createContext(request, contextData); const routeName = route.name.replace(/:.*$/, ""); + let context: RequestContextImpl; + try { + context = this.#createContext(request, contextData); + } catch (error) { + if ( + request.method !== "POST" || + routeName !== "inbox" && routeName !== "sharedInbox" + ) throw error; + return await this.#reportInboxPreparationError( + request, + contextData, + { + kind: routeName === "inbox" ? "personal" : "shared", + recipient: route.values.identifier ?? null, + }, + error, + span, + metricState, + ); + } // Routes that aren't JSON-LD based: switch (routeName) { @@ -3464,6 +3493,48 @@ export class FederationImpl } return response; } + if ( + request.method === "POST" && + (routeName === "inbox" || routeName === "sharedInbox") + ) { + const recipient = route.values.identifier ?? null; + const observation = new InboxObservation({ + kind: routeName === "inbox" ? "personal" : "shared", + recipient, + }); + this.#setInboxCompletion(metricState, observation, () => context); + return await observation.run( + () => context, + undefined, + async () => { + if (routeName === "inbox") { + context = this.#createContext(request, contextData, { + documentLoader: await context.getDocumentLoader({ + identifier: recipient!, + }), + }); + } else if (this.sharedInboxKeyDispatcher != null) { + const identity = await this.sharedInboxKeyDispatcher(context); + if (identity != null) { + context = this.#createContext(request, contextData, { + documentLoader: + "identifier" in identity || "username" in identity + ? await context.getDocumentLoader(identity) + : context.getDocumentLoader(identity), + }); + } + } + return await this.#handleInbox(request, { + recipient, + context, + contextData, + onNotFound, + observation, + }); + }, + span, + ); + } switch (routeName) { case "actor": case "actorAlias": { @@ -3547,14 +3618,11 @@ export class FederationImpl onNotFound, }); } - context = this.#createContext(request, contextData, { - documentLoader: await context.getDocumentLoader({ - identifier: route.values.identifier, - }), - }); - // falls through + // POST deliveries are handled by the observed ingress above. + throw new Error("Unreachable inbox delivery."); case "sharedInbox": { - if (routeName !== "inbox" && this.sharedInboxKeyDispatcher != null) { + // Preserve the existing non-POST handling without reporting a delivery. + if (this.sharedInboxKeyDispatcher != null) { const identity = await this.sharedInboxKeyDispatcher(context); if (identity != null) { context = this.#createContext(request, contextData, { @@ -3980,6 +4048,74 @@ export class FederationImpl return await onNotFound(request); } + #setInboxCompletion( + metricState: HttpMetricState, + observation: InboxObservation, + getContext: () => RequestContext, + ): void { + const handler = this.inboxRequestFinishedHandler; + metricState.inboxCompletion = { + observation, + finish: (outcome) => observation.finish(getContext(), handler, outcome), + }; + } + + async #observeInboxFetch( + metricState: HttpMetricState, + operation: () => Promise, + ): Promise { + let response: Response; + try { + response = await operation(); + } catch (error) { + const completion = metricState.inboxCompletion; + if (completion != null) { + await completion.finish({ + type: "exception", + stage: completion.observation.stage, + error, + }); + } + throw error; + } + const completion = metricState.inboxCompletion; + if (completion != null) { + await completion.finish({ + type: "response", + status: response.status, + ...completion.observation.result, + }); + } + return response; + } + + async #reportInboxPreparationError( + request: Request, + contextData: TContextData, + inbox: import("./inbox-report.ts").InboxRequestReport["inbox"], + error: unknown, + span: Span, + metricState: HttpMetricState, + ): Promise { + const unavailableLoader: DocumentLoader = () => Promise.reject(error); + const context = new RequestContextImpl({ + url: new URL(request.url), + request, + federation: this, + data: contextData, + documentLoader: unavailableLoader, + contextLoader: unavailableLoader, + }); + const observation = new InboxObservation(inbox); + this.#setInboxCompletion(metricState, observation, () => context); + return await observation.run( + () => context, + undefined, + () => Promise.reject(error), + span, + ); + } + async #handleInbox( request: Request, { @@ -3988,12 +4124,14 @@ export class FederationImpl contextData, onNotFound, portableInbox, + observation, }: { recipient: string | null; context: RequestContextImpl; contextData: TContextData; onNotFound: (request: Request) => Response | Promise; portableInbox?: PortableInboxDelivery; + observation?: InboxObservation; }, ): Promise { if (!this.manuallyStartQueue) this._startQueueInternal(contextData); @@ -4025,6 +4163,7 @@ export class FederationImpl tracerProvider: this.tracerProvider, idempotencyStrategy: this.idempotencyStrategy, portableInbox, + observation, }); } @@ -4066,94 +4205,123 @@ export class FederationImpl metricState.endpoint = "inbox"; span.updateName(`${request.method} ${metricState.routeTemplate}`); const identifier = route.values.identifier; - let context = this.#createContext(request, contextData); - // The actor is looked up only by its identifier, as for ordinary inbox - // deliveries, so that the identifier alone determines the recipient, - // also for inbox listeners and queued deliveries: - const actor = this.actorCallbacks?.dispatcher == null - ? null - : await this.actorCallbacks.dispatcher(context, identifier); - const localOrigin = context.canonicalOrigin; - const resolution = resolvePortableInboxRecipient( - actor == null || actor instanceof Tombstone ? null : actor, - { - authority: portable.portableRequest.authority, - canonicalInboxId: portable.canonicalId, - localOrigin, - }, - ); - if (resolution.status === "rejected") { - logger.debug( - "Not accepting a delivery to the portable inbox {inbox} on behalf " + - "of the actor {identifier}: {reason}.", - { - inbox: portable.canonicalId, - identifier, - reason: resolution.reason, - }, + let context: RequestContextImpl; + try { + context = this.#createContext(request, contextData); + } catch (error) { + return await this.#reportInboxPreparationError( + request, + contextData, + { kind: "portable", recipient: identifier }, + error, + span, + metricState, ); - return await onNotFound(request); } - const { recipient } = resolution; - // A portable actor does not necessarily have key pairs for authorized - // fetch, so fall back to the default document loader without them: - if (this.actorCallbacks?.keyPairsDispatcher != null) { - context = this.#createContext(request, contextData, { - documentLoader: await context.getDocumentLoader({ identifier }), - }); - } - const excludedOrigins = [localOrigin, new URL(request.url).origin]; - return await this.#handleInbox(request, { + const observation = new InboxObservation({ + kind: "portable", recipient: identifier, - context, - contextData, - onNotFound, - portableInbox: { - recipient, - forward: async (activity, activityId, activityType, signatures) => { - if (this.portableInboxForwarding.maxTargets < 1) return; - if (this.kv.cas == null) { - if (!this.#portableInboxForwardingWarned) { - this.#portableInboxForwardingWarned = true; - logger.warn( - "Activities delivered to FEP-ef61 portable inboxes are not " + - "forwarded to the other gateways, as the key–value store " + - "does not support compare-and-swap (KvStore.cas()), which " + - "is needed to forward each activity at most once.", - ); - } - return; - } - await forwardPortableInboxActivity({ - recipient, - activity, - activityId, - activityType, - excludedOrigins, - baseUrl: context.origin, - kv: this.kv, - kvPrefix: this.kvPrefixes.portableInboxForwarding, - outboxQueue: this.outboxQueue, - startQueue: this.manuallyStartQueue - ? undefined - : () => this._startQueueInternal(contextData), - allowPrivateAddress: this.allowPrivateAddress, - getKeys: () => - this.#getPortableGatewayKeyPairs(context, identifier, recipient), - specDeterminer: new KvSpecDeterminer( - this.kv, - this.kvPrefixes.httpMessageSignaturesSpec, - this.firstKnock, - { specTtl: this.httpMessageSignaturesSpecTtl }, - ), - signatures, - options: this.portableInboxForwarding, - meterProvider: this.meterProvider, - tracerProvider: this.tracerProvider, + }); + this.#setInboxCompletion(metricState, observation, () => context); + return await observation.run( + () => context, + undefined, + async () => { + // The actor is looked up only by its identifier, as for ordinary inbox + // deliveries, so that the identifier alone determines the recipient, + // also for inbox listeners and queued deliveries: + const actor = this.actorCallbacks?.dispatcher == null + ? null + : await this.actorCallbacks.dispatcher(context, identifier); + const localOrigin = context.canonicalOrigin; + const resolution = resolvePortableInboxRecipient( + actor == null || actor instanceof Tombstone ? null : actor, + { + authority: portable.portableRequest.authority, + canonicalInboxId: portable.canonicalId, + localOrigin, + }, + ); + if (resolution.status === "rejected") { + logger.debug( + "Not accepting a delivery to the portable inbox {inbox} on behalf " + + "of the actor {identifier}: {reason}.", + { + inbox: portable.canonicalId, + identifier, + reason: resolution.reason, + }, + ); + return await onNotFound(request); + } + const { recipient } = resolution; + // A portable actor does not necessarily have key pairs for authorized + // fetch, so fall back to the default document loader without them: + if (this.actorCallbacks?.keyPairsDispatcher != null) { + context = this.#createContext(request, contextData, { + documentLoader: await context.getDocumentLoader({ identifier }), }); - }, + } + const excludedOrigins = [localOrigin, new URL(request.url).origin]; + return await this.#handleInbox(request, { + recipient: identifier, + observation, + context, + contextData, + onNotFound, + portableInbox: { + recipient, + forward: async (activity, activityId, activityType, signatures) => { + if (this.portableInboxForwarding.maxTargets < 1) return; + if (this.kv.cas == null) { + if (!this.#portableInboxForwardingWarned) { + this.#portableInboxForwardingWarned = true; + logger.warn( + "Activities delivered to FEP-ef61 portable inboxes are not " + + "forwarded to the other gateways, as the key–value store " + + "does not support compare-and-swap (KvStore.cas()), which " + + "is needed to forward each activity at most once.", + ); + } + return; + } + await forwardPortableInboxActivity({ + recipient, + activity, + activityId, + activityType, + excludedOrigins, + baseUrl: context.origin, + kv: this.kv, + kvPrefix: this.kvPrefixes.portableInboxForwarding, + outboxQueue: this.outboxQueue, + startQueue: this.manuallyStartQueue + ? undefined + : () => this._startQueueInternal(contextData), + allowPrivateAddress: this.allowPrivateAddress, + getKeys: () => + this.#getPortableGatewayKeyPairs( + context, + identifier, + recipient, + ), + specDeterminer: new KvSpecDeterminer( + this.kv, + this.kvPrefixes.httpMessageSignaturesSpec, + this.firstKnock, + { specTtl: this.httpMessageSignaturesSpecTtl }, + ), + signatures, + options: this.portableInboxForwarding, + meterProvider: this.meterProvider, + tracerProvider: this.tracerProvider, + }); + }, + }, + }); }, - }); + span, + ); } /** @@ -4377,6 +4545,12 @@ type FedifyEndpoint = | "error"; interface HttpMetricState { + inboxCompletion?: { + observation: InboxObservation; + finish( + outcome: import("./inbox-report.ts").InboxRequestOutcome, + ): Promise; + }; endpoint?: FedifyEndpoint; routeTemplate?: string; } diff --git a/packages/fedify/src/federation/mod.ts b/packages/fedify/src/federation/mod.ts index 6a3bb1f6e..4bdb6369d 100644 --- a/packages/fedify/src/federation/mod.ts +++ b/packages/fedify/src/federation/mod.ts @@ -14,6 +14,7 @@ export { respondWithObjectIfAcceptable, type RespondWithObjectOptions, } from "./handler.ts"; +export * from "./inbox-report.ts"; export * from "./kv.ts"; export { createFederation, diff --git a/packages/fedify/src/federation/portable-inbox.test.ts b/packages/fedify/src/federation/portable-inbox.test.ts index a027c80cd..a22ef54b6 100644 --- a/packages/fedify/src/federation/portable-inbox.test.ts +++ b/packages/fedify/src/federation/portable-inbox.test.ts @@ -1,3 +1,4 @@ +import type { InboxRequestReport } from "./inbox-report.ts"; import { mockDocumentLoader, test } from "@fedify/fixture"; import { type Activity, @@ -175,8 +176,13 @@ function setup( mapPortableActorId(identifier) ); } + const reports: InboxRequestReport[] = []; const inboxListeners = federation - .setInboxListeners("/users/{identifier}/inbox", "/inbox"); + .setInboxListeners("/users/{identifier}/inbox", "/inbox").onRequestFinished( + (_ctx, report) => { + reports.push(report); + }, + ); if (onSharedInboxKey != null) { inboxListeners.setSharedKeyDispatcher(() => { onSharedInboxKey(); @@ -197,7 +203,7 @@ function setup( recipient: ctx.recipient, }); }); - return { federation, received, kv, queue }; + return { federation, received, kv, queue, reports }; } let activityCounter = 0; @@ -350,6 +356,59 @@ test("Federation.fetch() refuses portable inbox deliveries it does not accept", }); }); +test("onRequestFinished retains crypto success when a portable activity's DID mismatches", async () => { + const { federation, reports, received } = setup(); + const signingKeyId = new URL( + `${otherDid}#${otherDid.substring("did:key:".length)}`, + ); + const activity = await signObject( + new Follow({ + id: parseIri(`ap+ef61://${did}/follows/mismatched-report`), + actor: parseIri(`ap+ef61://${otherDid}/users/bob`), + object: parseIri(`ap+ef61://${did}/users/alice`), + }), + otherKeyPair.privateKey, + signingKeyId, + { contextLoader: mockDocumentLoader }, + ); + const response = await federation.fetch( + post( + inboxUrl(), + await activity.toJsonLd({ contextLoader: mockDocumentLoader }), + ), + { contextData: undefined }, + ); + assertEquals(response.status, 401); + assertEquals(received.length, 0); + assertEquals(reports.length, 1); + const report = reports[0]; + assert(report.authentication.status === "rejected"); + assert(report.authentication.reason.type === "proofPolicy"); + assertEquals(report.authentication.reason.policy, "portableActivity"); + assertEquals( + report.authentication.reason.detail?.type, + "verificationMethodMismatch", + ); + assert( + report.attempts.some((attempt) => + attempt.mechanism === "objectIntegrity" && + attempt.checks.some((check) => check.status === "verified") + ), + ); + assert( + report.attempts.some((attempt) => + attempt.status === "rejected" && attempt.reason.type === "proofPolicy" && + attempt.reason.reason.type === "verificationMethodMismatch" + ), + ); + assertEquals(report.outcome, { + type: "response", + status: 401, + disposition: "rejected", + reason: "authentication", + }); +}); + test("Federation.fetch() applies the proof policy to portable inbox deliveries", async (t) => { const queue = new RecordingQueue(); const { federation, received } = setup({ queue }); @@ -2172,3 +2231,52 @@ test("Federation.fetch() keeps ordinary inbox deliveries unchanged", async () => assertEquals(received.length, 1); assertEquals(queue.outbox.length, 0); }); + +test("onRequestFinished covers portable ingress and recipient lookup failures", async () => { + const { federation, reports } = setup({ + options: { portableInboxForwarding: { maxTargets: 0 } }, + }); + const response = await federation.fetch( + post(inboxUrl(), await signedFollow()), + { contextData: undefined }, + ); + assertEquals(response.status, 202); + assertEquals(reports.length, 1); + assertEquals(reports[0].inbox, { kind: "portable", recipient: "alice" }); + assertEquals(reports[0].authentication.status, "verified"); + assert( + reports[0].attempts.some((attempt) => + attempt.subject.pointer === "" && attempt.status === "verified" + ), + ); + const absent = setup({ actor: () => null }); + assertEquals( + (await absent.federation.fetch(post(inboxUrl(), {}), { + contextData: undefined, + })).status, + 404, + ); + assertEquals(absent.reports[0].payload, { status: "unavailable" }); + assertEquals(absent.reports[0].authentication, { status: "notDetermined" }); + const failure = new Error("recipient lookup failed"); + const broken = setup({ + actor: () => { + throw failure; + }, + }); + let thrown: unknown; + try { + await broken.federation.fetch(post(inboxUrl(), {}), { + contextData: undefined, + }); + } catch (error) { + thrown = error; + } + assertEquals(thrown, failure); + assertEquals(broken.reports.length, 1); + assertEquals(broken.reports[0].outcome, { + type: "exception", + stage: "prepare", + error: failure, + }); +}); diff --git a/packages/fedify/src/sig/compound-proof-verification.test.ts b/packages/fedify/src/sig/compound-proof-verification.test.ts index f7c5cdd52..eebd65d28 100644 --- a/packages/fedify/src/sig/compound-proof-verification.test.ts +++ b/packages/fedify/src/sig/compound-proof-verification.test.ts @@ -1155,3 +1155,27 @@ test("verifyCompoundPortableObjectProofs() leaves keys at DID URLs alone", async assert(result.verified); assertEquals(result.portableObjects.map((o) => o.path), [""]); }); + +test("compound proof observation does not throw for malformed subject IDs", async () => { + const { verificationObservation } = await import("./verification.ts"); + const evidence = { + attempts: [] as import("./verification.ts").InboxVerificationAttempt[], + }; + const result = await verifyCompoundPortableObjectProofs( + { + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/data-integrity/v1", + ], + id: "ap://did%ZZkey/objects/1", + type: "Note", + proof: {}, + }, + limits, + { ...options, [verificationObservation]: evidence }, + ); + assertEquals(result.status, "ok"); + assert(result.status === "ok" && !result.verified); + assertEquals(evidence.attempts[0].subject.id, null); + assertEquals(evidence.attempts[0].subject.pointer, ""); +}); diff --git a/packages/fedify/src/sig/compound-proof.ts b/packages/fedify/src/sig/compound-proof.ts index 892aca337..98de3146a 100644 --- a/packages/fedify/src/sig/compound-proof.ts +++ b/packages/fedify/src/sig/compound-proof.ts @@ -1,3 +1,4 @@ +import { observeAttempt, verificationObservation } from "./verification.ts"; import type { Multikey } from "@fedify/vocab"; import { parseIri, preloadedContexts } from "@fedify/vocab-runtime"; import jsonld from "@fedify/vocab-runtime/jsonld"; @@ -913,9 +914,37 @@ async function verifyDiscoveredProofDocuments( reason: { type: "missingContext" as const }, }); } - const key = await verifyMapLocalProof( - document.securedDocument, - options, + const inherited = options[verificationObservation]; + let subjectId: URL | null = null; + if (inherited != null && document.id != null) { + try { + subjectId = parseIri(document.id); + } catch { /* Diagnostic metadata must not change policy handling. */ } + } + const key = await observeAttempt( + { + [verificationObservation]: inherited == null ? undefined : { + ...inherited, + attempt: undefined, + check: undefined, + subject: { + id: subjectId, + pointer: document.path, + }, + }, + }, + "objectIntegrity", + (observation) => + verifyMapLocalProof( + document.securedDocument, + { + ...options, + [verificationObservation]: inherited == null + ? undefined + : observation, + }, + ), + (key) => key != null, ); return key == null ? Object.freeze({ diff --git a/packages/fedify/src/sig/http.ts b/packages/fedify/src/sig/http.ts index 3ca167fcc..dbf4efc03 100644 --- a/packages/fedify/src/sig/http.ts +++ b/packages/fedify/src/sig/http.ts @@ -1,3 +1,10 @@ +import { + observeAttempt, + observeCheck, + triedKey, + verificationObservation, + type VerificationObservationOptions, +} from "./verification.ts"; import { CryptographicKey } from "@fedify/vocab"; import { type DocumentLoader, FetchError } from "@fedify/vocab-runtime"; import { getLogger } from "@logtape/logtape"; @@ -756,7 +763,7 @@ const supportedHashAlgorithms: Record = { /** * Options for {@link verifyRequest}. */ -export interface VerifyRequestOptions { +export interface VerifyRequestOptions extends VerificationObservationOptions { /** * The document loader to use for fetching the public key. */ @@ -1015,6 +1022,23 @@ export async function verifyRequestDetailed( request: Request, options: VerifyRequestOptions = {}, ): Promise { + if ( + options[verificationObservation] != null && + options[verificationObservation]?.attempt == null + ) { + return await observeAttempt(options, "http", async (observation) => { + const result = await verifyRequestDetailed(request, { + ...options, + [verificationObservation]: observation, + }); + if (!result.verified) { + observation.attempt!.reason = result.reason.type === "noSignature" + ? { type: "noSignature" } + : { type: "signatureVerificationFailed" }; + } + return result; + }, (result) => result.verified); + } if (options.maxSignatures !== undefined) { validateMaxSignatures(options.maxSignatures, "maxSignatures"); } @@ -1109,6 +1133,43 @@ export async function verifyRequestDetailed( } async function verifyRequestDraft( + request: Request, + span: Span, + metricsContext: HttpSignatureMetricsContext, + options: VerifyRequestOptions = {}, +): Promise { + if (options[verificationObservation]?.check != null) { + return await verifyRequestDraftInternal( + request, + span, + metricsContext, + options, + ); + } + let result: VerifyRequestDetailedResult = noSignatureResult(); + const raw = request.headers.get("Signature"); + const declared = raw == null ? null : parseDraftSignature(raw)?.keyId ?? null; + if (raw == null) return result; + await observeCheck( + options, + { mechanism: "http", spec: "draft-cavage-http-signatures-12", label: null }, + declared, + async (observation) => { + result = await verifyRequestDraftInternal(request, span, metricsContext, { + ...options, + [verificationObservation]: observation, + }); + if ( + !result.verified && result.reason.type === "keyFetchError" && + observation.check != null + ) observation.check.reason = result.reason; + return result.verified ? result.key : null; + }, + ); + return result; +} + +async function verifyRequestDraftInternal( request: Request, span: Span, metricsContext: HttpSignatureMetricsContext, @@ -1120,6 +1181,7 @@ async function verifyRequestDraft( keyCache, meterProvider, tracerProvider, + [verificationObservation]: observation, }: VerifyRequestOptions = {}, ): Promise { const logger = getLogger(["fedify", "sig", "http"]); @@ -1384,6 +1446,7 @@ async function verifyRequestDraft( const sig = decodeBase64(signature); span?.setAttribute("http_signatures.signature", encodeHex(sig)); // TODO: support other than RSASSA-PKCS1-v1_5: + triedKey({ [verificationObservation]: observation }, key); const verified = await crypto.subtle.verify( "RSASSA-PKCS1-v1_5", key.publicKey, @@ -1413,6 +1476,7 @@ async function verifyRequestDraft( keyCache: bypassKeyCacheReads(keyCache), meterProvider, tracerProvider, + [verificationObservation]: observation, }, ); } @@ -1529,6 +1593,7 @@ async function verifyRfc9421SignatureWithKey( sigBytes: Uint8Array, key: CryptographicKey & { publicKey: CryptoKey }, span: Span, + observationOptions: VerificationObservationOptions = {}, ): Promise { const logger = getLogger(["fedify", "sig", "http"]); // Map algorithm name to WebCrypto algorithm @@ -1607,6 +1672,7 @@ async function verifyRfc9421SignatureWithKey( } let verified: boolean; try { + triedKey(observationOptions, key); verified = await crypto.subtle.verify( algorithm, key.publicKey, @@ -1639,6 +1705,7 @@ async function verifyRequestRfc9421( currentTime, keyCache, maxSignatures = DEFAULT_MAX_RFC9421_SIGNATURES, + [verificationObservation]: observation, meterProvider, tracerProvider, }: VerifyRequestOptions = {}, @@ -1761,152 +1828,171 @@ async function verifyRequestRfc9421( let digestValid: boolean | null = null; for (const sigName of signatureNames) { - // Skip if we don't have the signature bytes - if (!signatures[sigName]) { - setFailure( - invalidSignatureResult(parseKeyId(signatureInputs[sigName]?.keyId)), - ); - continue; - } - - const sigInput = signatureInputs[sigName]; - const sigBytes = signatures[sigName]; - const keyId = parseKeyId(sigInput.keyId); - - // Validate signature input parameters - if (!sigInput.keyId) { - logger.debug( - "Failed to verify; missing keyId in signature {signatureName}.", - { signatureName: sigName, signatureInput: signatureInputHeader }, - ); - setFailure(invalidSignatureResult(null)); - continue; - } + let winning: VerifyRequestDetailedResult | undefined; + await observeCheck( + { [verificationObservation]: observation }, + { mechanism: "http", spec: "rfc9421", label: sigName }, + signatureInputs[sigName]?.keyId ?? null, + async (candidateObservation) => { + // Skip if we don't have the signature bytes + if (!signatures[sigName]) { + setFailure( + invalidSignatureResult(parseKeyId(signatureInputs[sigName]?.keyId)), + ); + return null; + } - if (!sigInput.created) { - logger.debug( - "Failed to verify; missing created timestamp in signature {signatureName}.", - { signatureName: sigName, signatureInput: signatureInputHeader }, - ); - setFailure(invalidSignatureResult(keyId)); - continue; - } + const sigInput = signatureInputs[sigName]; + const sigBytes = signatures[sigName]; + const keyId = parseKeyId(sigInput.keyId); - // Check timestamp validity - const signatureCreated = Temporal.Instant.fromEpochMilliseconds( - sigInput.created * 1000, - ); - const now = currentTime ?? Temporal.Now.instant(); + // Validate signature input parameters + if (!sigInput.keyId) { + logger.debug( + "Failed to verify; missing keyId in signature {signatureName}.", + { signatureName: sigName, signatureInput: signatureInputHeader }, + ); + setFailure(invalidSignatureResult(null)); + return null; + } - if (timeWindow !== false) { - const tw: Temporal.Duration | Temporal.DurationLike = timeWindow ?? - { hours: 1 }; - if (Temporal.Instant.compare(signatureCreated, now.add(tw)) > 0) { - logger.debug( - "Failed to verify; signature created time is too far in the future.", - { created: signatureCreated.toString(), now: now.toString() }, - ); - setFailure(invalidSignatureResult(keyId)); - continue; - } else if ( - Temporal.Instant.compare(signatureCreated, now.subtract(tw)) < 0 - ) { - logger.debug( - "Failed to verify; signature created time is too far in the past.", - { created: signatureCreated.toString(), now: now.toString() }, - ); - setFailure(invalidSignatureResult(keyId)); - continue; - } - } + if (!sigInput.created) { + logger.debug( + "Failed to verify; missing created timestamp in signature {signatureName}.", + { signatureName: sigName, signatureInput: signatureInputHeader }, + ); + setFailure(invalidSignatureResult(keyId)); + return null; + } - // Verify Content-Digest if present and required - if ( - request.method !== "GET" && - request.method !== "HEAD" && - sigInput.components.some((c) => c.value === "content-digest") - ) { - const contentDigestHeader = request.headers.get("Content-Digest"); - if (!contentDigestHeader) { - logger.debug( - "Failed to verify; Content-Digest header required but not found.", - { components: sigInput.components }, + // Check timestamp validity + const signatureCreated = Temporal.Instant.fromEpochMilliseconds( + sigInput.created * 1000, ); - setFailure(invalidSignatureResult(keyId)); - continue; - } + const now = currentTime ?? Temporal.Now.instant(); + + if (timeWindow !== false) { + const tw: Temporal.Duration | Temporal.DurationLike = timeWindow ?? + { hours: 1 }; + if (Temporal.Instant.compare(signatureCreated, now.add(tw)) > 0) { + logger.debug( + "Failed to verify; signature created time is too far in the future.", + { created: signatureCreated.toString(), now: now.toString() }, + ); + setFailure(invalidSignatureResult(keyId)); + return null; + } else if ( + Temporal.Instant.compare(signatureCreated, now.subtract(tw)) < 0 + ) { + logger.debug( + "Failed to verify; signature created time is too far in the past.", + { created: signatureCreated.toString(), now: now.toString() }, + ); + setFailure(invalidSignatureResult(keyId)); + return null; + } + } - // Every signature covers the same body and Content-Digest header. - body ??= await request.arrayBuffer(); - digestValid ??= await verifyRfc9421ContentDigest( - contentDigestHeader, - body, - ); + // Verify Content-Digest if present and required + if ( + request.method !== "GET" && + request.method !== "HEAD" && + sigInput.components.some((c) => c.value === "content-digest") + ) { + const contentDigestHeader = request.headers.get("Content-Digest"); + if (!contentDigestHeader) { + logger.debug( + "Failed to verify; Content-Digest header required but not found.", + { components: sigInput.components }, + ); + setFailure(invalidSignatureResult(keyId)); + return null; + } - if (!digestValid) { - logger.debug( - "Failed to verify; Content-Digest verification failed.", - { contentDigest: contentDigestHeader }, - ); - setFailure(invalidSignatureResult(keyId)); - continue; - } - } + // Every signature covers the same body and Content-Digest header. + body ??= await request.arrayBuffer(); + digestValid ??= await verifyRfc9421ContentDigest( + contentDigestHeader, + body, + ); - // Fetch the public key - span?.setAttribute("http_signatures.key_id", sigInput.keyId); - span?.setAttribute("http_signatures.created", sigInput.created.toString()); - if (keyId == null) { - setFailure(invalidSignatureResult(null)); - continue; - } + if (!digestValid) { + logger.debug( + "Failed to verify; Content-Digest verification failed.", + { contentDigest: contentDigestHeader }, + ); + setFailure(invalidSignatureResult(keyId)); + return null; + } + } - let lookup = keyLookups.get(keyId.href); - if (lookup == null) { - lookup = await lookUpKey(keyId, keyCache); - keyLookups.set(keyId.href, lookup); - } - while (true) { - const { key, cached, fetchError } = lookup; - if (fetchError != null) { - setFailure(keyFetchErrorResult(keyId, fetchError)); - break; - } - if (!key) { - logger.debug("Failed to fetch key: {keyId}", { - keyId: sigInput.keyId, - }); - setFailure(invalidSignatureResult(keyId)); - break; - } - const result = await verifyRfc9421SignatureWithKey( - request, - sigInput, - sigBytes, - key, - span, - ); - if (result.verified) { - metricsContext.algorithm = result.algorithm; - return { verified: true, key, signatureLabel: sigName }; - } - if (result.mismatched && cached && !refreshedKeyIds.has(keyId.href)) { - // The cached key may be stale, so look it up again without the cache, - // but only once for each key ID, and only for this signature; the - // other signatures naming the same key use the fresh one: - logger.debug( - "Failed to verify with cached key {keyId}; retrying with fresh " + - "key...", - { keyId: sigInput.keyId }, + // Fetch the public key + span?.setAttribute("http_signatures.key_id", sigInput.keyId); + span?.setAttribute( + "http_signatures.created", + sigInput.created.toString(), ); - refreshedKeyIds.add(keyId.href); - lookup = await lookUpKey(keyId, bypassKeyCacheReads(keyCache)); - keyLookups.set(keyId.href, lookup); - continue; - } - setFailure(invalidSignatureResult(keyId), result.algorithm); - break; - } + if (keyId == null) { + setFailure(invalidSignatureResult(null)); + return null; + } + + let lookup = keyLookups.get(keyId.href); + if (lookup == null) { + lookup = await lookUpKey(keyId, keyCache); + keyLookups.set(keyId.href, lookup); + } + while (true) { + const { key, cached, fetchError } = lookup; + if (fetchError != null) { + setFailure(keyFetchErrorResult(keyId, fetchError)); + break; + } + if (!key) { + logger.debug("Failed to fetch key: {keyId}", { + keyId: sigInput.keyId, + }); + setFailure(invalidSignatureResult(keyId)); + break; + } + const result = await verifyRfc9421SignatureWithKey( + request, + sigInput, + sigBytes, + key, + span, + { [verificationObservation]: candidateObservation }, + ); + if (result.verified) { + metricsContext.algorithm = result.algorithm; + winning = { verified: true, key, signatureLabel: sigName }; + return key; + } + if (result.mismatched && cached && !refreshedKeyIds.has(keyId.href)) { + // The cached key may be stale, so look it up again without the cache, + // but only once for each key ID, and only for this signature; the + // other signatures naming the same key use the fresh one: + logger.debug( + "Failed to verify with cached key {keyId}; retrying with fresh " + + "key...", + { keyId: sigInput.keyId }, + ); + refreshedKeyIds.add(keyId.href); + lookup = await lookUpKey(keyId, bypassKeyCacheReads(keyCache)); + keyLookups.set(keyId.href, lookup); + continue; + } + setFailure(invalidSignatureResult(keyId), result.algorithm); + break; + } + if ( + !failure.verified && failure.reason.type === "keyFetchError" && + candidateObservation.check != null + ) candidateObservation.check.reason = failure.reason; + return null; + }, + ); + if (winning != null) return winning; } metricsContext.algorithm = failureAlgorithm; diff --git a/packages/fedify/src/sig/key.ts b/packages/fedify/src/sig/key.ts index 5865cabca..b882fec65 100644 --- a/packages/fedify/src/sig/key.ts +++ b/packages/fedify/src/sig/key.ts @@ -1,3 +1,7 @@ +import { + verificationObservation, + type VerificationObservationOptions, +} from "./verification.ts"; import { type Actor, CryptographicKey, @@ -178,7 +182,7 @@ export async function importJwk( * Options for {@link fetchKey}. * @since 1.3.0 */ -export interface FetchKeyOptions { +export interface FetchKeyOptions extends VerificationObservationOptions { /** * The document loader for loading remote JSON-LD documents. */ @@ -1694,10 +1698,48 @@ async function fetchKeyInternal( cacheKey, cls, options, - (_cacheKey, _keyId, _keyCache, _logger) => { + async (_cacheKey, _keyId, _keyCache, _logger) => { + const check = options[verificationObservation]?.check; + if (check != null) { + try { + const result = await _keyCache?.getFetchError?.(_cacheKey); + if (result != null) { + check.reason = { + type: "keyFetchError", + keyId: new URL(_cacheKey.href), + result, + }; + } + } catch { + // Optional diagnostic metadata must not change a cached miss. + } + } return { key: null, cached: true }; }, async (error, cacheKey, keyId, keyCache, logger) => { + const check = options[verificationObservation]?.check; + if (check != null) { + let result: FetchKeyErrorResult; + try { + result = error instanceof FetchError && error.response != null + ? { + status: error.response.status, + response: error.response.clone(), + } + : { + error: error instanceof Error ? error : new Error(String(error)), + }; + } catch { + // A custom loader can provide a response whose body is already used. + // Collecting evidence must preserve the original verification result. + result = { error: error instanceof Error ? error : new Error() }; + } + check.reason = { + type: "keyFetchError", + keyId: new URL(cacheKey.href), + result, + }; + } logger.debug("Failed to fetch key {keyId}.", { keyId, error }); await keyCache?.set(cacheKey, null); if (error instanceof FetchError && error.response != null) { diff --git a/packages/fedify/src/sig/ld.ts b/packages/fedify/src/sig/ld.ts index e588bbd9f..2b854f38a 100644 --- a/packages/fedify/src/sig/ld.ts +++ b/packages/fedify/src/sig/ld.ts @@ -1,3 +1,10 @@ +import { + observeAttempt, + observeCheck, + triedKey, + verificationObservation, + type VerificationObservationOptions, +} from "./verification.ts"; import { Activity, CryptographicKey, getTypeId, Object } from "@fedify/vocab"; import { type DocumentLoader, @@ -881,7 +888,7 @@ export function detachSignature(jsonLd: unknown): unknown { * Options for verifying Linked Data Signatures. * @since 1.0.0 */ -export interface VerifySignatureOptions { +export interface VerifySignatureOptions extends VerificationObservationOptions { /** * The document loader to use for fetching the public key. */ @@ -935,6 +942,22 @@ export async function verifySignature( jsonLd: unknown, options: VerifySignatureOptions = {}, ): Promise { + if ( + options[verificationObservation]?.attempt != null && + options[verificationObservation]?.check == null + ) { + const declared = getLdSignatureObject(jsonLd)?.creator; + return await observeCheck( + options, + { mechanism: "linkedData" }, + typeof declared === "string" ? declared : null, + (observation) => + verifySignature(jsonLd, { + ...options, + [verificationObservation]: observation, + }), + ); + } if (!hasSignature(jsonLd)) return null; const sig = jsonLd.signature; let signature: Uint8Array; @@ -990,6 +1013,7 @@ export async function verifySignature( const encoder = new TextEncoder(); const message = sigOptsHash + docHash; const messageBytes = encoder.encode(message); + triedKey(options, key); const verified = await crypto.subtle.verify( "RSASSA-PKCS1-v1_5", key.publicKey, @@ -1014,6 +1038,7 @@ export async function verifySignature( }), ); if (key == null) return null; + triedKey(options, key); const verified = await crypto.subtle.verify( "RSASSA-PKCS1-v1_5", key.publicKey, @@ -1108,6 +1133,25 @@ async function verifyJsonLdInternal( options: VerifyJsonLdOptions, compact: boolean, ): Promise { + if ( + options[verificationObservation]?.attempt == null + ) { + return await observeAttempt( + { + ...options, + [verificationObservation]: options[verificationObservation] ?? + { attempts: [] }, + }, + "linkedData", + (observation) => + verifyJsonLdInternal(jsonLd, { + ...options, + [verificationObservation]: observation, + }, compact), + (value) => value, + ); + } + const observation = options[verificationObservation]; const tracerProvider = options.tracerProvider ?? trace.getTracerProvider(); const tracer = tracerProvider.getTracer(metadata.name, metadata.version); return await tracer.startActiveSpan( @@ -1130,6 +1174,12 @@ async function verifyJsonLdInternal( : jsonLd : jsonLd; const object = await Object.fromJsonLd(compacted, verificationOptions); + observation?.parsedObject?.(object); + if (observation?.subject != null) { + observation.subject.id = object.id == null + ? null + : new URL(object.id.href); + } if (object.id != null) { span.setAttribute("activitypub.object.id", object.id.href); } @@ -1159,13 +1209,27 @@ async function verifyJsonLdInternal( for (const uri of object.actorIds) attributions.add(uri.href); } const key = await verifySignature(compacted, verificationOptions); - if (key == null) return false; + if (key == null) { + if (observation?.attempt != null && !hasLdSignatureProperty(jsonLd)) { + observation.attempt.reason = { type: "noSignature" }; + } + return false; + } if (key.ownerId == null) { + if (observation?.attempt != null) { + observation.attempt.reason = { type: "missingOwner" }; + } logger.debug("Key {keyId} has no owner.", { keyId: key.id?.href }); return false; } attributions.delete(key.ownerId.href); if (attributions.size > 0) { + if (observation?.attempt != null) { + observation.attempt.reason = { + type: "uncoveredAttribution", + attributionIds: [...attributions].map((id) => new URL(id)), + }; + } logger.debug( "Some attributions are not authenticated by the Linked Data " + "Signatures: {attributions}.", @@ -1187,6 +1251,13 @@ async function verifyJsonLdInternal( // or a primitive) counts as "had signature" for classification, so // malformed signatures are reported as `rejected` rather than as // `missing`. + if (observation?.attempt?.reason != null) { + span.setAttribute( + "activitypub.verification.failure_reason", + observation.attempt.reason.type, + ); + span.setStatus({ code: SpanStatusCode.ERROR }); + } const classified: SignatureVerificationResult = threw ? "error" : verified @@ -1199,7 +1270,15 @@ async function verifyJsonLdInternal( getDurationMs(start), "linked_data", classified, - { ldType: signatureType }, + { + ldType: signatureType, + verificationFailureReason: verified || threw + ? undefined + : observation?.attempt?.reason?.type ?? + (hasLdSignatureProperty(jsonLd) + ? "signatureVerificationFailed" + : "noSignature"), + }, ); span.end(); } diff --git a/packages/fedify/src/sig/proof.ts b/packages/fedify/src/sig/proof.ts index 2f4b66a45..7e13a18cf 100644 --- a/packages/fedify/src/sig/proof.ts +++ b/packages/fedify/src/sig/proof.ts @@ -1,3 +1,10 @@ +import { + observeAttempt, + observeCheck, + triedKey, + verificationObservation, + type VerificationObservationOptions, +} from "./verification.ts"; import { Activity, DataIntegrityProof, @@ -449,7 +456,7 @@ export async function signObject( * Options for {@link verifyProof}. * @since 0.10.0 */ -export interface VerifyProofOptions { +export interface VerifyProofOptions extends VerificationObservationOptions { /** * The security domain expected by the verifier. When specified, it must * contain the same strings as the proof's `domain` option. @@ -625,6 +632,24 @@ export async function verifyMapLocalProof( ) { return null; } + const rawProof = jsonLd.proof; + const previousChecks = options[verificationObservation]?.attempt?.checks + .length; + const malformed = () => + observeCheck( + options, + { + mechanism: "objectIntegrity", + proofId: typeof rawProof.id === "string" + ? rawProof.id + : typeof rawProof["@id"] === "string" + ? rawProof["@id"] + : null, + proofIndex: previousChecks ?? null, + }, + getDeclaredProofKeyId(rawProof), + () => Promise.resolve(null), + ); const proofContextLoader = getNormalizationContextLoader( preloadedOnlyDocumentLoader, ); @@ -635,7 +660,7 @@ export async function verifyMapLocalProof( options, proofContextLoader, ); - if (candidate.proof == null) return null; + if (candidate.proof == null) return await malformed(); return await verifyProofWithMessageDigestCache( jsonLd, candidate.proof, @@ -644,10 +669,33 @@ export async function verifyMapLocalProof( candidate, ); } catch { + if ( + previousChecks != null && + options[verificationObservation]?.attempt?.checks.length === + previousChecks + ) return await malformed(); return null; } } +function getDeclaredProofKeyId( + value: unknown, + propertyNames: Iterable = [ + "verificationMethod", + "https://w3id.org/security#verificationMethod", + ], +): string | null { + if (!isJsonLdNode(value)) return null; + const method = Array.from(propertyNames, (name) => value[name]).find((v) => + v != null + ); + const candidate = Array.isArray(method) ? method[0] : method; + if (typeof candidate === "string") return candidate; + return isJsonLdNode(candidate) && typeof candidate["@id"] === "string" + ? candidate["@id"] + : null; +} + async function verifyProofWithMessageDigestCache( jsonLd: unknown, proof: DataIntegrityProof, @@ -657,6 +705,44 @@ async function verifyProofWithMessageDigestCache( // See the call in verifyPortableObjectProof() for why this exists. keyIdBoundByCaller = false, ): Promise { + if (options[verificationObservation] == null) { + return await verifyProofWithMessageDigestCache( + jsonLd, + proof, + { + ...options, + [verificationObservation]: { attempts: [], attempt: { checks: [] } }, + }, + messageDigestCache, + rawProofCandidate, + keyIdBoundByCaller, + ); + } + if ( + options[verificationObservation]?.attempt != null && + options[verificationObservation]?.check == null + ) { + return await observeCheck( + options, + { + mechanism: "objectIntegrity", + proofId: proof.id?.href ?? null, + proofIndex: options[verificationObservation]!.attempt!.checks.length, + }, + rawProofCandidate?.declaredKeyId ?? + getDeclaredProofKeyId(rawProofCandidate?.value) ?? + proof.verificationMethodId?.href ?? null, + (observation) => + verifyProofWithMessageDigestCache( + jsonLd, + proof, + { ...options, [verificationObservation]: observation }, + messageDigestCache, + rawProofCandidate, + keyIdBoundByCaller, + ), + ); + } const tracerProvider = options.tracerProvider ?? trace.getTracerProvider(); const tracer = tracerProvider.getTracer(metadata.name, metadata.version); return await tracer.startActiveSpan( @@ -699,8 +785,14 @@ async function verifyProofWithMessageDigestCache( rawProofCandidate, keyIdBoundByCaller, ); - if (key == null) span.setStatus({ code: SpanStatusCode.ERROR }); - else verified = true; + if (key == null) { + span.setStatus({ code: SpanStatusCode.ERROR }); + span.setAttribute( + "activitypub.verification.failure_reason", + options[verificationObservation]?.check?.reason?.type ?? + "invalidSignature", + ); + } else verified = true; return key; } catch (error) { threw = true; @@ -720,7 +812,13 @@ async function verifyProofWithMessageDigestCache( getDurationMs(start), "object_integrity", classified, - { cryptosuite }, + { + cryptosuite, + verificationFailureReason: verified || threw + ? undefined + : options[verificationObservation]?.check?.reason?.type ?? + "invalidSignature", + }, ); span.end(); } @@ -774,18 +872,29 @@ async function getJsonLdPropertyNames( documentLoader: DocumentLoader = preloadedOnlyDocumentLoader, inheritedContext?: unknown, rejectOnContextError = false, + contextState?: { initial?: unknown; scoped?: unknown; active?: unknown }, ): Promise | null> { const names = new Set(defaults); const context = jsonLd["@context"] ?? inheritedContext; - if (context == null) return names; + if (context == null && contextState?.initial == null) return names; try { const options = { documentLoader }; - let activeContext = await jsonld.processContext(null, null, options); - activeContext = await jsonld.processContext( - activeContext, - context, - options, - ); + let activeContext = contextState?.initial ?? + await jsonld.processContext(null, null, options); + if (contextState?.scoped != null) { + activeContext = await jsonld.processContext( + activeContext, + contextState.scoped, + options, + ); + } + if (context != null) { + activeContext = await jsonld.processContext( + activeContext, + context, + options, + ); + } const typeScopedContext = activeContext; for (const key of globalThis.Object.keys(jsonLd).sort()) { if ( @@ -812,6 +921,7 @@ async function getJsonLdPropertyNames( } } } + if (contextState != null) contextState.active = activeContext; for (const key of globalThis.Object.keys(jsonLd)) { if (expandContextPropertyIri(activeContext, key) === propertyIri) { names.add(key); @@ -962,6 +1072,72 @@ interface RawProofCandidate { readonly value: unknown; readonly proof: DataIntegrityProof | null; readonly reference?: string; + readonly declaredKeyId?: string | null; +} + +// Replay contexts already read by the vocabulary parser when resolving raw +// property aliases. Diagnostic extraction never dereferences another context. +function recordProofContexts(documentLoader: DocumentLoader): { + loader: DocumentLoader; + replay: DocumentLoader; +} { + const documents = new Map(); + return { + loader: async (url, options) => { + const document = await documentLoader(url, options); + documents.set(url, document); + return document; + }, + replay: (url, options) => { + const document = documents.get(url); + return document == null + ? preloadedOnlyDocumentLoader(url, options) + : Promise.resolve(document); + }, + }; +} + +async function getAliasedDeclaredProofKeyId( + value: unknown, + inheritedContext: unknown, + contextLoader: DocumentLoader, +): Promise { + if (!isJsonLdNode(value)) return null; + const contextState: { active?: unknown } = {}; + const names = await getJsonLdPropertyNames( + value, + "https://w3id.org/security#verificationMethod", + ["verificationMethod", "https://w3id.org/security#verificationMethod"], + contextLoader, + inheritedContext, + false, + contextState, + ); + const methodName = Array.from(names ?? []).find((name) => + value[name] != null + ); + const method = methodName == null ? undefined : value[methodName]; + const candidate = Array.isArray(method) ? method[0] : method; + if (typeof candidate === "string") return candidate; + if (!isJsonLdNode(candidate)) return null; + const idNames = await getJsonLdPropertyNames( + candidate, + "@id", + ["@id"], + contextLoader, + undefined, + false, + { + initial: contextState.active, + scoped: contextState.active == null || methodName == null + ? undefined + : jsonld.getContextValue(contextState.active, methodName, "@context"), + }, + ); + for (const name of idNames ?? []) { + if (typeof candidate[name] === "string") return candidate[name]; + } + return null; } function normalizeDocumentUrl(url: string): string { @@ -989,6 +1165,7 @@ async function parseRawProofCandidates( const candidates: RawProofCandidate[] = []; for (const value of values) { let parsed: DataIntegrityProof | null = null; + const contexts = recordProofContexts(documentLoader); if (isJsonLdNode(value)) { const proofJsonLd = value["@context"] == null && jsonLd["@context"] != null @@ -997,7 +1174,7 @@ async function parseRawProofCandidates( try { parsed = await DataIntegrityProof.fromJsonLd( proofJsonLd, - { ...options, contextLoader: documentLoader }, + { ...options, contextLoader: contexts.loader }, ); } catch { // Malformed sibling proofs cannot match a typed proof. @@ -1007,6 +1184,11 @@ async function parseRawProofCandidates( value, proof: parsed, reference: getRawProofReference(value) ?? parsed?.id?.href, + declaredKeyId: await getAliasedDeclaredProofKeyId( + value, + jsonLd["@context"], + contexts.replay, + ), }); } return candidates; @@ -1505,8 +1687,13 @@ async function verifyProofInternal( const digest = new Uint8Array(proofDigest.byteLength + SHA256_LENGTH); digest.set(new Uint8Array(proofDigest), 0); const proofValue = proof.proofValue; + let keyTried = false; const verifyCandidate = async (msgDigest: ArrayBuffer): Promise => { digest.set(new Uint8Array(msgDigest), proofDigest.byteLength); + if (!keyTried) { + triedKey(options, publicKey); + keyTried = true; + } return await crypto.subtle.verify( "Ed25519", publicKey.publicKey, @@ -2231,8 +2418,57 @@ export async function verifyObject( jsonLd: unknown, options: VerifyObjectOptions = {}, ): Promise { + if (options[verificationObservation]?.attempt == null) { + const observedOptions = { + ...options, + [verificationObservation]: options[verificationObservation] ?? + { attempts: [] }, + }; + const tracer = (options.tracerProvider ?? trace.getTracerProvider()) + .getTracer(metadata.name, metadata.version); + return await tracer.startActiveSpan( + "object_integrity_proofs.verify_object", + async (span) => { + try { + return await observeAttempt( + observedOptions, + "objectIntegrity", + async (observation) => { + const object = await verifyObject(cls, jsonLd, { + ...options, + [verificationObservation]: observation, + }); + if (object == null) { + span.setStatus({ code: SpanStatusCode.ERROR }); + span.setAttribute( + "activitypub.verification.failure_reason", + observation.attempt?.reason?.type ?? + "signatureVerificationFailed", + ); + } + return object; + }, + (value) => value != null, + ); + } catch (error) { + span.setStatus({ + code: SpanStatusCode.ERROR, + message: String(error), + }); + throw error; + } finally { + span.end(); + } + }, + ); + } + const observation = options[verificationObservation]; const logger = getLogger(["fedify", "sig", "proof"]); const object = await cls.fromJsonLd(jsonLd, options); + observation?.parsedObject?.(object); + if (observation?.subject != null) { + observation.subject.id = object.id == null ? null : new URL(object.id.href); + } const defaultDocumentLoader = getDocumentLoader(); const proofContextLoader = options.contextLoader ?? defaultDocumentLoader; const attributions = new Set(object.attributionIds.map((uri) => uri.href)); @@ -2288,12 +2524,13 @@ export async function verifyObject( if (candidateIndex >= 0) { hydratedCandidates.add(candidateIndex); let parsed: DataIntegrityProof | null = null; + const contexts = recordProofContexts(proofContextLoader); try { parsed = await DataIntegrityProof.fromJsonLd( remoteDocument.document, { documentLoader: baseDocumentLoader, - contextLoader: proofContextLoader, + contextLoader: contexts.loader, tracerProvider: options.tracerProvider, baseUrl: parseIri(remoteDocument.documentUrl), }, @@ -2305,6 +2542,11 @@ export async function verifyObject( value: structuredClone(remoteDocument.document), proof: parsed, reference, + declaredKeyId: await getAliasedDeclaredProofKeyId( + remoteDocument.document, + undefined, + contexts.replay, + ), }; } return remoteDocument; @@ -2357,6 +2599,15 @@ export async function verifyObject( return null; } if (attributions.size > 0) { + if (observation?.attempt != null) { + observation.attempt.reason = observation.attempt.checks.length === 0 + ? { type: "noSignature" } + : { + type: "uncoveredAttribution", + attributionIds: [...attributions].map((id) => new URL(id)), + }; + } + logger.debug( "Some attributions are not authenticated by the proofs: {attributions}.", { attributions: [...attributions] }, diff --git a/packages/fedify/src/sig/verification.test.ts b/packages/fedify/src/sig/verification.test.ts new file mode 100644 index 000000000..48cad513f --- /dev/null +++ b/packages/fedify/src/sig/verification.test.ts @@ -0,0 +1,402 @@ +import { mockDocumentLoader, test } from "@fedify/fixture"; +import { Activity, Create, CryptographicKey, Multikey } from "@fedify/vocab"; +import { FetchError } from "@fedify/vocab-runtime"; +import { deepStrictEqual, ok, strictEqual } from "node:assert/strict"; +import { signRequest, verifyRequestDetailed } from "./http.ts"; +import { signJsonLd, verifyJsonLd } from "./ld.ts"; +import { signObject, verifyObject } from "./proof.ts"; +import { + type VerificationObservation, + verificationObservation, +} from "./verification.ts"; +import { + ed25519Multikey, + ed25519PrivateKey, + rsaPrivateKey2, + rsaPublicKey1, + rsaPublicKey2, +} from "../testing/keys.ts"; + +const loaders = { + documentLoader: mockDocumentLoader, + contextLoader: mockDocumentLoader, +}; +function observation(): VerificationObservation { + return { attempts: [] }; +} + +test("signature evidence preserves stale and fresh HTTP keys for both specs", async () => { + for (const spec of ["draft-cavage-http-signatures-12", "rfc9421"] as const) { + const evidence = observation(); + const signed = await signRequest( + new Request("https://example.com/inbox", { method: "POST", body: "{}" }), + rsaPrivateKey2, + rsaPublicKey2.id!, + { spec }, + ); + const stale = rsaPublicKey1.clone({ id: rsaPublicKey2.id }); + const result = await verifyRequestDetailed(signed, { + ...loaders, + [verificationObservation]: evidence, + keyCache: { + get: () => Promise.resolve(stale), + set: () => Promise.resolve(), + }, + }); + strictEqual(result.verified, true); + const attempt = evidence.attempts[0]; + ok(attempt.status === "verified"); + strictEqual(attempt.checks.length, 1); + const check = attempt.checks[0]; + ok(check.status === "verified"); + strictEqual(check.triedKeys.length, 2); + strictEqual(check.triedKeys[0].publicKey, rsaPublicKey1.publicKey); + // The freshly loaded key has the same material as key2. + deepStrictEqual( + await crypto.subtle.exportKey("jwk", check.triedKeys[1].publicKey), + await crypto.subtle.exportKey("jwk", rsaPublicKey2.publicKey), + ); + strictEqual(check.key, check.triedKeys[1]); + strictEqual(attempt.signatures[0], check); + } +}); + +test("signature evidence retains the failed key when HTTP refresh cannot load", async () => { + for (const spec of ["draft-cavage-http-signatures-12", "rfc9421"] as const) { + const evidence = observation(); + const signed = await signRequest( + new Request("https://example.com/inbox", { method: "POST", body: "{}" }), + rsaPrivateKey2, + rsaPublicKey2.id!, + { spec }, + ); + const response = new Response(null, { status: 410 }); + const result = await verifyRequestDetailed(signed, { + ...loaders, + [verificationObservation]: evidence, + documentLoader: () => + Promise.reject(new FetchError(rsaPublicKey2.id!, "gone", response)), + keyCache: { + get: () => + Promise.resolve(rsaPublicKey1.clone({ id: rsaPublicKey2.id })), + set: () => Promise.resolve(), + }, + }); + strictEqual(result.verified, false); + const check = evidence.attempts[0].checks[0]; + ok(check.status === "rejected"); + strictEqual(check.reason.type, "keyFetchError"); + strictEqual(check.triedKeys[0].publicKey, rsaPublicKey1.publicKey); + } +}); + +test("signature evidence preserves failed LDS keys and successful stale-key refresh", async () => { + const activity = await new Create({ + actor: new URL("https://example.com/person"), + }).toJsonLd(loaders); + const signed = await signJsonLd( + activity, + rsaPrivateKey2, + rsaPublicKey2.id!, + loaders, + ); + const evidence = observation(); + // key2 has no owner, so crypto verifies but full LDS authentication rejects. + strictEqual( + await verifyJsonLd(signed, { + ...loaders, + [verificationObservation]: evidence, + keyCache: { + get: () => + Promise.resolve(rsaPublicKey1.clone({ id: rsaPublicKey2.id })), + set: () => Promise.resolve(), + }, + }), + false, + ); + const attempt = evidence.attempts[0]; + ok(attempt.status === "rejected"); + strictEqual(attempt.reason.type, "missingOwner"); + strictEqual(attempt.checks[0].status, "verified"); + strictEqual(attempt.checks[0].triedKeys.length, 2); + const bad = observation(); + strictEqual( + await verifyJsonLd(signed, { + ...loaders, + [verificationObservation]: bad, + documentLoader: async () => ({ + contextUrl: null, + documentUrl: rsaPublicKey2.id!.href, + document: await new CryptographicKey({ + id: rsaPublicKey2.id, + publicKey: rsaPublicKey1.publicKey, + }).toJsonLd(loaders), + }), + }), + false, + ); + strictEqual(bad.attempts[0].checks[0].status, "rejected"); + strictEqual(bad.attempts[0].checks[0].triedKeys.length, 1); +}); + +test("signature evidence preserves multiple valid proofs despite uncovered attribution", async () => { + const activity = new Create({ actor: new URL("https://example.com/person") }); + const first = await signObject( + activity, + ed25519PrivateKey, + ed25519Multikey.id!, + loaders, + ); + const second = await signObject( + first, + ed25519PrivateKey, + ed25519Multikey.id!, + loaders, + ); + const evidence = observation(); + strictEqual( + await verifyObject(Activity, await second.toJsonLd(loaders), { + ...loaders, + [verificationObservation]: evidence, + }), + null, + ); + const attempt = evidence.attempts[0]; + ok(attempt.status === "rejected"); + strictEqual(attempt.reason.type, "uncoveredAttribution"); + strictEqual(attempt.checks.length, 2); + ok(attempt.checks.every((check) => check.status === "verified")); +}); + +test("signature evidence preserves OIP stale keys when fresh verification fails", async () => { + const signed = await signObject( + new Create({ actor: ed25519Multikey.controllerId }), + ed25519PrivateKey, + ed25519Multikey.id!, + loaders, + ); + const pair = await crypto.subtle.generateKey("Ed25519", true, [ + "sign", + "verify", + ]) as CryptoKeyPair; + const stale = new Multikey({ + id: ed25519Multikey.id, + controller: null, + publicKey: pair.publicKey, + }); + const evidence = observation(); + strictEqual( + await verifyObject(Activity, await signed.toJsonLd(loaders), { + ...loaders, + [verificationObservation]: evidence, + keyCache: { + get: () => Promise.resolve(stale), + set: () => Promise.resolve(), + }, + documentLoader: async () => ({ + contextUrl: null, + documentUrl: ed25519Multikey.id!.href, + document: await stale.toJsonLd(loaders), + }), + }), + null, + ); + const check = evidence.attempts[0].checks[0]; + strictEqual(check.status, "rejected"); + strictEqual(check.triedKeys.length, 2); + strictEqual(check.triedKeys[0].publicKey, pair.publicKey); +}); + +test("OIP check preserves the literal declared key ID", async () => { + const signed = await signObject( + new Create({ actor: ed25519Multikey.controllerId }), + ed25519PrivateKey, + ed25519Multikey.id!, + loaders, + ); + const json = await signed.toJsonLd(loaders) as Record; + const proof = json.proof as Record; + const declaredKeyId = "https://EXAMPLE.com/person2#key4"; + proof.verificationMethod = declaredKeyId; + const evidence = observation(); + await verifyObject(Activity, json, { + ...loaders, + [verificationObservation]: evidence, + }); + strictEqual(evidence.attempts[0].checks[0].declaredKeyId, declaredKeyId); +}); + +test("signature observation cannot turn a cached miss into a metadata exception", async () => { + const json = await signJsonLd( + await new Create({ actor: new URL("https://example.com/person") }).toJsonLd( + loaders, + ), + rsaPrivateKey2, + rsaPublicKey2.id!, + loaders, + ); + const evidence = observation(); + const cache = { + get: () => Promise.resolve(null), + set: () => Promise.resolve(), + getFetchError: () => Promise.reject(new Error("diagnostic unavailable")), + }; + strictEqual( + await verifyJsonLd(json, { + ...loaders, + keyCache: cache, + [verificationObservation]: evidence, + }), + false, + ); + strictEqual(evidence.attempts[0].checks[0].status, "rejected"); +}); + +test("signature observation preserves rejection for consumed fetch-error responses", async () => { + const json = await signJsonLd( + await new Create({ actor: new URL("https://example.com/person") }).toJsonLd( + loaders, + ), + rsaPrivateKey2, + rsaPublicKey2.id!, + loaders, + ); + const response = new Response("gone", { status: 410 }); + await response.text(); + const error = new FetchError(rsaPublicKey2.id!, "gone", response); + const options = { + ...loaders, + documentLoader: () => Promise.reject(error), + }; + strictEqual(await verifyJsonLd(json, options), false); + const evidence = observation(); + strictEqual( + await verifyJsonLd(json, { + ...options, + [verificationObservation]: evidence, + }), + false, + ); + const check = evidence.attempts[0].checks[0]; + ok(check.status === "rejected" && check.reason.type === "keyFetchError"); + let cloneThrows = false; + try { + response.clone(); + } catch { + cloneThrows = true; + } + if (cloneThrows) { + ok("error" in check.reason.result); + strictEqual(check.reason.result.error, error); + } else { + ok("status" in check.reason.result); + strictEqual(check.reason.result.status, 410); + } +}); + +test("OIP check retains aliased declarations without extra context fetches", async () => { + const signed = await signObject( + new Create({ actor: ed25519Multikey.controllerId }), + ed25519PrivateKey, + ed25519Multikey.id!, + loaders, + ); + const json = await signed.toJsonLd(loaders) as Record; + const proof = json.proof as Record; + const context = { + vm: { + "@id": "https://w3id.org/security#verificationMethod", + "@type": "@id", + }, + }; + const contextUrl = "https://example.com/custom-proof-context"; + json["@context"] = [...json["@context"] as unknown[], contextUrl]; + proof["@context"] = [...proof["@context"] as unknown[], contextUrl]; + const declaredKeyId = "https://EXAMPLE.com/person2#key4"; + proof.vm = declaredKeyId; + delete proof.verificationMethod; + const run = async (evidence?: VerificationObservation) => { + let fetches = 0; + await verifyObject(Activity, structuredClone(json), { + ...loaders, + contextLoader: async (url, options) => { + fetches++; + if (url === contextUrl) { + return { + contextUrl: null, + documentUrl: url, + document: { "@context": context }, + }; + } + return await mockDocumentLoader(url, options); + }, + ...(evidence == null ? {} : { [verificationObservation]: evidence }), + }); + return fetches; + }; + const baselineFetches = await run(); + const evidence = observation(); + strictEqual(await run(evidence), baselineFetches); + strictEqual(evidence.attempts[0].checks[0].declaredKeyId, declaredKeyId); +}); + +test("OIP check preserves compact node identifiers and their aliases", async () => { + for (const idProperty of ["id", "rawId", "scopedId"]) { + const signed = await signObject( + new Create({ actor: ed25519Multikey.controllerId }), + ed25519PrivateKey, + ed25519Multikey.id!, + loaders, + ); + const json = await signed.toJsonLd(loaders) as Record; + const proof = json.proof as Record; + const context = { + rawId: "@id", + vm: { + "@id": "https://w3id.org/security#verificationMethod", + "@type": "@id", + "@context": { scopedId: "@id" }, + }, + }; + json["@context"] = [...json["@context"] as unknown[], context]; + proof["@context"] = [...proof["@context"] as unknown[], context]; + const declaredKeyId = "https://EXAMPLE.com/person2#key4"; + if (idProperty === "scopedId") { + proof.vm = { [idProperty]: declaredKeyId }; + delete proof.verificationMethod; + } else { + proof.verificationMethod = { [idProperty]: declaredKeyId }; + } + const evidence = observation(); + await verifyObject(Activity, json, { + ...loaders, + [verificationObservation]: evidence, + }); + strictEqual(evidence.attempts[0].checks[0].declaredKeyId, declaredKeyId); + } +}); + +test("signature evidence excludes keys loaded before canonicalization errors", async () => { + const signed = await signObject( + new Create({ actor: ed25519Multikey.controllerId }), + ed25519PrivateKey, + ed25519Multikey.id!, + loaders, + ); + const json = await signed.toJsonLd(loaders) as Record; + json.extra = JSON.parse("1e400"); + const evidence = observation(); + let thrown = false; + try { + await verifyObject(Activity, json, { + ...loaders, + [verificationObservation]: evidence, + }); + } catch { + thrown = true; + } + strictEqual(thrown, true); + const check = evidence.attempts[0].checks[0]; + strictEqual(check.status, "error"); + deepStrictEqual(check.triedKeys, []); +}); diff --git a/packages/fedify/src/sig/verification.ts b/packages/fedify/src/sig/verification.ts new file mode 100644 index 000000000..6ccc3a752 --- /dev/null +++ b/packages/fedify/src/sig/verification.ts @@ -0,0 +1,278 @@ +import type { + CompoundPortableObjectFailureReason, + CompoundProofDiscoveryFailureReason, +} from "./compound-proof.ts"; +import { CryptographicKey, type Multikey } from "@fedify/vocab"; +import type { HttpMessageSignaturesSpec } from "./http.ts"; +import type { FetchKeyErrorResult } from "./key.ts"; +import type { VerifyPortableObjectProofFailureReason } from "./proof.ts"; + +/** + * A snapshot of a key actually used to check a signature. + * @since 2.4.0 + */ +export type InboxVerificationKey = + | { + readonly type: "cryptographicKey"; + readonly id: URL | null; + readonly ownerId: URL | null; + readonly publicKey: CryptoKey; + } + | { + readonly type: "multikey"; + readonly id: URL | null; + readonly controllerId: URL | null; + readonly publicKey: CryptoKey; + }; + +/** + * Why a cryptographic check failed. + * @since 2.4.0 + */ +export type InboxSignatureFailureReason = + | { readonly type: "invalidSignature" } + | { + readonly type: "keyFetchError"; + readonly keyId: URL; + readonly result: FetchKeyErrorResult; + }; + +/** + * The signature or proof being checked. + * @since 2.4.0 + */ +export type InboxSignatureIdentity = + | { + readonly mechanism: "http"; + readonly spec: HttpMessageSignaturesSpec; + readonly label: string | null; + } + | { readonly mechanism: "linkedData" } + | { + readonly mechanism: "objectIntegrity"; + readonly proofId: string | null; + /** Index within this evaluation, not a global proof identifier. */ + readonly proofIndex: number | null; + }; + +/** + * Evidence from one signature/proof, including cached-key retries. + * @since 2.4.0 + */ +export type InboxSignatureCheck = + & InboxSignatureIdentity + & { + /** The declaration as received, including invalid IRIs. */ + readonly declaredKeyId: string | null; + /** Keys actually tried, in use order; refresh details are not a retry API. */ + readonly triedKeys: readonly InboxVerificationKey[]; + } + & ( + | { readonly status: "verified"; readonly key: InboxVerificationKey } + | { + readonly status: "rejected"; + readonly reason: InboxSignatureFailureReason; + } + | { readonly status: "error"; readonly error: unknown } + ); + +/** + * A bounded proof-policy diagnostic. + * @since 2.4.0 + */ +export type InboxProofPolicyFailureReason = + | VerifyPortableObjectProofFailureReason + | CompoundPortableObjectFailureReason + | CompoundProofDiscoveryFailureReason + | { + readonly type: "invalidObjectId" | "invalidDocument" | "subjectMismatch"; + }; + +/** + * Why a complete verification evaluation was rejected. + * @since 2.4.0 + */ +export type InboxVerificationFailureReason = + | { readonly type: "noSignature" } + | { readonly type: "signatureVerificationFailed" } + | { + readonly type: "uncoveredAttribution"; + readonly attributionIds: readonly URL[]; + } + | { readonly type: "missingOwner" } + | { + readonly type: "proofPolicy"; + readonly reason: InboxProofPolicyFailureReason; + }; + +/** + * A logical verification evaluation, separate from inbox authentication. + * @since 2.4.0 + */ +export type InboxVerificationAttempt = + & { + readonly mechanism: "http" | "linkedData" | "objectIntegrity"; + readonly subject: { + readonly id: URL | null; + /** RFC 6901 pointer; empty for the root, null when unavailable. */ + readonly pointer: string | null; + }; + readonly checks: readonly InboxSignatureCheck[]; + } + & ( + | { + readonly status: "verified"; + /** Direct references to successful members of checks. */ + readonly signatures: readonly Extract< + InboxSignatureCheck, + { status: "verified" } + >[]; + } + | { + readonly status: "rejected"; + readonly reason: InboxVerificationFailureReason; + } + | { readonly status: "error"; readonly error: unknown } + ); + +// Internal observation follows options, including recursive retries. It never +// runs application code inside a verifier or uses ambient/global request state. +export const verificationObservation: unique symbol = Symbol( + "verificationObservation", +); +export interface VerificationObservationOptions { + [verificationObservation]?: VerificationObservation; +} +export interface VerificationObservation { + readonly attempts: InboxVerificationAttempt[]; + readonly parsedObject?: (object: unknown) => void; + readonly subject?: { id: URL | null; pointer: string | null }; + readonly attempt?: AttemptBuilder; + readonly check?: CheckBuilder; +} +export interface AttemptBuilder { + checks: InboxSignatureCheck[]; + reason?: InboxVerificationFailureReason; +} +export interface CheckBuilder { + identity: InboxSignatureIdentity; + declaredKeyId: string | null; + triedKeys: InboxVerificationKey[]; + reason?: InboxSignatureFailureReason; +} + +export function snapshotKey( + key: CryptographicKey | Multikey, +): InboxVerificationKey { + if (key.publicKey == null) { + throw new TypeError("Verification key has no public key."); + } + const id = key.id == null ? null : new URL(key.id.href); + return key instanceof CryptographicKey + ? { + type: "cryptographicKey", + id, + ownerId: key.ownerId == null ? null : new URL(key.ownerId.href), + publicKey: key.publicKey, + } + : { + type: "multikey", + id, + controllerId: key.controllerId == null + ? null + : new URL(key.controllerId.href), + publicKey: key.publicKey, + }; +} + +export function triedKey( + options: VerificationObservationOptions, + key: CryptographicKey | Multikey, +): void { + const check = options[verificationObservation]?.check; + if (check != null) check.triedKeys.push(snapshotKey(key)); +} + +export async function observeCheck( + options: VerificationObservationOptions, + identity: InboxSignatureIdentity, + declaredKeyId: string | null, + operation: (observation: VerificationObservation) => Promise, +): Promise { + const observation = options[verificationObservation]; + if (observation?.attempt == null) { + return await operation(observation ?? { attempts: [] }); + } + const check: CheckBuilder = { identity, declaredKeyId, triedKeys: [] }; + const base = { ...identity, declaredKeyId, triedKeys: check.triedKeys }; + try { + const key = await operation({ ...observation, check }); + observation.attempt.checks.push( + key == null + ? { + ...base, + status: "rejected", + reason: check.reason ?? { type: "invalidSignature" }, + } + : { + ...base, + status: "verified", + key: check.triedKeys.at(-1) ?? snapshotKey(key), + }, + ); + return key; + } catch (error) { + observation.attempt.checks.push({ ...base, status: "error", error }); + throw error; + } +} + +export async function observeAttempt( + options: VerificationObservationOptions, + mechanism: InboxVerificationAttempt["mechanism"], + operation: (observation: VerificationObservation) => Promise, + isVerified: (value: T) => boolean, +): Promise { + const observation = options[verificationObservation]; + if (observation == null) return await operation({ attempts: [] }); + const attempt: AttemptBuilder = { checks: [] }; + const base = { + mechanism, + subject: observation.subject == null ? { id: null, pointer: "" } : { + id: observation.subject.id == null + ? null + : new URL(observation.subject.id.href), + pointer: observation.subject.pointer, + }, + checks: attempt.checks, + }; + try { + const value = await operation({ + ...observation, + subject: base.subject, + attempt, + check: undefined, + }); + observation.attempts.push( + isVerified(value) + ? { + ...base, + status: "verified", + signatures: attempt.checks.filter(( + check, + ): check is Extract => + check.status === "verified" + ), + } + : { + ...base, + status: "rejected", + reason: attempt.reason ?? { type: "signatureVerificationFailed" }, + }, + ); + return value; + } catch (error) { + observation.attempts.push({ ...base, status: "error", error }); + throw error; + } +} diff --git a/packages/testing/src/mock.test.ts b/packages/testing/src/mock.test.ts index cc3b453af..3f0b6ed9a 100644 --- a/packages/testing/src/mock.test.ts +++ b/packages/testing/src/mock.test.ts @@ -183,6 +183,13 @@ test("reset clears sent activities", async () => { assertEquals(mockFederation.sentActivities.length, 0); }); +test("MockFederation accepts inbox request observation registration", () => { + const federation = createFederation(); + const setters = federation.setInboxListeners("/users/{identifier}/inbox"); + assertStrictEquals(setters.onRequestFinished(() => {}), setters); + assertStrictEquals(setters.on(Create, () => {}), setters); +}); + test("receiveActivity triggers inbox listeners", async () => { // Provide contextData through constructor const mockFederation = createFederation<{ test: string }>({ diff --git a/packages/testing/src/mock.ts b/packages/testing/src/mock.ts index 560f5511e..958e93ff6 100644 --- a/packages/testing/src/mock.ts +++ b/packages/testing/src/mock.ts @@ -602,6 +602,9 @@ class MockFederation implements Federation { onUnverifiedActivity(): any { return this; }, + onRequestFinished(): any { + return this; + }, setSharedKeyDispatcher(): any { return this; }, From 302d780bf0d56dbe3e61ff712a04d00bd90aa535 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 00:28:22 +0900 Subject: [PATCH 006/184] Skip LDS checks without a usable signature Check the signature shape before opening an evidence entry. Unsigned objects and malformed signature values still produce rejected attempts, but no longer claim that a signature was checked. Cover absent and malformed signatures while preserving their distinct attempt failure reasons. https://github.com/fedify-dev/fedify/pull/1201#discussion_r4146232568 Assisted-by: Codex:gpt-6.1-sol --- packages/fedify/src/sig/ld.ts | 2 +- packages/fedify/src/sig/verification.test.ts | 26 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/fedify/src/sig/ld.ts b/packages/fedify/src/sig/ld.ts index 2b854f38a..6d009ca62 100644 --- a/packages/fedify/src/sig/ld.ts +++ b/packages/fedify/src/sig/ld.ts @@ -942,6 +942,7 @@ export async function verifySignature( jsonLd: unknown, options: VerifySignatureOptions = {}, ): Promise { + if (!hasSignature(jsonLd)) return null; if ( options[verificationObservation]?.attempt != null && options[verificationObservation]?.check == null @@ -958,7 +959,6 @@ export async function verifySignature( }), ); } - if (!hasSignature(jsonLd)) return null; const sig = jsonLd.signature; let signature: Uint8Array; try { diff --git a/packages/fedify/src/sig/verification.test.ts b/packages/fedify/src/sig/verification.test.ts index 48cad513f..9d223e9a2 100644 --- a/packages/fedify/src/sig/verification.test.ts +++ b/packages/fedify/src/sig/verification.test.ts @@ -25,6 +25,32 @@ function observation(): VerificationObservation { return { attempts: [] }; } +test("LDS evidence has no checks for absent or malformed signatures", async () => { + const json = await new Create({ actor: rsaPublicKey2.ownerId }).toJsonLd( + loaders, + ); + for (const signature of [undefined, null, "invalid", [], {}]) { + const evidence = observation(); + const value = signature === undefined + ? json + : { ...json as Record, signature }; + strictEqual( + await verifyJsonLd(value, { + ...loaders, + [verificationObservation]: evidence, + }), + false, + ); + const attempt = evidence.attempts[0]; + ok(attempt.status === "rejected"); + strictEqual( + attempt.reason.type, + signature === undefined ? "noSignature" : "signatureVerificationFailed", + ); + deepStrictEqual(attempt.checks, []); + } +}); + test("signature evidence preserves stale and fresh HTTP keys for both specs", async () => { for (const spec of ["draft-cavage-http-signatures-12", "rfc9421"] as const) { const evidence = observation(); From ae1f525f2c85a01eb4f85deb9695f4484a42e35d Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 00:30:37 +0900 Subject: [PATCH 007/184] Limit raw proof metadata to caller observations Skip context recording and raw key-ID extraction when only internal telemetry needs verification evidence. Apply this to local proofs and hydrated remote proofs while retaining raw declarations for callers that request observations. Compare observed and unobserved verification across all five proof entry points to cover the extra processing without changing results. https://github.com/fedify-dev/fedify/pull/1201#discussion_r4146232576 Assisted-by: Codex:gpt-6.1-sol --- packages/fedify/src/sig/proof.test.ts | 94 +++++++++++++++++++++++++ packages/fedify/src/sig/proof.ts | 46 +++++++----- packages/fedify/src/sig/verification.ts | 2 + 3 files changed, 126 insertions(+), 16 deletions(-) diff --git a/packages/fedify/src/sig/proof.test.ts b/packages/fedify/src/sig/proof.test.ts index 422e8309a..cf5a629c1 100644 --- a/packages/fedify/src/sig/proof.test.ts +++ b/packages/fedify/src/sig/proof.test.ts @@ -24,6 +24,7 @@ import { importMultibaseKey, parseIri, } from "@fedify/vocab-runtime"; +import jsonld from "@fedify/vocab-runtime/jsonld"; import { assert, assertEquals, @@ -49,12 +50,14 @@ import { createProof, hasProofLike, signObject, + verifyMapLocalProof, verifyObject, type VerifyObjectOptions, verifyPortableObjectProof, verifyProof, type VerifyProofOptions, } from "./proof.ts"; +import { verificationObservation } from "./verification.ts"; // Test vector from : const fep8b32TestVectorPrivateKey = await crypto.subtle.importKey( @@ -1363,6 +1366,97 @@ test("verifyProof() records verification duration metric", async (t) => { ); }); +test("proof verification processes raw declaration contexts only for observers", async (t) => { + const options = { + documentLoader: mockDocumentLoader, + contextLoader: mockDocumentLoader, + }; + const proofUrl = `ap://did:key:${portableDidMethod}/proofs/diagnostics`; + const signed = await signPortableJsonLd({ + "@context": portableContext, + id: `ap://did:key:${portableDidMethod}/objects/diagnostics`, + type: "Note", + attributedTo: `ap://did:key:${portableDidMethod}/actor`, + content: "Observed proof", + }, { proofOptions: { id: proofUrl } }); + const rawProof = signed.proof; + const proof = await DataIntegrityProof.fromJsonLd(rawProof, options); + const referenced = { ...signed }; + delete referenced.proof; + referenced["https://w3id.org/security#proof"] = { + "@graph": [{ "@id": proofUrl }], + }; + const cases: { + name: string; + verify: (options: VerifyProofOptions) => Promise; + }[] = [ + { + name: "object", + verify: async (options) => + await verifyObject(Note, structuredClone(signed), options) != null, + }, + { + name: "portable", + verify: async (options) => + (await verifyPortableObjectProof(structuredClone(signed), options)) + .verified, + }, + { + name: "map-local", + verify: async (options) => + await verifyMapLocalProof(structuredClone(signed), options) != null, + }, + { + name: "proof", + verify: async (options) => + await verifyProof(structuredClone(signed), proof, options) != null, + }, + { + name: "remote proof", + verify: async (options) => + await verifyObject(Note, structuredClone(referenced), { + ...options, + documentLoader: (url) => + Promise.resolve({ + contextUrl: null, + documentUrl: url, + document: structuredClone(rawProof), + }), + }) != null, + }, + ]; + for (const { name, verify } of cases) { + await t.step(name, async () => { + const original = jsonld.processContext; + let calls = 0; + jsonld.processContext = (...args: Parameters) => { + calls++; + return original(...args); + }; + try { + assert(await verify(options)); + const unobservedCalls = calls; + calls = 0; + assert( + await verify({ + ...options, + [verificationObservation]: { + attempts: [], + attempt: { checks: [] }, + }, + }), + ); + assert( + calls > unobservedCalls, + "Raw declaration processing should be absent from unobserved verification", + ); + } finally { + jsonld.processContext = original; + } + }); + } +}); + test("verifyPortableObjectProof()", async (t) => { const options: VerifyProofOptions = { documentLoader() { diff --git a/packages/fedify/src/sig/proof.ts b/packages/fedify/src/sig/proof.ts index 7e13a18cf..29162260b 100644 --- a/packages/fedify/src/sig/proof.ts +++ b/packages/fedify/src/sig/proof.ts @@ -711,7 +711,11 @@ async function verifyProofWithMessageDigestCache( proof, { ...options, - [verificationObservation]: { attempts: [], attempt: { checks: [] } }, + [verificationObservation]: { + attempts: [], + attempt: { checks: [] }, + captureRawKeyIds: false, + }, }, messageDigestCache, rawProofCandidate, @@ -1165,7 +1169,10 @@ async function parseRawProofCandidates( const candidates: RawProofCandidate[] = []; for (const value of values) { let parsed: DataIntegrityProof | null = null; - const contexts = recordProofContexts(documentLoader); + const contexts = options[verificationObservation] != null && + options[verificationObservation]?.captureRawKeyIds !== false + ? recordProofContexts(documentLoader) + : undefined; if (isJsonLdNode(value)) { const proofJsonLd = value["@context"] == null && jsonLd["@context"] != null @@ -1174,7 +1181,7 @@ async function parseRawProofCandidates( try { parsed = await DataIntegrityProof.fromJsonLd( proofJsonLd, - { ...options, contextLoader: contexts.loader }, + { ...options, contextLoader: contexts?.loader ?? documentLoader }, ); } catch { // Malformed sibling proofs cannot match a typed proof. @@ -1184,11 +1191,13 @@ async function parseRawProofCandidates( value, proof: parsed, reference: getRawProofReference(value) ?? parsed?.id?.href, - declaredKeyId: await getAliasedDeclaredProofKeyId( - value, - jsonLd["@context"], - contexts.replay, - ), + declaredKeyId: contexts == null + ? undefined + : await getAliasedDeclaredProofKeyId( + value, + jsonLd["@context"], + contexts.replay, + ), }); } return candidates; @@ -2422,7 +2431,7 @@ export async function verifyObject( const observedOptions = { ...options, [verificationObservation]: options[verificationObservation] ?? - { attempts: [] }, + { attempts: [], captureRawKeyIds: false }, }; const tracer = (options.tracerProvider ?? trace.getTracerProvider()) .getTracer(metadata.name, metadata.version); @@ -2524,13 +2533,16 @@ export async function verifyObject( if (candidateIndex >= 0) { hydratedCandidates.add(candidateIndex); let parsed: DataIntegrityProof | null = null; - const contexts = recordProofContexts(proofContextLoader); + const contexts = options[verificationObservation] != null && + options[verificationObservation]?.captureRawKeyIds !== false + ? recordProofContexts(proofContextLoader) + : undefined; try { parsed = await DataIntegrityProof.fromJsonLd( remoteDocument.document, { documentLoader: baseDocumentLoader, - contextLoader: contexts.loader, + contextLoader: contexts?.loader ?? proofContextLoader, tracerProvider: options.tracerProvider, baseUrl: parseIri(remoteDocument.documentUrl), }, @@ -2542,11 +2554,13 @@ export async function verifyObject( value: structuredClone(remoteDocument.document), proof: parsed, reference, - declaredKeyId: await getAliasedDeclaredProofKeyId( - remoteDocument.document, - undefined, - contexts.replay, - ), + declaredKeyId: contexts == null + ? undefined + : await getAliasedDeclaredProofKeyId( + remoteDocument.document, + undefined, + contexts.replay, + ), }; } return remoteDocument; diff --git a/packages/fedify/src/sig/verification.ts b/packages/fedify/src/sig/verification.ts index 6ccc3a752..5008f23a7 100644 --- a/packages/fedify/src/sig/verification.ts +++ b/packages/fedify/src/sig/verification.ts @@ -145,6 +145,8 @@ export interface VerificationObservationOptions { } export interface VerificationObservation { readonly attempts: InboxVerificationAttempt[]; + /** False for internal telemetry collectors; observers capture raw IDs by default. */ + readonly captureRawKeyIds?: boolean; readonly parsedObject?: (object: unknown) => void; readonly subject?: { id: URL | null; pointer: string | null }; readonly attempt?: AttemptBuilder; From e8ede09918acadeb6303a13d01f3d20c68ea7bef Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 00:30:53 +0900 Subject: [PATCH 008/184] Cover dispatch context failures in inbox reports Verify that an inbox context factory failure is recorded before the application error hook runs, even when that hook also throws. The report must retain verified authentication and the original listener failure without invoking the listener. The existing dispatch wrapper already preserves this outcome, so cover it with a regression test rather than adding a redundant assignment. https://github.com/fedify-dev/fedify/pull/1201#pullrequestreview-5368263447 Changelog: none Assisted-by: Codex:gpt-6.1-sol --- .../fedify/src/federation/handler.test.ts | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/packages/fedify/src/federation/handler.test.ts b/packages/fedify/src/federation/handler.test.ts index 8beb8344d..4d33cac6f 100644 --- a/packages/fedify/src/federation/handler.test.ts +++ b/packages/fedify/src/federation/handler.test.ts @@ -1580,6 +1580,77 @@ test("handleCollection() records not_found collection metrics", async () => { ); }); +test("handleInbox() reports dispatch context errors before a failing error hook", async () => { + const kv = new MemoryKvStore(); + const federation = createFederation({ kv }); + const request = await signRequest( + new Request("https://example.com/inbox", { + method: "POST", + body: JSON.stringify( + await new Create({ + actor: rsaPublicKey3.ownerId, + }).toJsonLd({ contextLoader: mockDocumentLoader }), + ), + }), + rsaPrivateKey3, + rsaPublicKey3.id!, + ); + const context = createRequestContext({ + federation, + request, + url: new URL(request.url), + data: undefined, + documentLoader: mockDocumentLoader, + contextLoader: mockDocumentLoader, + }); + const error = new Error("Cannot create dispatch context"); + const reports: InboxRequestReport[] = []; + const listeners = new ActivityListenerSet>(); + let listenerCalled = false; + listeners.add(Create, () => { + listenerCalled = true; + }); + let errorHookCalled = false; + const response = await handleInbox(request, { + context, + recipient: null, + kv, + kvPrefixes: { + activityIdempotence: ["activity"], + publicKey: ["key"], + acceptSignatureNonce: ["nonce"], + }, + actorDispatcher: () => new Person({}), + inboxListeners: listeners, + inboxContextFactory: () => { + throw error; + }, + inboxErrorHandler: (_ctx, value) => { + assertEquals(value, error); + errorHookCalled = true; + throw new Error("Error hook failed"); + }, + inboxRequestFinishedHandler: (_ctx, report) => { + reports.push(report); + }, + onNotFound: () => new Response(null, { status: 404 }), + signatureTimeWindow: false, + skipSignatureVerification: false, + }); + assertEquals(response.status, 500); + assertEquals(listenerCalled, false); + assertEquals(errorHookCalled, true); + assertEquals(reports.length, 1); + assertEquals(reports[0].authentication.status, "verified"); + assertEquals(reports[0].outcome, { + type: "response", + status: 500, + disposition: "failed", + reason: "listenerError", + error, + }); +}); + test("handleInbox()", async () => { const activity = new Create({ id: new URL("https://example.com/activities/1"), From d2d67387561e2d1ed8c28df40d1eb3aec37aec0b Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Wed, 30 Sep 2026 22:05:08 +0900 Subject: [PATCH 009/184] Accept tootik's unmapped portable gateways Tootik v0.25.4 emits portable actors with valid JCS proofs but no JSON-LD mapping for gateways. Fedify previously dropped the list and rejected the actor with invalidGateways. Share gateway decoding between generated actor classes and portable proof validation. Accept unmapped ActivityStreams gateways only for portable actors, and require JCS proofs before trusting that list. Preserve explicit mappings and the original signed JSON. Include the unchanged actor captured from the pinned tootik binary, regressions for actor lookup, key ownership, collections and tampering, all three generator snapshots and documentation. FEP-ef61 support has not been released, so this refinement needs no separate changelog entry. https://github.com/fedify-dev/fedify/issues/1097 Changelog: none Assisted-by: Codex:gpt-6.1-sol --- FEDERATION.md | 20 +++ docs/manual/send.md | 7 +- docs/manual/vocab.md | 6 + .../fedify/src/sig/portable-interop.test.ts | 97 +++++++++++++ packages/fedify/src/sig/proof.test.ts | 132 ++++++++++++++++++ packages/fedify/src/sig/proof.ts | 25 +++- .../fep-ef61/tootik-v0.25.4/README.md | 107 ++++++++++++++ .../fep-ef61/tootik-v0.25.4/actor.body | 1 + .../fep-ef61/tootik-v0.25.4/actor.json | 68 +++++++++ .../fep-ef61/tootik-v0.25.4/metadata.json | 54 +++++++ .../src/internal/jsonld-cache.ts | 38 ++++- .../vocab-runtime/src/jsonld-cache.test.ts | 89 ++++++++++++ .../src/__snapshots__/class.test.ts.deno.snap | 11 +- .../src/__snapshots__/class.test.ts.node.snap | 11 +- .../src/__snapshots__/class.test.ts.snap | 11 +- packages/vocab-tools/src/class.ts | 1 + packages/vocab-tools/src/codec.ts | 5 +- packages/vocab/src/vocab.test.ts | 69 +++++++++ 18 files changed, 728 insertions(+), 24 deletions(-) create mode 100644 packages/fedify/src/sig/portable-interop.test.ts create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/README.md create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/actor.body create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/actor.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/metadata.json diff --git a/FEDERATION.md b/FEDERATION.md index 1f6325865..d02519668 100644 --- a/FEDERATION.md +++ b/FEDERATION.md @@ -30,6 +30,7 @@ Supported FEPs - [FEP-9091][]: Export Actor Service Endpoint - [FEP-f1d5][]: NodeInfo in Fediverse Software - [FEP-8b32][]: Object Integrity Proofs + - [FEP-ef61][]: Portable objects - [FEP-521a][]: Representing actor's public keys - [FEP-5feb][]: Search indexing consent for actors - [FEP-fe34][]: Origin-based security model @@ -49,6 +50,7 @@ Supported FEPs [FEP-9091]: https://w3id.org/fep/9091 [FEP-f1d5]: https://w3id.org/fep/f1d5 [FEP-8b32]: https://w3id.org/fep/8b32 +[FEP-ef61]: https://w3id.org/fep/ef61 [FEP-521a]: https://w3id.org/fep/521a [FEP-5feb]: https://w3id.org/fep/5feb [FEP-fe34]: https://w3id.org/fep/fe34 @@ -91,6 +93,24 @@ profile. [portable objects]: https://fedify.dev/manual/portable +FEP-ef61 interoperability +------------------------- + +Fedify accepts the portable `Application` actor captured from tootik v0.25.4 +(commit `5ce4b7fe074d7c385808be387ffcda7040842a19`), including its HTTPS +compatible identifier and `eddsa-jcs-2022` Object Integrity Proof. The actor +omits the JSON-LD mapping for `gateways`; Fedify reads that list and requires +JCS proofs to authenticate the original JSON. The unchanged response and +capture procedure are recorded in the [tootik fixture]. + +This result covers actor parsing and proof verification. Incoming HTTP +Signatures and activities captured from tootik, acceptance of Fedify output +by other implementations, and live Mitra/Mastodon interoperability remain +unverified. + +[tootik fixture]: packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/README.md + + ActivityPub ----------- diff --git a/docs/manual/send.md b/docs/manual/send.md index 3dee80ba1..eec1a4431 100644 --- a/docs/manual/send.md +++ b/docs/manual/send.md @@ -1169,7 +1169,12 @@ proof must use a DID URL, and that DID must match the authority of the portable object ID. A portable actor must also have a non-empty `gateways` list whose items are all HTTP(S) URIs with an empty path, query, and fragment; this is checked before the proofs, so the `invalidGateways` reason does not mean that -the proofs are valid. The detailed result distinguishes documents outside the +the proofs are valid. When a portable actor omits the JSON-LD mapping for +`gateways`, as tootik v0.25.4 does, Fedify accepts the otherwise unmapped +ActivityStreams term only if every proof uses `eddsa-jcs-2022`. These proofs +authenticate the original JSON, including the gateway list. + +The detailed result distinguishes documents outside the policy, missing or invalid proofs, actors without valid gateways, unsupported verification methods, DID mismatches, and successful verification: diff --git a/docs/manual/vocab.md b/docs/manual/vocab.md index 6bc2225f3..6dd64fa62 100644 --- a/docs/manual/vocab.md +++ b/docs/manual/vocab.md @@ -266,6 +266,12 @@ const actor = new Person({ Each gateway must be an HTTP(S) base URI with no path, query, or fragment. +For portable actors with inbox and outbox properties, Fedify also reads an +unmapped `gateways` term under the ActivityStreams context, as emitted by +tootik v0.25.4. Explicit JSON-LD mappings take precedence. Parsing this list +does not authenticate it; use portable object verification before trusting +the actor or its gateways. + Software that does not understand portable IRIs can still refer to portable objects through *compatible identifiers*: HTTP(S) URLs under a gateway's fixed `/.well-known/apgateway/` path. Use `toCompatibleEf61Id()` to build diff --git a/packages/fedify/src/sig/portable-interop.test.ts b/packages/fedify/src/sig/portable-interop.test.ts new file mode 100644 index 000000000..281c9f744 --- /dev/null +++ b/packages/fedify/src/sig/portable-interop.test.ts @@ -0,0 +1,97 @@ +import { mockDocumentLoader, test } from "@fedify/fixture"; +import { Application, DataIntegrityProof, lookupObject } from "@fedify/vocab"; +import { assert, assertEquals } from "@std/assert"; +import actor from "../../test-vectors/fep-ef61/tootik-v0.25.4/actor.json" with { + type: "json", +}; +import { verifyPortableObjectProof, verifyProof } from "./proof.ts"; +import { getKeyOwner } from "./owner.ts"; +import { verifyPortableObject } from "./portable-collection.ts"; + +const options = { + contextLoader: mockDocumentLoader, + documentLoader() { + throw new TypeError("The captured did:key proof must resolve locally"); + }, +}; + +test("tootik v0.25.4 actor has a valid DID proof", async () => { + const proof = await DataIntegrityProof.fromJsonLd(actor.proof, options); + const key = await verifyProof(actor, proof, options); + assert(key != null); + assertEquals(key.id?.href, actor.proof.verificationMethod); +}); + +test("tootik v0.25.4 actor proof rejects tampering", async () => { + const proof = await DataIntegrityProof.fromJsonLd(actor.proof, options); + assertEquals( + await verifyProof( + { ...actor, preferredUsername: "tampered" }, + proof, + options, + ), + null, + ); +}); + +test("tootik v0.25.4 actor retains its unmapped gateways", async () => { + const original = structuredClone(actor); + assertEquals(actor.gateways, ["https://tootik.example"]); + const parsed = await Application.fromJsonLd(actor, options); + assertEquals(parsed.id?.href, actor.id); + assertEquals(parsed.gateways, [new URL("https://tootik.example")]); + assert((await verifyPortableObjectProof(actor, options)).verified); + assertEquals(actor, original); +}); + +const loadedOptions = { + contextLoader: mockDocumentLoader, + documentLoader(url: string) { + assertEquals(url.split("#")[0], actor.id); + return Promise.resolve({ + document: structuredClone(actor), + documentUrl: actor.id, + contextUrl: null, + }); + }, +}; + +test("tootik v0.25.4 actor can be looked up and own a gateway key", async () => { + const parsed = await lookupObject(actor.id, { + ...loadedOptions, + verifyPortableObject: verifyPortableObjectProof, + }); + assert(parsed instanceof Application); + assertEquals(parsed.gateways, [new URL("https://tootik.example")]); + const owner = await getKeyOwner(new URL(actor.publicKey.id), loadedOptions); + assert(owner != null); + assertEquals(owner.id?.href, actor.id); + assertEquals(owner.gateways, [new URL("https://tootik.example")]); +}); + +test("tootik v0.25.4 actor authenticates its gateway for collections", async () => { + // The collection is synthetic; its owner is the unchanged captured actor. + const result = await verifyPortableObject({ + "@context": "https://www.w3.org/ns/activitystreams", + id: actor.outbox, + type: "OrderedCollection", + attributedTo: actor.id, + orderedItems: [], + }, { ...loadedOptions, documentUrl: new URL(actor.outbox) }); + assert(result.verified); + assertEquals(result.method, "gateway"); + if (result.method === "gateway") { + assertEquals(result.gateway, new URL("https://tootik.example")); + } +}); + +test("tootik v0.25.4 actor rejects tampered gateways", async () => { + const result = await verifyPortableObjectProof({ + ...actor, + gateways: ["https://attacker.example"], + }, options); + assertEquals(result, { + verified: false, + reason: { type: "invalidProof", proofIndex: 0 }, + }); +}); diff --git a/packages/fedify/src/sig/proof.test.ts b/packages/fedify/src/sig/proof.test.ts index 422e8309a..7ba4234b3 100644 --- a/packages/fedify/src/sig/proof.test.ts +++ b/packages/fedify/src/sig/proof.test.ts @@ -1675,6 +1675,138 @@ test("verifyPortableObjectProof()", async (t) => { ); }); + await t.step( + "verifies JCS-signed actors with unmapped gateways", + async () => { + for ( + const id of [ + `ap+ef61://${portableDid}/actor`, + `https://gateway.example/.well-known/apgateway/${portableDid}/actor`, + ] + ) { + const actor = { + "@context": portableContext, + id, + type: "Person", + inbox: `${id}/inbox`, + outbox: `${id}/outbox`, + gateways: ["https://gateway.example", "https://other.example"], + }; + const signed = await signPortableJsonLd(actor); + const original = structuredClone(signed); + assert((await verifyPortableObjectProof(signed, options)).verified); + assertEquals(signed, original); + assertEquals( + await verifyPortableObjectProof({ + ...signed, + gateways: ["https://attacker.example"], + }, options), + { verified: false, reason: { type: "invalidProof", proofIndex: 0 } }, + ); + } + }, + ); + + await t.step("rejects malformed unmapped actor gateways", async () => { + const id = `ap+ef61://${portableDid}/actor`; + for ( + const gateways of [ + [], + ["https://gateway.example", 42], + [{ bad: "https://gateway.example" }], + ["ftp://gateway.example"], + ["https://gateway.example/path"], + ["https://gateway.example/?query"], + ["https://gateway.example/#fragment"], + ["https://user:password@gateway.example"], + ] + ) { + assertEquals( + await verifyPortableObjectProof( + await signPortableJsonLd({ + "@context": portableContext, + id, + type: "Person", + inbox: `${id}/inbox`, + outbox: `${id}/outbox`, + gateways, + }), + options, + ), + { verified: false, reason: { type: "invalidGateways" } }, + JSON.stringify(gateways), + ); + } + }); + + await t.step( + "does not replace context-defined gateway semantics", + async () => { + const id = `ap+ef61://${portableDid}/actor`; + const actor = { + "@context": portableContext, + id, + type: "Person", + inbox: `${id}/inbox`, + outbox: `${id}/outbox`, + gateways: ["https://gateway.example"], + }; + const property = "https://w3id.org/fep/ef61/gateways"; + for ( + const extra of [ + { [property]: { "@list": [] } }, + { [property]: { "@list": [{ "@id": "https://bad.example/path" }] } }, + { "@context": [...portableContext, { gateways: null }] }, + { + "@context": [ + ...portableContext, + { gateways: "https://other.example/gateways" }, + ], + }, + { + "@context": [ + ...portableContext, + { + Person: { + "@id": "https://www.w3.org/ns/activitystreams#Person", + "@context": { gateways: null }, + }, + }, + ], + }, + ] + ) { + assertEquals( + await verifyPortableObjectProof( + await signPortableJsonLd({ ...actor, ...extra }), + options, + ), + { verified: false, reason: { type: "invalidGateways" } }, + JSON.stringify(extra), + ); + } + assert( + (await verifyPortableObjectProof( + await signPortableJsonLd({ + ...actor, + gateways: ["https://bad.example/path"], + [property]: { "@list": [{ "@id": "https://canonical.example" }] }, + }), + options, + )).verified, + ); + assertEquals( + await verifyPortableObjectProof( + await signPortableJsonLd(actor, { + proofOptions: { cryptosuite: "eddsa-rdfc-2022" }, + }), + options, + ), + { verified: false, reason: { type: "invalidGateways" } }, + ); + }, + ); + await t.step("checks gateways only for FEP-2277 actors", async () => { // Without an outbox, a Person is not an actor by FEP-2277: const result = await verifyPortableObjectProof( diff --git a/packages/fedify/src/sig/proof.ts b/packages/fedify/src/sig/proof.ts index 2f4b66a45..36b64951b 100644 --- a/packages/fedify/src/sig/proof.ts +++ b/packages/fedify/src/sig/proof.ts @@ -17,6 +17,7 @@ import { type PortableObjectVerifier, type RemoteDocument, } from "@fedify/vocab-runtime"; +import { getPortableActorGateways } from "@fedify/vocab-runtime/internal/jsonld-cache"; import { isPlainJsonTree, retainSignedRepresentation, @@ -1590,7 +1591,6 @@ const FEP_2277_COLLECTION_PROPERTIES = [ "prev", "current", ].map((property) => AS_NAMESPACE + property); -const FEP_EF61_GATEWAYS = "https://w3id.org/fep/ef61/gateways"; const PORTABLE_OBJECT_ID_PATTERN = /^ap(?:\+ef61)?:\/\//i; const FUNCTIONAL_PROOF_PROPERTIES = [ `${SECURITY_NAMESPACE}cryptosuite`, @@ -1634,14 +1634,18 @@ function hasValidPortableProofShape(proofValue: unknown): boolean { * FEP-ef61 requires: a non-empty list whose items are all HTTP(S) URIs with * an empty path, query, and fragment. Like the generated vocabulary decoder, * this also tolerates a plain set of values instead of a `@list`, and gateway - * strings given as `@value`s instead of `@id`s. + * strings given as `@value`s instead of `@id`s. JCS-authenticated actors may + * also supply an unmapped literal `gateways` list. */ -function hasValidPortableActorGateways(node: Record): boolean { - const values = node[FEP_EF61_GATEWAYS]; +function hasValidPortableActorGateways( + node: Record, + allowUnmapped: boolean, +): boolean { + const values = getPortableActorGateways(node, allowUnmapped); if (!Array.isArray(values)) return false; let items: unknown = values; if (values.some((value) => isJsonLdNode(value) && "@list" in value)) { - if (values.length !== 1) return false; + if (values.length !== 1 || !isJsonLdNode(values[0])) return false; items = values[0]["@list"]; } if (!Array.isArray(items) || items.length < 1) return false; @@ -1951,7 +1955,14 @@ async function preparePortableObjectProof( // FEP-ef61 requires a portable actor to list where it can be retrieved. // This is checked before any key is resolved, since the document is // rejected whether or not its proofs are valid: - if (objectType === "actor" && !hasValidPortableActorGateways(root)) { + if ( + objectType === "actor" && + !hasValidPortableActorGateways( + root, + // JCS authenticates unmapped JSON properties, unlike RDF-based suites. + proofs.every((proof) => proof.cryptosuite === "eddsa-jcs-2022"), + ) + ) { return { prepared: false, root, @@ -2048,6 +2059,8 @@ export async function verifyPortableObjectProofPolicy( * and fragment; otherwise, it is rejected with the `invalidGateways` reason * before its proofs are verified. The proofs are verified over the document as * given; a compatible identifier is never rewritten into a portable ID. + * An unmapped literal `gateways` property is also accepted when every proof + * uses `eddsa-jcs-2022`, which authenticates the original JSON properties. * * [FEP-ef61]: https://w3id.org/fep/ef61 * diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/README.md b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/README.md new file mode 100644 index 000000000..56725eedf --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/README.md @@ -0,0 +1,107 @@ +Tootik v0.25.4 actor capture +============================ + +This fixture records Fedify's verification of a tootik actor captured for +[#1097]. It was captured +from the official Linux amd64 binary for tootik v0.25.4, whose tag points to +commit 5ce4b7fe074d7c385808be387ffcda7040842a19. The unmodified binary created +its default portable `Application` actor in a fresh SQLite database. + +*actor.body* is the exact HTTP response body. *actor.json* contains the same +JSON values and member order, with whitespace formatted for repository checks. +*metadata.json* records the binary and response hashes, capture URL/time, +context snapshots, and the Fedify commit used for the baseline verification. No +private keys or database files are included. + +The server listened only on loopback. HTTPS requests used a self-signed +certificate trusted explicitly by curl, with `--connect-to` routing the +`tootik.example` authority to the local listener. This check does not establish +public federation or acceptance of Fedify output by tootik. + +The three remote contexts declared by the actor were fetched with +`Accept: application/ld+json`. Their parsed JSON values matched the existing +`@fedify/fixture` snapshots listed in *metadata.json*, so the offline tests +reuse those snapshots. + +[#1097]: https://github.com/fedify-dev/fedify/issues/1097 + + +Baseline result +--------------- + +At Fedify commit 3d507d94631110b066056a16618b907a75e8e7ff: + + - `verifyProof()` accepted the original `eddsa-jcs-2022` proof and resolved + its `did:key` verification method without fetching a key document. + - Changing `preferredUsername` caused proof verification to fail. + - The raw actor contained `gateways: ["https://tootik.example"]`, but + `Application.fromJsonLd()` decoded an empty gateway list. None of the + declared contexts maps `gateways` to + `https://w3id.org/fep/ef61/gateways`. + - `verifyPortableObjectProof()` rejected the original actor with + `{ verified: false, reason: { type: "invalidGateways" } }`. + +The regression tests in *src/sig/portable-interop.test.ts* now require the +unchanged captured actor to pass `verifyPortableObjectProof()` and expose +`https://tootik.example/` in its decoded gateway list. Fedify accepts the +otherwise unmapped `gateways` term on this portable actor because its +`eddsa-jcs-2022` proof signs the original JSON, including that list. The actor +has not been repaired or re-signed. + +This fixture covers actor parsing and proof verification. It does not contain +an incoming HTTP Signature or an activity captured from tootik, and does not +establish acceptance of Fedify output by tootik, Mitra, or Mastodon. + + +Capture procedure +----------------- + +Run the following on Linux amd64. Each fresh database produces new public +keys and a new proof, so its response hash will differ from this fixture. + +~~~~ bash +capture_dir=$(mktemp -d) +cd "$capture_dir" +curl --fail --location --output tootik \ + https://github.com/dimkr/tootik/releases/download/v0.25.4/tootik-amd64 +chmod u+x tootik +./tootik -version +sha256sum tootik + +openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \ + -nodes -keyout tls-key.pem -out tls-cert.pem -days 2 \ + -subj /CN=tootik.example -addext subjectAltName=DNS:tootik.example + +./tootik -domain tootik.example -addr 127.0.0.1:18443 \ + -gemaddr 127.0.0.1:11965 -db db.sqlite3 \ + -cert tls-cert.pem -key tls-key.pem \ + -gemcert tls-cert.pem -gemkey tls-key.pem >server.log 2>&1 & +tootik_pid=$! +trap 'kill "$tootik_pid" 2>/dev/null; wait "$tootik_pid" 2>/dev/null' EXIT + +curl --fail --retry 10 --retry-connrefused --retry-delay 1 --max-time 5 \ + --noproxy '*' --cacert tls-cert.pem \ + --connect-to tootik.example:443:127.0.0.1:18443 \ + -H 'Accept: application/activity+json' \ + --output actor-alias.json https://tootik.example/actor +actor_url=$(python3 -c 'import json; print(json.load(open("actor-alias.json"))["id"])') +curl --fail --max-time 5 --noproxy '*' --cacert tls-cert.pem \ + --connect-to tootik.example:443:127.0.0.1:18443 \ + -H 'Accept: application/activity+json' \ + --dump-header actor.headers --output actor.body "$actor_url" +date -u +sha256sum actor.body +~~~~ + +Use a domain without an explicit port in `-domain`. In an earlier capture +with `-domain tootik.example:18443`, tootik emitted an HTTPS proof verification +method instead of a `did:key` method. Its gateway URL regular expression does +not recognize an authority containing a port. Fedify rejected that document +with `unsupportedVerificationMethod`. The fixture uses +`-domain tootik.example`, which produced a `did:key` verification method. + +Replay the recorded fixture from the Fedify repository root with: + +~~~~ bash +mise run test:deno packages/fedify/src/sig/portable-interop.test.ts +~~~~ diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/actor.body b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/actor.body new file mode 100644 index 000000000..f8e3897d0 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/actor.body @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/v1"],"id":"https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor","type":"Application","inbox":"https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor/inbox","outbox":"https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor/outbox","preferredUsername":"actor","followers":"https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor/followers","publicKey":{"id":"https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor#main-key","owner":"https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr70sLuCyvDBKblca6Jsk\nJW5ZmTpmyFK4gY6dpDkjvsokBjTR6oUO5GF7QGT4xGaGDtnzhd+K0/IE2Jo2cbBu\nTAK92xo3qB4nL+0XIfqXK/ju/pIo4ClZ1oHYNeJnmjGDAJmZmaf9/b0sd0osfTPX\nWSqAkgZuxZYrWSXKs6WYuEJof5YfTHgH5PBzwtQGyexZKYkumyrq5lazeEvqBLyx\nyNc5u6LdkkHP+HR9DJIQ3CDv6d1yQ7ELiP5pXvKRV9jJKlBQ1TK1vlMGC8GcBlDy\nQT0UsbM/1lRbxnbbqiwY6rFlT6FpHd5cl9tblGU6sF9gyCDATCHAdZ/2laUzParD\n+QIDAQAB\n-----END PUBLIC KEY-----\n"},"icon":[{"type":"Image","mediaType":"image/gif","url":"https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor/icon.gif"}],"manuallyApprovesFollowers":false,"assertionMethod":[{"id":"https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor#ed25519-key","type":"Multikey","controller":"https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor","publicKeyMultibase":"z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE"},{"id":"https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor#ml-dsa-44-key","type":"Multikey","controller":"https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor","publicKeyMultibase":"ukCRpmFGeqQvqCAsbrRIKdfH1ZD2Y-2NiDr5tmgYFceiWCipFyeJKL65fEBcHa3gIBJbuzwvTfFeiMppDxvQySHhXFMf12o2mZ1d9Rw5fP9JKxSgCH7TyjeXEsvN6Zv_3q3ignCU3UxQKL5q2Yks9bfQkDxPJdDvzgyP5D0lDWulx1I9wyQS_f0SXG-Muph2rHBIT_u30ZuN7PHNNk7VAv4AWn7DlbJ6h2871YgFD7YHmtZiq_YCWerBe9TPBAoIOYEY1LV_nPVEe5xDIBlQ2EXYcfJviKQ1rB1iP4c0uoxdGm1RLDOXd65EDmtzil_R1Y5Le4s5td6AV2iFanIQtoJabH1IfL3Ju9n1nM-X3T8YM5FCngvoFME7UxhUHUggZ7vbWy_hy99tRvlaPG3U2OogtyPELx1o91itRjVH276UB8frLb06oJj6RzHE8pwfImH7POETjxEMPzfX4RA7BQVge6TU3fiBx4V4wmofJ3eiMu6yo497mUjJMiFjnt4AC1xiY8_XzdAauJag55HjKDf1xKNHIpQe2IE_n2zJvjfh__coWwl5qJLyszAVBZTn-MTg8nS--PTZMZPaDJSwk9NAT6qdCAnaP5PPkoWlTedCVbDNE-az45x9rKs3sob1OVoJW-2Ogf0S37noPe3L2lfUidr32k5fXPCsg3GfB0F5ZS9sQ-ZBzQvgchArohI1DnX9cbObTj4bGrJu_N9SPFLp0jYQb5bujeIDdpiVu46PVbv4fV4gxQAt4XPZLExZq_WQhKVVn3A89NU6qwxKsAp1LWoouehQSSNaC-Wif7ev5vaCSE0eeTOCO0Ip1URirY7hKhjbp-hfAMx_Vnoj5gQeiRQkUW2oxkgXEpfdzJDvVoeaTmJ_k3soJlJYjp9ZJAc9qn8ygsFpRKFMUYZQL3Wcj7vFxjlX_42a-5p0_0UHA7JjK3UlvE_nG9cIeoqU-WgygEU9rf1CCJflppbwXMFmBQvJ1oMDoutbZTuDIdnRO5DVQ4uNEPyT3p_kv0smEGU3lzZERTYHPM-CNEF5Pk2rrVea9WxpC0TG2njHxmHsO0nCWmUgoB3cAMWpby-YBaen1xvXt5po7ge5KD3SC_cXMSLAJem_ZMVWtR070zXCJdsoB-GN8nFTchyjPpI6SLxXcVwWXNEzI_dEvcx0YTEwlI9OEDuF2rizU4UzZMIT_Ec5OgEehh-o0MLpgLRvLo15TOz0FFZfaKYWfVS6CEBxHg0g3XwmvbrhA47ZJNfLYniPV4K7ELTp3nsoe9xZo2yORy8KiYUV9AETu90oZd-ZnZG_J1IXY7HmzT3DQ5rXWRMHx1Uym_SU7TCk0hIvFpta012lS_Hv8OZ2cnXC70VUx8_LS27ICE4k6xJbwxZCZZ0oLZ_XSicvg9vOP_N7KWbR_Jc7sxjpIDc2IY9EUNn0FiGs6IDy-YJJ5kq31N0Di28uYuX910sAbymPGl--SD1feo4-SBXA9qejrfq85iHcgKWpOVmID1HxulHKZRcKM-T_TfEVlHUPvkiPo61xda2ak1ni05GpPc_iknAFUbM1D6eIh4mFSxdnLTDXVkvNByPb8QCaZCwOSiN5bDy-CvHseH7uuDrwilnqgMruLQmVj0oj2HM1vsjQqXMdVWi6dtfaj1qqyf8Cti_bt7m0qPKe4B6Mc9ALBFtk6gGLjAuygg4_WSCAr8WPnDjrLEI7Xmo_uFvPRsDEfQUCvXVP_vapaCr6vSPvQ-hJmXy2-u5qe"}],"implements":[{"href":"https://datatracker.ietf.org/doc/html/rfc9421","name":"RFC-9421: HTTP Message Signatures"},{"href":"https://datatracker.ietf.org/doc/html/rfc9421#name-eddsa-using-curve-edwards25","name":"RFC-9421 signatures using the Ed25519 algorithm"},{"href":"https://c2sp.org/httpsig-pq@v1.0.0#ml-dsa-44","name":"RFC-9421 signatures using the ml-dsa-44 algorithm"}],"gateways":["https://tootik.example"],"proof":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/v1"],"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","verificationMethod":"did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE#z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE","proofPurpose":"assertionMethod","proofValue":"zjGdNqPpqgx45ecMAz8jY3gVRrTphG5Cn7v9EiBKn7WyeHtdvTYPSkzyvWqZqfQuw92Kn3pD58qXw6wFTLAvkWee","created":"2026-09-30T11:57:45Z"}} \ No newline at end of file diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/actor.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/actor.json new file mode 100644 index 000000000..2391fd6c0 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/actor.json @@ -0,0 +1,68 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/data-integrity/v1", + "https://w3id.org/security/v1" + ], + "id": "https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor", + "type": "Application", + "inbox": "https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor/inbox", + "outbox": "https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor/outbox", + "preferredUsername": "actor", + "followers": "https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor/followers", + "publicKey": { + "id": "https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor#main-key", + "owner": "https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr70sLuCyvDBKblca6Jsk\nJW5ZmTpmyFK4gY6dpDkjvsokBjTR6oUO5GF7QGT4xGaGDtnzhd+K0/IE2Jo2cbBu\nTAK92xo3qB4nL+0XIfqXK/ju/pIo4ClZ1oHYNeJnmjGDAJmZmaf9/b0sd0osfTPX\nWSqAkgZuxZYrWSXKs6WYuEJof5YfTHgH5PBzwtQGyexZKYkumyrq5lazeEvqBLyx\nyNc5u6LdkkHP+HR9DJIQ3CDv6d1yQ7ELiP5pXvKRV9jJKlBQ1TK1vlMGC8GcBlDy\nQT0UsbM/1lRbxnbbqiwY6rFlT6FpHd5cl9tblGU6sF9gyCDATCHAdZ/2laUzParD\n+QIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "icon": [ + { + "type": "Image", + "mediaType": "image/gif", + "url": "https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor/icon.gif" + } + ], + "manuallyApprovesFollowers": false, + "assertionMethod": [ + { + "id": "https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor#ed25519-key", + "type": "Multikey", + "controller": "https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor", + "publicKeyMultibase": "z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE" + }, + { + "id": "https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor#ml-dsa-44-key", + "type": "Multikey", + "controller": "https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor", + "publicKeyMultibase": "ukCRpmFGeqQvqCAsbrRIKdfH1ZD2Y-2NiDr5tmgYFceiWCipFyeJKL65fEBcHa3gIBJbuzwvTfFeiMppDxvQySHhXFMf12o2mZ1d9Rw5fP9JKxSgCH7TyjeXEsvN6Zv_3q3ignCU3UxQKL5q2Yks9bfQkDxPJdDvzgyP5D0lDWulx1I9wyQS_f0SXG-Muph2rHBIT_u30ZuN7PHNNk7VAv4AWn7DlbJ6h2871YgFD7YHmtZiq_YCWerBe9TPBAoIOYEY1LV_nPVEe5xDIBlQ2EXYcfJviKQ1rB1iP4c0uoxdGm1RLDOXd65EDmtzil_R1Y5Le4s5td6AV2iFanIQtoJabH1IfL3Ju9n1nM-X3T8YM5FCngvoFME7UxhUHUggZ7vbWy_hy99tRvlaPG3U2OogtyPELx1o91itRjVH276UB8frLb06oJj6RzHE8pwfImH7POETjxEMPzfX4RA7BQVge6TU3fiBx4V4wmofJ3eiMu6yo497mUjJMiFjnt4AC1xiY8_XzdAauJag55HjKDf1xKNHIpQe2IE_n2zJvjfh__coWwl5qJLyszAVBZTn-MTg8nS--PTZMZPaDJSwk9NAT6qdCAnaP5PPkoWlTedCVbDNE-az45x9rKs3sob1OVoJW-2Ogf0S37noPe3L2lfUidr32k5fXPCsg3GfB0F5ZS9sQ-ZBzQvgchArohI1DnX9cbObTj4bGrJu_N9SPFLp0jYQb5bujeIDdpiVu46PVbv4fV4gxQAt4XPZLExZq_WQhKVVn3A89NU6qwxKsAp1LWoouehQSSNaC-Wif7ev5vaCSE0eeTOCO0Ip1URirY7hKhjbp-hfAMx_Vnoj5gQeiRQkUW2oxkgXEpfdzJDvVoeaTmJ_k3soJlJYjp9ZJAc9qn8ygsFpRKFMUYZQL3Wcj7vFxjlX_42a-5p0_0UHA7JjK3UlvE_nG9cIeoqU-WgygEU9rf1CCJflppbwXMFmBQvJ1oMDoutbZTuDIdnRO5DVQ4uNEPyT3p_kv0smEGU3lzZERTYHPM-CNEF5Pk2rrVea9WxpC0TG2njHxmHsO0nCWmUgoB3cAMWpby-YBaen1xvXt5po7ge5KD3SC_cXMSLAJem_ZMVWtR070zXCJdsoB-GN8nFTchyjPpI6SLxXcVwWXNEzI_dEvcx0YTEwlI9OEDuF2rizU4UzZMIT_Ec5OgEehh-o0MLpgLRvLo15TOz0FFZfaKYWfVS6CEBxHg0g3XwmvbrhA47ZJNfLYniPV4K7ELTp3nsoe9xZo2yORy8KiYUV9AETu90oZd-ZnZG_J1IXY7HmzT3DQ5rXWRMHx1Uym_SU7TCk0hIvFpta012lS_Hv8OZ2cnXC70VUx8_LS27ICE4k6xJbwxZCZZ0oLZ_XSicvg9vOP_N7KWbR_Jc7sxjpIDc2IY9EUNn0FiGs6IDy-YJJ5kq31N0Di28uYuX910sAbymPGl--SD1feo4-SBXA9qejrfq85iHcgKWpOVmID1HxulHKZRcKM-T_TfEVlHUPvkiPo61xda2ak1ni05GpPc_iknAFUbM1D6eIh4mFSxdnLTDXVkvNByPb8QCaZCwOSiN5bDy-CvHseH7uuDrwilnqgMruLQmVj0oj2HM1vsjQqXMdVWi6dtfaj1qqyf8Cti_bt7m0qPKe4B6Mc9ALBFtk6gGLjAuygg4_WSCAr8WPnDjrLEI7Xmo_uFvPRsDEfQUCvXVP_vapaCr6vSPvQ-hJmXy2-u5qe" + } + ], + "implements": [ + { + "href": "https://datatracker.ietf.org/doc/html/rfc9421", + "name": "RFC-9421: HTTP Message Signatures" + }, + { + "href": "https://datatracker.ietf.org/doc/html/rfc9421#name-eddsa-using-curve-edwards25", + "name": "RFC-9421 signatures using the Ed25519 algorithm" + }, + { + "href": "https://c2sp.org/httpsig-pq@v1.0.0#ml-dsa-44", + "name": "RFC-9421 signatures using the ml-dsa-44 algorithm" + } + ], + "gateways": ["https://tootik.example"], + "proof": { + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/data-integrity/v1", + "https://w3id.org/security/v1" + ], + "type": "DataIntegrityProof", + "cryptosuite": "eddsa-jcs-2022", + "verificationMethod": "did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE#z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE", + "proofPurpose": "assertionMethod", + "proofValue": "zjGdNqPpqgx45ecMAz8jY3gVRrTphG5Cn7v9EiBKn7WyeHtdvTYPSkzyvWqZqfQuw92Kn3pD58qXw6wFTLAvkWee", + "created": "2026-09-30T11:57:45Z" + } +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/metadata.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/metadata.json new file mode 100644 index 000000000..f8c65d128 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/metadata.json @@ -0,0 +1,54 @@ +{ + "implementation": "tootik", + "version": "0.25.4", + "tag": "v0.25.4", + "commit": "5ce4b7fe074d7c385808be387ffcda7040842a19", + "binaryUrl": "https://github.com/dimkr/tootik/releases/download/v0.25.4/tootik-amd64", + "binarySha256": "c24982af1a58cf8d4a8ae1a66dae7252d90bb1310c31d297ddc4b040d790f0c2", + "capturedAt": "2026-09-30T11:57:45.598951+00:00", + "actorUrl": "https://tootik.example/.well-known/apgateway/did:key:z6MknxT9xX8cmnsEqBk2u74aYaGQNjVQL1eHxhn1qb27p5vE/actor", + "transport": "HTTPS; curl --connect-to maps tootik.example:443 to 127.0.0.1:18443; self-signed certificate trusted explicitly", + "actorSha256": "c9826d63e3ed01529a048e32389df27ff4d31a3fc4d46a207d30c6a406a8ce82", + "contexts": [ + { + "url": "https://www.w3.org/ns/activitystreams", + "capturedSha256": "a27b78b82f4980963127140d0cb74f0e8f21c0e2b8efd0368232bf9823edff5a", + "fixture": "packages/fixture/src/fixtures/www.w3.org/ns/activitystreams.json", + "matchesFixtureJsonValues": true + }, + { + "url": "https://w3id.org/security/data-integrity/v1", + "capturedSha256": "b5d829bd09aa7c42abc6efa0c8ed7635313b5487f37ccfce3ecd149ca9418554", + "fixture": "packages/fixture/src/fixtures/w3id.org/security/data-integrity/v1.json", + "matchesFixtureJsonValues": true + }, + { + "url": "https://w3id.org/security/v1", + "capturedSha256": "abaf97e107d1925503c433dcaf3ffd2831697cacc1ed2a293e1bc8030d5bcb47", + "fixture": "packages/fixture/src/fixtures/w3id.org/security/v1.json", + "matchesFixtureJsonValues": true + } + ], + "expected": { + "proofVerified": true, + "parsedGateways": [ + "https://tootik.example/" + ], + "portableObjectProof": { + "verified": true + } + }, + "baseline": { + "fedifyCommit": "3d507d94631110b066056a16618b907a75e8e7ff", + "observed": { + "proofVerified": true, + "parsedGateways": [], + "portableObjectProof": { + "verified": false, + "reason": { + "type": "invalidGateways" + } + } + } + } +} diff --git a/packages/vocab-runtime/src/internal/jsonld-cache.ts b/packages/vocab-runtime/src/internal/jsonld-cache.ts index 8289666df..6e46caa3d 100644 --- a/packages/vocab-runtime/src/internal/jsonld-cache.ts +++ b/packages/vocab-runtime/src/internal/jsonld-cache.ts @@ -1,6 +1,42 @@ import type { DocumentLoader } from "../docloader.ts"; import jsonld from "../jsonld.ts"; -import { formatIri, haveSameFe34Origin, haveSameIriOrigin } from "../url.ts"; +import { + formatIri, + fromCompatibleEf61Id, + getFe34Origin, + haveSameFe34Origin, + haveSameIriOrigin, + parseIri, +} from "../url.ts"; + +/** + * Reads expanded gateways, including an unmapped term on portable actors. + * The original values and their order are preserved for URL validation by + * the caller. An explicitly mapped FEP-ef61 property always takes precedence. + * @internal Used by generated vocabulary classes and portable proof checks. + */ +export function getPortableActorGateways( + node: Record, + allowUnmapped = true, +): unknown[] | undefined { + const property = "https://w3id.org/fep/ef61/gateways"; + if (globalThis.Object.hasOwn(node, property)) { + return Array.isArray(node[property]) ? node[property] : undefined; + } + if ( + !allowUnmapped || typeof node["@id"] !== "string" || + !("http://www.w3.org/ns/ldp#inbox" in node) || + !("https://www.w3.org/ns/activitystreams#outbox" in node) + ) return undefined; + try { + const id = fromCompatibleEf61Id(node["@id"]) ?? node["@id"]; + if (!getFe34Origin(parseIri(id)).startsWith("did:")) return undefined; + } catch (error) { + if (error instanceof TypeError) return undefined; + throw error; + } + return Array.isArray(node["_:gateways"]) ? node["_:gateways"] : undefined; +} const noJsonLdContext = Symbol("noJsonLdContext"); diff --git a/packages/vocab-runtime/src/jsonld-cache.test.ts b/packages/vocab-runtime/src/jsonld-cache.test.ts index 6f95fde19..2be2bfb96 100644 --- a/packages/vocab-runtime/src/jsonld-cache.test.ts +++ b/packages/vocab-runtime/src/jsonld-cache.test.ts @@ -3,12 +3,101 @@ import { test } from "node:test"; import { compactJsonLdCache, getJsonLdContext, + getPortableActorGateways, isTrustedIriOrigin, normalizeJsonLdIris, } from "./internal/jsonld-cache.ts"; import jsonld from "./jsonld.ts"; import { parseIri } from "./url.ts"; +test("getPortableActorGateways() preserves unmapped portable actor gateways", () => { + const gateways = [ + { "@value": "https://second.example" }, + { "@value": "https://first.example" }, + { "@value": "not a valid gateway" }, + ]; + const ids = [ + "ap://did:key:z6Mkabc/actor", + "ap+ef61://did:key:z6Mkabc/actor", + "https://gateway.example/.well-known/apgateway/did:key:z6Mkabc/actor", + ]; + for (const id of ids) { + const node = { + "@id": id, + "http://www.w3.org/ns/ldp#inbox": [{ "@id": `${id}/inbox` }], + "https://www.w3.org/ns/activitystreams#outbox": [ + { "@id": `${id}/outbox` }, + ], + "_:gateways": gateways, + }; + const original = structuredClone(node); + strictEqual(getPortableActorGateways(node), gateways, id); + strictEqual(getPortableActorGateways(node, false), undefined, id); + deepStrictEqual(node, original); + } +}); + +test("getPortableActorGateways() gives mapped gateways precedence", () => { + const canonical = "https://w3id.org/fep/ef61/gateways"; + const gateways = [{ "@list": [{ "@id": "https://gateway.example" }] }]; + const node: Record = { + "@id": "ap://did:key:z6Mkabc/actor", + "http://www.w3.org/ns/ldp#inbox": [], + "https://www.w3.org/ns/activitystreams#outbox": [], + "_:gateways": [{ "@value": "https://other.example" }], + [canonical]: gateways, + }; + strictEqual(getPortableActorGateways(node), gateways); + strictEqual(getPortableActorGateways(node, false), gateways); + for (const value of [undefined, null, {}, "https://gateway.example", []]) { + node[canonical] = value; + strictEqual( + getPortableActorGateways(node), + Array.isArray(value) ? value : undefined, + ); + } +}); + +test("getPortableActorGateways() limits unmapped terms to portable actors", () => { + const node: Record = { + "@id": "ap://did:key:z6Mkabc/actor", + "http://www.w3.org/ns/ldp#inbox": [], + "https://www.w3.org/ns/activitystreams#outbox": [], + "_:gateways": [{ "@value": "https://gateway.example" }], + }; + for ( + const id of [ + undefined, + 1, + "not an IRI", + "https://ordinary.example/actor", + "https://gateway.example/.well-known/apgateway/not-a-did/actor", + "https://user@gateway.example/.well-known/apgateway/did:key:z6Mkabc/actor", + ] + ) { + strictEqual(getPortableActorGateways({ ...node, "@id": id }), undefined); + } + for ( + const property of [ + "http://www.w3.org/ns/ldp#inbox", + "https://www.w3.org/ns/activitystreams#outbox", + ] + ) { + const nonActor = { ...node }; + delete nonActor[property]; + strictEqual(getPortableActorGateways(nonActor), undefined); + } + strictEqual( + getPortableActorGateways({ ...node, "_:gateways": null }), + undefined, + ); + const empty: unknown[] = []; + strictEqual( + getPortableActorGateways({ ...node, "_:gateways": empty }), + empty, + ); +}); + test("isTrustedIriOrigin() trusts same portable IRI origins", () => { ok(isTrustedIriOrigin( {}, diff --git a/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap b/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap index 438c2a402..2d17eb19d 100644 --- a/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap +++ b/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap @@ -32,6 +32,7 @@ import { compactJsonLdCache, createScopedContextLoader, getJsonLdContext, + getPortableActorGateways, isTrustedIriOrigin, normalizeJsonLdIris } from \\"@fedify/vocab-runtime/internal/jsonld-cache\\"; @@ -70539,7 +70540,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values[\\"https://w3id.org/fep/ef61/gateways\\"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null @@ -91637,7 +91638,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values[\\"https://w3id.org/fep/ef61/gateways\\"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null @@ -111364,7 +111365,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values[\\"https://w3id.org/fep/ef61/gateways\\"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null @@ -122387,7 +122388,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values[\\"https://w3id.org/fep/ef61/gateways\\"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null @@ -141820,7 +141821,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values[\\"https://w3id.org/fep/ef61/gateways\\"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null diff --git a/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap b/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap index 17b7d821f..9d9b2b7dd 100644 --- a/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap +++ b/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap @@ -30,6 +30,7 @@ import { compactJsonLdCache, createScopedContextLoader, getJsonLdContext, + getPortableActorGateways, isTrustedIriOrigin, normalizeJsonLdIris } from \\"@fedify/vocab-runtime/internal/jsonld-cache\\"; @@ -70537,7 +70538,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values[\\"https://w3id.org/fep/ef61/gateways\\"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null @@ -91635,7 +91636,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values[\\"https://w3id.org/fep/ef61/gateways\\"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null @@ -111362,7 +111363,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values[\\"https://w3id.org/fep/ef61/gateways\\"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null @@ -122385,7 +122386,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values[\\"https://w3id.org/fep/ef61/gateways\\"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null @@ -141818,7 +141819,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values[\\"https://w3id.org/fep/ef61/gateways\\"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null diff --git a/packages/vocab-tools/src/__snapshots__/class.test.ts.snap b/packages/vocab-tools/src/__snapshots__/class.test.ts.snap index bc8c09167..59be9ef0f 100644 --- a/packages/vocab-tools/src/__snapshots__/class.test.ts.snap +++ b/packages/vocab-tools/src/__snapshots__/class.test.ts.snap @@ -32,6 +32,7 @@ import { compactJsonLdCache, createScopedContextLoader, getJsonLdContext, + getPortableActorGateways, isTrustedIriOrigin, normalizeJsonLdIris } from "@fedify/vocab-runtime/internal/jsonld-cache"; @@ -70539,7 +70540,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values["https://w3id.org/fep/ef61/gateways"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null @@ -91637,7 +91638,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values["https://w3id.org/fep/ef61/gateways"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null @@ -111364,7 +111365,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values["https://w3id.org/fep/ef61/gateways"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null @@ -122387,7 +122388,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values["https://w3id.org/fep/ef61/gateways"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null @@ -141820,7 +141821,7 @@ get gateways(): (URL)[] { instance.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = _4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod; const _hQiaHhZP8hqxckxTBrpsGNs57E3: (URL)[] = []; - let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = values["https://w3id.org/fep/ef61/gateways"]; + let _hQiaHhZP8hqxckxTBrpsGNs57E3__array = getPortableActorGateways(values) as typeof values[string]; for ( const v of _hQiaHhZP8hqxckxTBrpsGNs57E3__array == null diff --git a/packages/vocab-tools/src/class.ts b/packages/vocab-tools/src/class.ts index 7937b7fb9..39bb86f84 100644 --- a/packages/vocab-tools/src/class.ts +++ b/packages/vocab-tools/src/class.ts @@ -16,6 +16,7 @@ const INTERNAL_RUNTIME_IMPORTS = [ "compactJsonLdCache", "createScopedContextLoader", "getJsonLdContext", + "getPortableActorGateways", "isTrustedIriOrigin", "normalizeJsonLdIris", ].join(",\n "); diff --git a/packages/vocab-tools/src/codec.ts b/packages/vocab-tools/src/codec.ts index 540c2693d..b4ff7a0a8 100644 --- a/packages/vocab-tools/src/codec.ts +++ b/packages/vocab-tools/src/codec.ts @@ -538,8 +538,11 @@ export async function* generateDecoder( const variable = await getFieldName(property.uri, ""); yield await generateField(property, types, "const "); const arrayVariable = `${variable}__array`; + const propertyValues = property.uri === "https://w3id.org/fep/ef61/gateways" + ? "getPortableActorGateways(values) as typeof values[string]" + : `values[${JSON.stringify(property.uri)}]`; yield ` - let ${arrayVariable} = values[${JSON.stringify(property.uri)}]; + let ${arrayVariable} = ${propertyValues}; `; if (property.functional && property.redundantProperties != null) { for (const prop of property.redundantProperties) { diff --git a/packages/vocab/src/vocab.test.ts b/packages/vocab/src/vocab.test.ts index 5924e6e47..cb2f698c4 100644 --- a/packages/vocab/src/vocab.test.ts +++ b/packages/vocab/src/vocab.test.ts @@ -722,6 +722,75 @@ test("FEP-ef61: actor gateways round-trip as an ordered URI list", async () => { } }); +test("FEP-ef61: portable actors parse unmapped gateway lists", async () => { + const actorClasses = [Application, Group, Organization, Person, Service]; + const gateways = ["https://first.example", "https://second.example"]; + const ids = [ + "ap://did:key:z6Mkabc/actor", + "https://first.example/.well-known/apgateway/did:key:z6Mkabc/actor", + ]; + for (const ActorClass of actorClasses) { + for (const id of ids) { + const actor = await ActorClass.fromJsonLd({ + "@context": "https://www.w3.org/ns/activitystreams", + type: ActorClass.name, + id, + inbox: `${id}/inbox`, + outbox: `${id}/outbox`, + gateways, + }); + deepStrictEqual(actor.gateways, gateways.map((g) => new URL(g))); + } + } +}); + +test("FEP-ef61: unmapped gateways retain their context meaning", async () => { + const actorClasses = [Application, Group, Organization, Person, Service]; + const id = "ap://did:key:z6Mkabc/actor"; + for (const ActorClass of actorClasses) { + const document = { + type: ActorClass.name, + id, + inbox: `${id}/inbox`, + outbox: `${id}/outbox`, + gateways: ["https://unmapped.example"], + }; + for ( + const context of [ + { gateways: "https://example.com/unrelated" }, + { gateways: null }, + { "@vocab": "https://example.com/" }, + { + [ActorClass.name]: { + "@id": `https://www.w3.org/ns/activitystreams#${ActorClass.name}`, + "@context": { gateways: "https://example.com/scoped" }, + }, + }, + ] + ) { + const actor = await ActorClass.fromJsonLd({ + "@context": ["https://www.w3.org/ns/activitystreams", context], + ...document, + }); + deepStrictEqual(actor.gateways, []); + } + const ordinary = await ActorClass.fromJsonLd({ + "@context": "https://www.w3.org/ns/activitystreams", + ...document, + id: "https://ordinary.example/actor", + }); + deepStrictEqual(ordinary.gateways, []); + const canonical = await ActorClass.fromJsonLd({ + "@context": "https://www.w3.org/ns/activitystreams", + ...document, + "https://w3id.org/fep/ef61/gateways": { + "@list": [{ "@id": "https://canonical.example" }], + }, + }); + deepStrictEqual(canonical.gateways, [new URL("https://canonical.example")]); + } +}); + test("FEP-ef61: actor gateways preserve single, empty, and invalid cases", async () => { const singleGateway = new Person({ id: new URL("ap+ef61://did%3Akey%3Az6Mkabc/actor"), From 571870aa6839c35adb560551958e931d2ac0a654 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Wed, 30 Sep 2026 23:42:52 +0900 Subject: [PATCH 010/184] Verify tootik portable delivery both ways Record an unchanged tootik Follow received by Fedify and a native Fedify Create processed into tootik's notes database. Verify captured proofs, HTTP signatures and key ownership independently, and preserve negative tampering results and pinned capture provenance. Document tootik's portless gateway requirement and proof-authenticated inbox behavior. Use runtime-neutral body imports for Deno, Node.js and Bun, and bridge the timer mock assertion through unknown so the native package checks accept current Node timer declarations. https://github.com/fedify-dev/fedify/issues/1097 Changelog: none Assisted-by: Codex:gpt-6.1-sol Assisted-by: Claude Code:claude-opus-5-5 --- FEDERATION.md | 31 +++- packages/fedify/src/federation/mq.test.ts | 2 +- .../src/sig/tootik-request-interop.test.ts | 172 ++++++++++++++++++ .../src/sig/tootik-send-interop.test.ts | 140 ++++++++++++++ .../fep-ef61/tootik-v0.25.4/follow/README.md | 124 +++++++++++++ .../fep-ef61/tootik-v0.25.4/follow/actor.body | 1 + .../fep-ef61/tootik-v0.25.4/follow/actor.json | 56 ++++++ .../tootik-v0.25.4/follow/metadata.json | 20 ++ .../tootik-v0.25.4/follow/raw-bodies.json | 4 + .../tootik-v0.25.4/follow/request.body | 1 + .../tootik-v0.25.4/follow/request.json | 39 ++++ .../fep-ef61/tootik-v0.25.4/send/README.md | 91 +++++++++ .../fep-ef61/tootik-v0.25.4/send/actor.body | 1 + .../fep-ef61/tootik-v0.25.4/send/actor.json | 129 +++++++++++++ .../tootik-v0.25.4/send/first-request.json | 31 ++++ .../tootik-v0.25.4/send/first-response.json | 18 ++ .../tootik-v0.25.4/send/metadata.json | 64 +++++++ .../tootik-v0.25.4/send/processed-note.json | 87 +++++++++ .../tootik-v0.25.4/send/raw-bodies.json | 6 + .../tootik-v0.25.4/send/recipient.body | 1 + .../tootik-v0.25.4/send/recipient.json | 70 +++++++ .../fep-ef61/tootik-v0.25.4/send/request.body | 1 + .../fep-ef61/tootik-v0.25.4/send/request.json | 27 +++ .../tootik-v0.25.4/send/response.json | 14 ++ .../fep-ef61/tootik-v0.25.4/send/state.json | 13 ++ .../send/tampered-response.json | 18 ++ .../tootik-v0.25.4/send/tampered.body | 1 + 27 files changed, 1157 insertions(+), 5 deletions(-) create mode 100644 packages/fedify/src/sig/tootik-request-interop.test.ts create mode 100644 packages/fedify/src/sig/tootik-send-interop.test.ts create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/README.md create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/actor.body create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/actor.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/metadata.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/raw-bodies.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/request.body create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/request.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/README.md create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/actor.body create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/actor.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/first-request.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/first-response.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/metadata.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/processed-note.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/raw-bodies.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/recipient.body create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/recipient.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/request.body create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/request.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/response.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/state.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/tampered-response.json create mode 100644 packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/tampered.body diff --git a/FEDERATION.md b/FEDERATION.md index d02519668..31f2b9df4 100644 --- a/FEDERATION.md +++ b/FEDERATION.md @@ -62,7 +62,6 @@ Supported FEPs [FEP-22cd]: https://w3id.org/fep/22cd [FEP-0837]: https://w3id.org/fep/0837 [FEP-ae0c]: https://w3id.org/fep/ae0c -[FEP-ef61]: https://w3id.org/fep/ef61 [FEP-ef61 section]: #fep-ef61 @@ -103,12 +102,36 @@ omits the JSON-LD mapping for `gateways`; Fedify reads that list and requires JCS proofs to authenticate the original JSON. The unchanged response and capture procedure are recorded in the [tootik fixture]. -This result covers actor parsing and proof verification. Incoming HTTP -Signatures and activities captured from tootik, acceptance of Fedify output -by other implementations, and live Mitra/Mastodon interoperability remain +In a separate local HTTPS test, a freshly registered portable tootik `Person` +sent a `Follow` to a Fedify inbox. Fedify independently verified the original +Cavage RSA HTTP Signature, returned HTTP 202, and dispatched the activity to +the `Follow` listener. The inbox authenticated the activity's original +`eddsa-jcs-2022` proof; proof-authenticated delivery does not itself check the +HTTP Signature. The exact request, actor response, and procedure are recorded +in the [tootik Follow fixture]. Offline replay uses the captured time to check +the HTTP Signature's freshness; the live request used the normal current-time +check. + +In the reverse direction, tootik v0.25.4 accepted a Fedify-generated portable +`Create` and stored its embedded `Note` with the expected ID, author, and +content. Fedify generated the actor and object proofs and sent the activity +through `Context.sendActivity()`. The first request received HTTP 401 with +`actor is too young`; the automatic retry received HTTP 202, followed by +database confirmation of processing. Changing the embedded note's content +without updating its proofs received HTTP 401. The [Fedify to tootik fixture] +records the original output, responses, and stored note. + +This reverse test used HTTPS gateway origins without explicit ports: tootik +v0.25.4 does not recognize compatible actor IDs with an explicit port. Its +inbox authenticated the activity through its proof and skipped HTTP Signature +verification. The request carried a gateway RSA signature, but this result +does not establish independent acceptance of that signature by tootik. +Bidirectional Mitra interoperability and Mastodon compatibility remain unverified. [tootik fixture]: packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/README.md +[tootik Follow fixture]: packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/README.md +[Fedify to tootik fixture]: packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/README.md ActivityPub diff --git a/packages/fedify/src/federation/mq.test.ts b/packages/fedify/src/federation/mq.test.ts index 08d8d6a45..7c6004773 100644 --- a/packages/fedify/src/federation/mq.test.ts +++ b/packages/fedify/src/federation/mq.test.ts @@ -158,7 +158,7 @@ function captureTimers(enqueue: () => Promise): { globalThis.setTimeout = ((callback: () => void, delay?: number) => { timers.push({ callback, delay }); return 0; - }) as typeof globalThis.setTimeout; + }) as unknown as typeof globalThis.setTimeout; try { return { timers, enqueued: enqueue() }; } finally { diff --git a/packages/fedify/src/sig/tootik-request-interop.test.ts b/packages/fedify/src/sig/tootik-request-interop.test.ts new file mode 100644 index 000000000..5e761abc1 --- /dev/null +++ b/packages/fedify/src/sig/tootik-request-interop.test.ts @@ -0,0 +1,172 @@ +import { mockDocumentLoader, test } from "@fedify/fixture"; +import { Follow, Person } from "@fedify/vocab"; +import { assert, assertEquals } from "@std/assert"; +import { encodeHex } from "byte-encodings/hex"; +import { createFederation } from "../federation/middleware.ts"; +import { MemoryKvStore } from "../federation/kv.ts"; +import actor from "../../test-vectors/fep-ef61/tootik-v0.25.4/follow/actor.json" with { + type: "json", +}; +import captured from "../../test-vectors/fep-ef61/tootik-v0.25.4/follow/request.json" with { + type: "json", +}; +import metadata from "../../test-vectors/fep-ef61/tootik-v0.25.4/follow/metadata.json" with { + type: "json", +}; +import rawBodies from "../../test-vectors/fep-ef61/tootik-v0.25.4/follow/raw-bodies.json" with { + type: "json", +}; +import { verifyRequestDetailed } from "./http.ts"; +import { doesActorOwnKey } from "./owner.ts"; +import { verifyPortableObjectProof } from "./proof.ts"; + +const body = rawBodies.requestBody; +const activity = JSON.parse(body); + +async function sha256(value: string): Promise { + return encodeHex( + new Uint8Array( + await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value)), + ), + ); +} + +function loader(document: unknown = actor) { + return (url: string) => { + assertEquals(url.split("#")[0], actor.id); + return Promise.resolve({ + document: structuredClone(document), + documentUrl: actor.id, + contextUrl: null, + }); + }; +} + +const options = { + documentLoader: loader(), + contextLoader: mockDocumentLoader, + currentTime: Temporal.Instant.from(captured.capturedAt), +}; + +function request( + requestBody = body, + url = captured.url, + headers = new Headers(captured.headers as [string, string][]), +): Request { + return new Request(url, { + method: captured.method, + headers, + body: requestBody, + }); +} + +async function deliver(requestBody: string) { + const federation = createFederation({ + kv: new MemoryKvStore(), + documentLoaderFactory: () => loader(), + contextLoaderFactory: () => mockDocumentLoader, + // HTTP time validation is tested separately at the capture time. + signatureTimeWindow: false, + }); + federation.setActorDispatcher( + "/users/{identifier}", + (ctx, identifier) => + identifier === "alice" + ? new Person({ + id: ctx.getActorUri(identifier), + inbox: ctx.getInboxUri(identifier), + }) + : null, + ).setKeyPairsDispatcher(() => []); + const received: Follow[] = []; + federation.setInboxListeners("/users/{identifier}/inbox", "/inbox") + .on(Follow, (_ctx, follow) => { + received.push(follow); + }); + const response = await federation.fetch(request(requestBody), { + contextData: undefined, + }); + return { response, received }; +} + +test("tootik v0.25.4 captured Follow verifies its proof and HTTP signature", async () => { + const actorBody = rawBodies.actorBody; + assertEquals( + await sha256(body), + metadata.requestBodySha256, + ); + assertEquals( + await sha256(actorBody), + metadata.actorBodySha256, + ); + assertEquals(JSON.parse(actorBody), actor); + assertEquals(activity.type, "Follow"); + assertEquals(actor.type, "Person"); + assertEquals(activity.actor, actor.id); + assert((await verifyPortableObjectProof(activity, options)).verified); + const verified = await verifyRequestDetailed(request(), options); + assert(verified.verified); + assertEquals(verified.key.id?.href, actor.publicKey.id); + const parsed = await Follow.fromJsonLd(activity, options); + assert(await doesActorOwnKey(parsed, verified.key, options)); + assertEquals(captured.capturedAt, metadata.capturedAt); +}); + +test("tootik v0.25.4 captured Follow reaches the Fedify inbox listener", async () => { + const { response, received } = await deliver(body); + assertEquals(response.status, 202); + assertEquals(received.length, 1); + assertEquals(received[0].id?.href, activity.id); + assertEquals(received[0].actorId?.href, actor.id); +}); + +test("tootik v0.25.4 captured Follow rejects body tampering", async () => { + const tampered = { + ...activity, + object: "https://fedify.example:18444/users/mallory", + }; + assertEquals( + (await verifyPortableObjectProof(tampered, options)).verified, + false, + ); + const changedBody = JSON.stringify(tampered); + assertEquals( + (await verifyRequestDetailed(request(changedBody), options)).verified, + false, + ); + const { response, received } = await deliver(changedBody); + assertEquals(response.status, 401); + assertEquals(received.length, 0); +}); + +test("tootik v0.25.4 captured Follow rejects signed header and path tampering", async () => { + const headers = new Headers(captured.headers as [string, string][]); + headers.set("Content-Type", "application/json"); + assertEquals( + (await verifyRequestDetailed(request(body, captured.url, headers), options)) + .verified, + false, + ); + assertEquals( + (await verifyRequestDetailed( + request(body, `${captured.url}/tampered`), + options, + )).verified, + false, + ); +}); + +test("tootik v0.25.4 captured Follow rejects a tampered actor proof", async () => { + const tampered = { ...actor, preferredUsername: "mallory" }; + assertEquals( + (await verifyPortableObjectProof(tampered, options)).verified, + false, + ); + assertEquals( + (await verifyRequestDetailed(request(), { + ...options, + documentLoader: loader(tampered), + })).verified, + false, + ); +}); diff --git a/packages/fedify/src/sig/tootik-send-interop.test.ts b/packages/fedify/src/sig/tootik-send-interop.test.ts new file mode 100644 index 000000000..a5f8b548e --- /dev/null +++ b/packages/fedify/src/sig/tootik-send-interop.test.ts @@ -0,0 +1,140 @@ +import { mockDocumentLoader, test } from "@fedify/fixture"; +import { Create } from "@fedify/vocab"; +import { decodeMultibase, importDidKey } from "@fedify/vocab-runtime"; +import { assert, assertEquals } from "@std/assert"; +import { encodeHex } from "byte-encodings/hex"; +import serialize from "json-canon"; +import actor from "../../test-vectors/fep-ef61/tootik-v0.25.4/send/actor.json" with { + type: "json", +}; +import captured from "../../test-vectors/fep-ef61/tootik-v0.25.4/send/request.json" with { + type: "json", +}; +import firstResponse from "../../test-vectors/fep-ef61/tootik-v0.25.4/send/first-response.json" with { + type: "json", +}; +import metadata from "../../test-vectors/fep-ef61/tootik-v0.25.4/send/metadata.json" with { + type: "json", +}; +import processed from "../../test-vectors/fep-ef61/tootik-v0.25.4/send/processed-note.json" with { + type: "json", +}; +import raw from "../../test-vectors/fep-ef61/tootik-v0.25.4/send/raw-bodies.json" with { + type: "json", +}; +import response from "../../test-vectors/fep-ef61/tootik-v0.25.4/send/response.json" with { + type: "json", +}; +import tamperedResponse from "../../test-vectors/fep-ef61/tootik-v0.25.4/send/tampered-response.json" with { + type: "json", +}; +import { verifyRequestDetailed } from "./http.ts"; +import { doesActorOwnKey } from "./owner.ts"; +import { verifyPortableObjectProof } from "./proof.ts"; + +const activity = JSON.parse(raw.requestBody); +const tampered = JSON.parse(raw.tamperedBody); + +async function digest(value: string): Promise { + return new Uint8Array( + await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value)), + ); +} + +// Verifies the exact JSON maps without Fedify's outgoing-normalization fallback. +async function verifyRawJcs( + document: Record, +): Promise { + const { proof, ...unsecured } = document; + assert(proof != null && typeof proof === "object" && !Array.isArray(proof)); + const { proofValue, ...configuration } = proof as Record; + assertEquals(configuration.cryptosuite, "eddsa-jcs-2022"); + configuration["@context"] ??= document["@context"]; + assert(typeof configuration.verificationMethod === "string"); + assert(typeof proofValue === "string"); + const key = await importDidKey( + configuration.verificationMethod.split("#")[0], + ); + const combined = new Uint8Array(64); + combined.set(await digest(serialize(configuration)), 0); + combined.set(await digest(serialize(unsecured)), 32); + return await crypto.subtle.verify( + "Ed25519", + key, + new Uint8Array(decodeMultibase(proofValue)), + combined, + ); +} + +const options = { + contextLoader: mockDocumentLoader, + documentLoader(url: string) { + assertEquals(url.split("#")[0], actor.id); + return Promise.resolve({ + document: structuredClone(actor), + documentUrl: actor.id, + contextUrl: null, + }); + }, + currentTime: Temporal.Instant.from(captured.capturedAt), +}; + +function request(): Request { + return new Request(captured.url, { + method: captured.method, + headers: captured.headers as [string, string][], + body: raw.requestBody, + }); +} + +test("Fedify to tootik v0.25.4 captured actor and compound proofs verify raw JCS", async () => { + for (const [name, value] of Object.entries(raw)) { + assertEquals( + encodeHex(await digest(value)), + metadata.sha256[name as keyof typeof metadata.sha256], + ); + } + assertEquals(JSON.parse(raw.actorBody), actor); + assert(await verifyRawJcs(actor)); + assert(await verifyRawJcs(activity)); + assert(await verifyRawJcs(activity.object)); + assert((await verifyPortableObjectProof(actor, options)).verified); + assert((await verifyPortableObjectProof(activity, options)).verified); + assert((await verifyPortableObjectProof(activity.object, options)).verified); +}); + +test("Fedify to tootik v0.25.4 captured HTTP signature belongs to its portable actor", async () => { + // This is independent local verification: tootik preferred the object proof. + const verified = await verifyRequestDetailed(request(), options); + assert(verified.verified); + assertEquals(verified.key.id?.href, actor.publicKey.id); + assert( + await doesActorOwnKey( + await Create.fromJsonLd(activity, options), + verified.key, + options, + ), + ); +}); + +test("Fedify to tootik v0.25.4 captured result records native Note processing", () => { + assertEquals(firstResponse.status, 401); + assertEquals(JSON.parse(firstResponse.body).error, "actor is too young"); + assertEquals(response.status, 202); + assertEquals(processed.rows.length, 1); + assertEquals(processed.rows[0].id, activity.object.id); + assertEquals(processed.rows[0].author, actor.id); + assertEquals(processed.rows[0].object.content, activity.object.content); + assertEquals( + processed.rows[0].object.proof.proofValue, + activity.object.proof.proofValue, + ); +}); + +test("Fedify to tootik v0.25.4 captured nested tampering invalidates both proofs", async () => { + assertEquals(tamperedResponse.status, 401); + assertEquals(tampered.id, activity.id); + assert(tampered.object.content !== activity.object.content); + assertEquals(await verifyRawJcs(tampered), false); + assertEquals(await verifyRawJcs(tampered.object), false); +}); diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/README.md b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/README.md new file mode 100644 index 000000000..08ccfa515 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/README.md @@ -0,0 +1,124 @@ +Tootik to Fedify follow capture +=============================== + +This fixture records a portable `Person` created by the unmodified official +tootik v0.25.4 Linux amd64 binary, followed by its live `Follow` delivery to a +Fedify HTTPS inbox. The tag points to commit +`5ce4b7fe074d7c385808be387ffcda7040842a19`; the binary SHA-256 is +`c24982af1a58cf8d4a8ae1a66dae7252d90bb1310c31d297ddc4b040d790f0c2`. +The binary download and actor-only capture are documented in the +[parent fixture]. + +*request.body* is the exact delivered body. *request.json* records the method, +URL, headers, and capture time. *actor.body* is the exact actor response fetched +while resolving the HTTP signing key. *actor.json* contains the same JSON +values with repository formatting. *metadata.json* records their hashes and +the live result. *raw-bodies.json* contains the same two bodies as JSON strings +for runtime-neutral test imports; regenerate it together with the *.body* +files and their hashes when recapturing. Private keys, client certificates, +and databases are excluded. + +Fedify independently verified the Cavage RSA HTTP Signature with the portable +actor's `#main-key`, using the normal current-time freshness check. Its inbox +then returned HTTP 202 and dispatched the original `Follow` to its listener. +The inbox authenticated the original `eddsa-jcs-2022` Object Integrity Proof; +this path skips HTTP Signature verification, so HTTP 202 alone would not +establish that the HTTP Signature was valid. Neither the actor nor the activity +was repaired or re-signed by Fedify. + +Offline tests in *src/sig/tootik-request-interop.test.ts* replay the captured +request with `currentTime` set to its capture time. They preserve the normal +freshness window instead of treating an old request as a new live delivery. +This result covers tootik to Fedify only. Acceptance of Fedify output by tootik, +Mitra interoperability, and Mastodon compatibility remain separate work. + +[parent fixture]: ../README.md + + +Capture procedure +----------------- + +The capture used a fresh SQLite database and a TLS client certificate with +common name `alice`. The client registered a portable user through tootik's +Gemini frontend, supplying `generate` rather than an imported signing key. +It then resolved the Fedify user through WebFinger and followed that user. +All signing and delivery were performed by the official tootik binary. + +Create a local CA and a server leaf certificate with SANs for `tootik.example`, +`fedify.example`, and `localhost`. The CA must have `CA:TRUE`; the leaf must +have `CA:FALSE`, `digitalSignature` key usage, and `serverAuth` extended key +usage. Use the leaf followed by the CA as *tls-cert.pem*, its private key as +*tls-key.pem*, and a separate client certificate/key as *client-cert.pem* and +*client-key.pem*. Trust the CA explicitly in the Gemini client and both HTTPS +clients. These files stay outside the repository. + +Run a Fedify HTTPS receiver at `127.0.0.1:18444` with origin +`https://fedify.example:18444`. Serve an ordinary `Person` at +*/users/alice*, its inbox at */users/alice/inbox*, and a WebFinger self link +for `acct:alice@fedify.example:18444`. Register a `Follow` listener and record +its activity ID and actor ID. Before passing each original POST to +`federation.fetch()`, separately call `verifyRequestDetailed()` on a clone and +record its result. Capture the exact body, request headers, URL, receipt time, +inbox response, and actor document fetched by the key loader. + +The receiver's actor loader connected to `https://localhost:18443` while +retaining tootik's original document URL. Its TLS client trusted the local CA; +it did not disable certificate verification. Context loading reused the +snapshots described in the parent fixture. + +Run tootik in Podman with the official binary mounted read-only. This uses +container-specific host entries instead of changing host DNS. The capture +used `169.254.1.2` for the host-facing address in its rootless container +network; replace that address if the local network uses another address. + +~~~~ bash +capture_dir=/tmp/fedify-1097-wire-live +binary_path=/tmp/fedify-1097-tootik-v0.25.4/tootik-amd64 +mkdir -p "$capture_dir/data" +cat > "$capture_dir/signing.json" <<'JSON' +{"RFC9421Threshold":1,"Ed25519Threshold":1,"MLDSA44Threshold":1} +JSON +podman run --name fedify-1097-tootik \ + --network pasta:--map-host-loopback,169.254.1.2 \ + --add-host fedify.example:169.254.1.2 \ + --add-host tootik.example:127.0.0.1 \ + -p 127.0.0.1:18443:443 -p 127.0.0.1:11965:1965 \ + -v "$capture_dir:/capture" \ + -v "$binary_path:/usr/local/bin/tootik:ro" \ + -e SSL_CERT_FILE=/capture/tls-cert.pem \ + docker.io/library/alpine:3.23 \ + tootik -domain tootik.example -db /capture/data/db.sqlite3 \ + -cfg /capture/signing.json -cert /capture/tls-cert.pem \ + -key /capture/tls-key.pem -gemcert /capture/tls-cert.pem \ + -gemkey /capture/tls-key.pem -loglevel -4 +~~~~ + +The pinned binary defaults to HTTPS port 443 and Gemini port 1965, as verified +with `tootik -help`. The three threshold values suppress random HTTP signature +algorithm probes. +The Fedify recipient did not advertise alternative signature capabilities, +so tootik sent a Cavage RSA signature covering `(request-target)`, `host`, +`date`, `content-type`, and `digest`. + +From a Gemini client using the `alice` client certificate, connect to +`127.0.0.1:11965` with TLS server name `tootik.example` and request these URLs +in order: + +~~~~ text +gemini://tootik.example/users/register?generate +gemini://tootik.example/users/resolve?alice%40fedify.example%3A18444 +gemini://tootik.example/users/follow/fedify.example:18444/users/alice +~~~~ + +Registration and resolution return redirects. The final request queues the +proof-signed `Follow`; the running daemon delivers it to +`https://fedify.example:18444/users/alice/inbox`. Verify both the independent +HTTP signature result and the inbox listener record. Fresh registrations +generate new keys, IDs, proofs, and hashes, so a repeated capture will differ +from these files. + +Replay the recorded fixture from the repository root with: + +~~~~ bash +mise run test:deno packages/fedify/src/sig/tootik-request-interop.test.ts +~~~~ diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/actor.body b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/actor.body new file mode 100644 index 000000000..54d4972df --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/actor.body @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/v1"],"id":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor","type":"Person","inbox":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/inbox","outbox":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/outbox","preferredUsername":"alice","followers":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/followers","publicKey":{"id":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor#main-key","owner":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyLpYZnhnVih6ToB4UThp\nEZIcxbBcGng71XeEfiR42v+cCyUL+jzQm12x/I0a3FNh4dzIicMvtbmLewQ/HscR\nUNIxAFHF8GqshIjg2tDAmGswTQDsvTzBsaEixXtL0qTTX8X0tFzVKJEsMJJ99jzg\nodERW73G55WwpJYyI4v1RT3G5tU3p0tmD52hhCLCRLRCPKy75iz416nCwDt5sA8B\nowVE5n/J+tjqG3umnnI3gJpTtuJxTyB/SVjLjnC604RKowwQQTHGAmcl3E5F3IrK\nfnmfqdXNCrNbfvJFFAWB+XNXFB0I+fJbGUZAOYMfjhMGEpPzzkKI8cI1eR+Z5DeZ\nGQIDAQAB\n-----END PUBLIC KEY-----\n"},"icon":[{"type":"Image","mediaType":"image/gif","url":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/icon.gif"}],"manuallyApprovesFollowers":false,"assertionMethod":[{"id":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor#ed25519-key","type":"Multikey","controller":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor","publicKeyMultibase":"z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR"},{"id":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor#ml-dsa-44-key","type":"Multikey","controller":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor","publicKeyMultibase":"ukCQjRdBDVD0QfnNnj4wFAJE82TmNXoNQ80Rf6s3ivFXlFCzb5_tZHVhfsR5JysgCbOqYPnXYyXIgXAm_klgaj1a4_MB-KLhmueucnnMKUjl60ORt4RG2fDAjZoCzBy-m7PMX5hByOfuDTXbAhSFhG44xvBumN2x877PLudpMqhe9hhBDwgL4NTxUWOP3xJR4KhO0GMzjA6r4HGw0F2Mw3cYQNJs2t40k9w_Yt1qiVfyr4Qk0pk5vnZEkNFF71OBm-SUUSPtrHQEo02HhElN7uFE8wgYmziC_RqzrvyWAi9XQofgDGps2d-xXQew28NkyhAjv-7yIwd3ukjm_0UxjslLFpcjRAW7hNkrIm6oxV_Wv3ynpUVII7uc6v3Q3hkTtJxL4bcsl-oOpZKAqJide5A09G0XE_PvPrnVU3n9hH1HIhs4aWUeo3xda_gLfA5yoavGhqh1oOKnT3yiZYysjKt4GbdcLE_AMCDvWAqLdHTywnl5CG_9gUa3GlgjEsrJK8-SWCXoVgjQmGtdLWWMXTwzAwNZZwkoiR72v0uVOAzE54U_0oz6_Fowdgr29o0qu8TTb6NY70fF34XMWDDlKOWpgo7s5ejL15jfsrzcLhzP1xQlcBqQRZIsSQ_e0z_6mPJlYMu-UjsJIu4SM1__mn48TAQbw__B7VtClD_wGpedwF8gPpATziNsmOVvK8LKtYt983i2bzLYlV3Um31R4r-0i13JY6tBDC3SXkbOyOW3HkfecC1EJ11ffqoBwYT6KJGYH1pd8YR7cvwQn6C4kItLQnoUcIPBY7hKmw6B78e0ZexMMZlmQkW_JEHpgRi0Fb9atgSfGs8IIHTZGOkU5MGUUH1Evqz995dqFjoUxZaCGNKE2Rh-c0F4UdVToex7ZniQOFL1-D16mTloNwPgA9tvd7SUnSY2fr_E4Vyt-Rvcy_azBWBZWPzKdOy9u0OEW8uLeX680qp1Qbx97zDwCsiNAoTRMPyS_azqB12RThb3L-o28UXw5cPyeW9NSSN3G4yaweaIDmQ16vB1biKknrOU9XNVwkwZ4ilzYoESkGmQoCOomrNjGclx99d42S_7laMBlOkQcy846EyxhaHpkOj7t5LIU4Vs1TKeXXDV08wZQHz_r557uwtly8ltLHCg1pWm6MJNRgkhcGBhlE7Jt3gybA9HkYrg_x3NTR-uQocckeUbZZI1Q0aQuMa_F6_qC8WJOAkGDfERlFs7-gVjqYtTSHFLky3B_CgZukp_YZ-HLDlbxAO2qw_itfcn3fn95LLPUxiOZvB49xyha_z2r4rHt9R0BymvDM9ufp-pg2CiLBe3cPiy1Ck_BE7kvA7TyjShi3YyQIGfUcwAoWXOj4lKwejeqUmsjJ-gpD2iVJ3frWao9Cu846ubamb6wQZf5faAx6yTJsHLYdeDBqqJRCMSVEnOYHf6SaNfzdE8EFqCJ7LP2IYDnSFaiZovhja6BJBM4fphH27mnkrQ10whn35XX843QVAOLJa5fn4GoIwkSFY0PSL1J4MT1MobKfA0lROfF5fE29sKLRt-wbnHveAFE_CRiyzW6IFQO9flnSmn83VxigN2hv_xD51KX6p8dCzX1QLl0S9fWF1K9iHkq4ulz6slvypfacesLLGvbVnAWX491PPq9LIOHjCLoZbr1Ap8vkLw61-XvDFSBHUxGKvrlpPOKO5V3zop0sT_QiEymx9DpGAGrbYiyDEC3LhNmD14DxRdRqQLG3wW6HFTMJtl6"}],"gateways":["https://tootik.example"],"proof":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/v1"],"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","verificationMethod":"did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR#z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR","proofPurpose":"assertionMethod","proofValue":"z2G5haKKAJk3rfL8njG9V2jybnPuHrXjR8ipPBjDSFim9cFuJ9xEMEWBLQLdBmoQKXmHhqXfheadf8EaNW3cEpX8s","created":"2026-09-30T13:25:15Z"}} \ No newline at end of file diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/actor.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/actor.json new file mode 100644 index 000000000..cd1f164d9 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/actor.json @@ -0,0 +1,56 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/data-integrity/v1", + "https://w3id.org/security/v1" + ], + "id": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor", + "type": "Person", + "inbox": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/inbox", + "outbox": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/outbox", + "preferredUsername": "alice", + "followers": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/followers", + "publicKey": { + "id": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor#main-key", + "owner": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyLpYZnhnVih6ToB4UThp\nEZIcxbBcGng71XeEfiR42v+cCyUL+jzQm12x/I0a3FNh4dzIicMvtbmLewQ/HscR\nUNIxAFHF8GqshIjg2tDAmGswTQDsvTzBsaEixXtL0qTTX8X0tFzVKJEsMJJ99jzg\nodERW73G55WwpJYyI4v1RT3G5tU3p0tmD52hhCLCRLRCPKy75iz416nCwDt5sA8B\nowVE5n/J+tjqG3umnnI3gJpTtuJxTyB/SVjLjnC604RKowwQQTHGAmcl3E5F3IrK\nfnmfqdXNCrNbfvJFFAWB+XNXFB0I+fJbGUZAOYMfjhMGEpPzzkKI8cI1eR+Z5DeZ\nGQIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "icon": [ + { + "type": "Image", + "mediaType": "image/gif", + "url": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/icon.gif" + } + ], + "manuallyApprovesFollowers": false, + "assertionMethod": [ + { + "id": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor#ed25519-key", + "type": "Multikey", + "controller": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor", + "publicKeyMultibase": "z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR" + }, + { + "id": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor#ml-dsa-44-key", + "type": "Multikey", + "controller": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor", + "publicKeyMultibase": "ukCQjRdBDVD0QfnNnj4wFAJE82TmNXoNQ80Rf6s3ivFXlFCzb5_tZHVhfsR5JysgCbOqYPnXYyXIgXAm_klgaj1a4_MB-KLhmueucnnMKUjl60ORt4RG2fDAjZoCzBy-m7PMX5hByOfuDTXbAhSFhG44xvBumN2x877PLudpMqhe9hhBDwgL4NTxUWOP3xJR4KhO0GMzjA6r4HGw0F2Mw3cYQNJs2t40k9w_Yt1qiVfyr4Qk0pk5vnZEkNFF71OBm-SUUSPtrHQEo02HhElN7uFE8wgYmziC_RqzrvyWAi9XQofgDGps2d-xXQew28NkyhAjv-7yIwd3ukjm_0UxjslLFpcjRAW7hNkrIm6oxV_Wv3ynpUVII7uc6v3Q3hkTtJxL4bcsl-oOpZKAqJide5A09G0XE_PvPrnVU3n9hH1HIhs4aWUeo3xda_gLfA5yoavGhqh1oOKnT3yiZYysjKt4GbdcLE_AMCDvWAqLdHTywnl5CG_9gUa3GlgjEsrJK8-SWCXoVgjQmGtdLWWMXTwzAwNZZwkoiR72v0uVOAzE54U_0oz6_Fowdgr29o0qu8TTb6NY70fF34XMWDDlKOWpgo7s5ejL15jfsrzcLhzP1xQlcBqQRZIsSQ_e0z_6mPJlYMu-UjsJIu4SM1__mn48TAQbw__B7VtClD_wGpedwF8gPpATziNsmOVvK8LKtYt983i2bzLYlV3Um31R4r-0i13JY6tBDC3SXkbOyOW3HkfecC1EJ11ffqoBwYT6KJGYH1pd8YR7cvwQn6C4kItLQnoUcIPBY7hKmw6B78e0ZexMMZlmQkW_JEHpgRi0Fb9atgSfGs8IIHTZGOkU5MGUUH1Evqz995dqFjoUxZaCGNKE2Rh-c0F4UdVToex7ZniQOFL1-D16mTloNwPgA9tvd7SUnSY2fr_E4Vyt-Rvcy_azBWBZWPzKdOy9u0OEW8uLeX680qp1Qbx97zDwCsiNAoTRMPyS_azqB12RThb3L-o28UXw5cPyeW9NSSN3G4yaweaIDmQ16vB1biKknrOU9XNVwkwZ4ilzYoESkGmQoCOomrNjGclx99d42S_7laMBlOkQcy846EyxhaHpkOj7t5LIU4Vs1TKeXXDV08wZQHz_r557uwtly8ltLHCg1pWm6MJNRgkhcGBhlE7Jt3gybA9HkYrg_x3NTR-uQocckeUbZZI1Q0aQuMa_F6_qC8WJOAkGDfERlFs7-gVjqYtTSHFLky3B_CgZukp_YZ-HLDlbxAO2qw_itfcn3fn95LLPUxiOZvB49xyha_z2r4rHt9R0BymvDM9ufp-pg2CiLBe3cPiy1Ck_BE7kvA7TyjShi3YyQIGfUcwAoWXOj4lKwejeqUmsjJ-gpD2iVJ3frWao9Cu846ubamb6wQZf5faAx6yTJsHLYdeDBqqJRCMSVEnOYHf6SaNfzdE8EFqCJ7LP2IYDnSFaiZovhja6BJBM4fphH27mnkrQ10whn35XX843QVAOLJa5fn4GoIwkSFY0PSL1J4MT1MobKfA0lROfF5fE29sKLRt-wbnHveAFE_CRiyzW6IFQO9flnSmn83VxigN2hv_xD51KX6p8dCzX1QLl0S9fWF1K9iHkq4ulz6slvypfacesLLGvbVnAWX491PPq9LIOHjCLoZbr1Ap8vkLw61-XvDFSBHUxGKvrlpPOKO5V3zop0sT_QiEymx9DpGAGrbYiyDEC3LhNmD14DxRdRqQLG3wW6HFTMJtl6" + } + ], + "gateways": [ + "https://tootik.example" + ], + "proof": { + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/data-integrity/v1", + "https://w3id.org/security/v1" + ], + "type": "DataIntegrityProof", + "cryptosuite": "eddsa-jcs-2022", + "verificationMethod": "did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR#z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR", + "proofPurpose": "assertionMethod", + "proofValue": "z2G5haKKAJk3rfL8njG9V2jybnPuHrXjR8ipPBjDSFim9cFuJ9xEMEWBLQLdBmoQKXmHhqXfheadf8EaNW3cEpX8s", + "created": "2026-09-30T13:25:15Z" + } +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/metadata.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/metadata.json new file mode 100644 index 000000000..28a63ea00 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/metadata.json @@ -0,0 +1,20 @@ +{ + "implementation": "tootik", + "version": "0.25.4", + "tag": "v0.25.4", + "commit": "5ce4b7fe074d7c385808be387ffcda7040842a19", + "binarySha256": "c24982af1a58cf8d4a8ae1a66dae7252d90bb1310c31d297ddc4b040d790f0c2", + "capturedAt": "2026-09-30T13:30:43.325Z", + "requestUrl": "https://fedify.example:18444/users/alice/inbox", + "actorUrl": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor", + "actorLoaderUrl": "https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor#main-key", + "activityType": "Follow", + "actorType": "Person", + "requestBodySha256": "6650d90a7758918702bcf329166459244f904f5495b70a297be28f695e54febf", + "actorBodySha256": "a58dad10d1051aed670bd79ee7dbfb9d3606cc8e6f231a9a742edd9317b28cd8", + "liveResult": { + "httpSignatureVerified": true, + "inboxStatus": 202, + "listenerActivityType": "Follow" + } +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/raw-bodies.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/raw-bodies.json new file mode 100644 index 000000000..565216963 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/raw-bodies.json @@ -0,0 +1,4 @@ +{ + "requestBody": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/v1\"],\"id\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/follow/01a0f282-9cba-7125-af77-e8c7210b7b65\",\"type\":\"Follow\",\"actor\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor\",\"object\":\"https://fedify.example:18444/users/alice\",\"to\":[\"https://fedify.example:18444/users/alice\"],\"cc\":[],\"proof\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/v1\"],\"type\":\"DataIntegrityProof\",\"cryptosuite\":\"eddsa-jcs-2022\",\"verificationMethod\":\"did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR#z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z4yttRN3ak6xdXqdkg6KF9UyiVLv85tbcEvGFEcAKRSg5hpzhMFZzK2A8dp3o3wnJq5CA9t6nc47umjJkjmT5Kpmk\",\"created\":\"2026-09-30T13:30:41Z\"}}", + "actorBody": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/v1\"],\"id\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor\",\"type\":\"Person\",\"inbox\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/inbox\",\"outbox\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/outbox\",\"preferredUsername\":\"alice\",\"followers\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/followers\",\"publicKey\":{\"id\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor#main-key\",\"owner\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor\",\"publicKeyPem\":\"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyLpYZnhnVih6ToB4UThp\\nEZIcxbBcGng71XeEfiR42v+cCyUL+jzQm12x/I0a3FNh4dzIicMvtbmLewQ/HscR\\nUNIxAFHF8GqshIjg2tDAmGswTQDsvTzBsaEixXtL0qTTX8X0tFzVKJEsMJJ99jzg\\nodERW73G55WwpJYyI4v1RT3G5tU3p0tmD52hhCLCRLRCPKy75iz416nCwDt5sA8B\\nowVE5n/J+tjqG3umnnI3gJpTtuJxTyB/SVjLjnC604RKowwQQTHGAmcl3E5F3IrK\\nfnmfqdXNCrNbfvJFFAWB+XNXFB0I+fJbGUZAOYMfjhMGEpPzzkKI8cI1eR+Z5DeZ\\nGQIDAQAB\\n-----END PUBLIC KEY-----\\n\"},\"icon\":[{\"type\":\"Image\",\"mediaType\":\"image/gif\",\"url\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/icon.gif\"}],\"manuallyApprovesFollowers\":false,\"assertionMethod\":[{\"id\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor#ed25519-key\",\"type\":\"Multikey\",\"controller\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor\",\"publicKeyMultibase\":\"z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR\"},{\"id\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor#ml-dsa-44-key\",\"type\":\"Multikey\",\"controller\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor\",\"publicKeyMultibase\":\"ukCQjRdBDVD0QfnNnj4wFAJE82TmNXoNQ80Rf6s3ivFXlFCzb5_tZHVhfsR5JysgCbOqYPnXYyXIgXAm_klgaj1a4_MB-KLhmueucnnMKUjl60ORt4RG2fDAjZoCzBy-m7PMX5hByOfuDTXbAhSFhG44xvBumN2x877PLudpMqhe9hhBDwgL4NTxUWOP3xJR4KhO0GMzjA6r4HGw0F2Mw3cYQNJs2t40k9w_Yt1qiVfyr4Qk0pk5vnZEkNFF71OBm-SUUSPtrHQEo02HhElN7uFE8wgYmziC_RqzrvyWAi9XQofgDGps2d-xXQew28NkyhAjv-7yIwd3ukjm_0UxjslLFpcjRAW7hNkrIm6oxV_Wv3ynpUVII7uc6v3Q3hkTtJxL4bcsl-oOpZKAqJide5A09G0XE_PvPrnVU3n9hH1HIhs4aWUeo3xda_gLfA5yoavGhqh1oOKnT3yiZYysjKt4GbdcLE_AMCDvWAqLdHTywnl5CG_9gUa3GlgjEsrJK8-SWCXoVgjQmGtdLWWMXTwzAwNZZwkoiR72v0uVOAzE54U_0oz6_Fowdgr29o0qu8TTb6NY70fF34XMWDDlKOWpgo7s5ejL15jfsrzcLhzP1xQlcBqQRZIsSQ_e0z_6mPJlYMu-UjsJIu4SM1__mn48TAQbw__B7VtClD_wGpedwF8gPpATziNsmOVvK8LKtYt983i2bzLYlV3Um31R4r-0i13JY6tBDC3SXkbOyOW3HkfecC1EJ11ffqoBwYT6KJGYH1pd8YR7cvwQn6C4kItLQnoUcIPBY7hKmw6B78e0ZexMMZlmQkW_JEHpgRi0Fb9atgSfGs8IIHTZGOkU5MGUUH1Evqz995dqFjoUxZaCGNKE2Rh-c0F4UdVToex7ZniQOFL1-D16mTloNwPgA9tvd7SUnSY2fr_E4Vyt-Rvcy_azBWBZWPzKdOy9u0OEW8uLeX680qp1Qbx97zDwCsiNAoTRMPyS_azqB12RThb3L-o28UXw5cPyeW9NSSN3G4yaweaIDmQ16vB1biKknrOU9XNVwkwZ4ilzYoESkGmQoCOomrNjGclx99d42S_7laMBlOkQcy846EyxhaHpkOj7t5LIU4Vs1TKeXXDV08wZQHz_r557uwtly8ltLHCg1pWm6MJNRgkhcGBhlE7Jt3gybA9HkYrg_x3NTR-uQocckeUbZZI1Q0aQuMa_F6_qC8WJOAkGDfERlFs7-gVjqYtTSHFLky3B_CgZukp_YZ-HLDlbxAO2qw_itfcn3fn95LLPUxiOZvB49xyha_z2r4rHt9R0BymvDM9ufp-pg2CiLBe3cPiy1Ck_BE7kvA7TyjShi3YyQIGfUcwAoWXOj4lKwejeqUmsjJ-gpD2iVJ3frWao9Cu846ubamb6wQZf5faAx6yTJsHLYdeDBqqJRCMSVEnOYHf6SaNfzdE8EFqCJ7LP2IYDnSFaiZovhja6BJBM4fphH27mnkrQ10whn35XX843QVAOLJa5fn4GoIwkSFY0PSL1J4MT1MobKfA0lROfF5fE29sKLRt-wbnHveAFE_CRiyzW6IFQO9flnSmn83VxigN2hv_xD51KX6p8dCzX1QLl0S9fWF1K9iHkq4ulz6slvypfacesLLGvbVnAWX491PPq9LIOHjCLoZbr1Ap8vkLw61-XvDFSBHUxGKvrlpPOKO5V3zop0sT_QiEymx9DpGAGrbYiyDEC3LhNmD14DxRdRqQLG3wW6HFTMJtl6\"}],\"gateways\":[\"https://tootik.example\"],\"proof\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/v1\"],\"type\":\"DataIntegrityProof\",\"cryptosuite\":\"eddsa-jcs-2022\",\"verificationMethod\":\"did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR#z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z2G5haKKAJk3rfL8njG9V2jybnPuHrXjR8ipPBjDSFim9cFuJ9xEMEWBLQLdBmoQKXmHhqXfheadf8EaNW3cEpX8s\",\"created\":\"2026-09-30T13:25:15Z\"}}" +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/request.body b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/request.body new file mode 100644 index 000000000..c40777da0 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/request.body @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/v1"],"id":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor/follow/01a0f282-9cba-7125-af77-e8c7210b7b65","type":"Follow","actor":"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor","object":"https://fedify.example:18444/users/alice","to":["https://fedify.example:18444/users/alice"],"cc":[],"proof":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/v1"],"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","verificationMethod":"did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR#z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR","proofPurpose":"assertionMethod","proofValue":"z4yttRN3ak6xdXqdkg6KF9UyiVLv85tbcEvGFEcAKRSg5hpzhMFZzK2A8dp3o3wnJq5CA9t6nc47umjJkjmT5Kpmk","created":"2026-09-30T13:30:41Z"}} \ No newline at end of file diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/request.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/request.json new file mode 100644 index 000000000..1fae80204 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/request.json @@ -0,0 +1,39 @@ +{ + "url": "https://fedify.example:18444/users/alice/inbox", + "method": "POST", + "headers": [ + [ + "accept-encoding", + "gzip" + ], + [ + "content-length", + "1033" + ], + [ + "content-type", + "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"" + ], + [ + "date", + "Wed, 30 Sep 2026 13:30:43 GMT" + ], + [ + "digest", + "SHA-256=ZlDZCndYkYcCvPMpFmRZJE+QT1SVtwope+KPaV5U/r8=" + ], + [ + "host", + "fedify.example:18444" + ], + [ + "signature", + "keyId=\"https://tootik.example/.well-known/apgateway/did:key:z6MkpWqhz4YAuBfC4ddjU49mGfs6CAuYcm243K5hW2YEGAyR/actor#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date content-type digest\",signature=\"Rqd+mtn7knlPY5SXUE2Zz93ICDgBeamFu5v8SagsII8vYcBTX1gan+S0oded4+f4gLB0cs+xdlaqeAUBj3BtWYBJ/cEcCWDFp+bB0xhq/grE/xt4fkdgCCfXWSU2EnJuFCEmUoB1zRemNvTOHwZV4wDrkLVwQsIxrUIjPbMFTVGyMjnpY71Ydta3rdia7VW0VWK3gEC4FJ6YweFxV52dmcOTmA3Qj1h0riHHVEZXs5UOzPJLL6FJQoz8ezyjE7LanxSoXpeOSHa5K1fAo9i35eJr1/eQdFpHt7ftabpv3+6u6MhCFAt2lJs3XJbJZL8DYNkYwJNAYi9fqmH8JOVuMw==\"" + ], + [ + "user-agent", + "tootik/0.25.4" + ] + ], + "capturedAt": "2026-09-30T13:30:43.325Z" +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/README.md b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/README.md new file mode 100644 index 000000000..0b505832a --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/README.md @@ -0,0 +1,91 @@ +Fedify to tootik portable create capture +======================================== + +This fixture records native `signObject()` and `Context.sendActivity()` output +received by the unmodified official tootik v0.25.4 binary. The source commit +and binary SHA-256 match the [parent fixture]. It complements the +[tootik to Fedify capture]. Mastodon was not tested. + +The sender used a signed portable `Person`, a separately signed public `Note`, +and a signed `Create` embedding that `Note`. Signing used the default JSON-LD +contexts. Sending used `normalizeExistingProofs: true`, as required for +locally pre-signed activities. No vocabulary subclass, gateway rewrite, or +re-signing of the outgoing wire document was used. + +Tootik initially returned HTTP 401 with `actor is too young`. Fedify's retry +delivered the same body and received HTTP 202. The recorded SQLite query then +found the exact note ID, author, and content in tootik's `notes` table. This +establishes asynchronous processing, beyond acceptance into an inbox queue. +A separate request changing the embedded note's content after signing returned +HTTP 401. + +Tootik authenticates proof-bearing activities through their Object Integrity +Proofs and skips HTTP Signature verification on that path. The accepted +request also carried a Cavage RSA gateway HTTP Signature, which the offline +test verifies independently at the capture time. That check does not imply +that tootik enforced the HTTP Signature during this delivery. + +The *.body* files preserve the outgoing request and served sender actor bytes. +The recipient actor is a compact JSON copy of the tootik response. +*raw-bodies.json* holds these bodies as JSON strings for runtime-neutral test +imports; regenerate it with the bodies and their hashes when recapturing. +The request/response records include the original URL, headers, receipt time, +and statuses. *processed-note.json* records the database query and its result. +*metadata.json* records provenance and body hashes. Private keys, databases, +and TLS certificates are excluded. + +[parent fixture]: ../README.md +[tootik to Fedify capture]: ../follow/README.md + + +Capture procedure +----------------- + +Start with the pinned binary, registered recipient, TLS certificates, and +Fedify receiver described in the [tootik to Fedify capture]. Preserve the +receiver's ordinary actor and inbox routes. Add a route serving the exact +signed sender `Person` at its compatible portable actor URL. + +The sender gateway must have no explicit port: tootik v0.25.4's portable +gateway identifier matcher does not recognize an actor URL containing a port. +The capture used `https://fedify.example`, with a TLS passthrough proxy on a +dedicated Podman network. The proxy was named `fedify.example` and forwarded +TCP ports 443 and 18444 to `host.containers.internal:18444`. The receiver bound +to `0.0.0.0:18444` for that route. Tootik kept its original database, binary, +configuration, and certificates. This was transport configuration, not a +modification to either implementation. + +Generate a fresh Ed25519 identity key and separate gateway signing keys. Use +`exportDidKey()` for the identity DID, and `toCompatibleEf61Id()` for the +sender's actor, inbox, outbox, activity, and note identifiers under +`https://fedify.example/.well-known/apgateway/`. Publish the gateway keys in +the actor's `publicKey` and `assertionMethods`. Sign the actor, note, and +activity with the identity key and its `did:key` verification method. The +public note's `tos` include the full ActivityStreams Public URI and the +tootik recipient's actor URL. + +Send the activity through the native API: + +~~~~ typescript +await ctx.sendActivity(gatewayKeys, recipient, signedCreate, { + normalizeExistingProofs: true, +}); +~~~~ + +Capture each HTTP attempt before transmission. For the local test, connect +to `https://localhost:18443` while retaining the signed request's original +`https://tootik.example` URL and `Host` value in the capture. Trust the local +CA explicitly. Keep the actor server available while tootik resolves the +sender and processes its queue. Use the repository's context snapshots for +signing and retain the original raw documents for verification. + +After HTTP 202, query tootik's SQLite database for the exact generated note +ID, and verify its author and content. Send a second request changing only +the embedded content without updating either proof, and record its rejection. +Fresh keys and proof timestamps make repeated capture bytes differ. + +Replay the recorded fixture with: + +~~~~ bash +mise run test:deno packages/fedify/src/sig/tootik-send-interop.test.ts +~~~~ diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/actor.body b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/actor.body new file mode 100644 index 000000000..73159c4e3 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/actor.body @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/fep/ef61","https://w3id.org/security/v1","https://w3id.org/security/data-integrity/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/multikey/v1","https://gotosocial.org/ns","https://w3id.org/fep/7aa9",{"alsoKnownAs":{"@id":"as:alsoKnownAs","@type":"@id"},"featuredCollections":{"@id":"https://w3id.org/fep/7aa9#featuredCollections","@type":"@id"},"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","movedTo":{"@id":"as:movedTo","@type":"@id"},"toot":"http://joinmastodon.org/ns#","Emoji":"toot:Emoji","featured":{"@id":"toot:featured","@type":"@id"},"featuredTags":{"@id":"toot:featuredTags","@type":"@id"},"discoverable":"toot:discoverable","suspended":"toot:suspended","memorial":"toot:memorial","indexable":"toot:indexable","schema":"http://schema.org#","PropertyValue":"schema:PropertyValue","value":"schema:value","misskey":"https://misskey-hub.net/ns#","_misskey_followedMessage":"misskey:_misskey_followedMessage","isCat":"misskey:isCat"}],"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor","type":"Person","inbox":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor/inbox","gateways":["https://fedify.example/"],"assertionMethod":[{"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#ed25519-key","type":"Multikey","controller":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor","publicKeyMultibase":"z6MkoHdcDxRg36BmHgY8riW5xW8NbZdbgKBMmXUoyDAN9LEX"},{"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#main-key","type":"Multikey","controller":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor","publicKeyMultibase":"zgghBUVkqmWS8e1j5pNkit2HZTY7551YeVnqt4nok9y5j6Qj4zHfHAiTCUWeiSfvfgC8cuknF4312kUZa79gAAwCyoXqA3PZppMxsGmdwRprmxYkGrZkfvmmLfzCvw6faQrsph6hiMvYtFEQUZTwd2n6CG9j7ZqiXA5NGN9WRu5MNqucWNpMTQZFSdPnow2GgMnGy7G5fDhg7BQtSPLCYdEWEipFWJuy6nKwmySnffKYnZQZQRzNysFg2xJ91ZceWVrAjFxHwjekyUe2CrkNM1vYq829SnCoXUfPBsA31ujzVuYBwjDZhCDXmJ87fbWFmDg6zmwyXLdGLRmGY3nbkU8Jwt4iyRNqCpjirKjEx54JQj2wahyxL6r2BBjMnuoisDXNi6vjztoE7WbmHDoMVoz9qGUv5s2b6VVvn7vNgHYjjvKjYLbrj2fhe6ccwycxphU5vphepKWTRCNa3DsC8HpCjBjq3YZ9da8P8JorDKWyZLRAUn6piCn1LMJpHDDbeun1YgdXw3sDhDk5bHfBUJ7y5Lgnob8HpVBcjDA7ttbBEtFJ1RYb7XFYJJcaersNhWAoiZtLaQucHdNoRWJF8ByRJPRp5wz9rk2tkzTQoA5PFdomjbgYhqdq77d9VMuUPHJ97117xGVffGjGFipt5ZEuNazcVfes8Z21XzHBR7D39GyYvGAs1aiFx4wmyLiCw21ATd6Uq2kN6EcHex"}],"proof":{"type":"DataIntegrityProof","created":"2026-09-30T14:16:34.822909912Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z2qzHQQ9yWvvfJdZvcWRKU8gYBnKNNMzppy7J6pcr7tqWevY3PFr3RUAVrnK9yuCPh9oP27XWPXrmQjaPDEkJm6Yx","verificationMethod":"did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN","@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/fep/ef61","https://w3id.org/security/v1","https://w3id.org/security/data-integrity/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/multikey/v1","https://gotosocial.org/ns","https://w3id.org/fep/7aa9",{"alsoKnownAs":{"@id":"as:alsoKnownAs","@type":"@id"},"featuredCollections":{"@id":"https://w3id.org/fep/7aa9#featuredCollections","@type":"@id"},"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","movedTo":{"@id":"as:movedTo","@type":"@id"},"toot":"http://joinmastodon.org/ns#","Emoji":"toot:Emoji","featured":{"@id":"toot:featured","@type":"@id"},"featuredTags":{"@id":"toot:featuredTags","@type":"@id"},"discoverable":"toot:discoverable","suspended":"toot:suspended","memorial":"toot:memorial","indexable":"toot:indexable","schema":"http://schema.org#","PropertyValue":"schema:PropertyValue","value":"schema:value","misskey":"https://misskey-hub.net/ns#","_misskey_followedMessage":"misskey:_misskey_followedMessage","isCat":"misskey:isCat"}]},"publicKey":{"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#main-key","type":"CryptographicKey","owner":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5PRU4GP79WfFGwBvSJ4V\ntAmtreYrzQuLY/whIprIZScL7t5lvvdyu8qX6odu0LsBozosQ1A/oyaCv00jyhjj\nupQdtJXhzW+WG9AuZT4rH4Z0r9u1bpGJT67msalb4ffDxS1d8Ipb1Xe/Hfs6Uu+d\niyINnR3S4qj1bOXLBfNt4lI1wfycFwFtmtqOsxLKqY0VMZ2d9yeYnAUYAOh/C82t\ng69nuXkeyyRJUNSBaY7ej6jnSPbJCpSsnYHzL/bE5h37vo0DUClV5ZPUGzFggDYK\nYC6py31LOEXIn94AV4xVSVpKrQEPeBHrcx4ejJuUVpA9s9L5OoLMcUyZS5OSs8ek\nM8Mj+LjCkakzsZWCusWstyebsszYNz1zq/yiXBiJJ0ypcbraYkltLJ5Ui8KSdH6e\n2r5zC951YifyJZp8p+qK+Z52ZGjbMsWlfwHAynZEn8F5Bqzd4Xlo4s8/mgYtJBIk\nKC4t4HgPXZSCH866wyOOJZz1m7jS5XwopX5s/ST7XzLVw9WpTqd2hqRGpAvCGR42\nM8JOcPqHCAi/KjN4Nyhj9e3TzkoETYYqzQvxCy0LeDi/dHr8EDbT7tF5rCAeglc9\nWWSBqpOnromClOWxX9HgklXvUmid4CkstoQzFb5H+uovtbLrPzMY9kokEXnG69UD\nVkq6SwoNVm0551D8M2smtf0CAwEAAQ==\n-----END PUBLIC KEY-----\n"},"name":"Native Fedify portable sender","outbox":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor/outbox","preferredUsername":"fedifyreverse"} \ No newline at end of file diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/actor.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/actor.json new file mode 100644 index 000000000..cf10450e6 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/actor.json @@ -0,0 +1,129 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/fep/ef61", + "https://w3id.org/security/v1", + "https://w3id.org/security/data-integrity/v1", + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/multikey/v1", + "https://gotosocial.org/ns", + "https://w3id.org/fep/7aa9", + { + "alsoKnownAs": { + "@id": "as:alsoKnownAs", + "@type": "@id" + }, + "featuredCollections": { + "@id": "https://w3id.org/fep/7aa9#featuredCollections", + "@type": "@id" + }, + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "movedTo": { + "@id": "as:movedTo", + "@type": "@id" + }, + "toot": "http://joinmastodon.org/ns#", + "Emoji": "toot:Emoji", + "featured": { + "@id": "toot:featured", + "@type": "@id" + }, + "featuredTags": { + "@id": "toot:featuredTags", + "@type": "@id" + }, + "discoverable": "toot:discoverable", + "suspended": "toot:suspended", + "memorial": "toot:memorial", + "indexable": "toot:indexable", + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value", + "misskey": "https://misskey-hub.net/ns#", + "_misskey_followedMessage": "misskey:_misskey_followedMessage", + "isCat": "misskey:isCat" + } + ], + "id": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor", + "type": "Person", + "inbox": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor/inbox", + "gateways": [ + "https://fedify.example/" + ], + "assertionMethod": [ + { + "id": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#ed25519-key", + "type": "Multikey", + "controller": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor", + "publicKeyMultibase": "z6MkoHdcDxRg36BmHgY8riW5xW8NbZdbgKBMmXUoyDAN9LEX" + }, + { + "id": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#main-key", + "type": "Multikey", + "controller": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor", + "publicKeyMultibase": "zgghBUVkqmWS8e1j5pNkit2HZTY7551YeVnqt4nok9y5j6Qj4zHfHAiTCUWeiSfvfgC8cuknF4312kUZa79gAAwCyoXqA3PZppMxsGmdwRprmxYkGrZkfvmmLfzCvw6faQrsph6hiMvYtFEQUZTwd2n6CG9j7ZqiXA5NGN9WRu5MNqucWNpMTQZFSdPnow2GgMnGy7G5fDhg7BQtSPLCYdEWEipFWJuy6nKwmySnffKYnZQZQRzNysFg2xJ91ZceWVrAjFxHwjekyUe2CrkNM1vYq829SnCoXUfPBsA31ujzVuYBwjDZhCDXmJ87fbWFmDg6zmwyXLdGLRmGY3nbkU8Jwt4iyRNqCpjirKjEx54JQj2wahyxL6r2BBjMnuoisDXNi6vjztoE7WbmHDoMVoz9qGUv5s2b6VVvn7vNgHYjjvKjYLbrj2fhe6ccwycxphU5vphepKWTRCNa3DsC8HpCjBjq3YZ9da8P8JorDKWyZLRAUn6piCn1LMJpHDDbeun1YgdXw3sDhDk5bHfBUJ7y5Lgnob8HpVBcjDA7ttbBEtFJ1RYb7XFYJJcaersNhWAoiZtLaQucHdNoRWJF8ByRJPRp5wz9rk2tkzTQoA5PFdomjbgYhqdq77d9VMuUPHJ97117xGVffGjGFipt5ZEuNazcVfes8Z21XzHBR7D39GyYvGAs1aiFx4wmyLiCw21ATd6Uq2kN6EcHex" + } + ], + "proof": { + "type": "DataIntegrityProof", + "created": "2026-09-30T14:16:34.822909912Z", + "cryptosuite": "eddsa-jcs-2022", + "proofPurpose": "assertionMethod", + "proofValue": "z2qzHQQ9yWvvfJdZvcWRKU8gYBnKNNMzppy7J6pcr7tqWevY3PFr3RUAVrnK9yuCPh9oP27XWPXrmQjaPDEkJm6Yx", + "verificationMethod": "did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN", + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/fep/ef61", + "https://w3id.org/security/v1", + "https://w3id.org/security/data-integrity/v1", + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/multikey/v1", + "https://gotosocial.org/ns", + "https://w3id.org/fep/7aa9", + { + "alsoKnownAs": { + "@id": "as:alsoKnownAs", + "@type": "@id" + }, + "featuredCollections": { + "@id": "https://w3id.org/fep/7aa9#featuredCollections", + "@type": "@id" + }, + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "movedTo": { + "@id": "as:movedTo", + "@type": "@id" + }, + "toot": "http://joinmastodon.org/ns#", + "Emoji": "toot:Emoji", + "featured": { + "@id": "toot:featured", + "@type": "@id" + }, + "featuredTags": { + "@id": "toot:featuredTags", + "@type": "@id" + }, + "discoverable": "toot:discoverable", + "suspended": "toot:suspended", + "memorial": "toot:memorial", + "indexable": "toot:indexable", + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value", + "misskey": "https://misskey-hub.net/ns#", + "_misskey_followedMessage": "misskey:_misskey_followedMessage", + "isCat": "misskey:isCat" + } + ] + }, + "publicKey": { + "id": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#main-key", + "type": "CryptographicKey", + "owner": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5PRU4GP79WfFGwBvSJ4V\ntAmtreYrzQuLY/whIprIZScL7t5lvvdyu8qX6odu0LsBozosQ1A/oyaCv00jyhjj\nupQdtJXhzW+WG9AuZT4rH4Z0r9u1bpGJT67msalb4ffDxS1d8Ipb1Xe/Hfs6Uu+d\niyINnR3S4qj1bOXLBfNt4lI1wfycFwFtmtqOsxLKqY0VMZ2d9yeYnAUYAOh/C82t\ng69nuXkeyyRJUNSBaY7ej6jnSPbJCpSsnYHzL/bE5h37vo0DUClV5ZPUGzFggDYK\nYC6py31LOEXIn94AV4xVSVpKrQEPeBHrcx4ejJuUVpA9s9L5OoLMcUyZS5OSs8ek\nM8Mj+LjCkakzsZWCusWstyebsszYNz1zq/yiXBiJJ0ypcbraYkltLJ5Ui8KSdH6e\n2r5zC951YifyJZp8p+qK+Z52ZGjbMsWlfwHAynZEn8F5Bqzd4Xlo4s8/mgYtJBIk\nKC4t4HgPXZSCH866wyOOJZz1m7jS5XwopX5s/ST7XzLVw9WpTqd2hqRGpAvCGR42\nM8JOcPqHCAi/KjN4Nyhj9e3TzkoETYYqzQvxCy0LeDi/dHr8EDbT7tF5rCAeglc9\nWWSBqpOnromClOWxX9HgklXvUmid4CkstoQzFb5H+uovtbLrPzMY9kokEXnG69UD\nVkq6SwoNVm0551D8M2smtf0CAwEAAQ==\n-----END PUBLIC KEY-----\n" + }, + "name": "Native Fedify portable sender", + "outbox": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor/outbox", + "preferredUsername": "fedifyreverse" +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/first-request.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/first-request.json new file mode 100644 index 000000000..ffa17b4d5 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/first-request.json @@ -0,0 +1,31 @@ +{ + "url": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/inbox", + "method": "POST", + "headers": [ + [ + "content-digest", + "sha-256=:WB7t6jsP47/AEPHyEcEz/RSb1MTRXkeJ7y/zuMLzJVc=:" + ], + [ + "content-type", + "application/activity+json" + ], + [ + "date", + "Wed, 30 Sep 2026 14:16:34 GMT" + ], + [ + "host", + "tootik.example" + ], + [ + "signature", + "sig1=:LNql9D4KSPhxjjz3JcCrPhx8qtaIWWRFxqYQVGQLVFJdbx9pKROOCWzqOqPWuSQb0LQmSxfiJnIP5//IIJV1wpWjBs5aFWO8VwqlGDo9aA1pMV/TxsBrLMZKSzQrPKhJIwVg4wjEy5ylBrfl5XTMVwG/wYPKZhVyEPQkNrbIinCHPI+6esPcJGx9dubLmyJPqHgYNMB9G9+lWwkdQGe1l52UkaA7O0MxjeceqpcKOommoLIfJc3EiVVLbOwJVKj4ypVm2fMBt0Pa7ed11IrVZgnR3SmBeP4XMZMHFUYHgBFdI2Lp890wZiK7jykoQop7R4+gBUY4i8vNLQrVqAmY85TugaR55t6qfJLC1bUWa7WsoK27yrCicJnuOnqfO3BR+xzi9JJVMLCVHOT8BiW8RZRtirIchKmT4DB+avl5L7ZTuoMAIzmLtFRM5dZ25PbcsfPqvfTbyM5B6IZ9zq7qPFckLLk/p3+Aaf51YrtJUtxwFLM3JRrs2W7fzNkLI7vSmCXGGREgWVJ/GzoT/cpGkoOqgF/E/zTQzKG07yWQZB37KEyKjQJNSlOJpCX81gnsH8qMUlhN8UwJ9TYwip5sCRTrXgih09WwY9JCCDOyaa/nVuDGdwe3052addFrt8Ksoh5yIz7nzUtRI0F7UJW25+Sj1mZ++ceoxXlzuRz9vrs=:" + ], + [ + "signature-input", + "sig1=(\"@method\" \"@target-uri\" \"@authority\" \"host\" \"date\" \"content-digest\");alg=\"rsa-v1_5-sha256\";keyid=\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#main-key\";created=1790777794" + ] + ], + "capturedAt": "2026-09-30T14:16:34.891Z" +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/first-response.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/first-response.json new file mode 100644 index 000000000..58dfbd5cf --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/first-response.json @@ -0,0 +1,18 @@ +{ + "status": 401, + "headers": [ + [ + "content-length", + "31" + ], + [ + "content-type", + "application/json" + ], + [ + "date", + "Wed, 30 Sep 2026 14:16:35 GMT" + ] + ], + "body": "{\"error\":\"actor is too young\"}\n" +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/metadata.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/metadata.json new file mode 100644 index 000000000..27881e4de --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/metadata.json @@ -0,0 +1,64 @@ +{ + "implementation": "tootik", + "version": "0.25.4", + "tag": "v0.25.4", + "commit": "5ce4b7fe074d7c385808be387ffcda7040842a19", + "binarySha256": "c24982af1a58cf8d4a8ae1a66dae7252d90bb1310c31d297ddc4b040d790f0c2", + "direction": "Fedify to tootik", + "capturedAt": "2026-09-30T14:16:35.040Z", + "requestUrl": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/inbox", + "sha256": { + "requestBody": "581eedea3b0fe3bfc010f1f211c133fd149bd4c4d15e4789ef2ff3b8c2f32557", + "actorBody": "e164c9b9c9009887a97b4260b3acdad5cb68281b11663a2f99e1e3cf66b8d5c1", + "recipientBody": "8104376557559155f4a82406a66bc7ac571dd02bd23ee8ad9cbbb9eefc4e6aa5", + "tamperedBody": "5a6f2c7fe5dccac671511d0a6b43d9bb5158acdb585ae6897d78be34c96a919b" + }, + "firstAttempt": { + "spec": "rfc9421", + "status": 401, + "reason": "actor is too young" + }, + "acceptedAttempt": { + "spec": "draft-cavage-http-signatures-12", + "status": 202, + "nativeNotePersisted": true + }, + "tamperedNestedNoteStatus": 401, + "httpVerification": { + "localReplay": true, + "tootikEnforcedForProofAuthenticatedActivity": false + }, + "strategy": "Native default signObject contexts and Context.sendActivity normalizeExistingProofs:true; compatible HTTPS portable identifiers; transport-only remap with original Host", + "source": { + "repository": "https://github.com/dimkr/tootik", + "tag": "v0.25.4", + "commit": "5ce4b7fe074d7c385808be387ffcda7040842a19", + "binarySha256": "c24982af1a58cf8d4a8ae1a66dae7252d90bb1310c31d297ddc4b040d790f0c2" + }, + "runtime": { + "deno": "deno 2.9.5 (stable, release, x86_64-unknown-linux-gnu)\nv8 15.0.245.2-rusty\ntypescript 6.0.3", + "nativeMethods": [ + "signObject(Person)", + "signObject(Note)", + "signObject(Create)", + "Context.sendActivity(normalizeExistingProofs:true)" + ] + }, + "routing": { + "network": "fedify-1097-reverse-net", + "tlsProxy": "fedify-1097-reverse-proxy; Alpine3.23 socat TCP443/18444 -> host.containers.internal:18444", + "actorGateway": "https://fedify.example", + "inboxTransport": "original signed URL https://tootik.example mapped to https://localhost:18443; retained Host tootik.example; TLS certificate explicitly trusted", + "receiverBind": "0.0.0.0:18444", + "externalBinaryModified": false + }, + "observed": { + "attempt1": 401, + "attempt1Reason": "actor is too young", + "nativeFallbackAttempt2": 202, + "processedDatabaseNote": true, + "tamperedNestedContent": 401, + "authenticationLimit": "tootik verifies object integrity proof in preference to HTTP signatures; this does not establish independent HTTP signature acceptance" + }, + "recipientBodyProvenance": "Semantic copy of the tootik recipient actor produced by parsing and serializing the captured document; not an original wire byte capture" +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/processed-note.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/processed-note.json new file mode 100644 index 000000000..76c9f2aa3 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/processed-note.json @@ -0,0 +1,87 @@ +{ + "capturedAt": "2026-09-30T14:16:58.628204+00:00", + "query": "SELECT id, author, json(object) FROM notes WHERE id = ?", + "parameter": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/notes/native-inbox", + "rows": [ + { + "id": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/notes/native-inbox", + "author": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor", + "object": { + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/data-integrity/v1", + "https://gotosocial.org/ns", + { + "Emoji": "toot:Emoji", + "Hashtag": "as:Hashtag", + "QuoteAuthorization": "https://w3id.org/fep/044f#QuoteAuthorization", + "_misskey_quote": "misskey:_misskey_quote", + "emojiReactions": { + "@id": "fedibird:emojiReactions", + "@type": "@id" + }, + "fedibird": "http://fedibird.com/ns#", + "misskey": "https://misskey-hub.net/ns#", + "quote": { + "@id": "https://w3id.org/fep/044f#quote", + "@type": "@id" + }, + "quoteAuthorization": { + "@id": "https://w3id.org/fep/044f#quoteAuthorization", + "@type": "@id" + }, + "quoteUri": "fedibird:quoteUri", + "quoteUrl": "as:quoteUrl", + "sensitive": "as:sensitive", + "toot": "http://joinmastodon.org/ns#" + } + ], + "id": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/notes/native-inbox", + "type": "Note", + "attributedTo": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor", + "content": "

Native Fedify to tootik v0.25.4 portable interoperability.

", + "to": [ + "https://www.w3.org/ns/activitystreams#Public", + "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor" + ], + "proof": { + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/data-integrity/v1", + "https://gotosocial.org/ns", + { + "Emoji": "toot:Emoji", + "Hashtag": "as:Hashtag", + "QuoteAuthorization": "https://w3id.org/fep/044f#QuoteAuthorization", + "_misskey_quote": "misskey:_misskey_quote", + "emojiReactions": { + "@id": "fedibird:emojiReactions", + "@type": "@id" + }, + "fedibird": "http://fedibird.com/ns#", + "misskey": "https://misskey-hub.net/ns#", + "quote": { + "@id": "https://w3id.org/fep/044f#quote", + "@type": "@id" + }, + "quoteAuthorization": { + "@id": "https://w3id.org/fep/044f#quoteAuthorization", + "@type": "@id" + }, + "quoteUri": "fedibird:quoteUri", + "quoteUrl": "as:quoteUrl", + "sensitive": "as:sensitive", + "toot": "http://joinmastodon.org/ns#" + } + ], + "type": "DataIntegrityProof", + "cryptosuite": "eddsa-jcs-2022", + "verificationMethod": "did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN", + "proofPurpose": "assertionMethod", + "proofValue": "z3Qs33iEXVq9qLD29kiMa26yLGVuYaKvUKCMqPmuj2z3Y4FmjVVtm4Nb3vMGiaeSNvVahpPni6H7ttesNjpZ9SsDe", + "created": "2026-09-30T14:16:34.84575Z" + } + } + } + ] +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/raw-bodies.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/raw-bodies.json new file mode 100644 index 000000000..c73415b3d --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/raw-bodies.json @@ -0,0 +1,6 @@ +{ + "requestBody": "{\"@context\":[\"https://w3id.org/identity/v1\",\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://gotosocial.org/ns\",{\"toot\":\"http://joinmastodon.org/ns#\",\"misskey\":\"https://misskey-hub.net/ns#\",\"fedibird\":\"http://fedibird.com/ns#\",\"sensitive\":\"as:sensitive\",\"votersCount\":{\"@id\":\"toot:votersCount\",\"@type\":\"http://www.w3.org/2001/XMLSchema#nonNegativeInteger\"},\"Emoji\":\"toot:Emoji\",\"Hashtag\":\"as:Hashtag\",\"ChatMessage\":\"http://litepub.social/ns#ChatMessage\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUrl\":\"as:quoteUrl\",\"_misskey_quote\":\"misskey:_misskey_quote\",\"quoteUri\":\"fedibird:quoteUri\",\"QuoteAuthorization\":\"https://w3id.org/fep/044f#QuoteAuthorization\",\"QuoteRequest\":\"https://w3id.org/fep/044f#QuoteRequest\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"emojiReactions\":{\"@id\":\"fedibird:emojiReactions\",\"@type\":\"@id\"}}],\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/creates/native-inbox\",\"type\":\"Create\",\"proof\":{\"type\":\"DataIntegrityProof\",\"created\":\"2026-09-30T14:16:34.859806885Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z4fZQxG72dz6Qp2z1xj9NS96bPRCitAnM1FBVWYqHq65pYdQBwbk5ZJ3S7suxuZYHFPjCuL7vPKHFT8v2w4LHbyUK\",\"verificationMethod\":\"did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN\",\"@context\":[\"https://w3id.org/identity/v1\",\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://gotosocial.org/ns\",{\"toot\":\"http://joinmastodon.org/ns#\",\"misskey\":\"https://misskey-hub.net/ns#\",\"fedibird\":\"http://fedibird.com/ns#\",\"sensitive\":\"as:sensitive\",\"votersCount\":{\"@id\":\"toot:votersCount\",\"@type\":\"http://www.w3.org/2001/XMLSchema#nonNegativeInteger\"},\"Emoji\":\"toot:Emoji\",\"Hashtag\":\"as:Hashtag\",\"ChatMessage\":\"http://litepub.social/ns#ChatMessage\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUrl\":\"as:quoteUrl\",\"_misskey_quote\":\"misskey:_misskey_quote\",\"quoteUri\":\"fedibird:quoteUri\",\"QuoteAuthorization\":\"https://w3id.org/fep/044f#QuoteAuthorization\",\"QuoteRequest\":\"https://w3id.org/fep/044f#QuoteRequest\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"emojiReactions\":{\"@id\":\"fedibird:emojiReactions\",\"@type\":\"@id\"}}]},\"actor\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor\",\"object\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://gotosocial.org/ns\",{\"toot\":\"http://joinmastodon.org/ns#\",\"misskey\":\"https://misskey-hub.net/ns#\",\"fedibird\":\"http://fedibird.com/ns#\",\"sensitive\":\"as:sensitive\",\"Emoji\":\"toot:Emoji\",\"Hashtag\":\"as:Hashtag\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUrl\":\"as:quoteUrl\",\"_misskey_quote\":\"misskey:_misskey_quote\",\"quoteUri\":\"fedibird:quoteUri\",\"QuoteAuthorization\":\"https://w3id.org/fep/044f#QuoteAuthorization\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"emojiReactions\":{\"@id\":\"fedibird:emojiReactions\",\"@type\":\"@id\"}}],\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/notes/native-inbox\",\"type\":\"Note\",\"attributedTo\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor\",\"content\":\"

Native Fedify to tootik v0.25.4 portable interoperability.

\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\",\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor\"],\"proof\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://gotosocial.org/ns\",{\"toot\":\"http://joinmastodon.org/ns#\",\"misskey\":\"https://misskey-hub.net/ns#\",\"fedibird\":\"http://fedibird.com/ns#\",\"sensitive\":\"as:sensitive\",\"Emoji\":\"toot:Emoji\",\"Hashtag\":\"as:Hashtag\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUrl\":\"as:quoteUrl\",\"_misskey_quote\":\"misskey:_misskey_quote\",\"quoteUri\":\"fedibird:quoteUri\",\"QuoteAuthorization\":\"https://w3id.org/fep/044f#QuoteAuthorization\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"emojiReactions\":{\"@id\":\"fedibird:emojiReactions\",\"@type\":\"@id\"}}],\"type\":\"DataIntegrityProof\",\"created\":\"2026-09-30T14:16:34.84575Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z3Qs33iEXVq9qLD29kiMa26yLGVuYaKvUKCMqPmuj2z3Y4FmjVVtm4Nb3vMGiaeSNvVahpPni6H7ttesNjpZ9SsDe\",\"verificationMethod\":\"did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN\"}},\"to\":[\"https://www.w3.org/ns/activitystreams#Public\",\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor\"]}", + "actorBody": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/fep/ef61\",\"https://w3id.org/security/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/multikey/v1\",\"https://gotosocial.org/ns\",\"https://w3id.org/fep/7aa9\",{\"alsoKnownAs\":{\"@id\":\"as:alsoKnownAs\",\"@type\":\"@id\"},\"featuredCollections\":{\"@id\":\"https://w3id.org/fep/7aa9#featuredCollections\",\"@type\":\"@id\"},\"manuallyApprovesFollowers\":\"as:manuallyApprovesFollowers\",\"movedTo\":{\"@id\":\"as:movedTo\",\"@type\":\"@id\"},\"toot\":\"http://joinmastodon.org/ns#\",\"Emoji\":\"toot:Emoji\",\"featured\":{\"@id\":\"toot:featured\",\"@type\":\"@id\"},\"featuredTags\":{\"@id\":\"toot:featuredTags\",\"@type\":\"@id\"},\"discoverable\":\"toot:discoverable\",\"suspended\":\"toot:suspended\",\"memorial\":\"toot:memorial\",\"indexable\":\"toot:indexable\",\"schema\":\"http://schema.org#\",\"PropertyValue\":\"schema:PropertyValue\",\"value\":\"schema:value\",\"misskey\":\"https://misskey-hub.net/ns#\",\"_misskey_followedMessage\":\"misskey:_misskey_followedMessage\",\"isCat\":\"misskey:isCat\"}],\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor\",\"type\":\"Person\",\"inbox\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor/inbox\",\"gateways\":[\"https://fedify.example/\"],\"assertionMethod\":[{\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#ed25519-key\",\"type\":\"Multikey\",\"controller\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor\",\"publicKeyMultibase\":\"z6MkoHdcDxRg36BmHgY8riW5xW8NbZdbgKBMmXUoyDAN9LEX\"},{\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#main-key\",\"type\":\"Multikey\",\"controller\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor\",\"publicKeyMultibase\":\"zgghBUVkqmWS8e1j5pNkit2HZTY7551YeVnqt4nok9y5j6Qj4zHfHAiTCUWeiSfvfgC8cuknF4312kUZa79gAAwCyoXqA3PZppMxsGmdwRprmxYkGrZkfvmmLfzCvw6faQrsph6hiMvYtFEQUZTwd2n6CG9j7ZqiXA5NGN9WRu5MNqucWNpMTQZFSdPnow2GgMnGy7G5fDhg7BQtSPLCYdEWEipFWJuy6nKwmySnffKYnZQZQRzNysFg2xJ91ZceWVrAjFxHwjekyUe2CrkNM1vYq829SnCoXUfPBsA31ujzVuYBwjDZhCDXmJ87fbWFmDg6zmwyXLdGLRmGY3nbkU8Jwt4iyRNqCpjirKjEx54JQj2wahyxL6r2BBjMnuoisDXNi6vjztoE7WbmHDoMVoz9qGUv5s2b6VVvn7vNgHYjjvKjYLbrj2fhe6ccwycxphU5vphepKWTRCNa3DsC8HpCjBjq3YZ9da8P8JorDKWyZLRAUn6piCn1LMJpHDDbeun1YgdXw3sDhDk5bHfBUJ7y5Lgnob8HpVBcjDA7ttbBEtFJ1RYb7XFYJJcaersNhWAoiZtLaQucHdNoRWJF8ByRJPRp5wz9rk2tkzTQoA5PFdomjbgYhqdq77d9VMuUPHJ97117xGVffGjGFipt5ZEuNazcVfes8Z21XzHBR7D39GyYvGAs1aiFx4wmyLiCw21ATd6Uq2kN6EcHex\"}],\"proof\":{\"type\":\"DataIntegrityProof\",\"created\":\"2026-09-30T14:16:34.822909912Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z2qzHQQ9yWvvfJdZvcWRKU8gYBnKNNMzppy7J6pcr7tqWevY3PFr3RUAVrnK9yuCPh9oP27XWPXrmQjaPDEkJm6Yx\",\"verificationMethod\":\"did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN\",\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/fep/ef61\",\"https://w3id.org/security/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/multikey/v1\",\"https://gotosocial.org/ns\",\"https://w3id.org/fep/7aa9\",{\"alsoKnownAs\":{\"@id\":\"as:alsoKnownAs\",\"@type\":\"@id\"},\"featuredCollections\":{\"@id\":\"https://w3id.org/fep/7aa9#featuredCollections\",\"@type\":\"@id\"},\"manuallyApprovesFollowers\":\"as:manuallyApprovesFollowers\",\"movedTo\":{\"@id\":\"as:movedTo\",\"@type\":\"@id\"},\"toot\":\"http://joinmastodon.org/ns#\",\"Emoji\":\"toot:Emoji\",\"featured\":{\"@id\":\"toot:featured\",\"@type\":\"@id\"},\"featuredTags\":{\"@id\":\"toot:featuredTags\",\"@type\":\"@id\"},\"discoverable\":\"toot:discoverable\",\"suspended\":\"toot:suspended\",\"memorial\":\"toot:memorial\",\"indexable\":\"toot:indexable\",\"schema\":\"http://schema.org#\",\"PropertyValue\":\"schema:PropertyValue\",\"value\":\"schema:value\",\"misskey\":\"https://misskey-hub.net/ns#\",\"_misskey_followedMessage\":\"misskey:_misskey_followedMessage\",\"isCat\":\"misskey:isCat\"}]},\"publicKey\":{\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#main-key\",\"type\":\"CryptographicKey\",\"owner\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor\",\"publicKeyPem\":\"-----BEGIN PUBLIC KEY-----\\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5PRU4GP79WfFGwBvSJ4V\\ntAmtreYrzQuLY/whIprIZScL7t5lvvdyu8qX6odu0LsBozosQ1A/oyaCv00jyhjj\\nupQdtJXhzW+WG9AuZT4rH4Z0r9u1bpGJT67msalb4ffDxS1d8Ipb1Xe/Hfs6Uu+d\\niyINnR3S4qj1bOXLBfNt4lI1wfycFwFtmtqOsxLKqY0VMZ2d9yeYnAUYAOh/C82t\\ng69nuXkeyyRJUNSBaY7ej6jnSPbJCpSsnYHzL/bE5h37vo0DUClV5ZPUGzFggDYK\\nYC6py31LOEXIn94AV4xVSVpKrQEPeBHrcx4ejJuUVpA9s9L5OoLMcUyZS5OSs8ek\\nM8Mj+LjCkakzsZWCusWstyebsszYNz1zq/yiXBiJJ0ypcbraYkltLJ5Ui8KSdH6e\\n2r5zC951YifyJZp8p+qK+Z52ZGjbMsWlfwHAynZEn8F5Bqzd4Xlo4s8/mgYtJBIk\\nKC4t4HgPXZSCH866wyOOJZz1m7jS5XwopX5s/ST7XzLVw9WpTqd2hqRGpAvCGR42\\nM8JOcPqHCAi/KjN4Nyhj9e3TzkoETYYqzQvxCy0LeDi/dHr8EDbT7tF5rCAeglc9\\nWWSBqpOnromClOWxX9HgklXvUmid4CkstoQzFb5H+uovtbLrPzMY9kokEXnG69UD\\nVkq6SwoNVm0551D8M2smtf0CAwEAAQ==\\n-----END PUBLIC KEY-----\\n\"},\"name\":\"Native Fedify portable sender\",\"outbox\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor/outbox\",\"preferredUsername\":\"fedifyreverse\"}", + "recipientBody": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/v1\"],\"id\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor\",\"type\":\"Application\",\"inbox\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/inbox\",\"outbox\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/outbox\",\"preferredUsername\":\"actor\",\"followers\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/followers\",\"publicKey\":{\"id\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor#main-key\",\"owner\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor\",\"publicKeyPem\":\"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvOrxaDyQG0jyLQ6OlLYi\\n5GabA3ieKKQi5Z3fS/yVDxV9WEyu79FzCC+uTZQXXXqzljI4ziTA4GmaITRHwGcU\\nji5bYK2y/fvfAQLhwhJotbZF4u4ZeWtyXN8Ds7IQ+Dr67ci7K/htsMNSysAMF/+u\\n5witcW5hdJrWSAIZEg/17UVQO+0EbuPXL5o6fRHm/t1GLchvFCo1pcyV3G+y3q2E\\nOx8FQTIkVPDwPNBzfX21YbBOIDo6AlbqSjB9tWKZePkUymX/JX4FARK3aVJvstUt\\neOX7hPxp8TvjGjA7nzLDf0E6kntFYzjaMG0qumjXftAQZUFZHL7eGCGOaIAgm68Z\\nAQIDAQAB\\n-----END PUBLIC KEY-----\\n\"},\"icon\":[{\"type\":\"Image\",\"mediaType\":\"image/gif\",\"url\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/icon.gif\"}],\"manuallyApprovesFollowers\":false,\"assertionMethod\":[{\"id\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor#ed25519-key\",\"type\":\"Multikey\",\"controller\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor\",\"publicKeyMultibase\":\"z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg\"},{\"id\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor#ml-dsa-44-key\",\"type\":\"Multikey\",\"controller\":\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor\",\"publicKeyMultibase\":\"ukCTy_ExYm-3IjZfDghrCf0O1P76JI3iS6sOVeu0WISMvS0w-0cLogJ9RK_cZivJFOHadKtTHT2IUGufuhLpPnxhymkQnmagnryXEexIvK-Vpl4Q4CV6jldBib_yXSYIZJnIofLK-BfB8itzLns95VMAFI3j_aqpoj4-02sSvcIfW7dQzmk__73LVux8HchjzvumnVhhJtNwnM2IeS60Yo6XQqqDrFfaOJ6-7dEIfabzwGwiJTYjtpn6pwjlg7uvP4b1rEyBosb9jgpuH2tBBxjbTceARNdnndrj6n5LnAPh0V5Zs2cs2Hc097lB_exY_ICOEzZ9Go654IKy9AGcKwDxaLl_BMvIo7YYDSlK8h86q2K6pBVOa1MPx2ixFCrA9HdlNPeqSs5giI_yWmkxR2_Tsm_0WbQ6ZOR7j7Ra4srqJVPGTAIvBpW2hlsOriiL73xjuOMptoQq3-23epnF-hIKVTa5vjSer_7V_UR-qoXHqWfMgAaGXIviMM8CGc4-_12ktGZPA-Okvqf5f3K6_0tIjOCh3zZN1CHblH-rstgXMk5tH7lK22wV2IfUz_i7o98Wd4hm10yUrFu_-cPrL7unhRBpiDVeKtIJ2F4t6xuXypRjV-bN282U1Zve5daiMvT0xb07T6Yfn34l01_HkklxywcgOKVZ8bpXJEaEg9lfozqTTvp2DuvkMlYqIvzoiLa5YbUKQb0g8Bio049_i79R3KDfl6K8aIqLPNtzS3q06BdpP4jflfpm6JXzInV_SX-WnM4xQ2eJJj7N7hsnDV9Tt1oWs5yzQyoi7v0pJSbJpPsnzdlNYyqJPrH8jHXuaq74T0kxX7wGLDNFMAVnOWiW8aIiqRthKOrQ7fxZGBWiREmjOWDtwjmWmay3JFkG6D0nby78zPMnTROPU9I6ZeGIjdZRsi5Mc1eXqpUiqnncuXtaOa1nzUAU5MmMEvj441R8lPk1ax2F0XYbxHWCmUSg3y4K8JQwbn2DBryvBV8KT9EcDibqdSZ9hz158uIXJtJuK70RiQw1JC3iI6tB5A_rnprpt8ooyPXUsLNYyS-dXN_oyrv8eWAWrVh4v3XAwhwajkq9jknzY0V-TNpX37KWWVfPg_z7t9qGwIx_RHND2FjLjrrnm0t-q7dAdWjeVBHXzpaU3eLIzCJRORbPFCsjkbSiiBKnCurBOxXUe4tp-vxzIDkICfKn93vJrs09WpELN93B1CaauiwWEstcjrvcB_2cz_7Z3KmRoOhErJ08G4lxApru4Xuwp4GvPys1uxO7ntBONLzkHsWXd6jwwC0jQwRc8J2lrlljYTeRIhYKiRIjwo47VigHnr3Od4drnMXwr2PJw6QqKhmWvmRvZBWDoncbtEKd7oOEoPE7gA5z-P9Q1ZxkcjVNBd3zniwLUORVCrm9dgChHRy9wpQzRoQX-fPRjVUSm8sS3KLFH7JU74UoUaJfn7eOzUfydz_Ad6peDqpSFWEaWLFUMnr_fsSaNaZRNWaLfvZmskWYq5YGBrPYPdh6rx7P1XctYzBG2chqDKdDblmsWSKKZBJlUxAAas1C-AYC3j_PsZo58MBRhNgxS-UaKDkh73JSYNLGSt7T9WdUSKul5l8mXJSjzxrnIFHmvBozVMcxfHMMe8Ii9h5MogAN5hyTOyN2Ug0QDG47_w9ylz3ljNzzavRGWT49KCk1x3tqlxaf8_Ghx4sKY3B6s1c77YCX_Rne_MO96JA4xDLN11hqai39cVfNfyJoz\"}],\"implements\":[{\"href\":\"https://datatracker.ietf.org/doc/html/rfc9421\",\"name\":\"RFC-9421: HTTP Message Signatures\"},{\"href\":\"https://datatracker.ietf.org/doc/html/rfc9421#name-eddsa-using-curve-edwards25\",\"name\":\"RFC-9421 signatures using the Ed25519 algorithm\"},{\"href\":\"https://c2sp.org/httpsig-pq@v1.0.0#ml-dsa-44\",\"name\":\"RFC-9421 signatures using the ml-dsa-44 algorithm\"}],\"gateways\":[\"https://tootik.example\"],\"proof\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/v1\"],\"type\":\"DataIntegrityProof\",\"cryptosuite\":\"eddsa-jcs-2022\",\"verificationMethod\":\"did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg#z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z4dTmsRsKvgqVBBHJnrkxfZUA44bzZxotkkjNwQtx62h77vpGbwA7X3KNNZwaYcT8zTiwCmXCDurPwEdZax9p8oQQ\",\"created\":\"2026-09-30T13:23:34Z\"}}", + "tamperedBody": "{\"@context\":[\"https://w3id.org/identity/v1\",\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://gotosocial.org/ns\",{\"toot\":\"http://joinmastodon.org/ns#\",\"misskey\":\"https://misskey-hub.net/ns#\",\"fedibird\":\"http://fedibird.com/ns#\",\"sensitive\":\"as:sensitive\",\"votersCount\":{\"@id\":\"toot:votersCount\",\"@type\":\"http://www.w3.org/2001/XMLSchema#nonNegativeInteger\"},\"Emoji\":\"toot:Emoji\",\"Hashtag\":\"as:Hashtag\",\"ChatMessage\":\"http://litepub.social/ns#ChatMessage\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUrl\":\"as:quoteUrl\",\"_misskey_quote\":\"misskey:_misskey_quote\",\"quoteUri\":\"fedibird:quoteUri\",\"QuoteAuthorization\":\"https://w3id.org/fep/044f#QuoteAuthorization\",\"QuoteRequest\":\"https://w3id.org/fep/044f#QuoteRequest\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"emojiReactions\":{\"@id\":\"fedibird:emojiReactions\",\"@type\":\"@id\"}}],\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/creates/native-inbox\",\"type\":\"Create\",\"proof\":{\"type\":\"DataIntegrityProof\",\"created\":\"2026-09-30T14:16:34.859806885Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z4fZQxG72dz6Qp2z1xj9NS96bPRCitAnM1FBVWYqHq65pYdQBwbk5ZJ3S7suxuZYHFPjCuL7vPKHFT8v2w4LHbyUK\",\"verificationMethod\":\"did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN\",\"@context\":[\"https://w3id.org/identity/v1\",\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://gotosocial.org/ns\",{\"toot\":\"http://joinmastodon.org/ns#\",\"misskey\":\"https://misskey-hub.net/ns#\",\"fedibird\":\"http://fedibird.com/ns#\",\"sensitive\":\"as:sensitive\",\"votersCount\":{\"@id\":\"toot:votersCount\",\"@type\":\"http://www.w3.org/2001/XMLSchema#nonNegativeInteger\"},\"Emoji\":\"toot:Emoji\",\"Hashtag\":\"as:Hashtag\",\"ChatMessage\":\"http://litepub.social/ns#ChatMessage\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUrl\":\"as:quoteUrl\",\"_misskey_quote\":\"misskey:_misskey_quote\",\"quoteUri\":\"fedibird:quoteUri\",\"QuoteAuthorization\":\"https://w3id.org/fep/044f#QuoteAuthorization\",\"QuoteRequest\":\"https://w3id.org/fep/044f#QuoteRequest\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"emojiReactions\":{\"@id\":\"fedibird:emojiReactions\",\"@type\":\"@id\"}}]},\"actor\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor\",\"object\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://gotosocial.org/ns\",{\"toot\":\"http://joinmastodon.org/ns#\",\"misskey\":\"https://misskey-hub.net/ns#\",\"fedibird\":\"http://fedibird.com/ns#\",\"sensitive\":\"as:sensitive\",\"Emoji\":\"toot:Emoji\",\"Hashtag\":\"as:Hashtag\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUrl\":\"as:quoteUrl\",\"_misskey_quote\":\"misskey:_misskey_quote\",\"quoteUri\":\"fedibird:quoteUri\",\"QuoteAuthorization\":\"https://w3id.org/fep/044f#QuoteAuthorization\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"emojiReactions\":{\"@id\":\"fedibird:emojiReactions\",\"@type\":\"@id\"}}],\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/notes/native-inbox\",\"type\":\"Note\",\"attributedTo\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor\",\"content\":\"

Tampered after signing.

\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\",\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor\"],\"proof\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://gotosocial.org/ns\",{\"toot\":\"http://joinmastodon.org/ns#\",\"misskey\":\"https://misskey-hub.net/ns#\",\"fedibird\":\"http://fedibird.com/ns#\",\"sensitive\":\"as:sensitive\",\"Emoji\":\"toot:Emoji\",\"Hashtag\":\"as:Hashtag\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUrl\":\"as:quoteUrl\",\"_misskey_quote\":\"misskey:_misskey_quote\",\"quoteUri\":\"fedibird:quoteUri\",\"QuoteAuthorization\":\"https://w3id.org/fep/044f#QuoteAuthorization\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"emojiReactions\":{\"@id\":\"fedibird:emojiReactions\",\"@type\":\"@id\"}}],\"type\":\"DataIntegrityProof\",\"created\":\"2026-09-30T14:16:34.84575Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z3Qs33iEXVq9qLD29kiMa26yLGVuYaKvUKCMqPmuj2z3Y4FmjVVtm4Nb3vMGiaeSNvVahpPni6H7ttesNjpZ9SsDe\",\"verificationMethod\":\"did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN\"}},\"to\":[\"https://www.w3.org/ns/activitystreams#Public\",\"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor\"]}" +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/recipient.body b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/recipient.body new file mode 100644 index 000000000..e58f143b0 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/recipient.body @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/v1"],"id":"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor","type":"Application","inbox":"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/inbox","outbox":"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/outbox","preferredUsername":"actor","followers":"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/followers","publicKey":{"id":"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor#main-key","owner":"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvOrxaDyQG0jyLQ6OlLYi\n5GabA3ieKKQi5Z3fS/yVDxV9WEyu79FzCC+uTZQXXXqzljI4ziTA4GmaITRHwGcU\nji5bYK2y/fvfAQLhwhJotbZF4u4ZeWtyXN8Ds7IQ+Dr67ci7K/htsMNSysAMF/+u\n5witcW5hdJrWSAIZEg/17UVQO+0EbuPXL5o6fRHm/t1GLchvFCo1pcyV3G+y3q2E\nOx8FQTIkVPDwPNBzfX21YbBOIDo6AlbqSjB9tWKZePkUymX/JX4FARK3aVJvstUt\neOX7hPxp8TvjGjA7nzLDf0E6kntFYzjaMG0qumjXftAQZUFZHL7eGCGOaIAgm68Z\nAQIDAQAB\n-----END PUBLIC KEY-----\n"},"icon":[{"type":"Image","mediaType":"image/gif","url":"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/icon.gif"}],"manuallyApprovesFollowers":false,"assertionMethod":[{"id":"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor#ed25519-key","type":"Multikey","controller":"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor","publicKeyMultibase":"z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg"},{"id":"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor#ml-dsa-44-key","type":"Multikey","controller":"https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor","publicKeyMultibase":"ukCTy_ExYm-3IjZfDghrCf0O1P76JI3iS6sOVeu0WISMvS0w-0cLogJ9RK_cZivJFOHadKtTHT2IUGufuhLpPnxhymkQnmagnryXEexIvK-Vpl4Q4CV6jldBib_yXSYIZJnIofLK-BfB8itzLns95VMAFI3j_aqpoj4-02sSvcIfW7dQzmk__73LVux8HchjzvumnVhhJtNwnM2IeS60Yo6XQqqDrFfaOJ6-7dEIfabzwGwiJTYjtpn6pwjlg7uvP4b1rEyBosb9jgpuH2tBBxjbTceARNdnndrj6n5LnAPh0V5Zs2cs2Hc097lB_exY_ICOEzZ9Go654IKy9AGcKwDxaLl_BMvIo7YYDSlK8h86q2K6pBVOa1MPx2ixFCrA9HdlNPeqSs5giI_yWmkxR2_Tsm_0WbQ6ZOR7j7Ra4srqJVPGTAIvBpW2hlsOriiL73xjuOMptoQq3-23epnF-hIKVTa5vjSer_7V_UR-qoXHqWfMgAaGXIviMM8CGc4-_12ktGZPA-Okvqf5f3K6_0tIjOCh3zZN1CHblH-rstgXMk5tH7lK22wV2IfUz_i7o98Wd4hm10yUrFu_-cPrL7unhRBpiDVeKtIJ2F4t6xuXypRjV-bN282U1Zve5daiMvT0xb07T6Yfn34l01_HkklxywcgOKVZ8bpXJEaEg9lfozqTTvp2DuvkMlYqIvzoiLa5YbUKQb0g8Bio049_i79R3KDfl6K8aIqLPNtzS3q06BdpP4jflfpm6JXzInV_SX-WnM4xQ2eJJj7N7hsnDV9Tt1oWs5yzQyoi7v0pJSbJpPsnzdlNYyqJPrH8jHXuaq74T0kxX7wGLDNFMAVnOWiW8aIiqRthKOrQ7fxZGBWiREmjOWDtwjmWmay3JFkG6D0nby78zPMnTROPU9I6ZeGIjdZRsi5Mc1eXqpUiqnncuXtaOa1nzUAU5MmMEvj441R8lPk1ax2F0XYbxHWCmUSg3y4K8JQwbn2DBryvBV8KT9EcDibqdSZ9hz158uIXJtJuK70RiQw1JC3iI6tB5A_rnprpt8ooyPXUsLNYyS-dXN_oyrv8eWAWrVh4v3XAwhwajkq9jknzY0V-TNpX37KWWVfPg_z7t9qGwIx_RHND2FjLjrrnm0t-q7dAdWjeVBHXzpaU3eLIzCJRORbPFCsjkbSiiBKnCurBOxXUe4tp-vxzIDkICfKn93vJrs09WpELN93B1CaauiwWEstcjrvcB_2cz_7Z3KmRoOhErJ08G4lxApru4Xuwp4GvPys1uxO7ntBONLzkHsWXd6jwwC0jQwRc8J2lrlljYTeRIhYKiRIjwo47VigHnr3Od4drnMXwr2PJw6QqKhmWvmRvZBWDoncbtEKd7oOEoPE7gA5z-P9Q1ZxkcjVNBd3zniwLUORVCrm9dgChHRy9wpQzRoQX-fPRjVUSm8sS3KLFH7JU74UoUaJfn7eOzUfydz_Ad6peDqpSFWEaWLFUMnr_fsSaNaZRNWaLfvZmskWYq5YGBrPYPdh6rx7P1XctYzBG2chqDKdDblmsWSKKZBJlUxAAas1C-AYC3j_PsZo58MBRhNgxS-UaKDkh73JSYNLGSt7T9WdUSKul5l8mXJSjzxrnIFHmvBozVMcxfHMMe8Ii9h5MogAN5hyTOyN2Ug0QDG47_w9ylz3ljNzzavRGWT49KCk1x3tqlxaf8_Ghx4sKY3B6s1c77YCX_Rne_MO96JA4xDLN11hqai39cVfNfyJoz"}],"implements":[{"href":"https://datatracker.ietf.org/doc/html/rfc9421","name":"RFC-9421: HTTP Message Signatures"},{"href":"https://datatracker.ietf.org/doc/html/rfc9421#name-eddsa-using-curve-edwards25","name":"RFC-9421 signatures using the Ed25519 algorithm"},{"href":"https://c2sp.org/httpsig-pq@v1.0.0#ml-dsa-44","name":"RFC-9421 signatures using the ml-dsa-44 algorithm"}],"gateways":["https://tootik.example"],"proof":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/v1"],"type":"DataIntegrityProof","cryptosuite":"eddsa-jcs-2022","verificationMethod":"did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg#z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg","proofPurpose":"assertionMethod","proofValue":"z4dTmsRsKvgqVBBHJnrkxfZUA44bzZxotkkjNwQtx62h77vpGbwA7X3KNNZwaYcT8zTiwCmXCDurPwEdZax9p8oQQ","created":"2026-09-30T13:23:34Z"}} \ No newline at end of file diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/recipient.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/recipient.json new file mode 100644 index 000000000..1b8521646 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/recipient.json @@ -0,0 +1,70 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/data-integrity/v1", + "https://w3id.org/security/v1" + ], + "id": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor", + "type": "Application", + "inbox": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/inbox", + "outbox": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/outbox", + "preferredUsername": "actor", + "followers": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/followers", + "publicKey": { + "id": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor#main-key", + "owner": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvOrxaDyQG0jyLQ6OlLYi\n5GabA3ieKKQi5Z3fS/yVDxV9WEyu79FzCC+uTZQXXXqzljI4ziTA4GmaITRHwGcU\nji5bYK2y/fvfAQLhwhJotbZF4u4ZeWtyXN8Ds7IQ+Dr67ci7K/htsMNSysAMF/+u\n5witcW5hdJrWSAIZEg/17UVQO+0EbuPXL5o6fRHm/t1GLchvFCo1pcyV3G+y3q2E\nOx8FQTIkVPDwPNBzfX21YbBOIDo6AlbqSjB9tWKZePkUymX/JX4FARK3aVJvstUt\neOX7hPxp8TvjGjA7nzLDf0E6kntFYzjaMG0qumjXftAQZUFZHL7eGCGOaIAgm68Z\nAQIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "icon": [ + { + "type": "Image", + "mediaType": "image/gif", + "url": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/icon.gif" + } + ], + "manuallyApprovesFollowers": false, + "assertionMethod": [ + { + "id": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor#ed25519-key", + "type": "Multikey", + "controller": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor", + "publicKeyMultibase": "z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg" + }, + { + "id": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor#ml-dsa-44-key", + "type": "Multikey", + "controller": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor", + "publicKeyMultibase": "ukCTy_ExYm-3IjZfDghrCf0O1P76JI3iS6sOVeu0WISMvS0w-0cLogJ9RK_cZivJFOHadKtTHT2IUGufuhLpPnxhymkQnmagnryXEexIvK-Vpl4Q4CV6jldBib_yXSYIZJnIofLK-BfB8itzLns95VMAFI3j_aqpoj4-02sSvcIfW7dQzmk__73LVux8HchjzvumnVhhJtNwnM2IeS60Yo6XQqqDrFfaOJ6-7dEIfabzwGwiJTYjtpn6pwjlg7uvP4b1rEyBosb9jgpuH2tBBxjbTceARNdnndrj6n5LnAPh0V5Zs2cs2Hc097lB_exY_ICOEzZ9Go654IKy9AGcKwDxaLl_BMvIo7YYDSlK8h86q2K6pBVOa1MPx2ixFCrA9HdlNPeqSs5giI_yWmkxR2_Tsm_0WbQ6ZOR7j7Ra4srqJVPGTAIvBpW2hlsOriiL73xjuOMptoQq3-23epnF-hIKVTa5vjSer_7V_UR-qoXHqWfMgAaGXIviMM8CGc4-_12ktGZPA-Okvqf5f3K6_0tIjOCh3zZN1CHblH-rstgXMk5tH7lK22wV2IfUz_i7o98Wd4hm10yUrFu_-cPrL7unhRBpiDVeKtIJ2F4t6xuXypRjV-bN282U1Zve5daiMvT0xb07T6Yfn34l01_HkklxywcgOKVZ8bpXJEaEg9lfozqTTvp2DuvkMlYqIvzoiLa5YbUKQb0g8Bio049_i79R3KDfl6K8aIqLPNtzS3q06BdpP4jflfpm6JXzInV_SX-WnM4xQ2eJJj7N7hsnDV9Tt1oWs5yzQyoi7v0pJSbJpPsnzdlNYyqJPrH8jHXuaq74T0kxX7wGLDNFMAVnOWiW8aIiqRthKOrQ7fxZGBWiREmjOWDtwjmWmay3JFkG6D0nby78zPMnTROPU9I6ZeGIjdZRsi5Mc1eXqpUiqnncuXtaOa1nzUAU5MmMEvj441R8lPk1ax2F0XYbxHWCmUSg3y4K8JQwbn2DBryvBV8KT9EcDibqdSZ9hz158uIXJtJuK70RiQw1JC3iI6tB5A_rnprpt8ooyPXUsLNYyS-dXN_oyrv8eWAWrVh4v3XAwhwajkq9jknzY0V-TNpX37KWWVfPg_z7t9qGwIx_RHND2FjLjrrnm0t-q7dAdWjeVBHXzpaU3eLIzCJRORbPFCsjkbSiiBKnCurBOxXUe4tp-vxzIDkICfKn93vJrs09WpELN93B1CaauiwWEstcjrvcB_2cz_7Z3KmRoOhErJ08G4lxApru4Xuwp4GvPys1uxO7ntBONLzkHsWXd6jwwC0jQwRc8J2lrlljYTeRIhYKiRIjwo47VigHnr3Od4drnMXwr2PJw6QqKhmWvmRvZBWDoncbtEKd7oOEoPE7gA5z-P9Q1ZxkcjVNBd3zniwLUORVCrm9dgChHRy9wpQzRoQX-fPRjVUSm8sS3KLFH7JU74UoUaJfn7eOzUfydz_Ad6peDqpSFWEaWLFUMnr_fsSaNaZRNWaLfvZmskWYq5YGBrPYPdh6rx7P1XctYzBG2chqDKdDblmsWSKKZBJlUxAAas1C-AYC3j_PsZo58MBRhNgxS-UaKDkh73JSYNLGSt7T9WdUSKul5l8mXJSjzxrnIFHmvBozVMcxfHMMe8Ii9h5MogAN5hyTOyN2Ug0QDG47_w9ylz3ljNzzavRGWT49KCk1x3tqlxaf8_Ghx4sKY3B6s1c77YCX_Rne_MO96JA4xDLN11hqai39cVfNfyJoz" + } + ], + "implements": [ + { + "href": "https://datatracker.ietf.org/doc/html/rfc9421", + "name": "RFC-9421: HTTP Message Signatures" + }, + { + "href": "https://datatracker.ietf.org/doc/html/rfc9421#name-eddsa-using-curve-edwards25", + "name": "RFC-9421 signatures using the Ed25519 algorithm" + }, + { + "href": "https://c2sp.org/httpsig-pq@v1.0.0#ml-dsa-44", + "name": "RFC-9421 signatures using the ml-dsa-44 algorithm" + } + ], + "gateways": [ + "https://tootik.example" + ], + "proof": { + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/data-integrity/v1", + "https://w3id.org/security/v1" + ], + "type": "DataIntegrityProof", + "cryptosuite": "eddsa-jcs-2022", + "verificationMethod": "did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg#z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg", + "proofPurpose": "assertionMethod", + "proofValue": "z4dTmsRsKvgqVBBHJnrkxfZUA44bzZxotkkjNwQtx62h77vpGbwA7X3KNNZwaYcT8zTiwCmXCDurPwEdZax9p8oQQ", + "created": "2026-09-30T13:23:34Z" + } +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/request.body b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/request.body new file mode 100644 index 000000000..52a8318cd --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/request.body @@ -0,0 +1 @@ +{"@context":["https://w3id.org/identity/v1","https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://gotosocial.org/ns",{"toot":"http://joinmastodon.org/ns#","misskey":"https://misskey-hub.net/ns#","fedibird":"http://fedibird.com/ns#","sensitive":"as:sensitive","votersCount":{"@id":"toot:votersCount","@type":"http://www.w3.org/2001/XMLSchema#nonNegativeInteger"},"Emoji":"toot:Emoji","Hashtag":"as:Hashtag","ChatMessage":"http://litepub.social/ns#ChatMessage","quote":{"@id":"https://w3id.org/fep/044f#quote","@type":"@id"},"quoteUrl":"as:quoteUrl","_misskey_quote":"misskey:_misskey_quote","quoteUri":"fedibird:quoteUri","QuoteAuthorization":"https://w3id.org/fep/044f#QuoteAuthorization","QuoteRequest":"https://w3id.org/fep/044f#QuoteRequest","quoteAuthorization":{"@id":"https://w3id.org/fep/044f#quoteAuthorization","@type":"@id"},"emojiReactions":{"@id":"fedibird:emojiReactions","@type":"@id"}}],"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/creates/native-inbox","type":"Create","proof":{"type":"DataIntegrityProof","created":"2026-09-30T14:16:34.859806885Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z4fZQxG72dz6Qp2z1xj9NS96bPRCitAnM1FBVWYqHq65pYdQBwbk5ZJ3S7suxuZYHFPjCuL7vPKHFT8v2w4LHbyUK","verificationMethod":"did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN","@context":["https://w3id.org/identity/v1","https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://gotosocial.org/ns",{"toot":"http://joinmastodon.org/ns#","misskey":"https://misskey-hub.net/ns#","fedibird":"http://fedibird.com/ns#","sensitive":"as:sensitive","votersCount":{"@id":"toot:votersCount","@type":"http://www.w3.org/2001/XMLSchema#nonNegativeInteger"},"Emoji":"toot:Emoji","Hashtag":"as:Hashtag","ChatMessage":"http://litepub.social/ns#ChatMessage","quote":{"@id":"https://w3id.org/fep/044f#quote","@type":"@id"},"quoteUrl":"as:quoteUrl","_misskey_quote":"misskey:_misskey_quote","quoteUri":"fedibird:quoteUri","QuoteAuthorization":"https://w3id.org/fep/044f#QuoteAuthorization","QuoteRequest":"https://w3id.org/fep/044f#QuoteRequest","quoteAuthorization":{"@id":"https://w3id.org/fep/044f#quoteAuthorization","@type":"@id"},"emojiReactions":{"@id":"fedibird:emojiReactions","@type":"@id"}}]},"actor":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor","object":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://gotosocial.org/ns",{"toot":"http://joinmastodon.org/ns#","misskey":"https://misskey-hub.net/ns#","fedibird":"http://fedibird.com/ns#","sensitive":"as:sensitive","Emoji":"toot:Emoji","Hashtag":"as:Hashtag","quote":{"@id":"https://w3id.org/fep/044f#quote","@type":"@id"},"quoteUrl":"as:quoteUrl","_misskey_quote":"misskey:_misskey_quote","quoteUri":"fedibird:quoteUri","QuoteAuthorization":"https://w3id.org/fep/044f#QuoteAuthorization","quoteAuthorization":{"@id":"https://w3id.org/fep/044f#quoteAuthorization","@type":"@id"},"emojiReactions":{"@id":"fedibird:emojiReactions","@type":"@id"}}],"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/notes/native-inbox","type":"Note","attributedTo":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor","content":"

Native Fedify to tootik v0.25.4 portable interoperability.

","to":["https://www.w3.org/ns/activitystreams#Public","https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor"],"proof":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://gotosocial.org/ns",{"toot":"http://joinmastodon.org/ns#","misskey":"https://misskey-hub.net/ns#","fedibird":"http://fedibird.com/ns#","sensitive":"as:sensitive","Emoji":"toot:Emoji","Hashtag":"as:Hashtag","quote":{"@id":"https://w3id.org/fep/044f#quote","@type":"@id"},"quoteUrl":"as:quoteUrl","_misskey_quote":"misskey:_misskey_quote","quoteUri":"fedibird:quoteUri","QuoteAuthorization":"https://w3id.org/fep/044f#QuoteAuthorization","quoteAuthorization":{"@id":"https://w3id.org/fep/044f#quoteAuthorization","@type":"@id"},"emojiReactions":{"@id":"fedibird:emojiReactions","@type":"@id"}}],"type":"DataIntegrityProof","created":"2026-09-30T14:16:34.84575Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z3Qs33iEXVq9qLD29kiMa26yLGVuYaKvUKCMqPmuj2z3Y4FmjVVtm4Nb3vMGiaeSNvVahpPni6H7ttesNjpZ9SsDe","verificationMethod":"did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN"}},"to":["https://www.w3.org/ns/activitystreams#Public","https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor"]} \ No newline at end of file diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/request.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/request.json new file mode 100644 index 000000000..561ee4903 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/request.json @@ -0,0 +1,27 @@ +{ + "url": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor/inbox", + "method": "POST", + "headers": [ + [ + "content-type", + "application/activity+json" + ], + [ + "date", + "Wed, 30 Sep 2026 14:16:35 GMT" + ], + [ + "digest", + "SHA-256=WB7t6jsP47/AEPHyEcEz/RSb1MTRXkeJ7y/zuMLzJVc=" + ], + [ + "host", + "tootik.example" + ], + [ + "signature", + "keyId=\"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) content-type date digest host\",signature=\"y2ub43LG9Akaqko3y0bTKSWyQwAlbDdH6x2pLFHqyFfogCXm3zjCJGjISkYsDQn56B6PteHT1JWSgKsmS8/ohH+lYvnSqaZ6KYU3DC0DozJTYHRy18nr9GP9w4Sq0EUAx+jOgpMGlud7G3DRMcZ17aeVCaT8IQCTezBbfzbGjb7fh0U6mYhiI+wKYMAqxmHym9lJDiBP+1s2Gctp9vN2lInvZ0Ve9zW9ue4Yfx/7mnHaSk9Kv9rk3Crjh+pf2U2FZMs5MgnXgqmLgQ3xIuzSyXZ/knj3Eqv0pLVGD4oUehypatPC7VGhRRECCYygVfx9GUdCSxHLNRFP0BXAIcQ5rkJ7hI54moSDXL3VP0+7FPI8FhbZmDS+bW0P6prAWlxYJPdpF/Zy/eiwNBPIQiOz0WQkJ8G0++roZH/Ov9QQqSfb2wziNaE+zRBBKdwKRW8NO7mYfFvmHK+q2sPh/WCBZU7zPPSeGTSlREcUO6EIPNLVC5tYEyyGhONgPn/mjfIllxItb/XzNOyzRYbYw3zoDMS7D1CZE81YX/TmX+UcDkXGOxQyiMcBGFCKPWWcEdYQgaQz4MffhLXSR/UqDG520xGk0aaUZRyCalLK/kUhPKYxd4WB3wa61nQ6s6bn0/s2RKbK5U4crsgvDw6f8ebIm5ZO6PcQjz+d3sLx/D/FYgo=\"" + ] + ], + "capturedAt": "2026-09-30T14:16:35.040Z" +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/response.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/response.json new file mode 100644 index 000000000..e624efc2e --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/response.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "headers": [ + [ + "content-length", + "0" + ], + [ + "date", + "Wed, 30 Sep 2026 14:16:35 GMT" + ] + ], + "body": "" +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/state.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/state.json new file mode 100644 index 000000000..09c4b4335 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/state.json @@ -0,0 +1,13 @@ +{ + "did": "did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN", + "actorId": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor", + "proofId": "did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN", + "rsaId": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#main-key", + "edId": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor#ed25519-key", + "noteId": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/notes/native-inbox", + "createId": "https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/creates/native-inbox", + "gateway": "https://fedify.example", + "recipient": "https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor", + "startedAt": "2026-09-30T14:16:34.862Z", + "strategy": "Native default signObject contexts and Context.sendActivity normalizeExistingProofs:true; compatible HTTPS portable identifiers; transport-only remap with original Host" +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/tampered-response.json b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/tampered-response.json new file mode 100644 index 000000000..6b8def0c9 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/tampered-response.json @@ -0,0 +1,18 @@ +{ + "status": 401, + "headers": [ + [ + "content-length", + "174" + ], + [ + "content-type", + "application/json" + ], + [ + "date", + "Wed, 30 Sep 2026 14:16:35 GMT" + ] + ], + "body": "{\"error\":\"failed to verify proof using did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN: proof verification failed\"}\n" +} diff --git a/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/tampered.body b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/tampered.body new file mode 100644 index 000000000..db0f3642f --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/tampered.body @@ -0,0 +1 @@ +{"@context":["https://w3id.org/identity/v1","https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://gotosocial.org/ns",{"toot":"http://joinmastodon.org/ns#","misskey":"https://misskey-hub.net/ns#","fedibird":"http://fedibird.com/ns#","sensitive":"as:sensitive","votersCount":{"@id":"toot:votersCount","@type":"http://www.w3.org/2001/XMLSchema#nonNegativeInteger"},"Emoji":"toot:Emoji","Hashtag":"as:Hashtag","ChatMessage":"http://litepub.social/ns#ChatMessage","quote":{"@id":"https://w3id.org/fep/044f#quote","@type":"@id"},"quoteUrl":"as:quoteUrl","_misskey_quote":"misskey:_misskey_quote","quoteUri":"fedibird:quoteUri","QuoteAuthorization":"https://w3id.org/fep/044f#QuoteAuthorization","QuoteRequest":"https://w3id.org/fep/044f#QuoteRequest","quoteAuthorization":{"@id":"https://w3id.org/fep/044f#quoteAuthorization","@type":"@id"},"emojiReactions":{"@id":"fedibird:emojiReactions","@type":"@id"}}],"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/creates/native-inbox","type":"Create","proof":{"type":"DataIntegrityProof","created":"2026-09-30T14:16:34.859806885Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z4fZQxG72dz6Qp2z1xj9NS96bPRCitAnM1FBVWYqHq65pYdQBwbk5ZJ3S7suxuZYHFPjCuL7vPKHFT8v2w4LHbyUK","verificationMethod":"did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN","@context":["https://w3id.org/identity/v1","https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://gotosocial.org/ns",{"toot":"http://joinmastodon.org/ns#","misskey":"https://misskey-hub.net/ns#","fedibird":"http://fedibird.com/ns#","sensitive":"as:sensitive","votersCount":{"@id":"toot:votersCount","@type":"http://www.w3.org/2001/XMLSchema#nonNegativeInteger"},"Emoji":"toot:Emoji","Hashtag":"as:Hashtag","ChatMessage":"http://litepub.social/ns#ChatMessage","quote":{"@id":"https://w3id.org/fep/044f#quote","@type":"@id"},"quoteUrl":"as:quoteUrl","_misskey_quote":"misskey:_misskey_quote","quoteUri":"fedibird:quoteUri","QuoteAuthorization":"https://w3id.org/fep/044f#QuoteAuthorization","QuoteRequest":"https://w3id.org/fep/044f#QuoteRequest","quoteAuthorization":{"@id":"https://w3id.org/fep/044f#quoteAuthorization","@type":"@id"},"emojiReactions":{"@id":"fedibird:emojiReactions","@type":"@id"}}]},"actor":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor","object":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://gotosocial.org/ns",{"toot":"http://joinmastodon.org/ns#","misskey":"https://misskey-hub.net/ns#","fedibird":"http://fedibird.com/ns#","sensitive":"as:sensitive","Emoji":"toot:Emoji","Hashtag":"as:Hashtag","quote":{"@id":"https://w3id.org/fep/044f#quote","@type":"@id"},"quoteUrl":"as:quoteUrl","_misskey_quote":"misskey:_misskey_quote","quoteUri":"fedibird:quoteUri","QuoteAuthorization":"https://w3id.org/fep/044f#QuoteAuthorization","quoteAuthorization":{"@id":"https://w3id.org/fep/044f#quoteAuthorization","@type":"@id"},"emojiReactions":{"@id":"fedibird:emojiReactions","@type":"@id"}}],"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/notes/native-inbox","type":"Note","attributedTo":"https://fedify.example/.well-known/apgateway/did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN/actor","content":"

Tampered after signing.

","to":["https://www.w3.org/ns/activitystreams#Public","https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor"],"proof":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://gotosocial.org/ns",{"toot":"http://joinmastodon.org/ns#","misskey":"https://misskey-hub.net/ns#","fedibird":"http://fedibird.com/ns#","sensitive":"as:sensitive","Emoji":"toot:Emoji","Hashtag":"as:Hashtag","quote":{"@id":"https://w3id.org/fep/044f#quote","@type":"@id"},"quoteUrl":"as:quoteUrl","_misskey_quote":"misskey:_misskey_quote","quoteUri":"fedibird:quoteUri","QuoteAuthorization":"https://w3id.org/fep/044f#QuoteAuthorization","quoteAuthorization":{"@id":"https://w3id.org/fep/044f#quoteAuthorization","@type":"@id"},"emojiReactions":{"@id":"fedibird:emojiReactions","@type":"@id"}}],"type":"DataIntegrityProof","created":"2026-09-30T14:16:34.84575Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z3Qs33iEXVq9qLD29kiMa26yLGVuYaKvUKCMqPmuj2z3Y4FmjVVtm4Nb3vMGiaeSNvVahpPni6H7ttesNjpZ9SsDe","verificationMethod":"did:key:z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN#z6MkuVzJw5PGsWVBkEtE7k2vsNqCgWwnBm9iBFAVGmzfCjwN"}},"to":["https://www.w3.org/ns/activitystreams#Public","https://tootik.example/.well-known/apgateway/did:key:z6MkqoM6ybQGmFBWcwsDGbD927SQrnLGTHGJxTABHtWk7DVg/actor"]} \ No newline at end of file From 0d3160935c638ae3e046d58c50bdd7dfdfaf81e4 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 00:17:20 +0900 Subject: [PATCH 011/184] Serialize portable gateways as origins Mitra rejects gateway URLs with a trailing slash. Serialize fresh portable actor gateways as origins in both compact and expanded JSON-LD, while retaining the spelling cached in imported documents. Cover all five actor types and record native delivery from an unregistered Fedify actor to a different registered Mitra recipient. Verify exact JCS proofs, HTTP signatures, worker/post processing, and signature tampering rejection against public live captures. https://github.com/fedify-dev/fedify/issues/1097 Changelog: none Assisted-by: Codex:gpt-6.1-sol Assisted-by: Claude Code:claude-opus-5-5 --- FEDERATION.md | 24 ++- docs/manual/vocab.md | 4 + .../fedify/src/sig/mitra-send-interop.test.ts | 201 ++++++++++++++++++ .../fep-ef61/mitra-v5.10.0/send/README.md | 119 +++++++++++ .../fep-ef61/mitra-v5.10.0/send/actor.body | 1 + .../fep-ef61/mitra-v5.10.0/send/actor.json | 129 +++++++++++ .../send/baseline-gateway-response.json | 26 +++ .../mitra-v5.10.0/send/baseline-gateway.body | 1 + .../fep-ef61/mitra-v5.10.0/send/metadata.json | 46 ++++ .../send/processed-collections.json | 13 ++ .../mitra-v5.10.0/send/processed-note.json | 92 ++++++++ .../fep-ef61/mitra-v5.10.0/send/profiles.json | 16 ++ .../mitra-v5.10.0/send/raw-bodies.json | 6 + .../send/registration-response.json | 34 +++ .../fep-ef61/mitra-v5.10.0/send/request.body | 1 + .../fep-ef61/mitra-v5.10.0/send/request.json | 31 +++ .../fep-ef61/mitra-v5.10.0/send/response.json | 26 +++ .../mitra-v5.10.0/send/served-actor.body | 1 + .../mitra-v5.10.0/send/served-actor.json | 62 ++++++ .../fep-ef61/mitra-v5.10.0/send/state.json | 16 ++ .../mitra-v5.10.0/send/tampered-request.json | 31 +++ .../mitra-v5.10.0/send/tampered-response.json | 26 +++ .../src/__snapshots__/class.test.ts.deno.snap | 20 +- .../src/__snapshots__/class.test.ts.node.snap | 20 +- .../src/__snapshots__/class.test.ts.snap | 20 +- packages/vocab-tools/src/type.ts | 4 +- packages/vocab/src/vocab.test.ts | 45 +++- 27 files changed, 978 insertions(+), 37 deletions(-) create mode 100644 packages/fedify/src/sig/mitra-send-interop.test.ts create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/README.md create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/actor.body create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/actor.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/baseline-gateway-response.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/baseline-gateway.body create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/metadata.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/processed-collections.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/processed-note.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/profiles.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/raw-bodies.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/registration-response.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/request.body create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/request.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/response.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/served-actor.body create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/served-actor.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/state.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/tampered-request.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/tampered-response.json diff --git a/FEDERATION.md b/FEDERATION.md index 31f2b9df4..c16f1ac57 100644 --- a/FEDERATION.md +++ b/FEDERATION.md @@ -126,12 +126,32 @@ v0.25.4 does not recognize compatible actor IDs with an explicit port. Its inbox authenticated the activity through its proof and skipped HTTP Signature verification. The request carried a gateway RSA signature, but this result does not establish independent acceptance of that signature by tootik. -Bidirectional Mitra interoperability and Mastodon compatibility remain -unverified. + +Mitra v5.10.0 (commit `17340ef09d4a902f301acdcfde094f5778d72f35`) accepted +a Fedify-generated portable actor registration and processed its setup +activities. A separate portable Fedify sender, which had no registered Mitra +account, then delivered a `Create` to the registered actor's inbox. This used +native Fedify objects, default signing contexts, and `Context.sendActivity()` +with `normalizeExistingProofs: true`. Mitra returned HTTP 202 on the first RFC +9421 RSA request and its worker stored the sender's activity in the recipient's +inbox. Corrupting the HTTP Signature returned HTTP 401. This required +serializing `gateways` as origins without a trailing slash; Mitra rejected the +previous spelling with `invalid gateway URL`. + +Gateway registration used a separate scratch client for Mitra's FEP-ae97 +endpoint; Fedify does not provide that client. Its setup `Update` used a +compact context and Fedify's existing internal outgoing normalizer because +Mitra's embedded-object limit rejected the default actor context. This setup +workaround was separate from the native server-to-server delivery. The +[Fedify to Mitra fixture] records the results and limitations, including the +portless HTTPS gateway used for the sender because Mitra's WebFinger lookup +drops explicit gateway ports. Mitra to +Fedify verification remains separate work, as does Mastodon compatibility. [tootik fixture]: packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/README.md [tootik Follow fixture]: packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/README.md [Fedify to tootik fixture]: packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/README.md +[Fedify to Mitra fixture]: packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/README.md ActivityPub diff --git a/docs/manual/vocab.md b/docs/manual/vocab.md index 6dd64fa62..b346ffe6f 100644 --- a/docs/manual/vocab.md +++ b/docs/manual/vocab.md @@ -265,6 +265,10 @@ const actor = new Person({ ~~~~ Each gateway must be an HTTP(S) base URI with no path, query, or fragment. +Newly serialized gateway lists use origins without a trailing slash, while +the in-memory `URL` values retain their root path. A parsed actor's default +JSON output can retain the cached spelling of its gateways. Keep the received +JSON when verifying existing proofs. For portable actors with inbox and outbox properties, Fedify also reads an unmapped `gateways` term under the ActivityStreams context, as emitted by diff --git a/packages/fedify/src/sig/mitra-send-interop.test.ts b/packages/fedify/src/sig/mitra-send-interop.test.ts new file mode 100644 index 000000000..52388826c --- /dev/null +++ b/packages/fedify/src/sig/mitra-send-interop.test.ts @@ -0,0 +1,201 @@ +import { mockDocumentLoader, test } from "@fedify/fixture"; +import { Create } from "@fedify/vocab"; +import { + canonicalizePortableUri, + decodeMultibase, + fromCompatibleEf61Id, + importDidKey, +} from "@fedify/vocab-runtime"; +import { assert, assertEquals } from "@std/assert"; +import { encodeHex } from "byte-encodings/hex"; +import serialize from "json-canon"; +import actor from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/actor.json" with { + type: "json", +}; +import captured from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/request.json" with { + type: "json", +}; +import registration from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/registration-response.json" with { + type: "json", +}; +import servedActor from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/served-actor.json" with { + type: "json", +}; +import baselineResponse from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/baseline-gateway-response.json" with { + type: "json", +}; +import tamperedRequest from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/tampered-request.json" with { + type: "json", +}; +import metadata from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/metadata.json" with { + type: "json", +}; +import processed from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/processed-collections.json" with { + type: "json", +}; +import processedNote from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/processed-note.json" with { + type: "json", +}; +import profiles from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/profiles.json" with { + type: "json", +}; +import raw from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/raw-bodies.json" with { + type: "json", +}; +import response from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/response.json" with { + type: "json", +}; +import tamperedResponse from "../../test-vectors/fep-ef61/mitra-v5.10.0/send/tampered-response.json" with { + type: "json", +}; +import { verifyRequestDetailed } from "./http.ts"; +import { doesActorOwnKey } from "./owner.ts"; +import { verifyPortableObjectProof } from "./proof.ts"; + +const activity = JSON.parse(raw.requestBody); +const baseline = JSON.parse(raw.baselineGatewayBody); + +async function digest(value: string): Promise { + return new Uint8Array( + await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value)), + ); +} + +// Verifies the exact JSON maps without Fedify's outgoing-normalization fallback. +async function verifyRawJcs( + document: Record, +): Promise { + const { proof, ...unsecured } = document; + assert(proof != null && typeof proof === "object" && !Array.isArray(proof)); + const { proofValue, ...configuration } = proof as Record; + assertEquals(configuration.cryptosuite, "eddsa-jcs-2022"); + configuration["@context"] ??= document["@context"]; + assert(typeof configuration.verificationMethod === "string"); + assert(typeof proofValue === "string"); + const key = await importDidKey( + configuration.verificationMethod.split("#")[0], + ); + const combined = new Uint8Array(64); + combined.set(await digest(serialize(configuration)), 0); + combined.set(await digest(serialize(unsecured)), 32); + return await crypto.subtle.verify( + "Ed25519", + key, + new Uint8Array(decodeMultibase(proofValue)), + combined, + ); +} + +const options = { + contextLoader: mockDocumentLoader, + documentLoader(url: string) { + assertEquals(url.split("#")[0], actor.publicKey.id.split("#")[0]); + return Promise.resolve({ + document: structuredClone(actor), + documentUrl: actor.publicKey.id.split("#")[0], + contextUrl: null, + }); + }, + currentTime: Temporal.Instant.from(metadata.capturedAt), +}; + +function request(headers = captured.headers as [string, string][]): Request { + return new Request(captured.url, { + method: captured.method, + headers, + body: raw.requestBody, + }); +} + +test("Fedify to Mitra v5.10.0 captured actor and compound proofs verify raw JCS", async () => { + for (const [name, value] of Object.entries(raw)) { + assertEquals( + encodeHex(await digest(value)), + metadata.sha256[name as keyof typeof metadata.sha256], + ); + } + assertEquals(JSON.parse(raw.actorBody), actor); + assertEquals(JSON.parse(raw.servedActorBody), servedActor); + assert(metadata.senderDid !== metadata.recipientDid); + for (const document of [actor, activity, activity.object]) { + assertEquals( + document.proof.verificationMethod.split("#")[0], + metadata.senderDid, + ); + const owner = document.actor ?? document.attributedTo ?? document.id; + assert(owner.includes(metadata.senderDid)); + } + assert(captured.url.includes(metadata.recipientDid)); + assert(servedActor.id.includes(metadata.recipientDid)); + assert(await verifyRawJcs(actor)); + assert(await verifyRawJcs(activity)); + assert(await verifyRawJcs(activity.object)); + assert((await verifyPortableObjectProof(actor, options)).verified); + assert((await verifyPortableObjectProof(activity, options)).verified); + assert((await verifyPortableObjectProof(activity.object, options)).verified); +}); + +test("Fedify to Mitra v5.10.0 captured HTTP signature belongs to its portable actor", async () => { + // The live RFC 9421 request succeeded on the first attempt. + assert( + new Headers(captured.headers as [string, string][]).has("signature-input"), + ); + const verified = await verifyRequestDetailed(request(), options); + assert(verified.verified); + assertEquals(verified.key.id?.href, actor.publicKey.id); + assert( + await doesActorOwnKey( + await Create.fromJsonLd(activity, options), + verified.key, + options, + ), + ); +}); + +test("Fedify to Mitra v5.10.0 records native registration and worker processing", () => { + assertEquals(registration.status, 201); + assertEquals(response.status, 202); + const portableId = fromCompatibleEf61Id(activity.id); + assert(portableId != null); + const expectedId = canonicalizePortableUri(portableId.href); + const entries = processed.rows.filter((row) => + canonicalizePortableUri(row.object_id) === expectedId + ); + assert(entries.some((row) => row.collection_id.endsWith("/actor/inbox"))); + assert(entries.every((row) => row.type === "Create")); + assert(entries.every((row) => row.actor === actor.id)); + assert( + entries.every((row) => row.collection_id.includes(metadata.recipientDid)), + ); + const sender = profiles.rows.find((row) => + row.actor_id.includes(metadata.senderDid) + ); + const recipient = profiles.rows.find((row) => + row.actor_id.includes(metadata.recipientDid) + ); + assert(sender != null && recipient != null); + assertEquals(sender.has_portable_account, false); + assertEquals(recipient.has_portable_account, true); + assertEquals(processedNote.rows.length, 1); + assertEquals(processedNote.rows[0].has_processed_post, true); + assertEquals(processedNote.rows[0].object_data, activity.object); +}); + +test("Fedify to Mitra v5.10.0 rejects a tampered RFC 9421 HTTP signature", async () => { + assertEquals(tamperedResponse.status, 401); + assertEquals( + (await verifyRequestDetailed( + request(tamperedRequest.headers as [string, string][]), + options, + )).verified, + false, + ); +}); + +test("Fedify to Mitra v5.10.0 records signed trailing-slash gateway rejection", async () => { + assertEquals(baselineResponse.status, 400); + assertEquals(baselineResponse.body, "invalid gateway URL"); + assert(await verifyRawJcs(baseline)); + assert(baseline.gateways.some((gateway: string) => gateway.endsWith("/"))); + assert(actor.gateways.every((gateway) => !gateway.endsWith("/"))); +}); diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/README.md b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/README.md new file mode 100644 index 000000000..a5109c055 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/README.md @@ -0,0 +1,119 @@ +Fedify to mitra capture +======================= + +This fixture records live Fedify to Mitra v5.10.0 interoperability. The +unmodified Mitra image was pinned to +`codeberg.org/silverpill/mitra@sha256:4348ddea1d819f654cd3e6be4e955b3933d1d21807c6a9a8ef64eda4333f1d0a`. +Its version output was `mitra 5.10.0`; tag `v5.10.0` points to source commit +`17340ef09d4a902f301acdcfde094f5778d72f35`. + +Fedify's native `Person` registered successfully with Mitra's FEP-ae97 +gateway endpoint after gateway serialization changed from root-path URLs to +origins. Registration returned HTTP 201; the previous trailing-slash +representation returned HTTP 400 with `invalid gateway URL`. No actor +subclass or gateway-string rewrite was used in the successful capture. + +The registration prerequisite created recipient A using a scratch client, a +fresh invite code, and a fresh Ed25519 identity. Fedify does not supply a +public FEP-ae97 client. +The scratch client submitted the actor to `POST /.well-known/apgateway`, +incorporated the gateway keys returned by Mitra, and submitted a signed actor +`Update` and `Create` to the portable outbox. Registration returned HTTP 201; +both activities returned HTTP 202 and appeared in processed collections. + +These setup activities used the public `signObject()` context option with +compact remote contexts and the existing internal +`normalizeOutgoingActivityJsonLd()` helper. With default actor contexts, +registration succeeded but the embedded actor `Update` returned HTTP 400, +`too many embedded objects`. Mitra's limit counts JSON objects recursively, +including inline JSON-LD context maps, and its limit is 20. The +setup workaround is not evidence of a public Fedify client-to-server API. + +The subsequent server-to-server test used a distinct Fedify sender B, which +was not registered as a portable account on Mitra. Its native `Person`, `Note`, +and `Create` objects used default `signObject()` contexts and the documented +`normalizeExistingProofs: true` option to `Context.sendActivity()`. Its first +request carried an RFC 9421 RSA HTTP Signature and returned HTTP 202. A +subsequent PostgreSQL query confirmed worker processing by finding the +sender's `Create` in recipient A's inbox. A separate profile query confirmed +that A had a registered portable account and B did not. The embedded note also +had a processed post in Mitra's database. Replacing only the HTTP +signature bytes returned HTTP 401 with `signature verification error`. +This is stronger evidence than HTTP 202 alone, which does not establish +asynchronous processing. + +*request.body* and *request.json* preserve the native server-to-server body, +URL, headers, and capture time. *response.json* records the first response. +*actor.body* and *actor.json* record sender B's fetched native actor; the +Mitra-served actor files record recipient A. They retain the key material +needed for offline verification; *raw-bodies.json* and *metadata.json* record +provenance and hashes. *registration-response.json* records the gateway +registration response, *processed-collections.json* records the worker result, +*profiles.json* records the distinct account roles, and *processed-note.json* +records the note and its processed post, while *tampered-response.json* records +signature rejection. The baseline gateway files record the rejected spelling. +Private keys, database files, and registration requests containing invite codes +are excluded. + +Offline replay in *src/sig/mitra-send-interop.test.ts* verifies the captured +proofs and HTTP signature with the recorded time. Live processing is supported +by the recorded Mitra response and PostgreSQL rows; offline replay alone +does not reproduce an external server's processing. + + +Capture environment and procedure +--------------------------------- + +Mitra ran in Podman with PostgreSQL 16 on a dedicated bridge network. Its +HTTP listener was published at `127.0.0.1:18497`, gateway support was enabled, +and SSRF protection was disabled for this isolated local capture. Recipient +A's setup gateways were `http://127.0.0.1:18497` and +`http://localhost:18498`. Sender B used `https://fedify.example`, reached +through a TLS passthrough proxy on port 443 to the host receiver on port +18444. Mitra's CA store trusted the local CA; TLS verification remained +enabled. The local transport and security settings do not establish public +deployment behavior. + +Mitra fetched sender B's actual actor document and queried WebFinger for +`acct:fedifydistinct@fedify.example`. An earlier explicit-port gateway failed +because Mitra derives the WebFinger URL from the gateway hostname without +retaining the port. The successful capture used the portless HTTPS gateway +and the corresponding WebFinger response, rather than bypassing resolution. + +To repeat the capture: + +1. Start the pinned Mitra image with a fresh database, gateway support, and + the local listener described above. Keep its configuration, storage, and + signing keys outside the repository. +2. Generate an invite code with + `podman exec fedify-1097-mitra mitra generate-invite-code`. Create a native + Fedify recipient A `Person` with portable actor/inbox/outbox IDs, two + gateways, an Ed25519 DID identity, and an RSA gateway key. Sign the actor + and register it through Mitra's gateway endpoint with the `X-Invite-Code` + header. +3. Add the returned gateway verification methods to the actor, sign its + `Update`, and submit that activity to its compatible portable outbox. + Use compact contexts for this setup step because of the object limit. + Submit the setup `Create` and confirm processing in the outbox. +4. Create an independent Fedify sender B with new DID and RSA keys. Serve + its default-context signed `Person` at its HTTPS compatible actor URL, + together with a WebFinger self link on the same portless gateway. Sign + its new native `Note` and `Create` with default contexts. Call + `Context.sendActivity()` with B's RSA gateway key, A's Mitra inbox + as recipient, and `{ normalizeExistingProofs: true }`. Capture the exact + outgoing request and response without modifying the body or gateways. +5. Query Mitra's `activitypub_collection_item` and `activitypub_object` + tables for the unique portable `Create` ID. Record the collection IDs and + object type, requiring B's activity in A's inbox. Query `actor_profile` + to confirm A has a portable account and B does not. Repeat the POST with + corrupted HTTP signature bytes and record the HTTP 401 response. + +Fresh identities produce different keys, IDs, proofs, signatures, and hashes. +The captured test can be replayed from the repository root with: + +~~~~ bash +mise run test:deno packages/fedify/src/sig/mitra-send-interop.test.ts +~~~~ + +This fixture covers Fedify to Mitra only. Mitra to Fedify verification belongs +to a separate capture, and Mastodon interoperability is outside this result. diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/actor.body b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/actor.body new file mode 100644 index 000000000..8d1e21f76 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/actor.body @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/fep/ef61","https://w3id.org/security/v1","https://w3id.org/security/data-integrity/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/multikey/v1","https://gotosocial.org/ns","https://w3id.org/fep/7aa9",{"alsoKnownAs":{"@id":"as:alsoKnownAs","@type":"@id"},"featuredCollections":{"@id":"https://w3id.org/fep/7aa9#featuredCollections","@type":"@id"},"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","movedTo":{"@id":"as:movedTo","@type":"@id"},"toot":"http://joinmastodon.org/ns#","Emoji":"toot:Emoji","featured":{"@id":"toot:featured","@type":"@id"},"featuredTags":{"@id":"toot:featuredTags","@type":"@id"},"discoverable":"toot:discoverable","suspended":"toot:suspended","memorial":"toot:memorial","indexable":"toot:indexable","schema":"http://schema.org#","PropertyValue":"schema:PropertyValue","value":"schema:value","misskey":"https://misskey-hub.net/ns#","_misskey_followedMessage":"misskey:_misskey_followedMessage","isCat":"misskey:isCat"}],"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor","type":"Person","inbox":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor/inbox","gateways":["https://fedify.example"],"assertionMethod":[{"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#ed25519-key","type":"Multikey","controller":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor","publicKeyMultibase":"z6Mkf1YFSzwyC6ZJL28STR5rei2XNJHCVKU2mV1gP768cixM"},{"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#main-key","type":"Multikey","controller":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor","publicKeyMultibase":"zgghBUVkqmWS8e1ittJsA5xRdPNj4WxsfUGuo2kK6NrkUwKxyRNaEQHLxYUezPkdjEkRRjg98U6LJyngicRLa1Q6fTMMtJy8DujadGoHcbY1aUP9vskG7coev8Mw68VFnuvP7zwf1pH62HYt7CxMnx1CMfS719LfQubVU2VQra8YhWScQanNiRnQqe1qKeVrJLiMCEe7UtfhonS6KgtPQWgapVFZjk2a78n8arg4DdHdwhq9KwG9iBzAkKz5w3hxzLq4p8aVR9Mkcyq7265UoqUkRRz4sFcuKvGjB47MpSi8yEJuLFy1VZUkDRka5YV4N2AwUabVLYJF64itr1DpqaZRvkzMC1KEZY6KQPpS1vydLgqYFbJEV4bhzqu7GJpiGq6aL2NSNSAQxFTv9ergd5aLQdXQUGYk8NzPj5YSjchUmHhu1SVBSuYApHkcXbn4EUo9PYhRnCAY4wymKma4JzqYtQPPGCKps6zar2GM5DFNFkKFxPWdxY5Ugdk5jj9ccEr963hnnb9nPeRYsFYDhEFGzwLUGooWVHggoLVRDMHvqnCdSiQaQhdyE9DVxZMWgBynbZN71kzc6ur726TAmNo4X4NQiWcwKNnWbaBAPUocJ8Hy9YSD9xVg41644iE6Q8JaYz5d9E9NNZ8dv2vTL4aFdWELGP8fBnNvgjMz47tctMde4aKcqkdE9DRAJ82ShuUPWmEUBrRPXBwiXa"}],"proof":{"type":"DataIntegrityProof","created":"2026-09-30T14:54:41.245020996Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"zViP1tF9MaXjUAu9agaoL8RQuGKQyd6MLyyXi5P1RZPnC8kWR5TVFJWqNDFmvYpu5apF7cbq35msfCTNSbhNQsma","verificationMethod":"did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f#z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f","@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/fep/ef61","https://w3id.org/security/v1","https://w3id.org/security/data-integrity/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/multikey/v1","https://gotosocial.org/ns","https://w3id.org/fep/7aa9",{"alsoKnownAs":{"@id":"as:alsoKnownAs","@type":"@id"},"featuredCollections":{"@id":"https://w3id.org/fep/7aa9#featuredCollections","@type":"@id"},"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","movedTo":{"@id":"as:movedTo","@type":"@id"},"toot":"http://joinmastodon.org/ns#","Emoji":"toot:Emoji","featured":{"@id":"toot:featured","@type":"@id"},"featuredTags":{"@id":"toot:featuredTags","@type":"@id"},"discoverable":"toot:discoverable","suspended":"toot:suspended","memorial":"toot:memorial","indexable":"toot:indexable","schema":"http://schema.org#","PropertyValue":"schema:PropertyValue","value":"schema:value","misskey":"https://misskey-hub.net/ns#","_misskey_followedMessage":"misskey:_misskey_followedMessage","isCat":"misskey:isCat"}]},"publicKey":{"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#main-key","type":"CryptographicKey","owner":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvM94PB5yiw79af0NeKvL\nFICG2J3OjSvmQCI1+pRbXC07kmf9I4E6yTV+SO6yONpUYFrsmMw+SL13n6V7dyHR\nHx5FXD4Z09sUfhDiQgrrbmx5yu9FA5K88nvw0Fgi0npSdctTDuFVzfYron6jeZB9\ncEeXGoeGb+JTcHleozEPOOSKZ3gU4f/iZo2hg73igGswDtmQcIWKH3h7l0fxqoxk\na3iZt1gt+8TL1hwkAv7rnnPyWmZfPGNIG+CYD+bUwN5ee1ZonDJKZlMOgg0imNam\n3WEXtLpb0ZKla0MzIET452eUYgKNbBJkdvtbfI32x+Zf7OO0kkk1LxMeeRuUKEwv\n74gPJ6tKADz3cBGHkG77ZRrbazCncKoSeX4TdDWJC4gmvL2mPF8mtK2BuBQw26wB\nqaimlg+SJqmZEJgxbG3mGR6hu8d3ltpnjgxCeOUOuSB19Sird14OnNd9fL9SJW+R\ne4AIashoFt5l4SjGHF98Q+DbQu6wP2OICuFLslTfcoAqyXZqHe0SygUzg0/kWAhw\nGsa/25KBEYXnSMAn/+FrONDProw+qf9yX9qLS+gUn9yxhsm9bVAlT1wXIPrA9FRn\nR5SD8AWRnkAKB0mblohfoBCYqTSIDao0UvnwrdfaNAqOcrey5Gget5sZN3HU5kj8\nkciSCLPd/39lMbcFxLo25eECAwEAAQ==\n-----END PUBLIC KEY-----\n"},"name":"Distinct native Fedify portable sender","outbox":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor/outbox","preferredUsername":"fedifydistinct"} \ No newline at end of file diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/actor.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/actor.json new file mode 100644 index 000000000..3c2982535 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/actor.json @@ -0,0 +1,129 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/fep/ef61", + "https://w3id.org/security/v1", + "https://w3id.org/security/data-integrity/v1", + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/multikey/v1", + "https://gotosocial.org/ns", + "https://w3id.org/fep/7aa9", + { + "alsoKnownAs": { + "@id": "as:alsoKnownAs", + "@type": "@id" + }, + "featuredCollections": { + "@id": "https://w3id.org/fep/7aa9#featuredCollections", + "@type": "@id" + }, + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "movedTo": { + "@id": "as:movedTo", + "@type": "@id" + }, + "toot": "http://joinmastodon.org/ns#", + "Emoji": "toot:Emoji", + "featured": { + "@id": "toot:featured", + "@type": "@id" + }, + "featuredTags": { + "@id": "toot:featuredTags", + "@type": "@id" + }, + "discoverable": "toot:discoverable", + "suspended": "toot:suspended", + "memorial": "toot:memorial", + "indexable": "toot:indexable", + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value", + "misskey": "https://misskey-hub.net/ns#", + "_misskey_followedMessage": "misskey:_misskey_followedMessage", + "isCat": "misskey:isCat" + } + ], + "id": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor", + "type": "Person", + "inbox": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor/inbox", + "gateways": [ + "https://fedify.example" + ], + "assertionMethod": [ + { + "id": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#ed25519-key", + "type": "Multikey", + "controller": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor", + "publicKeyMultibase": "z6Mkf1YFSzwyC6ZJL28STR5rei2XNJHCVKU2mV1gP768cixM" + }, + { + "id": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#main-key", + "type": "Multikey", + "controller": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor", + "publicKeyMultibase": "zgghBUVkqmWS8e1ittJsA5xRdPNj4WxsfUGuo2kK6NrkUwKxyRNaEQHLxYUezPkdjEkRRjg98U6LJyngicRLa1Q6fTMMtJy8DujadGoHcbY1aUP9vskG7coev8Mw68VFnuvP7zwf1pH62HYt7CxMnx1CMfS719LfQubVU2VQra8YhWScQanNiRnQqe1qKeVrJLiMCEe7UtfhonS6KgtPQWgapVFZjk2a78n8arg4DdHdwhq9KwG9iBzAkKz5w3hxzLq4p8aVR9Mkcyq7265UoqUkRRz4sFcuKvGjB47MpSi8yEJuLFy1VZUkDRka5YV4N2AwUabVLYJF64itr1DpqaZRvkzMC1KEZY6KQPpS1vydLgqYFbJEV4bhzqu7GJpiGq6aL2NSNSAQxFTv9ergd5aLQdXQUGYk8NzPj5YSjchUmHhu1SVBSuYApHkcXbn4EUo9PYhRnCAY4wymKma4JzqYtQPPGCKps6zar2GM5DFNFkKFxPWdxY5Ugdk5jj9ccEr963hnnb9nPeRYsFYDhEFGzwLUGooWVHggoLVRDMHvqnCdSiQaQhdyE9DVxZMWgBynbZN71kzc6ur726TAmNo4X4NQiWcwKNnWbaBAPUocJ8Hy9YSD9xVg41644iE6Q8JaYz5d9E9NNZ8dv2vTL4aFdWELGP8fBnNvgjMz47tctMde4aKcqkdE9DRAJ82ShuUPWmEUBrRPXBwiXa" + } + ], + "proof": { + "type": "DataIntegrityProof", + "created": "2026-09-30T14:54:41.245020996Z", + "cryptosuite": "eddsa-jcs-2022", + "proofPurpose": "assertionMethod", + "proofValue": "zViP1tF9MaXjUAu9agaoL8RQuGKQyd6MLyyXi5P1RZPnC8kWR5TVFJWqNDFmvYpu5apF7cbq35msfCTNSbhNQsma", + "verificationMethod": "did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f#z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f", + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/fep/ef61", + "https://w3id.org/security/v1", + "https://w3id.org/security/data-integrity/v1", + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/multikey/v1", + "https://gotosocial.org/ns", + "https://w3id.org/fep/7aa9", + { + "alsoKnownAs": { + "@id": "as:alsoKnownAs", + "@type": "@id" + }, + "featuredCollections": { + "@id": "https://w3id.org/fep/7aa9#featuredCollections", + "@type": "@id" + }, + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "movedTo": { + "@id": "as:movedTo", + "@type": "@id" + }, + "toot": "http://joinmastodon.org/ns#", + "Emoji": "toot:Emoji", + "featured": { + "@id": "toot:featured", + "@type": "@id" + }, + "featuredTags": { + "@id": "toot:featuredTags", + "@type": "@id" + }, + "discoverable": "toot:discoverable", + "suspended": "toot:suspended", + "memorial": "toot:memorial", + "indexable": "toot:indexable", + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value", + "misskey": "https://misskey-hub.net/ns#", + "_misskey_followedMessage": "misskey:_misskey_followedMessage", + "isCat": "misskey:isCat" + } + ] + }, + "publicKey": { + "id": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#main-key", + "type": "CryptographicKey", + "owner": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvM94PB5yiw79af0NeKvL\nFICG2J3OjSvmQCI1+pRbXC07kmf9I4E6yTV+SO6yONpUYFrsmMw+SL13n6V7dyHR\nHx5FXD4Z09sUfhDiQgrrbmx5yu9FA5K88nvw0Fgi0npSdctTDuFVzfYron6jeZB9\ncEeXGoeGb+JTcHleozEPOOSKZ3gU4f/iZo2hg73igGswDtmQcIWKH3h7l0fxqoxk\na3iZt1gt+8TL1hwkAv7rnnPyWmZfPGNIG+CYD+bUwN5ee1ZonDJKZlMOgg0imNam\n3WEXtLpb0ZKla0MzIET452eUYgKNbBJkdvtbfI32x+Zf7OO0kkk1LxMeeRuUKEwv\n74gPJ6tKADz3cBGHkG77ZRrbazCncKoSeX4TdDWJC4gmvL2mPF8mtK2BuBQw26wB\nqaimlg+SJqmZEJgxbG3mGR6hu8d3ltpnjgxCeOUOuSB19Sird14OnNd9fL9SJW+R\ne4AIashoFt5l4SjGHF98Q+DbQu6wP2OICuFLslTfcoAqyXZqHe0SygUzg0/kWAhw\nGsa/25KBEYXnSMAn/+FrONDProw+qf9yX9qLS+gUn9yxhsm9bVAlT1wXIPrA9FRn\nR5SD8AWRnkAKB0mblohfoBCYqTSIDao0UvnwrdfaNAqOcrey5Gget5sZN3HU5kj8\nkciSCLPd/39lMbcFxLo25eECAwEAAQ==\n-----END PUBLIC KEY-----\n" + }, + "name": "Distinct native Fedify portable sender", + "outbox": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor/outbox", + "preferredUsername": "fedifydistinct" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/baseline-gateway-response.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/baseline-gateway-response.json new file mode 100644 index 000000000..c78c8f42b --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/baseline-gateway-response.json @@ -0,0 +1,26 @@ +{ + "status": 400, + "headers": [ + [ + "content-length", + "19" + ], + [ + "content-security-policy", + "base-uri 'self'; connect-src 'self' *; default-src 'none'; frame-ancestors 'none'; img-src 'self' data:; manifest-src 'self'; media-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self'" + ], + [ + "date", + "Wed, 30 Sep 2026 13:36:30 GMT" + ], + [ + "vary", + "Origin, Access-Control-Request-Method, Access-Control-Request-Headers" + ], + [ + "x-content-type-options", + "nosniff" + ] + ], + "body": "invalid gateway URL" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/baseline-gateway.body b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/baseline-gateway.body new file mode 100644 index 000000000..b9a50fd14 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/baseline-gateway.body @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/multikey/v1","https://w3id.org/fep/ef61"],"id":"ap+ef61://did:key:z6Mkwayt7WaDpNcgP6eRQsCTaTcP9TCZ4ALtFdfsXAiYJq31/actor","type":"Person","inbox":"ap+ef61://did:key:z6Mkwayt7WaDpNcgP6eRQsCTaTcP9TCZ4ALtFdfsXAiYJq31/actor/inbox","gateways":["http://127.0.0.1:18497/","http://127.0.0.1:18498/"],"proof":{"type":"DataIntegrityProof","created":"2026-09-30T13:36:30.213906006Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z2L7QsFwP7V2YRnXTxV896cCLZ7xHcoYp96yZct3WibVuZQ8rZBNt9sH8k2mgQrkCE5WXAwesxeeUz73xky2qUKhT","verificationMethod":"did:key:z6Mkwayt7WaDpNcgP6eRQsCTaTcP9TCZ4ALtFdfsXAiYJq31#z6Mkwayt7WaDpNcgP6eRQsCTaTcP9TCZ4ALtFdfsXAiYJq31","@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/multikey/v1","https://w3id.org/fep/ef61"]},"name":"Fedify live portable client","outbox":"ap+ef61://did:key:z6Mkwayt7WaDpNcgP6eRQsCTaTcP9TCZ4ALtFdfsXAiYJq31/actor/outbox","preferredUsername":"fedifyclient"} \ No newline at end of file diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/metadata.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/metadata.json new file mode 100644 index 000000000..bd39302a1 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/metadata.json @@ -0,0 +1,46 @@ +{ + "implementation": "Mitra", + "version": "5.10.0", + "direction": "Fedify to Mitra", + "capturedAt": "2026-09-30T14:54:41.299Z", + "source": { + "repository": "https://codeberg.org/silverpill/mitra", + "tag": "v5.10.0", + "commit": "17340ef09d4a902f301acdcfde094f5778d72f35", + "image": "codeberg.org/silverpill/mitra@sha256:4348ddea1d819f654cd3e6be4e955b3933d1d21807c6a9a8ef64eda4333f1d0a", + "binaryVersion": "mitra 5.10.0" + }, + "fedify": { + "baseCommit": "13640da6", + "patch": "gateway scalar encoder URL.origin, regenerated vocab.ts", + "actorImplementation": "native Person, no subclass", + "setup": "C2S registration/Update/Create use public signObject context option with compact contexts and existing private normalizeOutgoingActivityJsonLd for protocol setup; not application-level public C2S API evidence", + "nativeServerToServer": "default signObject contexts for Note/Create; Context.sendActivity normalizeExistingProofs:true", + "defaultSetupLimit": "Native default-context Person registration returned 201; embedded Update returned 400 (too many embedded objects) under Mitra's limit of 20 recursively counted JSON objects. Additional diagnostic captures are outside this fixture." + }, + "sha256": { + "requestBody": "3461032786b16c1ef24bbde18ad620cb3f4f335345ea8b9411b9e245464d5b52", + "actorBody": "929d8261e6cad24c5fba8dea51d657ce2533659414f92bfa22274e3f327402e0", + "servedActorBody": "f24c677b3854353c272c29164342f94f420b7570aaf2999d1ea179c7c24ba4bc", + "baselineGatewayBody": "67d10fbd74702a45697a310830439360b3f355af370bccbeea2a09b3000016f0" + }, + "actorBodyProvenance": "Exact native sender B actor callback response captured by the live harness", + "servedActorBodyProvenance": "Mitra-served registered recipient A actor; used as registration context, not sender B key ownership", + "observed": { + "registrationStatus": 201, + "nativeSendSpec": "rfc9421", + "nativeSendAttempts": 1, + "nativeSendStatus": 202, + "workerProcessedCreate": true, + "tamperedHttpSignatureStatus": 401, + "baselineGatewayStatus": 400, + "baselineGatewayError": "invalid gateway URL", + "distinctSender": true, + "senderRegisteredAtMitra": false, + "recipientRegisteredAtMitra": true, + "noteProcessedAsPost": true + }, + "senderDid": "did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f", + "recipientDid": "did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB", + "strategy": "Unregistered distinct native Fedify Person B to registered Mitra portable recipient A; default signObject contexts; public normalizeExistingProofs:true; no JSON mutation" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/processed-collections.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/processed-collections.json new file mode 100644 index 000000000..fe1a799d8 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/processed-collections.json @@ -0,0 +1,13 @@ +{ + "capturedAt": "2026-09-30T14:55:03.869598+00:00", + "query": "SELECT COALESCE(json_agg(row_to_json(t)), '[]'::json) FROM (SELECT c.collection_id,c.object_id,o.object_data->>'type' AS type,o.object_data->>'actor' AS actor,o.created_at FROM activitypub_collection_item c JOIN activitypub_object o USING(object_id) WHERE c.collection_id LIKE '%did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB%' AND c.object_id LIKE '%did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f%' ORDER BY c.collection_id,c.object_id) t", + "rows": [ + { + "collection_id": "ap://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/inbox", + "object_id": "ap://did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/creates/distinct-native-inbox", + "type": "Create", + "actor": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor", + "created_at": "2026-09-30T14:54:42.256068+00:00" + } + ] +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/processed-note.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/processed-note.json new file mode 100644 index 000000000..95aac6154 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/processed-note.json @@ -0,0 +1,92 @@ +{ + "capturedAt": "2026-09-30T14:55:52.028305+00:00", + "query": "SELECT COALESCE(json_agg(row_to_json(t)), '[]'::json) FROM (SELECT object_id,object_data,post_id IS NOT NULL AS has_processed_post,created_at FROM activitypub_object WHERE object_id = 'ap://did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/notes/distinct-native-inbox') t", + "rows": [ + { + "object_id": "ap://did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/notes/distinct-native-inbox", + "object_data": { + "id": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/notes/distinct-native-inbox", + "to": [ + "https://www.w3.org/ns/activitystreams#Public", + "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor" + ], + "tag": { + "href": "http://127.0.0.1:18497/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "name": "@recipient", + "type": "Mention" + }, + "type": "Note", + "proof": { + "type": "DataIntegrityProof", + "created": "2026-09-30T14:54:41.259099121Z", + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/data-integrity/v1", + "https://gotosocial.org/ns", + { + "toot": "http://joinmastodon.org/ns#", + "Emoji": "toot:Emoji", + "quote": { + "@id": "https://w3id.org/fep/044f#quote", + "@type": "@id" + }, + "Hashtag": "as:Hashtag", + "misskey": "https://misskey-hub.net/ns#", + "fedibird": "http://fedibird.com/ns#", + "quoteUri": "fedibird:quoteUri", + "quoteUrl": "as:quoteUrl", + "sensitive": "as:sensitive", + "_misskey_quote": "misskey:_misskey_quote", + "emojiReactions": { + "@id": "fedibird:emojiReactions", + "@type": "@id" + }, + "QuoteAuthorization": "https://w3id.org/fep/044f#QuoteAuthorization", + "quoteAuthorization": { + "@id": "https://w3id.org/fep/044f#quoteAuthorization", + "@type": "@id" + } + } + ], + "proofValue": "z3R9SJKwgDrpPUeiiLNP9gkQStLfpLSoyFAPAi3NF17Pk6nqJGrs3ZrprA9gcd8eWQkmrYXc5Cry2tFqDgHtDL3Ru", + "cryptosuite": "eddsa-jcs-2022", + "proofPurpose": "assertionMethod", + "verificationMethod": "did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f#z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f" + }, + "content": "

Distinct Fedify portable actor to live Mitra recipient.

", + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/data-integrity/v1", + "https://gotosocial.org/ns", + { + "toot": "http://joinmastodon.org/ns#", + "Emoji": "toot:Emoji", + "quote": { + "@id": "https://w3id.org/fep/044f#quote", + "@type": "@id" + }, + "Hashtag": "as:Hashtag", + "misskey": "https://misskey-hub.net/ns#", + "fedibird": "http://fedibird.com/ns#", + "quoteUri": "fedibird:quoteUri", + "quoteUrl": "as:quoteUrl", + "sensitive": "as:sensitive", + "_misskey_quote": "misskey:_misskey_quote", + "emojiReactions": { + "@id": "fedibird:emojiReactions", + "@type": "@id" + }, + "QuoteAuthorization": "https://w3id.org/fep/044f#QuoteAuthorization", + "quoteAuthorization": { + "@id": "https://w3id.org/fep/044f#quoteAuthorization", + "@type": "@id" + } + } + ], + "attributedTo": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor" + }, + "has_processed_post": true, + "created_at": "2026-09-30T14:54:42.251223+00:00" + } + ] +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/profiles.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/profiles.json new file mode 100644 index 000000000..db6d3dd38 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/profiles.json @@ -0,0 +1,16 @@ +{ + "capturedAt": "2026-09-30T14:55:03.982205+00:00", + "query": "SELECT COALESCE(json_agg(row_to_json(t)), '[]'::json) FROM (SELECT actor_id,identity_key,portable_user_id IS NOT NULL AS has_portable_account FROM actor_profile WHERE identity_key IN ('did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f','did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB') OR actor_id LIKE '%did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f%' OR actor_id LIKE '%did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB%') t", + "rows": [ + { + "actor_id": "ap://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "identity_key": null, + "has_portable_account": true + }, + { + "actor_id": "ap://did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor", + "identity_key": null, + "has_portable_account": false + } + ] +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/raw-bodies.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/raw-bodies.json new file mode 100644 index 000000000..aefb3cbd6 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/raw-bodies.json @@ -0,0 +1,6 @@ +{ + "requestBody": "{\"@context\":[\"https://w3id.org/identity/v1\",\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://gotosocial.org/ns\",{\"toot\":\"http://joinmastodon.org/ns#\",\"misskey\":\"https://misskey-hub.net/ns#\",\"fedibird\":\"http://fedibird.com/ns#\",\"sensitive\":\"as:sensitive\",\"votersCount\":{\"@id\":\"toot:votersCount\",\"@type\":\"http://www.w3.org/2001/XMLSchema#nonNegativeInteger\"},\"Emoji\":\"toot:Emoji\",\"Hashtag\":\"as:Hashtag\",\"ChatMessage\":\"http://litepub.social/ns#ChatMessage\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUrl\":\"as:quoteUrl\",\"_misskey_quote\":\"misskey:_misskey_quote\",\"quoteUri\":\"fedibird:quoteUri\",\"QuoteAuthorization\":\"https://w3id.org/fep/044f#QuoteAuthorization\",\"QuoteRequest\":\"https://w3id.org/fep/044f#QuoteRequest\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"emojiReactions\":{\"@id\":\"fedibird:emojiReactions\",\"@type\":\"@id\"}}],\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/creates/distinct-native-inbox\",\"type\":\"Create\",\"proof\":{\"type\":\"DataIntegrityProof\",\"created\":\"2026-09-30T14:54:41.271699951Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"zGf4yDymnbe7B8HqmcG7XBf5anp8WU653AzzVgRCxfZ4HB7BXwWV7qp22xrH3QxX8akwk4btngSomGStDjqshp7x\",\"verificationMethod\":\"did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f#z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f\",\"@context\":[\"https://w3id.org/identity/v1\",\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://gotosocial.org/ns\",{\"toot\":\"http://joinmastodon.org/ns#\",\"misskey\":\"https://misskey-hub.net/ns#\",\"fedibird\":\"http://fedibird.com/ns#\",\"sensitive\":\"as:sensitive\",\"votersCount\":{\"@id\":\"toot:votersCount\",\"@type\":\"http://www.w3.org/2001/XMLSchema#nonNegativeInteger\"},\"Emoji\":\"toot:Emoji\",\"Hashtag\":\"as:Hashtag\",\"ChatMessage\":\"http://litepub.social/ns#ChatMessage\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUrl\":\"as:quoteUrl\",\"_misskey_quote\":\"misskey:_misskey_quote\",\"quoteUri\":\"fedibird:quoteUri\",\"QuoteAuthorization\":\"https://w3id.org/fep/044f#QuoteAuthorization\",\"QuoteRequest\":\"https://w3id.org/fep/044f#QuoteRequest\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"emojiReactions\":{\"@id\":\"fedibird:emojiReactions\",\"@type\":\"@id\"}}]},\"actor\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor\",\"object\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://gotosocial.org/ns\",{\"toot\":\"http://joinmastodon.org/ns#\",\"misskey\":\"https://misskey-hub.net/ns#\",\"fedibird\":\"http://fedibird.com/ns#\",\"sensitive\":\"as:sensitive\",\"Emoji\":\"toot:Emoji\",\"Hashtag\":\"as:Hashtag\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUrl\":\"as:quoteUrl\",\"_misskey_quote\":\"misskey:_misskey_quote\",\"quoteUri\":\"fedibird:quoteUri\",\"QuoteAuthorization\":\"https://w3id.org/fep/044f#QuoteAuthorization\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"emojiReactions\":{\"@id\":\"fedibird:emojiReactions\",\"@type\":\"@id\"}}],\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/notes/distinct-native-inbox\",\"type\":\"Note\",\"attributedTo\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor\",\"content\":\"

Distinct Fedify portable actor to live Mitra recipient.

\",\"tag\":{\"type\":\"Mention\",\"href\":\"http://127.0.0.1:18497/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"name\":\"@recipient\"},\"to\":[\"https://www.w3.org/ns/activitystreams#Public\",\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\"],\"proof\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/data-integrity/v1\",\"https://gotosocial.org/ns\",{\"toot\":\"http://joinmastodon.org/ns#\",\"misskey\":\"https://misskey-hub.net/ns#\",\"fedibird\":\"http://fedibird.com/ns#\",\"sensitive\":\"as:sensitive\",\"Emoji\":\"toot:Emoji\",\"Hashtag\":\"as:Hashtag\",\"quote\":{\"@id\":\"https://w3id.org/fep/044f#quote\",\"@type\":\"@id\"},\"quoteUrl\":\"as:quoteUrl\",\"_misskey_quote\":\"misskey:_misskey_quote\",\"quoteUri\":\"fedibird:quoteUri\",\"QuoteAuthorization\":\"https://w3id.org/fep/044f#QuoteAuthorization\",\"quoteAuthorization\":{\"@id\":\"https://w3id.org/fep/044f#quoteAuthorization\",\"@type\":\"@id\"},\"emojiReactions\":{\"@id\":\"fedibird:emojiReactions\",\"@type\":\"@id\"}}],\"type\":\"DataIntegrityProof\",\"created\":\"2026-09-30T14:54:41.259099121Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z3R9SJKwgDrpPUeiiLNP9gkQStLfpLSoyFAPAi3NF17Pk6nqJGrs3ZrprA9gcd8eWQkmrYXc5Cry2tFqDgHtDL3Ru\",\"verificationMethod\":\"did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f#z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f\"}},\"to\":[\"https://www.w3.org/ns/activitystreams#Public\",\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\"]}", + "actorBody": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/fep/ef61\",\"https://w3id.org/security/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/multikey/v1\",\"https://gotosocial.org/ns\",\"https://w3id.org/fep/7aa9\",{\"alsoKnownAs\":{\"@id\":\"as:alsoKnownAs\",\"@type\":\"@id\"},\"featuredCollections\":{\"@id\":\"https://w3id.org/fep/7aa9#featuredCollections\",\"@type\":\"@id\"},\"manuallyApprovesFollowers\":\"as:manuallyApprovesFollowers\",\"movedTo\":{\"@id\":\"as:movedTo\",\"@type\":\"@id\"},\"toot\":\"http://joinmastodon.org/ns#\",\"Emoji\":\"toot:Emoji\",\"featured\":{\"@id\":\"toot:featured\",\"@type\":\"@id\"},\"featuredTags\":{\"@id\":\"toot:featuredTags\",\"@type\":\"@id\"},\"discoverable\":\"toot:discoverable\",\"suspended\":\"toot:suspended\",\"memorial\":\"toot:memorial\",\"indexable\":\"toot:indexable\",\"schema\":\"http://schema.org#\",\"PropertyValue\":\"schema:PropertyValue\",\"value\":\"schema:value\",\"misskey\":\"https://misskey-hub.net/ns#\",\"_misskey_followedMessage\":\"misskey:_misskey_followedMessage\",\"isCat\":\"misskey:isCat\"}],\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor\",\"type\":\"Person\",\"inbox\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor/inbox\",\"gateways\":[\"https://fedify.example\"],\"assertionMethod\":[{\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#ed25519-key\",\"type\":\"Multikey\",\"controller\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor\",\"publicKeyMultibase\":\"z6Mkf1YFSzwyC6ZJL28STR5rei2XNJHCVKU2mV1gP768cixM\"},{\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#main-key\",\"type\":\"Multikey\",\"controller\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor\",\"publicKeyMultibase\":\"zgghBUVkqmWS8e1ittJsA5xRdPNj4WxsfUGuo2kK6NrkUwKxyRNaEQHLxYUezPkdjEkRRjg98U6LJyngicRLa1Q6fTMMtJy8DujadGoHcbY1aUP9vskG7coev8Mw68VFnuvP7zwf1pH62HYt7CxMnx1CMfS719LfQubVU2VQra8YhWScQanNiRnQqe1qKeVrJLiMCEe7UtfhonS6KgtPQWgapVFZjk2a78n8arg4DdHdwhq9KwG9iBzAkKz5w3hxzLq4p8aVR9Mkcyq7265UoqUkRRz4sFcuKvGjB47MpSi8yEJuLFy1VZUkDRka5YV4N2AwUabVLYJF64itr1DpqaZRvkzMC1KEZY6KQPpS1vydLgqYFbJEV4bhzqu7GJpiGq6aL2NSNSAQxFTv9ergd5aLQdXQUGYk8NzPj5YSjchUmHhu1SVBSuYApHkcXbn4EUo9PYhRnCAY4wymKma4JzqYtQPPGCKps6zar2GM5DFNFkKFxPWdxY5Ugdk5jj9ccEr963hnnb9nPeRYsFYDhEFGzwLUGooWVHggoLVRDMHvqnCdSiQaQhdyE9DVxZMWgBynbZN71kzc6ur726TAmNo4X4NQiWcwKNnWbaBAPUocJ8Hy9YSD9xVg41644iE6Q8JaYz5d9E9NNZ8dv2vTL4aFdWELGP8fBnNvgjMz47tctMde4aKcqkdE9DRAJ82ShuUPWmEUBrRPXBwiXa\"}],\"proof\":{\"type\":\"DataIntegrityProof\",\"created\":\"2026-09-30T14:54:41.245020996Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"zViP1tF9MaXjUAu9agaoL8RQuGKQyd6MLyyXi5P1RZPnC8kWR5TVFJWqNDFmvYpu5apF7cbq35msfCTNSbhNQsma\",\"verificationMethod\":\"did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f#z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f\",\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/fep/ef61\",\"https://w3id.org/security/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/multikey/v1\",\"https://gotosocial.org/ns\",\"https://w3id.org/fep/7aa9\",{\"alsoKnownAs\":{\"@id\":\"as:alsoKnownAs\",\"@type\":\"@id\"},\"featuredCollections\":{\"@id\":\"https://w3id.org/fep/7aa9#featuredCollections\",\"@type\":\"@id\"},\"manuallyApprovesFollowers\":\"as:manuallyApprovesFollowers\",\"movedTo\":{\"@id\":\"as:movedTo\",\"@type\":\"@id\"},\"toot\":\"http://joinmastodon.org/ns#\",\"Emoji\":\"toot:Emoji\",\"featured\":{\"@id\":\"toot:featured\",\"@type\":\"@id\"},\"featuredTags\":{\"@id\":\"toot:featuredTags\",\"@type\":\"@id\"},\"discoverable\":\"toot:discoverable\",\"suspended\":\"toot:suspended\",\"memorial\":\"toot:memorial\",\"indexable\":\"toot:indexable\",\"schema\":\"http://schema.org#\",\"PropertyValue\":\"schema:PropertyValue\",\"value\":\"schema:value\",\"misskey\":\"https://misskey-hub.net/ns#\",\"_misskey_followedMessage\":\"misskey:_misskey_followedMessage\",\"isCat\":\"misskey:isCat\"}]},\"publicKey\":{\"id\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#main-key\",\"type\":\"CryptographicKey\",\"owner\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor\",\"publicKeyPem\":\"-----BEGIN PUBLIC KEY-----\\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAvM94PB5yiw79af0NeKvL\\nFICG2J3OjSvmQCI1+pRbXC07kmf9I4E6yTV+SO6yONpUYFrsmMw+SL13n6V7dyHR\\nHx5FXD4Z09sUfhDiQgrrbmx5yu9FA5K88nvw0Fgi0npSdctTDuFVzfYron6jeZB9\\ncEeXGoeGb+JTcHleozEPOOSKZ3gU4f/iZo2hg73igGswDtmQcIWKH3h7l0fxqoxk\\na3iZt1gt+8TL1hwkAv7rnnPyWmZfPGNIG+CYD+bUwN5ee1ZonDJKZlMOgg0imNam\\n3WEXtLpb0ZKla0MzIET452eUYgKNbBJkdvtbfI32x+Zf7OO0kkk1LxMeeRuUKEwv\\n74gPJ6tKADz3cBGHkG77ZRrbazCncKoSeX4TdDWJC4gmvL2mPF8mtK2BuBQw26wB\\nqaimlg+SJqmZEJgxbG3mGR6hu8d3ltpnjgxCeOUOuSB19Sird14OnNd9fL9SJW+R\\ne4AIashoFt5l4SjGHF98Q+DbQu6wP2OICuFLslTfcoAqyXZqHe0SygUzg0/kWAhw\\nGsa/25KBEYXnSMAn/+FrONDProw+qf9yX9qLS+gUn9yxhsm9bVAlT1wXIPrA9FRn\\nR5SD8AWRnkAKB0mblohfoBCYqTSIDao0UvnwrdfaNAqOcrey5Gget5sZN3HU5kj8\\nkciSCLPd/39lMbcFxLo25eECAwEAAQ==\\n-----END PUBLIC KEY-----\\n\"},\"name\":\"Distinct native Fedify portable sender\",\"outbox\":\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor/outbox\",\"preferredUsername\":\"fedifydistinct\"}", + "servedActorBody": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/multikey/v1\",\"https://w3id.org/fep/ef61\"],\"assertionMethod\":[{\"controller\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"id\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#main-key\",\"publicKeyMultibase\":\"z4MXj1wBzi9jUstyPQj1tJmBTCJQwSmgdEH3r3AcgJRwZBMkP3rY67NfsjsVyeRAH24e8frWsjLuhKJ3G9yRWp2R848U8Yeh8kNyR9GF2vmGEi6BHNEqhGnZMMQnAnLovqzQ7p9vfSsHUYU19yrzEwCSFumsDkk4np96HCjbkpejfNkDDAjPexavs9KSdovfFhJdb1uy4wcyG3ynZFSKsyPQyEUVFd72ufLKgG4h8j4fNHqwzvVQG1tRnqMqzFgS6uXJfftXGsAC6QVE5keYdicLvJ6n2t5UrCsVSeoMwgSuDpXVB8vXuhFkxNz4v2bKBHuHVUzA7cKWxoY5gaczcq4on1P23vsRbtxhkWUQgUA4KMenYWDLk\",\"type\":\"Multikey\"},{\"controller\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"id\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#ed25519-key\",\"publicKeyMultibase\":\"z6MknVDBdr3PRNFK35WPFbHxy7m5g18iuoSTht4vRwzt9WKq\",\"type\":\"Multikey\"},{\"controller\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"id\":\"http://localhost:18498/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#fedify-rsa\",\"publicKeyMultibase\":\"zgghBUVkqmWS8e1imM79CWx4zopmbKaBcdbLUSHjyo3KNnBVZscUs1T8HXSrY7yeSQJZSrrEjtnXq1tWc9fKL31uDYYbr8iSbtiRiXDxUQLA1ZDRH2tsz8a8PufoKK3w9qwNaxkcFVa5YKZ99ahxvvEJ86oDpPexr1HoE5wux1XihNx7kPtpJseQVKjTPYM1YcWe3SqDvy374ZaGFZx5YpxcVCr5gfF9iDHP8KWnYwWF3ge6icMQiqkiCZxsjeV8DL7ww7DJiQniYbk4qZ7mvcpqts657MPR7NWeFKim9wKy6mzaKEdDnkkVeTPbQYFgCUsZyrZcbBFTZp3YAnpTA2k4vmjBvKUyUKzrtXrJAuNgU7Y2cvdxRSCKorAJ38brzReEHA8Vwk72t9Le2P7PVqbUNScKt3L1v1pvQr28rim9Ff7uqPmK4R9j5FR7Tse4qq8zGoxYVAoH5isp9udJjLCs7BsF9MekS1D4aardVzMmqCzjiWCfjeUtTGdkqREsUkGyD3seFUGKui2aqafzVATZQCze4X3KcXL8vLWfq1W7VEx5HVCy5aCAV9E2VCUwimuUNfuSVYGaSY6S3XGXpMYCftak9VA4r22pZCCePC6fXwGhVNwo2mznyZNGbWc1fRLVCr45pS1RaXd58RrXWc2d4HcXdpsQ3XK6tiA4GJUe276bvKmktYKzcfn7KXs9ZHddFNe1SyctHP2JNL\",\"type\":\"Multikey\"}],\"gateways\":[\"http://127.0.0.1:18497\",\"http://localhost:18498\"],\"id\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"inbox\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/inbox\",\"name\":\"Fedify live portable client\",\"outbox\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/outbox\",\"preferredUsername\":\"fepsgnpakpb\",\"proof\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/multikey/v1\",\"https://w3id.org/fep/ef61\"],\"created\":\"2026-09-30T14:46:57.846825928Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z32F5XC6bGuzR6ZE5jCiKTQXcFm2F6fp7WLFWM69bkv7RDXSxe67fXjJXgtdLoQBYqsWnqZqczVvivhACfAYaj1kG\",\"type\":\"DataIntegrityProof\",\"verificationMethod\":\"did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB#z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB\"},\"publicKey\":{\"id\":\"http://localhost:18498/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#fedify-rsa\",\"owner\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"publicKeyPem\":\"-----BEGIN PUBLIC KEY-----\\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoSFdSVINqqwdCPZrEo8H\\nqwx1bmlm/sT7RXpb53oDt0kWOnjhGrNnRSXa4PbHKCPH6yrzV3xGpmN1zVAXcShg\\nu44m1NXbtBtfuEVHSOebRQWu2wyQRYlDk76MEyT33GDtNJf/4OnjnBXO71ebEFVY\\nSKWkZacdS0Ft42sqvFaAK4/RDUEiUWE2t4YsEthT90fo+rXz/Snnv74p70eHnjD8\\n6P29f8JKITTaqXp1ltuoiS9oEIFV/6FQ7HPMfzdBIgMvg/3pDDr1stFT56Slsvrr\\nnMF4J2jy1HNYEo1V7HvS7wStZmGRPNYoiSTHvbk5Vm3ZCmE3Qzng/Sus19KN/B57\\njkeOA8ObS5OXCjshZ+GrBmSnAzZjl+Gm6gQDKBk8/ilaSXH2QtCR4TQmvbsCjRFA\\njoXcKvMh4SfnWGXC5XdkbVjXJuFSHHFNbHBCLygk/IJdbvEHQpPH4Rsqbc3f4TvL\\n3ge/Jd6rm7huVlax3UMq7qUWTtb1PRjjSlrV0Tj5REv1KNe5VGvhMpQmHfJe7zd0\\nBVbgi4I91QRJg9XF/dYXgm330skdSkM0UapBNo9xbgK3ejyNWG5aHcazO+DSdWNu\\n5AbkXLB7m5djxb5ONrOYzz7llW4kg2H0zWNLFbRvdfKowdG906J4h9+6ZYhwufMa\\ndVHS/5EyQbbwVeqe+MG0Qo8CAwEAAQ==\\n-----END PUBLIC KEY-----\\n\",\"type\":\"CryptographicKey\"},\"type\":\"Person\"}", + "baselineGatewayBody": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/multikey/v1\",\"https://w3id.org/fep/ef61\"],\"id\":\"ap+ef61://did:key:z6Mkwayt7WaDpNcgP6eRQsCTaTcP9TCZ4ALtFdfsXAiYJq31/actor\",\"type\":\"Person\",\"inbox\":\"ap+ef61://did:key:z6Mkwayt7WaDpNcgP6eRQsCTaTcP9TCZ4ALtFdfsXAiYJq31/actor/inbox\",\"gateways\":[\"http://127.0.0.1:18497/\",\"http://127.0.0.1:18498/\"],\"proof\":{\"type\":\"DataIntegrityProof\",\"created\":\"2026-09-30T13:36:30.213906006Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z2L7QsFwP7V2YRnXTxV896cCLZ7xHcoYp96yZct3WibVuZQ8rZBNt9sH8k2mgQrkCE5WXAwesxeeUz73xky2qUKhT\",\"verificationMethod\":\"did:key:z6Mkwayt7WaDpNcgP6eRQsCTaTcP9TCZ4ALtFdfsXAiYJq31#z6Mkwayt7WaDpNcgP6eRQsCTaTcP9TCZ4ALtFdfsXAiYJq31\",\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/multikey/v1\",\"https://w3id.org/fep/ef61\"]},\"name\":\"Fedify live portable client\",\"outbox\":\"ap+ef61://did:key:z6Mkwayt7WaDpNcgP6eRQsCTaTcP9TCZ4ALtFdfsXAiYJq31/actor/outbox\",\"preferredUsername\":\"fedifyclient\"}" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/registration-response.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/registration-response.json new file mode 100644 index 000000000..01817dc5d --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/registration-response.json @@ -0,0 +1,34 @@ +{ + "status": 201, + "headers": [ + [ + "access-control-expose-headers", + "content-type" + ], + [ + "content-length", + "867" + ], + [ + "content-security-policy", + "base-uri 'self'; connect-src 'self' *; default-src 'none'; frame-ancestors 'none'; img-src 'self' data:; manifest-src 'self'; media-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self'" + ], + [ + "content-type", + "application/json" + ], + [ + "date", + "Wed, 30 Sep 2026 14:46:57 GMT" + ], + [ + "vary", + "Origin, Access-Control-Request-Method, Access-Control-Request-Headers" + ], + [ + "x-content-type-options", + "nosniff" + ] + ], + "body": "{\"assertionMethod\":[{\"id\":\"ap://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#main-key\",\"type\":\"Multikey\",\"controller\":\"ap://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"publicKeyMultibase\":\"z4MXj1wBzi9jUstyPQj1tJmBTCJQwSmgdEH3r3AcgJRwZBMkP3rY67NfsjsVyeRAH24e8frWsjLuhKJ3G9yRWp2R848U8Yeh8kNyR9GF2vmGEi6BHNEqhGnZMMQnAnLovqzQ7p9vfSsHUYU19yrzEwCSFumsDkk4np96HCjbkpejfNkDDAjPexavs9KSdovfFhJdb1uy4wcyG3ynZFSKsyPQyEUVFd72ufLKgG4h8j4fNHqwzvVQG1tRnqMqzFgS6uXJfftXGsAC6QVE5keYdicLvJ6n2t5UrCsVSeoMwgSuDpXVB8vXuhFkxNz4v2bKBHuHVUzA7cKWxoY5gaczcq4on1P23vsRbtxhkWUQgUA4KMenYWDLk\"},{\"id\":\"ap://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#ed25519-key\",\"type\":\"Multikey\",\"controller\":\"ap://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"publicKeyMultibase\":\"z6MknVDBdr3PRNFK35WPFbHxy7m5g18iuoSTht4vRwzt9WKq\"}]}" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/request.body b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/request.body new file mode 100644 index 000000000..75b0b89a3 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/request.body @@ -0,0 +1 @@ +{"@context":["https://w3id.org/identity/v1","https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://gotosocial.org/ns",{"toot":"http://joinmastodon.org/ns#","misskey":"https://misskey-hub.net/ns#","fedibird":"http://fedibird.com/ns#","sensitive":"as:sensitive","votersCount":{"@id":"toot:votersCount","@type":"http://www.w3.org/2001/XMLSchema#nonNegativeInteger"},"Emoji":"toot:Emoji","Hashtag":"as:Hashtag","ChatMessage":"http://litepub.social/ns#ChatMessage","quote":{"@id":"https://w3id.org/fep/044f#quote","@type":"@id"},"quoteUrl":"as:quoteUrl","_misskey_quote":"misskey:_misskey_quote","quoteUri":"fedibird:quoteUri","QuoteAuthorization":"https://w3id.org/fep/044f#QuoteAuthorization","QuoteRequest":"https://w3id.org/fep/044f#QuoteRequest","quoteAuthorization":{"@id":"https://w3id.org/fep/044f#quoteAuthorization","@type":"@id"},"emojiReactions":{"@id":"fedibird:emojiReactions","@type":"@id"}}],"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/creates/distinct-native-inbox","type":"Create","proof":{"type":"DataIntegrityProof","created":"2026-09-30T14:54:41.271699951Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"zGf4yDymnbe7B8HqmcG7XBf5anp8WU653AzzVgRCxfZ4HB7BXwWV7qp22xrH3QxX8akwk4btngSomGStDjqshp7x","verificationMethod":"did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f#z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f","@context":["https://w3id.org/identity/v1","https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://gotosocial.org/ns",{"toot":"http://joinmastodon.org/ns#","misskey":"https://misskey-hub.net/ns#","fedibird":"http://fedibird.com/ns#","sensitive":"as:sensitive","votersCount":{"@id":"toot:votersCount","@type":"http://www.w3.org/2001/XMLSchema#nonNegativeInteger"},"Emoji":"toot:Emoji","Hashtag":"as:Hashtag","ChatMessage":"http://litepub.social/ns#ChatMessage","quote":{"@id":"https://w3id.org/fep/044f#quote","@type":"@id"},"quoteUrl":"as:quoteUrl","_misskey_quote":"misskey:_misskey_quote","quoteUri":"fedibird:quoteUri","QuoteAuthorization":"https://w3id.org/fep/044f#QuoteAuthorization","QuoteRequest":"https://w3id.org/fep/044f#QuoteRequest","quoteAuthorization":{"@id":"https://w3id.org/fep/044f#quoteAuthorization","@type":"@id"},"emojiReactions":{"@id":"fedibird:emojiReactions","@type":"@id"}}]},"actor":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor","object":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://gotosocial.org/ns",{"toot":"http://joinmastodon.org/ns#","misskey":"https://misskey-hub.net/ns#","fedibird":"http://fedibird.com/ns#","sensitive":"as:sensitive","Emoji":"toot:Emoji","Hashtag":"as:Hashtag","quote":{"@id":"https://w3id.org/fep/044f#quote","@type":"@id"},"quoteUrl":"as:quoteUrl","_misskey_quote":"misskey:_misskey_quote","quoteUri":"fedibird:quoteUri","QuoteAuthorization":"https://w3id.org/fep/044f#QuoteAuthorization","quoteAuthorization":{"@id":"https://w3id.org/fep/044f#quoteAuthorization","@type":"@id"},"emojiReactions":{"@id":"fedibird:emojiReactions","@type":"@id"}}],"id":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/notes/distinct-native-inbox","type":"Note","attributedTo":"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor","content":"

Distinct Fedify portable actor to live Mitra recipient.

","tag":{"type":"Mention","href":"http://127.0.0.1:18497/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","name":"@recipient"},"to":["https://www.w3.org/ns/activitystreams#Public","ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor"],"proof":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/data-integrity/v1","https://gotosocial.org/ns",{"toot":"http://joinmastodon.org/ns#","misskey":"https://misskey-hub.net/ns#","fedibird":"http://fedibird.com/ns#","sensitive":"as:sensitive","Emoji":"toot:Emoji","Hashtag":"as:Hashtag","quote":{"@id":"https://w3id.org/fep/044f#quote","@type":"@id"},"quoteUrl":"as:quoteUrl","_misskey_quote":"misskey:_misskey_quote","quoteUri":"fedibird:quoteUri","QuoteAuthorization":"https://w3id.org/fep/044f#QuoteAuthorization","quoteAuthorization":{"@id":"https://w3id.org/fep/044f#quoteAuthorization","@type":"@id"},"emojiReactions":{"@id":"fedibird:emojiReactions","@type":"@id"}}],"type":"DataIntegrityProof","created":"2026-09-30T14:54:41.259099121Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z3R9SJKwgDrpPUeiiLNP9gkQStLfpLSoyFAPAi3NF17Pk6nqJGrs3ZrprA9gcd8eWQkmrYXc5Cry2tFqDgHtDL3Ru","verificationMethod":"did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f#z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f"}},"to":["https://www.w3.org/ns/activitystreams#Public","ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor"]} \ No newline at end of file diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/request.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/request.json new file mode 100644 index 000000000..5ae20c52c --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/request.json @@ -0,0 +1,31 @@ +{ + "url": "http://127.0.0.1:18497/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/inbox", + "method": "POST", + "headers": [ + [ + "content-digest", + "sha-256=:NGEDJ4axbB7yS73hitYgyz9PM1NF6ouUEbniRUZNW1I=:" + ], + [ + "content-type", + "application/activity+json" + ], + [ + "date", + "Wed, 30 Sep 2026 14:54:41 GMT" + ], + [ + "host", + "127.0.0.1:18497" + ], + [ + "signature", + "sig1=:qay1Qd3ThdK3t0I8P68f91NAnwCZZsyIfxSIfI4MHU6Vm/3yBqzCeY5V2GHRPDS6tZd4SzUlfiHEhTATD+eNoPHuzZwLjazgkV0Rb7wx9sfem8/D1TUkX6DugXKnNOIxK/73q+RHHU459ZwH+YPpZ9ggtkIXl2FY+2hd0R4dHtR4qpQiWP8HdWZNNU2uTYdH7g3f/qT+LoBRzAIcVA1/3TomT3b7shS740ZFndvPlvOZFyWjkGS7twNUPL/525ywe6y3I7YmWKccaNMM+ZIDUwwhgT0RF4SVYmbyxI7Nc5VZguu5DP8RqB4BFzNeTOqPJcv9xQUP/JiqqeBTG1kCvGjVAUfxt5JYDUDw1EROSZ6pSdKiL8gcGcg3TsS6jAAfqAvhxDEMh8DDsz4eHQrgJWIp44RdYHCM+eWdldzbS9wrVIFtiOWcaEFvf51HbWjR4UnGIjXldwOURKS0S7Phya5qwz+3x96Hfg58+DgK9xbINStvy4XjmYsFN3lTkLMikoB/FJ5LLEBa0VX/QBcsBzQs8QxFYnwDoYw0hz4Cpe3Qe4kEVkQNSxlkl1sbxt9S3S9KLdMeHNarzjyZldUxaCSQ/dFKVRibutk+BMKoM9JOMnR7MKq6rVvE8/99Ot8WEYHItpU/S74t/LCWLDy5NY/PlhMGssVASlHs3vA553s=:" + ], + [ + "signature-input", + "sig1=(\"@method\" \"@target-uri\" \"@authority\" \"host\" \"date\" \"content-digest\");alg=\"rsa-v1_5-sha256\";keyid=\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#main-key\";created=1790780081" + ] + ], + "capturedAt": "2026-09-30T14:54:41.299Z" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/response.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/response.json new file mode 100644 index 000000000..ac9c05ab5 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/response.json @@ -0,0 +1,26 @@ +{ + "status": 202, + "headers": [ + [ + "content-length", + "0" + ], + [ + "content-security-policy", + "base-uri 'self'; connect-src 'self' *; default-src 'none'; frame-ancestors 'none'; img-src 'self' data:; manifest-src 'self'; media-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self'" + ], + [ + "date", + "Wed, 30 Sep 2026 14:54:41 GMT" + ], + [ + "vary", + "Origin, Access-Control-Request-Method, Access-Control-Request-Headers" + ], + [ + "x-content-type-options", + "nosniff" + ] + ], + "body": "" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/served-actor.body b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/served-actor.body new file mode 100644 index 000000000..642878054 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/served-actor.body @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/multikey/v1","https://w3id.org/fep/ef61"],"assertionMethod":[{"controller":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","id":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#main-key","publicKeyMultibase":"z4MXj1wBzi9jUstyPQj1tJmBTCJQwSmgdEH3r3AcgJRwZBMkP3rY67NfsjsVyeRAH24e8frWsjLuhKJ3G9yRWp2R848U8Yeh8kNyR9GF2vmGEi6BHNEqhGnZMMQnAnLovqzQ7p9vfSsHUYU19yrzEwCSFumsDkk4np96HCjbkpejfNkDDAjPexavs9KSdovfFhJdb1uy4wcyG3ynZFSKsyPQyEUVFd72ufLKgG4h8j4fNHqwzvVQG1tRnqMqzFgS6uXJfftXGsAC6QVE5keYdicLvJ6n2t5UrCsVSeoMwgSuDpXVB8vXuhFkxNz4v2bKBHuHVUzA7cKWxoY5gaczcq4on1P23vsRbtxhkWUQgUA4KMenYWDLk","type":"Multikey"},{"controller":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","id":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#ed25519-key","publicKeyMultibase":"z6MknVDBdr3PRNFK35WPFbHxy7m5g18iuoSTht4vRwzt9WKq","type":"Multikey"},{"controller":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","id":"http://localhost:18498/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#fedify-rsa","publicKeyMultibase":"zgghBUVkqmWS8e1imM79CWx4zopmbKaBcdbLUSHjyo3KNnBVZscUs1T8HXSrY7yeSQJZSrrEjtnXq1tWc9fKL31uDYYbr8iSbtiRiXDxUQLA1ZDRH2tsz8a8PufoKK3w9qwNaxkcFVa5YKZ99ahxvvEJ86oDpPexr1HoE5wux1XihNx7kPtpJseQVKjTPYM1YcWe3SqDvy374ZaGFZx5YpxcVCr5gfF9iDHP8KWnYwWF3ge6icMQiqkiCZxsjeV8DL7ww7DJiQniYbk4qZ7mvcpqts657MPR7NWeFKim9wKy6mzaKEdDnkkVeTPbQYFgCUsZyrZcbBFTZp3YAnpTA2k4vmjBvKUyUKzrtXrJAuNgU7Y2cvdxRSCKorAJ38brzReEHA8Vwk72t9Le2P7PVqbUNScKt3L1v1pvQr28rim9Ff7uqPmK4R9j5FR7Tse4qq8zGoxYVAoH5isp9udJjLCs7BsF9MekS1D4aardVzMmqCzjiWCfjeUtTGdkqREsUkGyD3seFUGKui2aqafzVATZQCze4X3KcXL8vLWfq1W7VEx5HVCy5aCAV9E2VCUwimuUNfuSVYGaSY6S3XGXpMYCftak9VA4r22pZCCePC6fXwGhVNwo2mznyZNGbWc1fRLVCr45pS1RaXd58RrXWc2d4HcXdpsQ3XK6tiA4GJUe276bvKmktYKzcfn7KXs9ZHddFNe1SyctHP2JNL","type":"Multikey"}],"gateways":["http://127.0.0.1:18497","http://localhost:18498"],"id":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","inbox":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/inbox","name":"Fedify live portable client","outbox":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/outbox","preferredUsername":"fepsgnpakpb","proof":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/multikey/v1","https://w3id.org/fep/ef61"],"created":"2026-09-30T14:46:57.846825928Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z32F5XC6bGuzR6ZE5jCiKTQXcFm2F6fp7WLFWM69bkv7RDXSxe67fXjJXgtdLoQBYqsWnqZqczVvivhACfAYaj1kG","type":"DataIntegrityProof","verificationMethod":"did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB#z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB"},"publicKey":{"id":"http://localhost:18498/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#fedify-rsa","owner":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoSFdSVINqqwdCPZrEo8H\nqwx1bmlm/sT7RXpb53oDt0kWOnjhGrNnRSXa4PbHKCPH6yrzV3xGpmN1zVAXcShg\nu44m1NXbtBtfuEVHSOebRQWu2wyQRYlDk76MEyT33GDtNJf/4OnjnBXO71ebEFVY\nSKWkZacdS0Ft42sqvFaAK4/RDUEiUWE2t4YsEthT90fo+rXz/Snnv74p70eHnjD8\n6P29f8JKITTaqXp1ltuoiS9oEIFV/6FQ7HPMfzdBIgMvg/3pDDr1stFT56Slsvrr\nnMF4J2jy1HNYEo1V7HvS7wStZmGRPNYoiSTHvbk5Vm3ZCmE3Qzng/Sus19KN/B57\njkeOA8ObS5OXCjshZ+GrBmSnAzZjl+Gm6gQDKBk8/ilaSXH2QtCR4TQmvbsCjRFA\njoXcKvMh4SfnWGXC5XdkbVjXJuFSHHFNbHBCLygk/IJdbvEHQpPH4Rsqbc3f4TvL\n3ge/Jd6rm7huVlax3UMq7qUWTtb1PRjjSlrV0Tj5REv1KNe5VGvhMpQmHfJe7zd0\nBVbgi4I91QRJg9XF/dYXgm330skdSkM0UapBNo9xbgK3ejyNWG5aHcazO+DSdWNu\n5AbkXLB7m5djxb5ONrOYzz7llW4kg2H0zWNLFbRvdfKowdG906J4h9+6ZYhwufMa\ndVHS/5EyQbbwVeqe+MG0Qo8CAwEAAQ==\n-----END PUBLIC KEY-----\n","type":"CryptographicKey"},"type":"Person"} \ No newline at end of file diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/served-actor.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/served-actor.json new file mode 100644 index 000000000..7bc2b3fdf --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/served-actor.json @@ -0,0 +1,62 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/data-integrity/v1", + "https://w3id.org/security/multikey/v1", + "https://w3id.org/fep/ef61" + ], + "assertionMethod": [ + { + "controller": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "id": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#main-key", + "publicKeyMultibase": "z4MXj1wBzi9jUstyPQj1tJmBTCJQwSmgdEH3r3AcgJRwZBMkP3rY67NfsjsVyeRAH24e8frWsjLuhKJ3G9yRWp2R848U8Yeh8kNyR9GF2vmGEi6BHNEqhGnZMMQnAnLovqzQ7p9vfSsHUYU19yrzEwCSFumsDkk4np96HCjbkpejfNkDDAjPexavs9KSdovfFhJdb1uy4wcyG3ynZFSKsyPQyEUVFd72ufLKgG4h8j4fNHqwzvVQG1tRnqMqzFgS6uXJfftXGsAC6QVE5keYdicLvJ6n2t5UrCsVSeoMwgSuDpXVB8vXuhFkxNz4v2bKBHuHVUzA7cKWxoY5gaczcq4on1P23vsRbtxhkWUQgUA4KMenYWDLk", + "type": "Multikey" + }, + { + "controller": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "id": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#ed25519-key", + "publicKeyMultibase": "z6MknVDBdr3PRNFK35WPFbHxy7m5g18iuoSTht4vRwzt9WKq", + "type": "Multikey" + }, + { + "controller": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "id": "http://localhost:18498/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#fedify-rsa", + "publicKeyMultibase": "zgghBUVkqmWS8e1imM79CWx4zopmbKaBcdbLUSHjyo3KNnBVZscUs1T8HXSrY7yeSQJZSrrEjtnXq1tWc9fKL31uDYYbr8iSbtiRiXDxUQLA1ZDRH2tsz8a8PufoKK3w9qwNaxkcFVa5YKZ99ahxvvEJ86oDpPexr1HoE5wux1XihNx7kPtpJseQVKjTPYM1YcWe3SqDvy374ZaGFZx5YpxcVCr5gfF9iDHP8KWnYwWF3ge6icMQiqkiCZxsjeV8DL7ww7DJiQniYbk4qZ7mvcpqts657MPR7NWeFKim9wKy6mzaKEdDnkkVeTPbQYFgCUsZyrZcbBFTZp3YAnpTA2k4vmjBvKUyUKzrtXrJAuNgU7Y2cvdxRSCKorAJ38brzReEHA8Vwk72t9Le2P7PVqbUNScKt3L1v1pvQr28rim9Ff7uqPmK4R9j5FR7Tse4qq8zGoxYVAoH5isp9udJjLCs7BsF9MekS1D4aardVzMmqCzjiWCfjeUtTGdkqREsUkGyD3seFUGKui2aqafzVATZQCze4X3KcXL8vLWfq1W7VEx5HVCy5aCAV9E2VCUwimuUNfuSVYGaSY6S3XGXpMYCftak9VA4r22pZCCePC6fXwGhVNwo2mznyZNGbWc1fRLVCr45pS1RaXd58RrXWc2d4HcXdpsQ3XK6tiA4GJUe276bvKmktYKzcfn7KXs9ZHddFNe1SyctHP2JNL", + "type": "Multikey" + } + ], + "gateways": [ + "http://127.0.0.1:18497", + "http://localhost:18498" + ], + "id": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "inbox": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/inbox", + "name": "Fedify live portable client", + "outbox": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/outbox", + "preferredUsername": "fepsgnpakpb", + "proof": { + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/data-integrity/v1", + "https://w3id.org/security/multikey/v1", + "https://w3id.org/fep/ef61" + ], + "created": "2026-09-30T14:46:57.846825928Z", + "cryptosuite": "eddsa-jcs-2022", + "proofPurpose": "assertionMethod", + "proofValue": "z32F5XC6bGuzR6ZE5jCiKTQXcFm2F6fp7WLFWM69bkv7RDXSxe67fXjJXgtdLoQBYqsWnqZqczVvivhACfAYaj1kG", + "type": "DataIntegrityProof", + "verificationMethod": "did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB#z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB" + }, + "publicKey": { + "id": "http://localhost:18498/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#fedify-rsa", + "owner": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoSFdSVINqqwdCPZrEo8H\nqwx1bmlm/sT7RXpb53oDt0kWOnjhGrNnRSXa4PbHKCPH6yrzV3xGpmN1zVAXcShg\nu44m1NXbtBtfuEVHSOebRQWu2wyQRYlDk76MEyT33GDtNJf/4OnjnBXO71ebEFVY\nSKWkZacdS0Ft42sqvFaAK4/RDUEiUWE2t4YsEthT90fo+rXz/Snnv74p70eHnjD8\n6P29f8JKITTaqXp1ltuoiS9oEIFV/6FQ7HPMfzdBIgMvg/3pDDr1stFT56Slsvrr\nnMF4J2jy1HNYEo1V7HvS7wStZmGRPNYoiSTHvbk5Vm3ZCmE3Qzng/Sus19KN/B57\njkeOA8ObS5OXCjshZ+GrBmSnAzZjl+Gm6gQDKBk8/ilaSXH2QtCR4TQmvbsCjRFA\njoXcKvMh4SfnWGXC5XdkbVjXJuFSHHFNbHBCLygk/IJdbvEHQpPH4Rsqbc3f4TvL\n3ge/Jd6rm7huVlax3UMq7qUWTtb1PRjjSlrV0Tj5REv1KNe5VGvhMpQmHfJe7zd0\nBVbgi4I91QRJg9XF/dYXgm330skdSkM0UapBNo9xbgK3ejyNWG5aHcazO+DSdWNu\n5AbkXLB7m5djxb5ONrOYzz7llW4kg2H0zWNLFbRvdfKowdG906J4h9+6ZYhwufMa\ndVHS/5EyQbbwVeqe+MG0Qo8CAwEAAQ==\n-----END PUBLIC KEY-----\n", + "type": "CryptographicKey" + }, + "type": "Person" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/state.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/state.json new file mode 100644 index 000000000..b1dcc3444 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/state.json @@ -0,0 +1,16 @@ +{ + "senderDid": "did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f", + "recipientDid": "did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB", + "actorId": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor", + "recipientId": "ap+ef61://did%3Akey%3Az6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "inbox": "http://127.0.0.1:18497/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/inbox", + "proofId": "did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f#z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f", + "rsaId": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#main-key", + "edId": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#ed25519-key", + "noteId": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/notes/distinct-native-inbox", + "createId": "https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/creates/distinct-native-inbox", + "gateway": "https://fedify.example", + "mitra": "http://127.0.0.1:18497", + "startedAt": "2026-09-30T14:54:41.273Z", + "strategy": "Unregistered distinct native Fedify Person B to registered Mitra portable recipient A; default signObject contexts; public normalizeExistingProofs:true; no JSON mutation" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/tampered-request.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/tampered-request.json new file mode 100644 index 000000000..ca6f961ea --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/tampered-request.json @@ -0,0 +1,31 @@ +{ + "url": "http://127.0.0.1:18497/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/inbox", + "method": "POST", + "headers": [ + [ + "content-digest", + "sha-256=:NGEDJ4axbB7yS73hitYgyz9PM1NF6ouUEbniRUZNW1I=:" + ], + [ + "content-type", + "application/activity+json" + ], + [ + "date", + "Wed, 30 Sep 2026 14:54:41 GMT" + ], + [ + "host", + "127.0.0.1:18497" + ], + [ + "signature", + "sig1=:AAAA:" + ], + [ + "signature-input", + "sig1=(\"@method\" \"@target-uri\" \"@authority\" \"host\" \"date\" \"content-digest\");alg=\"rsa-v1_5-sha256\";keyid=\"https://fedify.example/.well-known/apgateway/did:key:z6MkprFq1ktAGdazKPpRaCJg11dHcRtjf8ZPXMvP3uauVw2f/actor#main-key\";created=1790780081" + ] + ], + "capturedAt": "2026-09-30T14:54:41.452Z" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/tampered-response.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/tampered-response.json new file mode 100644 index 000000000..dac64198f --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/tampered-response.json @@ -0,0 +1,26 @@ +{ + "status": 401, + "headers": [ + [ + "content-length", + "28" + ], + [ + "content-security-policy", + "base-uri 'self'; connect-src 'self' *; default-src 'none'; frame-ancestors 'none'; img-src 'self' data:; manifest-src 'self'; media-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self'" + ], + [ + "date", + "Wed, 30 Sep 2026 14:54:41 GMT" + ], + [ + "vary", + "Origin, Access-Control-Request-Method, Access-Control-Request-Headers" + ], + [ + "x-content-type-options", + "nosniff" + ] + ], + "body": "signature verification error" +} diff --git a/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap b/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap index 2d17eb19d..80d4026da 100644 --- a/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap +++ b/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap @@ -69292,7 +69292,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -69801,7 +69801,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { \\"@id\\": formatIri(v) } + { \\"@id\\": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; @@ -90390,7 +90390,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -90899,7 +90899,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { \\"@id\\": formatIri(v) } + { \\"@id\\": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; @@ -110117,7 +110117,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -110626,7 +110626,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { \\"@id\\": formatIri(v) } + { \\"@id\\": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; @@ -121140,7 +121140,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -121649,7 +121649,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { \\"@id\\": formatIri(v) } + { \\"@id\\": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; @@ -140573,7 +140573,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -141082,7 +141082,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { \\"@id\\": formatIri(v) } + { \\"@id\\": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; diff --git a/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap b/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap index 9d9b2b7dd..d12b81ab9 100644 --- a/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap +++ b/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap @@ -69290,7 +69290,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -69799,7 +69799,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { \\"@id\\": formatIri(v) } + { \\"@id\\": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; @@ -90388,7 +90388,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -90897,7 +90897,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { \\"@id\\": formatIri(v) } + { \\"@id\\": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; @@ -110115,7 +110115,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -110624,7 +110624,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { \\"@id\\": formatIri(v) } + { \\"@id\\": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; @@ -121138,7 +121138,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -121647,7 +121647,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { \\"@id\\": formatIri(v) } + { \\"@id\\": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; @@ -140571,7 +140571,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -141080,7 +141080,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { \\"@id\\": formatIri(v) } + { \\"@id\\": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; diff --git a/packages/vocab-tools/src/__snapshots__/class.test.ts.snap b/packages/vocab-tools/src/__snapshots__/class.test.ts.snap index 59be9ef0f..e66adfa74 100644 --- a/packages/vocab-tools/src/__snapshots__/class.test.ts.snap +++ b/packages/vocab-tools/src/__snapshots__/class.test.ts.snap @@ -69292,7 +69292,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -69801,7 +69801,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { "@id": formatIri(v) } + { "@id": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; @@ -90390,7 +90390,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -90899,7 +90899,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { "@id": formatIri(v) } + { "@id": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; @@ -110117,7 +110117,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -110626,7 +110626,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { "@id": formatIri(v) } + { "@id": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; @@ -121140,7 +121140,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -121649,7 +121649,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { "@id": formatIri(v) } + { "@id": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; @@ -140573,7 +140573,7 @@ get gateways(): (URL)[] { compactItems = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { const item = ( - formatIri(v) + v.origin ); compactItems.push(item); } @@ -141082,7 +141082,7 @@ get gateways(): (URL)[] { array = []; for (const v of this.#_hQiaHhZP8hqxckxTBrpsGNs57E3) { let element = ( - { "@id": formatIri(v) } + { "@id": v.origin } ); if (Array.isArray(element)) { if (element.length < 1) continue; diff --git a/packages/vocab-tools/src/type.ts b/packages/vocab-tools/src/type.ts index a52fa907a..703eaa150 100644 --- a/packages/vocab-tools/src/type.ts +++ b/packages/vocab-tools/src/type.ts @@ -340,10 +340,10 @@ const scalarTypes: Record = { return `${v} instanceof URL && isGatewayUrl(${v})`; }, encoder(v) { - return `{ "@id": formatIri(${v}) }`; + return `{ "@id": ${v}.origin }`; }, compactEncoder(v) { - return `formatIri(${v})`; + return `${v}.origin`; }, dataCheck(v) { return `${v} != null && typeof ${v} === "object" && diff --git a/packages/vocab/src/vocab.test.ts b/packages/vocab/src/vocab.test.ts index cb2f698c4..e45bcef25 100644 --- a/packages/vocab/src/vocab.test.ts +++ b/packages/vocab/src/vocab.test.ts @@ -713,15 +713,54 @@ test("FEP-ef61: actor gateways round-trip as an ordered URI list", async () => { }); deepStrictEqual(actor.gateways, gateways); - const jsonLd = await actor.toJsonLd() as Record; + const jsonLd = await actor.toJsonLd({ + format: "compact", + }) as Record; deepStrictEqual(jsonLd.type, ActorClass.name); - deepStrictEqual(jsonLd.gateways, gateways.map((gateway) => gateway.href)); + deepStrictEqual(jsonLd.gateways, gateways.map((gateway) => gateway.origin)); const restored = await ActorClass.fromJsonLd(jsonLd); deepStrictEqual(restored.gateways, gateways); } }); +test("FEP-ef61: actor gateways serialize as origins", async () => { + const actorClasses = [Application, Group, Organization, Person, Service]; + const gateways = [ + new URL("https://first.example:443/"), + new URL("http://second.example:80/"), + new URL("https://third.example:8443/"), + new URL("http://fourth.example:8080/"), + ]; + const origins = [ + "https://first.example", + "http://second.example", + "https://third.example:8443", + "http://fourth.example:8080", + ]; + for (const ActorClass of actorClasses) { + const actor = new ActorClass({ + id: parseIri("ap://did:key:z6Mkabc/actor"), + gateways, + }); + const compact = await actor.toJsonLd() as Record; + deepStrictEqual(compact.gateways, origins); + const expanded = await actor.toJsonLd({ + format: "expand", + }) as Record[]; + deepStrictEqual(expanded[0]["https://w3id.org/fep/ef61/gateways"], [ + { "@list": origins.map((origin) => ({ "@id": origin })) }, + ]); + deepStrictEqual(actor.gateways, gateways); + deepStrictEqual( + actor.gateways.map((gateway) => gateway.href), + origins.map((origin) => `${origin}/`), + ); + deepStrictEqual((await ActorClass.fromJsonLd(compact)).gateways, gateways); + deepStrictEqual((await ActorClass.fromJsonLd(expanded)).gateways, gateways); + } +}); + test("FEP-ef61: portable actors parse unmapped gateway lists", async () => { const actorClasses = [Application, Group, Organization, Person, Service]; const gateways = ["https://first.example", "https://second.example"]; @@ -798,7 +837,7 @@ test("FEP-ef61: actor gateways preserve single, empty, and invalid cases", async }); deepStrictEqual( (await singleGateway.toJsonLd() as Record).gateways, - ["https://server.example/"], + ["https://server.example"], ); const noGateways = new Person({ From 7df2d14acda866b91861cf50072238ba39e67050 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 00:29:41 +0900 Subject: [PATCH 012/184] Verify Mitra gateway delivery to Fedify Record Mitra's actual gateway delivery of a client-proved portable Create to Fedify, preserving the original request and signing-key actor. Verify raw JCS proofs, the gateway HTTP signature and key ownership, inbox dispatch, and rejection of body, header, path, and actor tampering. Distinguish the Fedify C2S client's DID proofs from Mitra's HTTP signing and forwarding. Document the live setup and offline freshness checks without claiming independent DID-proof generation by Mitra. https://github.com/fedify-dev/fedify/issues/1097 Changelog: none Assisted-by: Codex:gpt-6.1-sol --- FEDERATION.md | 14 +- .../src/sig/mitra-receive-interop.test.ts | 262 ++++++++++++++++++ .../fep-ef61/mitra-v5.10.0/receive/README.md | 85 ++++++ .../mitra-v5.10.0/receive/actor-response.json | 4 + .../fep-ef61/mitra-v5.10.0/receive/actor.body | 1 + .../fep-ef61/mitra-v5.10.0/receive/actor.json | 62 +++++ .../mitra-v5.10.0/receive/listener.json | 5 + .../mitra-v5.10.0/receive/metadata.json | 28 ++ .../mitra-v5.10.0/receive/raw-bodies.json | 4 + .../mitra-v5.10.0/receive/request.body | 1 + .../mitra-v5.10.0/receive/request.json | 21 ++ .../mitra-v5.10.0/receive/response.json | 1 + .../mitra-v5.10.0/receive/verification.json | 4 + 13 files changed, 490 insertions(+), 2 deletions(-) create mode 100644 packages/fedify/src/sig/mitra-receive-interop.test.ts create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/README.md create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/actor-response.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/actor.body create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/actor.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/listener.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/metadata.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/raw-bodies.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/request.body create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/request.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/response.json create mode 100644 packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/verification.json diff --git a/FEDERATION.md b/FEDERATION.md index c16f1ac57..fdd59f06b 100644 --- a/FEDERATION.md +++ b/FEDERATION.md @@ -145,13 +145,23 @@ Mitra's embedded-object limit rejected the default actor context. This setup workaround was separate from the native server-to-server delivery. The [Fedify to Mitra fixture] records the results and limitations, including the portless HTTPS gateway used for the sender because Mitra's WebFinger lookup -drops explicit gateway ports. Mitra to -Fedify verification remains separate work, as does Mastodon compatibility. +drops explicit gateway ports. + +In the other direction, Mitra forwarded a portable `Create` submitted to its +gateway outbox by the Fedify client. Mitra signed the HTTP request with its +Cavage RSA gateway key; the activity and embedded note retained the client's +DID proofs. Fedify separately verified the HTTP Signature with the normal +current-time freshness check, returned HTTP 202 from its proof-authenticated +inbox, and dispatched the `Create` listener. The [Mitra to Fedify fixture] +records this delivery. It tests Mitra's gateway transport of client-signed +objects, rather than independent generation of DID proofs by Mitra. +Mastodon compatibility remains unverified. [tootik fixture]: packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/README.md [tootik Follow fixture]: packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/follow/README.md [Fedify to tootik fixture]: packages/fedify/test-vectors/fep-ef61/tootik-v0.25.4/send/README.md [Fedify to Mitra fixture]: packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/send/README.md +[Mitra to Fedify fixture]: packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/README.md ActivityPub diff --git a/packages/fedify/src/sig/mitra-receive-interop.test.ts b/packages/fedify/src/sig/mitra-receive-interop.test.ts new file mode 100644 index 000000000..9234cb82e --- /dev/null +++ b/packages/fedify/src/sig/mitra-receive-interop.test.ts @@ -0,0 +1,262 @@ +// Mitra authenticates transport with its gateway HTTP key; the portable actor, +// Create, and Note proofs are produced by the Fedify C2S client before Mitra +// forwards them. This fixture does not claim Mitra generated those DID proofs. +import { mockDocumentLoader, test } from "@fedify/fixture"; +import { Create, Person } from "@fedify/vocab"; +import { + canonicalizePortableUri, + decodeMultibase, + importDidKey, +} from "@fedify/vocab-runtime"; +import serialize from "json-canon"; +import { assert, assertEquals } from "@std/assert"; +import { encodeHex } from "byte-encodings/hex"; +import { createFederation } from "../federation/middleware.ts"; +import { MemoryKvStore } from "../federation/kv.ts"; +import actor from "../../test-vectors/fep-ef61/mitra-v5.10.0/receive/actor.json" with { + type: "json", +}; +import captured from "../../test-vectors/fep-ef61/mitra-v5.10.0/receive/request.json" with { + type: "json", +}; +import metadata from "../../test-vectors/fep-ef61/mitra-v5.10.0/receive/metadata.json" with { + type: "json", +}; +import rawBodies from "../../test-vectors/fep-ef61/mitra-v5.10.0/receive/raw-bodies.json" with { + type: "json", +}; +import liveResponse from "../../test-vectors/fep-ef61/mitra-v5.10.0/receive/response.json" with { + type: "json", +}; +import liveListener from "../../test-vectors/fep-ef61/mitra-v5.10.0/receive/listener.json" with { + type: "json", +}; +import liveVerification from "../../test-vectors/fep-ef61/mitra-v5.10.0/receive/verification.json" with { + type: "json", +}; +import actorResponse from "../../test-vectors/fep-ef61/mitra-v5.10.0/receive/actor-response.json" with { + type: "json", +}; +import { verifyRequestDetailed } from "./http.ts"; +import { doesActorOwnKey } from "./owner.ts"; +import { verifyPortableObjectProof } from "./proof.ts"; + +const body = rawBodies.requestBody; +const activity = JSON.parse(body); + +async function sha256(value: string): Promise { + return encodeHex( + new Uint8Array( + await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value)), + ), + ); +} + +async function digest(value: string): Promise { + return new Uint8Array( + await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value)), + ); +} + +// Verifies the exact JSON maps without Fedify's outgoing-normalization fallback. +async function verifyRawJcs( + document: Record, +): Promise { + const { proof, ...unsecured } = document; + assert(proof != null && typeof proof === "object" && !Array.isArray(proof)); + const { proofValue, ...configuration } = proof as Record; + assertEquals(configuration.cryptosuite, "eddsa-jcs-2022"); + configuration["@context"] ??= document["@context"]; + assert(typeof configuration.verificationMethod === "string"); + assert(typeof proofValue === "string"); + const key = await importDidKey( + configuration.verificationMethod.split("#")[0], + ); + const combined = new Uint8Array(64); + combined.set(await digest(serialize(configuration)), 0); + combined.set(await digest(serialize(unsecured)), 32); + return await crypto.subtle.verify( + "Ed25519", + key, + new Uint8Array(decodeMultibase(proofValue)), + combined, + ); +} + +function loader(document: unknown = actor) { + return (url: string) => { + assertEquals(url.split("#")[0], metadata.httpKeyId.split("#")[0]); + return Promise.resolve({ + document: structuredClone(document), + documentUrl: metadata.httpKeyId.split("#")[0], + contextUrl: null, + }); + }; +} + +const options = { + documentLoader: loader(), + contextLoader: mockDocumentLoader, + currentTime: Temporal.Instant.from(captured.capturedAt), +}; + +function request( + requestBody = body, + url = captured.url, + headers = new Headers(captured.headers as [string, string][]), +): Request { + return new Request(url, { + method: captured.method, + headers, + body: requestBody, + }); +} + +async function deliver(requestBody: string) { + const federation = createFederation({ + kv: new MemoryKvStore(), + documentLoaderFactory: () => loader(), + contextLoaderFactory: () => mockDocumentLoader, + // HTTP time validation is tested separately at the capture time. + signatureTimeWindow: false, + }); + federation.setActorDispatcher( + "/users/{identifier}", + (ctx, identifier) => + identifier === "alice" + ? new Person({ + id: ctx.getActorUri(identifier), + inbox: ctx.getInboxUri(identifier), + }) + : null, + ).setKeyPairsDispatcher(() => []); + const received: Create[] = []; + federation.setInboxListeners("/users/{identifier}/inbox", "/inbox") + .on(Create, (_ctx, create) => { + received.push(create); + }); + const response = await federation.fetch(request(requestBody), { + contextData: undefined, + }); + return { response, received }; +} + +test("Mitra v5.10.0 forwarded client-proved Create verifies its proof and HTTP signature", async () => { + const actorBody = rawBodies.actorBody; + assertEquals( + await sha256(body), + metadata.sha256.requestBody, + ); + assertEquals( + await sha256(actorBody), + metadata.sha256.actorBody, + ); + assertEquals(JSON.parse(actorBody), actor); + assertEquals(actorResponse.status, 200); + assertEquals(actorResponse.url, metadata.httpKeyId); + assertEquals(liveVerification.verified, true); + assertEquals(liveVerification.key, metadata.httpKeyId); + assertEquals(activity.type, "Create"); + assertEquals(actor.type, "Person"); + assert((await verifyPortableObjectProof(activity.object, options)).verified); + assertEquals(activity.actor, actor.id); + assert(await verifyRawJcs(actor)); + assert(await verifyRawJcs(activity)); + assert(await verifyRawJcs(activity.object)); + assert((await verifyPortableObjectProof(actor, options)).verified); + assert((await verifyPortableObjectProof(activity, options)).verified); + const verified = await verifyRequestDetailed(request(), options); + assert(verified.verified); + assertEquals(verified.key.id?.href, metadata.httpKeyId); + assert(verified.key.id?.href !== actor.publicKey.id); + const parsed = await Create.fromJsonLd(activity, options); + assert(await doesActorOwnKey(parsed, verified.key, options)); + assertEquals(captured.capturedAt, metadata.capturedAt); +}); + +test("Mitra v5.10.0 forwarded client-proved Create reaches the Fedify inbox listener", async () => { + assertEquals(liveResponse.status, 202); + assertEquals(liveListener.type, "Create"); + assertEquals( + canonicalizePortableUri(liveListener.id), + canonicalizePortableUri(activity.id), + ); + assertEquals( + canonicalizePortableUri(liveListener.actor), + canonicalizePortableUri(activity.actor), + ); + const { response, received } = await deliver(body); + assertEquals(response.status, 202); + assertEquals(received.length, 1); + assert(received[0].id != null); + assertEquals( + canonicalizePortableUri(received[0].id.href), + canonicalizePortableUri(activity.id), + ); + assert(received[0].actorId != null); + assertEquals( + canonicalizePortableUri(received[0].actorId.href), + canonicalizePortableUri(actor.id), + ); +}); + +test("Mitra v5.10.0 forwarded client-proved Create rejects body tampering", async () => { + const tampered = { + ...activity, + object: { ...activity.object, content: "Tampered received Note" }, + }; + assertEquals( + (await verifyPortableObjectProof(tampered, options)).verified, + false, + ); + assertEquals(await verifyRawJcs(tampered), false); + assertEquals(await verifyRawJcs(tampered.object), false); + const changedBody = JSON.stringify(tampered); + assertEquals( + (await verifyRequestDetailed(request(changedBody), options)).verified, + false, + ); + const { response, received } = await deliver(changedBody); + assertEquals(response.status, 401); + assertEquals(received.length, 0); +}); + +test("Mitra v5.10.0 forwarded client-proved Create rejects signed header and path tampering", async () => { + const headers = new Headers(captured.headers as [string, string][]); + headers.set( + "Date", + new Date( + Date.parse( + new Headers(captured.headers as [string, string][]).get("Date")!, + ) + 1000, + ).toUTCString(), + ); + assertEquals( + (await verifyRequestDetailed(request(body, captured.url, headers), options)) + .verified, + false, + ); + assertEquals( + (await verifyRequestDetailed( + request(body, `${captured.url}/tampered`), + options, + )).verified, + false, + ); +}); + +test("Mitra v5.10.0 forwarded client-proved Create rejects a tampered actor proof", async () => { + const tampered = { ...actor, preferredUsername: "mallory" }; + assertEquals(await verifyRawJcs(tampered), false); + assertEquals( + (await verifyPortableObjectProof(tampered, options)).verified, + false, + ); + assertEquals( + (await verifyRequestDetailed(request(), { + ...options, + documentLoader: loader(tampered), + })).verified, + false, + ); +}); diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/README.md b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/README.md new file mode 100644 index 000000000..f15525dea --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/README.md @@ -0,0 +1,85 @@ +Mitra to Fedify gateway delivery +================================ + +This fixture records Mitra v5.10.0 delivering a portable `Create` to a Fedify +inbox. The unmodified image was pinned to +`codeberg.org/silverpill/mitra@sha256:4348ddea1d819f654cd3e6be4e955b3933d1d21807c6a9a8ef64eda4333f1d0a`. +Its version output was `mitra 5.10.0`; tag `v5.10.0` points to source commit +`17340ef09d4a902f301acdcfde094f5778d72f35`. + +The Fedify scratch client created the portable actor and the DID-signed +`Note` and `Create`, then submitted the activity to Mitra's gateway outbox. +Mitra's delivery worker forwarded it to +`https://fedify.example:18444/users/alice/inbox`, signing the HTTP request +with Mitra's RSA gateway key. The original `eddsa-jcs-2022` proofs on the +activity and note were generated by Fedify's client and retained by Mitra. +This capture verifies Mitra's transport of client-signed portable objects; +it does not establish independent DID-proof generation by Mitra. + +Fedify separately called `verifyRequestDetailed()` on the original request +and accepted its Cavage HTTP Signature with the normal current-time +freshness check. The signing key ID was the actor's compatible identifier +on the Mitra gateway with `#main-key`. Mitra's signed components were +`(request-target)`, `host`, `date`, and `digest`. + +Fedify's inbox then returned HTTP 202 and dispatched the `Create` listener +with the expected activity and actor IDs. The inbox authenticated the +activity's DID proof and skipped HTTP Signature verification. HTTP 202 and +listener dispatch therefore establish proof-authenticated receipt; the +separate verification result establishes acceptance of the gateway HTTP +Signature. + +The request body and headers were captured directly at the Fedify receiver. +The actor document was fetched from Mitra while resolving the HTTP signing +key. Neither the request nor that response was reconstructed from fixture +objects. The capture time, source pins, hashes, response, and listener result +are recorded alongside the original bodies. Private keys, database files, +and invite codes are excluded. + + +Capture procedure and limits +---------------------------- + +The capture used the registered actor from the [Fedify to Mitra setup]. +Gateway registration and the actor `Update` used a scratch FEP-ae97 client, +compact signing contexts, and Fedify's existing internal outgoing normalizer. +The compact setup contexts avoided Mitra's limit of 20 recursively +counted embedded JSON objects. Fedify does not provide a public FEP-ae97 +client; this delivery is not evidence of one. + +Mitra and PostgreSQL 16 ran locally in Podman. Mitra's listener was +`http://127.0.0.1:18497`; gateway support was enabled and SSRF protection +was disabled for the local capture. The Fedify receiver used HTTPS on +`127.0.0.1:18444` with a certificate signed by a local CA trusted by Mitra's +OS CA store. Certificate verification remained enabled. These settings do +not establish public deployment behavior. + +To repeat the delivery, complete the registered-actor setup described in the +linked fixture, then: + +1. Run a Fedify HTTPS receiver with a `Person` at */users/alice*, its inbox + at */users/alice/inbox*, and a `Create` listener that records activity + and actor IDs. Capture incoming bodies and headers before consuming them. +2. Sign a native `Note` and `Create` with the registered actor's DID key. + Address both to `https://fedify.example:18444/users/alice` and submit the + activity to the actor's compatible outbox on Mitra using the same compact + setup contexts and normalization described in the linked fixture. +3. Let Mitra's delivery worker send the request. Independently verify its + HTTP Signature on a request clone, then pass the original request to + `federation.fetch()`. Record the HTTP verification result, inbox response, + listener record, and exact fetched signing-key actor document. + +Fresh identities and proofs produce different IDs, signatures, and hashes. +Offline replay uses the captured time for a separate strict HTTP signature +freshness check. The inbox replay disables HTTP timestamp validation for the +stored request; it does not recreate Mitra's worker. The live capture used the +normal current-time check. +Run the offline regressions with: + +~~~~ bash +mise run test:deno packages/fedify/src/sig/mitra-receive-interop.test.ts +~~~~ + +Mastodon interoperability is outside this result. + +[Fedify to Mitra setup]: ../send/README.md diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/actor-response.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/actor-response.json new file mode 100644 index 000000000..2f597a7e0 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/actor-response.json @@ -0,0 +1,4 @@ +{ + "url": "http://127.0.0.1:18497/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#main-key", + "status": 200 +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/actor.body b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/actor.body new file mode 100644 index 000000000..642878054 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/actor.body @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/multikey/v1","https://w3id.org/fep/ef61"],"assertionMethod":[{"controller":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","id":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#main-key","publicKeyMultibase":"z4MXj1wBzi9jUstyPQj1tJmBTCJQwSmgdEH3r3AcgJRwZBMkP3rY67NfsjsVyeRAH24e8frWsjLuhKJ3G9yRWp2R848U8Yeh8kNyR9GF2vmGEi6BHNEqhGnZMMQnAnLovqzQ7p9vfSsHUYU19yrzEwCSFumsDkk4np96HCjbkpejfNkDDAjPexavs9KSdovfFhJdb1uy4wcyG3ynZFSKsyPQyEUVFd72ufLKgG4h8j4fNHqwzvVQG1tRnqMqzFgS6uXJfftXGsAC6QVE5keYdicLvJ6n2t5UrCsVSeoMwgSuDpXVB8vXuhFkxNz4v2bKBHuHVUzA7cKWxoY5gaczcq4on1P23vsRbtxhkWUQgUA4KMenYWDLk","type":"Multikey"},{"controller":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","id":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#ed25519-key","publicKeyMultibase":"z6MknVDBdr3PRNFK35WPFbHxy7m5g18iuoSTht4vRwzt9WKq","type":"Multikey"},{"controller":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","id":"http://localhost:18498/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#fedify-rsa","publicKeyMultibase":"zgghBUVkqmWS8e1imM79CWx4zopmbKaBcdbLUSHjyo3KNnBVZscUs1T8HXSrY7yeSQJZSrrEjtnXq1tWc9fKL31uDYYbr8iSbtiRiXDxUQLA1ZDRH2tsz8a8PufoKK3w9qwNaxkcFVa5YKZ99ahxvvEJ86oDpPexr1HoE5wux1XihNx7kPtpJseQVKjTPYM1YcWe3SqDvy374ZaGFZx5YpxcVCr5gfF9iDHP8KWnYwWF3ge6icMQiqkiCZxsjeV8DL7ww7DJiQniYbk4qZ7mvcpqts657MPR7NWeFKim9wKy6mzaKEdDnkkVeTPbQYFgCUsZyrZcbBFTZp3YAnpTA2k4vmjBvKUyUKzrtXrJAuNgU7Y2cvdxRSCKorAJ38brzReEHA8Vwk72t9Le2P7PVqbUNScKt3L1v1pvQr28rim9Ff7uqPmK4R9j5FR7Tse4qq8zGoxYVAoH5isp9udJjLCs7BsF9MekS1D4aardVzMmqCzjiWCfjeUtTGdkqREsUkGyD3seFUGKui2aqafzVATZQCze4X3KcXL8vLWfq1W7VEx5HVCy5aCAV9E2VCUwimuUNfuSVYGaSY6S3XGXpMYCftak9VA4r22pZCCePC6fXwGhVNwo2mznyZNGbWc1fRLVCr45pS1RaXd58RrXWc2d4HcXdpsQ3XK6tiA4GJUe276bvKmktYKzcfn7KXs9ZHddFNe1SyctHP2JNL","type":"Multikey"}],"gateways":["http://127.0.0.1:18497","http://localhost:18498"],"id":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","inbox":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/inbox","name":"Fedify live portable client","outbox":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/outbox","preferredUsername":"fepsgnpakpb","proof":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/multikey/v1","https://w3id.org/fep/ef61"],"created":"2026-09-30T14:46:57.846825928Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z32F5XC6bGuzR6ZE5jCiKTQXcFm2F6fp7WLFWM69bkv7RDXSxe67fXjJXgtdLoQBYqsWnqZqczVvivhACfAYaj1kG","type":"DataIntegrityProof","verificationMethod":"did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB#z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB"},"publicKey":{"id":"http://localhost:18498/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#fedify-rsa","owner":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoSFdSVINqqwdCPZrEo8H\nqwx1bmlm/sT7RXpb53oDt0kWOnjhGrNnRSXa4PbHKCPH6yrzV3xGpmN1zVAXcShg\nu44m1NXbtBtfuEVHSOebRQWu2wyQRYlDk76MEyT33GDtNJf/4OnjnBXO71ebEFVY\nSKWkZacdS0Ft42sqvFaAK4/RDUEiUWE2t4YsEthT90fo+rXz/Snnv74p70eHnjD8\n6P29f8JKITTaqXp1ltuoiS9oEIFV/6FQ7HPMfzdBIgMvg/3pDDr1stFT56Slsvrr\nnMF4J2jy1HNYEo1V7HvS7wStZmGRPNYoiSTHvbk5Vm3ZCmE3Qzng/Sus19KN/B57\njkeOA8ObS5OXCjshZ+GrBmSnAzZjl+Gm6gQDKBk8/ilaSXH2QtCR4TQmvbsCjRFA\njoXcKvMh4SfnWGXC5XdkbVjXJuFSHHFNbHBCLygk/IJdbvEHQpPH4Rsqbc3f4TvL\n3ge/Jd6rm7huVlax3UMq7qUWTtb1PRjjSlrV0Tj5REv1KNe5VGvhMpQmHfJe7zd0\nBVbgi4I91QRJg9XF/dYXgm330skdSkM0UapBNo9xbgK3ejyNWG5aHcazO+DSdWNu\n5AbkXLB7m5djxb5ONrOYzz7llW4kg2H0zWNLFbRvdfKowdG906J4h9+6ZYhwufMa\ndVHS/5EyQbbwVeqe+MG0Qo8CAwEAAQ==\n-----END PUBLIC KEY-----\n","type":"CryptographicKey"},"type":"Person"} \ No newline at end of file diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/actor.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/actor.json new file mode 100644 index 000000000..7bc2b3fdf --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/actor.json @@ -0,0 +1,62 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/data-integrity/v1", + "https://w3id.org/security/multikey/v1", + "https://w3id.org/fep/ef61" + ], + "assertionMethod": [ + { + "controller": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "id": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#main-key", + "publicKeyMultibase": "z4MXj1wBzi9jUstyPQj1tJmBTCJQwSmgdEH3r3AcgJRwZBMkP3rY67NfsjsVyeRAH24e8frWsjLuhKJ3G9yRWp2R848U8Yeh8kNyR9GF2vmGEi6BHNEqhGnZMMQnAnLovqzQ7p9vfSsHUYU19yrzEwCSFumsDkk4np96HCjbkpejfNkDDAjPexavs9KSdovfFhJdb1uy4wcyG3ynZFSKsyPQyEUVFd72ufLKgG4h8j4fNHqwzvVQG1tRnqMqzFgS6uXJfftXGsAC6QVE5keYdicLvJ6n2t5UrCsVSeoMwgSuDpXVB8vXuhFkxNz4v2bKBHuHVUzA7cKWxoY5gaczcq4on1P23vsRbtxhkWUQgUA4KMenYWDLk", + "type": "Multikey" + }, + { + "controller": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "id": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#ed25519-key", + "publicKeyMultibase": "z6MknVDBdr3PRNFK35WPFbHxy7m5g18iuoSTht4vRwzt9WKq", + "type": "Multikey" + }, + { + "controller": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "id": "http://localhost:18498/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#fedify-rsa", + "publicKeyMultibase": "zgghBUVkqmWS8e1imM79CWx4zopmbKaBcdbLUSHjyo3KNnBVZscUs1T8HXSrY7yeSQJZSrrEjtnXq1tWc9fKL31uDYYbr8iSbtiRiXDxUQLA1ZDRH2tsz8a8PufoKK3w9qwNaxkcFVa5YKZ99ahxvvEJ86oDpPexr1HoE5wux1XihNx7kPtpJseQVKjTPYM1YcWe3SqDvy374ZaGFZx5YpxcVCr5gfF9iDHP8KWnYwWF3ge6icMQiqkiCZxsjeV8DL7ww7DJiQniYbk4qZ7mvcpqts657MPR7NWeFKim9wKy6mzaKEdDnkkVeTPbQYFgCUsZyrZcbBFTZp3YAnpTA2k4vmjBvKUyUKzrtXrJAuNgU7Y2cvdxRSCKorAJ38brzReEHA8Vwk72t9Le2P7PVqbUNScKt3L1v1pvQr28rim9Ff7uqPmK4R9j5FR7Tse4qq8zGoxYVAoH5isp9udJjLCs7BsF9MekS1D4aardVzMmqCzjiWCfjeUtTGdkqREsUkGyD3seFUGKui2aqafzVATZQCze4X3KcXL8vLWfq1W7VEx5HVCy5aCAV9E2VCUwimuUNfuSVYGaSY6S3XGXpMYCftak9VA4r22pZCCePC6fXwGhVNwo2mznyZNGbWc1fRLVCr45pS1RaXd58RrXWc2d4HcXdpsQ3XK6tiA4GJUe276bvKmktYKzcfn7KXs9ZHddFNe1SyctHP2JNL", + "type": "Multikey" + } + ], + "gateways": [ + "http://127.0.0.1:18497", + "http://localhost:18498" + ], + "id": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "inbox": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/inbox", + "name": "Fedify live portable client", + "outbox": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/outbox", + "preferredUsername": "fepsgnpakpb", + "proof": { + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + "https://www.w3.org/ns/did/v1", + "https://w3id.org/security/data-integrity/v1", + "https://w3id.org/security/multikey/v1", + "https://w3id.org/fep/ef61" + ], + "created": "2026-09-30T14:46:57.846825928Z", + "cryptosuite": "eddsa-jcs-2022", + "proofPurpose": "assertionMethod", + "proofValue": "z32F5XC6bGuzR6ZE5jCiKTQXcFm2F6fp7WLFWM69bkv7RDXSxe67fXjJXgtdLoQBYqsWnqZqczVvivhACfAYaj1kG", + "type": "DataIntegrityProof", + "verificationMethod": "did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB#z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB" + }, + "publicKey": { + "id": "http://localhost:18498/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#fedify-rsa", + "owner": "ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoSFdSVINqqwdCPZrEo8H\nqwx1bmlm/sT7RXpb53oDt0kWOnjhGrNnRSXa4PbHKCPH6yrzV3xGpmN1zVAXcShg\nu44m1NXbtBtfuEVHSOebRQWu2wyQRYlDk76MEyT33GDtNJf/4OnjnBXO71ebEFVY\nSKWkZacdS0Ft42sqvFaAK4/RDUEiUWE2t4YsEthT90fo+rXz/Snnv74p70eHnjD8\n6P29f8JKITTaqXp1ltuoiS9oEIFV/6FQ7HPMfzdBIgMvg/3pDDr1stFT56Slsvrr\nnMF4J2jy1HNYEo1V7HvS7wStZmGRPNYoiSTHvbk5Vm3ZCmE3Qzng/Sus19KN/B57\njkeOA8ObS5OXCjshZ+GrBmSnAzZjl+Gm6gQDKBk8/ilaSXH2QtCR4TQmvbsCjRFA\njoXcKvMh4SfnWGXC5XdkbVjXJuFSHHFNbHBCLygk/IJdbvEHQpPH4Rsqbc3f4TvL\n3ge/Jd6rm7huVlax3UMq7qUWTtb1PRjjSlrV0Tj5REv1KNe5VGvhMpQmHfJe7zd0\nBVbgi4I91QRJg9XF/dYXgm330skdSkM0UapBNo9xbgK3ejyNWG5aHcazO+DSdWNu\n5AbkXLB7m5djxb5ONrOYzz7llW4kg2H0zWNLFbRvdfKowdG906J4h9+6ZYhwufMa\ndVHS/5EyQbbwVeqe+MG0Qo8CAwEAAQ==\n-----END PUBLIC KEY-----\n", + "type": "CryptographicKey" + }, + "type": "Person" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/listener.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/listener.json new file mode 100644 index 000000000..6e9420f46 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/listener.json @@ -0,0 +1,5 @@ +{ + "type": "Create", + "id": "ap+ef61://did%3Akey%3Az6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/creates/1", + "actor": "ap+ef61://did%3Akey%3Az6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/metadata.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/metadata.json new file mode 100644 index 000000000..99cd3d082 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/metadata.json @@ -0,0 +1,28 @@ +{ + "implementation": "Mitra", + "version": "5.10.0", + "direction": "Mitra gateway to Fedify", + "capturedAt": "2026-09-30T14:47:04.185Z", + "source": { + "repository": "https://codeberg.org/silverpill/mitra", + "tag": "v5.10.0", + "commit": "17340ef09d4a902f301acdcfde094f5778d72f35", + "image": "codeberg.org/silverpill/mitra@sha256:4348ddea1d819f654cd3e6be4e955b3933d1d21807c6a9a8ef64eda4333f1d0a", + "binaryVersion": "mitra 5.10.0" + }, + "httpKeyId": "http://127.0.0.1:18497/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#main-key", + "sha256": { + "requestBody": "775a330bd8b4af20d4fffc12b0c033c3dc03febe47374b62e70a2f8d44aa37c9", + "actorBody": "f24c677b3854353c272c29164342f94f420b7570aaf2999d1ea179c7c24ba4bc" + }, + "proofProvenance": "The portable actor, Create, and Note DID proofs were produced by the Fedify C2S client; Mitra forwarded the activity and added its own gateway HTTP Signature. This does not demonstrate a Mitra-authored DID proof.", + "observed": { + "independentHttpSignatureVerified": true, + "fedifyInboxStatus": 202, + "fedifyListenerType": "Create" + }, + "replay": { + "httpTime": "Capture timestamp with normal verification time window", + "inboxTime": "HTTP timestamp disabled only for offline fixture replay; valid activity proofs bypass inbox HTTP signature verification" + } +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/raw-bodies.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/raw-bodies.json new file mode 100644 index 000000000..b60513240 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/raw-bodies.json @@ -0,0 +1,4 @@ +{ + "requestBody": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/multikey/v1\",\"https://w3id.org/fep/ef61\"],\"actor\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"id\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/creates/1\",\"object\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/multikey/v1\",\"https://w3id.org/fep/ef61\"],\"attributedTo\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"content\":\"

@alice Fedify to Mitra portable C2S live interop.

\",\"id\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/notes/1\",\"proof\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/multikey/v1\",\"https://w3id.org/fep/ef61\"],\"created\":\"2026-09-30T14:47:01.910135986Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z33dM5LxM7KnmoDjVMnYb44y8skPARP8qur6TiRDLr5P51SQZu3goY2JCVAFVLNjmnxE6dHPRRrcGW6qHr8vusyjt\",\"type\":\"DataIntegrityProof\",\"verificationMethod\":\"did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB#z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB\"},\"tag\":{\"href\":\"https://fedify.example:18444/users/alice\",\"name\":\"@alice\",\"type\":\"Mention\"},\"to\":[\"https://www.w3.org/ns/activitystreams#Public\",\"https://fedify.example:18444/users/alice\"],\"type\":\"Note\"},\"proof\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/multikey/v1\",\"https://w3id.org/fep/ef61\"],\"created\":\"2026-09-30T14:47:01.923062012Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z4AqgJsruzRmAz7JZdmTY5zRNXZknLomUgGNmN4jwwBZorMg19MurHvhsHaSfW6Uooc5zXSTRZZK4T6uaLc4hJoL1\",\"type\":\"DataIntegrityProof\",\"verificationMethod\":\"did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB#z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB\"},\"to\":[\"https://www.w3.org/ns/activitystreams#Public\",\"https://fedify.example:18444/users/alice\"],\"type\":\"Create\"}", + "actorBody": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/multikey/v1\",\"https://w3id.org/fep/ef61\"],\"assertionMethod\":[{\"controller\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"id\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#main-key\",\"publicKeyMultibase\":\"z4MXj1wBzi9jUstyPQj1tJmBTCJQwSmgdEH3r3AcgJRwZBMkP3rY67NfsjsVyeRAH24e8frWsjLuhKJ3G9yRWp2R848U8Yeh8kNyR9GF2vmGEi6BHNEqhGnZMMQnAnLovqzQ7p9vfSsHUYU19yrzEwCSFumsDkk4np96HCjbkpejfNkDDAjPexavs9KSdovfFhJdb1uy4wcyG3ynZFSKsyPQyEUVFd72ufLKgG4h8j4fNHqwzvVQG1tRnqMqzFgS6uXJfftXGsAC6QVE5keYdicLvJ6n2t5UrCsVSeoMwgSuDpXVB8vXuhFkxNz4v2bKBHuHVUzA7cKWxoY5gaczcq4on1P23vsRbtxhkWUQgUA4KMenYWDLk\",\"type\":\"Multikey\"},{\"controller\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"id\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#ed25519-key\",\"publicKeyMultibase\":\"z6MknVDBdr3PRNFK35WPFbHxy7m5g18iuoSTht4vRwzt9WKq\",\"type\":\"Multikey\"},{\"controller\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"id\":\"http://localhost:18498/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#fedify-rsa\",\"publicKeyMultibase\":\"zgghBUVkqmWS8e1imM79CWx4zopmbKaBcdbLUSHjyo3KNnBVZscUs1T8HXSrY7yeSQJZSrrEjtnXq1tWc9fKL31uDYYbr8iSbtiRiXDxUQLA1ZDRH2tsz8a8PufoKK3w9qwNaxkcFVa5YKZ99ahxvvEJ86oDpPexr1HoE5wux1XihNx7kPtpJseQVKjTPYM1YcWe3SqDvy374ZaGFZx5YpxcVCr5gfF9iDHP8KWnYwWF3ge6icMQiqkiCZxsjeV8DL7ww7DJiQniYbk4qZ7mvcpqts657MPR7NWeFKim9wKy6mzaKEdDnkkVeTPbQYFgCUsZyrZcbBFTZp3YAnpTA2k4vmjBvKUyUKzrtXrJAuNgU7Y2cvdxRSCKorAJ38brzReEHA8Vwk72t9Le2P7PVqbUNScKt3L1v1pvQr28rim9Ff7uqPmK4R9j5FR7Tse4qq8zGoxYVAoH5isp9udJjLCs7BsF9MekS1D4aardVzMmqCzjiWCfjeUtTGdkqREsUkGyD3seFUGKui2aqafzVATZQCze4X3KcXL8vLWfq1W7VEx5HVCy5aCAV9E2VCUwimuUNfuSVYGaSY6S3XGXpMYCftak9VA4r22pZCCePC6fXwGhVNwo2mznyZNGbWc1fRLVCr45pS1RaXd58RrXWc2d4HcXdpsQ3XK6tiA4GJUe276bvKmktYKzcfn7KXs9ZHddFNe1SyctHP2JNL\",\"type\":\"Multikey\"}],\"gateways\":[\"http://127.0.0.1:18497\",\"http://localhost:18498\"],\"id\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"inbox\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/inbox\",\"name\":\"Fedify live portable client\",\"outbox\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor/outbox\",\"preferredUsername\":\"fepsgnpakpb\",\"proof\":{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",\"https://www.w3.org/ns/did/v1\",\"https://w3id.org/security/data-integrity/v1\",\"https://w3id.org/security/multikey/v1\",\"https://w3id.org/fep/ef61\"],\"created\":\"2026-09-30T14:46:57.846825928Z\",\"cryptosuite\":\"eddsa-jcs-2022\",\"proofPurpose\":\"assertionMethod\",\"proofValue\":\"z32F5XC6bGuzR6ZE5jCiKTQXcFm2F6fp7WLFWM69bkv7RDXSxe67fXjJXgtdLoQBYqsWnqZqczVvivhACfAYaj1kG\",\"type\":\"DataIntegrityProof\",\"verificationMethod\":\"did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB#z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB\"},\"publicKey\":{\"id\":\"http://localhost:18498/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#fedify-rsa\",\"owner\":\"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor\",\"publicKeyPem\":\"-----BEGIN PUBLIC KEY-----\\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAoSFdSVINqqwdCPZrEo8H\\nqwx1bmlm/sT7RXpb53oDt0kWOnjhGrNnRSXa4PbHKCPH6yrzV3xGpmN1zVAXcShg\\nu44m1NXbtBtfuEVHSOebRQWu2wyQRYlDk76MEyT33GDtNJf/4OnjnBXO71ebEFVY\\nSKWkZacdS0Ft42sqvFaAK4/RDUEiUWE2t4YsEthT90fo+rXz/Snnv74p70eHnjD8\\n6P29f8JKITTaqXp1ltuoiS9oEIFV/6FQ7HPMfzdBIgMvg/3pDDr1stFT56Slsvrr\\nnMF4J2jy1HNYEo1V7HvS7wStZmGRPNYoiSTHvbk5Vm3ZCmE3Qzng/Sus19KN/B57\\njkeOA8ObS5OXCjshZ+GrBmSnAzZjl+Gm6gQDKBk8/ilaSXH2QtCR4TQmvbsCjRFA\\njoXcKvMh4SfnWGXC5XdkbVjXJuFSHHFNbHBCLygk/IJdbvEHQpPH4Rsqbc3f4TvL\\n3ge/Jd6rm7huVlax3UMq7qUWTtb1PRjjSlrV0Tj5REv1KNe5VGvhMpQmHfJe7zd0\\nBVbgi4I91QRJg9XF/dYXgm330skdSkM0UapBNo9xbgK3ejyNWG5aHcazO+DSdWNu\\n5AbkXLB7m5djxb5ONrOYzz7llW4kg2H0zWNLFbRvdfKowdG906J4h9+6ZYhwufMa\\ndVHS/5EyQbbwVeqe+MG0Qo8CAwEAAQ==\\n-----END PUBLIC KEY-----\\n\",\"type\":\"CryptographicKey\"},\"type\":\"Person\"}" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/request.body b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/request.body new file mode 100644 index 000000000..c95adbd02 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/request.body @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/multikey/v1","https://w3id.org/fep/ef61"],"actor":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","id":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/creates/1","object":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/multikey/v1","https://w3id.org/fep/ef61"],"attributedTo":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor","content":"

@alice Fedify to Mitra portable C2S live interop.

","id":"ap+ef61://did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/notes/1","proof":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/multikey/v1","https://w3id.org/fep/ef61"],"created":"2026-09-30T14:47:01.910135986Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z33dM5LxM7KnmoDjVMnYb44y8skPARP8qur6TiRDLr5P51SQZu3goY2JCVAFVLNjmnxE6dHPRRrcGW6qHr8vusyjt","type":"DataIntegrityProof","verificationMethod":"did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB#z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB"},"tag":{"href":"https://fedify.example:18444/users/alice","name":"@alice","type":"Mention"},"to":["https://www.w3.org/ns/activitystreams#Public","https://fedify.example:18444/users/alice"],"type":"Note"},"proof":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1","https://www.w3.org/ns/did/v1","https://w3id.org/security/data-integrity/v1","https://w3id.org/security/multikey/v1","https://w3id.org/fep/ef61"],"created":"2026-09-30T14:47:01.923062012Z","cryptosuite":"eddsa-jcs-2022","proofPurpose":"assertionMethod","proofValue":"z4AqgJsruzRmAz7JZdmTY5zRNXZknLomUgGNmN4jwwBZorMg19MurHvhsHaSfW6Uooc5zXSTRZZK4T6uaLc4hJoL1","type":"DataIntegrityProof","verificationMethod":"did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB#z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB"},"to":["https://www.w3.org/ns/activitystreams#Public","https://fedify.example:18444/users/alice"],"type":"Create"} \ No newline at end of file diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/request.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/request.json new file mode 100644 index 000000000..efde5f596 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/request.json @@ -0,0 +1,21 @@ +{ + "url": "https://fedify.example:18444/users/alice/inbox", + "method": "POST", + "headers": [ + ["accept", "*/*"], + ["content-length", "2409"], + [ + "content-type", + "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"" + ], + ["date", "Wed, 30 Sep 2026 14:47:04 GMT"], + ["digest", "SHA-256=d1ozC9i0ryDU//wSsMAzw9wD/r5HN0ti5wovjUSqN8k="], + ["host", "fedify.example:18444"], + [ + "signature", + "keyId=\"http://127.0.0.1:18497/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#main-key\",algorithm=\"rsa-sha256\",headers=\"(request-target) host date digest\",signature=\"PQHhIZUyBNsH779V+IB0Q08Pw8fsgq9RflyLExtYqNWwd/DXRyddBG1Y0RRCKrzigwFnW74rvuZpjU35gZzPaQA+TFxQvl8wBcPKLrYuc+NkIwGrCIpnFkUCglG6JagZ3cJfSqIB7DU7RIEvYfPjK9IchHug8ZghLnWhwLTE9UpKmtH/nJrU2Pd3n2Dn+EkfcYFe+n2KZxS7cjgPiRDRgei31WaCIIDRK4x7PvKq0VmrLwsNSKJzFsUp+KxiwoOHT1Ad9d6BPAJI8p+HqvWu0b2rMu4EK/nqHNwDYB7uYcundCYeQNI8wHmt2qxHxC2JuCuuV99WJxvXMSTbfUfgWg==\"" + ], + ["user-agent", "Mitra 5.10.0; http://127.0.0.1:18497"] + ], + "capturedAt": "2026-09-30T14:47:04.185Z" +} diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/response.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/response.json new file mode 100644 index 000000000..f7a3fd62a --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/response.json @@ -0,0 +1 @@ +{ "status": 202, "body": "" } diff --git a/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/verification.json b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/verification.json new file mode 100644 index 000000000..cd1545f50 --- /dev/null +++ b/packages/fedify/test-vectors/fep-ef61/mitra-v5.10.0/receive/verification.json @@ -0,0 +1,4 @@ +{ + "verified": true, + "key": "http://127.0.0.1:18497/.well-known/apgateway/did:key:z6MkuLKdSc7GHbgu9zDC8sZEjSbhAn7GzoHKXxsgsGNPakpB/actor#main-key" +} From 282c63812d13c1fd694cead1baf35a480c24d351 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 00:54:58 +0900 Subject: [PATCH 013/184] Give inbox completion one owner per delivery Remove completion arguments from the ingress observation runner so HTTP paths cannot invoke the request-finished callback before fetch finishes response decoration. Keep standalone handleInbox calls on an explicit runAndFinish path because they have no enclosing fetch boundary. Existing tests cover awaited completion, observer failures, preparation errors, portable inboxes, and final response decoration. All three runtime suites retain the delivery and reporting behavior. https://github.com/fedify-dev/fedify/pull/1201#discussion_r4146504899 Assisted-by: Codex:gpt-6.1-sol --- packages/fedify/src/federation/handler.ts | 2 +- .../src/federation/inbox-observation.ts | 31 ++++++++++++++++--- packages/fedify/src/federation/middleware.ts | 6 ---- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/packages/fedify/src/federation/handler.ts b/packages/fedify/src/federation/handler.ts index 3b503b66c..fa93aace4 100644 --- a/packages/fedify/src/federation/handler.ts +++ b/packages/fedify/src/federation/handler.ts @@ -1801,7 +1801,7 @@ export async function handleInbox( : "personal", recipient: options.recipient, }); - return await observation.run( + return await observation.runAndFinish( () => options.context, options.inboxRequestFinishedHandler, () => handleInbox(request, { ...options, observation }), diff --git a/packages/fedify/src/federation/inbox-observation.ts b/packages/fedify/src/federation/inbox-observation.ts index 316f1763d..576c1fe6c 100644 --- a/packages/fedify/src/federation/inbox-observation.ts +++ b/packages/fedify/src/federation/inbox-observation.ts @@ -49,9 +49,8 @@ export class InboxObservation { }; constructor(readonly inbox: InboxRequestReport["inbox"]) {} - async run( - getContext: () => RequestContext, - handler: InboxRequestFinishedHandler | undefined, + /** Run an ingress operation and project telemetry; fetch owns completion. */ + async run( operation: () => Promise, span?: Span, ): Promise { @@ -69,11 +68,35 @@ export class InboxObservation { outcome = { type: "exception", stage: this.stage, error }; } if (span != null) this.project(span, outcome); - await this.finish(getContext(), handler, outcome); if (threw) throw originalError; return response!; } + /** Complete standalone handler calls that have no enclosing fetch boundary. */ + async runAndFinish( + getContext: () => RequestContext, + handler: InboxRequestFinishedHandler | undefined, + operation: () => Promise, + ): Promise { + let response: Response; + try { + response = await this.run(operation); + } catch (error) { + await this.finish(getContext(), handler, { + type: "exception", + stage: this.stage, + error, + }); + throw error; + } + await this.finish(getContext(), handler, { + type: "response", + status: response.status, + ...this.result, + }); + return response; + } + project(span: Span, outcome?: InboxRequestOutcome): void { span.setAttribute( "activitypub.authentication.status", diff --git a/packages/fedify/src/federation/middleware.ts b/packages/fedify/src/federation/middleware.ts index 57e243919..414c0c3a0 100644 --- a/packages/fedify/src/federation/middleware.ts +++ b/packages/fedify/src/federation/middleware.ts @@ -3504,8 +3504,6 @@ export class FederationImpl }); this.#setInboxCompletion(metricState, observation, () => context); return await observation.run( - () => context, - undefined, async () => { if (routeName === "inbox") { context = this.#createContext(request, contextData, { @@ -4109,8 +4107,6 @@ export class FederationImpl const observation = new InboxObservation(inbox); this.#setInboxCompletion(metricState, observation, () => context); return await observation.run( - () => context, - undefined, () => Promise.reject(error), span, ); @@ -4224,8 +4220,6 @@ export class FederationImpl }); this.#setInboxCompletion(metricState, observation, () => context); return await observation.run( - () => context, - undefined, async () => { // The actor is looked up only by its identifier, as for ordinary inbox // deliveries, so that the identifier alone determines the recipient, From d4a64bae0534fd28d3788275b08fe726cded13f6 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 01:20:28 +0900 Subject: [PATCH 014/184] Keep verification telemetry references aligned Derive metric failure reasons from the observation reason types so new reasons cannot leave the metric definition behind. Document the inbox span attributes and object verification span in the operator reference, including the separate values used for final inbox authentication. Package checks, the 37 metric tests, Markdown checks, and the production documentation build pass. https://github.com/fedify-dev/fedify/pull/1201#discussion_r4146789635 https://github.com/fedify-dev/fedify/pull/1201#discussion_r4146789658 Changelog: none Assisted-by: Codex:gpt-6.1-sol --- docs/manual/opentelemetry.md | 156 +++++++++++----------- packages/fedify/src/federation/metrics.ts | 13 +- 2 files changed, 86 insertions(+), 83 deletions(-) diff --git a/docs/manual/opentelemetry.md b/docs/manual/opentelemetry.md index 7adff4ac8..894bc9030 100644 --- a/docs/manual/opentelemetry.md +++ b/docs/manual/opentelemetry.md @@ -233,6 +233,7 @@ spans: | `ld_signatures.verify` | Internal | Verifies the Linked Data signature. | | `object_integrity_proofs.sign` | Internal | Makes the object integrity proof. | | `object_integrity_proofs.verify` | Internal | Verifies the object integrity proof. | +| `object_integrity_proofs.verify_object` | Internal | Verifies an object's proofs and attribution. | | `webfinger.handle` | Server | Handles the WebFinger request. | | `webfinger.lookup` | Client | Looks up the WebFinger resource. | @@ -979,82 +980,85 @@ for ActivityPub as of November 2024. However, Fedify provides a set of semantic [attributes] for ActivityPub. The following table shows the semantic attributes for ActivityPub: -| Attribute | Type | Description | Example | -| -------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | -| `activitypub.activity.id` | string | The URI of the activity object. | `"https://example.com/activity/1"` | -| `activitypub.activity.type` | string[] | The qualified URI(s) of the activity type(s). | `["https://www.w3.org/ns/activitystreams#Create"]` | -| `activitypub.activity.to` | string[] | The URI(s) of the recipient collections/actors of the activity. | `["https://example.com/1/followers/2"]` | -| `activitypub.activity.cc` | string[] | The URI(s) of the carbon-copied recipient collections/actors of the activity. | `["https://www.w3.org/ns/activitystreams#Public"]` | -| `activitypub.activity.bto` | string[] | The URI(s) of the blind recipient collections/actors of the activity. | `["https://example.com/1/followers/2"]` | -| `activitypub.activity.bcc` | string[] | The URI(s) of the blind carbon-copied recipient collections/actors of the activity. | `["https://www.w3.org/ns/activitystreams#Public"]` | -| `activitypub.activity.retries` | int | The ordinal number of activity resending attempt (if and only if it's retried). | `3` | -| `activitypub.delivery.attempt` | int | The zero-based delivery attempt number for a queued outgoing activity. | `0` | -| `activitypub.delivery.permanent_failure` | boolean | Whether an outgoing delivery failure will be abandoned instead of retried. | `true` | -| `activitypub.circuit_breaker.previous_state` | string | Previous queued outbox circuit breaker state: `closed`, `open`, or `half_open`. | `"closed"` | -| `activitypub.circuit_breaker.state` | string | Current queued outbox circuit breaker state: `closed`, `open`, or `half_open`. | `"open"` | -| `activitypub.processing.result` | string | Lifecycle outcome of an inbox or outbox activity: `queued`, `processed`, `retried`, `rejected`, or `abandoned`. | `"retried"` | -| `activitypub.actor.discovery.result` | string | Terminal outcome of `getActorHandle()`: `resolved`, `not_found`, or `error`. | `"resolved"` | -| `activitypub.actor.id` | string | The URI of the actor object. | `"https://example.com/actor/1"` | -| `activitypub.actor.key.cached` | boolean | Whether the actor's public keys are cached. | `true` | -| `activitypub.actor.type` | string[] | The qualified URI(s) of the actor type(s). | `["https://www.w3.org/ns/activitystreams#Person"]` | -| `activitypub.key.id` | string | The URI of the cryptographic key being verified. | `"https://example.com/actor/1#main-key"` | -| `activitypub.key_ownership.method` | string | The method used to verify key ownership (`key_owner`, `actor_fetch`, or `none`). | `"actor_fetch"` | -| `activitypub.key_ownership.verified` | boolean | Whether the key ownership was successfully verified. | `true` | -| `activitypub.collection.id` | string | The URI of the collection object. | `"https://example.com/collection/1"` | -| `activitypub.collection.kind` | string | The bounded collection kind: `inbox`, `outbox`, `following`, `followers`, `liked`, `featured`, `featured_tags`, or `custom`. | `"followers"` | -| `activitypub.collection.page` | boolean | Whether the collection request targets a cursor page rather than the collection object. | `false` | -| `activitypub.collection.result` | string | Terminal collection request outcome: `served`, `not_found`, `not_acceptable`, `unauthorized`, or `error`. | `"served"` | -| `activitypub.collection.type` | string[] | The qualified URI(s) of the collection type(s). | `["https://www.w3.org/ns/activitystreams#OrderedCollection"]` | -| `activitypub.collection.total_items` | int | The total number of items in the collection. | `42` | -| `activitypub.object.id` | string | The URI of the object or the object enclosed by the activity. | `"https://example.com/object/1"` | -| `activitypub.object.type` | string[] | The qualified URI(s) of the object type(s). | `["https://www.w3.org/ns/activitystreams#Note"]` | -| `activitypub.object.in_reply_to` | string[] | The URI(s) of the original object to which the object reply. | `["https://example.com/object/1"]` | -| `activitypub.inboxes` | int | The number of inboxes the activity is sent to. | `12` | -| `activitypub.remote.host` | string | The host of the remote ActivityPub server, including any non-default port. | `"example.com:8443"` | -| `activitypub.shared_inbox` | boolean | Whether the activity is sent to the shared inbox. | `true` | -| `docloader.context_url` | string | The URL of the JSON-LD context document (if provided via Link header). | `"https://www.w3.org/ns/activitystreams"` | -| `docloader.document_url` | string | The final URL of the fetched document (after following redirects). | `"https://example.com/object/1"` | -| `fedify.actor.identifier` | string | The identifier of the actor. | `"1"` | -| `fedify.endpoint` | string | The bounded endpoint category that classified an inbound HTTP request handled by `Federation.fetch()`. | `"actor"` | -| `fedify.federation.instance_id` | string | Opaque per-Federation instance identifier used to distinguish queue depth series on a shared `MeterProvider`. | `"fedify-1"` | -| `fedify.route.template` | string | The matched URI Template, with parameter names (not values). | `"/users/{identifier}"` | -| `fedify.inbox.recipient` | string | The identifier of the inbox recipient. | `"1"` | -| `fedify.object.type` | string | The URI of the object type. | `"https://www.w3.org/ns/activitystreams#Note"` | -| `fedify.object.values.{parameter}` | string[] | The argument values of the object dispatcher. | `["1", "2"]` | -| `fedify.collection.dispatcher` | string | The collection dispatcher family: `built_in` or `custom`. | `"built_in"` | -| `fedify.collection.cursor` | string | The cursor of the collection. | `"eyJpZCI6IjEiLCJ0eXBlIjoiT3JkZXJlZENvbGxlY3Rpb24ifQ=="` | -| `fedify.collection.items` | number | The number of materialized items in the collection response or page. It can be less than the total items. | `10` | -| `fedify.queue.role` | string | The Fedify queue role: `inbox`, `outbox`, `fanout`, or `shared` for queue depth rows where one queue backs multiple roles. | `"outbox"` | -| `fedify.queue.backend` | string | The queue implementation's constructor name (best-effort backend identifier). | `"RedisMessageQueue"` | -| `fedify.queue.native_retrial` | boolean | Whether the queue backend declares `nativeRetrial`, meaning Fedify defers retry handling to the backend. | `true` | -| `fedify.queue.depth.state` | string | Queue depth count kind: `queued`, `ready`, or `delayed`. | `"queued"` | -| `fedify.queue.roles` | string | Comma-separated queue roles when one queue instance backs multiple roles. | `"fanout,inbox,outbox"` | -| `fedify.queue.task.attempt` | int | The zero-based attempt number recorded on `fedify.queue.task.enqueued`; non-zero for retry re-enqueues. | `1` | -| `fedify.queue.task.result` | string | The terminal outcome of queue task processing: `completed`, `failed`, or `aborted`. | `"failed"` | -| `fedify.task.name` | string | The name of a custom background task: always on the `fedify.task` span; on the task's `fedify.queue.task.*` run metrics only for a registered task (omitted for an `unknown_task` drop, keeping cardinality bounded). | `"sendDigest"` | -| `fedify.task.attempt` | int | The zero-based attempt number of a custom background task, on the `fedify.task` span. | `0` | -| `fedify.task.failure_reason` | string | Why a custom background task failed: `deserialization`, `validation`, `unknown_task`, `handler`, or `retry_enqueue`. Set only on a terminal failure. | `"validation"` | -| `http.redirect.url` | string | The redirect URL when a document fetch results in a redirect. | `"https://example.com/new-location"` | -| `http.response.status_code` | int | The HTTP response status code. | `200` | -| `http_signatures.signature` | string | The signature of the HTTP request in hexadecimal. | `"73a74c990beabe6e59cc68f9c6db7811b59cbb22fd12dcffb3565b651540efe9"` | -| `http_signatures.algorithm` | string | The algorithm of the HTTP request signature. | `"rsa-sha256"` | -| `http_signatures.key_id` | string | The public key ID of the HTTP request signature. | `"https://example.com/actor/1#main-key"` | -| `http_signatures.verified` | boolean | Whether the HTTP request signature was verified successfully. | `false` | -| `http_signatures.failure_reason` | string | Why HTTP signature verification failed (`noSignature`, `invalidSignature`, or `keyFetchError`). | `"keyFetchError"` | -| `http_signatures.key_fetch_status` | int | The HTTP status code from a failed signing-key fetch, when available. | `410` | -| `http_signatures.key_fetch_error` | string | The error type from a non-HTTP signing-key fetch failure, when available. | `"TypeError"` | -| `http_signatures.digest.{algorithm}` | string | The digest of the HTTP request body in hexadecimal. The `{algorithm}` is the digest algorithm (e.g., `sha`, `sha-256`). | `"d41d8cd98f00b204e9800998ecf8427e"` | -| `ld_signatures.key_id` | string | The public key ID of the Linked Data signature. | `"https://example.com/actor/1#main-key"` | -| `ld_signatures.signature` | string | The signature of the Linked Data in hexadecimal. | `"73a74c990beabe6e59cc68f9c6db7811b59cbb22fd12dcffb3565b651540efe9"` | -| `ld_signatures.type` | string | The algorithm of the Linked Data signature. | `"RsaSignature2017"` | -| `object_integrity_proofs.cryptosuite` | string | The cryptographic suite of the object integrity proof. | `"eddsa-jcs-2022"` | -| `object_integrity_proofs.key_id` | string | The public key ID of the object integrity proof. | `"https://example.com/actor/1#main-key"` | -| `object_integrity_proofs.signature` | string | The integrity proof of the object in hexadecimal. | `"73a74c990beabe6e59cc68f9c6db7811b59cbb22fd12dcffb3565b651540efe9"` | -| `url.full` | string | The full URL being fetched by the document loader. | `"https://example.com/actor/1"` | -| `webfinger.handle.result` | string | Terminal outcome of an incoming WebFinger request: `resolved`, `invalid`, `not_found`, `tombstoned`, or `error`. | `"resolved"` | -| `webfinger.lookup.result` | string | Terminal outcome of an outgoing WebFinger lookup: `found`, `not_found`, `invalid`, `network_error`, or `error`. | `"found"` | -| `webfinger.resource` | string | The queried resource URI. | `"acct:fedify@hollo.social"` | -| `webfinger.resource.scheme` | string | The scheme of the queried resource URI. Metric attribute is bucketed to `acct`, `http`, `https`, `mailto`, or `other`. | `"acct"` | +| Attribute | Type | Description | Example | +| -------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- | +| `activitypub.activity.id` | string | The URI of the activity object. | `"https://example.com/activity/1"` | +| `activitypub.activity.type` | string[] | The qualified URI(s) of the activity type(s). | `["https://www.w3.org/ns/activitystreams#Create"]` | +| `activitypub.activity.to` | string[] | The URI(s) of the recipient collections/actors of the activity. | `["https://example.com/1/followers/2"]` | +| `activitypub.activity.cc` | string[] | The URI(s) of the carbon-copied recipient collections/actors of the activity. | `["https://www.w3.org/ns/activitystreams#Public"]` | +| `activitypub.activity.bto` | string[] | The URI(s) of the blind recipient collections/actors of the activity. | `["https://example.com/1/followers/2"]` | +| `activitypub.activity.bcc` | string[] | The URI(s) of the blind carbon-copied recipient collections/actors of the activity. | `["https://www.w3.org/ns/activitystreams#Public"]` | +| `activitypub.activity.retries` | int | The ordinal number of activity resending attempt (if and only if it's retried). | `3` | +| `activitypub.delivery.attempt` | int | The zero-based delivery attempt number for a queued outgoing activity. | `0` | +| `activitypub.delivery.permanent_failure` | boolean | Whether an outgoing delivery failure will be abandoned instead of retried. | `true` | +| `activitypub.circuit_breaker.previous_state` | string | Previous queued outbox circuit breaker state: `closed`, `open`, or `half_open`. | `"closed"` | +| `activitypub.circuit_breaker.state` | string | Current queued outbox circuit breaker state: `closed`, `open`, or `half_open`. | `"open"` | +| `activitypub.processing.result` | string | Lifecycle outcome of an inbox or outbox activity: `queued`, `processed`, `retried`, `rejected`, or `abandoned`. | `"retried"` | +| `activitypub.actor.discovery.result` | string | Terminal outcome of `getActorHandle()`: `resolved`, `not_found`, or `error`. | `"resolved"` | +| `activitypub.actor.id` | string | The URI of the actor object. | `"https://example.com/actor/1"` | +| `activitypub.actor.key.cached` | boolean | Whether the actor's public keys are cached. | `true` | +| `activitypub.actor.type` | string[] | The qualified URI(s) of the actor type(s). | `["https://www.w3.org/ns/activitystreams#Person"]` | +| `activitypub.key.id` | string | The URI of the cryptographic key being verified. | `"https://example.com/actor/1#main-key"` | +| `activitypub.key_ownership.method` | string | The method used to verify key ownership (`key_owner`, `actor_fetch`, or `none`). | `"actor_fetch"` | +| `activitypub.key_ownership.verified` | boolean | Whether the key ownership was successfully verified. | `true` | +| `activitypub.collection.id` | string | The URI of the collection object. | `"https://example.com/collection/1"` | +| `activitypub.collection.kind` | string | The bounded collection kind: `inbox`, `outbox`, `following`, `followers`, `liked`, `featured`, `featured_tags`, or `custom`. | `"followers"` | +| `activitypub.collection.page` | boolean | Whether the collection request targets a cursor page rather than the collection object. | `false` | +| `activitypub.collection.result` | string | Terminal collection request outcome: `served`, `not_found`, `not_acceptable`, `unauthorized`, or `error`. | `"served"` | +| `activitypub.collection.type` | string[] | The qualified URI(s) of the collection type(s). | `["https://www.w3.org/ns/activitystreams#OrderedCollection"]` | +| `activitypub.collection.total_items` | int | The total number of items in the collection. | `42` | +| `activitypub.object.id` | string | The URI of the object or the object enclosed by the activity. | `"https://example.com/object/1"` | +| `activitypub.object.type` | string[] | The qualified URI(s) of the object type(s). | `["https://www.w3.org/ns/activitystreams#Note"]` | +| `activitypub.object.in_reply_to` | string[] | The URI(s) of the original object to which the object reply. | `["https://example.com/object/1"]` | +| `activitypub.inboxes` | int | The number of inboxes the activity is sent to. | `12` | +| `activitypub.remote.host` | string | The host of the remote ActivityPub server, including any non-default port. | `"example.com:8443"` | +| `activitypub.shared_inbox` | boolean | Whether the activity is sent to the shared inbox. | `true` | +| `activitypub.authentication.status` | string | The final inbox authentication decision: `verified`, `rejected`, `skipped`, or `notDetermined`. | `"verified"` | +| `activitypub.inbox.disposition` | string | The inbox delivery outcome: `processed`, `enqueued`, `duplicate`, `unhandled`, `customResponse`, `rejected`, `failed`, or `exception`. | `"processed"` | +| `activitypub.verification.failure_reason` | string | The bounded failure reason. Signature/proof verification uses `invalidSignature`, `keyFetchError`, `noSignature`, `signatureVerificationFailed`, `uncoveredAttribution`, `missingOwner`, or `proofPolicy`. Rejected inbox authentication uses `verificationFailed`, `actorKeyMismatch`, `proofPolicy`, or `invalidNonce`. | `"invalidSignature"` | +| `docloader.context_url` | string | The URL of the JSON-LD context document (if provided via Link header). | `"https://www.w3.org/ns/activitystreams"` | +| `docloader.document_url` | string | The final URL of the fetched document (after following redirects). | `"https://example.com/object/1"` | +| `fedify.actor.identifier` | string | The identifier of the actor. | `"1"` | +| `fedify.endpoint` | string | The bounded endpoint category that classified an inbound HTTP request handled by `Federation.fetch()`. | `"actor"` | +| `fedify.federation.instance_id` | string | Opaque per-Federation instance identifier used to distinguish queue depth series on a shared `MeterProvider`. | `"fedify-1"` | +| `fedify.route.template` | string | The matched URI Template, with parameter names (not values). | `"/users/{identifier}"` | +| `fedify.inbox.recipient` | string | The identifier of the inbox recipient. | `"1"` | +| `fedify.object.type` | string | The URI of the object type. | `"https://www.w3.org/ns/activitystreams#Note"` | +| `fedify.object.values.{parameter}` | string[] | The argument values of the object dispatcher. | `["1", "2"]` | +| `fedify.collection.dispatcher` | string | The collection dispatcher family: `built_in` or `custom`. | `"built_in"` | +| `fedify.collection.cursor` | string | The cursor of the collection. | `"eyJpZCI6IjEiLCJ0eXBlIjoiT3JkZXJlZENvbGxlY3Rpb24ifQ=="` | +| `fedify.collection.items` | number | The number of materialized items in the collection response or page. It can be less than the total items. | `10` | +| `fedify.queue.role` | string | The Fedify queue role: `inbox`, `outbox`, `fanout`, or `shared` for queue depth rows where one queue backs multiple roles. | `"outbox"` | +| `fedify.queue.backend` | string | The queue implementation's constructor name (best-effort backend identifier). | `"RedisMessageQueue"` | +| `fedify.queue.native_retrial` | boolean | Whether the queue backend declares `nativeRetrial`, meaning Fedify defers retry handling to the backend. | `true` | +| `fedify.queue.depth.state` | string | Queue depth count kind: `queued`, `ready`, or `delayed`. | `"queued"` | +| `fedify.queue.roles` | string | Comma-separated queue roles when one queue instance backs multiple roles. | `"fanout,inbox,outbox"` | +| `fedify.queue.task.attempt` | int | The zero-based attempt number recorded on `fedify.queue.task.enqueued`; non-zero for retry re-enqueues. | `1` | +| `fedify.queue.task.result` | string | The terminal outcome of queue task processing: `completed`, `failed`, or `aborted`. | `"failed"` | +| `fedify.task.name` | string | The name of a custom background task: always on the `fedify.task` span; on the task's `fedify.queue.task.*` run metrics only for a registered task (omitted for an `unknown_task` drop, keeping cardinality bounded). | `"sendDigest"` | +| `fedify.task.attempt` | int | The zero-based attempt number of a custom background task, on the `fedify.task` span. | `0` | +| `fedify.task.failure_reason` | string | Why a custom background task failed: `deserialization`, `validation`, `unknown_task`, `handler`, or `retry_enqueue`. Set only on a terminal failure. | `"validation"` | +| `http.redirect.url` | string | The redirect URL when a document fetch results in a redirect. | `"https://example.com/new-location"` | +| `http.response.status_code` | int | The HTTP response status code. | `200` | +| `http_signatures.signature` | string | The signature of the HTTP request in hexadecimal. | `"73a74c990beabe6e59cc68f9c6db7811b59cbb22fd12dcffb3565b651540efe9"` | +| `http_signatures.algorithm` | string | The algorithm of the HTTP request signature. | `"rsa-sha256"` | +| `http_signatures.key_id` | string | The public key ID of the HTTP request signature. | `"https://example.com/actor/1#main-key"` | +| `http_signatures.verified` | boolean | Whether the HTTP request signature was verified successfully. | `false` | +| `http_signatures.failure_reason` | string | Why HTTP signature verification failed (`noSignature`, `invalidSignature`, or `keyFetchError`). | `"keyFetchError"` | +| `http_signatures.key_fetch_status` | int | The HTTP status code from a failed signing-key fetch, when available. | `410` | +| `http_signatures.key_fetch_error` | string | The error type from a non-HTTP signing-key fetch failure, when available. | `"TypeError"` | +| `http_signatures.digest.{algorithm}` | string | The digest of the HTTP request body in hexadecimal. The `{algorithm}` is the digest algorithm (e.g., `sha`, `sha-256`). | `"d41d8cd98f00b204e9800998ecf8427e"` | +| `ld_signatures.key_id` | string | The public key ID of the Linked Data signature. | `"https://example.com/actor/1#main-key"` | +| `ld_signatures.signature` | string | The signature of the Linked Data in hexadecimal. | `"73a74c990beabe6e59cc68f9c6db7811b59cbb22fd12dcffb3565b651540efe9"` | +| `ld_signatures.type` | string | The algorithm of the Linked Data signature. | `"RsaSignature2017"` | +| `object_integrity_proofs.cryptosuite` | string | The cryptographic suite of the object integrity proof. | `"eddsa-jcs-2022"` | +| `object_integrity_proofs.key_id` | string | The public key ID of the object integrity proof. | `"https://example.com/actor/1#main-key"` | +| `object_integrity_proofs.signature` | string | The integrity proof of the object in hexadecimal. | `"73a74c990beabe6e59cc68f9c6db7811b59cbb22fd12dcffb3565b651540efe9"` | +| `url.full` | string | The full URL being fetched by the document loader. | `"https://example.com/actor/1"` | +| `webfinger.handle.result` | string | Terminal outcome of an incoming WebFinger request: `resolved`, `invalid`, `not_found`, `tombstoned`, or `error`. | `"resolved"` | +| `webfinger.lookup.result` | string | Terminal outcome of an outgoing WebFinger lookup: `found`, `not_found`, `invalid`, `network_error`, or `error`. | `"found"` | +| `webfinger.resource` | string | The queried resource URI. | `"acct:fedify@hollo.social"` | +| `webfinger.resource.scheme` | string | The scheme of the queried resource URI. Metric attribute is bucketed to `acct`, `http`, `https`, `mailto`, or `other`. | `"acct"` | [attributes]: https://opentelemetry.io/docs/specs/otel/common/#attribute [OpenTelemetry Semantic Conventions]: https://opentelemetry.io/docs/specs/semconv/ diff --git a/packages/fedify/src/federation/metrics.ts b/packages/fedify/src/federation/metrics.ts index 4542b749a..794c8e5b0 100644 --- a/packages/fedify/src/federation/metrics.ts +++ b/packages/fedify/src/federation/metrics.ts @@ -11,6 +11,10 @@ import { } from "@opentelemetry/api"; import metadata from "../../deno.json" with { type: "json" }; import type { MessageQueue } from "./mq.ts"; +import type { + InboxSignatureFailureReason, + InboxVerificationFailureReason, +} from "../sig/verification.ts"; /** * The role of a queued task, derived from the queued message's `type` field. @@ -413,13 +417,8 @@ export interface SignatureVerificationExtraAttributes { failureReason?: HttpSignatureMetricFailureReason; /** Bounded diagnostic shared by signature mechanisms. */ verificationFailureReason?: - | "invalidSignature" - | "keyFetchError" - | "noSignature" - | "signatureVerificationFailed" - | "uncoveredAttribution" - | "missingOwner" - | "proofPolicy"; + | InboxSignatureFailureReason["type"] + | InboxVerificationFailureReason["type"]; } /** From 82b84ce0c0dd1b7a3f72bc7915d9191532ea1378 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 01:45:13 +0900 Subject: [PATCH 015/184] Clean up FEP-ef61 changelog entries and docs The FEP-ef61 work for Fedify 2.4 left about 30 changelog fragments per package, several of which described changes between unreleased states or contradicted later fragments, and documentation spread over many chapters with a few stale or wrong spots. This commit includes the following changes: - Consolidated the FEP-ef61 fragments into one "Added support for FEP-ef61 portable objects" entry per package, with nested items that describe only the behavior users will receive, and kept changes of existing behavior, e.g., to compatible identifiers, property accessors, and the Accept header of document loaders, as separate entries. CHANGES.md was regenerated with Sacho. - Added a "Running portable actors" walkthrough to the Portable objects chapter, which links to the existing sections, and replaced its stale "still in progress" list with an Interoperability section based on the tootik and Mitra tests. - Added a Portable actors section to the WebFinger chapter, fixed the Twoslash preamble in send.md that called new URL("ap://did:key:...") to use parseIri(), and updated FEDERATION.md, which still said that interoperability was being tested. - Added @since 2.4.0 and fuller JSDoc to parseJsonLdId(), parseIri(), formatIri(), haveSameIriOrigin(), isGatewayUrl(), parseGatewayUrl(), and DocumentLoaderOptions.suppressError. Closes https://github.com/fedify-dev/fedify/issues/1150 https://github.com/fedify-dev/fedify/issues/288 Assisted-by: Claude Code:claude-opus-5-5 Assisted-by: OpenCode:deepseek-flash Assisted-by: Codex:gpt-6.1-sol --- CHANGES.md | 1536 +++++++---------- FEDERATION.md | 6 +- changes.d/cli/portable-objects.md | 50 +- changes.d/fedify/compatible-id-documents.md | 69 - changes.d/fedify/compatible-id-publishing.md | 49 - changes.d/fedify/compound-portable-proofs.md | 37 - .../fedify/compound-proof-key-selection.md | 26 - changes.d/fedify/hashlink-media-serving.md | 24 - changes.d/fedify/imported-unreleased.md | 28 - .../outbox-portable-actor-references.md | 15 - changes.d/fedify/portable-actor-gateways.md | 20 - changes.d/fedify/portable-actor-uri.md | 35 - changes.d/fedify/portable-chain-verifiers.md | 41 - changes.d/fedify/portable-collection-trust.md | 21 - changes.d/fedify/portable-collections.md | 49 - changes.d/fedify/portable-delivery.md | 33 - changes.d/fedify/portable-dot-segments.md | 10 - changes.d/fedify/portable-gateway-keys.md | 93 - changes.d/fedify/portable-inbox.md | 56 - changes.d/fedify/portable-object-serving.md | 60 - changes.d/fedify/portable-objects.md | 362 ++++ changes.d/fedify/portable-parse-uri.md | 20 - changes.d/fedify/portable-route-activity.md | 20 - changes.d/fedify/portable-webfinger.md | 31 - .../fedify/signed-child-representation.md | 31 - changes.d/lint/portable-uri-mismatches.md | 12 +- changes.d/next/hashlink-media-requests.md | 2 +- .../testing/hashlink-media-dispatcher.md | 10 - changes.d/testing/is-signed-by-audience.md | 11 - changes.d/testing/portable-actor-uri.md | 12 - changes.d/testing/portable-chain-verifiers.md | 12 - changes.d/testing/portable-collection-uris.md | 12 - changes.d/testing/portable-gateway-keys.md | 11 - changes.d/testing/portable-inbox-uri.md | 11 - changes.d/testing/portable-mock-requests.md | 11 - changes.d/testing/portable-objects.md | 65 + changes.d/testing/portable-parse-uri.md | 12 - .../activitystreams-accept-header.md | 13 - .../vocab-runtime/compatible-ef61-ids.md | 18 - changes.d/vocab-runtime/gateway-hints.md | 17 - .../vocab-runtime/imported-unreleased.md | 53 - .../vocab-runtime/portable-chain-verifiers.md | 12 - .../vocab-runtime/portable-dot-segments.md | 11 - .../vocab-runtime/portable-object-verifier.md | 19 - changes.d/vocab-runtime/portable-objects.md | 126 ++ .../vocab-runtime/verified-portable-media.md | 13 - .../vocab/compatible-id-dereferencing.md | 41 - changes.d/vocab/compatible-id-documents.md | 15 - changes.d/vocab/imported-unreleased.md | 25 - changes.d/vocab/lookup-object-gateways.md | 13 - changes.d/vocab/portable-chain-verifiers.md | 47 - changes.d/vocab/portable-collection-trust.md | 22 - .../vocab/portable-gateway-dereferencing.md | 19 - changes.d/vocab/portable-inspection.md | 13 - changes.d/vocab/portable-objects.md | 163 ++ changes.d/vocab/portable-verifier-types.md | 10 - changes.d/vocab/portable-webfinger-lookup.md | 35 - changes.d/vocab/recipient-gateways.md | 14 - .../vocab/signed-child-representation.md | 12 - docs/manual/portable.md | 562 +++++- docs/manual/send.md | 21 +- docs/manual/vocab.md | 8 +- docs/manual/webfinger.md | 18 + packages/vocab-runtime/src/docloader.ts | 1 + packages/vocab-runtime/src/url.ts | 57 +- 65 files changed, 1979 insertions(+), 2302 deletions(-) delete mode 100644 changes.d/fedify/compatible-id-documents.md delete mode 100644 changes.d/fedify/compatible-id-publishing.md delete mode 100644 changes.d/fedify/compound-portable-proofs.md delete mode 100644 changes.d/fedify/compound-proof-key-selection.md delete mode 100644 changes.d/fedify/hashlink-media-serving.md delete mode 100644 changes.d/fedify/outbox-portable-actor-references.md delete mode 100644 changes.d/fedify/portable-actor-gateways.md delete mode 100644 changes.d/fedify/portable-actor-uri.md delete mode 100644 changes.d/fedify/portable-chain-verifiers.md delete mode 100644 changes.d/fedify/portable-collection-trust.md delete mode 100644 changes.d/fedify/portable-collections.md delete mode 100644 changes.d/fedify/portable-delivery.md delete mode 100644 changes.d/fedify/portable-dot-segments.md delete mode 100644 changes.d/fedify/portable-gateway-keys.md delete mode 100644 changes.d/fedify/portable-inbox.md delete mode 100644 changes.d/fedify/portable-object-serving.md create mode 100644 changes.d/fedify/portable-objects.md delete mode 100644 changes.d/fedify/portable-parse-uri.md delete mode 100644 changes.d/fedify/portable-route-activity.md delete mode 100644 changes.d/fedify/portable-webfinger.md delete mode 100644 changes.d/fedify/signed-child-representation.md delete mode 100644 changes.d/testing/hashlink-media-dispatcher.md delete mode 100644 changes.d/testing/is-signed-by-audience.md delete mode 100644 changes.d/testing/portable-actor-uri.md delete mode 100644 changes.d/testing/portable-chain-verifiers.md delete mode 100644 changes.d/testing/portable-collection-uris.md delete mode 100644 changes.d/testing/portable-gateway-keys.md delete mode 100644 changes.d/testing/portable-inbox-uri.md delete mode 100644 changes.d/testing/portable-mock-requests.md create mode 100644 changes.d/testing/portable-objects.md delete mode 100644 changes.d/testing/portable-parse-uri.md delete mode 100644 changes.d/vocab-runtime/activitystreams-accept-header.md delete mode 100644 changes.d/vocab-runtime/compatible-ef61-ids.md delete mode 100644 changes.d/vocab-runtime/gateway-hints.md delete mode 100644 changes.d/vocab-runtime/portable-chain-verifiers.md delete mode 100644 changes.d/vocab-runtime/portable-dot-segments.md delete mode 100644 changes.d/vocab-runtime/portable-object-verifier.md create mode 100644 changes.d/vocab-runtime/portable-objects.md delete mode 100644 changes.d/vocab-runtime/verified-portable-media.md delete mode 100644 changes.d/vocab/compatible-id-dereferencing.md delete mode 100644 changes.d/vocab/compatible-id-documents.md delete mode 100644 changes.d/vocab/lookup-object-gateways.md delete mode 100644 changes.d/vocab/portable-chain-verifiers.md delete mode 100644 changes.d/vocab/portable-collection-trust.md delete mode 100644 changes.d/vocab/portable-gateway-dereferencing.md delete mode 100644 changes.d/vocab/portable-inspection.md create mode 100644 changes.d/vocab/portable-objects.md delete mode 100644 changes.d/vocab/portable-verifier-types.md delete mode 100644 changes.d/vocab/portable-webfinger-lookup.md delete mode 100644 changes.d/vocab/recipient-gateways.md delete mode 100644 changes.d/vocab/signed-child-representation.md diff --git a/CHANGES.md b/CHANGES.md index 2eab6708a..4d1f54bfb 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,434 +10,295 @@ To be released. ### @fedify/fedify - - Added WebFinger support for [FEP-ef61] portable actors. When an actor - dispatcher returns an actor whose ID is an `ap:` or `ap+ef61:` URI, the - WebFinger response takes the domain of the actor's `acct:` URI from the - first gateway in its `gateways`, as FEP-ef61 requires, and its `self` - link is the actor's compatible identifier based on that gateway, e.g., - `https://example.com/.well-known/apgateway/did:key:z6Mk.../actor`, so - that software without portable ID support can fetch it. A portable - actor without a valid first gateway is not found. Existing - `mapHandle()` and `mapAlias()` callbacks work as before, and WebFinger - resources can now be `ap:` or `ap+ef61:` URIs, which are passed to - `mapAlias()`. To serve the actor itself at its compatible identifier, - register an object dispatcher for it. [[#288], [#837], [#1082]] - - - `Context.lookupObject()` now uses `verifyPortableObjectProof()` as its - new `verifyPortableObject` option by default, so it looks up - [FEP-ef61] portable objects, including portable actors found through - WebFinger, through their gateways and returns them only if they have - valid Object Integrity Proofs made by the DIDs in their IDs. - [[#288], [#837], [#1082]] - - - Actor dispatchers no longer log warnings that a portable actor's ID or - collection URIs do not match the URIs that `Context` builds, such as - `Context.getActorUri()`. [[#288], [#837], [#1082]] - - - Added delivery to [FEP-ef61] portable inboxes through the gateway endpoint, - e.g., `POST /.well-known/apgateway/did:key:z6Mk.../users/alice/inbox`. - Existing inbox listeners handle such a delivery with the path after the - DID, so the inbox path `/users/{identifier}/inbox` also receives - deliveries to the portable inbox - `ap+ef61://did:key:z6Mk.../users/alice/inbox`. Fedify accepts a delivery - only if the actor dispatcher returns, for the identifier, a portable actor - with the same DID whose `inbox` is the requested portable inbox and whose - `gateways` include this server; otherwise, it responds with - `404 Not Found`. Applications without portable actors are unaffected. - [[#288], [#839], [#1092]] - - - Fedify now forwards an activity delivered to a portable inbox to the same - inbox on the actor's other gateways, as FEP-ef61 recommends, if the - activity is authenticated by its own Object Integrity Proof or Linked Data - Signature. Each activity is forwarded to each gateway at most once, which - requires a `KvStore` that supports `cas()`; with other stores, Fedify logs - a warning and does not forward. Forwarded requests are signed with HTTP - Signatures by this server's gateway key for the actor if - `mapPortableActorId()` maps the recipient to the same portable actor and - the key pairs dispatcher returns an RSA key pair for it, and are sent - unsigned otherwise. An activity is not forwarded back to the gateway that - forwarded it if the delivery is signed by that gateway with its gateway - key for the actor, which costs fetching the actor document from that - gateway. Configure the `origin` option on gateways so that Fedify can - tell which gateway it is regardless of the `Host` header. - [[#288], [#839], [#1092], [#1100], [#1101], [#1104], [#1110]] - - - Added the `Context.getPortableInboxUri()` method, which builds the portable - inbox ID of an actor from the inbox path and a DID. Custom - implementations of the `Context` interface need to implement the new - method. [[#288], [#839], [#1092]] - - - Added the `FederationOptions.portableInboxForwarding` option, whose - `maxTargets`, `ttl`, and `deadline` properties change how many gateways - a delivery is forwarded to (10 by default; `0` turns off forwarding), how - long forwarded activities are remembered (30 days by default), and how - long a delivery waits for forwarding without an outbox queue, and for - identifying the gateway that forwarded it (10 seconds by default). - [[#288], [#839], [#1092], [#1101], [#1110]] - - - Added the `FederationKvPrefixes.portableInboxForwarding` option, the key - prefix for remembering forwarded activities, which defaults to - `["_fedify", "portableInboxForwarding"]`. [[#288], [#839], [#1092]] - - - Added delivery to [FEP-ef61] portable inboxes, i.e., `ap:` and `ap+ef61:` - URIs, to `Context.sendActivity()` and `InboxContext.forwardActivity()`. - They deliver an activity to the compatible identifier of such an inbox - on one of the recipient's gateways, e.g., - `https://gateway.example/.well-known/apgateway/did:key:z6Mk.../actor/inbox`. - The gateways are taken from the recipient's `gateways`, or, if it has no - valid gateway, from the `@gateway` location hints of the inbox URI, and - at most five of them are tried one after another until one accepts the - activity. Previously, such a delivery failed with - `UrlError: Unsupported protocol: ap+ef61:`. A recipient with no gateway - to deliver through is skipped with a warning. [[#288], [#1147], [#1180]] - - - A gateway that fails with a permanent failure status, such as - `404 Not Found`, is not tried again for the activity. If no gateway - accepts the activity, the whole round of gateways counts as one - attempt of the retry policy. - - - The `preferSharedInbox` option is ignored for recipients with portable - inboxes, the `excludeBaseUris` option is compared with the origins of - their gateways, and deliveries to a portable inbox are ordered by the - actor's DID when the `orderingKey` option is given. - - - Queue workers of older Fedify versions deliver queued activities to - portable inboxes only through the first gateway, so upgrade them - before the servers that enqueue deliveries. - - Added `onRequestFinished()` to observe every inbox delivery, including rejected requests and preparation errors, with signature/proof checks, actual verification keys, the final authentication decision, and the processing outcome. The callback is awaited independently of trace sampling, and its errors do not change delivery results. [[#1191], [#1201]] - - Added serving of [FEP-ef61] portable collections through the gateway - endpoint, e.g., - `GET /.well-known/apgateway/did:key:z6Mk.../users/alice/outbox`, by the - existing collection dispatchers, including the inbox collection, so that a - portable actor's outbox and other collections are no longer tied to a - single server. Fedify serves such a collection only if the actor whose - identifier is in its path is a portable actor under the requested DID whose - corresponding property, e.g., `outbox`, refers to the collection; otherwise - it responds with `404 Not Found`. The collection and its pages keep the - actor's form of the ID, a portable ID or a compatible identifier, identify - pages with the `cursor` query parameter, and have `attributedTo` set to the - actor. The collection's `authorize()` predicate is applied before anything - is dispatched. The collection itself is served without an Object Integrity - Proof, as FEP-ef61 allows, but it is refused with - `500 Internal Server Error` if it embeds a portable actor, activity, or - object without a valid proof made with a key of the DID in its ID. - Applications without portable actors are unaffected, except that their - actor dispatchers may be called for such requests. - [[#288], [#1111], [#1142]] - - - Added the `Context.getPortableOutboxUri()`, - `Context.getPortableFollowingUri()`, `Context.getPortableFollowersUri()`, - `Context.getPortableLikedUri()`, `Context.getPortableFeaturedUri()`, - `Context.getPortableFeaturedTagsUri()`, and - `Context.getPortableCollectionUri()` methods, which build the portable IDs - of an actor's collections and of custom collections from the same paths - as their non-portable counterparts and a DID. On a `RequestContext`, the - DID defaults to the one in the gateway request. Custom implementations of - the `Context` interface need to implement the new methods. - [[#288], [#1111], [#1142]] - - - Added the `CustomCollectionCallbackSetters.mapPortableOwner()` method and - the `PortableCollectionOwnerMapper` type. A custom collection is served - through the FEP-ef61 gateway endpoint only if this callback maps it to - a portable actor under the requested DID. [[#288], [#1111], [#1142]] - - - Changed the actor dispatcher to warn when a portable actor's collection - property is a portable ID or a compatible identifier that does not match - the one that the corresponding `Context.getPortable*Uri()` method builds, - as the gateway endpoint would not serve the collection. - [[#288], [#1111], [#1142]] - - - Added serving of [FEP-ef61] portable objects through the gateway endpoint, - e.g., `GET /.well-known/apgateway/did:key:z6Mk.../notes/123`. Existing - object dispatchers serve such a request with the path after the DID, so - the object dispatcher registered for `/notes/{id}` serves the portable - object `ap+ef61://did:key:z6Mk.../notes/123`. Fedify responds with - `404 Not Found` unless the dispatcher returns an object with that ID, and - refuses to serve a portable actor, activity, or object that does not have - an Object Integrity Proof made with a key of the DID. As FEP-ef61 - forbids gateways to serve a non-public object to anyone but its intended - audience, and a gateway may store objects that it did not create, Fedify - also responds with `404 Not Found` unless the object is publicly - addressed, i.e., its `to`, `cc`, `bto`, `bcc`, or `audience` has - the public collection, or is an actor. To serve non-public portable - objects to their audience, set an authorization predicate on the object - dispatcher, e.g., one that checks the request with the new - `RequestContext.isSignedByAudience()` method; the predicate then decides - who may retrieve the dispatcher's portable objects, and Fedify responds to - the requests that it allows with `Cache-Control: private`. Applications - that do not serve portable objects are unaffected, except that their - object dispatchers may be called for such requests. - [[#288], [#835], [#1076], [#1153], [#1183]] - - - Added the `RequestContext.isSignedByAudience()` method, which checks - whether the request is signed by an actor in the audience of an object, - comparing [FEP-ef61] portable IDs canonically, and the - `IsSignedByAudienceOptions` interface. Its `isMember` option checks - the members of collections such as followers, which Fedify cannot tell - by itself. Custom implementations of the `RequestContext` interface need - to implement the new method. [[#288], [#1153], [#1183]] - - - Added the `Context.getPortableObjectUri()` method, which builds the - portable ID of an object from its object dispatcher's path and a DID, - and the `RequestContext.portableRequest` property, which tells an object - dispatcher the DID and ID of the requested portable object. Custom - implementations of the `Context` interface need to implement the new - method. [[#288], [#835], [#1076]] - - - Added serving of tombstones of [FEP-ef61] portable objects and actors - through the gateway endpoint with `410 Gone`, as for ordinary objects, - so that other gateways and consumers can tell a deleted portable object - from one that the gateway never stored. A `Tombstone` that an object - dispatcher or the actor dispatcher returns for such a request is served - with `410 Gone` if its ID is the requested portable ID and it has - an Object Integrity Proof made with a key of the DID, and with - `404 Not Found` if it has no proof. Like other portable objects, - a tombstone from an object dispatcher without an authorization predicate - needs public addressing to be served. - [[#288], [#1113], [#1124], [#1153], [#1183]] - - - Added serving of resources addressed by [FEP-ef61] hashlinks, such as - media attached to portable objects, through the gateway endpoint, e.g., - `GET /.well-known/apgateway/hl:zQmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n`. - Register a dispatcher with the new - `Federatable.setHashlinkMediaDispatcher()` method; it receives the parsed - hashlink and its SHA-256 digest as a `HashlinkMediaRequest` object and - returns a `Response`, which Fedify sends as is so that it can be streamed, - or `null` for `404 Not Found`. Fedify responds with `400 Bad Request` to - malformed hashlinks without calling the dispatcher, and does not verify the - response body, so the dispatcher must serve only the resource whose bytes - hash to the requested digest. Applications that do not register the - dispatcher are unaffected. [[#288], [#838]] - - - Added `hashlink_media` to the values of the `fedify.endpoint` metric - attribute, used for requests to the hashlink media endpoint. - [[#288], [#838], [#1080]] - - - Added support for HTTP Signature keys that gateways use on behalf of - [FEP-ef61] portable actors, which Fedify calls *gateway keys*. Register - the new `ActorCallbackSetters.mapPortableActorId()` callback to tell - Fedify which actors are portable, and `Context.getActorKeyPairs()` then - identifies their dispatched key pairs by the actor's compatible identifier - on this server, e.g., - `https://example.com/.well-known/apgateway/did:key:z6Mk.../actors/alice#main-key`, - with the portable actor as their owner, and with the same IDs for their - `CryptographicKey` and `Multikey` forms so that they can be listed in the - actor's `assertionMethods` as FEP-ef61 requires. Requests made on behalf - of such actors, including activity deliveries and signed fetches, are - signed with these keys. The new `PortableActorIdMapper` type describes the - callback. [[#288], [#840], [#1099]] - - - Changed HTTP Signature verification to accept a gateway key of a portable - actor if the actor's document, fetched from the key ID, has a valid Object - Integrity Proof made by the actor's DID, embeds the key in its - `assertionMethod`, and lists the gateway in its `gateways`. Such a key is - owned by the portable actor, so `RequestContext.getSignedKeyOwner()`, - `getKeyOwner()`, and `doesActorOwnKey()` return or match the portable - actor. Given the very key that HTTP Signature verification returned, - they take the actor from the document it verified rather than fetching - and verifying the document again. The document may list the key under - the key ID itself or under the `ap:` URI with the same canonical ID, as - Mitra does, but not under both, nor under a compatible identifier on - another gateway. Previously, no gateway key of a portable actor could be - verified. [[#288], [#840], [#1096], [#1099], [#1123], [#1134], [#1164]] - - - Changed HTTP Signature verification to accept a key of a portable actor - itself whose ID is an `ap:` or `ap+ef61:` URI, e.g., - `ap://did:key:z6Mk.../actor?@gateway=https%3A%2F%2Fexample.com#main-key`. - Fedify fetches the actor's document from the gateways in the key ID's - `@gateway` location hints, or, without them, asks the document loader for - the `ap:` URI itself, and accepts the key if the document has a valid - Object Integrity Proof made by the actor's DID, embeds the key under - the `ap:` URI, and has a valid gateway. Since the signer chooses the - hints, only the first three are followed, and all the gateways share - a timeout of ten seconds; a lookup that runs out of time is reported as - a `keyFetchError` without an HTTP status. Such a key is used only for - HTTP Signatures, and is owned by the portable actor like a gateway key. - Keys at `ap:` URIs are never used to make Object Integrity Proofs or - Linked Data Signatures either. [[#288], [#1096], [#1132], [#1134], [#1165]] - - - Changed inboxes to reject activities of portable actors that do not have - a valid Object Integrity Proof made by the actor's DID with - `401 Unauthorized`, even if the request has a valid HTTP Signature or the - activity has a valid Linked Data Signature. [[#288], [#840], [#1099]] - - - Changed `Context.sendActivity()` so that keys whose IDs are FEP-ef61 - compatible identifiers, such as gateway keys, never make Object Integrity - Proofs or Linked Data Signatures; they only sign HTTP requests. Also, - activities of portable actors never get Linked Data Signatures, and have - to have portable IDs of the actors' DIDs, and an unsigned portable - activity is signed only by a key whose ID is a DID URL for its DID, even - if it is the only Ed25519 key. In these cases `sendActivity()` rejects - with a `TypeError` before anything is delivered or queued. Sign - portable activities with `signObject()` beforehand, or pass the DID's key - as an explicit sender key. [[#288], [#840], [#1099]] - - - Changed key lookups so that keys whose IDs are FEP-ef61 compatible - identifiers are cached apart for each purpose, as whether such a key is - valid depends on what it is used for: a gateway key cached for an HTTP - Signature is never used for an Object Integrity Proof or a Linked Data - Signature, and a key rejected for one of them is not rejected for - the others. A failure to fetch such a key, e.g., a network error or - `404 Not Found`, fails every purpose alike and is cached like that of any - other key. A gateway key is cached for an hour at most, and never - beyond the expiration of the proof on the actor's document, since - the actor can drop the gateway from its document at any time. - `fetchKey()` and `fetchKeyDetailed()` do not resolve gateway keys of - portable actors. - [[#288], [#840], [#1095], [#1099], [#1119]] - - - Only the key cache that Fedify's inbox uses caches keys at compatible - identifiers apart for each purpose. A custom `KeyCache` passed to - `verifyRequest()`, `fetchKey()`, and the like caches only the - failures to fetch them. - - - Added support for publishing [FEP-ef61] portable actors and objects whose - IDs are compatible identifiers, such as - `https://example.com/.well-known/apgateway/did:key:z6Mk.../actor`, for - interoperability with software that cannot handle `ap:` URIs. Fedify now - treats such an actor or object as portable wherever it publishes one, as - it already did for those with `ap:` or `ap+ef61:` IDs. Build compatible - identifiers with `toCompatibleEf61Id()` and the first gateway of the - actor before signing the documents; portable IDs remain the recommended - form. [[#288], [#1106], [#1109]] - - - `Context.sendActivity()` now requires an activity of an actor whose - ID is a compatible identifier to have an `ap:` or `ap+ef61:` ID or - a compatible identifier of the actor's DID, and signs an unsigned one - only with the key whose ID is a DID URL for that DID, instead of - sending activities that FEP-ef61 receivers reject. A malformed - compatible actor or activity ID, e.g., one with `@gateway` location - hints, is rejected with a `TypeError`. - - - The FEP-ef61 gateway endpoint now serves an object whose ID is - a compatible identifier of the requested portable object, on any - gateway, instead of responding with `404 Not Found`. - - - Portable inboxes now accept deliveries on behalf of actors whose IDs - or inboxes are compatible identifiers, and forward each activity to - the other gateways at most once whether its ID is an `ap:` URI or - a compatible identifier. - - - WebFinger now takes the domain of such an actor's address from its - first gateway, and uses its ID as the `self` link. - - - Actor dispatchers no longer warn that such an actor's ID or collection - URIs do not match the URIs that `Context` builds, but warn if its ID - is a malformed compatible identifier or is not on its first gateway, - as FEP-ef61 requires. - - - Fedify now warns when a served object, or a sent activity and its - embedded objects, use compatible identifiers away from the owner's - first gateway when that gateway is known locally. The warning does - not change what is served or sent. [[#1155], [#1188]] - - - Added the `Context.getPortableActorUri()` method, which builds the - [FEP-ef61] portable ID of an actor from its actor dispatcher's path and - a DID, e.g., `ap+ef61://did:key:z6Mk.../users/alice`. Like - `Context.getPortableObjectUri()`, the DID can be omitted while handling - a gateway request, in which case the DID in the request path is used. - Custom implementations of the `Context` interface need to implement the - new method. [[#288], [#841], [#1114]] - - - The actor dispatcher now serves portable actors through the FEP-ef61 - gateway endpoint, e.g., - `GET /.well-known/apgateway/did:key:z6Mk.../users/alice`, the same way - object dispatchers serve portable objects, so a portable actor whose ID - `Context.getPortableActorUri()` builds can be fetched at its compatible - identifier without registering an extra object dispatcher. The actor is - served only if its ID canonically equals the requested portable ID and it - has an Object Integrity Proof made with a key of the DID, and - `RequestContext.portableRequest` is set for such requests. Applications - that do not have portable actors are unaffected, except that their actor - dispatchers may be called for such requests. [[#288], [#841], [#1114]] - - - `Context.getPortableActorUri()`, `Context.getPortableObjectUri()`, and - `Context.getPortableInboxUri()` now throw a `TypeError` if the DID is - a `did:key` DID that is not encoded in base58-btc, as FEP-ef61 requires, - so that the same key does not yield two different portable IDs. Use - `exportDidKey()` from `@fedify/vocab-runtime` to make such DIDs. - Likewise, the gateway endpoint responds with `400 Bad Request` to - requests whose path has such a DID. [[#288], [#841], [#1114]] - - - Added the `Context.verifyPortableObject` property, the [FEP-ef61] - portable object policy of the context: `verifyPortableObject()` with the - context's document loader and context loader. Since it has the same name - as the `verifyPortableObject` option of property accessors, passing - a context as their options, e.g., `await create.getObject(ctx)`, now - verifies portable objects that they dereference. Previously, - `create.getObject(ctx)` on an activity whose ID is a compatible - identifier, such as one from tootik, fetched the object it refers to as - an ordinary HTTP(S) URL and trusted it because of its origin. Note that - this also applies to objects with ordinary HTTP(S) IDs: their references - to compatible identifiers are now verified as portable objects when you - pass a context. [[#288], [#1107], [#1120]] - - - Inboxes now parse received activities with `Context.verifyPortableObject` - as their default verifier, so accessors called without options in inbox - listeners, e.g., `await create.getObject()`, verify portable objects - too, including for queued activities and for activities authenticated - by Object Integrity Proofs. The activities passed to the - `onOutboxError` callback have the default as well. - [[#288], [#1107], [#1120]] - - - Changed `Context.lookupObject()` to use `Context.verifyPortableObject` - instead of `verifyPortableObjectProof()` as the default - `verifyPortableObject` option, so that it also accepts an unsecured - portable collection served by a gateway that its owner lists, as - accessors do. Pass `verifyPortableObject: verifyPortableObjectProof` to - accept only objects with proofs. The returned object uses the policy by - default for its property accessors. `Context.traverseCollection()` also - uses `Context.verifyPortableObject` by default. [[#288], [#1107], [#1120]] - - - Added the `verifyPortableObject` option to `VerifyObjectOptions`. It is - not used to verify the given object; the returned object uses it by - default for its property accessors. [[#288], [#1107], [#1120]] - - - Added the `portable` option to `Context.parseUri()`, and the - `ParseUriOptions` interface. With `{ portable: true }`, the method also - recognizes [FEP-ef61] portable IDs, e.g., - `ap+ef61://did:key:z6Mk.../users/alice`, and their compatible identifiers - on any gateway by the same paths through which the gateway endpoint serves - them, so that an inbox listener can tell that an activity is about one of - its portable actors, objects, or collections. The result then has the DID - of the ID in its new `authority` property. Since anyone can make - a portable ID with the same path under another DID, check that - `authority` is the DID that you store for the actor or object before - acting on the result. Without the option, `parseUri()` behaves as - before. [[#288], [#1143], [#1145]] - - - Added validation of the `gateways` of [FEP-ef61] portable actors, which - FEP-ef61 requires to be a non-empty list of HTTP(S) URIs with an empty - path, query, and fragment. `verifyPortableObjectProof()` and - `verifyPortableObject()` now reject a portable actor whose `gateways` is - missing or empty, or has any other item, with the new `invalidGateways` - reason, even if its proofs are valid, so such an actor is no longer looked - up, accepted in an inbox, or served through the gateway endpoint. If an - actor dispatcher returns a portable actor with such `gateways`, Fedify - logs a warning. An incoming activity that embeds an actor with a gateway - that has a path, query, or fragment is now rejected with - `400 Bad Request` as malformed, instead of failing with an error. - [[#288], [#1148], [#1178]] - - - Added `verifyPortableObject()`, which applies the [FEP-ef61] trust policy - to portable objects fetched through gateways. It verifies Object - Integrity Proofs like `verifyPortableObjectProof()`, and also accepts - a portable collection or collection page without a proof if it was - served by a gateway listed in the `gateways` of the actor that owns it. - The owner must be the actor whose `inbox`, `outbox`, `followers`, - `following`, or `liked` it is, as confirmed by the owner's signed actor - document. Pass it as the `verifyPortableObject` option of property - accessors and `traverseCollection()` instead of - `verifyPortableObjectProof()` to read portable actors' collections, such - as their outboxes. The new `VerifyPortableObjectOptions`, - `VerifyPortableObjectResult`, and `VerifyPortableObjectFailureReason` - types describe it. [[#288], [#836], [#1084]] + - Added support for [FEP-ef61] portable objects, whose IDs are `ap:` or + `ap+ef61:` URIs with a DID instead of a host, e.g., + `ap://did:key:z6Mk.../actor`. A Fedify server can now act as a gateway for + portable actors: it serves their actor documents, objects, collections, and + hashlink media, accepts deliveries to their inboxes, and sends their + activities. It can also consume the portable objects of others. The new + [*Portable objects*] chapter of the manual walks through + running portable actors, and describes the FEP-ef61 profile that Fedify + supports, including where it deliberately differs from the FEP and what it + does not implement. Applications without portable actors are unaffected, + except that their dispatchers may be called for requests to the gateway + endpoint, */.well-known/apgateway/*, and that `Context.sendActivity()` may + reject activities that embed others' portable objects (see below). + [[#288], [#1151], [#1198]] + + - Added `verifyPortableObjectProof()`, which enforces the FEP-ef61 proof + policy: a portable actor, activity, or object needs an [FEP-8b32] + Object Integrity Proof whose `verificationMethod` is a DID URL of + the DID in its ID, and a portable actor needs a non-empty `gateways` + list of HTTP(S) origins. A document whose ID is a compatible + identifier, e.g., + `https://gw.example/.well-known/apgateway/did:key:z6Mk.../actor`, is + verified against the DID in it. Its detailed result distinguishes + documents outside the policy, unsecured collections, missing or invalid + proofs, invalid gateways, unsupported verification methods, and DID + mismatches. [[#832], [#968], [#1093], [#1105], [#1148], [#1178]] + + - Added `verifyPortableObject()`, which verifies proofs like + `verifyPortableObjectProof()`, and also accepts an actor's `inbox`, + `outbox`, `followers`, `following`, or `liked` collection without + a proof if a gateway that the actor lists served it, as FEP-ef61 + allows. The `VerifyPortableObjectOptions`, + `VerifyPortableObjectResult`, and `VerifyPortableObjectFailureReason` + types describe it. [[#836], [#1084], [#1093], [#1105]] + + - Added the `Context.verifyPortableObject` property, which is + `verifyPortableObject()` with the context's loaders. Since it has + the same name as the option of property accessors, passing a context + as their options, e.g., `await create.getObject(ctx)`, verifies + portable objects. Inboxes use it as the default verifier of received + activities, as do `Context.lookupObject()`, + `Context.traverseCollection()`, and the `onOutboxError` callback. + Added the `verifyPortableObject` option to `VerifyObjectOptions`. + [[#1107], [#1120]] + + - `verifyProof()` now resolves Ed25519 `did:key` verification methods, + e.g., `did:key:z6Mk...#z6Mk...`, locally without fetching them, and + `verifyObject()` accepts a proof made by a DID as authenticating + an actor or attribution whose portable ID or compatible identifier + has that DID. [[#827], [#829], [#915], [#926], [#1093], [#1105]] + + - Added the `Context.getPortableActorUri()`, + `Context.getPortableObjectUri()`, `Context.getPortableInboxUri()`, + `Context.getPortableOutboxUri()`, `Context.getPortableFollowingUri()`, + `Context.getPortableFollowersUri()`, `Context.getPortableLikedUri()`, + `Context.getPortableFeaturedUri()`, + `Context.getPortableFeaturedTagsUri()`, and + `Context.getPortableCollectionUri()` methods, which build portable IDs + from the paths of the corresponding dispatchers and a DID. Custom + implementations of the `Context` interface need to implement them. + [[#835], [#839], [#841], [#1076], [#1092], [#1111], [#1114], [#1142]] + They throw a `TypeError` for a `did:key` DID that is not encoded in + base58-btc, as FEP-ef61 requires, or for an identifier that has + a `.` or `..` path segment. [[#841], [#1114], [#1154], [#1186]] + + - Added the `portable` option to `Context.parseUri()` and + the `ParseUriOptions` interface. With `{ portable: true }`, + the method also recognizes portable IDs and their compatible + identifiers, and the result has the DID in its new `authority` + property. [[#1143], [#1145]] + + - Object dispatchers and the actor dispatcher now serve portable objects + and actors through the gateway endpoint, e.g., + `GET /.well-known/apgateway/did:key:z6Mk.../notes/123`, with the path + after the DID. An object is served only if its ID canonically equals + the requested portable ID and it has a proof made with a key of + the DID. A non-public object is served only if the dispatcher has + an authorization predicate, as FEP-ef61 forbids gateways to serve it + to anyone but its audience. Signed tombstones are served with + `410 Gone`. Added the `RequestContext.portableRequest` property, + which tells the dispatcher the requested DID and ID. + [[#835], [#841], [#1076], [#1113], [#1114], [#1124], [#1153], [#1183]] + + - Added the `RequestContext.isSignedByAudience()` method and + the `IsSignedByAudienceOptions` interface, which check whether + a request is signed by an actor in the audience of an object, e.g., + in the authorization predicate of an object dispatcher. Custom + implementations of the `RequestContext` interface need to implement + the method. [[#1153], [#1183]] + + - Collection dispatchers now serve the collections of portable actors + through the gateway endpoint, e.g., + `GET /.well-known/apgateway/did:key:z6Mk.../users/alice/outbox`, if + the actor is a portable actor under the requested DID whose + corresponding property refers to the collection. Added + the `CustomCollectionCallbackSetters.mapPortableOwner()` method and + the `PortableCollectionOwnerMapper` type, which tie a custom + collection to its portable owner. [[#1111], [#1142]] + + - Added `Federatable.setHashlinkMediaDispatcher()` and + the `HashlinkMediaRequest` interface, which serve resources that + portable objects refer to with SHA-256 hashlinks, e.g., + `GET /.well-known/apgateway/hl:zQm...`. Fedify does not verify the + dispatcher's response against the digest. Added `hashlink_media` to + the values of the `fedify.endpoint` metric attribute. + [[#838], [#1080]] + + - Inbox listeners now accept deliveries to portable inboxes through + the gateway endpoint, e.g., + `POST /.well-known/apgateway/did:key:z6Mk.../users/alice/inbox`, if + the actor dispatcher returns a portable actor whose `inbox` is + the requested inbox and whose `gateways` include this server. + [[#839], [#1092]] + + - Fedify now forwards an activity delivered to a portable inbox to + the actor's other gateways at most once, as FEP-ef61 recommends, if + the activity is authenticated by its own proof or Linked Data + Signature and the `KvStore` supports `cas()`. Forwarded requests are + signed with this server's RSA gateway key for the actor if the key + pairs dispatcher returns one, and are sent unsigned otherwise. An + activity is not forwarded back to the gateway that forwarded it if + Fedify can identify that gateway by its gateway key signature on the + delivery. Added the `FederationOptions.portableInboxForwarding` and + `FederationKvPrefixes.portableInboxForwarding` options. + [[#839], [#1092], [#1100], [#1101], [#1104], [#1110]] + + - `Context.sendActivity()` and `InboxContext.forwardActivity()` now + deliver to portable inboxes through the recipient's gateways, or else + the `@gateway` location hints of the inbox, trying at most five of + them until one accepts the activity. Previously, such a delivery + failed with `UrlError: Unsupported protocol: ap+ef61:`. Queue + workers of older Fedify versions deliver such queued activities only + through the first gateway, so upgrade them before the servers that + enqueue deliveries. [[#1147], [#1180]] + + - Added the `ActorCallbackSetters.mapPortableActorId()` method and + the `PortableActorIdMapper` type. For an actor that the callback + maps to a portable ID, `Context.getActorKeyPairs()` identifies its key + pairs by the actor's compatible identifier on this server, e.g., + `https://example.com/.well-known/apgateway/did:key:z6Mk.../users/alice#main-key`, + so that they serve as this server's *gateway keys* for the actor, which + sign HTTP requests made on behalf of the actor, but never make Object + Integrity Proofs or Linked Data Signatures. [[#840], [#1099]] + + - HTTP Signature verification now accepts a gateway key of a portable + actor if the actor document at the key ID has a valid proof by + the actor's DID, embeds the key in its `assertionMethod`, or else in + its `publicKey`, and lists the gateway in its `gateways`. Such a key + is owned by the portable actor, so + `RequestContext.getSignedKeyOwner()`, `getKeyOwner()`, and + `doesActorOwnKey()` return or match the actor. Keys at compatible + identifiers are cached apart for each purpose, for an hour at most. + [[#840], [#1095], [#1099], [#1105], [#1119], [#1123], [#1164]] + A key at an `ap:` key ID is accepted likewise if an actor document + fetched through the key ID's location hints vouches for it. + [[#1096], [#1132], [#1134], [#1165]] + + - Inboxes accept an activity of a portable actor, or an activity with + a portable ID, only if it has a valid proof made by the DID of that + ID; an HTTP Signature or a Linked Data Signature does not + authenticate it, and such an activity is rejected with + `401 Unauthorized`. [[#840], [#1099]] + + - Inboxes independently verify each portable actor, activity, and + object embedded in a compound document, e.g., the `Note` in + a `Create`, against its own proof before dispatch, following Fedify's + interim *map-local* profile, since neither FEP-8b32 nor Verifiable + Credential Data Integrity defines the boundaries of embedded proofs + yet. A valid outer proof does not authenticate an unsigned or invalid + embedded portable object. Documents with proof sets, or that exceed + the traversal limits, are rejected. A key embedded in a verified + portable actor needs no proof of its own if the key's ID is the actor's + ID plus a fragment. This profile may change in Fedify 3.0. + [[#938], [#1041], [#1094], [#1102], [#1133], [#1138]] + + - `Context.sendActivity()` gives an activity that contains portable + objects at most one proof: an activity that already has one is sent + as is, and a portable activity is signed only by the key whose ID is + a DID URL for its DID. An activity of a portable actor has to have + a portable ID or a compatible identifier of the actor's DID, and never + gets a Linked Data Signature. Otherwise, `sendActivity()` rejects with + a `TypeError` before anything is delivered or queued. So does a + non-portable activity that embeds portable objects, including ones with + compatible identifiers, when several Ed25519 keys are available, and an + activity with portable objects in which any map carries a proof set. + Sign portable activities with `signObject()` beforehand, or pass the + DID's key as an explicit sender key. + [[#840], [#1041], [#1045], [#1073], [#1099]] + + - Your portable actors and objects may have compatible identifiers as + their IDs, e.g., + `https://example.com/.well-known/apgateway/did:key:z6Mk.../actor`, + for interoperability with software that cannot handle portable IDs. + Fedify treats them as portable wherever it serves or sends them, and + warns if such an ID is malformed or is not on the owner's first + gateway, as FEP-ef61 requires. Build them with `toCompatibleEf61Id()` + before signing the documents. [[#1106], [#1109], [#1155], [#1188]] + + - The WebFinger endpoint now serves portable actors: the domain of + the actor's address comes from the first gateway in its `gateways`, + and its `self` link is its compatible identifier on that gateway. + WebFinger resources can be portable IDs, which are passed to + `mapAlias()`. `Context.lookupObject()` resolves the handles of + portable actors on other servers. [[#837], [#1082], [#1106], [#1109]] + + - Fedify logs a warning if an actor dispatcher returns a portable actor + whose `gateways` are invalid, or whose collections are not the + portable IDs or compatible identifiers that the corresponding + `Context.getPortable*Uri()` methods build, instead of warning that + a portable actor's ID or collections do not match the URIs that + `Context.getActorUri()` and the like build. + [[#837], [#1082], [#1111], [#1142], [#1148], [#1178]] + + - `Context.routeActivity()` routes a portable activity that has no + valid proof only if all of its actors have the same DID as + the activity, comparing [FEP-fe34] origins, where the origin of + a portable ID or a compatible identifier is its DID. [[#1146], [#1171]] + + - Outbox listeners compare the `actor` of a posted activity with + a portable outbox owner by their canonical portable IDs, so that + the actor can be referred to with `@gateway` location hints, another + URI scheme, or as a compatible identifier on another gateway. + [[#1159], [#1189]] + + - Changed Fedify to treat documents whose IDs are [FEP-ef61] compatible + identifiers, such as + `https://gw.example/.well-known/apgateway/did:key:z6Mk.../actor`, as + the portable objects they stand for, as FEP-ef61 requires, instead of + trusting them by the web origin that served them. Previously, any server + could act as + `https://evil.example/.well-known/apgateway/did:key:z6MkAlice/actor` + without a proof by Alice's DID. Some implementations, e.g., tootik, + identify their portable actors this way. [[#288], [#1093], [#1105]] + + - Inboxes now reject an activity of an actor whose ID is a compatible + identifier with `401 Unauthorized` unless it has a valid Object + Integrity Proof made by the actor's DID. Activities of actors that + publish compatible identifiers without signing them, or whose DIDs + use key types Fedify does not support, are no longer accepted. + + - `verifyObject()` never authenticates an attribution or actor whose ID + is a compatible identifier by a key at an ordinary URL. + + - HTTP Signature verification rejects a key at a compatible identifier + unless the actor document has a valid proof by the actor's DID and + vouches for the key. A key at an ordinary URL that claims a portable + actor as its owner or controller is no longer that actor's key, and + `getKeyOwner()` and `doesActorOwnKey()` no longer resolve portable + actors by web origin. + + - Changed property accessors to verify the [FEP-ef61] portable objects that + they dereference when a `Context` is passed as their options, e.g., + `await create.getObject(ctx)`, since the new `Context.verifyPortableObject` + property has the same name as their `verifyPortableObject` option. This + also applies to objects with ordinary HTTP(S) IDs: their references to + compatible identifiers are now verified as portable objects instead of + being trusted because of their origin. In inbox listeners, accessors do + so even without options. [[#288], [#1107], [#1120]] + + - Fixed `signObject()` so that a signed object keeps verifying after it is + assigned to a typed parent and the parent is serialized. `signObject()` + now captures the secured JSON document its proof covers, and nested + serialization embeds that document verbatim instead of rebuilding the + child under the parent's JSON-LD context. Producing a compound document, + such as a signed `Note` in a signed [FEP-ef61] portable `Create`, with + `signObject()` no longer requires assembling the JSON by hand. + [[#288], [#1041], [#1044], [#1051]] + + - The captured document is a snapshot: `clone()` does not carry it, and + mutating a signed object in place does not change it. Sign a clone + again when it has to be embedded as a secured child. + - Serialization falls back to the previous behavior for objects parsed + with `fromJsonLd()`, objects that already carried a proof, and + `toJsonLd()` calls whose `context` option could hide the internal + placeholder. + - Outgoing JSON-LD compatibility normalization now leaves a nested + self-contained secured document untouched while signing and sending, + so it cannot rewrite bytes that the child's own proof covers. + Inbound verification is unaffected. + - Fanout delivery now reuses the document the activity was already + serialized into instead of reparsing and reserializing it, which + previously invalidated an embedded signed child and the outer proof + that covered it. - Allowed object dispatchers to return `Tombstone` for deleted objects, as actor dispatchers already can. Fedify now serves such object URIs with @@ -459,98 +320,6 @@ To be released. that return tombstones to be served with `410 Gone` instead of `200 OK`. - - Changed `Context.routeActivity()` to compare an activity that has no - valid proof with its actors by their [FEP-fe34] origins once it has - dereferenced the activity, where the origin of an [FEP-ef61] portable ID, - i.e., an `ap:` or `ap+ef61:` URI or a compatible identifier, is its DID - rather than the gateway that serves it. Previously, it compared their web - origins, so a portable activity was routed even if its actors had other - DIDs. Now a portable activity is routed only if all of its actors have - the same DID as the activity itself, and an activity with an ordinary - HTTP(S) ID is not routed if any of its actors has a portable ID. - A portable activity dereferenced through a compatible identifier also - matches its `ap:` ID, and vice versa. [[#288], [#1146], [#1171]] - - - Changed `Context.sendActivity()` so that an activity containing - [FEP-ef61] portable objects gets at most one Object Integrity Proof. - Previously Fedify signed every outgoing activity once for each Ed25519 - key, which produced a proof set that Fedify's own inbox rejects in a - compound portable document. [[#288], [#1041], [#1045], [#1073]] - - - An activity that already carries a proof is sent as is. - - With several Ed25519 keys, a portable activity is signed only by the - key whose ID is a DID URL for the activity's DID. - - If no single key qualifies, or a non-portable activity that embeds - portable objects has several Ed25519 keys, `sendActivity()` rejects - with a `TypeError` before anything is delivered or queued. Pass - explicit sender keys with exactly one Ed25519 key, or sign the - activity with `signObject()` beforehand. - - An activity with portable objects in which any map carries a proof - set is rejected the same way. - - Activities without portable objects are signed as before. - - - Changed Fedify to treat documents whose IDs are [FEP-ef61] compatible - identifiers, such as - `https://gw.example/.well-known/apgateway/did:key:z6Mk.../actor`, as the - portable objects they stand for, as FEP-ef61 requires. Some - implementations, e.g., tootik, identify their portable actors this way. - Previously, Fedify trusted such documents by the web origin that served - them, so any server could act as - `https://evil.example/.well-known/apgateway/did:key:z6MkAlice/actor` - without a proof by Alice's DID. [[#288], [#1093], [#1105]] - - - `verifyPortableObjectProof()` now verifies a document whose `@id` is - a compatible identifier against the DID in it, instead of reporting - it as `notPortableObject`. The proof is verified over the document - as is. - - - Inboxes now reject an activity of an actor whose ID is a compatible - identifier with `401 Unauthorized` unless it has a valid Object - Integrity Proof made by the actor's DID, as they already did for - actors with `ap:` IDs. Likewise, an activity whose own ID is an - `ap:` URI or a compatible identifier is rejected unless its proof is - made by the DID of that ID, and embedded maps with compatible - identifiers need their own proofs as embedded portable objects do. - The exception is a key embedded in the `publicKey` or - `assertionMethod` of a verified portable actor, such as a gateway - key, whose ID is the actor's compatible identifier plus a fragment; - the actor's proof covers it. - Activities of actors that publish compatible identifiers without - signing them, or whose DIDs use key types Fedify does not support, - are no longer accepted. - - - `verifyObject()` now accepts an Object Integrity Proof made by a DID - as authenticating an attribution or actor whose compatible identifier - has that DID, and never authenticates such an attribution by a key at - an ordinary URL. - - - HTTP Signature verification now resolves a gateway key whose actor - document has a compatible identifier as its ID the same way as for - actors with `ap:` IDs, and rejects the key if the document does not - have a valid proof by the actor's DID, instead of trusting the - gateway's web origin. A key at an ordinary URL that claims - a portable actor as its owner or controller is no longer that actor's - key, and `getKeyOwner()` and `doesActorOwnKey()` no longer resolve - portable actors by web origin. - - - `Context.sendActivity()` now applies the compound-proof key selection - to activities that embed objects with compatible identifiers, as it - does for embedded objects with `ap:` IDs, so that Fedify inboxes - accept what it sends. - - - Changed HTTP Signature verification to accept a gateway key of a portable - actor that the actor's signed document embeds only in its `publicKey`, - with the actor as its `owner`, when no `assertionMethod` entry has the - key ID. Some publishers, e.g., tootik, list their RSA keys only there. - A document that has more than one entry with the key ID in either - property is rejected. [[#288], [#1093], [#1105]] - - - Changed the gateway trust policy for unsecured portable collections in - `verifyPortableObject()` to accept collections and owners identified by - compatible identifiers. An owner with a compatible identifier is fetched - through the gateway that the identifier names first, unless the - `gateways` option is given. [[#288], [#1093], [#1105]] - - Changed HTTP Signature verification to verify at most the first three RFC 9421 signatures of a request, in the order of its `Signature-Input` header, and to ignore the rest. Each signature may make Fedify fetch the @@ -621,42 +390,6 @@ To be released. store compares encoded values. Existing half-open states can now recover after switching to a CAS-capable store. [[#1163], [#1167]] - - Fixed outbox listeners rejecting a posted activity with - `400 Bad Request` when its `actor` referred to an [FEP-ef61] portable - outbox owner in another form than the owner's ID, e.g., with `@gateway` - location hints, another URI scheme or DID encoding, or as a compatible - identifier on another gateway. Portable actor IDs are now compared by - their canonical forms, while other actor IDs still have to match exactly. - [[#288], [#1159], [#1189]] - - - Fixed portable actor and object URI helpers so a dispatcher identifier - containing a `.` or `..` path segment raises a `TypeError` instead of - silently producing another object's ID. Use identifiers without such - segments. [[#288], [#1154], [#1186]] - - - Fixed `signObject()` so that a signed object keeps verifying after it is - assigned to a typed parent and the parent is serialized. `signObject()` - now captures the secured JSON document its proof covers, and nested - serialization embeds that document verbatim instead of rebuilding the - child under the parent's JSON-LD context. Producing a [FEP-ef61] compound - document with `signObject()` no longer requires assembling the JSON by - hand. [[#288], [#1041], [#1044], [#1051]] - - - The captured document is a snapshot: `clone()` does not carry it, and - mutating a signed object in place does not change it. Sign a clone - again when it has to be embedded as a secured child. - - An object parsed with `fromJsonLd()`, an object that already carried a - proof, and a `toJsonLd()` `context` option that could hide the - internal placeholder all fall back to the previous behavior. - - Outgoing JSON-LD compatibility normalization now leaves a nested - self-contained secured document untouched while signing and sending, - so it cannot rewrite bytes that the child's own proof covers. - Inbound verification is unaffected. - - Fanout delivery now reuses the document the activity was already - serialized into instead of reparsing and reserializing it, which - previously invalidated an embedded signed child and the outer proof - that covered it. - - Fixed `verifyProof()` so Ed25519 JCS proofs authenticate every received proof option except `proofValue`, including `expires`, `domain`, `challenge`, `nonce`, and extension options. It now rejects expired or @@ -664,26 +397,6 @@ To be released. `challenge` values through `VerifyProofOptions` to prevent cross-domain or replay use. [[#968]] - - Added `verifyPortableObjectProof()` to enforce the [FEP-ef61] proof policy - for portable actors, activities, objects, and signed collections. Its - detailed result distinguishes documents outside the policy, unsecured - collections, missing or invalid [FEP-8b32] proofs, unsupported verification - methods, DID authority mismatches, and successful verification. - [[#832], [#968]] - - - Updated `verifyObject()` so [FEP-8b32] proofs signed by `did:key` - verification methods can authenticate portable objects whose owner is an - `ap:` or `ap+ef61:` URI with the same [FEP-fe34] cryptographic origin. - [[#829], [#926]] - - - Added local `did:key` verification method resolution for - [FEP-8b32] Object Integrity Proofs. `verifyProof()` can now verify - Ed25519 `eddsa-jcs-2022` proofs whose `verificationMethod` is a - `did:key:z...#z...` DID URL without fetching the verification method - as a remote JSON-LD document, which is required for [FEP-ef61] - portable objects. - [[#827], [#915]] - - Added support for the [ActivityPub Media Upload extension] so that servers can accept client-to-server media uploads: [[#754], [#927]] @@ -755,36 +468,13 @@ To be released. `esnext.temporal` lib reference. [[#823], [#925]] - - Security: Inbox processing now independently verifies each portable actor, - activity, and object in a compound JSON document against its own map-local - Object Integrity Proof before dispatch. A valid outer proof no longer - authenticates an unsigned or invalid nested portable object. - Portable documents with proof sets or which exceed the inbox compound - traversal limits are rejected as unsupported. The top-level Linked - Data Signature of an activity is not part of any proof input, so an - activity that carries both proofs and a Linked Data Signature is - accepted. An unsigned key embedded in the `publicKey` or - `assertionMethod` of a verified portable actor needs no proof of its own - if its ID is the actor's compatible identifier or `ap:` or `ap+ef61:` URI - plus a non-empty fragment, as with the keys that [FEP-ae97] clients make - for their actors, which Mitra serves under `ap:` URIs. - [[#288], [#938], [#1041], [#1094], [#1102], [#1133], [#1138]] - - The map-local profile is Fedify's interim interpretation, since neither - FEP-8b32 nor Verifiable Credential Data Integrity defines the boundaries - of embedded proofs yet, and may change in Fedify 3.0. The new - [*Portable objects*] chapter of the manual describes - the [FEP-ef61] profile that Fedify supports, including this and the parts - of FEP-ef61 that Fedify does not implement. [[#288], [#1151], [#1198]] - [FEP-ef61]: https://w3id.org/fep/ef61 +[*Portable objects*]: https://fedify.dev/manual/portable +[FEP-8b32]: https://w3id.org/fep/8b32 [FEP-fe34]: https://w3id.org/fep/fe34 [key–value store guide]: https://fedify.dev/manual/kv -[FEP-8b32]: https://w3id.org/fep/8b32 [ActivityPub Media Upload extension]: https://www.w3.org/wiki/SocialCG/ActivityPub/MediaUpload [Standard Schema]: https://standardschema.dev/ -[FEP-ae97]: https://w3id.org/fep/ae97 -[*Portable objects*]: https://fedify.dev/manual/portable [#206]: https://github.com/fedify-dev/fedify/issues/206 [#288]: https://github.com/fedify-dev/fedify/issues/288 [#754]: https://github.com/fedify-dev/fedify/issues/754 @@ -913,53 +603,66 @@ To be released. - Added \[SvelteKit\] option to `fedify init` command. This option allows users to initialize a new Fedify project with SvelteKit integration. [[#892], [#971] by Jang Hanarae\] + - Added `fedify.com.es` as a tunneling service. The CLI pins the service's SSH host key and rejects a mismatched server before exposing a local port. [[#940]] + - Removed `localhost.run` as a tunneling service. The service is no longer available, and the CLI now rejects attempts to use it. [[#940]] + - Switched the CLI's Temporal runtime dependency from `@js-temporal/polyfill` to `temporal-polyfill`. [[#823], [#925]] - - Added support for [FEP-ef61] portable objects to `fedify lookup`. It now - looks up portable objects by their `ap:` and `ap+ef61:` IDs, compatible - identifiers, and the WebFinger handles of portable actors, and verifies - their Object Integrity Proofs. Previously, - it failed to look up portable IDs, and refused portable objects found - through compatible identifiers as cross-origin objects. The same applies - to the collections that `-t`/`--traverse` traverses and the objects that - `--recurse` follows. When no gateway returns an acceptable object, the - command tells why, e.g., that the object's proof is invalid. + + - Added support for [FEP-ef61] portable objects to the `fedify` command. [[#288], [#1156], [#1199]] - - Added the `--gateway` option to `fedify lookup`, `fedify inbox`, and - `fedify webfinger`, which specifies the FEP-ef61 gateways to look up - portable objects from, e.g., for portable IDs without `@gateway` location - hints. [[#288], [#1156], [#1199]] - - Changed `fedify inbox -f`/`--follow` to follow FEP-ef61 portable actors, - and changed the `-a`/`--accept-follow` option of `fedify inbox` and the - `-a`/`--accept-follow` and `-r`/`--reject-follow` options of `fedify relay` - to accept portable IDs and compatible identifiers, which match the actor - regardless of `@gateway` location hints and the gateway of a compatible - identifier. [[#288], [#1156], [#1199]] - - Changed `fedify webfinger` to accept FEP-ef61 portable actor IDs. As such - an ID does not tell which server to ask, the command looks up the actor and - then its WebFinger address, which consists of its `preferredUsername` and - the host of its first gateway, and reports whether the response links back - to the actor. [[#288], [#1156], [#1199]] + + - `fedify lookup` now looks up portable objects by their `ap:` and + `ap+ef61:` IDs, compatible identifiers, and the WebFinger handles of + portable actors, and verifies their Object Integrity Proofs. + Previously, it failed to look up portable IDs, and refused portable + objects found through compatible identifiers as cross-origin objects. + The same applies to the collections that `-t`/`--traverse` traverses + and the objects that `--recurse` follows. When no gateway returns + an acceptable object, the command tells why, e.g., that the object's + proof is invalid. + + - Added the `--gateway` option to `fedify lookup`, `fedify inbox`, and + `fedify webfinger`, which specifies the gateways to look up portable + objects from, e.g., for portable IDs without `@gateway` location + hints. + + - `fedify inbox -f`/`--follow` now follows portable actors, and + the `-a`/`--accept-follow` option of `fedify inbox` and + the `-a`/`--accept-follow` and `-r`/`--reject-follow` options of + `fedify relay` accept portable IDs and compatible identifiers, which + match the actor regardless of `@gateway` location hints and + the gateway of a compatible identifier. + + - `fedify webfinger` now accepts portable actor IDs. As such an ID + does not tell which server to ask, the command looks up the actor + and then its WebFinger address, which consists of its + `preferredUsername` and the host of its first gateway, and reports + whether the response links back to the actor. + - Fixed `fedify lookup --recurse` reporting a timeout or another network failure of the first object or of a linked object as a possibly private object, suggesting the `-a`/`--authorized-fetch` option. It now reports the actual cause, e.g., “Request timed out after 10 seconds,” like the other modes of `fedify lookup` do. [[#1156], [#1199]] + - Fixed the `-p`/`--allow-private-address` option of `fedify webfinger` being ignored. [[#1156], [#1199]] + - Changed `fedify lookup` to time out each request after 10 seconds when the `-T`/`--timeout` option is not given, since the document loaders it uses now have a default timeout. Previously, there was no timeout by default. The `-T`/`--timeout` option now also limits how long a request waits for a DNS lookup, though it cannot stop the lookup itself. [[#1131], [#1169]] + - Updated Optique to 1.3.2. This fixes several command-line parsing issues, so options with attached values such as `--timeout=30` are handled consistently, typo suggestions for mistyped options are more @@ -1070,10 +773,11 @@ To be released. counts wherever it is passed. [[#900], [#1050] by Jae-Hyuk-Jang\] - - Fixed actor URI mismatch rules reporting portable actor and collection - URIs, including gateway-compatible IDs built from them. Applications can - use the `getPortable*Uri()` helpers in actor dispatchers without disabling - these rules. [[#1157], [#1179]] + - Changed the actor URI mismatch rules to accept the [FEP-ef61] portable + IDs of actors and collections, and the compatible identifiers built from + them, so that applications can use the `getPortable*Uri()` methods of + `Context` in actor dispatchers without disabling these rules. + [[#288], [#1157], [#1179]] - Fixed `outbox-listener-delivery-required` and `outbox-listener-delivery-not-awaited` (`@fedify/lint`) losing track of @@ -1146,7 +850,7 @@ To be released. `isFederationRequest()` now recognizes them by their paths regardless of their headers. To make Next.js run the middleware for them, add `{ source: "/.well-known/apgateway/:path*" }` to the `matcher` of your - *middleware.ts* or *proxy.ts* file. [[#288], [#1149], [#1170]] + *middleware.ts* or *proxy.ts* file. [[#288], [#1149], [#1170]] - Added `isHashlinkMediaRequest()` function. [[#288], [#1149], [#1170]] [#1149]: https://github.com/fedify-dev/fedify/issues/1149 @@ -1222,105 +926,195 @@ To be released. ### @fedify/testing - - Added fixture document loaders and portable-object verification to mock - context lookups, explicit portable gateway request information for mock - dispatchers, and hashlink media responses from mock federations. Tests can - now exercise these FEP-ef61 paths without a live gateway. - [[#288], [#1161], [#1196]] + - Added support for [FEP-ef61] portable objects to the mock federation and + contexts, following the new APIs of `@fedify/fedify`, so that tests can + exercise portable objects without a live gateway. [[#288]] + + - Added the `getPortableActorUri()`, `getPortableObjectUri()`, + `getPortableInboxUri()`, `getPortableOutboxUri()`, + `getPortableFollowingUri()`, `getPortableFollowersUri()`, + `getPortableLikedUri()`, `getPortableFeaturedUri()`, + `getPortableFeaturedTagsUri()`, and `getPortableCollectionUri()` + methods to the mock contexts. They reject `did:key` DIDs that are + not encoded in base58-btc. + [[#835], [#839], [#841], [#1092], [#1111], [#1114], [#1142]] + + - Added the `portable` option to `parseUri()` of the mock contexts. + Without it, `parseUri()` no longer recognizes a portable ID or + compatible identifier whose path starts with `/users/`; with it, + the result has the DID in its `authority` property. It also returns + `null` for `null`. [[#1143], [#1145]] + + - The mock contexts that `createContext()` creates keep + the `verifyPortableObject` property given to them, and their + `lookupObject()` and `traverseCollection()` pass it on. + `createFederation()` accepts a fixture `documentLoader`, + a `contextLoader`, and `verifyPortableObject`, which mock context + lookups use for portable IDs. [[#1107], [#1120], [#1161], [#1196]] + + - Added the `isSignedByAudience()` method to the mock request contexts, + which checks the audience against the actor that + `getSignedKeyOwner()` returns. [[#1153], [#1183]] + + - `federation.createContext()` accepts an explicit `portableRequest` + for a request context, which dispatchers can inspect. + [[#1161], [#1196]] + + - Added the `mapPortableActorId()` method to the setters that + `MockFederation.setActorDispatcher()` returns, the + `mapPortableOwner()` method to the mock custom collection setters, + and the `setHashlinkMediaDispatcher()` method to the mock federation, + which serves hashlink media responses. + [[#838], [#840], [#1080], [#1099], [#1111], [#1142], [#1161], [#1196]] + - Added support for registering `onRequestFinished()` on mock federations so applications can reuse their inbox configuration in tests. [[#1191], [#1201]] + - Added `testKvStore()`, a conformance test suite for `KvStore` implementations, complementing `testMessageQueue()`. [[#1018], [#1020] by ChanHaeng Lee\] - - Added the `getPortableActorUri()` method to the mock contexts that - `createFederation()`, `createContext()`, `createRequestContext()`, - `createInboxContext()`, and `createOutboxContext()` create, following - the new `Context.getPortableActorUri()` method of `@fedify/fedify`. - The mock contexts' portable ID methods now also reject `did:key` DIDs - that are not encoded in base58-btc. [[#288], [#841], [#1114]] - - Added the `getPortableInboxUri()` method to the mock contexts that - `createFederation()`, `createContext()`, `createRequestContext()`, - `createInboxContext()`, and `createOutboxContext()` create, following - the new `Context.getPortableInboxUri()` method of `@fedify/fedify`. - [[#288], [#839], [#1092]] - - Added the `getPortableOutboxUri()`, `getPortableFollowingUri()`, - `getPortableFollowersUri()`, `getPortableLikedUri()`, - `getPortableFeaturedUri()`, `getPortableFeaturedTagsUri()`, and - `getPortableCollectionUri()` methods to the mock contexts, and - the `mapPortableOwner()` method to the mock custom collection setters, - following the new APIs of `@fedify/fedify`. [[#288], [#1111], [#1142]] - - Added the `isSignedByAudience()` method to the mock contexts that - `createFederation()` and `createRequestContext()` create, following - the new `RequestContext.isSignedByAudience()` method of `@fedify/fedify`. - It checks the audience against the actor that `getSignedKeyOwner()` - returns. [[#288], [#1153], [#1183]] - - Added the `mapPortableActorId()` method to the setters that - `MockFederation.setActorDispatcher()` returns, which `ActorCallbackSetters` - gained for [FEP-ef61] portable actors. [[#288], [#840], [#1099]] - - Added the `setHashlinkMediaDispatcher()` method to the `Federation` - object returned by `createFederation()`, following the new - `Federatable.setHashlinkMediaDispatcher()` method of `@fedify/fedify`. - [[#288], [#838], [#1080]] + - Changed `getObject()` of the mock context that `createFederation()` creates to follow `RequestContext.getObject()` of `@fedify/fedify`: it now returns `null` for a `Tombstone` that the object dispatcher returns, unless the tombstone is an instance of the requested class or `{ tombstone: "passthrough" }` is given. [[#1112], [#1117]] - - Changed `parseUri()` of the mock contexts to accept the `portable` option, - following `Context.parseUri()` of `@fedify/fedify`. It no longer - recognizes an FEP-ef61 portable ID or compatible identifier whose path - starts with `/users/` unless the option is enabled, in which case the - result has the DID in its `authority` property. It also returns `null` - for `null`. [[#288], [#1143], [#1145]] + - Fixed the CommonJS testing utilities build so it no longer requires `@js-temporal/polyfill` at runtime. The build now bundles `temporal-polyfill`, while type declarations rely on the standard `esnext.temporal` lib reference. [[#823], [#925]] - - The mock contexts that `createContext()` creates now keep the - `verifyPortableObject` property given to them, following the new - `Context.verifyPortableObject` property of `@fedify/fedify`, and their - default `lookupObject()` and `traverseCollection()` methods pass it and - a `verifyPortableObject` option given to them on. - [[#288], [#1107], [#1120]] [#1161]: https://github.com/fedify-dev/fedify/issues/1161 [#1196]: https://github.com/fedify-dev/fedify/pull/1196 ### @fedify/vocab - - Added [FEP-ef61] gateway dereferencing to property accessors such as - `Create.getObject()`. Accessors now fetch `ap:` and `ap+ef61:` - references through the gateways given by the new `gateways` option, or - through the `@gateway` location hints in the reference when the option is - omitted, trying each gateway in order until one serves a valid object. - A fetched object is returned only if its `@id` canonically matches the - reference and the new `verifyPortableObject` option, typically - `verifyPortableObjectProof()` from `@fedify/fedify`, accepts it. Portable - references can no longer be dereferenced without `verifyPortableObject`, - and the `crossOrigin: "trust"` option does not skip these checks. - HTTP(S) references are fetched as before. [[#288], [#834], [#1077]] - - - Added [FEP-ef61] vocabulary terms for portable ActivityPub objects. - Actor classes now expose ordered `gateways` lists, and `Link` plus - document/media classes expose `digestMultibase` for external resource - integrity metadata. - [[#830], [#928]] - - - Updated [FEP-fe34] cross-origin checks to understand cryptographic origins - for [FEP-ef61] portable ActivityPub IDs and DID URLs. Generated property - accessors and `lookupObject()` now treat `ap:`/`ap+ef61:` IDs and matching - `did:key` verification method IDs as same-origin when their DID components - match. - [[#829], [#926]] - - - Added support for [FEP-ef61] portable ActivityPub IRIs in generated - vocabulary codecs. `ap:` and `ap+ef61:` values with decoded or - percent-encoded DID authorities now parse as `URL` objects, and JSON-LD - serialization emits canonical `ap+ef61:` values with decoded DID - authorities. - [[#826], [#850]] + - Added support for [FEP-ef61] portable objects, whose IDs are `ap:` or + `ap+ef61:` URIs with a DID instead of a host, e.g., + `ap://did:key:z6Mk.../actor`, and which are retrieved through the + servers listed in their actors' `gateways`. See the + [*Portable objects*] chapter of the manual for the + FEP-ef61 profile that Fedify supports. [[#288]] + + - Generated vocabulary classes now accept portable IDs with decoded or + percent-encoded DID authorities wherever an IRI is expected, and + serialize them as canonical `ap+ef61:` IRIs with decoded DID + authorities. Inspecting vocabulary objects, e.g., with + `console.log()`, also shows them in this form. + [[#826], [#850], [#1156], [#1199]] + + - Added the `gateways` property to actor classes, and the + `digestMultibase` property to `Link` and document and media classes. + Gateways are serialized as origins without a trailing slash. + A portable actor that uses the `gateways` term without mapping it in + its JSON-LD context, as tootik does, is also read. + [[#830], [#928], [#1097], [#1202]] + + - Added the optional `Recipient.gateways` property, through which Fedify + delivers activities to portable inboxes. Applications that build + `Recipient` objects by hand, e.g., in followers collection + dispatchers, need to set it for portable actors. [[#1147], [#1180]] + + - Property accessors such as `Create.getObject()` now fetch portable + references through gateways: those in the new `gateways` option, or + else those in the `@gateway` location hints of the reference. + A fetched object is returned only if its `@id` identifies the referenced + portable object and the verifier given as the new + `verifyPortableObject` option accepts it, typically + `verifyPortableObject()` from `@fedify/fedify`, or a `Context` passed + as the options. Portable references cannot be dereferenced + without the option, and `crossOrigin: "trust"` does not skip these + checks. [[#834], [#1077], [#1093], [#1105]] + + - Property accessors tell the `verifyPortableObject` function where + a portable object was retrieved from and which objects led to it, so + that it can accept a portable collection without a proof if a gateway + that its owner lists served it. Objects embedded in such a collection + are fetched and verified one by one. Added the `crossOrigin`, + `gateways`, and `verifyPortableObject` options to + `TraverseCollectionOptions` as well. [[#836], [#1084]] + + - Added the `verifyPortableObject` option to the constructors, + the `fromJsonLd()` methods, and the `clone()` methods of vocabulary + classes, which sets the verifier that the object's property accessors + use by default. Objects embedded in the parsed document, and objects + that accessors and `traverseCollection()` fetch, get the verifier of + the call or of their parent by default, so that, e.g., + `(await create.getObject(ctx))?.getAttribution()` verifies portable + objects without passing `ctx` again. Having a default verifier does + not mean that an object was verified. Added + the `inheritPortableObjectVerifier` option to property accessors and + `TraverseCollectionOptions` to limit a verifier to a single call. + [[#1107], [#1120], [#1129], [#1137]] + + - Added the `verifyPortableObject` and `gateways` options to + `LookupObjectOptions`. With the former, `lookupObject()` looks up + portable IDs through their `@gateway` location hints or the gateways + given by the latter, compatible identifiers through the gateways they + name, and the handles of portable actors through their WebFinger + responses, trying at most five gateways per lookup. The gateways + that it infers from compatible identifiers, WebFinger responses, and + location hints are passed to the `verifyPortableObject` function as + `gatewayHints`, while `gateways` has the ones given explicitly. + [[#837], [#1082], [#1090], [#1091], [#1158], [#1194]] + + - `getActorHandle()` now supports portable actors. It takes the domain + of a portable actor's handle from the first gateway in its `gateways`, + and returns the handle only if its WebFinger response links back to + the actor. [[#837], [#1082]] + + - Exported the portable object verifier types and other types used in + vocabulary API signatures from `@fedify/vocab`, so that custom + verifiers can be typed without importing `@fedify/vocab-runtime`. + [[#1160], [#1184]] + + - Changed property accessors and `lookupObject()` so that they no longer + trust [FEP-ef61] compatible identifiers, i.e., HTTP(S) URLs under + a gateway's */.well-known/apgateway/* path such as + `https://gw.example/.well-known/apgateway/did:key:z6Mk.../actor`, because + of the origin that serves them. Anyone can serve a compatible identifier + for any DID, so previously anyone could serve an unsigned object that + claimed to be someone else's portable object. + [[#288], [#837], [#1082], [#1090], [#1091], [#1107], [#1120]] + + - With the `verifyPortableObject` option, a compatible identifier is + dereferenced as the portable object it stands for: through the + gateway that it names and then the gateways in the `gateways` option, + only if the option accepts the object. A document fetched from + an ordinary HTTP(S) URL is verified the same way if its final URL is + a compatible identifier or its `@id` is a portable ID. Malformed + compatible identifiers are rejected without a request. + + - Without the option, accessors keep fetching compatible identifiers as + ordinary HTTP(S) URLs, but no longer cache the results in the parent + objects, so that a later call with the option verifies them. + However, accessors of an object whose ID is a portable ID or + a compatible identifier now throw a `TypeError` (or return `null` with + `suppressError: true`) for such references without the option, as + for portable IDs. + + - Accessors no longer trust an embedded object whose `@id` is + a compatible identifier, or a portable ID with a DID other than its + parent's, even with `crossOrigin: "trust"`; they dereference and + verify it on its own. Likewise, `crossOrigin: "trust"` no longer + makes `lookupObject()` return an object with a portable `@id` from + a document URL of another origin. + + - Updated [FEP-fe34] cross-origin checks to understand the cryptographic + origins of [FEP-ef61] portable IDs and DID URLs. Property accessors and + `lookupObject()` now treat `ap:` and `ap+ef61:` IDs and `did:key` + verification method IDs as the same origin when their DIDs match. + [[#288], [#829], [#926]] + + - Changed nested serialization so that an object carrying the signed + JSON-LD representation that `signObject()` retains is embedded with that + exact representation, including its own `@context`, rather than being + rebuilt under the parent's context, so that its proof keeps verifying. + `clone()` never carries the retained representation, because a clone may + differ from the document the proof covers. [[#288], [#1044], [#1051]] - Added vocabulary support for [FEP-7aa9], including `FeaturedCollection`, `FeaturedItem`, `FeatureRequest`, and @@ -1338,47 +1132,6 @@ To be released. `esnext.temporal` lib reference. [[#823], [#925]] - - Added a `gateways` option to `lookupObject()` and - `Context.lookupObject()`, so applications can look up a bare - [FEP-ef61] portable object ID without constructing location hints or - providing a custom document loader. The listed gateways are tried in - order in place of any `@gateway` hints. [[#288], [#1158], [#1194]] - - - Added the optional `Recipient.gateways` property, the [FEP-ef61] gateways - of a portable actor, through which Fedify delivers activities to its - `ap:` or `ap+ef61:` inbox. Every actor class already has it, so - applications that build `Recipient` objects by hand, e.g., in followers - collection dispatchers, need to set it only for portable actors. - [[#288], [#1147], [#1180]] - - - Added the `verifyPortableObject` option to `LookupObjectOptions`. With - it, `lookupObject()` looks up [FEP-ef61] portable objects: `ap:` and - `ap+ef61:` URIs through their `@gateway` location hints, compatible - identifiers through the gateways they name, and portable actors' - handles through the `self` links of their WebFinger responses, which - can be either of them. A fetched object is returned only if its `@id` - identifies the requested portable object and the option accepts it; - otherwise, the next candidate is tried, at most five gateways per - lookup. `crossOrigin: "throw"` makes a rejected object throw an error, - and `crossOrigin: "trust"` does not skip the checks. - [[#288], [#837], [#1082]] - - - `crossOrigin: "trust"` no longer makes `lookupObject()` return an object - whose `@id` is an `ap:` or `ap+ef61:` URI from a document URL of another - origin, such as a compatible identifier fetched as an ordinary HTTP(S) - URL, since a portable object is authenticated by its proofs, not by the - server that serves it. Look such objects up with the - `verifyPortableObject` option instead. [[#288], [#837], [#1082]] - - - `getActorHandle()` now supports [FEP-ef61] portable actors. It takes the - domain of a portable actor's handle from the first gateway in its - `gateways` instead of its ID, and returns the handle only if its - WebFinger response links back to the actor, either by its portable ID - or by a compatible identifier, since the gateways are claimed by the - actor itself. It throws a `TypeError` otherwise, including when the - WebFinger lookup fails, and for a portable actor without `gateways` or - `preferredUsername` or a portable actor URI. [[#288], [#837], [#1082]] - - Added vocabulary support for the [FEP-22cd] draft, associating each translated version with its translators, source object, and optional source review timestamp. [[#1037], [#1038]] @@ -1393,117 +1146,6 @@ To be released. `Note`, and other object types, for per-language translation metadata without creating separate posts. - - Changed nested serialization so that an object carrying a signed JSON-LD - representation retained by `signObject()` is embedded with that exact - representation, including its own `@context`, rather than being rebuilt - under the parent's context. `clone()` never carries the retained - representation, because a clone may differ from the document the proof - covers. [[#288], [#1044], [#1051]] - - - Changed the inspection of vocabulary objects, e.g., with `console.log()`, - `util.inspect()`, or `Deno.inspect()`, to show [FEP-ef61] portable IDs - in their canonical form, e.g., `ap+ef61://did:key:z6Mk.../actor`, instead - of the percent-encoded form of the `URL` objects that represent them, - e.g., `ap+ef61://did%3Akey%3Az6Mk.../actor`. [[#288], [#1156], [#1199]] - - - Exported portable object verifier types from `@fedify/vocab`, so callers - can type custom verifiers without importing `@fedify/vocab-runtime`. - Also exported other types used in vocabulary API signatures. - [[#288], [#1160], [#1184]] - - - Property accessors and `lookupObject()` with the `verifyPortableObject` - option now accept a portable object whose `@id` is an [FEP-ef61] - compatible identifier of the requested portable object, e.g., one on the - gateway that served it, and pass it to `verifyPortableObject`, keeping its - own `@id`. Previously, such documents, which some implementations such - as tootik publish, were rejected as objects with a mismatching ID. - [[#288], [#1093], [#1105]] - - - Property accessors now tell the `verifyPortableObject` function where - a portable object was retrieved from and which objects led to it, so - that it can apply the [FEP-ef61] trust policy for portable collections - served without proofs. Accessors of such an unsecured collection do not - trust the objects embedded in it, even with `crossOrigin: "trust"`; - they fetch and verify each of them on its own, and drop the ones without - an `@id`. [[#288], [#836], [#1084], [#1090], [#1091]] - - - Added `crossOrigin`, `gateways`, and `verifyPortableObject` options to - `TraverseCollectionOptions`, so that `traverseCollection()` can traverse - [FEP-ef61] portable collections through gateways. - [[#288], [#836], [#1084], [#1090], [#1091]] - - - Property accessors of objects whose IDs are [FEP-ef61] compatible - identifiers, e.g., - `https://gw.example/.well-known/apgateway/did:key:z6Mk.../activities/1`, - now dereference their references as portable objects, as those of objects - with `ap:` IDs do. Previously, such an accessor fetched a compatible - identifier as an ordinary HTTP(S) URL and trusted the result because of - its origin, so anyone could serve an unsigned object at the reference. - Without the `verifyPortableObject` option, such an accessor now throws - a `TypeError` (or returns `null` with `suppressError: true`) for - a portable reference or a compatible identifier; pass a `Context` from - `@fedify/fedify`, which carries a verifier, or use a default verifier - (see below). An object whose ID is a malformed compatible identifier is - handled the same way. Having such an ID does not make an object - verified. [[#288], [#1107], [#1120]] - - - Added the `verifyPortableObject` option to the constructors, the - `fromJsonLd()` methods, and the `clone()` methods of vocabulary - classes. The object uses it by default when its property accessors are - called without the option. Objects embedded in the JSON-LD document it - was parsed from inherit it. `lookupObject()` passes its - `verifyPortableObject` option to the object it returns. - [[#288], [#1107], [#1120]] - - - Objects that property accessors and `traverseCollection()` fetch now use - the `verifyPortableObject` option of that call, or else the default of - the object they were obtained from, as their default verifier. So - `(await create.getObject(ctx))?.getAttribution()` verifies portable - objects without passing `ctx` again. Objects already cached in their - parent keep the default they got when they were fetched. Having - a default verifier does not mean that an object was verified. - [[#288], [#1129], [#1137]] - - - Added the `inheritPortableObjectVerifier` option to property accessors - and `TraverseCollectionOptions`. Set it to `false` to keep - a `verifyPortableObject` option to that call only, e.g., for a verifier - that accepts everything; fetched objects then use the default of the - object they were obtained from, if any. [[#288], [#1129], [#1137]] - - - Property accessors such as `Create.getObject()` now dereference - [FEP-ef61] compatible identifiers, i.e., HTTP(S) URLs under a gateway's - */.well-known/apgateway/* path, as the portable objects they stand for - when the `verifyPortableObject` option is given or the parent object is - portable. Previously, they fetched such a reference as an ordinary - HTTP(S) URL and trusted the result because of its origin, so anyone could - serve an unsigned object that claimed to be someone else's portable - object. Now the accessor asks the gateway that the identifier names - first, and then the gateways in the `gateways` option, and returns the - object only if its `@id` identifies the same portable object and - `verifyPortableObject` accepts it, including the gateway trust policy for - unsecured collections. Malformed compatible identifiers are rejected - without a request. [[#288], [#1090], [#1091]] - - - Property accessors and `lookupObject()` with the `verifyPortableObject` - option now verify a document fetched from an ordinary HTTP(S) URL as - a portable object if its final URL is a compatible identifier or its - `@id` is an `ap:`/`ap+ef61:` URI, instead of trusting it because of its - origin. Likewise, accessors no longer trust an embedded object whose - `@id` is a compatible identifier, or a portable ID with a DID other than - its parent's, even with `crossOrigin: "trust"`; they dereference and - verify it on its own. [[#288], [#1090], [#1091]] - - - Without the `verifyPortableObject` option, property accessors keep - fetching compatible identifiers from ordinary objects as HTTP(S) URLs, - but no longer cache the results in the parent objects, so that a later - call with the option verifies them. [[#288], [#1090], [#1091]] - - - The gateways that `lookupObject()` infers from compatible identifiers, - WebFinger responses, and location hints are now passed to the - `verifyPortableObject` function as `gatewayHints` instead of `gateways`, - which are reserved for gateways that the caller gives explicitly. - [[#288], [#1090], [#1091]] - [FEP-22cd]: https://w3id.org/fep/22cd [#810]: https://github.com/fedify-dev/fedify/issues/810 [#826]: https://github.com/fedify-dev/fedify/issues/826 @@ -1517,57 +1159,114 @@ To be released. [#1077]: https://github.com/fedify-dev/fedify/pull/1077 [#1090]: https://github.com/fedify-dev/fedify/issues/1090 [#1091]: https://github.com/fedify-dev/fedify/pull/1091 +[#1097]: https://github.com/fedify-dev/fedify/issues/1097 [#1129]: https://github.com/fedify-dev/fedify/issues/1129 [#1137]: https://github.com/fedify-dev/fedify/pull/1137 [#1158]: https://github.com/fedify-dev/fedify/issues/1158 [#1160]: https://github.com/fedify-dev/fedify/issues/1160 [#1184]: https://github.com/fedify-dev/fedify/pull/1184 [#1194]: https://github.com/fedify-dev/fedify/pull/1194 +[#1202]: https://github.com/fedify-dev/fedify/pull/1202 ### @fedify/vocab-runtime - - Added SHA-256 `digestMultibase` and simple `hl:` hashlink helpers for - computing, parsing, creating, and verifying portable media resource - digests as required by [FEP-ef61]. - [[#831], [#935]] - - - Added the [FEP-ef61] JSON-LD context to the preloaded context registry so - portable actor and media documents can compact and expand `gateways` and - `digestMultibase` without fetching the context remotely. - [[#830], [#928]] - - - Added `getFe34Origin()` and `haveSameFe34Origin()` for comparing ordinary - web origins and [FEP-ef61] cryptographic origins with one shared - [FEP-fe34] helper. HTTP(S) URLs keep web-origin semantics, while - `ap:`/`ap+ef61:` URIs and DID URLs use their DID component as the origin. - [[#829], [#926]] - - - Added `canonicalizePortableUri()` and `arePortableUrisEqual()` for - comparing [FEP-ef61] portable ActivityPub URI strings. The helpers accept - `ap:` and `ap+ef61:` values with decoded or percent-encoded DID - authorities, normalize them to `ap+ef61:`, and ignore query hints such as - `gateways` during comparison. - [[#828], [#924]] - - Canonicalizing to `ap+ef61:` rather than `ap:`, which FEP-ef61 currently - recommends, is a deliberate choice of Fedify's that may change in - Fedify 3.0. Compare portable IDs with `arePortableUrisEqual()` rather - than as strings. See the [*Portable objects*] chapter - of the manual for the FEP-ef61 profile that Fedify supports. - [[#288], [#1151], [#1198]] + - Added to preloaded JSON-LD contexts. + [[#1037], [#1038]] + + - Added support for [FEP-ef61] portable objects, whose IDs are `ap:` or + `ap+ef61:` URIs with a DID instead of a host, e.g., + `ap://did:key:z6Mk.../actor`. See the + [*Portable objects*] chapter of the manual for the + FEP-ef61 profile that Fedify supports. [[#288]] + + - Added `parseIri()`, `formatIri()`, `parseJsonLdId()`, and + `haveSameIriOrigin()`, which parse, format, and compare IRIs, + including portable IDs with decoded or percent-encoded DID + authorities. The `URL` objects that represent portable IDs keep + their DIDs percent-encoded, and `formatIri()` formats them in their + canonical form, e.g., `ap+ef61://did:key:z6Mk.../actor`. Portable + IDs and compatible identifiers whose paths have `.` or `..` + segments, which the `URL` class would remove, are rejected with + a `TypeError`. [[#826], [#850], [#1154], [#1186]] + + - Added `canonicalizePortableUri()` and `arePortableUrisEqual()` for + comparing portable IDs. They accept both schemes with decoded or + percent-encoded DID authorities, normalize them to `ap+ef61:`, and + ignore the query, including `@gateway` location hints. + Fedify deliberately canonicalizes to `ap+ef61:` rather than `ap:`, + which FEP-ef61 currently recommends, and this may change in + Fedify 3.0, so compare portable IDs with + `arePortableUrisEqual()` rather than as strings. + [[#828], [#924], [#1151], [#1198]] + + - Added `getFe34Origin()` and `haveSameFe34Origin()`, which compare + [FEP-fe34] origins: HTTP(S) URLs have their web origins, while + portable IDs and DID URLs have their DIDs as their cryptographic + origins. [[#829], [#926]] + + - Added `exportDidKey()`, `importDidKey()`, and + `parseDidKeyVerificationMethod()` for Ed25519 `did:key` DIDs and + their verification method DID URLs. `exportDidKey()` always + encodes DIDs in base58-btc, as FEP-ef61 requires. [[#827], [#915]] + + - Added `toCompatibleEf61Id()` and `fromCompatibleEf61Id()` for + converting between portable IDs and compatible identifiers, i.e., + HTTP(S) URLs under a gateway's */.well-known/apgateway/* path such as + `https://example.com/.well-known/apgateway/did:key:z6Mk.../actor`, + which software without portable ID support can use. + `fromCompatibleEf61Id()` returns `null` for URLs that are not + compatible identifiers, and throws a `TypeError` for malformed ones, + including those with location hints. Converting a compatible + identifier does not authenticate it. [[#833], [#1074]] + + - Added `isGatewayUrl()` and `parseGatewayUrl()`, which check that + a gateway is an HTTP(S) origin without credentials, a path, a query, + or a fragment, as FEP-ef61 requires. + [[#830], [#928], [#1176], [#1190]] + + - Added `withGatewayHints()`, `withoutGatewayHints()`, and + `getGatewayHints()` to add, remove, and read the `@gateway` location + hints of portable IDs, which tell consumers where to retrieve + a referenced portable actor. [[#1159], [#1189]] + + - Added SHA-256 `digestMultibase` and `hl:` hashlink helpers: + `computeDigestMultibase()`, `parseDigestMultibase()`, + `verifyDigestMultibase()`, `createHashlink()`, `parseHashlink()`, + and `verifyHashlink()`. [[#831], [#935]] + + - Added `fetchPortableMedia()`, which retrieves the media of a portable + object through its owner's gateways, or an HTTP(S) resource directly, + and returns it only after verifying its `digestMultibase`. + It limits the response size and rejects private network addresses by + default. [[#1152], [#1182]] + + - Added the FEP-ef61 JSON-LD context to the preloaded contexts, so that + `gateways` and `digestMultibase` can be compacted and expanded + without fetching the context. [[#830], [#928]] + + - Added the `PortableObjectVerifier`, `PortableObjectVerifierOptions`, + `PortableObjectVerification`, and `PortableObjectReferrer` types, + which describe the `verifyPortableObject` option of property + accessors. A verifier receives a fetched document along with its + final URL, the gateways used, and the chain of objects that referred + to it, and can accept a collection without a proof as `unsecured`. + [[#834], [#836], [#1077], [#1084]] + + - Added the `verifyPortableObject` property to + `PropertyPreprocessorContext`, the default verifier that objects + returned by a property preprocessor should use. [[#1107], [#1120]] + + - Changed the `Accept` header that document loaders send when fetching + ActivityPub objects to + `application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"`, + as ActivityPub and [FEP-ef61] gateways require. Previously, the JSON-LD + media type lacked the ActivityStreams profile. [[#288], [#834], [#1077]] - Added the [FEP-7aa9] JSON-LD context to the preloaded context registry so FEP-7aa9 documents can be compacted and expanded without fetching the context remotely. [[#810], [#914]] - - Added helpers for Ed25519 `did:key` DIDs and verification method DID - URLs: `exportDidKey()` exports public keys to base58-btc `did:key` DIDs, - `importDidKey()` imports supported DIDs back to `CryptoKey`, and - `parseDidKeyVerificationMethod()` validates `did:key:z...#z...` - verification methods. - [[#827], [#915]] - - Changed `getDocumentLoader()` to reject HTML and XHTML responses that do not advertise an ActivityPub alternate document with a `FetchError` instead of attempting to parse the HTML as JSON. This makes remote HTML @@ -1575,51 +1274,6 @@ To be released. content type, rather than generic JSON parser crashes. [[#912], [#913]] - - Added `fetchPortableMedia()` to retrieve [FEP-ef61] hashlink media through - an actor's gateways or HTTP(S) media directly, and return the resource only - after verifying its `digestMultibase`. It rejects missing or mismatched - digests, limits response size, and checks private network addresses by - default. [[#288], [#1152], [#1182]] - - - Added to preloaded JSON-LD contexts. - [[#1037], [#1038]] - - - Added the `PortableObjectVerifier`, `PortableObjectVerifierOptions`, - `PortableObjectVerification`, and `PortableObjectReferrer` types, which - describe the `verifyPortableObject` option of property accessors for - [FEP-ef61] portable references. A verifier receives the fetched - document along with its final URL, the gateways used, and the chain of - objects that referred to it, and can accept a document without an - integrity proof as `unsecured`. `verifyPortableObject()` and - `verifyPortableObjectProof()` from `@fedify/fedify` satisfy - `PortableObjectVerifier`. [[#288], [#834], [#836], [#1077], [#1084]] - - - Added the `verifyPortableObject` property to - `PropertyPreprocessorContext`, the default [FEP-ef61] portable object - verifier that objects returned by a property preprocessor should use for - their property accessors. [[#288], [#1107], [#1120]] - - - Added `toCompatibleEf61Id()` and `fromCompatibleEf61Id()` for converting - between [FEP-ef61] portable IDs and compatible identifiers, which are - HTTP(S) URLs under a gateway's fixed `/.well-known/apgateway/` path that - software without portable IRI support can use. `toCompatibleEf61Id()` - removes location hints (`@gateway` query parameters, and the legacy - `gateways` parameter), and `fromCompatibleEf61Id()` returns - `null` for URLs that are not compatible identifiers and throws a - `TypeError` for malformed ones, including those with location hints. - Converting a compatible identifier does not authenticate it; the object's - proof still has to be verified against its DID. [[#288], [#833], [#1074]] - - - Added `withGatewayHints()`, `withoutGatewayHints()`, and - `getGatewayHints()` to add, remove, and read the [FEP-ef61] `@gateway` - location hints of portable IDs, which tell consumers where to retrieve - a referenced portable actor. Use `withGatewayHints()` when referring to - a portable actor, e.g., in `attributedTo` or `to`, instead of editing - the query by hand; it writes each gateway's URI-encoded origin as - FEP-ef61 requires, replaces existing hints, and keeps the other query - parameters. Do not add hints to an object's own `id`. - [[#288], [#1159], [#1189]] - - Changed `getDocumentLoader()` to time out each call after 10 seconds by default. The time limit covers the whole call, including every redirect and alternate document it follows and reading the response body. @@ -1637,18 +1291,6 @@ To be released. byte, or only the status and headers if the body is larger than that. [[#1131], [#1169]] - - Changed the `Accept` header that document loaders send when fetching - ActivityPub objects to - `application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"`, - as ActivityPub and [FEP-ef61] gateways require. Previously, the JSON-LD - media type lacked the ActivityStreams profile. [[#288], [#834], [#1077]] - - - Fixed portable and gateway-compatible ID strings with `.` or `..` path - segments being interpreted as different IDs after URL parsing. Fedify now - rejects these strings because the segments cannot be preserved by its - URL-based APIs. Raw portable ID strings can still be compared without - losing their paths. [[#288], [#1154], [#1186]] - [#828]: https://github.com/fedify-dev/fedify/issues/828 [#831]: https://github.com/fedify-dev/fedify/issues/831 [#833]: https://github.com/fedify-dev/fedify/issues/833 @@ -1658,7 +1300,9 @@ To be released. [#935]: https://github.com/fedify-dev/fedify/pull/935 [#1074]: https://github.com/fedify-dev/fedify/pull/1074 [#1152]: https://github.com/fedify-dev/fedify/issues/1152 +[#1176]: https://github.com/fedify-dev/fedify/issues/1176 [#1182]: https://github.com/fedify-dev/fedify/pull/1182 +[#1190]: https://github.com/fedify-dev/fedify/pull/1190 ### @fedify/vocab-tools diff --git a/FEDERATION.md b/FEDERATION.md index fdd59f06b..79d877717 100644 --- a/FEDERATION.md +++ b/FEDERATION.md @@ -84,9 +84,9 @@ current FEP text in two ways, which may change in Fedify 3.0: Fedify does not implement the [FEP-ae97] gateway endpoints, gateway discovery, synchronization across gateways, key rotation, built-in resolution of DID methods other than `did:key`, or gateways with paths. -Interoperability with other implementations is still being tested. See the -[*Portable objects* chapter][portable objects] of the manual for the full -profile. +Its interoperability with other implementations is described in the next +section. See the [*Portable objects* chapter][portable objects] of the manual +for the full profile. [FEP-ae97]: https://w3id.org/fep/ae97 [portable objects]: https://fedify.dev/manual/portable diff --git a/changes.d/cli/portable-objects.md b/changes.d/cli/portable-objects.md index a02d2ca53..99514f68b 100644 --- a/changes.d/cli/portable-objects.md +++ b/changes.d/cli/portable-objects.md @@ -4,34 +4,36 @@ links: '#1199': https://github.com/fedify-dev/fedify/pull/1199 '#288': https://github.com/fedify-dev/fedify/issues/288 --- - - Added support for [FEP-ef61] portable objects to `fedify lookup`. It now - looks up portable objects by their `ap:` and `ap+ef61:` IDs, compatible - identifiers, and the WebFinger handles of portable actors, and verifies - their Object Integrity Proofs. Previously, - it failed to look up portable IDs, and refused portable objects found - through compatible identifiers as cross-origin objects. The same applies - to the collections that `-t`/`--traverse` traverses and the objects that - `--recurse` follows. When no gateway returns an acceptable object, the - command tells why, e.g., that the object's proof is invalid. + - Added support for [FEP-ef61] portable objects to the `fedify` command. [[#288], [#1156], [#1199]] - - Added the `--gateway` option to `fedify lookup`, `fedify inbox`, and - `fedify webfinger`, which specifies the FEP-ef61 gateways to look up - portable objects from, e.g., for portable IDs without `@gateway` location - hints. [[#288], [#1156], [#1199]] + - `fedify lookup` now looks up portable objects by their `ap:` and + `ap+ef61:` IDs, compatible identifiers, and the WebFinger handles of + portable actors, and verifies their Object Integrity Proofs. + Previously, it failed to look up portable IDs, and refused portable + objects found through compatible identifiers as cross-origin objects. + The same applies to the collections that `-t`/`--traverse` traverses + and the objects that `--recurse` follows. When no gateway returns + an acceptable object, the command tells why, e.g., that the object's + proof is invalid. - - Changed `fedify inbox -f`/`--follow` to follow FEP-ef61 portable actors, - and changed the `-a`/`--accept-follow` option of `fedify inbox` and the - `-a`/`--accept-follow` and `-r`/`--reject-follow` options of `fedify relay` - to accept portable IDs and compatible identifiers, which match the actor - regardless of `@gateway` location hints and the gateway of a compatible - identifier. [[#288], [#1156], [#1199]] + - Added the `--gateway` option to `fedify lookup`, `fedify inbox`, and + `fedify webfinger`, which specifies the gateways to look up portable + objects from, e.g., for portable IDs without `@gateway` location + hints. - - Changed `fedify webfinger` to accept FEP-ef61 portable actor IDs. As such - an ID does not tell which server to ask, the command looks up the actor and - then its WebFinger address, which consists of its `preferredUsername` and - the host of its first gateway, and reports whether the response links back - to the actor. [[#288], [#1156], [#1199]] + - `fedify inbox -f`/`--follow` now follows portable actors, and + the `-a`/`--accept-follow` option of `fedify inbox` and + the `-a`/`--accept-follow` and `-r`/`--reject-follow` options of + `fedify relay` accept portable IDs and compatible identifiers, which + match the actor regardless of `@gateway` location hints and + the gateway of a compatible identifier. + + - `fedify webfinger` now accepts portable actor IDs. As such an ID + does not tell which server to ask, the command looks up the actor + and then its WebFinger address, which consists of its + `preferredUsername` and the host of its first gateway, and reports + whether the response links back to the actor. - Fixed `fedify lookup --recurse` reporting a timeout or another network failure of the first object or of a linked object as a possibly private diff --git a/changes.d/fedify/compatible-id-documents.md b/changes.d/fedify/compatible-id-documents.md deleted file mode 100644 index b379738e5..000000000 --- a/changes.d/fedify/compatible-id-documents.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -links: - '#1093': https://github.com/fedify-dev/fedify/issues/1093 - '#1105': https://github.com/fedify-dev/fedify/pull/1105 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Changed Fedify to treat documents whose IDs are [FEP-ef61] compatible - identifiers, such as - `https://gw.example/.well-known/apgateway/did:key:z6Mk.../actor`, as the - portable objects they stand for, as FEP-ef61 requires. Some - implementations, e.g., tootik, identify their portable actors this way. - Previously, Fedify trusted such documents by the web origin that served - them, so any server could act as - `https://evil.example/.well-known/apgateway/did:key:z6MkAlice/actor` - without a proof by Alice's DID. [[#288], [#1093], [#1105]] - - - `verifyPortableObjectProof()` now verifies a document whose `@id` is - a compatible identifier against the DID in it, instead of reporting - it as `notPortableObject`. The proof is verified over the document - as is. - - - Inboxes now reject an activity of an actor whose ID is a compatible - identifier with `401 Unauthorized` unless it has a valid Object - Integrity Proof made by the actor's DID, as they already did for - actors with `ap:` IDs. Likewise, an activity whose own ID is an - `ap:` URI or a compatible identifier is rejected unless its proof is - made by the DID of that ID, and embedded maps with compatible - identifiers need their own proofs as embedded portable objects do. - The exception is a key embedded in the `publicKey` or - `assertionMethod` of a verified portable actor, such as a gateway - key, whose ID is the actor's compatible identifier plus a fragment; - the actor's proof covers it. - Activities of actors that publish compatible identifiers without - signing them, or whose DIDs use key types Fedify does not support, - are no longer accepted. - - - `verifyObject()` now accepts an Object Integrity Proof made by a DID - as authenticating an attribution or actor whose compatible identifier - has that DID, and never authenticates such an attribution by a key at - an ordinary URL. - - - HTTP Signature verification now resolves a gateway key whose actor - document has a compatible identifier as its ID the same way as for - actors with `ap:` IDs, and rejects the key if the document does not - have a valid proof by the actor's DID, instead of trusting the - gateway's web origin. A key at an ordinary URL that claims - a portable actor as its owner or controller is no longer that actor's - key, and `getKeyOwner()` and `doesActorOwnKey()` no longer resolve - portable actors by web origin. - - - `Context.sendActivity()` now applies the compound-proof key selection - to activities that embed objects with compatible identifiers, as it - does for embedded objects with `ap:` IDs, so that Fedify inboxes - accept what it sends. - - - Changed HTTP Signature verification to accept a gateway key of a portable - actor that the actor's signed document embeds only in its `publicKey`, - with the actor as its `owner`, when no `assertionMethod` entry has the - key ID. Some publishers, e.g., tootik, list their RSA keys only there. - A document that has more than one entry with the key ID in either - property is rejected. [[#288], [#1093], [#1105]] - - - Changed the gateway trust policy for unsecured portable collections in - `verifyPortableObject()` to accept collections and owners identified by - compatible identifiers. An owner with a compatible identifier is fetched - through the gateway that the identifier names first, unless the - `gateways` option is given. [[#288], [#1093], [#1105]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/compatible-id-publishing.md b/changes.d/fedify/compatible-id-publishing.md deleted file mode 100644 index 8dfb3b157..000000000 --- a/changes.d/fedify/compatible-id-publishing.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -links: - '#1106': https://github.com/fedify-dev/fedify/issues/1106 - '#1109': https://github.com/fedify-dev/fedify/pull/1109 - '#1155': https://github.com/fedify-dev/fedify/issues/1155 - '#1188': https://github.com/fedify-dev/fedify/pull/1188 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added support for publishing [FEP-ef61] portable actors and objects whose - IDs are compatible identifiers, such as - `https://example.com/.well-known/apgateway/did:key:z6Mk.../actor`, for - interoperability with software that cannot handle `ap:` URIs. Fedify now - treats such an actor or object as portable wherever it publishes one, as - it already did for those with `ap:` or `ap+ef61:` IDs. Build compatible - identifiers with `toCompatibleEf61Id()` and the first gateway of the - actor before signing the documents; portable IDs remain the recommended - form. [[#288], [#1106], [#1109]] - - - `Context.sendActivity()` now requires an activity of an actor whose - ID is a compatible identifier to have an `ap:` or `ap+ef61:` ID or - a compatible identifier of the actor's DID, and signs an unsigned one - only with the key whose ID is a DID URL for that DID, instead of - sending activities that FEP-ef61 receivers reject. A malformed - compatible actor or activity ID, e.g., one with `@gateway` location - hints, is rejected with a `TypeError`. - - - The FEP-ef61 gateway endpoint now serves an object whose ID is - a compatible identifier of the requested portable object, on any - gateway, instead of responding with `404 Not Found`. - - - Portable inboxes now accept deliveries on behalf of actors whose IDs - or inboxes are compatible identifiers, and forward each activity to - the other gateways at most once whether its ID is an `ap:` URI or - a compatible identifier. - - - WebFinger now takes the domain of such an actor's address from its - first gateway, and uses its ID as the `self` link. - - - Actor dispatchers no longer warn that such an actor's ID or collection - URIs do not match the URIs that `Context` builds, but warn if its ID - is a malformed compatible identifier or is not on its first gateway, - as FEP-ef61 requires. - - - Fedify now warns when a served object, or a sent activity and its - embedded objects, use compatible identifiers away from the owner's - first gateway when that gateway is known locally. The warning does - not change what is served or sent. [[#1155], [#1188]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/compound-portable-proofs.md b/changes.d/fedify/compound-portable-proofs.md deleted file mode 100644 index c14939a1e..000000000 --- a/changes.d/fedify/compound-portable-proofs.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -links: - '#1041': https://github.com/fedify-dev/fedify/pull/1041 - '#1094': https://github.com/fedify-dev/fedify/issues/1094 - '#1102': https://github.com/fedify-dev/fedify/pull/1102 - '#1133': https://github.com/fedify-dev/fedify/issues/1133 - '#1138': https://github.com/fedify-dev/fedify/pull/1138 - '#1151': https://github.com/fedify-dev/fedify/issues/1151 - '#1198': https://github.com/fedify-dev/fedify/pull/1198 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#938': https://github.com/fedify-dev/fedify/issues/938 ---- - - Security: Inbox processing now independently verifies each portable actor, - activity, and object in a compound JSON document against its own map-local - Object Integrity Proof before dispatch. A valid outer proof no longer - authenticates an unsigned or invalid nested portable object. - Portable documents with proof sets or which exceed the inbox compound - traversal limits are rejected as unsupported. The top-level Linked - Data Signature of an activity is not part of any proof input, so an - activity that carries both proofs and a Linked Data Signature is - accepted. An unsigned key embedded in the `publicKey` or - `assertionMethod` of a verified portable actor needs no proof of its own - if its ID is the actor's compatible identifier or `ap:` or `ap+ef61:` URI - plus a non-empty fragment, as with the keys that [FEP-ae97] clients make - for their actors, which Mitra serves under `ap:` URIs. - [[#288], [#938], [#1041], [#1094], [#1102], [#1133], [#1138]] - - The map-local profile is Fedify's interim interpretation, since neither - FEP-8b32 nor Verifiable Credential Data Integrity defines the boundaries - of embedded proofs yet, and may change in Fedify 3.0. The new - [*Portable objects*][portable objects] chapter of the manual describes - the [FEP-ef61] profile that Fedify supports, including this and the parts - of FEP-ef61 that Fedify does not implement. [[#288], [#1151], [#1198]] - -[FEP-ae97]: https://w3id.org/fep/ae97 -[portable objects]: https://fedify.dev/manual/portable -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/compound-proof-key-selection.md b/changes.d/fedify/compound-proof-key-selection.md deleted file mode 100644 index a3f48584e..000000000 --- a/changes.d/fedify/compound-proof-key-selection.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -links: - '#1041': https://github.com/fedify-dev/fedify/pull/1041 - '#1045': https://github.com/fedify-dev/fedify/issues/1045 - '#1073': https://github.com/fedify-dev/fedify/pull/1073 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Changed `Context.sendActivity()` so that an activity containing - [FEP-ef61] portable objects gets at most one Object Integrity Proof. - Previously Fedify signed every outgoing activity once for each Ed25519 - key, which produced a proof set that Fedify's own inbox rejects in a - compound portable document. [[#288], [#1041], [#1045], [#1073]] - - - An activity that already carries a proof is sent as is. - - With several Ed25519 keys, a portable activity is signed only by the - key whose ID is a DID URL for the activity's DID. - - If no single key qualifies, or a non-portable activity that embeds - portable objects has several Ed25519 keys, `sendActivity()` rejects - with a `TypeError` before anything is delivered or queued. Pass - explicit sender keys with exactly one Ed25519 key, or sign the - activity with `signObject()` beforehand. - - An activity with portable objects in which any map carries a proof - set is rejected the same way. - - Activities without portable objects are signed as before. - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/hashlink-media-serving.md b/changes.d/fedify/hashlink-media-serving.md deleted file mode 100644 index 3cb24193c..000000000 --- a/changes.d/fedify/hashlink-media-serving.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -links: - '#1080': https://github.com/fedify-dev/fedify/pull/1080 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#838': https://github.com/fedify-dev/fedify/issues/838 ---- - - Added serving of resources addressed by [FEP-ef61] hashlinks, such as - media attached to portable objects, through the gateway endpoint, e.g., - `GET /.well-known/apgateway/hl:zQmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n`. - Register a dispatcher with the new - `Federatable.setHashlinkMediaDispatcher()` method; it receives the parsed - hashlink and its SHA-256 digest as a `HashlinkMediaRequest` object and - returns a `Response`, which Fedify sends as is so that it can be streamed, - or `null` for `404 Not Found`. Fedify responds with `400 Bad Request` to - malformed hashlinks without calling the dispatcher, and does not verify the - response body, so the dispatcher must serve only the resource whose bytes - hash to the requested digest. Applications that do not register the - dispatcher are unaffected. [[#288], [#838]] - - - Added `hashlink_media` to the values of the `fedify.endpoint` metric - attribute, used for requests to the hashlink media endpoint. - [[#288], [#838], [#1080]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/imported-unreleased.md b/changes.d/fedify/imported-unreleased.md index e808e467e..7a0895e14 100644 --- a/changes.d/fedify/imported-unreleased.md +++ b/changes.d/fedify/imported-unreleased.md @@ -9,13 +9,8 @@ links: '#806': https://github.com/fedify-dev/fedify/pull/806 '#812': https://github.com/fedify-dev/fedify/pull/812 '#823': https://github.com/fedify-dev/fedify/issues/823 - '#827': https://github.com/fedify-dev/fedify/issues/827 - '#829': https://github.com/fedify-dev/fedify/issues/829 - '#832': https://github.com/fedify-dev/fedify/issues/832 - '#915': https://github.com/fedify-dev/fedify/pull/915 '#923': https://github.com/fedify-dev/fedify/pull/923 '#925': https://github.com/fedify-dev/fedify/pull/925 - '#926': https://github.com/fedify-dev/fedify/pull/926 '#927': https://github.com/fedify-dev/fedify/pull/927 '#930': https://github.com/fedify-dev/fedify/issues/930 '#934': https://github.com/fedify-dev/fedify/pull/934 @@ -28,26 +23,6 @@ links: `challenge` values through `VerifyProofOptions` to prevent cross-domain or replay use. [[#968]] - - Added `verifyPortableObjectProof()` to enforce the [FEP-ef61] proof policy - for portable actors, activities, objects, and signed collections. Its - detailed result distinguishes documents outside the policy, unsecured - collections, missing or invalid [FEP-8b32] proofs, unsupported verification - methods, DID authority mismatches, and successful verification. - [[#832], [#968]] - - - Updated `verifyObject()` so [FEP-8b32] proofs signed by `did:key` - verification methods can authenticate portable objects whose owner is an - `ap:` or `ap+ef61:` URI with the same [FEP-fe34] cryptographic origin. - [[#829], [#926]] - - - Added local `did:key` verification method resolution for - [FEP-8b32] Object Integrity Proofs. `verifyProof()` can now verify - Ed25519 `eddsa-jcs-2022` proofs whose `verificationMethod` is a - `did:key:z...#z...` DID URL without fetching the verification method - as a remote JSON-LD document, which is required for [FEP-ef61] - portable objects. - [[#827], [#915]] - - Added support for the [ActivityPub Media Upload extension] so that servers can accept client-to-server media uploads: [[#754], [#927]] @@ -119,8 +94,5 @@ links: `esnext.temporal` lib reference. [[#823], [#925]] -[FEP-ef61]: https://w3id.org/fep/ef61 -[FEP-8b32]: https://w3id.org/fep/8b32 -[FEP-fe34]: https://w3id.org/fep/fe34 [ActivityPub Media Upload extension]: https://www.w3.org/wiki/SocialCG/ActivityPub/MediaUpload [Standard Schema]: https://standardschema.dev/ diff --git a/changes.d/fedify/outbox-portable-actor-references.md b/changes.d/fedify/outbox-portable-actor-references.md deleted file mode 100644 index 9909a13ad..000000000 --- a/changes.d/fedify/outbox-portable-actor-references.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -links: - '#1159': https://github.com/fedify-dev/fedify/issues/1159 - '#1189': https://github.com/fedify-dev/fedify/pull/1189 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Fixed outbox listeners rejecting a posted activity with - `400 Bad Request` when its `actor` referred to an [FEP-ef61] portable - outbox owner in another form than the owner's ID, e.g., with `@gateway` - location hints, another URI scheme or DID encoding, or as a compatible - identifier on another gateway. Portable actor IDs are now compared by - their canonical forms, while other actor IDs still have to match exactly. - [[#288], [#1159], [#1189]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/portable-actor-gateways.md b/changes.d/fedify/portable-actor-gateways.md deleted file mode 100644 index 476e13ef3..000000000 --- a/changes.d/fedify/portable-actor-gateways.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -links: - '#1148': https://github.com/fedify-dev/fedify/issues/1148 - '#1178': https://github.com/fedify-dev/fedify/pull/1178 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added validation of the `gateways` of [FEP-ef61] portable actors, which - FEP-ef61 requires to be a non-empty list of HTTP(S) URIs with an empty - path, query, and fragment. `verifyPortableObjectProof()` and - `verifyPortableObject()` now reject a portable actor whose `gateways` is - missing or empty, or has any other item, with the new `invalidGateways` - reason, even if its proofs are valid, so such an actor is no longer looked - up, accepted in an inbox, or served through the gateway endpoint. If an - actor dispatcher returns a portable actor with such `gateways`, Fedify - logs a warning. An incoming activity that embeds an actor with a gateway - that has a path, query, or fragment is now rejected with - `400 Bad Request` as malformed, instead of failing with an error. - [[#288], [#1148], [#1178]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/portable-actor-uri.md b/changes.d/fedify/portable-actor-uri.md deleted file mode 100644 index a5e7648fc..000000000 --- a/changes.d/fedify/portable-actor-uri.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -links: - '#1114': https://github.com/fedify-dev/fedify/pull/1114 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#841': https://github.com/fedify-dev/fedify/issues/841 ---- - - Added the `Context.getPortableActorUri()` method, which builds the - [FEP-ef61] portable ID of an actor from its actor dispatcher's path and - a DID, e.g., `ap+ef61://did:key:z6Mk.../users/alice`. Like - `Context.getPortableObjectUri()`, the DID can be omitted while handling - a gateway request, in which case the DID in the request path is used. - Custom implementations of the `Context` interface need to implement the - new method. [[#288], [#841], [#1114]] - - - The actor dispatcher now serves portable actors through the FEP-ef61 - gateway endpoint, e.g., - `GET /.well-known/apgateway/did:key:z6Mk.../users/alice`, the same way - object dispatchers serve portable objects, so a portable actor whose ID - `Context.getPortableActorUri()` builds can be fetched at its compatible - identifier without registering an extra object dispatcher. The actor is - served only if its ID canonically equals the requested portable ID and it - has an Object Integrity Proof made with a key of the DID, and - `RequestContext.portableRequest` is set for such requests. Applications - that do not have portable actors are unaffected, except that their actor - dispatchers may be called for such requests. [[#288], [#841], [#1114]] - - - `Context.getPortableActorUri()`, `Context.getPortableObjectUri()`, and - `Context.getPortableInboxUri()` now throw a `TypeError` if the DID is - a `did:key` DID that is not encoded in base58-btc, as FEP-ef61 requires, - so that the same key does not yield two different portable IDs. Use - `exportDidKey()` from `@fedify/vocab-runtime` to make such DIDs. - Likewise, the gateway endpoint responds with `400 Bad Request` to - requests whose path has such a DID. [[#288], [#841], [#1114]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/portable-chain-verifiers.md b/changes.d/fedify/portable-chain-verifiers.md deleted file mode 100644 index 2bb8831f7..000000000 --- a/changes.d/fedify/portable-chain-verifiers.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -links: - '#1107': https://github.com/fedify-dev/fedify/issues/1107 - '#1120': https://github.com/fedify-dev/fedify/pull/1120 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added the `Context.verifyPortableObject` property, the [FEP-ef61] - portable object policy of the context: `verifyPortableObject()` with the - context's document loader and context loader. Since it has the same name - as the `verifyPortableObject` option of property accessors, passing - a context as their options, e.g., `await create.getObject(ctx)`, now - verifies portable objects that they dereference. Previously, - `create.getObject(ctx)` on an activity whose ID is a compatible - identifier, such as one from tootik, fetched the object it refers to as - an ordinary HTTP(S) URL and trusted it because of its origin. Note that - this also applies to objects with ordinary HTTP(S) IDs: their references - to compatible identifiers are now verified as portable objects when you - pass a context. [[#288], [#1107], [#1120]] - - - Inboxes now parse received activities with `Context.verifyPortableObject` - as their default verifier, so accessors called without options in inbox - listeners, e.g., `await create.getObject()`, verify portable objects - too, including for queued activities and for activities authenticated - by Object Integrity Proofs. The activities passed to the - `onOutboxError` callback have the default as well. - [[#288], [#1107], [#1120]] - - - Changed `Context.lookupObject()` to use `Context.verifyPortableObject` - instead of `verifyPortableObjectProof()` as the default - `verifyPortableObject` option, so that it also accepts an unsecured - portable collection served by a gateway that its owner lists, as - accessors do. Pass `verifyPortableObject: verifyPortableObjectProof` to - accept only objects with proofs. The returned object uses the policy by - default for its property accessors. `Context.traverseCollection()` also - uses `Context.verifyPortableObject` by default. [[#288], [#1107], [#1120]] - - - Added the `verifyPortableObject` option to `VerifyObjectOptions`. It is - not used to verify the given object; the returned object uses it by - default for its property accessors. [[#288], [#1107], [#1120]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/portable-collection-trust.md b/changes.d/fedify/portable-collection-trust.md deleted file mode 100644 index 95cbbcd75..000000000 --- a/changes.d/fedify/portable-collection-trust.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -links: - '#1084': https://github.com/fedify-dev/fedify/pull/1084 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#836': https://github.com/fedify-dev/fedify/issues/836 ---- - - Added `verifyPortableObject()`, which applies the [FEP-ef61] trust policy - to portable objects fetched through gateways. It verifies Object - Integrity Proofs like `verifyPortableObjectProof()`, and also accepts - a portable collection or collection page without a proof if it was - served by a gateway listed in the `gateways` of the actor that owns it. - The owner must be the actor whose `inbox`, `outbox`, `followers`, - `following`, or `liked` it is, as confirmed by the owner's signed actor - document. Pass it as the `verifyPortableObject` option of property - accessors and `traverseCollection()` instead of - `verifyPortableObjectProof()` to read portable actors' collections, such - as their outboxes. The new `VerifyPortableObjectOptions`, - `VerifyPortableObjectResult`, and `VerifyPortableObjectFailureReason` - types describe it. [[#288], [#836], [#1084]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/portable-collections.md b/changes.d/fedify/portable-collections.md deleted file mode 100644 index 285e3fbb3..000000000 --- a/changes.d/fedify/portable-collections.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -links: - '#1111': https://github.com/fedify-dev/fedify/issues/1111 - '#1142': https://github.com/fedify-dev/fedify/pull/1142 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added serving of [FEP-ef61] portable collections through the gateway - endpoint, e.g., - `GET /.well-known/apgateway/did:key:z6Mk.../users/alice/outbox`, by the - existing collection dispatchers, including the inbox collection, so that a - portable actor's outbox and other collections are no longer tied to a - single server. Fedify serves such a collection only if the actor whose - identifier is in its path is a portable actor under the requested DID whose - corresponding property, e.g., `outbox`, refers to the collection; otherwise - it responds with `404 Not Found`. The collection and its pages keep the - actor's form of the ID, a portable ID or a compatible identifier, identify - pages with the `cursor` query parameter, and have `attributedTo` set to the - actor. The collection's `authorize()` predicate is applied before anything - is dispatched. The collection itself is served without an Object Integrity - Proof, as FEP-ef61 allows, but it is refused with - `500 Internal Server Error` if it embeds a portable actor, activity, or - object without a valid proof made with a key of the DID in its ID. - Applications without portable actors are unaffected, except that their - actor dispatchers may be called for such requests. - [[#288], [#1111], [#1142]] - - - Added the `Context.getPortableOutboxUri()`, - `Context.getPortableFollowingUri()`, `Context.getPortableFollowersUri()`, - `Context.getPortableLikedUri()`, `Context.getPortableFeaturedUri()`, - `Context.getPortableFeaturedTagsUri()`, and - `Context.getPortableCollectionUri()` methods, which build the portable IDs - of an actor's collections and of custom collections from the same paths - as their non-portable counterparts and a DID. On a `RequestContext`, the - DID defaults to the one in the gateway request. Custom implementations of - the `Context` interface need to implement the new methods. - [[#288], [#1111], [#1142]] - - - Added the `CustomCollectionCallbackSetters.mapPortableOwner()` method and - the `PortableCollectionOwnerMapper` type. A custom collection is served - through the FEP-ef61 gateway endpoint only if this callback maps it to - a portable actor under the requested DID. [[#288], [#1111], [#1142]] - - - Changed the actor dispatcher to warn when a portable actor's collection - property is a portable ID or a compatible identifier that does not match - the one that the corresponding `Context.getPortable*Uri()` method builds, - as the gateway endpoint would not serve the collection. - [[#288], [#1111], [#1142]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/portable-delivery.md b/changes.d/fedify/portable-delivery.md deleted file mode 100644 index 2e62c9205..000000000 --- a/changes.d/fedify/portable-delivery.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -links: - '#1147': https://github.com/fedify-dev/fedify/issues/1147 - '#1180': https://github.com/fedify-dev/fedify/pull/1180 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added delivery to [FEP-ef61] portable inboxes, i.e., `ap:` and `ap+ef61:` - URIs, to `Context.sendActivity()` and `InboxContext.forwardActivity()`. - They deliver an activity to the compatible identifier of such an inbox - on one of the recipient's gateways, e.g., - `https://gateway.example/.well-known/apgateway/did:key:z6Mk.../actor/inbox`. - The gateways are taken from the recipient's `gateways`, or, if it has no - valid gateway, from the `@gateway` location hints of the inbox URI, and - at most five of them are tried one after another until one accepts the - activity. Previously, such a delivery failed with - `UrlError: Unsupported protocol: ap+ef61:`. A recipient with no gateway - to deliver through is skipped with a warning. [[#288], [#1147], [#1180]] - - - A gateway that fails with a permanent failure status, such as - `404 Not Found`, is not tried again for the activity. If no gateway - accepts the activity, the whole round of gateways counts as one - attempt of the retry policy. - - - The `preferSharedInbox` option is ignored for recipients with portable - inboxes, the `excludeBaseUris` option is compared with the origins of - their gateways, and deliveries to a portable inbox are ordered by the - actor's DID when the `orderingKey` option is given. - - - Queue workers of older Fedify versions deliver queued activities to - portable inboxes only through the first gateway, so upgrade them - before the servers that enqueue deliveries. - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/portable-dot-segments.md b/changes.d/fedify/portable-dot-segments.md deleted file mode 100644 index 7886b2adc..000000000 --- a/changes.d/fedify/portable-dot-segments.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#1154': https://github.com/fedify-dev/fedify/issues/1154 - '#1186': https://github.com/fedify-dev/fedify/pull/1186 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Fixed portable actor and object URI helpers so a dispatcher identifier - containing a `.` or `..` path segment raises a `TypeError` instead of - silently producing another object's ID. Use identifiers without such - segments. [[#288], [#1154], [#1186]] diff --git a/changes.d/fedify/portable-gateway-keys.md b/changes.d/fedify/portable-gateway-keys.md deleted file mode 100644 index 5851d59c6..000000000 --- a/changes.d/fedify/portable-gateway-keys.md +++ /dev/null @@ -1,93 +0,0 @@ ---- -links: - '#1095': https://github.com/fedify-dev/fedify/issues/1095 - '#1096': https://github.com/fedify-dev/fedify/issues/1096 - '#1099': https://github.com/fedify-dev/fedify/pull/1099 - '#1119': https://github.com/fedify-dev/fedify/pull/1119 - '#1123': https://github.com/fedify-dev/fedify/issues/1123 - '#1132': https://github.com/fedify-dev/fedify/issues/1132 - '#1134': https://github.com/fedify-dev/fedify/pull/1134 - '#1164': https://github.com/fedify-dev/fedify/pull/1164 - '#1165': https://github.com/fedify-dev/fedify/pull/1165 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#840': https://github.com/fedify-dev/fedify/issues/840 ---- - - Added support for HTTP Signature keys that gateways use on behalf of - [FEP-ef61] portable actors, which Fedify calls *gateway keys*. Register - the new `ActorCallbackSetters.mapPortableActorId()` callback to tell - Fedify which actors are portable, and `Context.getActorKeyPairs()` then - identifies their dispatched key pairs by the actor's compatible identifier - on this server, e.g., - `https://example.com/.well-known/apgateway/did:key:z6Mk.../actors/alice#main-key`, - with the portable actor as their owner, and with the same IDs for their - `CryptographicKey` and `Multikey` forms so that they can be listed in the - actor's `assertionMethods` as FEP-ef61 requires. Requests made on behalf - of such actors, including activity deliveries and signed fetches, are - signed with these keys. The new `PortableActorIdMapper` type describes the - callback. [[#288], [#840], [#1099]] - - - Changed HTTP Signature verification to accept a gateway key of a portable - actor if the actor's document, fetched from the key ID, has a valid Object - Integrity Proof made by the actor's DID, embeds the key in its - `assertionMethod`, and lists the gateway in its `gateways`. Such a key is - owned by the portable actor, so `RequestContext.getSignedKeyOwner()`, - `getKeyOwner()`, and `doesActorOwnKey()` return or match the portable - actor. Given the very key that HTTP Signature verification returned, - they take the actor from the document it verified rather than fetching - and verifying the document again. The document may list the key under - the key ID itself or under the `ap:` URI with the same canonical ID, as - Mitra does, but not under both, nor under a compatible identifier on - another gateway. Previously, no gateway key of a portable actor could be - verified. [[#288], [#840], [#1096], [#1099], [#1123], [#1134], [#1164]] - - - Changed HTTP Signature verification to accept a key of a portable actor - itself whose ID is an `ap:` or `ap+ef61:` URI, e.g., - `ap://did:key:z6Mk.../actor?@gateway=https%3A%2F%2Fexample.com#main-key`. - Fedify fetches the actor's document from the gateways in the key ID's - `@gateway` location hints, or, without them, asks the document loader for - the `ap:` URI itself, and accepts the key if the document has a valid - Object Integrity Proof made by the actor's DID, embeds the key under - the `ap:` URI, and has a valid gateway. Since the signer chooses the - hints, only the first three are followed, and all the gateways share - a timeout of ten seconds; a lookup that runs out of time is reported as - a `keyFetchError` without an HTTP status. Such a key is used only for - HTTP Signatures, and is owned by the portable actor like a gateway key. - Keys at `ap:` URIs are never used to make Object Integrity Proofs or - Linked Data Signatures either. [[#288], [#1096], [#1132], [#1134], [#1165]] - - - Changed inboxes to reject activities of portable actors that do not have - a valid Object Integrity Proof made by the actor's DID with - `401 Unauthorized`, even if the request has a valid HTTP Signature or the - activity has a valid Linked Data Signature. [[#288], [#840], [#1099]] - - - Changed `Context.sendActivity()` so that keys whose IDs are FEP-ef61 - compatible identifiers, such as gateway keys, never make Object Integrity - Proofs or Linked Data Signatures; they only sign HTTP requests. Also, - activities of portable actors never get Linked Data Signatures, and have - to have portable IDs of the actors' DIDs, and an unsigned portable - activity is signed only by a key whose ID is a DID URL for its DID, even - if it is the only Ed25519 key. In these cases `sendActivity()` rejects - with a `TypeError` before anything is delivered or queued. Sign - portable activities with `signObject()` beforehand, or pass the DID's key - as an explicit sender key. [[#288], [#840], [#1099]] - - - Changed key lookups so that keys whose IDs are FEP-ef61 compatible - identifiers are cached apart for each purpose, as whether such a key is - valid depends on what it is used for: a gateway key cached for an HTTP - Signature is never used for an Object Integrity Proof or a Linked Data - Signature, and a key rejected for one of them is not rejected for - the others. A failure to fetch such a key, e.g., a network error or - `404 Not Found`, fails every purpose alike and is cached like that of any - other key. A gateway key is cached for an hour at most, and never - beyond the expiration of the proof on the actor's document, since - the actor can drop the gateway from its document at any time. - `fetchKey()` and `fetchKeyDetailed()` do not resolve gateway keys of - portable actors. - [[#288], [#840], [#1095], [#1099], [#1119]] - - - Only the key cache that Fedify's inbox uses caches keys at compatible - identifiers apart for each purpose. A custom `KeyCache` passed to - `verifyRequest()`, `fetchKey()`, and the like caches only the - failures to fetch them. - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/portable-inbox.md b/changes.d/fedify/portable-inbox.md deleted file mode 100644 index 173f8801d..000000000 --- a/changes.d/fedify/portable-inbox.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -links: - '#1092': https://github.com/fedify-dev/fedify/pull/1092 - '#1100': https://github.com/fedify-dev/fedify/issues/1100 - '#1101': https://github.com/fedify-dev/fedify/issues/1101 - '#1104': https://github.com/fedify-dev/fedify/pull/1104 - '#1110': https://github.com/fedify-dev/fedify/pull/1110 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#839': https://github.com/fedify-dev/fedify/issues/839 ---- - - Added delivery to [FEP-ef61] portable inboxes through the gateway endpoint, - e.g., `POST /.well-known/apgateway/did:key:z6Mk.../users/alice/inbox`. - Existing inbox listeners handle such a delivery with the path after the - DID, so the inbox path `/users/{identifier}/inbox` also receives - deliveries to the portable inbox - `ap+ef61://did:key:z6Mk.../users/alice/inbox`. Fedify accepts a delivery - only if the actor dispatcher returns, for the identifier, a portable actor - with the same DID whose `inbox` is the requested portable inbox and whose - `gateways` include this server; otherwise, it responds with - `404 Not Found`. Applications without portable actors are unaffected. - [[#288], [#839], [#1092]] - - - Fedify now forwards an activity delivered to a portable inbox to the same - inbox on the actor's other gateways, as FEP-ef61 recommends, if the - activity is authenticated by its own Object Integrity Proof or Linked Data - Signature. Each activity is forwarded to each gateway at most once, which - requires a `KvStore` that supports `cas()`; with other stores, Fedify logs - a warning and does not forward. Forwarded requests are signed with HTTP - Signatures by this server's gateway key for the actor if - `mapPortableActorId()` maps the recipient to the same portable actor and - the key pairs dispatcher returns an RSA key pair for it, and are sent - unsigned otherwise. An activity is not forwarded back to the gateway that - forwarded it if the delivery is signed by that gateway with its gateway - key for the actor, which costs fetching the actor document from that - gateway. Configure the `origin` option on gateways so that Fedify can - tell which gateway it is regardless of the `Host` header. - [[#288], [#839], [#1092], [#1100], [#1101], [#1104], [#1110]] - - - Added the `Context.getPortableInboxUri()` method, which builds the portable - inbox ID of an actor from the inbox path and a DID. Custom - implementations of the `Context` interface need to implement the new - method. [[#288], [#839], [#1092]] - - - Added the `FederationOptions.portableInboxForwarding` option, whose - `maxTargets`, `ttl`, and `deadline` properties change how many gateways - a delivery is forwarded to (10 by default; `0` turns off forwarding), how - long forwarded activities are remembered (30 days by default), and how - long a delivery waits for forwarding without an outbox queue, and for - identifying the gateway that forwarded it (10 seconds by default). - [[#288], [#839], [#1092], [#1101], [#1110]] - - - Added the `FederationKvPrefixes.portableInboxForwarding` option, the key - prefix for remembering forwarded activities, which defaults to - `["_fedify", "portableInboxForwarding"]`. [[#288], [#839], [#1092]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/portable-object-serving.md b/changes.d/fedify/portable-object-serving.md deleted file mode 100644 index 04490c38c..000000000 --- a/changes.d/fedify/portable-object-serving.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -links: - '#1076': https://github.com/fedify-dev/fedify/pull/1076 - '#1113': https://github.com/fedify-dev/fedify/issues/1113 - '#1124': https://github.com/fedify-dev/fedify/pull/1124 - '#1153': https://github.com/fedify-dev/fedify/issues/1153 - '#1183': https://github.com/fedify-dev/fedify/pull/1183 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#835': https://github.com/fedify-dev/fedify/issues/835 ---- - - Added serving of [FEP-ef61] portable objects through the gateway endpoint, - e.g., `GET /.well-known/apgateway/did:key:z6Mk.../notes/123`. Existing - object dispatchers serve such a request with the path after the DID, so - the object dispatcher registered for `/notes/{id}` serves the portable - object `ap+ef61://did:key:z6Mk.../notes/123`. Fedify responds with - `404 Not Found` unless the dispatcher returns an object with that ID, and - refuses to serve a portable actor, activity, or object that does not have - an Object Integrity Proof made with a key of the DID. As FEP-ef61 - forbids gateways to serve a non-public object to anyone but its intended - audience, and a gateway may store objects that it did not create, Fedify - also responds with `404 Not Found` unless the object is publicly - addressed, i.e., its `to`, `cc`, `bto`, `bcc`, or `audience` has - the public collection, or is an actor. To serve non-public portable - objects to their audience, set an authorization predicate on the object - dispatcher, e.g., one that checks the request with the new - `RequestContext.isSignedByAudience()` method; the predicate then decides - who may retrieve the dispatcher's portable objects, and Fedify responds to - the requests that it allows with `Cache-Control: private`. Applications - that do not serve portable objects are unaffected, except that their - object dispatchers may be called for such requests. - [[#288], [#835], [#1076], [#1153], [#1183]] - - - Added the `RequestContext.isSignedByAudience()` method, which checks - whether the request is signed by an actor in the audience of an object, - comparing [FEP-ef61] portable IDs canonically, and the - `IsSignedByAudienceOptions` interface. Its `isMember` option checks - the members of collections such as followers, which Fedify cannot tell - by itself. Custom implementations of the `RequestContext` interface need - to implement the new method. [[#288], [#1153], [#1183]] - - - Added the `Context.getPortableObjectUri()` method, which builds the - portable ID of an object from its object dispatcher's path and a DID, - and the `RequestContext.portableRequest` property, which tells an object - dispatcher the DID and ID of the requested portable object. Custom - implementations of the `Context` interface need to implement the new - method. [[#288], [#835], [#1076]] - - - Added serving of tombstones of [FEP-ef61] portable objects and actors - through the gateway endpoint with `410 Gone`, as for ordinary objects, - so that other gateways and consumers can tell a deleted portable object - from one that the gateway never stored. A `Tombstone` that an object - dispatcher or the actor dispatcher returns for such a request is served - with `410 Gone` if its ID is the requested portable ID and it has - an Object Integrity Proof made with a key of the DID, and with - `404 Not Found` if it has no proof. Like other portable objects, - a tombstone from an object dispatcher without an authorization predicate - needs public addressing to be served. - [[#288], [#1113], [#1124], [#1153], [#1183]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/portable-objects.md b/changes.d/fedify/portable-objects.md new file mode 100644 index 000000000..c1f4bf21d --- /dev/null +++ b/changes.d/fedify/portable-objects.md @@ -0,0 +1,362 @@ +--- +links: + '#1041': https://github.com/fedify-dev/fedify/pull/1041 + '#1044': https://github.com/fedify-dev/fedify/issues/1044 + '#1045': https://github.com/fedify-dev/fedify/issues/1045 + '#1051': https://github.com/fedify-dev/fedify/pull/1051 + '#1073': https://github.com/fedify-dev/fedify/pull/1073 + '#1076': https://github.com/fedify-dev/fedify/pull/1076 + '#1080': https://github.com/fedify-dev/fedify/pull/1080 + '#1082': https://github.com/fedify-dev/fedify/pull/1082 + '#1084': https://github.com/fedify-dev/fedify/pull/1084 + '#1092': https://github.com/fedify-dev/fedify/pull/1092 + '#1093': https://github.com/fedify-dev/fedify/issues/1093 + '#1094': https://github.com/fedify-dev/fedify/issues/1094 + '#1095': https://github.com/fedify-dev/fedify/issues/1095 + '#1096': https://github.com/fedify-dev/fedify/issues/1096 + '#1099': https://github.com/fedify-dev/fedify/pull/1099 + '#1100': https://github.com/fedify-dev/fedify/issues/1100 + '#1101': https://github.com/fedify-dev/fedify/issues/1101 + '#1102': https://github.com/fedify-dev/fedify/pull/1102 + '#1104': https://github.com/fedify-dev/fedify/pull/1104 + '#1105': https://github.com/fedify-dev/fedify/pull/1105 + '#1106': https://github.com/fedify-dev/fedify/issues/1106 + '#1107': https://github.com/fedify-dev/fedify/issues/1107 + '#1109': https://github.com/fedify-dev/fedify/pull/1109 + '#1110': https://github.com/fedify-dev/fedify/pull/1110 + '#1111': https://github.com/fedify-dev/fedify/issues/1111 + '#1113': https://github.com/fedify-dev/fedify/issues/1113 + '#1114': https://github.com/fedify-dev/fedify/pull/1114 + '#1119': https://github.com/fedify-dev/fedify/pull/1119 + '#1120': https://github.com/fedify-dev/fedify/pull/1120 + '#1123': https://github.com/fedify-dev/fedify/issues/1123 + '#1124': https://github.com/fedify-dev/fedify/pull/1124 + '#1132': https://github.com/fedify-dev/fedify/issues/1132 + '#1133': https://github.com/fedify-dev/fedify/issues/1133 + '#1134': https://github.com/fedify-dev/fedify/pull/1134 + '#1138': https://github.com/fedify-dev/fedify/pull/1138 + '#1142': https://github.com/fedify-dev/fedify/pull/1142 + '#1143': https://github.com/fedify-dev/fedify/issues/1143 + '#1145': https://github.com/fedify-dev/fedify/pull/1145 + '#1146': https://github.com/fedify-dev/fedify/issues/1146 + '#1147': https://github.com/fedify-dev/fedify/issues/1147 + '#1148': https://github.com/fedify-dev/fedify/issues/1148 + '#1151': https://github.com/fedify-dev/fedify/issues/1151 + '#1153': https://github.com/fedify-dev/fedify/issues/1153 + '#1154': https://github.com/fedify-dev/fedify/issues/1154 + '#1155': https://github.com/fedify-dev/fedify/issues/1155 + '#1159': https://github.com/fedify-dev/fedify/issues/1159 + '#1164': https://github.com/fedify-dev/fedify/pull/1164 + '#1165': https://github.com/fedify-dev/fedify/pull/1165 + '#1171': https://github.com/fedify-dev/fedify/pull/1171 + '#1178': https://github.com/fedify-dev/fedify/pull/1178 + '#1180': https://github.com/fedify-dev/fedify/pull/1180 + '#1183': https://github.com/fedify-dev/fedify/pull/1183 + '#1186': https://github.com/fedify-dev/fedify/pull/1186 + '#1188': https://github.com/fedify-dev/fedify/pull/1188 + '#1189': https://github.com/fedify-dev/fedify/pull/1189 + '#1198': https://github.com/fedify-dev/fedify/pull/1198 + '#288': https://github.com/fedify-dev/fedify/issues/288 + '#827': https://github.com/fedify-dev/fedify/issues/827 + '#829': https://github.com/fedify-dev/fedify/issues/829 + '#832': https://github.com/fedify-dev/fedify/issues/832 + '#835': https://github.com/fedify-dev/fedify/issues/835 + '#836': https://github.com/fedify-dev/fedify/issues/836 + '#837': https://github.com/fedify-dev/fedify/issues/837 + '#838': https://github.com/fedify-dev/fedify/issues/838 + '#839': https://github.com/fedify-dev/fedify/issues/839 + '#840': https://github.com/fedify-dev/fedify/issues/840 + '#841': https://github.com/fedify-dev/fedify/issues/841 + '#915': https://github.com/fedify-dev/fedify/pull/915 + '#926': https://github.com/fedify-dev/fedify/pull/926 + '#938': https://github.com/fedify-dev/fedify/issues/938 + '#968': https://github.com/fedify-dev/fedify/pull/968 +--- + - Added support for [FEP-ef61] portable objects, whose IDs are `ap:` or + `ap+ef61:` URIs with a DID instead of a host, e.g., + `ap://did:key:z6Mk.../actor`. A Fedify server can now act as a gateway for + portable actors: it serves their actor documents, objects, collections, and + hashlink media, accepts deliveries to their inboxes, and sends their + activities. It can also consume the portable objects of others. The new + [*Portable objects*][portable objects] chapter of the manual walks through + running portable actors, and describes the FEP-ef61 profile that Fedify + supports, including where it deliberately differs from the FEP and what it + does not implement. Applications without portable actors are unaffected, + except that their dispatchers may be called for requests to the gateway + endpoint, */.well-known/apgateway/*, and that `Context.sendActivity()` may + reject activities that embed others' portable objects (see below). + [[#288], [#1151], [#1198]] + + - Added `verifyPortableObjectProof()`, which enforces the FEP-ef61 proof + policy: a portable actor, activity, or object needs an [FEP-8b32] + Object Integrity Proof whose `verificationMethod` is a DID URL of + the DID in its ID, and a portable actor needs a non-empty `gateways` + list of HTTP(S) origins. A document whose ID is a compatible + identifier, e.g., + `https://gw.example/.well-known/apgateway/did:key:z6Mk.../actor`, is + verified against the DID in it. Its detailed result distinguishes + documents outside the policy, unsecured collections, missing or invalid + proofs, invalid gateways, unsupported verification methods, and DID + mismatches. [[#832], [#968], [#1093], [#1105], [#1148], [#1178]] + + - Added `verifyPortableObject()`, which verifies proofs like + `verifyPortableObjectProof()`, and also accepts an actor's `inbox`, + `outbox`, `followers`, `following`, or `liked` collection without + a proof if a gateway that the actor lists served it, as FEP-ef61 + allows. The `VerifyPortableObjectOptions`, + `VerifyPortableObjectResult`, and `VerifyPortableObjectFailureReason` + types describe it. [[#836], [#1084], [#1093], [#1105]] + + - Added the `Context.verifyPortableObject` property, which is + `verifyPortableObject()` with the context's loaders. Since it has + the same name as the option of property accessors, passing a context + as their options, e.g., `await create.getObject(ctx)`, verifies + portable objects. Inboxes use it as the default verifier of received + activities, as do `Context.lookupObject()`, + `Context.traverseCollection()`, and the `onOutboxError` callback. + Added the `verifyPortableObject` option to `VerifyObjectOptions`. + [[#1107], [#1120]] + + - `verifyProof()` now resolves Ed25519 `did:key` verification methods, + e.g., `did:key:z6Mk...#z6Mk...`, locally without fetching them, and + `verifyObject()` accepts a proof made by a DID as authenticating + an actor or attribution whose portable ID or compatible identifier + has that DID. [[#827], [#829], [#915], [#926], [#1093], [#1105]] + + - Added the `Context.getPortableActorUri()`, + `Context.getPortableObjectUri()`, `Context.getPortableInboxUri()`, + `Context.getPortableOutboxUri()`, `Context.getPortableFollowingUri()`, + `Context.getPortableFollowersUri()`, `Context.getPortableLikedUri()`, + `Context.getPortableFeaturedUri()`, + `Context.getPortableFeaturedTagsUri()`, and + `Context.getPortableCollectionUri()` methods, which build portable IDs + from the paths of the corresponding dispatchers and a DID. Custom + implementations of the `Context` interface need to implement them. + [[#835], [#839], [#841], [#1076], [#1092], [#1111], [#1114], [#1142]] + They throw a `TypeError` for a `did:key` DID that is not encoded in + base58-btc, as FEP-ef61 requires, or for an identifier that has + a `.` or `..` path segment. [[#841], [#1114], [#1154], [#1186]] + + - Added the `portable` option to `Context.parseUri()` and + the `ParseUriOptions` interface. With `{ portable: true }`, + the method also recognizes portable IDs and their compatible + identifiers, and the result has the DID in its new `authority` + property. [[#1143], [#1145]] + + - Object dispatchers and the actor dispatcher now serve portable objects + and actors through the gateway endpoint, e.g., + `GET /.well-known/apgateway/did:key:z6Mk.../notes/123`, with the path + after the DID. An object is served only if its ID canonically equals + the requested portable ID and it has a proof made with a key of + the DID. A non-public object is served only if the dispatcher has + an authorization predicate, as FEP-ef61 forbids gateways to serve it + to anyone but its audience. Signed tombstones are served with + `410 Gone`. Added the `RequestContext.portableRequest` property, + which tells the dispatcher the requested DID and ID. + [[#835], [#841], [#1076], [#1113], [#1114], [#1124], [#1153], [#1183]] + + - Added the `RequestContext.isSignedByAudience()` method and + the `IsSignedByAudienceOptions` interface, which check whether + a request is signed by an actor in the audience of an object, e.g., + in the authorization predicate of an object dispatcher. Custom + implementations of the `RequestContext` interface need to implement + the method. [[#1153], [#1183]] + + - Collection dispatchers now serve the collections of portable actors + through the gateway endpoint, e.g., + `GET /.well-known/apgateway/did:key:z6Mk.../users/alice/outbox`, if + the actor is a portable actor under the requested DID whose + corresponding property refers to the collection. Added + the `CustomCollectionCallbackSetters.mapPortableOwner()` method and + the `PortableCollectionOwnerMapper` type, which tie a custom + collection to its portable owner. [[#1111], [#1142]] + + - Added `Federatable.setHashlinkMediaDispatcher()` and + the `HashlinkMediaRequest` interface, which serve resources that + portable objects refer to with SHA-256 hashlinks, e.g., + `GET /.well-known/apgateway/hl:zQm...`. Fedify does not verify the + dispatcher's response against the digest. Added `hashlink_media` to + the values of the `fedify.endpoint` metric attribute. + [[#838], [#1080]] + + - Inbox listeners now accept deliveries to portable inboxes through + the gateway endpoint, e.g., + `POST /.well-known/apgateway/did:key:z6Mk.../users/alice/inbox`, if + the actor dispatcher returns a portable actor whose `inbox` is + the requested inbox and whose `gateways` include this server. + [[#839], [#1092]] + + - Fedify now forwards an activity delivered to a portable inbox to + the actor's other gateways at most once, as FEP-ef61 recommends, if + the activity is authenticated by its own proof or Linked Data + Signature and the `KvStore` supports `cas()`. Forwarded requests are + signed with this server's RSA gateway key for the actor if the key + pairs dispatcher returns one, and are sent unsigned otherwise. An + activity is not forwarded back to the gateway that forwarded it if + Fedify can identify that gateway by its gateway key signature on the + delivery. Added the `FederationOptions.portableInboxForwarding` and + `FederationKvPrefixes.portableInboxForwarding` options. + [[#839], [#1092], [#1100], [#1101], [#1104], [#1110]] + + - `Context.sendActivity()` and `InboxContext.forwardActivity()` now + deliver to portable inboxes through the recipient's gateways, or else + the `@gateway` location hints of the inbox, trying at most five of + them until one accepts the activity. Previously, such a delivery + failed with `UrlError: Unsupported protocol: ap+ef61:`. Queue + workers of older Fedify versions deliver such queued activities only + through the first gateway, so upgrade them before the servers that + enqueue deliveries. [[#1147], [#1180]] + + - Added the `ActorCallbackSetters.mapPortableActorId()` method and + the `PortableActorIdMapper` type. For an actor that the callback + maps to a portable ID, `Context.getActorKeyPairs()` identifies its key + pairs by the actor's compatible identifier on this server, e.g., + `https://example.com/.well-known/apgateway/did:key:z6Mk.../users/alice#main-key`, + so that they serve as this server's *gateway keys* for the actor, which + sign HTTP requests made on behalf of the actor, but never make Object + Integrity Proofs or Linked Data Signatures. [[#840], [#1099]] + + - HTTP Signature verification now accepts a gateway key of a portable + actor if the actor document at the key ID has a valid proof by + the actor's DID, embeds the key in its `assertionMethod`, or else in + its `publicKey`, and lists the gateway in its `gateways`. Such a key + is owned by the portable actor, so + `RequestContext.getSignedKeyOwner()`, `getKeyOwner()`, and + `doesActorOwnKey()` return or match the actor. Keys at compatible + identifiers are cached apart for each purpose, for an hour at most. + [[#840], [#1095], [#1099], [#1105], [#1119], [#1123], [#1164]] + A key at an `ap:` key ID is accepted likewise if an actor document + fetched through the key ID's location hints vouches for it. + [[#1096], [#1132], [#1134], [#1165]] + + - Inboxes accept an activity of a portable actor, or an activity with + a portable ID, only if it has a valid proof made by the DID of that + ID; an HTTP Signature or a Linked Data Signature does not + authenticate it, and such an activity is rejected with + `401 Unauthorized`. [[#840], [#1099]] + + - Inboxes independently verify each portable actor, activity, and + object embedded in a compound document, e.g., the `Note` in + a `Create`, against its own proof before dispatch, following Fedify's + interim *map-local* profile, since neither FEP-8b32 nor Verifiable + Credential Data Integrity defines the boundaries of embedded proofs + yet. A valid outer proof does not authenticate an unsigned or invalid + embedded portable object. Documents with proof sets, or that exceed + the traversal limits, are rejected. A key embedded in a verified + portable actor needs no proof of its own if the key's ID is the actor's + ID plus a fragment. This profile may change in Fedify 3.0. + [[#938], [#1041], [#1094], [#1102], [#1133], [#1138]] + + - `Context.sendActivity()` gives an activity that contains portable + objects at most one proof: an activity that already has one is sent + as is, and a portable activity is signed only by the key whose ID is + a DID URL for its DID. An activity of a portable actor has to have + a portable ID or a compatible identifier of the actor's DID, and never + gets a Linked Data Signature. Otherwise, `sendActivity()` rejects with + a `TypeError` before anything is delivered or queued. So does a + non-portable activity that embeds portable objects, including ones with + compatible identifiers, when several Ed25519 keys are available, and an + activity with portable objects in which any map carries a proof set. + Sign portable activities with `signObject()` beforehand, or pass the + DID's key as an explicit sender key. + [[#840], [#1041], [#1045], [#1073], [#1099]] + + - Your portable actors and objects may have compatible identifiers as + their IDs, e.g., + `https://example.com/.well-known/apgateway/did:key:z6Mk.../actor`, + for interoperability with software that cannot handle portable IDs. + Fedify treats them as portable wherever it serves or sends them, and + warns if such an ID is malformed or is not on the owner's first + gateway, as FEP-ef61 requires. Build them with `toCompatibleEf61Id()` + before signing the documents. [[#1106], [#1109], [#1155], [#1188]] + + - The WebFinger endpoint now serves portable actors: the domain of + the actor's address comes from the first gateway in its `gateways`, + and its `self` link is its compatible identifier on that gateway. + WebFinger resources can be portable IDs, which are passed to + `mapAlias()`. `Context.lookupObject()` resolves the handles of + portable actors on other servers. [[#837], [#1082], [#1106], [#1109]] + + - Fedify logs a warning if an actor dispatcher returns a portable actor + whose `gateways` are invalid, or whose collections are not the + portable IDs or compatible identifiers that the corresponding + `Context.getPortable*Uri()` methods build, instead of warning that + a portable actor's ID or collections do not match the URIs that + `Context.getActorUri()` and the like build. + [[#837], [#1082], [#1111], [#1142], [#1148], [#1178]] + + - `Context.routeActivity()` routes a portable activity that has no + valid proof only if all of its actors have the same DID as + the activity, comparing [FEP-fe34] origins, where the origin of + a portable ID or a compatible identifier is its DID. [[#1146], [#1171]] + + - Outbox listeners compare the `actor` of a posted activity with + a portable outbox owner by their canonical portable IDs, so that + the actor can be referred to with `@gateway` location hints, another + URI scheme, or as a compatible identifier on another gateway. + [[#1159], [#1189]] + + - Changed Fedify to treat documents whose IDs are [FEP-ef61] compatible + identifiers, such as + `https://gw.example/.well-known/apgateway/did:key:z6Mk.../actor`, as + the portable objects they stand for, as FEP-ef61 requires, instead of + trusting them by the web origin that served them. Previously, any server + could act as + `https://evil.example/.well-known/apgateway/did:key:z6MkAlice/actor` + without a proof by Alice's DID. Some implementations, e.g., tootik, + identify their portable actors this way. [[#288], [#1093], [#1105]] + + - Inboxes now reject an activity of an actor whose ID is a compatible + identifier with `401 Unauthorized` unless it has a valid Object + Integrity Proof made by the actor's DID. Activities of actors that + publish compatible identifiers without signing them, or whose DIDs + use key types Fedify does not support, are no longer accepted. + + - `verifyObject()` never authenticates an attribution or actor whose ID + is a compatible identifier by a key at an ordinary URL. + + - HTTP Signature verification rejects a key at a compatible identifier + unless the actor document has a valid proof by the actor's DID and + vouches for the key. A key at an ordinary URL that claims a portable + actor as its owner or controller is no longer that actor's key, and + `getKeyOwner()` and `doesActorOwnKey()` no longer resolve portable + actors by web origin. + + - Changed property accessors to verify the [FEP-ef61] portable objects that + they dereference when a `Context` is passed as their options, e.g., + `await create.getObject(ctx)`, since the new `Context.verifyPortableObject` + property has the same name as their `verifyPortableObject` option. This + also applies to objects with ordinary HTTP(S) IDs: their references to + compatible identifiers are now verified as portable objects instead of + being trusted because of their origin. In inbox listeners, accessors do + so even without options. [[#288], [#1107], [#1120]] + + - Fixed `signObject()` so that a signed object keeps verifying after it is + assigned to a typed parent and the parent is serialized. `signObject()` + now captures the secured JSON document its proof covers, and nested + serialization embeds that document verbatim instead of rebuilding the + child under the parent's JSON-LD context. Producing a compound document, + such as a signed `Note` in a signed [FEP-ef61] portable `Create`, with + `signObject()` no longer requires assembling the JSON by hand. + [[#288], [#1041], [#1044], [#1051]] + + - The captured document is a snapshot: `clone()` does not carry it, and + mutating a signed object in place does not change it. Sign a clone + again when it has to be embedded as a secured child. + - Serialization falls back to the previous behavior for objects parsed + with `fromJsonLd()`, objects that already carried a proof, and + `toJsonLd()` calls whose `context` option could hide the internal + placeholder. + - Outgoing JSON-LD compatibility normalization now leaves a nested + self-contained secured document untouched while signing and sending, + so it cannot rewrite bytes that the child's own proof covers. + Inbound verification is unaffected. + - Fanout delivery now reuses the document the activity was already + serialized into instead of reparsing and reserializing it, which + previously invalidated an embedded signed child and the outer proof + that covered it. + +[FEP-ef61]: https://w3id.org/fep/ef61 +[portable objects]: https://fedify.dev/manual/portable +[FEP-8b32]: https://w3id.org/fep/8b32 +[FEP-fe34]: https://w3id.org/fep/fe34 diff --git a/changes.d/fedify/portable-parse-uri.md b/changes.d/fedify/portable-parse-uri.md deleted file mode 100644 index abf5b302c..000000000 --- a/changes.d/fedify/portable-parse-uri.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -links: - '#1143': https://github.com/fedify-dev/fedify/issues/1143 - '#1145': https://github.com/fedify-dev/fedify/pull/1145 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added the `portable` option to `Context.parseUri()`, and the - `ParseUriOptions` interface. With `{ portable: true }`, the method also - recognizes [FEP-ef61] portable IDs, e.g., - `ap+ef61://did:key:z6Mk.../users/alice`, and their compatible identifiers - on any gateway by the same paths through which the gateway endpoint serves - them, so that an inbox listener can tell that an activity is about one of - its portable actors, objects, or collections. The result then has the DID - of the ID in its new `authority` property. Since anyone can make - a portable ID with the same path under another DID, check that - `authority` is the DID that you store for the actor or object before - acting on the result. Without the option, `parseUri()` behaves as - before. [[#288], [#1143], [#1145]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/portable-route-activity.md b/changes.d/fedify/portable-route-activity.md deleted file mode 100644 index 1041de198..000000000 --- a/changes.d/fedify/portable-route-activity.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -links: - '#1146': https://github.com/fedify-dev/fedify/issues/1146 - '#1171': https://github.com/fedify-dev/fedify/pull/1171 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Changed `Context.routeActivity()` to compare an activity that has no - valid proof with its actors by their [FEP-fe34] origins once it has - dereferenced the activity, where the origin of an [FEP-ef61] portable ID, - i.e., an `ap:` or `ap+ef61:` URI or a compatible identifier, is its DID - rather than the gateway that serves it. Previously, it compared their web - origins, so a portable activity was routed even if its actors had other - DIDs. Now a portable activity is routed only if all of its actors have - the same DID as the activity itself, and an activity with an ordinary - HTTP(S) ID is not routed if any of its actors has a portable ID. - A portable activity dereferenced through a compatible identifier also - matches its `ap:` ID, and vice versa. [[#288], [#1146], [#1171]] - -[FEP-fe34]: https://w3id.org/fep/fe34 -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/portable-webfinger.md b/changes.d/fedify/portable-webfinger.md deleted file mode 100644 index cb448454e..000000000 --- a/changes.d/fedify/portable-webfinger.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -links: - '#1082': https://github.com/fedify-dev/fedify/pull/1082 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#837': https://github.com/fedify-dev/fedify/issues/837 ---- - - Added WebFinger support for [FEP-ef61] portable actors. When an actor - dispatcher returns an actor whose ID is an `ap:` or `ap+ef61:` URI, the - WebFinger response takes the domain of the actor's `acct:` URI from the - first gateway in its `gateways`, as FEP-ef61 requires, and its `self` - link is the actor's compatible identifier based on that gateway, e.g., - `https://example.com/.well-known/apgateway/did:key:z6Mk.../actor`, so - that software without portable ID support can fetch it. A portable - actor without a valid first gateway is not found. Existing - `mapHandle()` and `mapAlias()` callbacks work as before, and WebFinger - resources can now be `ap:` or `ap+ef61:` URIs, which are passed to - `mapAlias()`. To serve the actor itself at its compatible identifier, - register an object dispatcher for it. [[#288], [#837], [#1082]] - - - `Context.lookupObject()` now uses `verifyPortableObjectProof()` as its - new `verifyPortableObject` option by default, so it looks up - [FEP-ef61] portable objects, including portable actors found through - WebFinger, through their gateways and returns them only if they have - valid Object Integrity Proofs made by the DIDs in their IDs. - [[#288], [#837], [#1082]] - - - Actor dispatchers no longer log warnings that a portable actor's ID or - collection URIs do not match the URIs that `Context` builds, such as - `Context.getActorUri()`. [[#288], [#837], [#1082]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/fedify/signed-child-representation.md b/changes.d/fedify/signed-child-representation.md deleted file mode 100644 index 3e1a532d3..000000000 --- a/changes.d/fedify/signed-child-representation.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -links: - '#1041': https://github.com/fedify-dev/fedify/pull/1041 - '#1044': https://github.com/fedify-dev/fedify/issues/1044 - '#1051': https://github.com/fedify-dev/fedify/pull/1051 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Fixed `signObject()` so that a signed object keeps verifying after it is - assigned to a typed parent and the parent is serialized. `signObject()` - now captures the secured JSON document its proof covers, and nested - serialization embeds that document verbatim instead of rebuilding the - child under the parent's JSON-LD context. Producing a [FEP-ef61] compound - document with `signObject()` no longer requires assembling the JSON by - hand. [[#288], [#1041], [#1044], [#1051]] - - - The captured document is a snapshot: `clone()` does not carry it, and - mutating a signed object in place does not change it. Sign a clone - again when it has to be embedded as a secured child. - - An object parsed with `fromJsonLd()`, an object that already carried a - proof, and a `toJsonLd()` `context` option that could hide the - internal placeholder all fall back to the previous behavior. - - Outgoing JSON-LD compatibility normalization now leaves a nested - self-contained secured document untouched while signing and sending, - so it cannot rewrite bytes that the child's own proof covers. - Inbound verification is unaffected. - - Fanout delivery now reuses the document the activity was already - serialized into instead of reparsing and reserializing it, which - previously invalidated an embedded signed child and the outer proof - that covered it. - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/lint/portable-uri-mismatches.md b/changes.d/lint/portable-uri-mismatches.md index 8259c8bd4..de1ad7944 100644 --- a/changes.d/lint/portable-uri-mismatches.md +++ b/changes.d/lint/portable-uri-mismatches.md @@ -2,8 +2,12 @@ links: '#1157': https://github.com/fedify-dev/fedify/issues/1157 '#1179': https://github.com/fedify-dev/fedify/pull/1179 + '#288': https://github.com/fedify-dev/fedify/issues/288 --- - - Fixed actor URI mismatch rules reporting portable actor and collection - URIs, including gateway-compatible IDs built from them. Applications can - use the `getPortable*Uri()` helpers in actor dispatchers without disabling - these rules. [[#1157], [#1179]] + - Changed the actor URI mismatch rules to accept the [FEP-ef61] portable + IDs of actors and collections, and the compatible identifiers built from + them, so that applications can use the `getPortable*Uri()` methods of + `Context` in actor dispatchers without disabling these rules. + [[#288], [#1157], [#1179]] + +[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/next/hashlink-media-requests.md b/changes.d/next/hashlink-media-requests.md index a0bc2a56c..3dfa49978 100644 --- a/changes.d/next/hashlink-media-requests.md +++ b/changes.d/next/hashlink-media-requests.md @@ -12,7 +12,7 @@ links: `isFederationRequest()` now recognizes them by their paths regardless of their headers. To make Next.js run the middleware for them, add `{ source: "/.well-known/apgateway/:path*" }` to the `matcher` of your - *middleware.ts* or *proxy.ts* file. [[#288], [#1149], [#1170]] + *middleware.ts* or *proxy.ts* file. [[#288], [#1149], [#1170]] - Added `isHashlinkMediaRequest()` function. [[#288], [#1149], [#1170]] diff --git a/changes.d/testing/hashlink-media-dispatcher.md b/changes.d/testing/hashlink-media-dispatcher.md deleted file mode 100644 index e34878b31..000000000 --- a/changes.d/testing/hashlink-media-dispatcher.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#1080': https://github.com/fedify-dev/fedify/pull/1080 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#838': https://github.com/fedify-dev/fedify/issues/838 ---- - - Added the `setHashlinkMediaDispatcher()` method to the `Federation` - object returned by `createFederation()`, following the new - `Federatable.setHashlinkMediaDispatcher()` method of `@fedify/fedify`. - [[#288], [#838], [#1080]] diff --git a/changes.d/testing/is-signed-by-audience.md b/changes.d/testing/is-signed-by-audience.md deleted file mode 100644 index 5e65bc242..000000000 --- a/changes.d/testing/is-signed-by-audience.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -links: - '#1153': https://github.com/fedify-dev/fedify/issues/1153 - '#1183': https://github.com/fedify-dev/fedify/pull/1183 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added the `isSignedByAudience()` method to the mock contexts that - `createFederation()` and `createRequestContext()` create, following - the new `RequestContext.isSignedByAudience()` method of `@fedify/fedify`. - It checks the audience against the actor that `getSignedKeyOwner()` - returns. [[#288], [#1153], [#1183]] diff --git a/changes.d/testing/portable-actor-uri.md b/changes.d/testing/portable-actor-uri.md deleted file mode 100644 index dfbbe965b..000000000 --- a/changes.d/testing/portable-actor-uri.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -links: - '#1114': https://github.com/fedify-dev/fedify/pull/1114 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#841': https://github.com/fedify-dev/fedify/issues/841 ---- - - Added the `getPortableActorUri()` method to the mock contexts that - `createFederation()`, `createContext()`, `createRequestContext()`, - `createInboxContext()`, and `createOutboxContext()` create, following - the new `Context.getPortableActorUri()` method of `@fedify/fedify`. - The mock contexts' portable ID methods now also reject `did:key` DIDs - that are not encoded in base58-btc. [[#288], [#841], [#1114]] diff --git a/changes.d/testing/portable-chain-verifiers.md b/changes.d/testing/portable-chain-verifiers.md deleted file mode 100644 index 762236dba..000000000 --- a/changes.d/testing/portable-chain-verifiers.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -links: - '#1107': https://github.com/fedify-dev/fedify/issues/1107 - '#1120': https://github.com/fedify-dev/fedify/pull/1120 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - The mock contexts that `createContext()` creates now keep the - `verifyPortableObject` property given to them, following the new - `Context.verifyPortableObject` property of `@fedify/fedify`, and their - default `lookupObject()` and `traverseCollection()` methods pass it and - a `verifyPortableObject` option given to them on. - [[#288], [#1107], [#1120]] diff --git a/changes.d/testing/portable-collection-uris.md b/changes.d/testing/portable-collection-uris.md deleted file mode 100644 index f7b7c4508..000000000 --- a/changes.d/testing/portable-collection-uris.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -links: - '#1111': https://github.com/fedify-dev/fedify/issues/1111 - '#1142': https://github.com/fedify-dev/fedify/pull/1142 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added the `getPortableOutboxUri()`, `getPortableFollowingUri()`, - `getPortableFollowersUri()`, `getPortableLikedUri()`, - `getPortableFeaturedUri()`, `getPortableFeaturedTagsUri()`, and - `getPortableCollectionUri()` methods to the mock contexts, and - the `mapPortableOwner()` method to the mock custom collection setters, - following the new APIs of `@fedify/fedify`. [[#288], [#1111], [#1142]] diff --git a/changes.d/testing/portable-gateway-keys.md b/changes.d/testing/portable-gateway-keys.md deleted file mode 100644 index 49e9d5194..000000000 --- a/changes.d/testing/portable-gateway-keys.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -links: - '#1099': https://github.com/fedify-dev/fedify/pull/1099 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#840': https://github.com/fedify-dev/fedify/issues/840 ---- - - Added the `mapPortableActorId()` method to the setters that - `MockFederation.setActorDispatcher()` returns, which `ActorCallbackSetters` - gained for [FEP-ef61] portable actors. [[#288], [#840], [#1099]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/testing/portable-inbox-uri.md b/changes.d/testing/portable-inbox-uri.md deleted file mode 100644 index bfc5c78a0..000000000 --- a/changes.d/testing/portable-inbox-uri.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -links: - '#1092': https://github.com/fedify-dev/fedify/pull/1092 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#839': https://github.com/fedify-dev/fedify/issues/839 ---- - - Added the `getPortableInboxUri()` method to the mock contexts that - `createFederation()`, `createContext()`, `createRequestContext()`, - `createInboxContext()`, and `createOutboxContext()` create, following - the new `Context.getPortableInboxUri()` method of `@fedify/fedify`. - [[#288], [#839], [#1092]] diff --git a/changes.d/testing/portable-mock-requests.md b/changes.d/testing/portable-mock-requests.md deleted file mode 100644 index 264ac7f3f..000000000 --- a/changes.d/testing/portable-mock-requests.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -links: - '#1161': https://github.com/fedify-dev/fedify/issues/1161 - '#1196': https://github.com/fedify-dev/fedify/pull/1196 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added fixture document loaders and portable-object verification to mock - context lookups, explicit portable gateway request information for mock - dispatchers, and hashlink media responses from mock federations. Tests can - now exercise these FEP-ef61 paths without a live gateway. - [[#288], [#1161], [#1196]] diff --git a/changes.d/testing/portable-objects.md b/changes.d/testing/portable-objects.md new file mode 100644 index 000000000..a2eaf5c7d --- /dev/null +++ b/changes.d/testing/portable-objects.md @@ -0,0 +1,65 @@ +--- +links: + '#1080': https://github.com/fedify-dev/fedify/pull/1080 + '#1092': https://github.com/fedify-dev/fedify/pull/1092 + '#1099': https://github.com/fedify-dev/fedify/pull/1099 + '#1107': https://github.com/fedify-dev/fedify/issues/1107 + '#1111': https://github.com/fedify-dev/fedify/issues/1111 + '#1114': https://github.com/fedify-dev/fedify/pull/1114 + '#1120': https://github.com/fedify-dev/fedify/pull/1120 + '#1142': https://github.com/fedify-dev/fedify/pull/1142 + '#1143': https://github.com/fedify-dev/fedify/issues/1143 + '#1145': https://github.com/fedify-dev/fedify/pull/1145 + '#1153': https://github.com/fedify-dev/fedify/issues/1153 + '#1161': https://github.com/fedify-dev/fedify/issues/1161 + '#1183': https://github.com/fedify-dev/fedify/pull/1183 + '#1196': https://github.com/fedify-dev/fedify/pull/1196 + '#288': https://github.com/fedify-dev/fedify/issues/288 + '#835': https://github.com/fedify-dev/fedify/issues/835 + '#838': https://github.com/fedify-dev/fedify/issues/838 + '#839': https://github.com/fedify-dev/fedify/issues/839 + '#840': https://github.com/fedify-dev/fedify/issues/840 + '#841': https://github.com/fedify-dev/fedify/issues/841 +--- + - Added support for [FEP-ef61] portable objects to the mock federation and + contexts, following the new APIs of `@fedify/fedify`, so that tests can + exercise portable objects without a live gateway. [[#288]] + + - Added the `getPortableActorUri()`, `getPortableObjectUri()`, + `getPortableInboxUri()`, `getPortableOutboxUri()`, + `getPortableFollowingUri()`, `getPortableFollowersUri()`, + `getPortableLikedUri()`, `getPortableFeaturedUri()`, + `getPortableFeaturedTagsUri()`, and `getPortableCollectionUri()` + methods to the mock contexts. They reject `did:key` DIDs that are + not encoded in base58-btc. + [[#835], [#839], [#841], [#1092], [#1111], [#1114], [#1142]] + + - Added the `portable` option to `parseUri()` of the mock contexts. + Without it, `parseUri()` no longer recognizes a portable ID or + compatible identifier whose path starts with `/users/`; with it, + the result has the DID in its `authority` property. It also returns + `null` for `null`. [[#1143], [#1145]] + + - The mock contexts that `createContext()` creates keep + the `verifyPortableObject` property given to them, and their + `lookupObject()` and `traverseCollection()` pass it on. + `createFederation()` accepts a fixture `documentLoader`, + a `contextLoader`, and `verifyPortableObject`, which mock context + lookups use for portable IDs. [[#1107], [#1120], [#1161], [#1196]] + + - Added the `isSignedByAudience()` method to the mock request contexts, + which checks the audience against the actor that + `getSignedKeyOwner()` returns. [[#1153], [#1183]] + + - `federation.createContext()` accepts an explicit `portableRequest` + for a request context, which dispatchers can inspect. + [[#1161], [#1196]] + + - Added the `mapPortableActorId()` method to the setters that + `MockFederation.setActorDispatcher()` returns, the + `mapPortableOwner()` method to the mock custom collection setters, + and the `setHashlinkMediaDispatcher()` method to the mock federation, + which serves hashlink media responses. + [[#838], [#840], [#1080], [#1099], [#1111], [#1142], [#1161], [#1196]] + +[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/testing/portable-parse-uri.md b/changes.d/testing/portable-parse-uri.md deleted file mode 100644 index 6081317bb..000000000 --- a/changes.d/testing/portable-parse-uri.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -links: - '#1143': https://github.com/fedify-dev/fedify/issues/1143 - '#1145': https://github.com/fedify-dev/fedify/pull/1145 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Changed `parseUri()` of the mock contexts to accept the `portable` option, - following `Context.parseUri()` of `@fedify/fedify`. It no longer - recognizes an FEP-ef61 portable ID or compatible identifier whose path - starts with `/users/` unless the option is enabled, in which case the - result has the DID in its `authority` property. It also returns `null` - for `null`. [[#288], [#1143], [#1145]] diff --git a/changes.d/vocab-runtime/activitystreams-accept-header.md b/changes.d/vocab-runtime/activitystreams-accept-header.md deleted file mode 100644 index 1a01824c0..000000000 --- a/changes.d/vocab-runtime/activitystreams-accept-header.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -links: - '#1077': https://github.com/fedify-dev/fedify/pull/1077 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#834': https://github.com/fedify-dev/fedify/issues/834 ---- - - Changed the `Accept` header that document loaders send when fetching - ActivityPub objects to - `application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"`, - as ActivityPub and [FEP-ef61] gateways require. Previously, the JSON-LD - media type lacked the ActivityStreams profile. [[#288], [#834], [#1077]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab-runtime/compatible-ef61-ids.md b/changes.d/vocab-runtime/compatible-ef61-ids.md deleted file mode 100644 index dae4399d3..000000000 --- a/changes.d/vocab-runtime/compatible-ef61-ids.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -links: - '#1074': https://github.com/fedify-dev/fedify/pull/1074 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#833': https://github.com/fedify-dev/fedify/issues/833 ---- - - Added `toCompatibleEf61Id()` and `fromCompatibleEf61Id()` for converting - between [FEP-ef61] portable IDs and compatible identifiers, which are - HTTP(S) URLs under a gateway's fixed `/.well-known/apgateway/` path that - software without portable IRI support can use. `toCompatibleEf61Id()` - removes location hints (`@gateway` query parameters, and the legacy - `gateways` parameter), and `fromCompatibleEf61Id()` returns - `null` for URLs that are not compatible identifiers and throws a - `TypeError` for malformed ones, including those with location hints. - Converting a compatible identifier does not authenticate it; the object's - proof still has to be verified against its DID. [[#288], [#833], [#1074]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab-runtime/gateway-hints.md b/changes.d/vocab-runtime/gateway-hints.md deleted file mode 100644 index e9298c643..000000000 --- a/changes.d/vocab-runtime/gateway-hints.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -links: - '#1159': https://github.com/fedify-dev/fedify/issues/1159 - '#1189': https://github.com/fedify-dev/fedify/pull/1189 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added `withGatewayHints()`, `withoutGatewayHints()`, and - `getGatewayHints()` to add, remove, and read the [FEP-ef61] `@gateway` - location hints of portable IDs, which tell consumers where to retrieve - a referenced portable actor. Use `withGatewayHints()` when referring to - a portable actor, e.g., in `attributedTo` or `to`, instead of editing - the query by hand; it writes each gateway's URI-encoded origin as - FEP-ef61 requires, replaces existing hints, and keeps the other query - parameters. Do not add hints to an object's own `id`. - [[#288], [#1159], [#1189]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab-runtime/imported-unreleased.md b/changes.d/vocab-runtime/imported-unreleased.md index 2918accf5..1f64890dc 100644 --- a/changes.d/vocab-runtime/imported-unreleased.md +++ b/changes.d/vocab-runtime/imported-unreleased.md @@ -1,65 +1,15 @@ --- links: - '#1151': https://github.com/fedify-dev/fedify/issues/1151 - '#1198': https://github.com/fedify-dev/fedify/pull/1198 - '#288': https://github.com/fedify-dev/fedify/issues/288 '#810': https://github.com/fedify-dev/fedify/issues/810 - '#827': https://github.com/fedify-dev/fedify/issues/827 - '#828': https://github.com/fedify-dev/fedify/issues/828 - '#829': https://github.com/fedify-dev/fedify/issues/829 - '#830': https://github.com/fedify-dev/fedify/issues/830 - '#831': https://github.com/fedify-dev/fedify/issues/831 '#912': https://github.com/fedify-dev/fedify/issues/912 '#913': https://github.com/fedify-dev/fedify/pull/913 '#914': https://github.com/fedify-dev/fedify/pull/914 - '#915': https://github.com/fedify-dev/fedify/pull/915 - '#924': https://github.com/fedify-dev/fedify/pull/924 - '#926': https://github.com/fedify-dev/fedify/pull/926 - '#928': https://github.com/fedify-dev/fedify/pull/928 - '#935': https://github.com/fedify-dev/fedify/pull/935 --- - - Added SHA-256 `digestMultibase` and simple `hl:` hashlink helpers for - computing, parsing, creating, and verifying portable media resource - digests as required by [FEP-ef61]. - [[#831], [#935]] - - - Added the [FEP-ef61] JSON-LD context to the preloaded context registry so - portable actor and media documents can compact and expand `gateways` and - `digestMultibase` without fetching the context remotely. - [[#830], [#928]] - - - Added `getFe34Origin()` and `haveSameFe34Origin()` for comparing ordinary - web origins and [FEP-ef61] cryptographic origins with one shared - [FEP-fe34] helper. HTTP(S) URLs keep web-origin semantics, while - `ap:`/`ap+ef61:` URIs and DID URLs use their DID component as the origin. - [[#829], [#926]] - - - Added `canonicalizePortableUri()` and `arePortableUrisEqual()` for - comparing [FEP-ef61] portable ActivityPub URI strings. The helpers accept - `ap:` and `ap+ef61:` values with decoded or percent-encoded DID - authorities, normalize them to `ap+ef61:`, and ignore query hints such as - `gateways` during comparison. - [[#828], [#924]] - - Canonicalizing to `ap+ef61:` rather than `ap:`, which FEP-ef61 currently - recommends, is a deliberate choice of Fedify's that may change in - Fedify 3.0. Compare portable IDs with `arePortableUrisEqual()` rather - than as strings. See the [*Portable objects*][portable objects] chapter - of the manual for the FEP-ef61 profile that Fedify supports. - [[#288], [#1151], [#1198]] - - Added the [FEP-7aa9] JSON-LD context to the preloaded context registry so FEP-7aa9 documents can be compacted and expanded without fetching the context remotely. [[#810], [#914]] - - Added helpers for Ed25519 `did:key` DIDs and verification method DID - URLs: `exportDidKey()` exports public keys to base58-btc `did:key` DIDs, - `importDidKey()` imports supported DIDs back to `CryptoKey`, and - `parseDidKeyVerificationMethod()` validates `did:key:z...#z...` - verification methods. - [[#827], [#915]] - - Changed `getDocumentLoader()` to reject HTML and XHTML responses that do not advertise an ActivityPub alternate document with a `FetchError` instead of attempting to parse the HTML as JSON. This makes remote HTML @@ -67,7 +17,4 @@ links: content type, rather than generic JSON parser crashes. [[#912], [#913]] -[FEP-ef61]: https://w3id.org/fep/ef61 -[FEP-fe34]: https://w3id.org/fep/fe34 -[portable objects]: https://fedify.dev/manual/portable [FEP-7aa9]: https://w3id.org/fep/7aa9 diff --git a/changes.d/vocab-runtime/portable-chain-verifiers.md b/changes.d/vocab-runtime/portable-chain-verifiers.md deleted file mode 100644 index 014b3fd74..000000000 --- a/changes.d/vocab-runtime/portable-chain-verifiers.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -links: - '#1107': https://github.com/fedify-dev/fedify/issues/1107 - '#1120': https://github.com/fedify-dev/fedify/pull/1120 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added the `verifyPortableObject` property to - `PropertyPreprocessorContext`, the default [FEP-ef61] portable object - verifier that objects returned by a property preprocessor should use for - their property accessors. [[#288], [#1107], [#1120]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab-runtime/portable-dot-segments.md b/changes.d/vocab-runtime/portable-dot-segments.md deleted file mode 100644 index 1452cf2fd..000000000 --- a/changes.d/vocab-runtime/portable-dot-segments.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -links: - '#1154': https://github.com/fedify-dev/fedify/issues/1154 - '#1186': https://github.com/fedify-dev/fedify/pull/1186 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Fixed portable and gateway-compatible ID strings with `.` or `..` path - segments being interpreted as different IDs after URL parsing. Fedify now - rejects these strings because the segments cannot be preserved by its - URL-based APIs. Raw portable ID strings can still be compared without - losing their paths. [[#288], [#1154], [#1186]] diff --git a/changes.d/vocab-runtime/portable-object-verifier.md b/changes.d/vocab-runtime/portable-object-verifier.md deleted file mode 100644 index 41fa16f07..000000000 --- a/changes.d/vocab-runtime/portable-object-verifier.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -links: - '#1077': https://github.com/fedify-dev/fedify/pull/1077 - '#1084': https://github.com/fedify-dev/fedify/pull/1084 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#834': https://github.com/fedify-dev/fedify/issues/834 - '#836': https://github.com/fedify-dev/fedify/issues/836 ---- - - Added the `PortableObjectVerifier`, `PortableObjectVerifierOptions`, - `PortableObjectVerification`, and `PortableObjectReferrer` types, which - describe the `verifyPortableObject` option of property accessors for - [FEP-ef61] portable references. A verifier receives the fetched - document along with its final URL, the gateways used, and the chain of - objects that referred to it, and can accept a document without an - integrity proof as `unsecured`. `verifyPortableObject()` and - `verifyPortableObjectProof()` from `@fedify/fedify` satisfy - `PortableObjectVerifier`. [[#288], [#834], [#836], [#1077], [#1084]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab-runtime/portable-objects.md b/changes.d/vocab-runtime/portable-objects.md new file mode 100644 index 000000000..1b6bf48cf --- /dev/null +++ b/changes.d/vocab-runtime/portable-objects.md @@ -0,0 +1,126 @@ +--- +links: + '#1074': https://github.com/fedify-dev/fedify/pull/1074 + '#1077': https://github.com/fedify-dev/fedify/pull/1077 + '#1084': https://github.com/fedify-dev/fedify/pull/1084 + '#1107': https://github.com/fedify-dev/fedify/issues/1107 + '#1120': https://github.com/fedify-dev/fedify/pull/1120 + '#1151': https://github.com/fedify-dev/fedify/issues/1151 + '#1152': https://github.com/fedify-dev/fedify/issues/1152 + '#1154': https://github.com/fedify-dev/fedify/issues/1154 + '#1159': https://github.com/fedify-dev/fedify/issues/1159 + '#1176': https://github.com/fedify-dev/fedify/issues/1176 + '#1182': https://github.com/fedify-dev/fedify/pull/1182 + '#1186': https://github.com/fedify-dev/fedify/pull/1186 + '#1189': https://github.com/fedify-dev/fedify/pull/1189 + '#1190': https://github.com/fedify-dev/fedify/pull/1190 + '#1198': https://github.com/fedify-dev/fedify/pull/1198 + '#288': https://github.com/fedify-dev/fedify/issues/288 + '#826': https://github.com/fedify-dev/fedify/issues/826 + '#827': https://github.com/fedify-dev/fedify/issues/827 + '#828': https://github.com/fedify-dev/fedify/issues/828 + '#829': https://github.com/fedify-dev/fedify/issues/829 + '#830': https://github.com/fedify-dev/fedify/issues/830 + '#831': https://github.com/fedify-dev/fedify/issues/831 + '#833': https://github.com/fedify-dev/fedify/issues/833 + '#834': https://github.com/fedify-dev/fedify/issues/834 + '#836': https://github.com/fedify-dev/fedify/issues/836 + '#850': https://github.com/fedify-dev/fedify/pull/850 + '#915': https://github.com/fedify-dev/fedify/pull/915 + '#924': https://github.com/fedify-dev/fedify/pull/924 + '#926': https://github.com/fedify-dev/fedify/pull/926 + '#928': https://github.com/fedify-dev/fedify/pull/928 + '#935': https://github.com/fedify-dev/fedify/pull/935 +--- + - Added support for [FEP-ef61] portable objects, whose IDs are `ap:` or + `ap+ef61:` URIs with a DID instead of a host, e.g., + `ap://did:key:z6Mk.../actor`. See the + [*Portable objects*][portable objects] chapter of the manual for the + FEP-ef61 profile that Fedify supports. [[#288]] + + - Added `parseIri()`, `formatIri()`, `parseJsonLdId()`, and + `haveSameIriOrigin()`, which parse, format, and compare IRIs, + including portable IDs with decoded or percent-encoded DID + authorities. The `URL` objects that represent portable IDs keep + their DIDs percent-encoded, and `formatIri()` formats them in their + canonical form, e.g., `ap+ef61://did:key:z6Mk.../actor`. Portable + IDs and compatible identifiers whose paths have `.` or `..` + segments, which the `URL` class would remove, are rejected with + a `TypeError`. [[#826], [#850], [#1154], [#1186]] + + - Added `canonicalizePortableUri()` and `arePortableUrisEqual()` for + comparing portable IDs. They accept both schemes with decoded or + percent-encoded DID authorities, normalize them to `ap+ef61:`, and + ignore the query, including `@gateway` location hints. + Fedify deliberately canonicalizes to `ap+ef61:` rather than `ap:`, + which FEP-ef61 currently recommends, and this may change in + Fedify 3.0, so compare portable IDs with + `arePortableUrisEqual()` rather than as strings. + [[#828], [#924], [#1151], [#1198]] + + - Added `getFe34Origin()` and `haveSameFe34Origin()`, which compare + [FEP-fe34] origins: HTTP(S) URLs have their web origins, while + portable IDs and DID URLs have their DIDs as their cryptographic + origins. [[#829], [#926]] + + - Added `exportDidKey()`, `importDidKey()`, and + `parseDidKeyVerificationMethod()` for Ed25519 `did:key` DIDs and + their verification method DID URLs. `exportDidKey()` always + encodes DIDs in base58-btc, as FEP-ef61 requires. [[#827], [#915]] + + - Added `toCompatibleEf61Id()` and `fromCompatibleEf61Id()` for + converting between portable IDs and compatible identifiers, i.e., + HTTP(S) URLs under a gateway's */.well-known/apgateway/* path such as + `https://example.com/.well-known/apgateway/did:key:z6Mk.../actor`, + which software without portable ID support can use. + `fromCompatibleEf61Id()` returns `null` for URLs that are not + compatible identifiers, and throws a `TypeError` for malformed ones, + including those with location hints. Converting a compatible + identifier does not authenticate it. [[#833], [#1074]] + + - Added `isGatewayUrl()` and `parseGatewayUrl()`, which check that + a gateway is an HTTP(S) origin without credentials, a path, a query, + or a fragment, as FEP-ef61 requires. + [[#830], [#928], [#1176], [#1190]] + + - Added `withGatewayHints()`, `withoutGatewayHints()`, and + `getGatewayHints()` to add, remove, and read the `@gateway` location + hints of portable IDs, which tell consumers where to retrieve + a referenced portable actor. [[#1159], [#1189]] + + - Added SHA-256 `digestMultibase` and `hl:` hashlink helpers: + `computeDigestMultibase()`, `parseDigestMultibase()`, + `verifyDigestMultibase()`, `createHashlink()`, `parseHashlink()`, + and `verifyHashlink()`. [[#831], [#935]] + + - Added `fetchPortableMedia()`, which retrieves the media of a portable + object through its owner's gateways, or an HTTP(S) resource directly, + and returns it only after verifying its `digestMultibase`. + It limits the response size and rejects private network addresses by + default. [[#1152], [#1182]] + + - Added the FEP-ef61 JSON-LD context to the preloaded contexts, so that + `gateways` and `digestMultibase` can be compacted and expanded + without fetching the context. [[#830], [#928]] + + - Added the `PortableObjectVerifier`, `PortableObjectVerifierOptions`, + `PortableObjectVerification`, and `PortableObjectReferrer` types, + which describe the `verifyPortableObject` option of property + accessors. A verifier receives a fetched document along with its + final URL, the gateways used, and the chain of objects that referred + to it, and can accept a collection without a proof as `unsecured`. + [[#834], [#836], [#1077], [#1084]] + + - Added the `verifyPortableObject` property to + `PropertyPreprocessorContext`, the default verifier that objects + returned by a property preprocessor should use. [[#1107], [#1120]] + + - Changed the `Accept` header that document loaders send when fetching + ActivityPub objects to + `application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"`, + as ActivityPub and [FEP-ef61] gateways require. Previously, the JSON-LD + media type lacked the ActivityStreams profile. [[#288], [#834], [#1077]] + +[FEP-ef61]: https://w3id.org/fep/ef61 +[portable objects]: https://fedify.dev/manual/portable +[FEP-fe34]: https://w3id.org/fep/fe34 diff --git a/changes.d/vocab-runtime/verified-portable-media.md b/changes.d/vocab-runtime/verified-portable-media.md deleted file mode 100644 index 8faa66235..000000000 --- a/changes.d/vocab-runtime/verified-portable-media.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -links: - '#1152': https://github.com/fedify-dev/fedify/issues/1152 - '#1182': https://github.com/fedify-dev/fedify/pull/1182 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added `fetchPortableMedia()` to retrieve [FEP-ef61] hashlink media through - an actor's gateways or HTTP(S) media directly, and return the resource only - after verifying its `digestMultibase`. It rejects missing or mismatched - digests, limits response size, and checks private network addresses by - default. [[#288], [#1152], [#1182]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab/compatible-id-dereferencing.md b/changes.d/vocab/compatible-id-dereferencing.md deleted file mode 100644 index 79173e1bc..000000000 --- a/changes.d/vocab/compatible-id-dereferencing.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -links: - '#1090': https://github.com/fedify-dev/fedify/issues/1090 - '#1091': https://github.com/fedify-dev/fedify/pull/1091 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Property accessors such as `Create.getObject()` now dereference - [FEP-ef61] compatible identifiers, i.e., HTTP(S) URLs under a gateway's - */.well-known/apgateway/* path, as the portable objects they stand for - when the `verifyPortableObject` option is given or the parent object is - portable. Previously, they fetched such a reference as an ordinary - HTTP(S) URL and trusted the result because of its origin, so anyone could - serve an unsigned object that claimed to be someone else's portable - object. Now the accessor asks the gateway that the identifier names - first, and then the gateways in the `gateways` option, and returns the - object only if its `@id` identifies the same portable object and - `verifyPortableObject` accepts it, including the gateway trust policy for - unsecured collections. Malformed compatible identifiers are rejected - without a request. [[#288], [#1090], [#1091]] - - - Property accessors and `lookupObject()` with the `verifyPortableObject` - option now verify a document fetched from an ordinary HTTP(S) URL as - a portable object if its final URL is a compatible identifier or its - `@id` is an `ap:`/`ap+ef61:` URI, instead of trusting it because of its - origin. Likewise, accessors no longer trust an embedded object whose - `@id` is a compatible identifier, or a portable ID with a DID other than - its parent's, even with `crossOrigin: "trust"`; they dereference and - verify it on its own. [[#288], [#1090], [#1091]] - - - Without the `verifyPortableObject` option, property accessors keep - fetching compatible identifiers from ordinary objects as HTTP(S) URLs, - but no longer cache the results in the parent objects, so that a later - call with the option verifies them. [[#288], [#1090], [#1091]] - - - The gateways that `lookupObject()` infers from compatible identifiers, - WebFinger responses, and location hints are now passed to the - `verifyPortableObject` function as `gatewayHints` instead of `gateways`, - which are reserved for gateways that the caller gives explicitly. - [[#288], [#1090], [#1091]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab/compatible-id-documents.md b/changes.d/vocab/compatible-id-documents.md deleted file mode 100644 index 546efe36e..000000000 --- a/changes.d/vocab/compatible-id-documents.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -links: - '#1093': https://github.com/fedify-dev/fedify/issues/1093 - '#1105': https://github.com/fedify-dev/fedify/pull/1105 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Property accessors and `lookupObject()` with the `verifyPortableObject` - option now accept a portable object whose `@id` is an [FEP-ef61] - compatible identifier of the requested portable object, e.g., one on the - gateway that served it, and pass it to `verifyPortableObject`, keeping its - own `@id`. Previously, such documents, which some implementations such - as tootik publish, were rejected as objects with a mismatching ID. - [[#288], [#1093], [#1105]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab/imported-unreleased.md b/changes.d/vocab/imported-unreleased.md index b5b676e22..20484cf9c 100644 --- a/changes.d/vocab/imported-unreleased.md +++ b/changes.d/vocab/imported-unreleased.md @@ -3,33 +3,10 @@ links: '#754': https://github.com/fedify-dev/fedify/issues/754 '#810': https://github.com/fedify-dev/fedify/issues/810 '#823': https://github.com/fedify-dev/fedify/issues/823 - '#826': https://github.com/fedify-dev/fedify/issues/826 - '#829': https://github.com/fedify-dev/fedify/issues/829 - '#830': https://github.com/fedify-dev/fedify/issues/830 - '#850': https://github.com/fedify-dev/fedify/pull/850 '#914': https://github.com/fedify-dev/fedify/pull/914 '#925': https://github.com/fedify-dev/fedify/pull/925 - '#926': https://github.com/fedify-dev/fedify/pull/926 '#927': https://github.com/fedify-dev/fedify/pull/927 - '#928': https://github.com/fedify-dev/fedify/pull/928 --- - - Added [FEP-ef61] vocabulary terms for portable ActivityPub objects. - Actor classes now expose ordered `gateways` lists, and `Link` plus - document/media classes expose `digestMultibase` for external resource - integrity metadata. - [[#830], [#928]] - - Updated [FEP-fe34] cross-origin checks to understand cryptographic origins - for [FEP-ef61] portable ActivityPub IDs and DID URLs. Generated property - accessors and `lookupObject()` now treat `ap:`/`ap+ef61:` IDs and matching - `did:key` verification method IDs as same-origin when their DID components - match. - [[#829], [#926]] - - Added support for [FEP-ef61] portable ActivityPub IRIs in generated - vocabulary codecs. `ap:` and `ap+ef61:` values with decoded or - percent-encoded DID authorities now parse as `URL` objects, and JSON-LD - serialization emits canonical `ap+ef61:` values with decoded DID - authorities. - [[#826], [#850]] - Added vocabulary support for [FEP-7aa9], including `FeaturedCollection`, `FeaturedItem`, `FeatureRequest`, and `FeatureAuthorization`, plus actor `featuredCollections` and @@ -44,7 +21,5 @@ links: `esnext.temporal` lib reference. [[#823], [#925]] -[FEP-ef61]: https://w3id.org/fep/ef61 -[FEP-fe34]: https://w3id.org/fep/fe34 [FEP-7aa9]: https://w3id.org/fep/7aa9 [ActivityPub Media Upload extension]: https://www.w3.org/wiki/SocialCG/ActivityPub/MediaUpload diff --git a/changes.d/vocab/lookup-object-gateways.md b/changes.d/vocab/lookup-object-gateways.md deleted file mode 100644 index d12b99d0f..000000000 --- a/changes.d/vocab/lookup-object-gateways.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -links: - '#1158': https://github.com/fedify-dev/fedify/issues/1158 - '#1194': https://github.com/fedify-dev/fedify/pull/1194 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added a `gateways` option to `lookupObject()` and - `Context.lookupObject()`, so applications can look up a bare - [FEP-ef61] portable object ID without constructing location hints or - providing a custom document loader. The listed gateways are tried in - order in place of any `@gateway` hints. [[#288], [#1158], [#1194]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab/portable-chain-verifiers.md b/changes.d/vocab/portable-chain-verifiers.md deleted file mode 100644 index 205989c11..000000000 --- a/changes.d/vocab/portable-chain-verifiers.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -links: - '#1107': https://github.com/fedify-dev/fedify/issues/1107 - '#1120': https://github.com/fedify-dev/fedify/pull/1120 - '#1129': https://github.com/fedify-dev/fedify/issues/1129 - '#1137': https://github.com/fedify-dev/fedify/pull/1137 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Property accessors of objects whose IDs are [FEP-ef61] compatible - identifiers, e.g., - `https://gw.example/.well-known/apgateway/did:key:z6Mk.../activities/1`, - now dereference their references as portable objects, as those of objects - with `ap:` IDs do. Previously, such an accessor fetched a compatible - identifier as an ordinary HTTP(S) URL and trusted the result because of - its origin, so anyone could serve an unsigned object at the reference. - Without the `verifyPortableObject` option, such an accessor now throws - a `TypeError` (or returns `null` with `suppressError: true`) for - a portable reference or a compatible identifier; pass a `Context` from - `@fedify/fedify`, which carries a verifier, or use a default verifier - (see below). An object whose ID is a malformed compatible identifier is - handled the same way. Having such an ID does not make an object - verified. [[#288], [#1107], [#1120]] - - - Added the `verifyPortableObject` option to the constructors, the - `fromJsonLd()` methods, and the `clone()` methods of vocabulary - classes. The object uses it by default when its property accessors are - called without the option. Objects embedded in the JSON-LD document it - was parsed from inherit it. `lookupObject()` passes its - `verifyPortableObject` option to the object it returns. - [[#288], [#1107], [#1120]] - - - Objects that property accessors and `traverseCollection()` fetch now use - the `verifyPortableObject` option of that call, or else the default of - the object they were obtained from, as their default verifier. So - `(await create.getObject(ctx))?.getAttribution()` verifies portable - objects without passing `ctx` again. Objects already cached in their - parent keep the default they got when they were fetched. Having - a default verifier does not mean that an object was verified. - [[#288], [#1129], [#1137]] - - - Added the `inheritPortableObjectVerifier` option to property accessors - and `TraverseCollectionOptions`. Set it to `false` to keep - a `verifyPortableObject` option to that call only, e.g., for a verifier - that accepts everything; fetched objects then use the default of the - object they were obtained from, if any. [[#288], [#1129], [#1137]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab/portable-collection-trust.md b/changes.d/vocab/portable-collection-trust.md deleted file mode 100644 index 1c07c9595..000000000 --- a/changes.d/vocab/portable-collection-trust.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -links: - '#1084': https://github.com/fedify-dev/fedify/pull/1084 - '#1090': https://github.com/fedify-dev/fedify/issues/1090 - '#1091': https://github.com/fedify-dev/fedify/pull/1091 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#836': https://github.com/fedify-dev/fedify/issues/836 ---- - - Property accessors now tell the `verifyPortableObject` function where - a portable object was retrieved from and which objects led to it, so - that it can apply the [FEP-ef61] trust policy for portable collections - served without proofs. Accessors of such an unsecured collection do not - trust the objects embedded in it, even with `crossOrigin: "trust"`; - they fetch and verify each of them on its own, and drop the ones without - an `@id`. [[#288], [#836], [#1084], [#1090], [#1091]] - - - Added `crossOrigin`, `gateways`, and `verifyPortableObject` options to - `TraverseCollectionOptions`, so that `traverseCollection()` can traverse - [FEP-ef61] portable collections through gateways. - [[#288], [#836], [#1084], [#1090], [#1091]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab/portable-gateway-dereferencing.md b/changes.d/vocab/portable-gateway-dereferencing.md deleted file mode 100644 index caf1227dc..000000000 --- a/changes.d/vocab/portable-gateway-dereferencing.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -links: - '#1077': https://github.com/fedify-dev/fedify/pull/1077 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#834': https://github.com/fedify-dev/fedify/issues/834 ---- - - Added [FEP-ef61] gateway dereferencing to property accessors such as - `Create.getObject()`. Accessors now fetch `ap:` and `ap+ef61:` - references through the gateways given by the new `gateways` option, or - through the `@gateway` location hints in the reference when the option is - omitted, trying each gateway in order until one serves a valid object. - A fetched object is returned only if its `@id` canonically matches the - reference and the new `verifyPortableObject` option, typically - `verifyPortableObjectProof()` from `@fedify/fedify`, accepts it. Portable - references can no longer be dereferenced without `verifyPortableObject`, - and the `crossOrigin: "trust"` option does not skip these checks. - HTTP(S) references are fetched as before. [[#288], [#834], [#1077]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab/portable-inspection.md b/changes.d/vocab/portable-inspection.md deleted file mode 100644 index 7e5c7a053..000000000 --- a/changes.d/vocab/portable-inspection.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -links: - '#1156': https://github.com/fedify-dev/fedify/issues/1156 - '#1199': https://github.com/fedify-dev/fedify/pull/1199 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Changed the inspection of vocabulary objects, e.g., with `console.log()`, - `util.inspect()`, or `Deno.inspect()`, to show [FEP-ef61] portable IDs - in their canonical form, e.g., `ap+ef61://did:key:z6Mk.../actor`, instead - of the percent-encoded form of the `URL` objects that represent them, - e.g., `ap+ef61://did%3Akey%3Az6Mk.../actor`. [[#288], [#1156], [#1199]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab/portable-objects.md b/changes.d/vocab/portable-objects.md new file mode 100644 index 000000000..37df2a7df --- /dev/null +++ b/changes.d/vocab/portable-objects.md @@ -0,0 +1,163 @@ +--- +links: + '#1044': https://github.com/fedify-dev/fedify/issues/1044 + '#1051': https://github.com/fedify-dev/fedify/pull/1051 + '#1077': https://github.com/fedify-dev/fedify/pull/1077 + '#1082': https://github.com/fedify-dev/fedify/pull/1082 + '#1084': https://github.com/fedify-dev/fedify/pull/1084 + '#1090': https://github.com/fedify-dev/fedify/issues/1090 + '#1091': https://github.com/fedify-dev/fedify/pull/1091 + '#1093': https://github.com/fedify-dev/fedify/issues/1093 + '#1097': https://github.com/fedify-dev/fedify/issues/1097 + '#1105': https://github.com/fedify-dev/fedify/pull/1105 + '#1107': https://github.com/fedify-dev/fedify/issues/1107 + '#1120': https://github.com/fedify-dev/fedify/pull/1120 + '#1129': https://github.com/fedify-dev/fedify/issues/1129 + '#1137': https://github.com/fedify-dev/fedify/pull/1137 + '#1147': https://github.com/fedify-dev/fedify/issues/1147 + '#1156': https://github.com/fedify-dev/fedify/issues/1156 + '#1158': https://github.com/fedify-dev/fedify/issues/1158 + '#1160': https://github.com/fedify-dev/fedify/issues/1160 + '#1180': https://github.com/fedify-dev/fedify/pull/1180 + '#1184': https://github.com/fedify-dev/fedify/pull/1184 + '#1194': https://github.com/fedify-dev/fedify/pull/1194 + '#1199': https://github.com/fedify-dev/fedify/pull/1199 + '#1202': https://github.com/fedify-dev/fedify/pull/1202 + '#288': https://github.com/fedify-dev/fedify/issues/288 + '#826': https://github.com/fedify-dev/fedify/issues/826 + '#829': https://github.com/fedify-dev/fedify/issues/829 + '#830': https://github.com/fedify-dev/fedify/issues/830 + '#834': https://github.com/fedify-dev/fedify/issues/834 + '#836': https://github.com/fedify-dev/fedify/issues/836 + '#837': https://github.com/fedify-dev/fedify/issues/837 + '#850': https://github.com/fedify-dev/fedify/pull/850 + '#926': https://github.com/fedify-dev/fedify/pull/926 + '#928': https://github.com/fedify-dev/fedify/pull/928 +--- + - Added support for [FEP-ef61] portable objects, whose IDs are `ap:` or + `ap+ef61:` URIs with a DID instead of a host, e.g., + `ap://did:key:z6Mk.../actor`, and which are retrieved through the + servers listed in their actors' `gateways`. See the + [*Portable objects*][portable objects] chapter of the manual for the + FEP-ef61 profile that Fedify supports. [[#288]] + + - Generated vocabulary classes now accept portable IDs with decoded or + percent-encoded DID authorities wherever an IRI is expected, and + serialize them as canonical `ap+ef61:` IRIs with decoded DID + authorities. Inspecting vocabulary objects, e.g., with + `console.log()`, also shows them in this form. + [[#826], [#850], [#1156], [#1199]] + + - Added the `gateways` property to actor classes, and the + `digestMultibase` property to `Link` and document and media classes. + Gateways are serialized as origins without a trailing slash. + A portable actor that uses the `gateways` term without mapping it in + its JSON-LD context, as tootik does, is also read. + [[#830], [#928], [#1097], [#1202]] + + - Added the optional `Recipient.gateways` property, through which Fedify + delivers activities to portable inboxes. Applications that build + `Recipient` objects by hand, e.g., in followers collection + dispatchers, need to set it for portable actors. [[#1147], [#1180]] + + - Property accessors such as `Create.getObject()` now fetch portable + references through gateways: those in the new `gateways` option, or + else those in the `@gateway` location hints of the reference. + A fetched object is returned only if its `@id` identifies the referenced + portable object and the verifier given as the new + `verifyPortableObject` option accepts it, typically + `verifyPortableObject()` from `@fedify/fedify`, or a `Context` passed + as the options. Portable references cannot be dereferenced + without the option, and `crossOrigin: "trust"` does not skip these + checks. [[#834], [#1077], [#1093], [#1105]] + + - Property accessors tell the `verifyPortableObject` function where + a portable object was retrieved from and which objects led to it, so + that it can accept a portable collection without a proof if a gateway + that its owner lists served it. Objects embedded in such a collection + are fetched and verified one by one. Added the `crossOrigin`, + `gateways`, and `verifyPortableObject` options to + `TraverseCollectionOptions` as well. [[#836], [#1084]] + + - Added the `verifyPortableObject` option to the constructors, + the `fromJsonLd()` methods, and the `clone()` methods of vocabulary + classes, which sets the verifier that the object's property accessors + use by default. Objects embedded in the parsed document, and objects + that accessors and `traverseCollection()` fetch, get the verifier of + the call or of their parent by default, so that, e.g., + `(await create.getObject(ctx))?.getAttribution()` verifies portable + objects without passing `ctx` again. Having a default verifier does + not mean that an object was verified. Added + the `inheritPortableObjectVerifier` option to property accessors and + `TraverseCollectionOptions` to limit a verifier to a single call. + [[#1107], [#1120], [#1129], [#1137]] + + - Added the `verifyPortableObject` and `gateways` options to + `LookupObjectOptions`. With the former, `lookupObject()` looks up + portable IDs through their `@gateway` location hints or the gateways + given by the latter, compatible identifiers through the gateways they + name, and the handles of portable actors through their WebFinger + responses, trying at most five gateways per lookup. The gateways + that it infers from compatible identifiers, WebFinger responses, and + location hints are passed to the `verifyPortableObject` function as + `gatewayHints`, while `gateways` has the ones given explicitly. + [[#837], [#1082], [#1090], [#1091], [#1158], [#1194]] + + - `getActorHandle()` now supports portable actors. It takes the domain + of a portable actor's handle from the first gateway in its `gateways`, + and returns the handle only if its WebFinger response links back to + the actor. [[#837], [#1082]] + + - Exported the portable object verifier types and other types used in + vocabulary API signatures from `@fedify/vocab`, so that custom + verifiers can be typed without importing `@fedify/vocab-runtime`. + [[#1160], [#1184]] + + - Changed property accessors and `lookupObject()` so that they no longer + trust [FEP-ef61] compatible identifiers, i.e., HTTP(S) URLs under + a gateway's */.well-known/apgateway/* path such as + `https://gw.example/.well-known/apgateway/did:key:z6Mk.../actor`, because + of the origin that serves them. Anyone can serve a compatible identifier + for any DID, so previously anyone could serve an unsigned object that + claimed to be someone else's portable object. + [[#288], [#837], [#1082], [#1090], [#1091], [#1107], [#1120]] + + - With the `verifyPortableObject` option, a compatible identifier is + dereferenced as the portable object it stands for: through the + gateway that it names and then the gateways in the `gateways` option, + only if the option accepts the object. A document fetched from + an ordinary HTTP(S) URL is verified the same way if its final URL is + a compatible identifier or its `@id` is a portable ID. Malformed + compatible identifiers are rejected without a request. + + - Without the option, accessors keep fetching compatible identifiers as + ordinary HTTP(S) URLs, but no longer cache the results in the parent + objects, so that a later call with the option verifies them. + However, accessors of an object whose ID is a portable ID or + a compatible identifier now throw a `TypeError` (or return `null` with + `suppressError: true`) for such references without the option, as + for portable IDs. + + - Accessors no longer trust an embedded object whose `@id` is + a compatible identifier, or a portable ID with a DID other than its + parent's, even with `crossOrigin: "trust"`; they dereference and + verify it on its own. Likewise, `crossOrigin: "trust"` no longer + makes `lookupObject()` return an object with a portable `@id` from + a document URL of another origin. + + - Updated [FEP-fe34] cross-origin checks to understand the cryptographic + origins of [FEP-ef61] portable IDs and DID URLs. Property accessors and + `lookupObject()` now treat `ap:` and `ap+ef61:` IDs and `did:key` + verification method IDs as the same origin when their DIDs match. + [[#288], [#829], [#926]] + + - Changed nested serialization so that an object carrying the signed + JSON-LD representation that `signObject()` retains is embedded with that + exact representation, including its own `@context`, rather than being + rebuilt under the parent's context, so that its proof keeps verifying. + `clone()` never carries the retained representation, because a clone may + differ from the document the proof covers. [[#288], [#1044], [#1051]] + +[FEP-ef61]: https://w3id.org/fep/ef61 +[portable objects]: https://fedify.dev/manual/portable +[FEP-fe34]: https://w3id.org/fep/fe34 diff --git a/changes.d/vocab/portable-verifier-types.md b/changes.d/vocab/portable-verifier-types.md deleted file mode 100644 index 999531d5d..000000000 --- a/changes.d/vocab/portable-verifier-types.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#1160': https://github.com/fedify-dev/fedify/issues/1160 - '#1184': https://github.com/fedify-dev/fedify/pull/1184 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Exported portable object verifier types from `@fedify/vocab`, so callers - can type custom verifiers without importing `@fedify/vocab-runtime`. - Also exported other types used in vocabulary API signatures. - [[#288], [#1160], [#1184]] diff --git a/changes.d/vocab/portable-webfinger-lookup.md b/changes.d/vocab/portable-webfinger-lookup.md deleted file mode 100644 index 1131aa71f..000000000 --- a/changes.d/vocab/portable-webfinger-lookup.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -links: - '#1082': https://github.com/fedify-dev/fedify/pull/1082 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#837': https://github.com/fedify-dev/fedify/issues/837 ---- - - Added the `verifyPortableObject` option to `LookupObjectOptions`. With - it, `lookupObject()` looks up [FEP-ef61] portable objects: `ap:` and - `ap+ef61:` URIs through their `@gateway` location hints, compatible - identifiers through the gateways they name, and portable actors' - handles through the `self` links of their WebFinger responses, which - can be either of them. A fetched object is returned only if its `@id` - identifies the requested portable object and the option accepts it; - otherwise, the next candidate is tried, at most five gateways per - lookup. `crossOrigin: "throw"` makes a rejected object throw an error, - and `crossOrigin: "trust"` does not skip the checks. - [[#288], [#837], [#1082]] - - - `crossOrigin: "trust"` no longer makes `lookupObject()` return an object - whose `@id` is an `ap:` or `ap+ef61:` URI from a document URL of another - origin, such as a compatible identifier fetched as an ordinary HTTP(S) - URL, since a portable object is authenticated by its proofs, not by the - server that serves it. Look such objects up with the - `verifyPortableObject` option instead. [[#288], [#837], [#1082]] - - - `getActorHandle()` now supports [FEP-ef61] portable actors. It takes the - domain of a portable actor's handle from the first gateway in its - `gateways` instead of its ID, and returns the handle only if its - WebFinger response links back to the actor, either by its portable ID - or by a compatible identifier, since the gateways are claimed by the - actor itself. It throws a `TypeError` otherwise, including when the - WebFinger lookup fails, and for a portable actor without `gateways` or - `preferredUsername` or a portable actor URI. [[#288], [#837], [#1082]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab/recipient-gateways.md b/changes.d/vocab/recipient-gateways.md deleted file mode 100644 index daf8db6ab..000000000 --- a/changes.d/vocab/recipient-gateways.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -links: - '#1147': https://github.com/fedify-dev/fedify/issues/1147 - '#1180': https://github.com/fedify-dev/fedify/pull/1180 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added the optional `Recipient.gateways` property, the [FEP-ef61] gateways - of a portable actor, through which Fedify delivers activities to its - `ap:` or `ap+ef61:` inbox. Every actor class already has it, so - applications that build `Recipient` objects by hand, e.g., in followers - collection dispatchers, need to set it only for portable actors. - [[#288], [#1147], [#1180]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab/signed-child-representation.md b/changes.d/vocab/signed-child-representation.md deleted file mode 100644 index 3510c0c56..000000000 --- a/changes.d/vocab/signed-child-representation.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -links: - '#1044': https://github.com/fedify-dev/fedify/issues/1044 - '#1051': https://github.com/fedify-dev/fedify/pull/1051 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Changed nested serialization so that an object carrying a signed JSON-LD - representation retained by `signObject()` is embedded with that exact - representation, including its own `@context`, rather than being rebuilt - under the parent's context. `clone()` never carries the retained - representation, because a clone may differ from the document the proof - covers. [[#288], [#1044], [#1051]] diff --git a/docs/manual/portable.md b/docs/manual/portable.md index 7b5041865..833a76a50 100644 --- a/docs/manual/portable.md +++ b/docs/manual/portable.md @@ -1,8 +1,9 @@ --- description: >- Fedify supports a profile of FEP-ef61 portable objects. This section - explains which parts of FEP-ef61 Fedify implements, where it deliberately - differs from the current FEP text, and what it does not support yet. + walks through running portable actors, and explains which parts of + FEP-ef61 Fedify implements, where it deliberately differs from the current + FEP text, and what it does not support yet. --- Portable objects @@ -23,16 +24,534 @@ FEP-ef61 is still a draft, and some of the specifications it relies on leave questions open. Fedify therefore implements a *profile* of FEP-ef61: most of what a gateway and a consumer of portable objects need, with a few deliberate choices that differ from the current FEP text or rest on semantics that are -not settled yet, and without some parts of the FEP. This section describes -that profile as a whole, so that you and other implementers can tell what to -expect from a Fedify server. Each feature is explained in detail in the -section it links to. +not settled yet, and without some parts of the FEP. + +This chapter first walks through running portable actors with Fedify, and +then describes the profile as a whole, so that you and other implementers can +tell what to expect from a Fedify server. Each feature is explained in detail +in the section it links to. [FEP-ef61]: https://w3id.org/fep/ef61 [DID]: https://www.w3.org/TR/did-core/ [FEP-8b32]: https://w3id.org/fep/8b32 +Running portable actors +----------------------- + +This section shows how to host a portable actor in a Fedify application, from +creating its DID to sending and receiving activities. Each step links to the +sections of the manual that explain its APIs in detail. The examples assume a +single server, `https://example.com`, that acts as the actor's only gateway; +see [*Running on several gateways*](#running-on-several-gateways) for more. + +### Creating a DID + +A portable actor is identified by a [DID] rather than by a server, and +everything it publishes is signed with a key of the DID. Fedify supports +`did:key` DIDs made from Ed25519 public keys, so generate an Ed25519 key pair +for each portable actor, and make its DID with `exportDidKey()`: + +~~~~ typescript twoslash +import { exportJwk, generateCryptoKeyPair } from "@fedify/fedify"; +import { exportDidKey } from "@fedify/vocab-runtime"; + +const { publicKey, privateKey } = await generateCryptoKeyPair("Ed25519"); +const did = await exportDidKey(publicKey); // did:key:z6Mk... +// The verification method of the DID's key, which proofs refer to: +const keyId = new URL(`${did}#${did.slice("did:key:".length)}`); + +// Store the DID and the key pair along with the actor, e.g., as JWKs: +const jwks = { + publicKey: await exportJwk(publicKey), + privateKey: await exportJwk(privateKey), +}; +~~~~ + +The DID is the actor's identity: every ID the actor has is built from it, and +whoever holds its private key can act as the actor. Keep the private key +safe, and do not lose it, since Fedify has no workflow for rotating it or for +moving an actor to another DID. Store the DID along with the actor, rather +than taking it from requests. See the [*Portable IDs* +section](./context.md#portable-ids) of the *Context* chapter for more. + +### Dispatching the actor + +The actor dispatcher returns a portable actor as it would an ordinary actor. +Build its portable ID from the dispatcher's path and the DID with +`~Context.getPortableActorUri()`, and sign the actor with the DID's key by +`signObject()`. Its inbox and collections get portable IDs as well, +and its `gateways` lists the servers that host it, the first of which gives +the domain of its fediverse handle: + +~~~~ typescript twoslash +import { + createFederation, + MemoryKvStore, + signObject, +} from "@fedify/fedify"; +import { Person } from "@fedify/vocab"; +interface User { + identifier: string; + username: string; + did: string; + didKeyPair: CryptoKeyPair; + gatewayKeyPair: CryptoKeyPair; +} +async function findUser(_identifier: string): Promise { + return null; +} +async function findUserByUsername(_username: string): Promise { + return null; +} +function getDidKeyId(did: string): URL { + return new URL(`${did}#${did.slice("did:key:".length)}`); +} +// ---cut-before--- +const federation = createFederation({ + kv: new MemoryKvStore(), + origin: "https://example.com", +}); + +federation + .setActorDispatcher("/users/{identifier}", async (ctx, identifier) => { + const user = await findUser(identifier); + if (user == null) return null; + // A request through the gateway endpoint, e.g., + // GET /.well-known/apgateway/did:key:z6Mk.../users/alice, names the DID + // in its path, so make sure that it is the user's: + if ( + ctx.portableRequest != null && + ctx.portableRequest.authority !== user.did + ) { + return null; + } + // This server's gateway keys for the actor (see below): + const keys = await ctx.getActorKeyPairs(identifier); + return await signObject( + new Person({ + // ap+ef61://did:key:z6Mk.../users/alice + id: ctx.getPortableActorUri(identifier, user.did), + preferredUsername: user.username, + inbox: ctx.getPortableInboxUri(identifier, user.did), + outbox: ctx.getPortableOutboxUri(identifier, user.did), + followers: ctx.getPortableFollowersUri(identifier, user.did), + gateways: [new URL("https://example.com")], + publicKeys: keys.map((key) => key.cryptographicKey), + assertionMethods: keys.map((key) => key.multikey), + }), + user.didKeyPair.privateKey, + getDidKeyId(user.did), // did:key:z6Mk...#z6Mk... + ); + }) + .setKeyPairsDispatcher(async (ctx, identifier) => { + const user = await findUser(identifier); + // This server's own key pair for the actor, not the DID's key pair: + return user == null ? [] : [user.gatewayKeyPair]; + }) + .mapPortableActorId(async (ctx, identifier) => { + const user = await findUser(identifier); + return user == null + ? null + : ctx.getPortableActorUri(identifier, user.did); + }) + .mapHandle(async (ctx, username) => { + const user = await findUserByUsername(username); + return user?.identifier ?? null; + }); +~~~~ + +With this dispatcher, Fedify serves the actor in several ways: + + - Through the FEP-ef61 gateway endpoint, at the actor's compatible + identifier, e.g., + `https://example.com/.well-known/apgateway/did:key:z6Mk.../users/alice`, + which is how other servers retrieve it. Fedify serves the actor there + only if its ID is the requested portable ID and it has a proof made with + a key of the DID, and responds with `500 Internal Server Error` if the + proof is missing. + - Through WebFinger, as `@alice@example.com`, whose `self` link is the + compatible identifier above. The domain comes from the first gateway in + the actor's `gateways`, which has to be an HTTP(S) origin. + - At its ordinary URL, e.g., `https://example.com/users/alice`, as before. + +See the [*Portable actors and WebFinger* +section](./actor.md#portable-actors-and-webfinger) for the details. + +The key pairs dispatcher and `~ActorCallbackSetters.mapPortableActorId()` +give the actor *gateway keys*: this server's own keys for the actor, which +sign the HTTP requests that the server makes on behalf of the actor, such as +deliveries. They never sign the actor's activities or objects, which only +the DID's key does. The actor document lists them in its +`assertionMethods`, so that other servers can verify the HTTP Signatures. +See the [*Gateway keys of portable actors* +section](./actor.md#gateway-keys-of-portable-actors). + +> [!TIP] +> Software that does not support FEP-ef61 may refuse an actor whose ID is +> a portable ID. If your actors have to interoperate with such software, +> identify them by their compatible identifiers instead; see the [*Compatible +> identifiers as actor IDs* +> section](./actor.md#compatible-identifiers-as-actor-ids). + +### Serving objects and collections + +Object dispatchers serve portable objects through the gateway endpoint in +the same way, e.g., +`GET /.well-known/apgateway/did:key:z6Mk.../users/alice/notes/1` by +the dispatcher for `/users/{identifier}/notes/{id}`. Give such an object +the portable ID that `~Context.getPortableObjectUri()` builds, and sign it +with the DID's key: + +~~~~ typescript twoslash +import { type Federation, signObject } from "@fedify/fedify"; +import { Note, PUBLIC_COLLECTION } from "@fedify/vocab"; +import { withGatewayHints } from "@fedify/vocab-runtime"; +const federation = null as unknown as Federation; +interface Post { content: string; didKeyPair: CryptoKeyPair } +async function findPost( + _did: string, + _identifier: string, + _id: string, +): Promise { + return null; +} +function getDidKeyId(did: string): URL { + return new URL(`${did}#${did.slice("did:key:".length)}`); +} +// ---cut-before--- +federation.setObjectDispatcher( + Note, + "/users/{identifier}/notes/{id}", + async (ctx, values) => { + // Ordinary requests are omitted for brevity: + if (ctx.portableRequest == null) return null; + const { authority } = ctx.portableRequest; + // Look the post up by the DID as well, since anyone can ask for any DID: + const post = await findPost(authority, values.identifier, values.id); + if (post == null) return null; + return await signObject( + new Note({ + // ap+ef61://did:key:z6Mk.../users/alice/notes/1 + id: ctx.getPortableObjectUri(Note, values), + // ap+ef61://did:key:z6Mk.../users/alice?@gateway=https%3A%2F%2Fexample.com + attribution: withGatewayHints( + ctx.getPortableActorUri(values.identifier), + [new URL("https://example.com")], + ), + to: PUBLIC_COLLECTION, + content: post.content, + }), + post.didKeyPair.privateKey, + getDidKeyId(authority), + ); + }, +); +~~~~ + +Fedify serves only publicly addressed portable objects unless the dispatcher +has an authorization predicate, since a gateway must not serve a non-public +object to anyone but its audience; `~RequestContext.isSignedByAudience()` +helps to write such a predicate. Return a signed `Tombstone` for a deleted +object, which is served with `410 Gone`. See the [*Serving portable objects* +section](./object.md#serving-portable-objects) and the sections that follow +it. + +Collection dispatchers, such as the outbox and followers dispatchers, serve +the actor's portable collections through the gateway endpoint as well, if the +actor's corresponding property has the portable ID that the matching method +builds, e.g., if its `outbox` is what `~Context.getPortableOutboxUri()` +returns. The collections themselves need no proofs, but the portable +activities and objects embedded in them do. See the +[*Portable collections* section](./collections.md#portable-collections). + +### Receiving activities + +A portable actor's inbox is reached through the gateway endpoint as well, +e.g., +`POST /.well-known/apgateway/did:key:z6Mk.../users/alice/inbox`, and Fedify +routes it by the path after the DID to the same inbox listeners as the ordinary +inbox. Fedify accepts such a delivery only if the actor dispatcher returns a +portable actor whose `inbox` is the requested inbox and whose `gateways` +include this server. + +In a listener, `~Context.parseUri()` with the `portable` option tells which +of your portable actors an activity is about, and its `authority` property +has the DID, which you have to check against the one you store: + +~~~~ typescript twoslash +import { type Federation, signObject } from "@fedify/fedify"; +import { Accept, Follow, Note } from "@fedify/vocab"; +import { withGatewayHints } from "@fedify/vocab-runtime"; +const federation = null as unknown as Federation; +interface User { identifier: string; did: string; didKeyPair: CryptoKeyPair } +async function findUser(_identifier: string): Promise { + return null; +} +async function addFollower(_user: User, _follower: URL): Promise {} +function getDidKeyId(did: string): URL { + return new URL(`${did}#${did.slice("did:key:".length)}`); +} +// ---cut-before--- +federation + .setInboxListeners("/users/{identifier}/inbox", "/inbox") + .on(Follow, async (ctx, follow) => { + if (follow.id == null || follow.objectId == null) return; + const parsed = ctx.parseUri(follow.objectId, { portable: true }); + if (parsed?.type !== "actor") return; + const user = await findUser(parsed.identifier); + if (user == null || parsed.authority !== user.did) return; + const follower = await follow.getActor(ctx); + if (follower?.id == null) return; + await addFollower(user, follower.id); + const accept = await signObject( + new Accept({ + id: ctx.getPortableObjectUri( + Note, // Any object dispatcher's path would do. + { identifier: user.identifier, id: crypto.randomUUID() }, + user.did, + ), + // With location hints, so that the recipient can fetch the actor: + actor: withGatewayHints( + ctx.getPortableActorUri(user.identifier, user.did), + [new URL("https://example.com")], + ), + object: follow.id, + }), + user.didKeyPair.privateKey, + getDidKeyId(user.did), + ); + await ctx.sendActivity( + { identifier: user.identifier }, + follower, + accept, + { normalizeExistingProofs: true }, + ); + }); +~~~~ + + - Fedify accepts an activity of a portable actor, or one with a portable + ID, only if it has a valid proof made by that DID; an HTTP Signature does + not authenticate it. Portable objects embedded in an activity need their + own proofs. See the [*Portable actors* section](./inbox.md#portable-actors) + and the [*Compound portable objects* + section](./inbox.md#compound-portable-objects) of the *Inbox listeners* + chapter. + - Accessors such as `~Follow.getActor()` verify the portable objects they + fetch, since activities that inboxes receive use + `~Context.verifyPortableObject` by default. See the [*Default verifiers* + section](./vocab.md#default-verifiers). + - Fedify forwards activities received in a portable inbox to the actor's + other gateways, if the key–value store supports `~KvStore.cas()`. + Configure the `origin` option, as in the example above, so that Fedify + can tell which gateway it is. See the [*Portable inboxes* + section](./inbox.md#portable-inboxes) and the [*Forwarding to other + gateways* section](./inbox.md#forwarding-to-other-gateways). + +### Sending activities + +The activities of a portable actor are signed with the DID's key, which +the key pairs dispatcher does not know. So sign them with `signObject()` +before sending them, as the `Accept` above is, and pass +`normalizeExistingProofs: true` to `~Context.sendActivity()` so that the +activity is sent in the form that the proof covers. If an activity embeds a +portable object, such as the `Note` of a `Create`, sign the object first, and +then the activity: + +~~~~ typescript twoslash +import { type Context, signObject } from "@fedify/fedify"; +import { Create, Note, PUBLIC_COLLECTION } from "@fedify/vocab"; +import { withGatewayHints } from "@fedify/vocab-runtime"; +const ctx = null as unknown as Context; +interface User { identifier: string; did: string; didKeyPair: CryptoKeyPair } +const user = null as unknown as User; +function getDidKeyId(did: string): URL { + return new URL(`${did}#${did.slice("did:key:".length)}`); +} +// ---cut-before--- +const gateways = [new URL("https://example.com")]; +// A reference to the actor, with location hints that tell where to get it: +// ap+ef61://did:key:z6Mk.../users/alice?@gateway=https%3A%2F%2Fexample.com +const actor = withGatewayHints( + ctx.getPortableActorUri(user.identifier, user.did), + gateways, +); +const note = await signObject( + new Note({ + id: ctx.getPortableObjectUri( + Note, + { identifier: user.identifier, id: crypto.randomUUID() }, + user.did, + ), + attribution: actor, + to: PUBLIC_COLLECTION, + content: "Hello, world!", + }), + user.didKeyPair.privateKey, + getDidKeyId(user.did), +); +const create = await signObject( + new Create({ + id: ctx.getPortableObjectUri( + Note, // Any object dispatcher's path would do. + { identifier: user.identifier, id: crypto.randomUUID() }, + user.did, + ), + actor, + to: PUBLIC_COLLECTION, + object: note, + }), + user.didKeyPair.privateKey, + getDidKeyId(user.did), +); +await ctx.sendActivity( + { identifier: user.identifier }, + "followers", + create, + { normalizeExistingProofs: true }, +); +~~~~ + + - The activity has to have a portable ID of the actor's DID, and it is + signed with the DID's key only; `~Context.sendActivity()` throws + a `TypeError` otherwise, e.g., for an unsigned portable activity. The + HTTP requests are signed with the gateway keys. See the [*Choosing the + proof key* section](./send.md#choosing-the-proof-key). + - Location hints go on references to portable actors, such as `actor` and + `attributedTo`, but not on an object's own `id`, and they have to be + added before signing. See the [*Location hints* + section](./vocab.md#location-hints). + - An embedded portable object can be verified on its own only if it is signed + with `signObject()` before it is embedded. See the [*Producing + a compound document* section](./send.md#producing-a-compound-document). + - Recipients that are portable actors themselves are delivered to through + their gateways. If your followers collection dispatcher returns + `Recipient` objects, include the `~Recipient.gateways` of portable + followers. See the [*Delivering to portable actors* + section](./send.md#delivering-to-portable-actors). + +### Attaching media + +A portable object refers to its media, such as images, by [hashlinks], which +carry the digests of the media, so that the media can be retrieved from any +gateway and verified. Compute the digest with `computeDigestMultibase()`, +and make the hashlink with `createHashlink()`: + +~~~~ typescript twoslash +import { Image } from "@fedify/vocab"; +import { + computeDigestMultibase, + createHashlink, +} from "@fedify/vocab-runtime"; +declare const bytes: Uint8Array; +// ---cut-before--- +const digestMultibase = await computeDigestMultibase(bytes); +const image = new Image({ + url: new URL(createHashlink(digestMultibase)), // hl:zQm... + mediaType: "image/png", + digestMultibase, +}); +~~~~ + +To serve the media through the gateway endpoint, e.g., +`GET /.well-known/apgateway/hl:zQm...`, register a hashlink media dispatcher +with `~Federatable.setHashlinkMediaDispatcher()`. Fedify does not check what +the dispatcher serves against the digest, so store the media under their +digests. See the [*Serving hashlink media* +section](./object.md#serving-hashlink-media). To retrieve and verify the media +of others' portable objects, use `fetchPortableMedia()`; see the +[*Portable media* section](./vocab.md#portable-media). + +[hashlinks]: https://datatracker.ietf.org/doc/html/draft-sporny-hashlink-07 + +### Looking up portable objects + +`~Context.lookupObject()` looks up portable objects of others by their +portable IDs, their compatible identifiers, and the fediverse handles of +portable actors, and returns them only if their proofs are valid: + +~~~~ typescript twoslash +import type { Context } from "@fedify/fedify"; +const ctx = null as unknown as Context; +// ---cut-before--- +// Through WebFinger: +const actor = await ctx.lookupObject("@alice@example.com"); +// A portable ID without location hints needs gateways to ask: +const note = await ctx.lookupObject("ap://did:key:z6Mk.../notes/1", { + gateways: ["https://example.com"], +}); +~~~~ + +Property accessors of the returned objects, and of the activities that +inboxes receive, verify the portable objects they dereference, too. For +objects obtained elsewhere, pass a `Context` as the options of an accessor, +e.g., `await create.getObject(ctx)`, to verify them. + +A portable actor's own collections, such as its outbox, have no location +hints, and accessors do not take the actor's `gateways` by themselves, so +pass them along with the context's verifier: + +~~~~ typescript twoslash +import type { Context } from "@fedify/fedify"; +import { isActor, traverseCollection } from "@fedify/vocab"; +const ctx = null as unknown as Context; +// ---cut-before--- +const actor = await ctx.lookupObject("@alice@example.com"); +if (isActor(actor)) { + const options = { + documentLoader: ctx.documentLoader, + contextLoader: ctx.contextLoader, + verifyPortableObject: ctx.verifyPortableObject, + gateways: actor.gateways, + }; + const outbox = await actor.getOutbox(options); + if (outbox != null) { + for await (const item of traverseCollection(outbox, options)) { + console.log(item.id?.href); + } + } +} +~~~~ + +Unsigned collections are accepted only from gateways that their owners +list, as described in the [*Portable collections* +section](./vocab.md#portable-collections) of the *Vocabulary* chapter. See the +[*Portable objects* section](./context.md#portable-objects) of the *Context* +chapter and the +[*Dereferencing portable references* section](./vocab.md#dereferencing-portable-references). + +### Running on several gateways + +The point of a portable actor is that it can be hosted by several servers, +so that it survives any of them. Fedify, however, does not copy actors, +objects, or collections between gateways; the only built-in exchange between +them is the forwarding of activities that portable inboxes receive. To host +an actor on several gateways: + + - List every gateway in the actor's `gateways`, in the order of preference. + Each of them has to serve the actor, its objects, and its collections, + and to accept deliveries to its inbox, e.g., by running an application + like the one above with the same data. + - List the gateway keys of every gateway in the actor's + `assertionMethods`, not only those of the server that serves the + document, so that each gateway's HTTP Signatures can be verified. See + the [*Gateway keys of portable actors* + section](./actor.md#gateway-keys-of-portable-actors). + - Decide which servers hold the DID's private key. A gateway that signs + documents when it serves them, like the example above, needs the key. + Otherwise, the application has to store the signed documents and keep + them in sync across the gateways by itself. Keep the received JSON of + such documents rather than serializing vocabulary objects parsed from + them, which can change what their proofs cover; see the [*Staying + compatible* section](#staying-compatible). + +### Testing + +The mock federation and contexts of `@fedify/testing` support portable IDs, +portable object verification with fixture document loaders, gateway +requests, and hashlink media. See the [*Testing* chapter](./test.md). + + Supported features ------------------ @@ -333,16 +852,31 @@ Other limits consumers, Fedify included, do not accept them unsecured, so they may not be usable by others yet. -The following work for Fedify 2.4 is still in progress: +[FEP-ae97]: https://w3id.org/fep/ae97 + - - Support for portable objects in the `fedify` CLI ([#1156]). - - Testing against other implementations of FEP-ef61 ([#1097]). Until - then, Fedify's profile has been checked only against Fedify itself and - against fixtures modeled on other implementations. +Interoperability +---------------- + +Besides Fedify itself, Fedify's profile has been tested against [tootik] +v0.25.4 and [Mitra] v5.10.0. Fedify verifies tootik's portable actors, +activities, and HTTP Signatures, and Mitra's gateway HTTP Signatures on +activities that a client signed, and both accept portable activities that +Fedify sends. Fedify has not yet verified a portable actor or activity that +Mitra itself signed. Mastodon's handling of portable actors has not +been tested. The [*FEP-ef61 interoperability*][interoperability] section of +*FEDERATION.md* records what was tested and how, along with the limits that +were found, e.g., that tootik v0.25.4 does not recognize compatible +identifiers with explicit ports. + +The `fedify lookup` command looks up and verifies portable objects, which +helps to check what your server serves; see the [*`fedify lookup`* +section](../cli.md#fedify-lookup-looking-up-an-activitypub-object) of the CLI +manual. *[DID]: Decentralized Identifier *[FEP]: Fediverse Enhancement Proposal -[FEP-ae97]: https://w3id.org/fep/ae97 -[#1097]: https://github.com/fedify-dev/fedify/issues/1097 -[#1156]: https://github.com/fedify-dev/fedify/issues/1156 +[tootik]: https://github.com/dimkr/tootik +[Mitra]: https://codeberg.org/silverpill/mitra +[interoperability]: https://github.com/fedify-dev/fedify/blob/main/FEDERATION.md#fep-ef61-interoperability diff --git a/docs/manual/send.md b/docs/manual/send.md index eec1a4431..dd7ac1001 100644 --- a/docs/manual/send.md +++ b/docs/manual/send.md @@ -1169,14 +1169,14 @@ proof must use a DID URL, and that DID must match the authority of the portable object ID. A portable actor must also have a non-empty `gateways` list whose items are all HTTP(S) URIs with an empty path, query, and fragment; this is checked before the proofs, so the `invalidGateways` reason does not mean that -the proofs are valid. When a portable actor omits the JSON-LD mapping for +the proofs are valid. When a portable actor omits the JSON-LD mapping for `gateways`, as tootik v0.25.4 does, Fedify accepts the otherwise unmapped -ActivityStreams term only if every proof uses `eddsa-jcs-2022`. These proofs +ActivityStreams term only if every proof uses `eddsa-jcs-2022`. These proofs authenticate the original JSON, including the gateway list. -The detailed result distinguishes documents outside the -policy, missing or invalid proofs, actors without valid gateways, unsupported -verification methods, DID mismatches, and successful verification: +The detailed result distinguishes documents outside the policy, missing or +invalid proofs, actors without valid gateways, unsupported verification +methods, DID mismatches, and successful verification: ~~~~ typescript import { verifyPortableObjectProof } from "@fedify/fedify"; @@ -1239,9 +1239,9 @@ the `publicKey` or `assertionMethod` of a portable actor, such as a gateway key, whose ID is the actor's compatible identifier plus a fragment; the actor's proof covers it. Fedify verifies each map against an immutable copy of the received JSON and applies the FEP-ef61 portable-ID and controlling-DID -policy to that map. It does not copy a parent's context into a child, try +policy to that map. It does not copy a parent's context into a child, try several proof-removal rules, or fetch an unpinned context from the live -network. Inputs that exceed the traversal limits are rejected. Fedify does not +network. Inputs that exceed the traversal limits are rejected. Fedify does not return authentication results for only part of a compound document. This profile authenticates JSON snapshots. A child proof may be valid when @@ -1265,9 +1265,10 @@ differ from the parent's: ~~~~ typescript twoslash import { signObject } from "@fedify/fedify"; import { Create, Note } from "@fedify/vocab"; -const noteId = new URL("ap://did:key:z6Mkabc/objects/1"); -const activityId = new URL("ap://did:key:z6Mkabc/activities/1"); -const actorId = new URL("ap://did:key:z6Mkabc/actor"); +import { parseIri } from "@fedify/vocab-runtime"; +const noteId = parseIri("ap://did:key:z6Mkabc/objects/1"); +const activityId = parseIri("ap://did:key:z6Mkabc/activities/1"); +const actorId = parseIri("ap://did:key:z6Mkabc/actor"); const key = null as unknown as CryptoKey; const keyId = new URL("did:key:z6Mkabc#z6Mkabc"); const portableContext = [ diff --git a/docs/manual/vocab.md b/docs/manual/vocab.md index b346ffe6f..a789e4e36 100644 --- a/docs/manual/vocab.md +++ b/docs/manual/vocab.md @@ -266,13 +266,13 @@ const actor = new Person({ Each gateway must be an HTTP(S) base URI with no path, query, or fragment. Newly serialized gateway lists use origins without a trailing slash, while -the in-memory `URL` values retain their root path. A parsed actor's default -JSON output can retain the cached spelling of its gateways. Keep the received +the in-memory `URL` values retain their root path. A parsed actor's default +JSON output can retain the cached spelling of its gateways. Keep the received JSON when verifying existing proofs. For portable actors with inbox and outbox properties, Fedify also reads an unmapped `gateways` term under the ActivityStreams context, as emitted by -tootik v0.25.4. Explicit JSON-LD mappings take precedence. Parsing this list +tootik v0.25.4. Explicit JSON-LD mappings take precedence. Parsing this list does not authenticate it; use portable object verification before trusting the actor or its gateways. @@ -539,7 +539,7 @@ instead. The option applies to that call only; it is not passed on. Objects that Fedify parses for you already have `~Context.verifyPortableObject` as their default: activities that inboxes receive, including queued ones, objects that `~Context.lookupObject()` returns, -and the activities passed to the `onOutboxError` callback. So +and the activities passed to the `onOutboxError` callback. So `create.getObject()` in an inbox listener verifies portable objects even without options. A clone does not inherit the default; pass `verifyPortableObject` to `clone()` if you need it. diff --git a/docs/manual/webfinger.md b/docs/manual/webfinger.md index fda739f55..d063d2b09 100644 --- a/docs/manual/webfinger.md +++ b/docs/manual/webfinger.md @@ -213,6 +213,24 @@ The WebFinger links dispatcher receives two parameters: > documentation for details on customizing WebFinger through actor properties. +Portable actors +--------------- + +*This API is available since Fedify 2.4.0.* + +The WebFinger endpoint also serves [FEP-ef61] portable actors, whose IDs are +not tied to any server. The domain of such an actor's address comes from +the first gateway in its `gateways` rather than from its ID, and the `self` +link is its compatible identifier on that gateway, e.g., +`https://example.com/.well-known/apgateway/did:key:z6Mk.../users/alice`. +See the [*Portable actors and WebFinger* +section](./actor.md#portable-actors-and-webfinger) of the *Actor dispatcher* +chapter for details, and the [*Portable objects* chapter](./portable.md) for +running portable actors in general. + +[FEP-ef61]: https://w3id.org/fep/ef61 + + Looking up WebFinger -------------------- diff --git a/packages/vocab-runtime/src/docloader.ts b/packages/vocab-runtime/src/docloader.ts index 7b4340430..83df23f75 100644 --- a/packages/vocab-runtime/src/docloader.ts +++ b/packages/vocab-runtime/src/docloader.ts @@ -62,6 +62,7 @@ export interface DocumentLoaderOptions { * Whether to lower error-level logs for recoverable document loading * failures to warning-level logs. The loader still throws the error. * @default `false` + * @since 2.4.0 */ suppressError?: boolean; } diff --git a/packages/vocab-runtime/src/url.ts b/packages/vocab-runtime/src/url.ts index 15d29fef3..6b6824ce9 100644 --- a/packages/vocab-runtime/src/url.ts +++ b/packages/vocab-runtime/src/url.ts @@ -81,7 +81,14 @@ function assertCompatiblePathCanBeParsed(raw: string, parsed: URL): void { } /** - * Parses a JSON-LD `@id` value as an IRI. + * Parses a JSON-LD `@id` value as an IRI, including FEP-ef61 portable + * ActivityPub IRIs. See {@link parseIri} for how IRIs are parsed. + * @param id The `@id` value. + * @param base The base IRI to resolve a relative `@id` against. + * @returns The parsed IRI, or `undefined` if `id` is missing or a blank node + * identifier. + * @throws {TypeError} If `id` is not a valid IRI. + * @since 2.4.0 */ export function parseJsonLdId( id: string | undefined, @@ -103,6 +110,16 @@ export function parseJsonLdId( * This also applies to compatible identifier strings used as relative bases. * A `URL` argument may already have lost such segments before this function * receives it. + * + * Portable IRIs, e.g., `ap://did:key:z6Mk.../actor`, cannot be represented by + * JavaScript `URL` as they are, so the returned `URL` keeps the DID authority + * percent-encoded, e.g., `ap+ef61://did%3Akey%3Az6Mk.../actor`. Use + * {@link formatIri} to get the canonical string back. + * @param iri The IRI to parse. + * @param base The base IRI to resolve a relative IRI against. + * @returns The parsed IRI. + * @throws {TypeError} If the IRI is malformed. + * @since 2.4.0 */ export function parseIri(iri: string | URL, base?: string | URL): URL { if (iri instanceof URL) { @@ -132,6 +149,12 @@ export function parseIri(iri: string | URL, base?: string | URL): URL { * the scheme this function produces. Do not compare its results as strings to * tell whether two portable IRIs identify the same object; use * `arePortableUrisEqual()` instead. + * @param iri The IRI to format. + * @returns The formatted IRI. A string that cannot be parsed as a URL at all + * is returned unchanged. + * @throws {TypeError} If the IRI is a malformed portable IRI or FEP-ef61 + * compatible identifier, e.g., one with dot segments. + * @since 2.4.0 */ export function formatIri(iri: string | URL): string { if (typeof iri === "string") assertPortablePathCanBeParsed(iri); @@ -271,7 +294,20 @@ export function haveSameFe34Origin( } /** - * Checks whether two IRIs have the same origin. + * Checks whether two IRIs have the same origin. Unlike comparing + * `URL.origin`, which is `"null"` for URLs with non-special schemes, this + * compares FEP-ef61 portable ActivityPub IRIs by their schemes and DIDs, so + * that `ap:` and `ap+ef61:` IRIs of the same DID with decoded or + * percent-encoded authorities have the same origin. Other IRIs with + * a non-special scheme and a host are compared by their schemes and hosts. + * + * This is not an FEP-fe34 origin check: an `ap+ef61:` IRI and the `did:key` + * verification method of the same DID have different origins here. Use + * {@link haveSameFe34Origin} for that. + * @param left The first IRI. + * @param right The second IRI. + * @returns `true` if the IRIs have the same origin. + * @since 2.4.0 */ export function haveSameIriOrigin(left: URL, right: URL): boolean { return getComparableIriOrigin(left) === getComparableIriOrigin(right); @@ -417,7 +453,16 @@ function parseAtUri(uri: string): URL { } /** - * Checks whether the URL is an FEP-ef61 gateway base URI. + * Checks whether the URL is an FEP-ef61 gateway base URI, i.e., an HTTP(S) + * URI with no credentials, path, query, or fragment, such as + * `https://example.com/`. FEP-ef61 requires every item of a portable actor's + * `gateways` to be such a URI. A URI with an empty query or fragment + * delimiter, such as `https://example.com/?`, is not a gateway base URI. + * + * Note that the `URL` class normalizes `https://example.com` to + * `https://example.com/`, so both are gateway base URIs. + * @param url The URL to check. + * @returns `true` if the URL is an FEP-ef61 gateway base URI. * @since 2.4.0 */ export function isGatewayUrl(url: URL): boolean { @@ -426,7 +471,11 @@ export function isGatewayUrl(url: URL): boolean { } /** - * Parses and validates an FEP-ef61 gateway base URI. + * Parses and validates an FEP-ef61 gateway base URI, i.e., an HTTP(S) URI with + * no credentials, path, query, or fragment, such as `https://example.com`. + * See {@link isGatewayUrl} for the rules. + * @param url The gateway base URI to parse. + * @returns The parsed gateway base URI, whose path is `/`. * @throws {TypeError} If the URI is malformed, or is not an HTTP(S) base URI * with no credentials, path, query, or fragment. In the * latter case, the message starts with From b8d3edffc8f209bf4a4a060e4b02990f8a0b97af Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 01:50:51 +0900 Subject: [PATCH 016/184] Serve empty portable collections with totalItems A portable collection is served without an Object Integrity Proof, so consumers tell it from other objects by its collection properties, as FEP-2277 does. An unpaginated collection whose dispatcher returned no items and that had no counter was served with none of them, e.g., {"type": "OrderedCollection", "id": ..., "attributedTo": ...}, so Fedify's own verifyPortableObject() classified it as an object and rejected it with missingProof. Reading an empty portable outbox served by Fedify therefore failed. For portable requests, the unpaginated collection now falls back to the number of dispatched items as its totalItems, since the dispatcher returns all of them in that case. Ordinary collections are served as before. https://github.com/fedify-dev/fedify/issues/288 Assisted-by: Claude Code:claude-opus-5-5 --- CHANGES.md | 4 +- changes.d/fedify/portable-objects.md | 4 +- docs/manual/collections.md | 5 ++ packages/fedify/src/federation/handler.ts | 8 ++- .../federation/portable-collection.test.ts | 50 ++++++++++++++++++- 5 files changed, 67 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 4d1f54bfb..db19f6dca 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -110,7 +110,9 @@ To be released. through the gateway endpoint, e.g., `GET /.well-known/apgateway/did:key:z6Mk.../users/alice/outbox`, if the actor is a portable actor under the requested DID whose - corresponding property refers to the collection. Added + corresponding property refers to the collection. A collection that + is not paginated always has `totalItems`, so that consumers can tell + an empty one from other objects. Added the `CustomCollectionCallbackSetters.mapPortableOwner()` method and the `PortableCollectionOwnerMapper` type, which tie a custom collection to its portable owner. [[#1111], [#1142]] diff --git a/changes.d/fedify/portable-objects.md b/changes.d/fedify/portable-objects.md index c1f4bf21d..a83279b3e 100644 --- a/changes.d/fedify/portable-objects.md +++ b/changes.d/fedify/portable-objects.md @@ -166,7 +166,9 @@ links: through the gateway endpoint, e.g., `GET /.well-known/apgateway/did:key:z6Mk.../users/alice/outbox`, if the actor is a portable actor under the requested DID whose - corresponding property refers to the collection. Added + corresponding property refers to the collection. A collection that + is not paginated always has `totalItems`, so that consumers can tell + an empty one from other objects. Added the `CustomCollectionCallbackSetters.mapPortableOwner()` method and the `PortableCollectionOwnerMapper` type, which tie a custom collection to its portable owner. [[#1111], [#1142]] diff --git a/docs/manual/collections.md b/docs/manual/collections.md index 0924bb612..2a9a3d249 100644 --- a/docs/manual/collections.md +++ b/docs/manual/collections.md @@ -1758,6 +1758,10 @@ section](./inbox.md#portable-inboxes)). The served collection has the same ID as the actor's property, whether it is a portable ID or a compatible identifier, and its `attributedTo` is the actor. +A collection that is not paginated always has `totalItems`, which is the number +of items the dispatcher returns if no counter is set, so that consumers can +tell an empty collection, which has no other collection properties, from other +objects, as [FEP-2277] does. Its pages are identified by the collection's ID with the `cursor` query parameter, e.g., `ap+ef61://did:key:z6Mk.../users/alice/outbox?cursor=abc`, and their `first`, `last`, `prev`, `next`, and `partOf` stay under the same @@ -1822,3 +1826,4 @@ federation > custom portable collections may not be usable by others yet. [FEP-ef61]: https://w3id.org/fep/ef61 +[FEP-2277]: https://w3id.org/fep/2277 diff --git a/packages/fedify/src/federation/handler.ts b/packages/fedify/src/federation/handler.ts index fa93aace4..14ecec4ee 100644 --- a/packages/fedify/src/federation/handler.ts +++ b/packages/fedify/src/federation/handler.ts @@ -992,7 +992,13 @@ export async function handleCollection< collection = new OrderedCollection({ id: baseUri, attribution, - totalItems: totalItemCount ?? null, + // A portable collection is served without a proof, so consumers tell + // it from other objects by its collection properties (FEP-2277). + // Without a counter, an empty one would have none of them, but + // the dispatcher has returned all the items, so their number is + // the total: + totalItems: totalItemCount ?? + (portable == null ? null : itemsOrResponse.length), items: itemsOrResponse, }); } else { diff --git a/packages/fedify/src/federation/portable-collection.test.ts b/packages/fedify/src/federation/portable-collection.test.ts index d1f17f6eb..b4e7573be 100644 --- a/packages/fedify/src/federation/portable-collection.test.ts +++ b/packages/fedify/src/federation/portable-collection.test.ts @@ -22,7 +22,7 @@ import { configure, type LogRecord, reset } from "@logtape/logtape"; import { assert, assertEquals, assertFalse, assertThrows } from "@std/assert"; import { verifyServedPortableObjects } from "../sig/compound-proof.ts"; import { verifyPortableObject } from "../sig/portable-collection.ts"; -import { signObject } from "../sig/proof.ts"; +import { signObject, verifyPortableObjectProof } from "../sig/proof.ts"; import { ed25519PrivateKey, ed25519PublicKey } from "../testing/keys.ts"; import type { Context } from "./context.ts"; import type { Federation } from "./federation.ts"; @@ -923,6 +923,54 @@ test("Fedify traverses portable collections that Fedify serves", async () => { assertEquals(await actor2.getOutbox(evilOptions), null); }); +test("Fedify accepts empty portable collections that Fedify serves", async () => { + // The inbox dispatcher returns no items and has no counter, so without + // totalItems nothing would tell that the document is a collection: + const federation = createTestFederation(); + const [response, json] = await fetchJson( + federation, + gatewayUrl("/users/alice/inbox"), + ); + assertEquals(response.status, 200); + assertEquals(json?.totalItems, 0); + assertEquals( + await verifyPortableObjectProof(json, { + contextLoader: mockDocumentLoader, + }), + { verified: false, reason: { type: "unsecuredCollection" } }, + ); + + const documentLoader: DocumentLoader = async (url) => { + const target = new URL(url); + const response = await federation.fetch( + new Request(new URL(target.pathname + target.search, ORIGIN), { + headers: { Accept: ACCEPT }, + }), + { contextData: undefined }, + ); + if (!response.ok) { + throw new FetchError(url, `HTTP ${response.status}`, response); + } + return { + contextUrl: null, + documentUrl: url, + document: await response.json(), + }; + }; + const options = { + documentLoader, + contextLoader: mockDocumentLoader, + gateways: [ORIGIN], + verifyPortableObject, + }; + const actor = await lookupObject(portableId("/users/alice"), options); + assert(actor instanceof Person); + const inbox = await actor.getInbox(options); + assert(inbox instanceof OrderedCollection); + assertEquals(inbox.totalItems, 0); + assertEquals(await Array.fromAsync(traverseCollection(inbox, options)), []); +}); + test("verifyServedPortableObjects() classifies unsigned maps under their effective contexts", async () => { const AS = "https://www.w3.org/ns/activitystreams"; const collection = (member: Record) => ({ From b4744ba16579e7741e31b4b45f278b54b97acb86 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 02:05:08 +0900 Subject: [PATCH 017/184] Use actors' gateways for their own references The references in a portable actor's own document, such as its outbox and followers, have no @gateway location hints, since the actor's gateways already tell where to retrieve them. Property accessors only looked at the hints and the gateways option, though, so actor.getOutbox(ctx) on a portable actor passed the bare portable ID to the document loader, which failed with "Invalid URL" unless the caller repeated the actor's gateways in the gateways option for every accessor call and every collection traversal. A portable reference without valid hints now falls back to the gateways of the portable actor it was reached from, found by walking up the objects that led to it, e.g., from a collection page to the collection and then to the actor, as long as the actor has the same DID as the reference. At most five gateways are used, as with hints, and whatever they serve is still verified, so they only decide which servers are asked. An explicit gateways option still takes precedence. https://github.com/fedify-dev/fedify/issues/288 Assisted-by: Claude Code:claude-opus-5-5 --- CHANGES.md | 16 +- changes.d/vocab/portable-objects.md | 16 +- docs/manual/portable.md | 16 +- docs/manual/vocab.md | 18 +- .../federation/portable-collection.test.ts | 41 + .../src/internal/portable-dereference.test.ts | 62 + .../src/internal/portable-dereference.ts | 67 + .../src/__snapshots__/class.test.ts.deno.snap | 1618 +++++++++++++++-- .../src/__snapshots__/class.test.ts.node.snap | 1618 +++++++++++++++-- .../src/__snapshots__/class.test.ts.snap | 1618 +++++++++++++++-- packages/vocab-tools/src/class.ts | 1 + packages/vocab-tools/src/property.ts | 11 +- 12 files changed, 4628 insertions(+), 474 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index db19f6dca..18ed55707 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1022,14 +1022,16 @@ To be released. - Property accessors such as `Create.getObject()` now fetch portable references through gateways: those in the new `gateways` option, or - else those in the `@gateway` location hints of the reference. - A fetched object is returned only if its `@id` identifies the referenced - portable object and the verifier given as the new - `verifyPortableObject` option accepts it, typically + else those in the `@gateway` location hints of the reference. A + reference without hints that has the same DID as a portable actor it + was reached from, e.g., the actor's `outbox`, is fetched through that + actor's `gateways`. A fetched object is returned only if its `@id` + identifies the referenced portable object and the verifier given as the + new `verifyPortableObject` option accepts it, typically `verifyPortableObject()` from `@fedify/fedify`, or a `Context` passed - as the options. Portable references cannot be dereferenced - without the option, and `crossOrigin: "trust"` does not skip these - checks. [[#834], [#1077], [#1093], [#1105]] + as the options. Portable references cannot be dereferenced without the + option, and `crossOrigin: "trust"` does not skip these checks. + [[#834], [#1077], [#1093], [#1105]] - Property accessors tell the `verifyPortableObject` function where a portable object was retrieved from and which objects led to it, so diff --git a/changes.d/vocab/portable-objects.md b/changes.d/vocab/portable-objects.md index 37df2a7df..13d2f9723 100644 --- a/changes.d/vocab/portable-objects.md +++ b/changes.d/vocab/portable-objects.md @@ -62,14 +62,16 @@ links: - Property accessors such as `Create.getObject()` now fetch portable references through gateways: those in the new `gateways` option, or - else those in the `@gateway` location hints of the reference. - A fetched object is returned only if its `@id` identifies the referenced - portable object and the verifier given as the new - `verifyPortableObject` option accepts it, typically + else those in the `@gateway` location hints of the reference. A + reference without hints that has the same DID as a portable actor it + was reached from, e.g., the actor's `outbox`, is fetched through that + actor's `gateways`. A fetched object is returned only if its `@id` + identifies the referenced portable object and the verifier given as the + new `verifyPortableObject` option accepts it, typically `verifyPortableObject()` from `@fedify/fedify`, or a `Context` passed - as the options. Portable references cannot be dereferenced - without the option, and `crossOrigin: "trust"` does not skip these - checks. [[#834], [#1077], [#1093], [#1105]] + as the options. Portable references cannot be dereferenced without the + option, and `crossOrigin: "trust"` does not skip these checks. + [[#834], [#1077], [#1093], [#1105]] - Property accessors tell the `verifyPortableObject` function where a portable object was retrieved from and which objects led to it, so diff --git a/docs/manual/portable.md b/docs/manual/portable.md index 833a76a50..1916ffe94 100644 --- a/docs/manual/portable.md +++ b/docs/manual/portable.md @@ -488,25 +488,19 @@ objects obtained elsewhere, pass a `Context` as the options of an accessor, e.g., `await create.getObject(ctx)`, to verify them. A portable actor's own collections, such as its outbox, have no location -hints, and accessors do not take the actor's `gateways` by themselves, so -pass them along with the context's verifier: +hints, so accessors fetch them, and the objects under the same DID that they +lead to, through the actor's `gateways`: ~~~~ typescript twoslash import type { Context } from "@fedify/fedify"; -import { isActor, traverseCollection } from "@fedify/vocab"; +import { isActor } from "@fedify/vocab"; const ctx = null as unknown as Context; // ---cut-before--- const actor = await ctx.lookupObject("@alice@example.com"); if (isActor(actor)) { - const options = { - documentLoader: ctx.documentLoader, - contextLoader: ctx.contextLoader, - verifyPortableObject: ctx.verifyPortableObject, - gateways: actor.gateways, - }; - const outbox = await actor.getOutbox(options); + const outbox = await actor.getOutbox(ctx); if (outbox != null) { - for await (const item of traverseCollection(outbox, options)) { + for await (const item of ctx.traverseCollection(outbox)) { console.log(item.id?.href); } } diff --git a/docs/manual/vocab.md b/docs/manual/vocab.md index a789e4e36..384a896be 100644 --- a/docs/manual/vocab.md +++ b/docs/manual/vocab.md @@ -444,11 +444,15 @@ gateways with a path are not supported. If you omit it, the accessor uses the `@gateway` location hints in the reference, e.g., `ap://did:key:z6Mk.../actor?@gateway=https%3A%2F%2Fserver1.example`. Since hints come from the document that contains the reference, only the first five -are used. An explicit `gateways` list replaces the hints, and an empty list -turns them off. When there is no gateway to try, the accessor passes the -portable ID itself to the document loader, which lets a custom document loader -retrieve portable objects in its own way. The two checks above apply in that -case as well. +are used. A reference without hints that has the same DID as a portable +actor it was reached from, e.g., the actor's `outbox`, or a page of the outbox, +is fetched through the first five valid gateways in that actor's `gateways` +instead, since references in a portable actor's own document do not need +hints. An explicit `gateways` list replaces the hints and the actor's +gateways, and an empty list turns them off. When there is no gateway to try, +the accessor passes the portable ID itself to the document loader, which lets a +custom document loader retrieve portable objects in its own way. The two +checks above apply in that case as well. Requests to gateways go through the document loader, so an authenticated document loader signs them, which lets you fetch non-public portable objects @@ -622,8 +626,8 @@ without a proof, and accepts it only if all of the following hold: its `inbox`, `outbox`, `followers`, `following`, or `liked`. If you dereferenced the collection from an actor that was itself fetched and verified through gateways, that actor document is used; otherwise the - owner is fetched through the same `gateways` option (or its location - hints). + owner is fetched through the same `gateways` option, or else its location + hints or the gateways that the collection was fetched through. - The gateway that served the collection is one of the owner's `gateways`. A collection with a proof is verified by its proof instead, and a collection diff --git a/packages/fedify/src/federation/portable-collection.test.ts b/packages/fedify/src/federation/portable-collection.test.ts index b4e7573be..00144200e 100644 --- a/packages/fedify/src/federation/portable-collection.test.ts +++ b/packages/fedify/src/federation/portable-collection.test.ts @@ -923,6 +923,47 @@ test("Fedify traverses portable collections that Fedify serves", async () => { assertEquals(await actor2.getOutbox(evilOptions), null); }); +test("Fedify traverses portable collections through their owners' gateways", async () => { + const federation = createTestFederation(); + const requests: string[] = []; + const documentLoader: DocumentLoader = async (url) => { + requests.push(url); + if (!/^https?:/.test(url)) throw new Error(`Not found: ${url}`); + const target = new URL(url); + const response = await federation.fetch( + new Request(new URL(target.pathname + target.search, ORIGIN), { + headers: { Accept: ACCEPT }, + }), + { contextData: undefined }, + ); + if (!response.ok) { + throw new FetchError(url, `HTTP ${response.status}`, response); + } + return { + contextUrl: null, + documentUrl: url, + document: await response.json(), + }; + }; + const options = { + documentLoader, + contextLoader: mockDocumentLoader, + verifyPortableObject, + }; + const actor = await lookupObject(portableId("/users/alice"), { + ...options, + gateways: [ORIGIN], + }); + assert(actor instanceof Person); + // Neither the actor's outbox nor its pages have location hints, and no + // gateways are given, so the actor's own gateways are used: + const outbox = await actor.getOutbox(options); + assert(outbox instanceof OrderedCollection); + const items = await Array.fromAsync(traverseCollection(outbox, options)); + assertEquals(items.length, PAGES.length * NOTES_PER_PAGE); + assert(requests.every((url) => url.startsWith(`${ORIGIN}/`))); +}); + test("Fedify accepts empty portable collections that Fedify serves", async () => { // The inbox dispatcher returns no items and has no counter, so without // totalItems nothing would tell that the document is a collection: diff --git a/packages/vocab-runtime/src/internal/portable-dereference.test.ts b/packages/vocab-runtime/src/internal/portable-dereference.test.ts index a8262a492..3dc49e647 100644 --- a/packages/vocab-runtime/src/internal/portable-dereference.test.ts +++ b/packages/vocab-runtime/src/internal/portable-dereference.test.ts @@ -6,7 +6,9 @@ import { createScopedContextLoader } from "./jsonld-cache.ts"; import { createSnapshotContextLoader, getPortableGatewayCandidates, + getReferrerGateways, isPortableIri, + recordPortableReferrer, } from "./portable-dereference.ts"; const hrefs = (urls: URL[]) => urls.map((url) => url.href); @@ -91,6 +93,66 @@ test("getPortableGatewayCandidates() reads hints from withGatewayHints()", () => ); }); +test("getReferrerGateways() takes gateways from the owner", () => { + const actor = { + id: parseIri("ap://did:key:z6Mkabc/actor"), + gateways: [ + new URL("https://a.example"), + new URL("https://a.example/"), + new URL("https://b.example/path"), + new URL("https://c.example"), + ], + }; + const outbox = { id: parseIri("ap://did:key:z6Mkabc/actor/outbox") }; + recordPortableReferrer(actor, outbox, "outbox"); + const page = parseIri("ap://did:key:z6Mkabc/actor/outbox?cursor=1"); + + // From the actor itself, and from an object obtained from it; duplicate and + // invalid gateways are dropped: + deepStrictEqual( + hrefs(getReferrerGateways(actor, outbox.id) ?? []), + ["https://a.example/", "https://c.example/"], + ); + deepStrictEqual( + hrefs(getReferrerGateways(outbox, page) ?? []), + ["https://a.example/", "https://c.example/"], + ); + + // Location hints take precedence: + deepStrictEqual( + getReferrerGateways( + outbox, + withGatewayHints(page, [new URL("https://hint.example")]), + ), + undefined, + ); + + // A reference under another DID does not belong to the actor: + deepStrictEqual( + getReferrerGateways(outbox, parseIri("ap://did:key:z6Mkdef/notes/1")), + undefined, + ); + + // An actor with a compatible identifier works the same way: + const compatible = { + id: new URL( + "https://a.example/.well-known/apgateway/did:key:z6Mkabc/actor", + ), + gateways: [new URL("https://a.example")], + }; + deepStrictEqual( + hrefs(getReferrerGateways(compatible, outbox.id) ?? []), + ["https://a.example/"], + ); + + // Objects that no portable actor leads to have no gateways to offer: + deepStrictEqual(getReferrerGateways({}, page), undefined); + deepStrictEqual( + getReferrerGateways({ id: actor.id, gateways: [] }, page), + undefined, + ); +}); + test("createSnapshotContextLoader() does not nest released snapshots", async () => { const calls: string[] = []; const base: DocumentLoader = (url) => { diff --git a/packages/vocab-runtime/src/internal/portable-dereference.ts b/packages/vocab-runtime/src/internal/portable-dereference.ts index 35b6179e6..871538339 100644 --- a/packages/vocab-runtime/src/internal/portable-dereference.ts +++ b/packages/vocab-runtime/src/internal/portable-dereference.ts @@ -538,6 +538,73 @@ export function getPortableGatewayCandidates( return candidates; } +/** + * Gets the gateways through which a portable reference without location hints + * can be dereferenced, from the portable actor that the reference belongs to. + * + * The references in a portable actor's own document, such as its `outbox`, + * usually have no `@gateway` hints, as they are not needed there, since + * the actor's `gateways` already tells where to retrieve them. So this walks + * from the object whose property is being dereferenced up through the objects + * it was obtained from, e.g., from a collection page to the collection and + * then to the actor, and returns the `gateways` of the first object that has + * any, but only if that object has the same DID as the reference. The + * gateways only tell where to look; whatever they serve is still verified. + * + * @param object The object whose property is being dereferenced. + * @param url The portable IRI to dereference. + * @returns Up to {@link MAX_GATEWAY_HINTS} valid gateways, or `undefined` if + * the IRI has valid `@gateway` hints or no such object is found. + * @internal Technically exported for generated vocabulary classes, but not + * part of the public API contract. This is not considered public API for + * Semantic Versioning decisions. + */ +export function getReferrerGateways( + object: object, + url: URL, +): URL[] | undefined { + if (getPortableGatewayCandidates(url).length > 0) return undefined; + const visited = new Set(); + let current: object | undefined = object; + while (current != null && !visited.has(current)) { + visited.add(current); + const gateways: unknown = "gateways" in current + ? current.gateways + : undefined; + if (Array.isArray(gateways) && gateways.length > 0) { + const id = getObjectId(current); + const portableId = id == null + ? null + : isPortableIri(id) + ? id + : getCompatibleEf61Target(id); + if (portableId == null || !haveSameFe34Origin(portableId, url)) { + return undefined; + } + const candidates: URL[] = []; + for (const gateway of gateways) { + if (candidates.length >= MAX_GATEWAY_HINTS) break; + if (typeof gateway !== "string" && !(gateway instanceof URL)) continue; + const parsed = parseGatewayOrigin(gateway); + if (parsed == null) continue; + if (candidates.some((c) => c.href === parsed.href)) continue; + candidates.push(parsed); + } + return candidates.length > 0 ? candidates : undefined; + } + current = provenances.get(current)?.referrer?.object; + } + return undefined; +} + +function getCompatibleEf61Target(id: URL): URL | null { + try { + return fromCompatibleEf61Id(id); + } catch { + return null; + } +} + /** * Creates a context loader that returns the same context documents for the * whole dereference operation, so that the identity check, the proof diff --git a/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap b/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap index 80d4026da..bb09ba22c 100644 --- a/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap +++ b/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap @@ -41,6 +41,7 @@ import { createSnapshotContextLoader, dereferencePortableIri, getPortableResponseClaim, + getReferrerGateways, isPortableIri, isPortableMode, isUnsecuredPortableObject, @@ -2373,7 +2374,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -2819,7 +2829,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -3453,7 +3472,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -4054,7 +4082,16 @@ get contents(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -4531,7 +4568,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -4960,7 +5006,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -5556,7 +5611,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -6152,7 +6216,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -6739,7 +6812,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -7326,7 +7408,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -7924,7 +8015,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -8334,7 +8434,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -8750,7 +8859,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -9166,7 +9284,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -9616,7 +9743,16 @@ get summaries(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -10082,7 +10218,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -10654,7 +10799,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -11226,7 +11380,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -11798,7 +11961,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -12434,7 +12606,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -13043,7 +13224,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -13453,7 +13643,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -13863,7 +14062,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -19478,7 +19686,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -19912,7 +20129,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -21574,7 +21800,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -22208,7 +22443,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -22782,7 +23026,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -23362,7 +23615,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -23936,7 +24198,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -24512,7 +24783,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -28106,7 +28386,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -28516,7 +28805,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -31913,7 +32211,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -32323,7 +32630,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -33843,7 +34159,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -34253,7 +34578,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -35773,7 +36107,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -36182,7 +36525,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -37985,7 +38337,16 @@ urls?: ((URL | Link))[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -39753,7 +40114,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -40161,7 +40531,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -42020,7 +42399,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -42430,7 +42818,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -42840,7 +43237,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -43250,7 +43656,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -43680,7 +44095,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -44089,7 +44513,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -44498,7 +44931,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -44907,7 +45349,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -45316,7 +45767,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -45725,7 +46185,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -46134,7 +46603,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -46543,7 +47021,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -48745,7 +49232,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -50456,7 +50952,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -50864,7 +51369,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -53102,7 +53616,16 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -54406,7 +54929,16 @@ owner?: Application | Group | Organization | Person | Service | URL | null;publi span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -55634,7 +56166,16 @@ controller?: Application | Group | Organization | Person | Service | URL | null; span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -62536,7 +63077,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -63104,7 +63654,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -63726,7 +64285,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -64162,7 +64730,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -64595,7 +65172,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -65008,7 +65594,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -65424,7 +66019,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -65838,7 +66442,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -66250,7 +66863,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -66662,7 +67284,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -67071,7 +67702,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -67560,7 +68200,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -68028,7 +68677,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -68664,7 +69322,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -73032,7 +73699,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -73466,7 +74142,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -76778,7 +77463,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -77188,7 +77882,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -77596,7 +78299,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -83634,7 +84346,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -84202,7 +84923,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -84824,7 +85554,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -85260,7 +85999,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -85693,7 +86441,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -86106,7 +86863,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -86522,7 +87288,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -86936,7 +87711,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -87348,7 +88132,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -87760,7 +88553,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -88169,7 +88971,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -88658,7 +89469,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -89126,7 +89946,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -89762,7 +90591,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -93766,7 +94604,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -99614,7 +100461,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -100048,7 +100904,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -101261,7 +102126,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -103361,7 +104235,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -103929,7 +104812,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -104551,7 +105443,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -104987,7 +105888,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -105420,7 +106330,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -105833,7 +106752,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -106249,7 +107177,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -106663,7 +107600,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -107075,7 +108021,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -107487,7 +108442,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -107896,7 +108860,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -108385,7 +109358,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -108853,7 +109835,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -109489,7 +110480,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -114384,7 +115384,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -114952,7 +115961,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -115574,7 +116592,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -116010,7 +117037,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -116443,7 +117479,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -116856,7 +117901,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -117272,7 +118326,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -117686,7 +118749,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -118098,7 +119170,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -118510,7 +119591,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -118919,7 +120009,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -119408,7 +120507,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -119876,7 +120984,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -120512,7 +121629,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -125188,7 +126314,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -126362,7 +127497,16 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -126778,7 +127922,16 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -127224,7 +128377,16 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -127658,7 +128820,16 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -130075,7 +131246,16 @@ relationships?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -130487,7 +131667,16 @@ relationships?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -131057,7 +132246,16 @@ relationships?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -133817,7 +135015,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -134385,7 +135592,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -135007,7 +136223,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -135443,7 +136668,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -135876,7 +137110,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -136289,7 +137532,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -136705,7 +137957,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -137119,7 +138380,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -137531,7 +138801,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -137943,7 +139222,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -138352,7 +139640,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -138841,7 +140138,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -139309,7 +140615,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -139945,7 +141260,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { diff --git a/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap b/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap index d12b81ab9..7d4ba1d37 100644 --- a/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap +++ b/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap @@ -39,6 +39,7 @@ import { createSnapshotContextLoader, dereferencePortableIri, getPortableResponseClaim, + getReferrerGateways, isPortableIri, isPortableMode, isUnsecuredPortableObject, @@ -2371,7 +2372,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -2817,7 +2827,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -3451,7 +3470,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -4052,7 +4080,16 @@ get contents(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -4529,7 +4566,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -4958,7 +5004,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -5554,7 +5609,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -6150,7 +6214,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -6737,7 +6810,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -7324,7 +7406,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -7922,7 +8013,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -8332,7 +8432,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -8748,7 +8857,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -9164,7 +9282,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -9614,7 +9741,16 @@ get summaries(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -10080,7 +10216,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -10652,7 +10797,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -11224,7 +11378,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -11796,7 +11959,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -12432,7 +12604,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -13041,7 +13222,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -13451,7 +13641,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -13861,7 +14060,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -19476,7 +19684,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -19910,7 +20127,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -21572,7 +21798,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -22206,7 +22441,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -22780,7 +23024,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -23360,7 +23613,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -23934,7 +24196,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -24510,7 +24781,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -28104,7 +28384,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -28514,7 +28803,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -31911,7 +32209,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -32321,7 +32628,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -33841,7 +34157,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -34251,7 +34576,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -35771,7 +36105,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -36180,7 +36523,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -37983,7 +38335,16 @@ urls?: ((URL | Link))[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -39751,7 +40112,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -40159,7 +40529,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -42018,7 +42397,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -42428,7 +42816,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -42838,7 +43235,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -43248,7 +43654,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -43678,7 +44093,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -44087,7 +44511,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -44496,7 +44929,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -44905,7 +45347,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -45314,7 +45765,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -45723,7 +46183,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -46132,7 +46601,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -46541,7 +47019,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -48743,7 +49230,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -50454,7 +50950,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -50862,7 +51367,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -53100,7 +53614,16 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -54404,7 +54927,16 @@ owner?: Application | Group | Organization | Person | Service | URL | null;publi span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -55632,7 +56164,16 @@ controller?: Application | Group | Organization | Person | Service | URL | null; span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -62534,7 +63075,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -63102,7 +63652,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -63724,7 +64283,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -64160,7 +64728,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -64593,7 +65170,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -65006,7 +65592,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -65422,7 +66017,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -65836,7 +66440,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -66248,7 +66861,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -66660,7 +67282,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -67069,7 +67700,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -67558,7 +68198,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -68026,7 +68675,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -68662,7 +69320,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -73030,7 +73697,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -73464,7 +74140,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -76776,7 +77461,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -77186,7 +77880,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -77594,7 +78297,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -83632,7 +84344,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -84200,7 +84921,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -84822,7 +85552,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -85258,7 +85997,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -85691,7 +86439,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -86104,7 +86861,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -86520,7 +87286,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -86934,7 +87709,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -87346,7 +88130,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -87758,7 +88551,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -88167,7 +88969,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -88656,7 +89467,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -89124,7 +89944,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -89760,7 +90589,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -93764,7 +94602,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -99612,7 +100459,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -100046,7 +100902,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -101259,7 +102124,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -103359,7 +104233,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -103927,7 +104810,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -104549,7 +105441,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -104985,7 +105886,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -105418,7 +106328,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -105831,7 +106750,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -106247,7 +107175,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -106661,7 +107598,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -107073,7 +108019,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -107485,7 +108440,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -107894,7 +108858,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -108383,7 +109356,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -108851,7 +109833,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -109487,7 +110478,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -114382,7 +115382,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -114950,7 +115959,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -115572,7 +116590,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -116008,7 +117035,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -116441,7 +117477,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -116854,7 +117899,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -117270,7 +118324,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -117684,7 +118747,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -118096,7 +119168,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -118508,7 +119589,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -118917,7 +120007,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -119406,7 +120505,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -119874,7 +120982,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -120510,7 +121627,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -125186,7 +126312,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -126360,7 +127495,16 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -126776,7 +127920,16 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -127222,7 +128375,16 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -127656,7 +128818,16 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -130073,7 +131244,16 @@ relationships?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -130485,7 +131665,16 @@ relationships?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -131055,7 +132244,16 @@ relationships?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -133815,7 +135013,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -134383,7 +135590,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -135005,7 +136221,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -135441,7 +136666,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -135874,7 +137108,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -136287,7 +137530,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -136703,7 +137955,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -137117,7 +138378,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -137529,7 +138799,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -137941,7 +139220,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -138350,7 +139638,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -138839,7 +140136,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -139307,7 +140613,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -139943,7 +141258,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { diff --git a/packages/vocab-tools/src/__snapshots__/class.test.ts.snap b/packages/vocab-tools/src/__snapshots__/class.test.ts.snap index e66adfa74..bfce2cb56 100644 --- a/packages/vocab-tools/src/__snapshots__/class.test.ts.snap +++ b/packages/vocab-tools/src/__snapshots__/class.test.ts.snap @@ -41,6 +41,7 @@ import { createSnapshotContextLoader, dereferencePortableIri, getPortableResponseClaim, + getReferrerGateways, isPortableIri, isPortableMode, isUnsecuredPortableObject, @@ -2373,7 +2374,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -2819,7 +2829,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -3453,7 +3472,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -4054,7 +4082,16 @@ get contents(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -4531,7 +4568,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -4960,7 +5006,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -5556,7 +5611,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -6152,7 +6216,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -6739,7 +6812,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -7326,7 +7408,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -7924,7 +8015,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -8334,7 +8434,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -8750,7 +8859,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -9166,7 +9284,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -9616,7 +9743,16 @@ get summaries(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -10082,7 +10218,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -10654,7 +10799,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -11226,7 +11380,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -11798,7 +11961,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -12434,7 +12606,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -13043,7 +13224,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -13453,7 +13643,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -13863,7 +14062,16 @@ get urls(): ((URL | Link))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -19478,7 +19686,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -19912,7 +20129,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -21574,7 +21800,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -22208,7 +22443,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -22782,7 +23026,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -23362,7 +23615,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -23936,7 +24198,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -24512,7 +24783,16 @@ instruments?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -28106,7 +28386,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -28516,7 +28805,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -31913,7 +32211,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -32323,7 +32630,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -33843,7 +34159,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -34253,7 +34578,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -35773,7 +36107,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -36182,7 +36525,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -37985,7 +38337,16 @@ urls?: ((URL | Link))[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -39753,7 +40114,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -40161,7 +40531,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -42020,7 +42399,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -42430,7 +42818,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -42840,7 +43237,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -43250,7 +43656,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -43680,7 +44095,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -44089,7 +44513,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -44498,7 +44931,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -44907,7 +45349,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -45316,7 +45767,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -45725,7 +46185,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -46134,7 +46603,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -46543,7 +47021,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -48745,7 +49232,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -50456,7 +50952,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -50864,7 +51369,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -53102,7 +53616,16 @@ cryptosuite?: "eddsa-jcs-2022" | null;verificationMethod?: Multikey | URL | null span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -54406,7 +54929,16 @@ owner?: Application | Group | Organization | Person | Service | URL | null;publi span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -55634,7 +56166,16 @@ controller?: Application | Group | Organization | Person | Service | URL | null; span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -62536,7 +63077,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -63104,7 +63654,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -63726,7 +64285,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -64162,7 +64730,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -64595,7 +65172,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -65008,7 +65594,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -65424,7 +66019,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -65838,7 +66442,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -66250,7 +66863,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -66662,7 +67284,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -67071,7 +67702,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -67560,7 +68200,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -68028,7 +68677,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -68664,7 +69322,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -73032,7 +73699,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -73466,7 +74142,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -76778,7 +77463,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -77188,7 +77882,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -77596,7 +78299,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -83634,7 +84346,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -84202,7 +84923,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -84824,7 +85554,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -85260,7 +85999,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -85693,7 +86441,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -86106,7 +86863,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -86522,7 +87288,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -86936,7 +87711,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -87348,7 +88132,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -87760,7 +88553,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -88169,7 +88971,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -88658,7 +89469,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -89126,7 +89946,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -89762,7 +90591,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -93766,7 +94604,16 @@ get names(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -99614,7 +100461,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -100048,7 +100904,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -101261,7 +102126,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -103361,7 +104235,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -103929,7 +104812,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -104551,7 +105443,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -104987,7 +105888,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -105420,7 +106330,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -105833,7 +106752,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -106249,7 +107177,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -106663,7 +107600,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -107075,7 +108021,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -107487,7 +108442,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -107896,7 +108860,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -108385,7 +109358,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -108853,7 +109835,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -109489,7 +110480,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -114384,7 +115384,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -114952,7 +115961,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -115574,7 +116592,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -116010,7 +117037,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -116443,7 +117479,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -116856,7 +117901,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -117272,7 +118326,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -117686,7 +118749,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -118098,7 +119170,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -118510,7 +119591,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -118919,7 +120009,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -119408,7 +120507,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -119876,7 +120984,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -120512,7 +121629,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -125188,7 +126314,16 @@ proofs?: (DataIntegrityProof | URL)[];interactionPolicy?: InteractionPolicy | nu span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -126362,7 +127497,16 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -126778,7 +127922,16 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -127224,7 +128377,16 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -127658,7 +128820,16 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -130075,7 +131246,16 @@ relationships?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -130487,7 +131667,16 @@ relationships?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -131057,7 +132246,16 @@ relationships?: (Object | URL)[];} span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -133817,7 +135015,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -134385,7 +135592,16 @@ get preferredUsernames(): ((string | LanguageString))[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -135007,7 +136223,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -135443,7 +136668,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -135876,7 +137110,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -136289,7 +137532,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -136705,7 +137957,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -137119,7 +138380,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -137531,7 +138801,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -137943,7 +139222,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -138352,7 +139640,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -138841,7 +140138,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -139309,7 +140615,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { @@ -139945,7 +141260,16 @@ get gateways(): (URL)[] { span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { diff --git a/packages/vocab-tools/src/class.ts b/packages/vocab-tools/src/class.ts index 39bb86f84..cf29c5f26 100644 --- a/packages/vocab-tools/src/class.ts +++ b/packages/vocab-tools/src/class.ts @@ -25,6 +25,7 @@ const PORTABLE_DEREFERENCE_IMPORTS = [ "createSnapshotContextLoader", "dereferencePortableIri", "getPortableResponseClaim", + "getReferrerGateways", "isPortableIri", "isPortableMode", "isUnsecuredPortableObject", diff --git a/packages/vocab-tools/src/property.ts b/packages/vocab-tools/src/property.ts index 20dfd5b75..d7adbb9da 100644 --- a/packages/vocab-tools/src/property.ts +++ b/packages/vocab-tools/src/property.ts @@ -151,7 +151,16 @@ async function* generateProperty( span.end(); } }; - if (isPortableIri(url)) return await dereferencePortable(url); + if (isPortableIri(url)) { + // A reference in a portable actor's own document, e.g., its outbox, + // has no location hints, so the actor's gateways are used instead: + return await dereferencePortable( + url, + options.gateways == null + ? { inferredGateways: getReferrerGateways(this, url) } + : {}, + ); + } const lookupUrl = formatIri(url); const portableMode = isPortableMode(this, options); if (portableMode) { From 775bbc35035722d1233552f716584087901641fc Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 02:16:52 +0900 Subject: [PATCH 018/184] Refuse rebuilt signed children in portable sends Fedify signs outgoing activities with Object Integrity Proofs by default, so a Follow that a Fedify server sends usually carries one. When a portable actor's inbox listener accepted such a Follow by embedding it, e.g., new Accept({ object: follow }), the parsed Follow was rebuilt under the Accept's context, losing its own @context but keeping its proof. The map-local compound-proof profile verifies each proof-bearing map on its own and rejects an embedded one without @context, so every Fedify inbox answered the Accept with 401 Unauthorized, and the follow never completed. Context.sendActivity() now refuses, with a TypeError that explains the cause and suggests referring to the object by its ID, an activity with portable objects in which an embedded map carries a proof but not its own @context, as it already refuses proof sets. Objects signed with signObject() are embedded with their own @context and are unaffected. The fanout worker applies the same check to a queued unsigned activity that it has to serialize again, which it used to deliver in a form that inboxes rejected. https://github.com/fedify-dev/fedify/issues/288 Assisted-by: Claude Code:claude-opus-5-5 --- CHANGES.md | 5 +- changes.d/fedify/portable-objects.md | 5 +- docs/manual/portable.md | 2 + docs/manual/send.md | 11 +- .../src/federation/outgoing-proof.test.ts | 105 +++++++++++++++++- .../fedify/src/federation/outgoing-proof.ts | 38 +++++-- packages/fedify/src/sig/compound-proof.ts | 30 +++++ 7 files changed, 178 insertions(+), 18 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 18ed55707..6c81a2a79 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -202,7 +202,10 @@ To be released. a `TypeError` before anything is delivered or queued. So does a non-portable activity that embeds portable objects, including ones with compatible identifiers, when several Ed25519 keys are available, and an - activity with portable objects in which any map carries a proof set. + activity with portable objects in which any map carries a proof set, or + an embedded map carries a proof but not its own `@context`, e.g., + a received signed `Follow` embedded in an `Accept`, which Fedify + inboxes would reject; refer to such an object by its ID instead. Sign portable activities with `signObject()` beforehand, or pass the DID's key as an explicit sender key. [[#840], [#1041], [#1045], [#1073], [#1099]] diff --git a/changes.d/fedify/portable-objects.md b/changes.d/fedify/portable-objects.md index a83279b3e..7fb02b05f 100644 --- a/changes.d/fedify/portable-objects.md +++ b/changes.d/fedify/portable-objects.md @@ -258,7 +258,10 @@ links: a `TypeError` before anything is delivered or queued. So does a non-portable activity that embeds portable objects, including ones with compatible identifiers, when several Ed25519 keys are available, and an - activity with portable objects in which any map carries a proof set. + activity with portable objects in which any map carries a proof set, or + an embedded map carries a proof but not its own `@context`, e.g., + a received signed `Follow` embedded in an `Accept`, which Fedify + inboxes would reject; refer to such an object by its ID instead. Sign portable activities with `signObject()` beforehand, or pass the DID's key as an explicit sender key. [[#840], [#1041], [#1045], [#1073], [#1099]] diff --git a/docs/manual/portable.md b/docs/manual/portable.md index 1916ffe94..1721111d1 100644 --- a/docs/manual/portable.md +++ b/docs/manual/portable.md @@ -316,6 +316,8 @@ federation ctx.getPortableActorUri(user.identifier, user.did), [new URL("https://example.com")], ), + // By its ID, as the received Follow may carry a proof that no longer + // verifies once it is embedded: object: follow.id, }), user.didKeyPair.privateKey, diff --git a/docs/manual/send.md b/docs/manual/send.md index dd7ac1001..9b6dec732 100644 --- a/docs/manual/send.md +++ b/docs/manual/send.md @@ -1388,7 +1388,16 @@ keys or pre-sign it instead. Fedify also refuses to send an activity with portable objects if any map in it already carries a proof set, which happens, for example, when `signObject()` is called twice on the same object. The error names the JSON Pointer of the -offending `proof`. These checks only prevent unsupported proof shapes. They +offending `proof`. For the same reason, it refuses to send one in which an +embedded map carries a proof but not its own `@context`, which Fedify inboxes +reject however valid the proof is. An object that you signed with +`signObject()` is embedded with its own `@context`, but one parsed from +a received document is rebuilt under the activity's context, so its proof no +longer covers it (see the warning below). This typically happens to +an `Accept` that embeds the `Follow` it accepts, as Fedify signs activities +with Object Integrity Proofs by default, so refer to such an object by its ID +instead, e.g., `new Accept({ object: follow.id })`. These checks only prevent +unsupported proof shapes. They do not otherwise validate a proof created with a single key. > [!WARNING] diff --git a/packages/fedify/src/federation/outgoing-proof.test.ts b/packages/fedify/src/federation/outgoing-proof.test.ts index 0f2df7704..62f7ab5a6 100644 --- a/packages/fedify/src/federation/outgoing-proof.test.ts +++ b/packages/fedify/src/federation/outgoing-proof.test.ts @@ -1,5 +1,5 @@ import { mockDocumentLoader, test } from "@fedify/fixture"; -import { Announce, Create, Note, Person } from "@fedify/vocab"; +import { Accept, Announce, Create, Follow, Note, Person } from "@fedify/vocab"; import { exportDidKey, parseIri } from "@fedify/vocab-runtime"; import { configure, type LogRecord, reset } from "@logtape/logtape"; import { assert, assertEquals, assertRejects } from "@std/assert"; @@ -474,6 +474,80 @@ test("a proof set on an embedded map is not delivered either", async () => { assertEquals(bodies.length, 0); }); +test("a received signed object rebuilt inside a portable activity is not delivered", async () => { + // A Follow that a Fedify server signed with an Object Integrity Proof, as + // Fedify does by default, parsed as an inbox listener receives it: + const followerKey = await didKey(); + const signedFollow = await signObject( + new Follow({ + id: new URL("https://example.com/follows/1"), + actor: new URL("https://example.com/users/bob"), + object: parseIri("ap+ef61://did:key:z6Mkabc/actor"), + }), + followerKey.privateKey, + new URL("https://example.com/users/bob#key"), + { ...options, created }, + ); + const follow = await Follow.fromJsonLd( + await signedFollow.toJsonLd({ format: "compact", ...options }), + options, + ); + const owner = await didKey(); + const accept = (object: Follow | URL) => + new Accept({ + id: parseIri(`ap+ef61://${owner.did}/accepts/${crypto.randomUUID()}`), + actor: parseIri(`ap+ef61://${owner.did}/actor`), + object, + }); + + // Embedding the parsed Follow rebuilds it under the Accept's context, so its + // proof cannot verify on its own, and Fedify inboxes would reject + // the Accept for it. Whether signed here or beforehand, it is rejected: + const unsigned = accept(follow); + const presigned = await signObject( + accept(follow), + owner.privateKey, + owner.keyId, + { ...options, created }, + ); + const cases: [Accept, SenderKeyPair[]][] = [ + [unsigned, [rsaKey, sender(owner)]], + [presigned, [rsaKey]], + ]; + for (const [activity, keys] of cases) { + const immediate = await capture(() => + assertRejects( + () => + createTestFederation().createContext( + new URL("https://example.com/"), + ).sendActivity(keys, recipient, activity), + TypeError, + 'JSON Pointer "/object"', + ) + ); + assertEquals(immediate.bodies.length, 0); + const fanout = createQueue(); + await assertRejects( + () => + createTestFederation(fanout.queue).createContext( + new URL("https://example.com/"), + ).sendActivity(keys, recipient, activity, { fanout: "force" }), + TypeError, + 'JSON Pointer "/object"', + ); + assertEquals(fanout.queued.length, 0); + } + + // Referring to the Follow by its ID works: + const { bodies } = await capture(() => + createTestFederation().createContext( + new URL("https://example.com/"), + ).sendActivity([rsaKey, sender(owner)], recipient, accept(follow.id!)) + ); + assertEquals(bodies.length, 1); + await assertCompoundVerifies(bodies[0]); +}); + test("forced fanout selects the DID-matching key before enqueueing", async () => { const owner = await didKey(); const childOwner = await didKey(); @@ -510,9 +584,8 @@ test("forced fanout selects the DID-matching key before enqueueing", async () => test("the fanout worker selects one key for an unsigned portable activity", async () => { const owner = await didKey(); const child = await signedChild(await didKey()); - const activity = portableCreate(owner, child); const federation = createTestFederation(); - const message: FanoutMessage = { + const message = async (activity: Create): Promise => ({ type: "fanout", id: crypto.randomUUID(), baseUrl: "https://example.com", @@ -532,12 +605,32 @@ test("the fanout worker selects one key for an unsigned portable activity", asyn activityId: activity.id!.href, activityType: "https://www.w3.org/ns/activitystreams#Create", traceContext: {}, - }; - const { bodies } = await capture(() => - federation.processQueuedTask(undefined, message) + }); + const byId = new Create({ + id: parseIri(`ap+ef61://${owner.did}/activities/${crypto.randomUUID()}`), + actor: parseIri(`ap+ef61://${owner.did}/actor`), + object: child.id, + }); + const { bodies } = await capture(async () => + federation.processQueuedTask(undefined, await message(byId)) ); assertEquals(bodies.length, 1); assertEquals(proofOf(bodies[0]).verificationMethod, owner.keyId.href); + await assertCompoundVerifies(bodies[0]); + + // Current senders sign an activity before enqueueing it, so the worker + // delivers the queued document as is. An unsigned one, e.g., queued by an + // older version, is parsed and serialized again, which rebuilds a signed + // child, so it is refused rather than delivered for inboxes to reject: + const embedded = await message(portableCreate(owner, child)); + const refused = await capture(() => + assertRejects( + () => federation.processQueuedTask(undefined, embedded), + TypeError, + 'JSON Pointer "/object"', + ) + ); + assertEquals(refused.bodies.length, 0); }); test("actor key pairs follow the compound-proof key selection too", async () => { diff --git a/packages/fedify/src/federation/outgoing-proof.ts b/packages/fedify/src/federation/outgoing-proof.ts index 5d497f041..9c9aeb362 100644 --- a/packages/fedify/src/federation/outgoing-proof.ts +++ b/packages/fedify/src/federation/outgoing-proof.ts @@ -5,6 +5,7 @@ import { getLogger } from "@logtape/logtape"; import type { TracerProvider } from "@opentelemetry/api"; import { containsCompoundPortableObject, + findEmbeddedProofWithoutContext, findUnsupportedCompoundProofShape, } from "../sig/compound-proof.ts"; import { @@ -264,7 +265,10 @@ function selectPortableActivityKey( /** * Rejects an outgoing activity whose proofs Fedify's own inbox would reject * as unsupported: a document with portable objects in which some map carries - * a proof set or another value that is not a single proof map. + * a proof set or another value that is not a single proof map, or in which + * an embedded map carries a proof but not its own `@context`, e.g., a signed + * object parsed from a received document and rebuilt under the activity's + * context. * * @param jsonLd The compact JSON-LD document about to be delivered. * @param activityId The activity ID, for the error message. @@ -277,12 +281,28 @@ export function assertSupportedCompoundProofShape( ): void { if (!containsCompoundPortableObject(jsonLd)) return; const path = findUnsupportedCompoundProofShape(jsonLd); - if (path == null) return; - throw new TypeError( - `Cannot send the activity ${activityId}: it embeds portable objects, ` + - `but its proof at the JSON Pointer ${JSON.stringify(path)} is not a ` + - `single proof map. The map-local compound-proof profile accepts ` + - `exactly one direct proof per map, so Fedify inboxes would reject the ` + - `activity. Sign each object with exactly one key.`, - ); + if (path != null) { + throw new TypeError( + `Cannot send the activity ${activityId}: it embeds portable objects, ` + + `but its proof at the JSON Pointer ${JSON.stringify(path)} is not a ` + + `single proof map. The map-local compound-proof profile accepts ` + + `exactly one direct proof per map, so Fedify inboxes would reject ` + + `the activity. Sign each object with exactly one key.`, + ); + } + const embedded = findEmbeddedProofWithoutContext(jsonLd); + if (embedded != null) { + throw new TypeError( + `Cannot send the activity ${activityId}: it embeds portable objects, ` + + `but the map at the JSON Pointer ${JSON.stringify(embedded)} carries ` + + `a proof without its own @context. The map-local compound-proof ` + + `profile verifies each proof-bearing map on its own, so Fedify ` + + `inboxes would reject the activity. This happens when a signed ` + + `object parsed from a received document, e.g., a Follow in an ` + + `inbox listener, is embedded, as it is rebuilt under the activity's ` + + `context and its proof no longer covers it. Refer to such an object ` + + `by its ID instead, e.g., new Accept({ object: follow.id }), or embed ` + + `an object that you signed with signObject().`, + ); + } } diff --git a/packages/fedify/src/sig/compound-proof.ts b/packages/fedify/src/sig/compound-proof.ts index 98de3146a..8ea9f1f70 100644 --- a/packages/fedify/src/sig/compound-proof.ts +++ b/packages/fedify/src/sig/compound-proof.ts @@ -822,6 +822,36 @@ export function findUnsupportedCompoundProofShape( ) ?? null; } +/** + * Finds the first embedded map that carries a direct `proof` but not its own + * `@context`. The map-local compound-proof profile verifies each proof-bearing + * map as a self-contained document, so the inbox rejects such a map with + * `missingContext` whatever its proof. An object embedded with its captured + * signed representation, e.g., by {@link signObject}, always keeps its own + * `@context`; one rebuilt under its parent's context, e.g., an object parsed + * from a received document, never does, and its proof no longer covers what + * it has become anyway. + * + * The input must be a finite, already-materialized JSON tree; see + * {@link containsCompoundPortableObject}. + * + * @returns The RFC 6901 JSON Pointer to the map, or `null` if every embedded + * proof-bearing map has its own `@context`. + * @internal + */ +export function findEmbeddedProofWithoutContext( + json: unknown, +): string | null { + return findInJsonMaps( + json, + (map, path) => + path !== "" && Object.hasOwn(map, "proof") && + !Object.hasOwn(map, "@context") + ? path + : undefined, + ) ?? null; +} + /** * Discovers direct literal proof-bearing maps in an immutable JSON snapshot. * From a0002240fd95ca028b897007ae6ab505399f2cb4 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 02:19:59 +0900 Subject: [PATCH 019/184] Release 2.4.0 --- CHANGES.md | 2 +- changes.d/adonisjs/adonisjs-integration.md | 12 - changes.d/astro/imported-unreleased.md | 11 - changes.d/cli/imported-unreleased.md | 15 - changes.d/cli/init-sveltekit.md | 8 - changes.d/cli/lookup-default-timeout.md | 11 - changes.d/cli/optique-1.3.2.md | 9 - changes.d/cli/portable-objects.md | 47 --- changes.d/debugger/imported-unreleased.md | 10 - .../fedify/circuit-breaker-encoded-cas.md | 8 - changes.d/fedify/document-loader-timeout.md | 29 -- changes.d/fedify/imported-unreleased.md | 98 ----- changes.d/fedify/kv-cache-ttl.md | 25 -- changes.d/fedify/object-tombstones.md | 24 -- changes.d/fedify/on-request-finished.md | 10 - changes.d/fedify/portable-objects.md | 367 ------------------ changes.d/fedify/rfc9421-signature-cap.md | 26 -- changes.d/init/imported-unreleased.md | 10 - changes.d/init/smoke-test.md | 8 - changes.d/init/sveltekit.md | 6 - changes.d/init/verify-runtime-version.md | 11 - .../imported-unreleased.md | 16 - .../lint/actor-preferred-username-rule.md | 8 - changes.d/lint/imported-unreleased.md | 19 - changes.d/lint/outbox-delivery-not-awaited.md | 18 - .../outbox-listener-nested-property-writes.md | 14 - changes.d/lint/outbox-listener-path-aware.md | 15 - .../outbox-listener-reachability-loops.md | 17 - changes.d/lint/portable-uri-mismatches.md | 13 - changes.d/mysql/imported-unreleased.md | 10 - changes.d/netlify/blobs-kv-store.md | 8 - changes.d/netlify/imported-unreleased.md | 12 - changes.d/next.txt | 1 - changes.d/next/hashlink-media-requests.md | 19 - changes.d/pglite/pglite-kv-store.md | 5 - changes.d/postgres/imported-unreleased.md | 24 -- changes.d/redis/atomic-kv-swaps.md | 11 - changes.d/redis/imported-unreleased.md | 10 - changes.d/relay/clarify-relay-contract.md | 4 - changes.d/relay/imported-unreleased.md | 10 - changes.d/sqlite/imported-unreleased.md | 10 - changes.d/testing/imported-unreleased.md | 10 - changes.d/testing/kv-store-tester.md | 3 - changes.d/testing/object-tombstones.md | 10 - changes.d/testing/on-request-finished.md | 8 - changes.d/testing/portable-objects.md | 65 ---- .../vocab-runtime/document-loader-timeout.md | 21 - .../vocab-runtime/imported-unreleased.md | 20 - changes.d/vocab-runtime/portable-objects.md | 126 ------ .../vocab-runtime/translation-context.md | 7 - changes.d/vocab-tools/conditional-contexts.md | 10 - .../vocab-tools/suppressed-error-log-level.md | 8 - changes.d/vocab/imported-unreleased.md | 25 -- changes.d/vocab/portable-objects.md | 165 -------- changes.d/vocab/translation-metadata.md | 20 - 55 files changed, 1 insertion(+), 1488 deletions(-) delete mode 100644 changes.d/adonisjs/adonisjs-integration.md delete mode 100644 changes.d/astro/imported-unreleased.md delete mode 100644 changes.d/cli/imported-unreleased.md delete mode 100644 changes.d/cli/init-sveltekit.md delete mode 100644 changes.d/cli/lookup-default-timeout.md delete mode 100644 changes.d/cli/optique-1.3.2.md delete mode 100644 changes.d/cli/portable-objects.md delete mode 100644 changes.d/debugger/imported-unreleased.md delete mode 100644 changes.d/fedify/circuit-breaker-encoded-cas.md delete mode 100644 changes.d/fedify/document-loader-timeout.md delete mode 100644 changes.d/fedify/imported-unreleased.md delete mode 100644 changes.d/fedify/kv-cache-ttl.md delete mode 100644 changes.d/fedify/object-tombstones.md delete mode 100644 changes.d/fedify/on-request-finished.md delete mode 100644 changes.d/fedify/portable-objects.md delete mode 100644 changes.d/fedify/rfc9421-signature-cap.md delete mode 100644 changes.d/init/imported-unreleased.md delete mode 100644 changes.d/init/smoke-test.md delete mode 100644 changes.d/init/sveltekit.md delete mode 100644 changes.d/init/verify-runtime-version.md delete mode 100644 changes.d/interaction-controls/imported-unreleased.md delete mode 100644 changes.d/lint/actor-preferred-username-rule.md delete mode 100644 changes.d/lint/imported-unreleased.md delete mode 100644 changes.d/lint/outbox-delivery-not-awaited.md delete mode 100644 changes.d/lint/outbox-listener-nested-property-writes.md delete mode 100644 changes.d/lint/outbox-listener-path-aware.md delete mode 100644 changes.d/lint/outbox-listener-reachability-loops.md delete mode 100644 changes.d/lint/portable-uri-mismatches.md delete mode 100644 changes.d/mysql/imported-unreleased.md delete mode 100644 changes.d/netlify/blobs-kv-store.md delete mode 100644 changes.d/netlify/imported-unreleased.md delete mode 100644 changes.d/next.txt delete mode 100644 changes.d/next/hashlink-media-requests.md delete mode 100644 changes.d/pglite/pglite-kv-store.md delete mode 100644 changes.d/postgres/imported-unreleased.md delete mode 100644 changes.d/redis/atomic-kv-swaps.md delete mode 100644 changes.d/redis/imported-unreleased.md delete mode 100644 changes.d/relay/clarify-relay-contract.md delete mode 100644 changes.d/relay/imported-unreleased.md delete mode 100644 changes.d/sqlite/imported-unreleased.md delete mode 100644 changes.d/testing/imported-unreleased.md delete mode 100644 changes.d/testing/kv-store-tester.md delete mode 100644 changes.d/testing/object-tombstones.md delete mode 100644 changes.d/testing/on-request-finished.md delete mode 100644 changes.d/testing/portable-objects.md delete mode 100644 changes.d/vocab-runtime/document-loader-timeout.md delete mode 100644 changes.d/vocab-runtime/imported-unreleased.md delete mode 100644 changes.d/vocab-runtime/portable-objects.md delete mode 100644 changes.d/vocab-runtime/translation-context.md delete mode 100644 changes.d/vocab-tools/conditional-contexts.md delete mode 100644 changes.d/vocab-tools/suppressed-error-log-level.md delete mode 100644 changes.d/vocab/imported-unreleased.md delete mode 100644 changes.d/vocab/portable-objects.md delete mode 100644 changes.d/vocab/translation-metadata.md diff --git a/CHANGES.md b/CHANGES.md index 6c81a2a79..8e82ebf8e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,7 +6,7 @@ Fedify changelog Version 2.4.0 ------------- -To be released. +Released on October 1, 2026. ### @fedify/fedify diff --git a/changes.d/adonisjs/adonisjs-integration.md b/changes.d/adonisjs/adonisjs-integration.md deleted file mode 100644 index 1989f907b..000000000 --- a/changes.d/adonisjs/adonisjs-integration.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -links: - '#1006': https://github.com/fedify-dev/fedify/pull/1006 - '#139': https://github.com/fedify-dev/fedify/issues/139 ---- - - Added the new *@fedify/adonisjs* package, an integration for the AdonisJS - framework. It provides a server middleware that mounts a `Federation` - inside an AdonisJS application, a service provider that owns the - federation's lifecycle, a `node ace configure` hook that scaffolds - *config/fedify.ts* and the federation preload files, and a `ctx.federation` - request context. The package targets Node.js and is published to npm only. - [[#139], [#1006] by Samuel Brinkmann] diff --git a/changes.d/astro/imported-unreleased.md b/changes.d/astro/imported-unreleased.md deleted file mode 100644 index 52c319300..000000000 --- a/changes.d/astro/imported-unreleased.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -links: - '#931': https://github.com/fedify-dev/fedify/issues/931 - '#936': https://github.com/fedify-dev/fedify/pull/936 ---- - - Added and continuously tested support for Astro 6 and 7 while retaining - Astro 5 compatibility. The Astro example and `fedify init` templates now - use Astro 7 with current Node.js and Deno adapters; Bun uses the tested - `@astrojs/node` standalone output instead of the Astro-5-only - `@nurodev/astro-bun` adapter. - [[#931], [#936]] diff --git a/changes.d/cli/imported-unreleased.md b/changes.d/cli/imported-unreleased.md deleted file mode 100644 index 837c2da1f..000000000 --- a/changes.d/cli/imported-unreleased.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -links: - '#823': https://github.com/fedify-dev/fedify/issues/823 - '#925': https://github.com/fedify-dev/fedify/pull/925 - '#940': https://github.com/fedify-dev/fedify/pull/940 ---- - - Added `fedify.com.es` as a tunneling service. The CLI pins the service's - SSH host key and rejects a mismatched server before exposing a local port. - [[#940]] - - Removed `localhost.run` as a tunneling service. The service is no longer - available, and the CLI now rejects attempts to use it. - [[#940]] - - Switched the CLI's Temporal runtime dependency from - `@js-temporal/polyfill` to `temporal-polyfill`. - [[#823], [#925]] diff --git a/changes.d/cli/init-sveltekit.md b/changes.d/cli/init-sveltekit.md deleted file mode 100644 index fdac414cb..000000000 --- a/changes.d/cli/init-sveltekit.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -links: - '#892': https://github.com/fedify-dev/fedify/issues/892 - '#971': https://github.com/fedify-dev/fedify/pull/971 ---- - - Added [SvelteKit] option to `fedify init` command. This option allows users - to initialize a new Fedify project with SvelteKit integration. - [[#892], [#971] by Jang Hanarae] diff --git a/changes.d/cli/lookup-default-timeout.md b/changes.d/cli/lookup-default-timeout.md deleted file mode 100644 index 634713055..000000000 --- a/changes.d/cli/lookup-default-timeout.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -links: - '#1131': https://github.com/fedify-dev/fedify/issues/1131 - '#1169': https://github.com/fedify-dev/fedify/pull/1169 ---- - - Changed `fedify lookup` to time out each request after 10 seconds when - the `-T`/`--timeout` option is not given, since the document loaders it - uses now have a default timeout. Previously, there was no timeout by - default. The `-T`/`--timeout` option now also limits how long - a request waits for a DNS lookup, though it cannot stop the lookup - itself. [[#1131], [#1169]] diff --git a/changes.d/cli/optique-1.3.2.md b/changes.d/cli/optique-1.3.2.md deleted file mode 100644 index 4f2ed06bf..000000000 --- a/changes.d/cli/optique-1.3.2.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -links: - '#1197': https://github.com/fedify-dev/fedify/pull/1197 ---- - - Updated Optique to 1.3.2. This fixes several command-line parsing - issues, so options with attached values such as `--timeout=30` are - handled consistently, typo suggestions for mistyped options are more - accurate, and errors for known options are no longer hidden by - positional arguments before `--`. [[#1197]] diff --git a/changes.d/cli/portable-objects.md b/changes.d/cli/portable-objects.md deleted file mode 100644 index 99514f68b..000000000 --- a/changes.d/cli/portable-objects.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -links: - '#1156': https://github.com/fedify-dev/fedify/issues/1156 - '#1199': https://github.com/fedify-dev/fedify/pull/1199 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added support for [FEP-ef61] portable objects to the `fedify` command. - [[#288], [#1156], [#1199]] - - - `fedify lookup` now looks up portable objects by their `ap:` and - `ap+ef61:` IDs, compatible identifiers, and the WebFinger handles of - portable actors, and verifies their Object Integrity Proofs. - Previously, it failed to look up portable IDs, and refused portable - objects found through compatible identifiers as cross-origin objects. - The same applies to the collections that `-t`/`--traverse` traverses - and the objects that `--recurse` follows. When no gateway returns - an acceptable object, the command tells why, e.g., that the object's - proof is invalid. - - - Added the `--gateway` option to `fedify lookup`, `fedify inbox`, and - `fedify webfinger`, which specifies the gateways to look up portable - objects from, e.g., for portable IDs without `@gateway` location - hints. - - - `fedify inbox -f`/`--follow` now follows portable actors, and - the `-a`/`--accept-follow` option of `fedify inbox` and - the `-a`/`--accept-follow` and `-r`/`--reject-follow` options of - `fedify relay` accept portable IDs and compatible identifiers, which - match the actor regardless of `@gateway` location hints and - the gateway of a compatible identifier. - - - `fedify webfinger` now accepts portable actor IDs. As such an ID - does not tell which server to ask, the command looks up the actor - and then its WebFinger address, which consists of its - `preferredUsername` and the host of its first gateway, and reports - whether the response links back to the actor. - - - Fixed `fedify lookup --recurse` reporting a timeout or another network - failure of the first object or of a linked object as a possibly private - object, suggesting the `-a`/`--authorized-fetch` option. It now reports - the actual cause, e.g., “Request timed out after 10 seconds,” like the - other modes of `fedify lookup` do. [[#1156], [#1199]] - - - Fixed the `-p`/`--allow-private-address` option of `fedify webfinger` - being ignored. [[#1156], [#1199]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/debugger/imported-unreleased.md b/changes.d/debugger/imported-unreleased.md deleted file mode 100644 index 2c65df90b..000000000 --- a/changes.d/debugger/imported-unreleased.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#823': https://github.com/fedify-dev/fedify/issues/823 - '#925': https://github.com/fedify-dev/fedify/pull/925 ---- - - Fixed the CommonJS debugger build so it no longer requires - `@js-temporal/polyfill` at runtime. The build now bundles - `temporal-polyfill`, while type declarations rely on the standard - `esnext.temporal` lib reference. - [[#823], [#925]] diff --git a/changes.d/fedify/circuit-breaker-encoded-cas.md b/changes.d/fedify/circuit-breaker-encoded-cas.md deleted file mode 100644 index 3f3192ee2..000000000 --- a/changes.d/fedify/circuit-breaker-encoded-cas.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -links: - '#1163': https://github.com/fedify-dev/fedify/issues/1163 - '#1167': https://github.com/fedify-dev/fedify/pull/1167 ---- - - Fixed outbound delivery circuit breaker transitions when a key–value - store compares encoded values. Existing half-open states can now recover - after switching to a CAS-capable store. [[#1163], [#1167]] diff --git a/changes.d/fedify/document-loader-timeout.md b/changes.d/fedify/document-loader-timeout.md deleted file mode 100644 index fb8aaffc7..000000000 --- a/changes.d/fedify/document-loader-timeout.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -links: - '#1131': https://github.com/fedify-dev/fedify/issues/1131 - '#1169': https://github.com/fedify-dev/fedify/pull/1169 ---- - - Changed the built-in document loader, context loader, and authenticated - document loader to time out each call after 10 seconds by default. - Previously, a remote server that responded slowly or never could hold - a request for as long as the runtime and the network allowed, e.g., - an incoming activity whose signature key Fedify fetched, and the sender - picks such key URLs. The time limit covers the whole call, including - every redirect and alternate document it follows, double-knocking - retries, and reading the response body. A call that times out throws - a `FetchError` without a response, whose `cause` is a `DOMException` - named `"TimeoutError"`, so a key fetch that times out is reported as - a `keyFetchError` by `verifyRequestDetailed()` and is cached like other - failures to fetch a key. Custom document loaders are not affected. - [[#1131], [#1169]] - - - Added `FederationOptions.documentLoaderTimeout` option to change - the time limit, or to turn it off with `null`. - - - Added the `timeout` option to `getAuthenticatedDocumentLoader()`. - - - Changed the built-in document loaders to read the body of an error - response before they throw a `FetchError`, at most 1 MiB, so that - the time limit also bounds reading it. `FetchError.response` keeps - the body byte for byte, or only the status and headers if the body is - larger than that. [[#1131], [#1169]] diff --git a/changes.d/fedify/imported-unreleased.md b/changes.d/fedify/imported-unreleased.md deleted file mode 100644 index 7a0895e14..000000000 --- a/changes.d/fedify/imported-unreleased.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -links: - '#206': https://github.com/fedify-dev/fedify/issues/206 - '#754': https://github.com/fedify-dev/fedify/issues/754 - '#797': https://github.com/fedify-dev/fedify/issues/797 - '#798': https://github.com/fedify-dev/fedify/issues/798 - '#799': https://github.com/fedify-dev/fedify/issues/799 - '#803': https://github.com/fedify-dev/fedify/pull/803 - '#806': https://github.com/fedify-dev/fedify/pull/806 - '#812': https://github.com/fedify-dev/fedify/pull/812 - '#823': https://github.com/fedify-dev/fedify/issues/823 - '#923': https://github.com/fedify-dev/fedify/pull/923 - '#925': https://github.com/fedify-dev/fedify/pull/925 - '#927': https://github.com/fedify-dev/fedify/pull/927 - '#930': https://github.com/fedify-dev/fedify/issues/930 - '#934': https://github.com/fedify-dev/fedify/pull/934 - '#968': https://github.com/fedify-dev/fedify/pull/968 ---- - - Fixed `verifyProof()` so Ed25519 JCS proofs authenticate every received - proof option except `proofValue`, including `expires`, `domain`, - `challenge`, `nonce`, and extension options. It now rejects expired or - malformed proof options, and callers can provide expected `domain` and - `challenge` values through `VerifyProofOptions` to prevent cross-domain or - replay use. [[#968]] - - - Added support for the [ActivityPub Media Upload extension] so that servers - can accept client-to-server media uploads: - [[#754], [#927]] - - - `Federation` and `FederationBuilder` gained a `setMediaUploader()` - method (through the new `MediaUploaderSetters` interface) that registers - a `multipart/form-data` upload endpoint. Its callback finalizes the - uploaded `file` alongside the posted `object` shell and returns either - the created object (`201 Created`) or the `URL` at which it will become - available once processing finishes (`202 Accepted`). - - `Context` gained a `getMediaUploaderUri()` method for building the - endpoint URI, which actor dispatchers advertise under the new - `Endpoints.uploadMedia` property. - - A new metric endpoint category, `media_upload`, classifies these - requests in the `fedify.endpoint` attribute. - - Fedify logs a runtime warning when a callback's returned URI does not - point at a registered object dispatcher route, when a registered - media uploader is not advertised under `endpoints.uploadMedia`, or - when a media uploader is registered without an `authorize()` hook (so - the endpoint would accept uploads from anyone). - - - Added a custom background task API that generalizes Fedify's - enqueue-and-process-later pattern to arbitrary application-defined jobs: - - - `Federation` and `FederationBuilder` gained a `defineTask()` method - through the new `TaskRegistry` interface, which `Federatable` now - extends. - - `Context` gained `enqueueTask()` and `enqueueTaskMany()` methods, - with `delay` and `orderingKey` options - (new `TaskEnqueueOptions` interface). - - Every task requires a [Standard Schema] - (`schema` option) from which the payload type is inferred; payloads - are validated at enqueue time (fail fast) and again at dequeue time - (protection against schema drift across deployments). - - Payloads are serialized by Fedify with devalue, so `Date`, `Map`, - `Set`, `URL`, `bigint`, circular references, and Activity Vocabulary - objects round-trip faithfully across every message queue backend. - - Failed handlers are retried with exponential backoff by default; - tasks support per-task `retryPolicy` and `onError` options, the new - `FederationOptions.taskRetryPolicy` sets the federation-wide default, - and queues with `nativeRetrial` delegate retries to the backend. - - Tasks can be isolated from activity delivery through the new - `FederationQueueOptions.task` slot or a per-task `queue` option; - without them, tasks fall back to the outbox queue unless the new - `FederationOptions.taskQueueResolution` option is set to `"strict"`. - `Federation.startQueue()` now accepts `queue: "task"` to run - a task-only worker. - - Tasks can request at-most-once enqueue with a `deduplicationKey` - (new `TaskEnqueueOptions.deduplicationKey`). A queue declaring the new - `MessageQueue.nativeDeduplication` capability owns the check and - receives the key through the new - `MessageQueueEnqueueOptions.deduplicationKey`; otherwise Fedify - performs a best-effort key–value guard through the optional - `KvStore.cas` primitive, under a new `taskDeduplication` key prefix. - The marker TTL and the no-`cas` fallback are tunable with the new - `FederationOptions.taskDeduplicationTtl` and - `FederationOptions.taskDeduplicationFallback` options. - [[#206], [#797], [#798], [#799], [#803], [#806], [#812], [#923] by ChanHaeng Lee\] - - - Added `MessageQueue.atomicEnqueueMany` for queues that implement - `enqueueMany()` with separate sends. Fedify still uses their batch path - normally, but rejects a multi-message batch governed by one - `deduplicationKey` before a partial send can undermine deduplication. - [[#930], [#934]] - - - Fixed CommonJS distribution files that use Temporal so they no longer - require `@js-temporal/polyfill` at runtime. The CommonJS build now - bundles `temporal-polyfill`, while type declarations rely on the standard - `esnext.temporal` lib reference. - [[#823], [#925]] - -[ActivityPub Media Upload extension]: https://www.w3.org/wiki/SocialCG/ActivityPub/MediaUpload -[Standard Schema]: https://standardschema.dev/ diff --git a/changes.d/fedify/kv-cache-ttl.md b/changes.d/fedify/kv-cache-ttl.md deleted file mode 100644 index f3caf4e8b..000000000 --- a/changes.d/fedify/kv-cache-ttl.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -links: - '#1017': https://github.com/fedify-dev/fedify/issues/1017 - '#1027': https://github.com/fedify-dev/fedify/pull/1027 ---- - - Changed cached actor public keys and remembered per-origin HTTP Message - Signatures specs to expire, so a `KvStore` that never sees an explicit - clear no longer accumulates entries for actors and origins that have - stopped federating. Keys expire after 30 days and specs after 90 days - by default, and both windows are configurable through the new - `FederationOptions.publicKeyTtl` and - `FederationOptions.httpMessageSignaturesSpecTtl` options. - [[#1017], [#1027] by Heewon Chae] - - - Shortening a window trades storage for remote requests: an expired - key has to be refetched before the next signature verification, and - an expired spec has to be relearned by double-knocking on the next - delivery. Refetching fails while the peer is unavailable, so a very - short window makes verification depend on the peer being reachable. - - Entries written by earlier versions of Fedify have no expiry and are - left as they are; they gain one the next time they are written. See - the new *Clearing legacy cache entries* section of the - [key–value store guide] to clear them proactively instead of waiting. - -[key–value store guide]: https://fedify.dev/manual/kv diff --git a/changes.d/fedify/object-tombstones.md b/changes.d/fedify/object-tombstones.md deleted file mode 100644 index 5132b747b..000000000 --- a/changes.d/fedify/object-tombstones.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -links: - '#1112': https://github.com/fedify-dev/fedify/issues/1112 - '#1117': https://github.com/fedify-dev/fedify/pull/1117 ---- - - Allowed object dispatchers to return `Tombstone` for deleted objects, as - actor dispatchers already can. Fedify now serves such object URIs with - `410 Gone` and the serialized tombstone body, as ActivityPub recommends, - after applying the authorization predicate as for other objects, so that - applications no longer need a separate route in front of Fedify for - deleted posts. Fedify logs a warning if the tombstone's `id` does not - match `Context.getObjectUri()`. [[#1112], [#1117]] - - - Changed the return type of `ObjectDispatcher` from - `TObject | null` to `TObject | Tombstone | null`. - - Added a `RequestContext.getObject()` overload that takes - a `GetObjectOptions` object. By default, `getObject()` still returns - `null` for a tombstone unless the tombstone is an instance of - the requested class, e.g., `Object` or `Tombstone`. Pass - `{ tombstone: "passthrough" }` to receive tombstones. - - Added the `GetObjectOptions` interface. - - Changed object dispatchers registered for `Tombstone` or `Object` - that return tombstones to be served with `410 Gone` instead of - `200 OK`. diff --git a/changes.d/fedify/on-request-finished.md b/changes.d/fedify/on-request-finished.md deleted file mode 100644 index f486a4e42..000000000 --- a/changes.d/fedify/on-request-finished.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#1191': https://github.com/fedify-dev/fedify/issues/1191 - '#1201': https://github.com/fedify-dev/fedify/pull/1201 ---- - - Added `onRequestFinished()` to observe every inbox delivery, including - rejected requests and preparation errors, with signature/proof checks, - actual verification keys, the final authentication decision, and the - processing outcome. The callback is awaited independently of trace - sampling, and its errors do not change delivery results. [[#1191], [#1201]] diff --git a/changes.d/fedify/portable-objects.md b/changes.d/fedify/portable-objects.md deleted file mode 100644 index 7fb02b05f..000000000 --- a/changes.d/fedify/portable-objects.md +++ /dev/null @@ -1,367 +0,0 @@ ---- -links: - '#1041': https://github.com/fedify-dev/fedify/pull/1041 - '#1044': https://github.com/fedify-dev/fedify/issues/1044 - '#1045': https://github.com/fedify-dev/fedify/issues/1045 - '#1051': https://github.com/fedify-dev/fedify/pull/1051 - '#1073': https://github.com/fedify-dev/fedify/pull/1073 - '#1076': https://github.com/fedify-dev/fedify/pull/1076 - '#1080': https://github.com/fedify-dev/fedify/pull/1080 - '#1082': https://github.com/fedify-dev/fedify/pull/1082 - '#1084': https://github.com/fedify-dev/fedify/pull/1084 - '#1092': https://github.com/fedify-dev/fedify/pull/1092 - '#1093': https://github.com/fedify-dev/fedify/issues/1093 - '#1094': https://github.com/fedify-dev/fedify/issues/1094 - '#1095': https://github.com/fedify-dev/fedify/issues/1095 - '#1096': https://github.com/fedify-dev/fedify/issues/1096 - '#1099': https://github.com/fedify-dev/fedify/pull/1099 - '#1100': https://github.com/fedify-dev/fedify/issues/1100 - '#1101': https://github.com/fedify-dev/fedify/issues/1101 - '#1102': https://github.com/fedify-dev/fedify/pull/1102 - '#1104': https://github.com/fedify-dev/fedify/pull/1104 - '#1105': https://github.com/fedify-dev/fedify/pull/1105 - '#1106': https://github.com/fedify-dev/fedify/issues/1106 - '#1107': https://github.com/fedify-dev/fedify/issues/1107 - '#1109': https://github.com/fedify-dev/fedify/pull/1109 - '#1110': https://github.com/fedify-dev/fedify/pull/1110 - '#1111': https://github.com/fedify-dev/fedify/issues/1111 - '#1113': https://github.com/fedify-dev/fedify/issues/1113 - '#1114': https://github.com/fedify-dev/fedify/pull/1114 - '#1119': https://github.com/fedify-dev/fedify/pull/1119 - '#1120': https://github.com/fedify-dev/fedify/pull/1120 - '#1123': https://github.com/fedify-dev/fedify/issues/1123 - '#1124': https://github.com/fedify-dev/fedify/pull/1124 - '#1132': https://github.com/fedify-dev/fedify/issues/1132 - '#1133': https://github.com/fedify-dev/fedify/issues/1133 - '#1134': https://github.com/fedify-dev/fedify/pull/1134 - '#1138': https://github.com/fedify-dev/fedify/pull/1138 - '#1142': https://github.com/fedify-dev/fedify/pull/1142 - '#1143': https://github.com/fedify-dev/fedify/issues/1143 - '#1145': https://github.com/fedify-dev/fedify/pull/1145 - '#1146': https://github.com/fedify-dev/fedify/issues/1146 - '#1147': https://github.com/fedify-dev/fedify/issues/1147 - '#1148': https://github.com/fedify-dev/fedify/issues/1148 - '#1151': https://github.com/fedify-dev/fedify/issues/1151 - '#1153': https://github.com/fedify-dev/fedify/issues/1153 - '#1154': https://github.com/fedify-dev/fedify/issues/1154 - '#1155': https://github.com/fedify-dev/fedify/issues/1155 - '#1159': https://github.com/fedify-dev/fedify/issues/1159 - '#1164': https://github.com/fedify-dev/fedify/pull/1164 - '#1165': https://github.com/fedify-dev/fedify/pull/1165 - '#1171': https://github.com/fedify-dev/fedify/pull/1171 - '#1178': https://github.com/fedify-dev/fedify/pull/1178 - '#1180': https://github.com/fedify-dev/fedify/pull/1180 - '#1183': https://github.com/fedify-dev/fedify/pull/1183 - '#1186': https://github.com/fedify-dev/fedify/pull/1186 - '#1188': https://github.com/fedify-dev/fedify/pull/1188 - '#1189': https://github.com/fedify-dev/fedify/pull/1189 - '#1198': https://github.com/fedify-dev/fedify/pull/1198 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#827': https://github.com/fedify-dev/fedify/issues/827 - '#829': https://github.com/fedify-dev/fedify/issues/829 - '#832': https://github.com/fedify-dev/fedify/issues/832 - '#835': https://github.com/fedify-dev/fedify/issues/835 - '#836': https://github.com/fedify-dev/fedify/issues/836 - '#837': https://github.com/fedify-dev/fedify/issues/837 - '#838': https://github.com/fedify-dev/fedify/issues/838 - '#839': https://github.com/fedify-dev/fedify/issues/839 - '#840': https://github.com/fedify-dev/fedify/issues/840 - '#841': https://github.com/fedify-dev/fedify/issues/841 - '#915': https://github.com/fedify-dev/fedify/pull/915 - '#926': https://github.com/fedify-dev/fedify/pull/926 - '#938': https://github.com/fedify-dev/fedify/issues/938 - '#968': https://github.com/fedify-dev/fedify/pull/968 ---- - - Added support for [FEP-ef61] portable objects, whose IDs are `ap:` or - `ap+ef61:` URIs with a DID instead of a host, e.g., - `ap://did:key:z6Mk.../actor`. A Fedify server can now act as a gateway for - portable actors: it serves their actor documents, objects, collections, and - hashlink media, accepts deliveries to their inboxes, and sends their - activities. It can also consume the portable objects of others. The new - [*Portable objects*][portable objects] chapter of the manual walks through - running portable actors, and describes the FEP-ef61 profile that Fedify - supports, including where it deliberately differs from the FEP and what it - does not implement. Applications without portable actors are unaffected, - except that their dispatchers may be called for requests to the gateway - endpoint, */.well-known/apgateway/*, and that `Context.sendActivity()` may - reject activities that embed others' portable objects (see below). - [[#288], [#1151], [#1198]] - - - Added `verifyPortableObjectProof()`, which enforces the FEP-ef61 proof - policy: a portable actor, activity, or object needs an [FEP-8b32] - Object Integrity Proof whose `verificationMethod` is a DID URL of - the DID in its ID, and a portable actor needs a non-empty `gateways` - list of HTTP(S) origins. A document whose ID is a compatible - identifier, e.g., - `https://gw.example/.well-known/apgateway/did:key:z6Mk.../actor`, is - verified against the DID in it. Its detailed result distinguishes - documents outside the policy, unsecured collections, missing or invalid - proofs, invalid gateways, unsupported verification methods, and DID - mismatches. [[#832], [#968], [#1093], [#1105], [#1148], [#1178]] - - - Added `verifyPortableObject()`, which verifies proofs like - `verifyPortableObjectProof()`, and also accepts an actor's `inbox`, - `outbox`, `followers`, `following`, or `liked` collection without - a proof if a gateway that the actor lists served it, as FEP-ef61 - allows. The `VerifyPortableObjectOptions`, - `VerifyPortableObjectResult`, and `VerifyPortableObjectFailureReason` - types describe it. [[#836], [#1084], [#1093], [#1105]] - - - Added the `Context.verifyPortableObject` property, which is - `verifyPortableObject()` with the context's loaders. Since it has - the same name as the option of property accessors, passing a context - as their options, e.g., `await create.getObject(ctx)`, verifies - portable objects. Inboxes use it as the default verifier of received - activities, as do `Context.lookupObject()`, - `Context.traverseCollection()`, and the `onOutboxError` callback. - Added the `verifyPortableObject` option to `VerifyObjectOptions`. - [[#1107], [#1120]] - - - `verifyProof()` now resolves Ed25519 `did:key` verification methods, - e.g., `did:key:z6Mk...#z6Mk...`, locally without fetching them, and - `verifyObject()` accepts a proof made by a DID as authenticating - an actor or attribution whose portable ID or compatible identifier - has that DID. [[#827], [#829], [#915], [#926], [#1093], [#1105]] - - - Added the `Context.getPortableActorUri()`, - `Context.getPortableObjectUri()`, `Context.getPortableInboxUri()`, - `Context.getPortableOutboxUri()`, `Context.getPortableFollowingUri()`, - `Context.getPortableFollowersUri()`, `Context.getPortableLikedUri()`, - `Context.getPortableFeaturedUri()`, - `Context.getPortableFeaturedTagsUri()`, and - `Context.getPortableCollectionUri()` methods, which build portable IDs - from the paths of the corresponding dispatchers and a DID. Custom - implementations of the `Context` interface need to implement them. - [[#835], [#839], [#841], [#1076], [#1092], [#1111], [#1114], [#1142]] - They throw a `TypeError` for a `did:key` DID that is not encoded in - base58-btc, as FEP-ef61 requires, or for an identifier that has - a `.` or `..` path segment. [[#841], [#1114], [#1154], [#1186]] - - - Added the `portable` option to `Context.parseUri()` and - the `ParseUriOptions` interface. With `{ portable: true }`, - the method also recognizes portable IDs and their compatible - identifiers, and the result has the DID in its new `authority` - property. [[#1143], [#1145]] - - - Object dispatchers and the actor dispatcher now serve portable objects - and actors through the gateway endpoint, e.g., - `GET /.well-known/apgateway/did:key:z6Mk.../notes/123`, with the path - after the DID. An object is served only if its ID canonically equals - the requested portable ID and it has a proof made with a key of - the DID. A non-public object is served only if the dispatcher has - an authorization predicate, as FEP-ef61 forbids gateways to serve it - to anyone but its audience. Signed tombstones are served with - `410 Gone`. Added the `RequestContext.portableRequest` property, - which tells the dispatcher the requested DID and ID. - [[#835], [#841], [#1076], [#1113], [#1114], [#1124], [#1153], [#1183]] - - - Added the `RequestContext.isSignedByAudience()` method and - the `IsSignedByAudienceOptions` interface, which check whether - a request is signed by an actor in the audience of an object, e.g., - in the authorization predicate of an object dispatcher. Custom - implementations of the `RequestContext` interface need to implement - the method. [[#1153], [#1183]] - - - Collection dispatchers now serve the collections of portable actors - through the gateway endpoint, e.g., - `GET /.well-known/apgateway/did:key:z6Mk.../users/alice/outbox`, if - the actor is a portable actor under the requested DID whose - corresponding property refers to the collection. A collection that - is not paginated always has `totalItems`, so that consumers can tell - an empty one from other objects. Added - the `CustomCollectionCallbackSetters.mapPortableOwner()` method and - the `PortableCollectionOwnerMapper` type, which tie a custom - collection to its portable owner. [[#1111], [#1142]] - - - Added `Federatable.setHashlinkMediaDispatcher()` and - the `HashlinkMediaRequest` interface, which serve resources that - portable objects refer to with SHA-256 hashlinks, e.g., - `GET /.well-known/apgateway/hl:zQm...`. Fedify does not verify the - dispatcher's response against the digest. Added `hashlink_media` to - the values of the `fedify.endpoint` metric attribute. - [[#838], [#1080]] - - - Inbox listeners now accept deliveries to portable inboxes through - the gateway endpoint, e.g., - `POST /.well-known/apgateway/did:key:z6Mk.../users/alice/inbox`, if - the actor dispatcher returns a portable actor whose `inbox` is - the requested inbox and whose `gateways` include this server. - [[#839], [#1092]] - - - Fedify now forwards an activity delivered to a portable inbox to - the actor's other gateways at most once, as FEP-ef61 recommends, if - the activity is authenticated by its own proof or Linked Data - Signature and the `KvStore` supports `cas()`. Forwarded requests are - signed with this server's RSA gateway key for the actor if the key - pairs dispatcher returns one, and are sent unsigned otherwise. An - activity is not forwarded back to the gateway that forwarded it if - Fedify can identify that gateway by its gateway key signature on the - delivery. Added the `FederationOptions.portableInboxForwarding` and - `FederationKvPrefixes.portableInboxForwarding` options. - [[#839], [#1092], [#1100], [#1101], [#1104], [#1110]] - - - `Context.sendActivity()` and `InboxContext.forwardActivity()` now - deliver to portable inboxes through the recipient's gateways, or else - the `@gateway` location hints of the inbox, trying at most five of - them until one accepts the activity. Previously, such a delivery - failed with `UrlError: Unsupported protocol: ap+ef61:`. Queue - workers of older Fedify versions deliver such queued activities only - through the first gateway, so upgrade them before the servers that - enqueue deliveries. [[#1147], [#1180]] - - - Added the `ActorCallbackSetters.mapPortableActorId()` method and - the `PortableActorIdMapper` type. For an actor that the callback - maps to a portable ID, `Context.getActorKeyPairs()` identifies its key - pairs by the actor's compatible identifier on this server, e.g., - `https://example.com/.well-known/apgateway/did:key:z6Mk.../users/alice#main-key`, - so that they serve as this server's *gateway keys* for the actor, which - sign HTTP requests made on behalf of the actor, but never make Object - Integrity Proofs or Linked Data Signatures. [[#840], [#1099]] - - - HTTP Signature verification now accepts a gateway key of a portable - actor if the actor document at the key ID has a valid proof by - the actor's DID, embeds the key in its `assertionMethod`, or else in - its `publicKey`, and lists the gateway in its `gateways`. Such a key - is owned by the portable actor, so - `RequestContext.getSignedKeyOwner()`, `getKeyOwner()`, and - `doesActorOwnKey()` return or match the actor. Keys at compatible - identifiers are cached apart for each purpose, for an hour at most. - [[#840], [#1095], [#1099], [#1105], [#1119], [#1123], [#1164]] - A key at an `ap:` key ID is accepted likewise if an actor document - fetched through the key ID's location hints vouches for it. - [[#1096], [#1132], [#1134], [#1165]] - - - Inboxes accept an activity of a portable actor, or an activity with - a portable ID, only if it has a valid proof made by the DID of that - ID; an HTTP Signature or a Linked Data Signature does not - authenticate it, and such an activity is rejected with - `401 Unauthorized`. [[#840], [#1099]] - - - Inboxes independently verify each portable actor, activity, and - object embedded in a compound document, e.g., the `Note` in - a `Create`, against its own proof before dispatch, following Fedify's - interim *map-local* profile, since neither FEP-8b32 nor Verifiable - Credential Data Integrity defines the boundaries of embedded proofs - yet. A valid outer proof does not authenticate an unsigned or invalid - embedded portable object. Documents with proof sets, or that exceed - the traversal limits, are rejected. A key embedded in a verified - portable actor needs no proof of its own if the key's ID is the actor's - ID plus a fragment. This profile may change in Fedify 3.0. - [[#938], [#1041], [#1094], [#1102], [#1133], [#1138]] - - - `Context.sendActivity()` gives an activity that contains portable - objects at most one proof: an activity that already has one is sent - as is, and a portable activity is signed only by the key whose ID is - a DID URL for its DID. An activity of a portable actor has to have - a portable ID or a compatible identifier of the actor's DID, and never - gets a Linked Data Signature. Otherwise, `sendActivity()` rejects with - a `TypeError` before anything is delivered or queued. So does a - non-portable activity that embeds portable objects, including ones with - compatible identifiers, when several Ed25519 keys are available, and an - activity with portable objects in which any map carries a proof set, or - an embedded map carries a proof but not its own `@context`, e.g., - a received signed `Follow` embedded in an `Accept`, which Fedify - inboxes would reject; refer to such an object by its ID instead. - Sign portable activities with `signObject()` beforehand, or pass the - DID's key as an explicit sender key. - [[#840], [#1041], [#1045], [#1073], [#1099]] - - - Your portable actors and objects may have compatible identifiers as - their IDs, e.g., - `https://example.com/.well-known/apgateway/did:key:z6Mk.../actor`, - for interoperability with software that cannot handle portable IDs. - Fedify treats them as portable wherever it serves or sends them, and - warns if such an ID is malformed or is not on the owner's first - gateway, as FEP-ef61 requires. Build them with `toCompatibleEf61Id()` - before signing the documents. [[#1106], [#1109], [#1155], [#1188]] - - - The WebFinger endpoint now serves portable actors: the domain of - the actor's address comes from the first gateway in its `gateways`, - and its `self` link is its compatible identifier on that gateway. - WebFinger resources can be portable IDs, which are passed to - `mapAlias()`. `Context.lookupObject()` resolves the handles of - portable actors on other servers. [[#837], [#1082], [#1106], [#1109]] - - - Fedify logs a warning if an actor dispatcher returns a portable actor - whose `gateways` are invalid, or whose collections are not the - portable IDs or compatible identifiers that the corresponding - `Context.getPortable*Uri()` methods build, instead of warning that - a portable actor's ID or collections do not match the URIs that - `Context.getActorUri()` and the like build. - [[#837], [#1082], [#1111], [#1142], [#1148], [#1178]] - - - `Context.routeActivity()` routes a portable activity that has no - valid proof only if all of its actors have the same DID as - the activity, comparing [FEP-fe34] origins, where the origin of - a portable ID or a compatible identifier is its DID. [[#1146], [#1171]] - - - Outbox listeners compare the `actor` of a posted activity with - a portable outbox owner by their canonical portable IDs, so that - the actor can be referred to with `@gateway` location hints, another - URI scheme, or as a compatible identifier on another gateway. - [[#1159], [#1189]] - - - Changed Fedify to treat documents whose IDs are [FEP-ef61] compatible - identifiers, such as - `https://gw.example/.well-known/apgateway/did:key:z6Mk.../actor`, as - the portable objects they stand for, as FEP-ef61 requires, instead of - trusting them by the web origin that served them. Previously, any server - could act as - `https://evil.example/.well-known/apgateway/did:key:z6MkAlice/actor` - without a proof by Alice's DID. Some implementations, e.g., tootik, - identify their portable actors this way. [[#288], [#1093], [#1105]] - - - Inboxes now reject an activity of an actor whose ID is a compatible - identifier with `401 Unauthorized` unless it has a valid Object - Integrity Proof made by the actor's DID. Activities of actors that - publish compatible identifiers without signing them, or whose DIDs - use key types Fedify does not support, are no longer accepted. - - - `verifyObject()` never authenticates an attribution or actor whose ID - is a compatible identifier by a key at an ordinary URL. - - - HTTP Signature verification rejects a key at a compatible identifier - unless the actor document has a valid proof by the actor's DID and - vouches for the key. A key at an ordinary URL that claims a portable - actor as its owner or controller is no longer that actor's key, and - `getKeyOwner()` and `doesActorOwnKey()` no longer resolve portable - actors by web origin. - - - Changed property accessors to verify the [FEP-ef61] portable objects that - they dereference when a `Context` is passed as their options, e.g., - `await create.getObject(ctx)`, since the new `Context.verifyPortableObject` - property has the same name as their `verifyPortableObject` option. This - also applies to objects with ordinary HTTP(S) IDs: their references to - compatible identifiers are now verified as portable objects instead of - being trusted because of their origin. In inbox listeners, accessors do - so even without options. [[#288], [#1107], [#1120]] - - - Fixed `signObject()` so that a signed object keeps verifying after it is - assigned to a typed parent and the parent is serialized. `signObject()` - now captures the secured JSON document its proof covers, and nested - serialization embeds that document verbatim instead of rebuilding the - child under the parent's JSON-LD context. Producing a compound document, - such as a signed `Note` in a signed [FEP-ef61] portable `Create`, with - `signObject()` no longer requires assembling the JSON by hand. - [[#288], [#1041], [#1044], [#1051]] - - - The captured document is a snapshot: `clone()` does not carry it, and - mutating a signed object in place does not change it. Sign a clone - again when it has to be embedded as a secured child. - - Serialization falls back to the previous behavior for objects parsed - with `fromJsonLd()`, objects that already carried a proof, and - `toJsonLd()` calls whose `context` option could hide the internal - placeholder. - - Outgoing JSON-LD compatibility normalization now leaves a nested - self-contained secured document untouched while signing and sending, - so it cannot rewrite bytes that the child's own proof covers. - Inbound verification is unaffected. - - Fanout delivery now reuses the document the activity was already - serialized into instead of reparsing and reserializing it, which - previously invalidated an embedded signed child and the outer proof - that covered it. - -[FEP-ef61]: https://w3id.org/fep/ef61 -[portable objects]: https://fedify.dev/manual/portable -[FEP-8b32]: https://w3id.org/fep/8b32 -[FEP-fe34]: https://w3id.org/fep/fe34 diff --git a/changes.d/fedify/rfc9421-signature-cap.md b/changes.d/fedify/rfc9421-signature-cap.md deleted file mode 100644 index c1080ada0..000000000 --- a/changes.d/fedify/rfc9421-signature-cap.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -links: - '#1130': https://github.com/fedify-dev/fedify/issues/1130 - '#1166': https://github.com/fedify-dev/fedify/pull/1166 ---- - - Changed HTTP Signature verification to verify at most the first three - RFC 9421 signatures of a request, in the order of its `Signature-Input` - header, and to ignore the rest. Each signature may make Fedify fetch the - key that it names from a URL of the sender's choosing, so a single - unauthenticated request with many signatures could make Fedify fetch any - number of URLs. A signature counts even if it fails before its key is - fetched, and a key is now looked up only once for all the signatures of - a request that name it. A request whose only valid signature comes after - the first three is no longer accepted; senders usually put a single - signature on a request. [[#1130], [#1166]] - - - Added the `FederationOptions.maxHttpSignatures` option to change the - limit for the inbox and `RequestContext.getSignedKey()`, and the - `maxSignatures` option of `verifyRequest()` and - `verifyRequestDetailed()` for verifying requests directly. Both - have to be positive integers or `Infinity`, which turns the limit - off; other values throw a `RangeError`. - - - When a cached key does not verify a signature, Fedify now fetches it - again for that signature only, instead of verifying every signature - of the request once more without the key cache. diff --git a/changes.d/init/imported-unreleased.md b/changes.d/init/imported-unreleased.md deleted file mode 100644 index 5d054c3a8..000000000 --- a/changes.d/init/imported-unreleased.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#950': https://github.com/fedify-dev/fedify/issues/950 - '#952': https://github.com/fedify-dev/fedify/pull/952 ---- - - Fixed `fedify init`'s hydration test validation to run `format` before - `format:check`, which previously caused the entire test suite to fail when - the package manager is `npm` or `pnpm`: - [[#950]] - [[#952] by Jang Hanarae\] diff --git a/changes.d/init/smoke-test.md b/changes.d/init/smoke-test.md deleted file mode 100644 index 29b6d3db8..000000000 --- a/changes.d/init/smoke-test.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -links: - '#990': https://github.com/fedify-dev/fedify/pull/990 ---- - - Added a `test` task to projects scaffolded by `fedify init`. It starts - the app, waits for it to become ready, and checks that it resolves a local - actor, giving projects a standard smoke test to run right after scaffolding - and whenever the app changes afterwards. [[#898], [#990] by Jang Hanarae] diff --git a/changes.d/init/sveltekit.md b/changes.d/init/sveltekit.md deleted file mode 100644 index 817f01752..000000000 --- a/changes.d/init/sveltekit.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -links: - '#971': https://github.com/fedify-dev/fedify/pull/971 ---- - - Supported [SvelteKit] as a web framework option in - `fedify init`. [[#892], [#971] by Jang Hanarae] diff --git a/changes.d/init/verify-runtime-version.md b/changes.d/init/verify-runtime-version.md deleted file mode 100644 index de73aff1a..000000000 --- a/changes.d/init/verify-runtime-version.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -links: - '#964': https://github.com/fedify-dev/fedify/issues/964 - '#981': https://github.com/fedify-dev/fedify/pull/981 ---- - - Added runtime version verification to `fedify init`. It checks that the - selected Deno, Bun, or Node.js meets Fedify's minimum version, or a higher - version required by a framework (such as Astro's Node.js 22.12), before - generating a project. A missing, malformed, or unsupported runtime now - produces a clear error in non-interactive mode and disables the affected - package managers in interactive mode. [[#964], [#981] by Lee Jeongmin] diff --git a/changes.d/interaction-controls/imported-unreleased.md b/changes.d/interaction-controls/imported-unreleased.md deleted file mode 100644 index 840474f1f..000000000 --- a/changes.d/interaction-controls/imported-unreleased.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -links: - '#811': https://github.com/fedify-dev/fedify/issues/811 - '#929': https://github.com/fedify-dev/fedify/pull/929 ---- - - Added the new `@fedify/interaction-controls` package for implementing - [GoToSocial interaction controls], [FEP-044f], and [FEP-7aa9]. It provides - immutable TypeScript APIs for creating and verifying interaction requests - and authorizations, evaluating `InteractionPolicy`, recognizing bare - interactions, and formatting stable storage keys for like, reply, announce, - quote, and feature interactions. - [[#811], [#929]] - -[GoToSocial interaction controls]: https://docs.gotosocial.org/en/v0.21.1/federation/interaction_controls/ -[FEP-044f]: https://w3id.org/fep/044f -[FEP-7aa9]: https://w3id.org/fep/7aa9 diff --git a/changes.d/lint/actor-preferred-username-rule.md b/changes.d/lint/actor-preferred-username-rule.md deleted file mode 100644 index 89b122b71..000000000 --- a/changes.d/lint/actor-preferred-username-rule.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -links: - '#1022': https://github.com/fedify-dev/fedify/pull/1022 - '#895': https://github.com/fedify-dev/fedify/issues/895 ---- - - Added the `actor-preferred-username-required` lint rule, which warns - when an actor dispatcher's return value does not include a - `preferredUsername` property. [[#895], [#1022] by Jae-Hyuk-Jang] diff --git a/changes.d/lint/imported-unreleased.md b/changes.d/lint/imported-unreleased.md deleted file mode 100644 index 8ca0bffc9..000000000 --- a/changes.d/lint/imported-unreleased.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -links: - '#754': https://github.com/fedify-dev/fedify/issues/754 - '#927': https://github.com/fedify-dev/fedify/pull/927 ---- - - Added four lint rules for the media upload endpoint introduced in - `@fedify/fedify`: - [[#754], [#927]] - - - `media-uploader-object-uri-required` warns when a `setMediaUploader()` - callback does not derive its return value from `ctx.getObjectUri()`. - - `media-uploader-authorization-required` warns when `setMediaUploader()` - is registered without an `.authorize()` hook. - - `actor-upload-media-property-required` warns when a media uploader is - registered but the actor dispatcher does not advertise - `endpoints.uploadMedia`. - - `actor-upload-media-property-mismatch` warns when - `endpoints.uploadMedia` is not built with - `ctx.getMediaUploaderUri(identifier)`. diff --git a/changes.d/lint/outbox-delivery-not-awaited.md b/changes.d/lint/outbox-delivery-not-awaited.md deleted file mode 100644 index 8a4a93287..000000000 --- a/changes.d/lint/outbox-delivery-not-awaited.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -links: - '#1057': https://github.com/fedify-dev/fedify/issues/1057 - '#1067': https://github.com/fedify-dev/fedify/pull/1067 ---- - - Added the `outbox-listener-delivery-not-awaited` rule to `@fedify/lint`. - It reports an outbox listener that calls `ctx.sendActivity()` or - `ctx.forwardActivity()` and drops the returned promise, so that the - activity may never leave on a runtime such as Cloudflare Workers, which - discards pending work once the response is returned. A call counts as - handled when its promise is awaited, returned, passed to `Promise.all()` - or `Promise.allSettled()`, or handed to `waitUntil()`, and `void`, - `Promise.race()` and `Promise.any()` are accepted as deliberate choices to - stop waiting. - The ESLint `recommended` configuration enables the rule as a warning and - `strict` as an error, and Oxlint users enable it by name. It is not - available in Deno Lint, which turns on every rule of a plugin at once. - [[#1057], [#1067] by Jae-Hyuk-Jang] diff --git a/changes.d/lint/outbox-listener-nested-property-writes.md b/changes.d/lint/outbox-listener-nested-property-writes.md deleted file mode 100644 index 388cecdbb..000000000 --- a/changes.d/lint/outbox-listener-nested-property-writes.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -links: - '#1125': https://github.com/fedify-dev/fedify/issues/1125 - '#1140': https://github.com/fedify-dev/fedify/pull/1140 ---- - - Fixed `outbox-listener-delivery-required` and - `outbox-listener-delivery-not-awaited` (`@fedify/lint`) losing track of - the functions an object already holds when a nested helper in the - listener assigns another property of that object, as in - `target.fallback = () => {}`. A listener that delivers through - `target.deliver()` after such an assignment is no longer reported as - undelivered, and a dropped delivery promise inside `target.deliver()` is - now reported. A helper that declares its own object of the same name is - still checked separately from the outer one. [[#1125], [#1140]] diff --git a/changes.d/lint/outbox-listener-path-aware.md b/changes.d/lint/outbox-listener-path-aware.md deleted file mode 100644 index b54c302ba..000000000 --- a/changes.d/lint/outbox-listener-path-aware.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -links: - '#1050': https://github.com/fedify-dev/fedify/pull/1050 - '#900': https://github.com/fedify-dev/fedify/issues/900 ---- - - Changed `outbox-listener-delivery-required` (`@fedify/lint`) to decide - whether a `ctx.sendActivity()`/`ctx.forwardActivity()` call actually - runs, instead of scanning the listener's source as a flat block of text. - It now reports a listener whose only delivery calls sit behind a dead - branch, after an unconditional `return`/`throw`, or inside a function - that is never used. When it cannot tell whether a delivery call runs, it - stays quiet: a function held under a name counts as used as soon as that - name is mentioned, however it is passed around, and an inline callback - counts wherever it is passed. - [[#900], [#1050] by Jae-Hyuk-Jang] diff --git a/changes.d/lint/outbox-listener-reachability-loops.md b/changes.d/lint/outbox-listener-reachability-loops.md deleted file mode 100644 index d517814c7..000000000 --- a/changes.d/lint/outbox-listener-reachability-loops.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -links: - '#1071': https://github.com/fedify-dev/fedify/issues/1071 - '#1088': https://github.com/fedify-dev/fedify/pull/1088 ---- - - Fixed `outbox-listener-delivery-required` and - `outbox-listener-delivery-not-awaited` (`@fedify/lint`) to properly - evaluate reachability in statically false loops (like `while (false)`) and - to correctly traverse `for...of` and `for...in` loop binding patterns. - Unreachable loop branches no longer count as deliveries, and - `outbox-listener-delivery-not-awaited` now correctly catches dropped - promises inside loop binding patterns. - Loop default functions are checked only when the bound value or target - object is referenced. Delivery helpers used after an assignment-form - loop default remain recognized, including when unrelated blocks reuse - their names. - [[#1071], [#1088] by @ArchieTansaria] diff --git a/changes.d/lint/portable-uri-mismatches.md b/changes.d/lint/portable-uri-mismatches.md deleted file mode 100644 index de1ad7944..000000000 --- a/changes.d/lint/portable-uri-mismatches.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -links: - '#1157': https://github.com/fedify-dev/fedify/issues/1157 - '#1179': https://github.com/fedify-dev/fedify/pull/1179 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Changed the actor URI mismatch rules to accept the [FEP-ef61] portable - IDs of actors and collections, and the compatible identifiers built from - them, so that applications can use the `getPortable*Uri()` methods of - `Context` in actor dispatchers without disabling these rules. - [[#288], [#1157], [#1179]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/mysql/imported-unreleased.md b/changes.d/mysql/imported-unreleased.md deleted file mode 100644 index 1dc944800..000000000 --- a/changes.d/mysql/imported-unreleased.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#823': https://github.com/fedify-dev/fedify/issues/823 - '#925': https://github.com/fedify-dev/fedify/pull/925 ---- - - Fixed the CommonJS MySQL adapter build so it no longer requires - `@js-temporal/polyfill` at runtime. The build now bundles - `temporal-polyfill`, while type declarations rely on the standard - `esnext.temporal` lib reference. - [[#823], [#925]] diff --git a/changes.d/netlify/blobs-kv-store.md b/changes.d/netlify/blobs-kv-store.md deleted file mode 100644 index 2e71283a2..000000000 --- a/changes.d/netlify/blobs-kv-store.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -links: - '#1029': https://github.com/fedify-dev/fedify/pull/1029 ---- - - Added `NetlifyBlobsKvStore`, a Netlify Blobs-backed key–value store with - expiration, prefix listing, and atomic compare-and-set operations. Netlify - deployments can now persist Fedify state and preserve ordered queue - delivery without a separate database. [[#1010], [#1029] by Jiwon Kwon] diff --git a/changes.d/netlify/imported-unreleased.md b/changes.d/netlify/imported-unreleased.md deleted file mode 100644 index f8e1ffc78..000000000 --- a/changes.d/netlify/imported-unreleased.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -links: - '#930': https://github.com/fedify-dev/fedify/issues/930 - '#934': https://github.com/fedify-dev/fedify/pull/934 ---- - - Added the new *@fedify/netlify* package for processing Fedify message queue - jobs with Netlify Async Workloads. It provides `NetlifyMessageQueue` for - durable event submission and `createNetlifyQueueHandler()` for Netlify - Function consumers, including delayed delivery, native retry delegation, - non-retryable malformed-event handling, durable per-key FIFO ordering, and - explicit recovery for unobservable dead-letter failures. - [[#930], [#934]] diff --git a/changes.d/next.txt b/changes.d/next.txt deleted file mode 100644 index 197c4d5c2..000000000 --- a/changes.d/next.txt +++ /dev/null @@ -1 +0,0 @@ -2.4.0 diff --git a/changes.d/next/hashlink-media-requests.md b/changes.d/next/hashlink-media-requests.md deleted file mode 100644 index 3dfa49978..000000000 --- a/changes.d/next/hashlink-media-requests.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -links: - '#1149': https://github.com/fedify-dev/fedify/issues/1149 - '#1170': https://github.com/fedify-dev/fedify/pull/1170 - '#288': https://github.com/fedify-dev/fedify/issues/288 ---- - - Added support for [FEP-ef61] hashlink media requests, e.g., - `GET /.well-known/apgateway/hl:zQm...`, to `fedifyWith()`. Clients fetch - such media with, e.g., `Accept: image/*`, so these requests were not - passed to Fedify unless they had federation media types in their headers, - and Next.js answered them instead of the hashlink media dispatcher. - `isFederationRequest()` now recognizes them by their paths regardless of - their headers. To make Next.js run the middleware for them, add - `{ source: "/.well-known/apgateway/:path*" }` to the `matcher` of your - *middleware.ts* or *proxy.ts* file. [[#288], [#1149], [#1170]] - - - Added `isHashlinkMediaRequest()` function. [[#288], [#1149], [#1170]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/pglite/pglite-kv-store.md b/changes.d/pglite/pglite-kv-store.md deleted file mode 100644 index b8b37c1c9..000000000 --- a/changes.d/pglite/pglite-kv-store.md +++ /dev/null @@ -1,5 +0,0 @@ - - Added the `@fedify/pglite` package with `PgliteKvStore`, a `KvStore` backed - by an embedded PGlite database. It accepts a caller-created PGlite instance - and is intended for a single PGlite instance in a single runtime isolate; a - message queue is not provided because PGlite does not share data between - processes. [[#1018], [#1020] by ChanHaeng Lee] diff --git a/changes.d/postgres/imported-unreleased.md b/changes.d/postgres/imported-unreleased.md deleted file mode 100644 index 7f3af8368..000000000 --- a/changes.d/postgres/imported-unreleased.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -links: - '#823': https://github.com/fedify-dev/fedify/issues/823 - '#925': https://github.com/fedify-dev/fedify/pull/925 - '#930': https://github.com/fedify-dev/fedify/issues/930 - '#934': https://github.com/fedify-dev/fedify/pull/934 ---- - - Added `PostgresKvStore.cas()`, including atomic creation, replacement, and - deletion with TTL-aware comparison. This allows PostgreSQL-backed stores, - including Netlify Database, to enforce queue ordering and other Fedify CAS - operations. - [[#930], [#934]] - - `PostgresKvStore` now creates crash-safe logged tables by default and - migrates existing unlogged tables during initialization. Transient - unlogged storage remains available with the `unlogged` option. The - one-time migration rewrites and exclusively locks an existing table, so - upgrades with large or busy key–value tables should schedule it - accordingly. - [[#930], [#934]] - - Fixed the CommonJS PostgreSQL adapter build so it no longer requires - `@js-temporal/polyfill` at runtime. The build now bundles - `temporal-polyfill`, while type declarations rely on the standard - `esnext.temporal` lib reference. - [[#823], [#925]] diff --git a/changes.d/redis/atomic-kv-swaps.md b/changes.d/redis/atomic-kv-swaps.md deleted file mode 100644 index 1fe10c9b9..000000000 --- a/changes.d/redis/atomic-kv-swaps.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -links: - '#1163': https://github.com/fedify-dev/fedify/issues/1163 - '#1167': https://github.com/fedify-dev/fedify/pull/1167 ---- - - Added atomic `RedisKvStore.cas()` for standalone Redis and Redis Cluster. - Redis-backed deployments can now use portable inbox forwarding and other - features that need compare-and-swap. Custom codecs must encode equal - values identically, and Redis must permit `EVAL`; deployments that deny - scripting can no longer rely on the previous non-CAS fallback. - [[#1163], [#1167]] diff --git a/changes.d/redis/imported-unreleased.md b/changes.d/redis/imported-unreleased.md deleted file mode 100644 index d37f4d8a2..000000000 --- a/changes.d/redis/imported-unreleased.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#823': https://github.com/fedify-dev/fedify/issues/823 - '#925': https://github.com/fedify-dev/fedify/pull/925 ---- - - Fixed the CommonJS Redis adapter build so it no longer requires - `@js-temporal/polyfill` at runtime. The build now bundles - `temporal-polyfill`, while type declarations rely on the standard - `esnext.temporal` lib reference. - [[#823], [#925]] diff --git a/changes.d/relay/clarify-relay-contract.md b/changes.d/relay/clarify-relay-contract.md deleted file mode 100644 index d3bd5d05d..000000000 --- a/changes.d/relay/clarify-relay-contract.md +++ /dev/null @@ -1,4 +0,0 @@ - - Fixed the relay documentation to use the canonical actor and shared inbox - URIs, distinguish Mastodon-style and LitePub-style subscription behavior, - and explain which deployment responsibilities remain with applications. - [[#899], [#996] by Jiwon Kwon] diff --git a/changes.d/relay/imported-unreleased.md b/changes.d/relay/imported-unreleased.md deleted file mode 100644 index f2e89928a..000000000 --- a/changes.d/relay/imported-unreleased.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#823': https://github.com/fedify-dev/fedify/issues/823 - '#925': https://github.com/fedify-dev/fedify/pull/925 ---- - - Fixed the CommonJS relay build so it no longer requires - `@js-temporal/polyfill` at runtime. The build now bundles - `temporal-polyfill`, while type declarations rely on the standard - `esnext.temporal` lib reference. - [[#823], [#925]] diff --git a/changes.d/sqlite/imported-unreleased.md b/changes.d/sqlite/imported-unreleased.md deleted file mode 100644 index 5ab8fbfca..000000000 --- a/changes.d/sqlite/imported-unreleased.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#823': https://github.com/fedify-dev/fedify/issues/823 - '#925': https://github.com/fedify-dev/fedify/pull/925 ---- - - Fixed the CommonJS SQLite adapter build so it no longer requires - `@js-temporal/polyfill` at runtime. The build now bundles - `temporal-polyfill`, while type declarations rely on the standard - `esnext.temporal` lib reference. - [[#823], [#925]] diff --git a/changes.d/testing/imported-unreleased.md b/changes.d/testing/imported-unreleased.md deleted file mode 100644 index af3f6ca4f..000000000 --- a/changes.d/testing/imported-unreleased.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#823': https://github.com/fedify-dev/fedify/issues/823 - '#925': https://github.com/fedify-dev/fedify/pull/925 ---- - - Fixed the CommonJS testing utilities build so it no longer requires - `@js-temporal/polyfill` at runtime. The build now bundles - `temporal-polyfill`, while type declarations rely on the standard - `esnext.temporal` lib reference. - [[#823], [#925]] diff --git a/changes.d/testing/kv-store-tester.md b/changes.d/testing/kv-store-tester.md deleted file mode 100644 index 994b4eb9d..000000000 --- a/changes.d/testing/kv-store-tester.md +++ /dev/null @@ -1,3 +0,0 @@ - - Added `testKvStore()`, a conformance test suite for `KvStore` - implementations, complementing `testMessageQueue()`. - [[#1018], [#1020] by ChanHaeng Lee] diff --git a/changes.d/testing/object-tombstones.md b/changes.d/testing/object-tombstones.md deleted file mode 100644 index a0550aece..000000000 --- a/changes.d/testing/object-tombstones.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#1112': https://github.com/fedify-dev/fedify/issues/1112 - '#1117': https://github.com/fedify-dev/fedify/pull/1117 ---- - - Changed `getObject()` of the mock context that `createFederation()` - creates to follow `RequestContext.getObject()` of `@fedify/fedify`: it - now returns `null` for a `Tombstone` that the object dispatcher returns, - unless the tombstone is an instance of the requested class or - `{ tombstone: "passthrough" }` is given. [[#1112], [#1117]] diff --git a/changes.d/testing/on-request-finished.md b/changes.d/testing/on-request-finished.md deleted file mode 100644 index 7f658529d..000000000 --- a/changes.d/testing/on-request-finished.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -links: - '#1191': https://github.com/fedify-dev/fedify/issues/1191 - '#1201': https://github.com/fedify-dev/fedify/pull/1201 ---- - - Added support for registering `onRequestFinished()` on mock federations so - applications can reuse their inbox configuration in tests. - [[#1191], [#1201]] diff --git a/changes.d/testing/portable-objects.md b/changes.d/testing/portable-objects.md deleted file mode 100644 index a2eaf5c7d..000000000 --- a/changes.d/testing/portable-objects.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -links: - '#1080': https://github.com/fedify-dev/fedify/pull/1080 - '#1092': https://github.com/fedify-dev/fedify/pull/1092 - '#1099': https://github.com/fedify-dev/fedify/pull/1099 - '#1107': https://github.com/fedify-dev/fedify/issues/1107 - '#1111': https://github.com/fedify-dev/fedify/issues/1111 - '#1114': https://github.com/fedify-dev/fedify/pull/1114 - '#1120': https://github.com/fedify-dev/fedify/pull/1120 - '#1142': https://github.com/fedify-dev/fedify/pull/1142 - '#1143': https://github.com/fedify-dev/fedify/issues/1143 - '#1145': https://github.com/fedify-dev/fedify/pull/1145 - '#1153': https://github.com/fedify-dev/fedify/issues/1153 - '#1161': https://github.com/fedify-dev/fedify/issues/1161 - '#1183': https://github.com/fedify-dev/fedify/pull/1183 - '#1196': https://github.com/fedify-dev/fedify/pull/1196 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#835': https://github.com/fedify-dev/fedify/issues/835 - '#838': https://github.com/fedify-dev/fedify/issues/838 - '#839': https://github.com/fedify-dev/fedify/issues/839 - '#840': https://github.com/fedify-dev/fedify/issues/840 - '#841': https://github.com/fedify-dev/fedify/issues/841 ---- - - Added support for [FEP-ef61] portable objects to the mock federation and - contexts, following the new APIs of `@fedify/fedify`, so that tests can - exercise portable objects without a live gateway. [[#288]] - - - Added the `getPortableActorUri()`, `getPortableObjectUri()`, - `getPortableInboxUri()`, `getPortableOutboxUri()`, - `getPortableFollowingUri()`, `getPortableFollowersUri()`, - `getPortableLikedUri()`, `getPortableFeaturedUri()`, - `getPortableFeaturedTagsUri()`, and `getPortableCollectionUri()` - methods to the mock contexts. They reject `did:key` DIDs that are - not encoded in base58-btc. - [[#835], [#839], [#841], [#1092], [#1111], [#1114], [#1142]] - - - Added the `portable` option to `parseUri()` of the mock contexts. - Without it, `parseUri()` no longer recognizes a portable ID or - compatible identifier whose path starts with `/users/`; with it, - the result has the DID in its `authority` property. It also returns - `null` for `null`. [[#1143], [#1145]] - - - The mock contexts that `createContext()` creates keep - the `verifyPortableObject` property given to them, and their - `lookupObject()` and `traverseCollection()` pass it on. - `createFederation()` accepts a fixture `documentLoader`, - a `contextLoader`, and `verifyPortableObject`, which mock context - lookups use for portable IDs. [[#1107], [#1120], [#1161], [#1196]] - - - Added the `isSignedByAudience()` method to the mock request contexts, - which checks the audience against the actor that - `getSignedKeyOwner()` returns. [[#1153], [#1183]] - - - `federation.createContext()` accepts an explicit `portableRequest` - for a request context, which dispatchers can inspect. - [[#1161], [#1196]] - - - Added the `mapPortableActorId()` method to the setters that - `MockFederation.setActorDispatcher()` returns, the - `mapPortableOwner()` method to the mock custom collection setters, - and the `setHashlinkMediaDispatcher()` method to the mock federation, - which serves hashlink media responses. - [[#838], [#840], [#1080], [#1099], [#1111], [#1142], [#1161], [#1196]] - -[FEP-ef61]: https://w3id.org/fep/ef61 diff --git a/changes.d/vocab-runtime/document-loader-timeout.md b/changes.d/vocab-runtime/document-loader-timeout.md deleted file mode 100644 index f3fea168c..000000000 --- a/changes.d/vocab-runtime/document-loader-timeout.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -links: - '#1131': https://github.com/fedify-dev/fedify/issues/1131 - '#1169': https://github.com/fedify-dev/fedify/pull/1169 ---- - - Changed `getDocumentLoader()` to time out each call after 10 seconds by - default. The time limit covers the whole call, including every redirect - and alternate document it follows and reading the response body. - A call that times out throws a `FetchError` without a response, whose - `cause` is a `DOMException` named `"TimeoutError"`. An `AbortSignal` - passed as the `signal` option still cancels a call as before. - [[#1131], [#1169]] - - - Added `DocumentLoaderFactoryOptions.timeout` option, in milliseconds, - to change the time limit, or to turn it off with `null`. - - - Changed `getDocumentLoader()` to read the body of an error response - before it throws a `FetchError`, at most 1 MiB, so that the time limit - also bounds reading it. `FetchError.response` keeps the body byte for - byte, or only the status and headers if the body is larger than that. - [[#1131], [#1169]] diff --git a/changes.d/vocab-runtime/imported-unreleased.md b/changes.d/vocab-runtime/imported-unreleased.md deleted file mode 100644 index 1f64890dc..000000000 --- a/changes.d/vocab-runtime/imported-unreleased.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -links: - '#810': https://github.com/fedify-dev/fedify/issues/810 - '#912': https://github.com/fedify-dev/fedify/issues/912 - '#913': https://github.com/fedify-dev/fedify/pull/913 - '#914': https://github.com/fedify-dev/fedify/pull/914 ---- - - Added the [FEP-7aa9] JSON-LD context to the preloaded context registry so - FEP-7aa9 documents can be compacted and expanded without fetching the - context remotely. - [[#810], [#914]] - - - Changed `getDocumentLoader()` to reject HTML and XHTML responses that do - not advertise an ActivityPub alternate document with a `FetchError` - instead of attempting to parse the HTML as JSON. This makes remote HTML - error pages surface as document loading failures with the response URL and - content type, rather than generic JSON parser crashes. - [[#912], [#913]] - -[FEP-7aa9]: https://w3id.org/fep/7aa9 diff --git a/changes.d/vocab-runtime/portable-objects.md b/changes.d/vocab-runtime/portable-objects.md deleted file mode 100644 index 1b6bf48cf..000000000 --- a/changes.d/vocab-runtime/portable-objects.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -links: - '#1074': https://github.com/fedify-dev/fedify/pull/1074 - '#1077': https://github.com/fedify-dev/fedify/pull/1077 - '#1084': https://github.com/fedify-dev/fedify/pull/1084 - '#1107': https://github.com/fedify-dev/fedify/issues/1107 - '#1120': https://github.com/fedify-dev/fedify/pull/1120 - '#1151': https://github.com/fedify-dev/fedify/issues/1151 - '#1152': https://github.com/fedify-dev/fedify/issues/1152 - '#1154': https://github.com/fedify-dev/fedify/issues/1154 - '#1159': https://github.com/fedify-dev/fedify/issues/1159 - '#1176': https://github.com/fedify-dev/fedify/issues/1176 - '#1182': https://github.com/fedify-dev/fedify/pull/1182 - '#1186': https://github.com/fedify-dev/fedify/pull/1186 - '#1189': https://github.com/fedify-dev/fedify/pull/1189 - '#1190': https://github.com/fedify-dev/fedify/pull/1190 - '#1198': https://github.com/fedify-dev/fedify/pull/1198 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#826': https://github.com/fedify-dev/fedify/issues/826 - '#827': https://github.com/fedify-dev/fedify/issues/827 - '#828': https://github.com/fedify-dev/fedify/issues/828 - '#829': https://github.com/fedify-dev/fedify/issues/829 - '#830': https://github.com/fedify-dev/fedify/issues/830 - '#831': https://github.com/fedify-dev/fedify/issues/831 - '#833': https://github.com/fedify-dev/fedify/issues/833 - '#834': https://github.com/fedify-dev/fedify/issues/834 - '#836': https://github.com/fedify-dev/fedify/issues/836 - '#850': https://github.com/fedify-dev/fedify/pull/850 - '#915': https://github.com/fedify-dev/fedify/pull/915 - '#924': https://github.com/fedify-dev/fedify/pull/924 - '#926': https://github.com/fedify-dev/fedify/pull/926 - '#928': https://github.com/fedify-dev/fedify/pull/928 - '#935': https://github.com/fedify-dev/fedify/pull/935 ---- - - Added support for [FEP-ef61] portable objects, whose IDs are `ap:` or - `ap+ef61:` URIs with a DID instead of a host, e.g., - `ap://did:key:z6Mk.../actor`. See the - [*Portable objects*][portable objects] chapter of the manual for the - FEP-ef61 profile that Fedify supports. [[#288]] - - - Added `parseIri()`, `formatIri()`, `parseJsonLdId()`, and - `haveSameIriOrigin()`, which parse, format, and compare IRIs, - including portable IDs with decoded or percent-encoded DID - authorities. The `URL` objects that represent portable IDs keep - their DIDs percent-encoded, and `formatIri()` formats them in their - canonical form, e.g., `ap+ef61://did:key:z6Mk.../actor`. Portable - IDs and compatible identifiers whose paths have `.` or `..` - segments, which the `URL` class would remove, are rejected with - a `TypeError`. [[#826], [#850], [#1154], [#1186]] - - - Added `canonicalizePortableUri()` and `arePortableUrisEqual()` for - comparing portable IDs. They accept both schemes with decoded or - percent-encoded DID authorities, normalize them to `ap+ef61:`, and - ignore the query, including `@gateway` location hints. - Fedify deliberately canonicalizes to `ap+ef61:` rather than `ap:`, - which FEP-ef61 currently recommends, and this may change in - Fedify 3.0, so compare portable IDs with - `arePortableUrisEqual()` rather than as strings. - [[#828], [#924], [#1151], [#1198]] - - - Added `getFe34Origin()` and `haveSameFe34Origin()`, which compare - [FEP-fe34] origins: HTTP(S) URLs have their web origins, while - portable IDs and DID URLs have their DIDs as their cryptographic - origins. [[#829], [#926]] - - - Added `exportDidKey()`, `importDidKey()`, and - `parseDidKeyVerificationMethod()` for Ed25519 `did:key` DIDs and - their verification method DID URLs. `exportDidKey()` always - encodes DIDs in base58-btc, as FEP-ef61 requires. [[#827], [#915]] - - - Added `toCompatibleEf61Id()` and `fromCompatibleEf61Id()` for - converting between portable IDs and compatible identifiers, i.e., - HTTP(S) URLs under a gateway's */.well-known/apgateway/* path such as - `https://example.com/.well-known/apgateway/did:key:z6Mk.../actor`, - which software without portable ID support can use. - `fromCompatibleEf61Id()` returns `null` for URLs that are not - compatible identifiers, and throws a `TypeError` for malformed ones, - including those with location hints. Converting a compatible - identifier does not authenticate it. [[#833], [#1074]] - - - Added `isGatewayUrl()` and `parseGatewayUrl()`, which check that - a gateway is an HTTP(S) origin without credentials, a path, a query, - or a fragment, as FEP-ef61 requires. - [[#830], [#928], [#1176], [#1190]] - - - Added `withGatewayHints()`, `withoutGatewayHints()`, and - `getGatewayHints()` to add, remove, and read the `@gateway` location - hints of portable IDs, which tell consumers where to retrieve - a referenced portable actor. [[#1159], [#1189]] - - - Added SHA-256 `digestMultibase` and `hl:` hashlink helpers: - `computeDigestMultibase()`, `parseDigestMultibase()`, - `verifyDigestMultibase()`, `createHashlink()`, `parseHashlink()`, - and `verifyHashlink()`. [[#831], [#935]] - - - Added `fetchPortableMedia()`, which retrieves the media of a portable - object through its owner's gateways, or an HTTP(S) resource directly, - and returns it only after verifying its `digestMultibase`. - It limits the response size and rejects private network addresses by - default. [[#1152], [#1182]] - - - Added the FEP-ef61 JSON-LD context to the preloaded contexts, so that - `gateways` and `digestMultibase` can be compacted and expanded - without fetching the context. [[#830], [#928]] - - - Added the `PortableObjectVerifier`, `PortableObjectVerifierOptions`, - `PortableObjectVerification`, and `PortableObjectReferrer` types, - which describe the `verifyPortableObject` option of property - accessors. A verifier receives a fetched document along with its - final URL, the gateways used, and the chain of objects that referred - to it, and can accept a collection without a proof as `unsecured`. - [[#834], [#836], [#1077], [#1084]] - - - Added the `verifyPortableObject` property to - `PropertyPreprocessorContext`, the default verifier that objects - returned by a property preprocessor should use. [[#1107], [#1120]] - - - Changed the `Accept` header that document loaders send when fetching - ActivityPub objects to - `application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"`, - as ActivityPub and [FEP-ef61] gateways require. Previously, the JSON-LD - media type lacked the ActivityStreams profile. [[#288], [#834], [#1077]] - -[FEP-ef61]: https://w3id.org/fep/ef61 -[portable objects]: https://fedify.dev/manual/portable -[FEP-fe34]: https://w3id.org/fep/fe34 diff --git a/changes.d/vocab-runtime/translation-context.md b/changes.d/vocab-runtime/translation-context.md deleted file mode 100644 index 97e8314d1..000000000 --- a/changes.d/vocab-runtime/translation-context.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -links: - '#1037': https://github.com/fedify-dev/fedify/issues/1037 - '#1038': https://github.com/fedify-dev/fedify/pull/1038 ---- - - Added to preloaded JSON-LD contexts. - [[#1037], [#1038]] diff --git a/changes.d/vocab-tools/conditional-contexts.md b/changes.d/vocab-tools/conditional-contexts.md deleted file mode 100644 index fb9712bd5..000000000 --- a/changes.d/vocab-tools/conditional-contexts.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -links: - '#1037': https://github.com/fedify-dev/fedify/issues/1037 - '#1038': https://github.com/fedify-dev/fedify/pull/1038 ---- - - Added the `extraContext` property schema option to include a JSON-LD - context only when its terms are used, preserving existing output for - objects without the extension. [[#1037], [#1038]] - - Added the `trustEmbeddedObjects` type schema option so embedded metadata - identifiers need not establish trust in linked actors. [[#1037], [#1038]] diff --git a/changes.d/vocab-tools/suppressed-error-log-level.md b/changes.d/vocab-tools/suppressed-error-log-level.md deleted file mode 100644 index 5962d3cbd..000000000 --- a/changes.d/vocab-tools/suppressed-error-log-level.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -links: - '#1035': https://github.com/fedify-dev/fedify/pull/1035 - '#933': https://github.com/fedify-dev/fedify/issues/933 ---- - - Changed suppressed vocabulary fetch and parsing failures to log at the - warning level so that intentionally handled failures are not reported as - application errors. [[#933], [#1035] by Jae Hui Hong] diff --git a/changes.d/vocab/imported-unreleased.md b/changes.d/vocab/imported-unreleased.md deleted file mode 100644 index 20484cf9c..000000000 --- a/changes.d/vocab/imported-unreleased.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -links: - '#754': https://github.com/fedify-dev/fedify/issues/754 - '#810': https://github.com/fedify-dev/fedify/issues/810 - '#823': https://github.com/fedify-dev/fedify/issues/823 - '#914': https://github.com/fedify-dev/fedify/pull/914 - '#925': https://github.com/fedify-dev/fedify/pull/925 - '#927': https://github.com/fedify-dev/fedify/pull/927 ---- - - Added vocabulary support for [FEP-7aa9], including - `FeaturedCollection`, `FeaturedItem`, `FeatureRequest`, and - `FeatureAuthorization`, plus actor `featuredCollections` and - `InteractionPolicy.canFeature` properties. - [[#810], [#914]] - - Added the `Endpoints.uploadMedia` property, the standard ActivityStreams - endpoint for the [ActivityPub Media Upload extension]. - [[#754], [#927]] - - Fixed the CommonJS vocabulary build so it no longer requires - `@js-temporal/polyfill` at runtime. The build now bundles - `temporal-polyfill`, while type declarations rely on the standard - `esnext.temporal` lib reference. - [[#823], [#925]] - -[FEP-7aa9]: https://w3id.org/fep/7aa9 -[ActivityPub Media Upload extension]: https://www.w3.org/wiki/SocialCG/ActivityPub/MediaUpload diff --git a/changes.d/vocab/portable-objects.md b/changes.d/vocab/portable-objects.md deleted file mode 100644 index 13d2f9723..000000000 --- a/changes.d/vocab/portable-objects.md +++ /dev/null @@ -1,165 +0,0 @@ ---- -links: - '#1044': https://github.com/fedify-dev/fedify/issues/1044 - '#1051': https://github.com/fedify-dev/fedify/pull/1051 - '#1077': https://github.com/fedify-dev/fedify/pull/1077 - '#1082': https://github.com/fedify-dev/fedify/pull/1082 - '#1084': https://github.com/fedify-dev/fedify/pull/1084 - '#1090': https://github.com/fedify-dev/fedify/issues/1090 - '#1091': https://github.com/fedify-dev/fedify/pull/1091 - '#1093': https://github.com/fedify-dev/fedify/issues/1093 - '#1097': https://github.com/fedify-dev/fedify/issues/1097 - '#1105': https://github.com/fedify-dev/fedify/pull/1105 - '#1107': https://github.com/fedify-dev/fedify/issues/1107 - '#1120': https://github.com/fedify-dev/fedify/pull/1120 - '#1129': https://github.com/fedify-dev/fedify/issues/1129 - '#1137': https://github.com/fedify-dev/fedify/pull/1137 - '#1147': https://github.com/fedify-dev/fedify/issues/1147 - '#1156': https://github.com/fedify-dev/fedify/issues/1156 - '#1158': https://github.com/fedify-dev/fedify/issues/1158 - '#1160': https://github.com/fedify-dev/fedify/issues/1160 - '#1180': https://github.com/fedify-dev/fedify/pull/1180 - '#1184': https://github.com/fedify-dev/fedify/pull/1184 - '#1194': https://github.com/fedify-dev/fedify/pull/1194 - '#1199': https://github.com/fedify-dev/fedify/pull/1199 - '#1202': https://github.com/fedify-dev/fedify/pull/1202 - '#288': https://github.com/fedify-dev/fedify/issues/288 - '#826': https://github.com/fedify-dev/fedify/issues/826 - '#829': https://github.com/fedify-dev/fedify/issues/829 - '#830': https://github.com/fedify-dev/fedify/issues/830 - '#834': https://github.com/fedify-dev/fedify/issues/834 - '#836': https://github.com/fedify-dev/fedify/issues/836 - '#837': https://github.com/fedify-dev/fedify/issues/837 - '#850': https://github.com/fedify-dev/fedify/pull/850 - '#926': https://github.com/fedify-dev/fedify/pull/926 - '#928': https://github.com/fedify-dev/fedify/pull/928 ---- - - Added support for [FEP-ef61] portable objects, whose IDs are `ap:` or - `ap+ef61:` URIs with a DID instead of a host, e.g., - `ap://did:key:z6Mk.../actor`, and which are retrieved through the - servers listed in their actors' `gateways`. See the - [*Portable objects*][portable objects] chapter of the manual for the - FEP-ef61 profile that Fedify supports. [[#288]] - - - Generated vocabulary classes now accept portable IDs with decoded or - percent-encoded DID authorities wherever an IRI is expected, and - serialize them as canonical `ap+ef61:` IRIs with decoded DID - authorities. Inspecting vocabulary objects, e.g., with - `console.log()`, also shows them in this form. - [[#826], [#850], [#1156], [#1199]] - - - Added the `gateways` property to actor classes, and the - `digestMultibase` property to `Link` and document and media classes. - Gateways are serialized as origins without a trailing slash. - A portable actor that uses the `gateways` term without mapping it in - its JSON-LD context, as tootik does, is also read. - [[#830], [#928], [#1097], [#1202]] - - - Added the optional `Recipient.gateways` property, through which Fedify - delivers activities to portable inboxes. Applications that build - `Recipient` objects by hand, e.g., in followers collection - dispatchers, need to set it for portable actors. [[#1147], [#1180]] - - - Property accessors such as `Create.getObject()` now fetch portable - references through gateways: those in the new `gateways` option, or - else those in the `@gateway` location hints of the reference. A - reference without hints that has the same DID as a portable actor it - was reached from, e.g., the actor's `outbox`, is fetched through that - actor's `gateways`. A fetched object is returned only if its `@id` - identifies the referenced portable object and the verifier given as the - new `verifyPortableObject` option accepts it, typically - `verifyPortableObject()` from `@fedify/fedify`, or a `Context` passed - as the options. Portable references cannot be dereferenced without the - option, and `crossOrigin: "trust"` does not skip these checks. - [[#834], [#1077], [#1093], [#1105]] - - - Property accessors tell the `verifyPortableObject` function where - a portable object was retrieved from and which objects led to it, so - that it can accept a portable collection without a proof if a gateway - that its owner lists served it. Objects embedded in such a collection - are fetched and verified one by one. Added the `crossOrigin`, - `gateways`, and `verifyPortableObject` options to - `TraverseCollectionOptions` as well. [[#836], [#1084]] - - - Added the `verifyPortableObject` option to the constructors, - the `fromJsonLd()` methods, and the `clone()` methods of vocabulary - classes, which sets the verifier that the object's property accessors - use by default. Objects embedded in the parsed document, and objects - that accessors and `traverseCollection()` fetch, get the verifier of - the call or of their parent by default, so that, e.g., - `(await create.getObject(ctx))?.getAttribution()` verifies portable - objects without passing `ctx` again. Having a default verifier does - not mean that an object was verified. Added - the `inheritPortableObjectVerifier` option to property accessors and - `TraverseCollectionOptions` to limit a verifier to a single call. - [[#1107], [#1120], [#1129], [#1137]] - - - Added the `verifyPortableObject` and `gateways` options to - `LookupObjectOptions`. With the former, `lookupObject()` looks up - portable IDs through their `@gateway` location hints or the gateways - given by the latter, compatible identifiers through the gateways they - name, and the handles of portable actors through their WebFinger - responses, trying at most five gateways per lookup. The gateways - that it infers from compatible identifiers, WebFinger responses, and - location hints are passed to the `verifyPortableObject` function as - `gatewayHints`, while `gateways` has the ones given explicitly. - [[#837], [#1082], [#1090], [#1091], [#1158], [#1194]] - - - `getActorHandle()` now supports portable actors. It takes the domain - of a portable actor's handle from the first gateway in its `gateways`, - and returns the handle only if its WebFinger response links back to - the actor. [[#837], [#1082]] - - - Exported the portable object verifier types and other types used in - vocabulary API signatures from `@fedify/vocab`, so that custom - verifiers can be typed without importing `@fedify/vocab-runtime`. - [[#1160], [#1184]] - - - Changed property accessors and `lookupObject()` so that they no longer - trust [FEP-ef61] compatible identifiers, i.e., HTTP(S) URLs under - a gateway's */.well-known/apgateway/* path such as - `https://gw.example/.well-known/apgateway/did:key:z6Mk.../actor`, because - of the origin that serves them. Anyone can serve a compatible identifier - for any DID, so previously anyone could serve an unsigned object that - claimed to be someone else's portable object. - [[#288], [#837], [#1082], [#1090], [#1091], [#1107], [#1120]] - - - With the `verifyPortableObject` option, a compatible identifier is - dereferenced as the portable object it stands for: through the - gateway that it names and then the gateways in the `gateways` option, - only if the option accepts the object. A document fetched from - an ordinary HTTP(S) URL is verified the same way if its final URL is - a compatible identifier or its `@id` is a portable ID. Malformed - compatible identifiers are rejected without a request. - - - Without the option, accessors keep fetching compatible identifiers as - ordinary HTTP(S) URLs, but no longer cache the results in the parent - objects, so that a later call with the option verifies them. - However, accessors of an object whose ID is a portable ID or - a compatible identifier now throw a `TypeError` (or return `null` with - `suppressError: true`) for such references without the option, as - for portable IDs. - - - Accessors no longer trust an embedded object whose `@id` is - a compatible identifier, or a portable ID with a DID other than its - parent's, even with `crossOrigin: "trust"`; they dereference and - verify it on its own. Likewise, `crossOrigin: "trust"` no longer - makes `lookupObject()` return an object with a portable `@id` from - a document URL of another origin. - - - Updated [FEP-fe34] cross-origin checks to understand the cryptographic - origins of [FEP-ef61] portable IDs and DID URLs. Property accessors and - `lookupObject()` now treat `ap:` and `ap+ef61:` IDs and `did:key` - verification method IDs as the same origin when their DIDs match. - [[#288], [#829], [#926]] - - - Changed nested serialization so that an object carrying the signed - JSON-LD representation that `signObject()` retains is embedded with that - exact representation, including its own `@context`, rather than being - rebuilt under the parent's context, so that its proof keeps verifying. - `clone()` never carries the retained representation, because a clone may - differ from the document the proof covers. [[#288], [#1044], [#1051]] - -[FEP-ef61]: https://w3id.org/fep/ef61 -[portable objects]: https://fedify.dev/manual/portable -[FEP-fe34]: https://w3id.org/fep/fe34 diff --git a/changes.d/vocab/translation-metadata.md b/changes.d/vocab/translation-metadata.md deleted file mode 100644 index 7b7bcca0a..000000000 --- a/changes.d/vocab/translation-metadata.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -links: - '#1037': https://github.com/fedify-dev/fedify/issues/1037 - '#1038': https://github.com/fedify-dev/fedify/pull/1038 ---- - - Added vocabulary support for the [FEP-22cd] draft, associating each - translated version with its translators, source object, and optional source - review timestamp. [[#1037], [#1038]] - - - Added `Translation` class with `id`, `language`, `original`, - `sourceUpdated`, `basis`, `url`, and `urls` properties. - - Added `Translation.getTranslator()`/`Translation.translatorId` and - `Translation.getTranslators()`/`Translation.translatorIds` for - accessing credited actors. The constructor accepts `translator` - and `translators` values. - - Added `Object.translations` property, inherited by `Article`, - `Note`, and other object types, for per-language translation - metadata without creating separate posts. - -[FEP-22cd]: https://w3id.org/fep/22cd From c7ba60feadf3b7392fb3c538552ecc3dbb18fc3c Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 02:20:54 +0900 Subject: [PATCH 020/184] Version bump [ci skip] --- CHANGES.md | 6 ++++++ changes.d/next.txt | 1 + packages/adonisjs/package.json | 2 +- packages/amqp/deno.json | 2 +- packages/amqp/package.json | 2 +- packages/astro/deno.json | 2 +- packages/astro/package.json | 2 +- packages/backfill/deno.json | 2 +- packages/backfill/package.json | 2 +- packages/cfworkers/deno.json | 2 +- packages/cfworkers/package.json | 2 +- packages/cli/deno.json | 2 +- packages/cli/package.json | 2 +- packages/create/package.json | 2 +- packages/debugger/deno.json | 2 +- packages/debugger/package.json | 2 +- packages/denokv/deno.json | 2 +- packages/elysia/deno.json | 2 +- packages/elysia/package.json | 2 +- packages/express/deno.json | 2 +- packages/express/package.json | 2 +- packages/fastify/deno.json | 2 +- packages/fastify/package.json | 2 +- packages/fedify/deno.json | 2 +- packages/fedify/package.json | 2 +- packages/fixture/deno.json | 2 +- packages/fresh/deno.json | 2 +- packages/h3/deno.json | 2 +- packages/h3/package.json | 2 +- packages/hono/deno.json | 2 +- packages/hono/package.json | 2 +- packages/init/deno.json | 2 +- packages/init/package.json | 2 +- packages/interaction-controls/deno.json | 2 +- packages/interaction-controls/package.json | 2 +- packages/koa/deno.json | 2 +- packages/koa/package.json | 2 +- packages/lint/deno.json | 2 +- packages/lint/package.json | 2 +- packages/mysql/deno.json | 2 +- packages/mysql/package.json | 2 +- packages/nestjs/package.json | 2 +- packages/netlify/deno.json | 2 +- packages/netlify/package.json | 2 +- packages/next/package.json | 2 +- packages/nuxt/deno.json | 2 +- packages/nuxt/package.json | 2 +- packages/pglite/deno.json | 2 +- packages/pglite/package.json | 2 +- packages/postgres/deno.json | 2 +- packages/postgres/package.json | 2 +- packages/redis/deno.json | 2 +- packages/redis/package.json | 2 +- packages/relay/deno.json | 2 +- packages/relay/package.json | 2 +- packages/solidstart/deno.json | 2 +- packages/solidstart/package.json | 2 +- packages/sqlite/deno.json | 2 +- packages/sqlite/package.json | 2 +- packages/sveltekit/deno.json | 2 +- packages/sveltekit/package.json | 2 +- packages/testing/deno.json | 2 +- packages/testing/package.json | 2 +- packages/uri-template/deno.json | 2 +- packages/uri-template/package.json | 2 +- packages/vocab-runtime/deno.json | 2 +- packages/vocab-runtime/package.json | 2 +- packages/vocab-tools/deno.json | 2 +- packages/vocab-tools/package.json | 2 +- packages/vocab/deno.json | 2 +- packages/vocab/package.json | 2 +- packages/webfinger/deno.json | 2 +- packages/webfinger/package.json | 2 +- 73 files changed, 78 insertions(+), 71 deletions(-) create mode 100644 changes.d/next.txt diff --git a/CHANGES.md b/CHANGES.md index 8e82ebf8e..cdac996b2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,12 @@ Fedify changelog ================ +Version 2.5.0 +------------- + +To be released. + + Version 2.4.0 ------------- diff --git a/changes.d/next.txt b/changes.d/next.txt new file mode 100644 index 000000000..437459cd9 --- /dev/null +++ b/changes.d/next.txt @@ -0,0 +1 @@ +2.5.0 diff --git a/packages/adonisjs/package.json b/packages/adonisjs/package.json index 345e166c2..dfc0a18c4 100644 --- a/packages/adonisjs/package.json +++ b/packages/adonisjs/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/adonisjs", - "version": "2.4.0", + "version": "2.5.0", "description": "Integration package for Fedify with AdonisJS", "keywords": [ "Fedify", diff --git a/packages/amqp/deno.json b/packages/amqp/deno.json index a258c5111..8f7f48f93 100644 --- a/packages/amqp/deno.json +++ b/packages/amqp/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/amqp", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/amqp/package.json b/packages/amqp/package.json index 160983fdf..57d71b953 100644 --- a/packages/amqp/package.json +++ b/packages/amqp/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/amqp", - "version": "2.4.0", + "version": "2.5.0", "description": "AMQP/RabbitMQ driver for Fedify", "keywords": [ "fedify", diff --git a/packages/astro/deno.json b/packages/astro/deno.json index 962ca0b94..747c8aae5 100644 --- a/packages/astro/deno.json +++ b/packages/astro/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/astro", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "imports": {}, "exports": { diff --git a/packages/astro/package.json b/packages/astro/package.json index 47fa046d5..5dfafa064 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/astro", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with Astro", "keywords": [ "Fedify", diff --git a/packages/backfill/deno.json b/packages/backfill/deno.json index f7986eae7..7168c6a1b 100644 --- a/packages/backfill/deno.json +++ b/packages/backfill/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/backfill", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/backfill/package.json b/packages/backfill/package.json index 4e4c4c4fb..e8aed9ca4 100644 --- a/packages/backfill/package.json +++ b/packages/backfill/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/backfill", - "version": "2.4.0", + "version": "2.5.0", "description": "ActivityPub backfill support for Fedify", "keywords": [ "Fedify", diff --git a/packages/cfworkers/deno.json b/packages/cfworkers/deno.json index d5ac79828..5bcafee7c 100644 --- a/packages/cfworkers/deno.json +++ b/packages/cfworkers/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cfworkers", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "imports": { "@cloudflare/workers-types/experimental": "npm:@cloudflare/workers-types@^4.20260511.1/experimental" diff --git a/packages/cfworkers/package.json b/packages/cfworkers/package.json index 22400c114..497b85c24 100644 --- a/packages/cfworkers/package.json +++ b/packages/cfworkers/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/cfworkers", - "version": "2.4.0", + "version": "2.5.0", "description": "Adapt Fedify with Cloudflare Workers", "keywords": [ "Fedify", diff --git a/packages/cli/deno.json b/packages/cli/deno.json index 0847d4340..e6478bd66 100644 --- a/packages/cli/deno.json +++ b/packages/cli/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": "./src/mod.ts", "imports": { diff --git a/packages/cli/package.json b/packages/cli/package.json index 5e6e57ed8..ef4c2350f 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "2.4.0", + "version": "2.5.0", "type": "module", "files": [ "README.md", diff --git a/packages/create/package.json b/packages/create/package.json index 9025b7665..2a94cefc6 100644 --- a/packages/create/package.json +++ b/packages/create/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/create", - "version": "2.4.0", + "version": "2.5.0", "description": "Create a new Fedify application", "keywords": [ "fedify", diff --git a/packages/debugger/deno.json b/packages/debugger/deno.json index e85c35932..fa39b3527 100644 --- a/packages/debugger/deno.json +++ b/packages/debugger/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/debugger", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.tsx" diff --git a/packages/debugger/package.json b/packages/debugger/package.json index cea565924..7ea5c1e94 100644 --- a/packages/debugger/package.json +++ b/packages/debugger/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/debugger", - "version": "2.4.0", + "version": "2.5.0", "description": "Embedded ActivityPub debug dashboard for Fedify", "type": "module", "main": "./dist/mod.cjs", diff --git a/packages/denokv/deno.json b/packages/denokv/deno.json index 4c7052e7c..69130d3f1 100644 --- a/packages/denokv/deno.json +++ b/packages/denokv/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/denokv", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13", diff --git a/packages/elysia/deno.json b/packages/elysia/deno.json index 7f086821a..b09b2fe5a 100644 --- a/packages/elysia/deno.json +++ b/packages/elysia/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/elysia", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/elysia/package.json b/packages/elysia/package.json index ddf2bb880..5b0d62189 100644 --- a/packages/elysia/package.json +++ b/packages/elysia/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/elysia", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with Elysia", "keywords": [ "Fedify", diff --git a/packages/express/deno.json b/packages/express/deno.json index d24d5f86e..7b3103c60 100644 --- a/packages/express/deno.json +++ b/packages/express/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/express", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/express/package.json b/packages/express/package.json index 203b2306f..668d59d24 100644 --- a/packages/express/package.json +++ b/packages/express/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/express", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with Express", "keywords": [ "Fedify", diff --git a/packages/fastify/deno.json b/packages/fastify/deno.json index 1982aea74..1c62ab1af 100644 --- a/packages/fastify/deno.json +++ b/packages/fastify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fastify", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/fastify/package.json b/packages/fastify/package.json index f4dd54ddb..0c31a081d 100644 --- a/packages/fastify/package.json +++ b/packages/fastify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/fastify", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with Fastify", "keywords": [ "Fedify", diff --git a/packages/fedify/deno.json b/packages/fedify/deno.json index e47c772ff..ae6d0ec05 100644 --- a/packages/fedify/deno.json +++ b/packages/fedify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/fedify/package.json b/packages/fedify/package.json index d02bd2402..3e598d42c 100644 --- a/packages/fedify/package.json +++ b/packages/fedify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "2.4.0", + "version": "2.5.0", "description": "An ActivityPub server framework", "keywords": [ "ActivityPub", diff --git a/packages/fixture/deno.json b/packages/fixture/deno.json index d0c0ae1d7..7a7023aa9 100644 --- a/packages/fixture/deno.json +++ b/packages/fixture/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fixture", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/fresh/deno.json b/packages/fresh/deno.json index b454cb469..bd783c872 100644 --- a/packages/fresh/deno.json +++ b/packages/fresh/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fresh", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "imports": { "@fresh/core": "jsr:@fresh/core@^2.1.4", diff --git a/packages/h3/deno.json b/packages/h3/deno.json index 66dda6320..80e0fe924 100644 --- a/packages/h3/deno.json +++ b/packages/h3/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/h3", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/h3/package.json b/packages/h3/package.json index 009e601c1..05327497b 100644 --- a/packages/h3/package.json +++ b/packages/h3/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/h3", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with h3", "keywords": [ "Fedify", diff --git a/packages/hono/deno.json b/packages/hono/deno.json index 3332bdba3..9578d2ee6 100644 --- a/packages/hono/deno.json +++ b/packages/hono/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/hono", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13" diff --git a/packages/hono/package.json b/packages/hono/package.json index a9e4a79d0..a4874ac5b 100644 --- a/packages/hono/package.json +++ b/packages/hono/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/hono", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with Hono", "keywords": [ "Fedify", diff --git a/packages/init/deno.json b/packages/init/deno.json index d050d6401..af6db990d 100644 --- a/packages/init/deno.json +++ b/packages/init/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/init", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": "./src/mod.ts", "imports": { diff --git a/packages/init/package.json b/packages/init/package.json index 8274a1cf4..a4f527717 100644 --- a/packages/init/package.json +++ b/packages/init/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/init", - "version": "2.4.0", + "version": "2.5.0", "description": "Project initializer for Fedify", "keywords": [ "fedify", diff --git a/packages/interaction-controls/deno.json b/packages/interaction-controls/deno.json index 33f63b5d4..59be69eba 100644 --- a/packages/interaction-controls/deno.json +++ b/packages/interaction-controls/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/interaction-controls", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/interaction-controls/package.json b/packages/interaction-controls/package.json index b7eb02b79..3c50abe1e 100644 --- a/packages/interaction-controls/package.json +++ b/packages/interaction-controls/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/interaction-controls", - "version": "2.4.0", + "version": "2.5.0", "description": "Interaction control helpers for Fedify", "keywords": [ "ActivityPub", diff --git a/packages/koa/deno.json b/packages/koa/deno.json index e36724130..c783de175 100644 --- a/packages/koa/deno.json +++ b/packages/koa/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/koa", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/koa/package.json b/packages/koa/package.json index 12c50e3a4..5b3b1550e 100644 --- a/packages/koa/package.json +++ b/packages/koa/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/koa", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with Koa", "keywords": [ "Fedify", diff --git a/packages/lint/deno.json b/packages/lint/deno.json index c056eeee0..7af92643c 100644 --- a/packages/lint/deno.json +++ b/packages/lint/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/lint", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/lint/package.json b/packages/lint/package.json index b58a88c79..6d4f7885a 100644 --- a/packages/lint/package.json +++ b/packages/lint/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/lint", - "version": "2.4.0", + "version": "2.5.0", "description": "Fedify linting rules and plugins", "keywords": [ "Fedify", diff --git a/packages/mysql/deno.json b/packages/mysql/deno.json index 45d1d62bc..2a734867d 100644 --- a/packages/mysql/deno.json +++ b/packages/mysql/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/mysql", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/mysql/package.json b/packages/mysql/package.json index 12edad69c..0e4bbf696 100644 --- a/packages/mysql/package.json +++ b/packages/mysql/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/mysql", - "version": "2.4.0", + "version": "2.5.0", "description": "MySQL/MariaDB drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index 8c3c9d910..65d6954e1 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/nestjs", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with Nest.js", "keywords": [ "Fedify", diff --git a/packages/netlify/deno.json b/packages/netlify/deno.json index 489721a06..0fc5b58a7 100644 --- a/packages/netlify/deno.json +++ b/packages/netlify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/netlify", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "imports": { "@netlify/async-workloads": "npm:@netlify/async-workloads@^0.0.106", diff --git a/packages/netlify/package.json b/packages/netlify/package.json index fab4d0726..e8338f86b 100644 --- a/packages/netlify/package.json +++ b/packages/netlify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/netlify", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with Netlify Async Workloads", "keywords": [ "Fedify", diff --git a/packages/next/package.json b/packages/next/package.json index dc2213ed5..06e61b2e5 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/next", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with Next.js", "keywords": [ "Fedify", diff --git a/packages/nuxt/deno.json b/packages/nuxt/deno.json index c2217c0dc..1b8d924d2 100644 --- a/packages/nuxt/deno.json +++ b/packages/nuxt/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/nuxt", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 664444013..15ab6c595 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/nuxt", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with Nuxt", "keywords": [ "Fedify", diff --git a/packages/pglite/deno.json b/packages/pglite/deno.json index 36794bc0c..017e19640 100644 --- a/packages/pglite/deno.json +++ b/packages/pglite/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/pglite", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/pglite/package.json b/packages/pglite/package.json index 9800d32e3..d98ae14b4 100644 --- a/packages/pglite/package.json +++ b/packages/pglite/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/pglite", - "version": "2.4.0", + "version": "2.5.0", "description": "PGlite driver for Fedify", "keywords": [ "fedify", diff --git a/packages/postgres/deno.json b/packages/postgres/deno.json index cf918f0eb..e6c3a925d 100644 --- a/packages/postgres/deno.json +++ b/packages/postgres/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/postgres", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/postgres/package.json b/packages/postgres/package.json index 9506b8eb2..d1f99ae11 100644 --- a/packages/postgres/package.json +++ b/packages/postgres/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/postgres", - "version": "2.4.0", + "version": "2.5.0", "description": "PostgreSQL drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/redis/deno.json b/packages/redis/deno.json index d7955386a..0d1b6ff16 100644 --- a/packages/redis/deno.json +++ b/packages/redis/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/redis", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/redis/package.json b/packages/redis/package.json index 795ea1c8b..73f49ed6c 100644 --- a/packages/redis/package.json +++ b/packages/redis/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/redis", - "version": "2.4.0", + "version": "2.5.0", "description": "Redis drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/relay/deno.json b/packages/relay/deno.json index ef531e6fa..757f2b07e 100644 --- a/packages/relay/deno.json +++ b/packages/relay/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/relay", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13" diff --git a/packages/relay/package.json b/packages/relay/package.json index 8322d9b41..a4c891f70 100644 --- a/packages/relay/package.json +++ b/packages/relay/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/relay", - "version": "2.4.0", + "version": "2.5.0", "description": "ActivityPub relay support for Fedify", "keywords": [ "Fedify", diff --git a/packages/solidstart/deno.json b/packages/solidstart/deno.json index 64de12a7a..26ffb006c 100644 --- a/packages/solidstart/deno.json +++ b/packages/solidstart/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/solidstart", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/solidstart/package.json b/packages/solidstart/package.json index de3fcdfae..b58325fdc 100644 --- a/packages/solidstart/package.json +++ b/packages/solidstart/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/solidstart", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with SolidStart", "keywords": [ "Fedify", diff --git a/packages/sqlite/deno.json b/packages/sqlite/deno.json index c1b1595e7..cbbc476b7 100644 --- a/packages/sqlite/deno.json +++ b/packages/sqlite/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/sqlite", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/sqlite/package.json b/packages/sqlite/package.json index 2215302f9..a899ed4fc 100644 --- a/packages/sqlite/package.json +++ b/packages/sqlite/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/sqlite", - "version": "2.4.0", + "version": "2.5.0", "description": "SQLite drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/sveltekit/deno.json b/packages/sveltekit/deno.json index f15d02f6a..c7b04d32e 100644 --- a/packages/sveltekit/deno.json +++ b/packages/sveltekit/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/sveltekit", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13", diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index cf109dfe4..02435dc3a 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/sveltekit", - "version": "2.4.0", + "version": "2.5.0", "description": "Integrate Fedify with SvelteKit", "keywords": [ "Fedify", diff --git a/packages/testing/deno.json b/packages/testing/deno.json index 00158c2bf..810bb7e64 100644 --- a/packages/testing/deno.json +++ b/packages/testing/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/testing", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/testing/package.json b/packages/testing/package.json index af50b60e7..a94788ad9 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/testing", - "version": "2.4.0", + "version": "2.5.0", "description": "Testing utilities for Fedify applications", "keywords": [ "fedify", diff --git a/packages/uri-template/deno.json b/packages/uri-template/deno.json index 619aca320..1478e18e9 100644 --- a/packages/uri-template/deno.json +++ b/packages/uri-template/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/uri-template", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/uri-template/package.json b/packages/uri-template/package.json index b360bba8a..f5b8f9d03 100644 --- a/packages/uri-template/package.json +++ b/packages/uri-template/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/uri-template", - "version": "2.4.0", + "version": "2.5.0", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/vocab-runtime/deno.json b/packages/vocab-runtime/deno.json index f83b7014a..3ecd025e3 100644 --- a/packages/vocab-runtime/deno.json +++ b/packages/vocab-runtime/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-runtime", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/vocab-runtime/package.json b/packages/vocab-runtime/package.json index 9082861c3..12e275498 100644 --- a/packages/vocab-runtime/package.json +++ b/packages/vocab-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-runtime", - "version": "2.4.0", + "version": "2.5.0", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/vocab-tools/deno.json b/packages/vocab-tools/deno.json index d8c4b1b9c..197bee5b4 100644 --- a/packages/vocab-tools/deno.json +++ b/packages/vocab-tools/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-tools", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/vocab-tools/package.json b/packages/vocab-tools/package.json index ddf8c7d86..771bfbd09 100644 --- a/packages/vocab-tools/package.json +++ b/packages/vocab-tools/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-tools", - "version": "2.4.0", + "version": "2.5.0", "description": "Code generator for Activity Vocabulary APIs", "homepage": "https://fedify.dev/", "repository": { diff --git a/packages/vocab/deno.json b/packages/vocab/deno.json index 9a19a59df..67c7c7f86 100644 --- a/packages/vocab/deno.json +++ b/packages/vocab/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/vocab/package.json b/packages/vocab/package.json index 4af7b7f07..a3319d4bb 100644 --- a/packages/vocab/package.json +++ b/packages/vocab/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab", - "version": "2.4.0", + "version": "2.5.0", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/webfinger/deno.json b/packages/webfinger/deno.json index ab7cc911c..701763bc2 100644 --- a/packages/webfinger/deno.json +++ b/packages/webfinger/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/webfinger", - "version": "2.4.0", + "version": "2.5.0", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/webfinger/package.json b/packages/webfinger/package.json index 235cace49..9fb98f3f2 100644 --- a/packages/webfinger/package.json +++ b/packages/webfinger/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/webfinger", - "version": "2.4.0", + "version": "2.5.0", "homepage": "https://fedify.dev/", "repository": { "type": "git", From 2c27b04c85397759000ce3c2ed5c8e6b7b2324b1 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Thu, 1 Oct 2026 02:22:15 +0900 Subject: [PATCH 021/184] Version bump [ci skip] --- CHANGES.md | 6 ++++++ changes.d/next.txt | 1 + packages/adonisjs/package.json | 2 +- packages/amqp/deno.json | 2 +- packages/amqp/package.json | 2 +- packages/astro/deno.json | 2 +- packages/astro/package.json | 2 +- packages/backfill/deno.json | 2 +- packages/backfill/package.json | 2 +- packages/cfworkers/deno.json | 2 +- packages/cfworkers/package.json | 2 +- packages/cli/deno.json | 2 +- packages/cli/package.json | 2 +- packages/create/package.json | 2 +- packages/debugger/deno.json | 2 +- packages/debugger/package.json | 2 +- packages/denokv/deno.json | 2 +- packages/elysia/deno.json | 2 +- packages/elysia/package.json | 2 +- packages/express/deno.json | 2 +- packages/express/package.json | 2 +- packages/fastify/deno.json | 2 +- packages/fastify/package.json | 2 +- packages/fedify/deno.json | 2 +- packages/fedify/package.json | 2 +- packages/fixture/deno.json | 2 +- packages/fresh/deno.json | 2 +- packages/h3/deno.json | 2 +- packages/h3/package.json | 2 +- packages/hono/deno.json | 2 +- packages/hono/package.json | 2 +- packages/init/deno.json | 2 +- packages/init/package.json | 2 +- packages/interaction-controls/deno.json | 2 +- packages/interaction-controls/package.json | 2 +- packages/koa/deno.json | 2 +- packages/koa/package.json | 2 +- packages/lint/deno.json | 2 +- packages/lint/package.json | 2 +- packages/mysql/deno.json | 2 +- packages/mysql/package.json | 2 +- packages/nestjs/package.json | 2 +- packages/netlify/deno.json | 2 +- packages/netlify/package.json | 2 +- packages/next/package.json | 2 +- packages/nuxt/deno.json | 2 +- packages/nuxt/package.json | 2 +- packages/pglite/deno.json | 2 +- packages/pglite/package.json | 2 +- packages/postgres/deno.json | 2 +- packages/postgres/package.json | 2 +- packages/redis/deno.json | 2 +- packages/redis/package.json | 2 +- packages/relay/deno.json | 2 +- packages/relay/package.json | 2 +- packages/solidstart/deno.json | 2 +- packages/solidstart/package.json | 2 +- packages/sqlite/deno.json | 2 +- packages/sqlite/package.json | 2 +- packages/sveltekit/deno.json | 2 +- packages/sveltekit/package.json | 2 +- packages/testing/deno.json | 2 +- packages/testing/package.json | 2 +- packages/uri-template/deno.json | 2 +- packages/uri-template/package.json | 2 +- packages/vocab-runtime/deno.json | 2 +- packages/vocab-runtime/package.json | 2 +- packages/vocab-tools/deno.json | 2 +- packages/vocab-tools/package.json | 2 +- packages/vocab/deno.json | 2 +- packages/vocab/package.json | 2 +- packages/webfinger/deno.json | 2 +- packages/webfinger/package.json | 2 +- 73 files changed, 78 insertions(+), 71 deletions(-) create mode 100644 changes.d/next.txt diff --git a/CHANGES.md b/CHANGES.md index 8e82ebf8e..828821633 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,12 @@ Fedify changelog ================ +Version 2.4.1 +------------- + +To be released. + + Version 2.4.0 ------------- diff --git a/changes.d/next.txt b/changes.d/next.txt new file mode 100644 index 000000000..005119baa --- /dev/null +++ b/changes.d/next.txt @@ -0,0 +1 @@ +2.4.1 diff --git a/packages/adonisjs/package.json b/packages/adonisjs/package.json index 345e166c2..2e25164f9 100644 --- a/packages/adonisjs/package.json +++ b/packages/adonisjs/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/adonisjs", - "version": "2.4.0", + "version": "2.4.1", "description": "Integration package for Fedify with AdonisJS", "keywords": [ "Fedify", diff --git a/packages/amqp/deno.json b/packages/amqp/deno.json index a258c5111..7a249f4ee 100644 --- a/packages/amqp/deno.json +++ b/packages/amqp/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/amqp", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/amqp/package.json b/packages/amqp/package.json index 160983fdf..b6294d7f6 100644 --- a/packages/amqp/package.json +++ b/packages/amqp/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/amqp", - "version": "2.4.0", + "version": "2.4.1", "description": "AMQP/RabbitMQ driver for Fedify", "keywords": [ "fedify", diff --git a/packages/astro/deno.json b/packages/astro/deno.json index 962ca0b94..52cb23318 100644 --- a/packages/astro/deno.json +++ b/packages/astro/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/astro", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "imports": {}, "exports": { diff --git a/packages/astro/package.json b/packages/astro/package.json index 47fa046d5..2651e5cf2 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/astro", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with Astro", "keywords": [ "Fedify", diff --git a/packages/backfill/deno.json b/packages/backfill/deno.json index f7986eae7..3cd0276f4 100644 --- a/packages/backfill/deno.json +++ b/packages/backfill/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/backfill", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/backfill/package.json b/packages/backfill/package.json index 4e4c4c4fb..511f99ddb 100644 --- a/packages/backfill/package.json +++ b/packages/backfill/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/backfill", - "version": "2.4.0", + "version": "2.4.1", "description": "ActivityPub backfill support for Fedify", "keywords": [ "Fedify", diff --git a/packages/cfworkers/deno.json b/packages/cfworkers/deno.json index d5ac79828..e319d614a 100644 --- a/packages/cfworkers/deno.json +++ b/packages/cfworkers/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cfworkers", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "imports": { "@cloudflare/workers-types/experimental": "npm:@cloudflare/workers-types@^4.20260511.1/experimental" diff --git a/packages/cfworkers/package.json b/packages/cfworkers/package.json index 22400c114..bdd50a9dc 100644 --- a/packages/cfworkers/package.json +++ b/packages/cfworkers/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/cfworkers", - "version": "2.4.0", + "version": "2.4.1", "description": "Adapt Fedify with Cloudflare Workers", "keywords": [ "Fedify", diff --git a/packages/cli/deno.json b/packages/cli/deno.json index 0847d4340..29664f2d4 100644 --- a/packages/cli/deno.json +++ b/packages/cli/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": "./src/mod.ts", "imports": { diff --git a/packages/cli/package.json b/packages/cli/package.json index 5e6e57ed8..10c9966f8 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/cli", - "version": "2.4.0", + "version": "2.4.1", "type": "module", "files": [ "README.md", diff --git a/packages/create/package.json b/packages/create/package.json index 9025b7665..e3f6d7faa 100644 --- a/packages/create/package.json +++ b/packages/create/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/create", - "version": "2.4.0", + "version": "2.4.1", "description": "Create a new Fedify application", "keywords": [ "fedify", diff --git a/packages/debugger/deno.json b/packages/debugger/deno.json index e85c35932..0e4ca15a7 100644 --- a/packages/debugger/deno.json +++ b/packages/debugger/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/debugger", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.tsx" diff --git a/packages/debugger/package.json b/packages/debugger/package.json index cea565924..876b2d274 100644 --- a/packages/debugger/package.json +++ b/packages/debugger/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/debugger", - "version": "2.4.0", + "version": "2.4.1", "description": "Embedded ActivityPub debug dashboard for Fedify", "type": "module", "main": "./dist/mod.cjs", diff --git a/packages/denokv/deno.json b/packages/denokv/deno.json index 4c7052e7c..603451498 100644 --- a/packages/denokv/deno.json +++ b/packages/denokv/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/denokv", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13", diff --git a/packages/elysia/deno.json b/packages/elysia/deno.json index 7f086821a..3e99c755e 100644 --- a/packages/elysia/deno.json +++ b/packages/elysia/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/elysia", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/elysia/package.json b/packages/elysia/package.json index ddf2bb880..26e98c713 100644 --- a/packages/elysia/package.json +++ b/packages/elysia/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/elysia", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with Elysia", "keywords": [ "Fedify", diff --git a/packages/express/deno.json b/packages/express/deno.json index d24d5f86e..5f8cd5aaf 100644 --- a/packages/express/deno.json +++ b/packages/express/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/express", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/express/package.json b/packages/express/package.json index 203b2306f..6f63b60b8 100644 --- a/packages/express/package.json +++ b/packages/express/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/express", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with Express", "keywords": [ "Fedify", diff --git a/packages/fastify/deno.json b/packages/fastify/deno.json index 1982aea74..087034622 100644 --- a/packages/fastify/deno.json +++ b/packages/fastify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fastify", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/fastify/package.json b/packages/fastify/package.json index f4dd54ddb..34724fc2a 100644 --- a/packages/fastify/package.json +++ b/packages/fastify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/fastify", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with Fastify", "keywords": [ "Fedify", diff --git a/packages/fedify/deno.json b/packages/fedify/deno.json index e47c772ff..094e18820 100644 --- a/packages/fedify/deno.json +++ b/packages/fedify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/fedify/package.json b/packages/fedify/package.json index d02bd2402..55f2602d1 100644 --- a/packages/fedify/package.json +++ b/packages/fedify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/fedify", - "version": "2.4.0", + "version": "2.4.1", "description": "An ActivityPub server framework", "keywords": [ "ActivityPub", diff --git a/packages/fixture/deno.json b/packages/fixture/deno.json index d0c0ae1d7..83e312f8c 100644 --- a/packages/fixture/deno.json +++ b/packages/fixture/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fixture", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/fresh/deno.json b/packages/fresh/deno.json index b454cb469..6bffa6553 100644 --- a/packages/fresh/deno.json +++ b/packages/fresh/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/fresh", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "imports": { "@fresh/core": "jsr:@fresh/core@^2.1.4", diff --git a/packages/h3/deno.json b/packages/h3/deno.json index 66dda6320..10933009f 100644 --- a/packages/h3/deno.json +++ b/packages/h3/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/h3", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/h3/package.json b/packages/h3/package.json index 009e601c1..beda36fca 100644 --- a/packages/h3/package.json +++ b/packages/h3/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/h3", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with h3", "keywords": [ "Fedify", diff --git a/packages/hono/deno.json b/packages/hono/deno.json index 3332bdba3..1b3154af6 100644 --- a/packages/hono/deno.json +++ b/packages/hono/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/hono", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13" diff --git a/packages/hono/package.json b/packages/hono/package.json index a9e4a79d0..cac0aba0b 100644 --- a/packages/hono/package.json +++ b/packages/hono/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/hono", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with Hono", "keywords": [ "Fedify", diff --git a/packages/init/deno.json b/packages/init/deno.json index d050d6401..2aa938c73 100644 --- a/packages/init/deno.json +++ b/packages/init/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/init", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": "./src/mod.ts", "imports": { diff --git a/packages/init/package.json b/packages/init/package.json index 8274a1cf4..43ebfe537 100644 --- a/packages/init/package.json +++ b/packages/init/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/init", - "version": "2.4.0", + "version": "2.4.1", "description": "Project initializer for Fedify", "keywords": [ "fedify", diff --git a/packages/interaction-controls/deno.json b/packages/interaction-controls/deno.json index 33f63b5d4..6fc55fa3a 100644 --- a/packages/interaction-controls/deno.json +++ b/packages/interaction-controls/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/interaction-controls", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/interaction-controls/package.json b/packages/interaction-controls/package.json index b7eb02b79..026b3652b 100644 --- a/packages/interaction-controls/package.json +++ b/packages/interaction-controls/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/interaction-controls", - "version": "2.4.0", + "version": "2.4.1", "description": "Interaction control helpers for Fedify", "keywords": [ "ActivityPub", diff --git a/packages/koa/deno.json b/packages/koa/deno.json index e36724130..369381089 100644 --- a/packages/koa/deno.json +++ b/packages/koa/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/koa", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/koa/package.json b/packages/koa/package.json index 12c50e3a4..e706285ec 100644 --- a/packages/koa/package.json +++ b/packages/koa/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/koa", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with Koa", "keywords": [ "Fedify", diff --git a/packages/lint/deno.json b/packages/lint/deno.json index c056eeee0..36b8f2ff2 100644 --- a/packages/lint/deno.json +++ b/packages/lint/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/lint", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/lint/package.json b/packages/lint/package.json index b58a88c79..4198678b8 100644 --- a/packages/lint/package.json +++ b/packages/lint/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/lint", - "version": "2.4.0", + "version": "2.4.1", "description": "Fedify linting rules and plugins", "keywords": [ "Fedify", diff --git a/packages/mysql/deno.json b/packages/mysql/deno.json index 45d1d62bc..73cec22a6 100644 --- a/packages/mysql/deno.json +++ b/packages/mysql/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/mysql", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/mysql/package.json b/packages/mysql/package.json index 12edad69c..e867e9ca9 100644 --- a/packages/mysql/package.json +++ b/packages/mysql/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/mysql", - "version": "2.4.0", + "version": "2.4.1", "description": "MySQL/MariaDB drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index 8c3c9d910..d3e7d552e 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/nestjs", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with Nest.js", "keywords": [ "Fedify", diff --git a/packages/netlify/deno.json b/packages/netlify/deno.json index 489721a06..8c93e6594 100644 --- a/packages/netlify/deno.json +++ b/packages/netlify/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/netlify", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "imports": { "@netlify/async-workloads": "npm:@netlify/async-workloads@^0.0.106", diff --git a/packages/netlify/package.json b/packages/netlify/package.json index fab4d0726..f5d0ac8fb 100644 --- a/packages/netlify/package.json +++ b/packages/netlify/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/netlify", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with Netlify Async Workloads", "keywords": [ "Fedify", diff --git a/packages/next/package.json b/packages/next/package.json index dc2213ed5..f84a9bf25 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/next", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with Next.js", "keywords": [ "Fedify", diff --git a/packages/nuxt/deno.json b/packages/nuxt/deno.json index c2217c0dc..2cf4980bc 100644 --- a/packages/nuxt/deno.json +++ b/packages/nuxt/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/nuxt", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 664444013..c9eab359f 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/nuxt", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with Nuxt", "keywords": [ "Fedify", diff --git a/packages/pglite/deno.json b/packages/pglite/deno.json index 36794bc0c..2baf88780 100644 --- a/packages/pglite/deno.json +++ b/packages/pglite/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/pglite", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/pglite/package.json b/packages/pglite/package.json index 9800d32e3..531097380 100644 --- a/packages/pglite/package.json +++ b/packages/pglite/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/pglite", - "version": "2.4.0", + "version": "2.4.1", "description": "PGlite driver for Fedify", "keywords": [ "fedify", diff --git a/packages/postgres/deno.json b/packages/postgres/deno.json index cf918f0eb..3c4cf496e 100644 --- a/packages/postgres/deno.json +++ b/packages/postgres/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/postgres", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/postgres/package.json b/packages/postgres/package.json index 9506b8eb2..60c5db45a 100644 --- a/packages/postgres/package.json +++ b/packages/postgres/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/postgres", - "version": "2.4.0", + "version": "2.4.1", "description": "PostgreSQL drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/redis/deno.json b/packages/redis/deno.json index d7955386a..bded43acb 100644 --- a/packages/redis/deno.json +++ b/packages/redis/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/redis", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/redis/package.json b/packages/redis/package.json index 795ea1c8b..aaf64c2a1 100644 --- a/packages/redis/package.json +++ b/packages/redis/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/redis", - "version": "2.4.0", + "version": "2.4.1", "description": "Redis drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/relay/deno.json b/packages/relay/deno.json index ef531e6fa..6551e8fc0 100644 --- a/packages/relay/deno.json +++ b/packages/relay/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/relay", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13" diff --git a/packages/relay/package.json b/packages/relay/package.json index 8322d9b41..380881418 100644 --- a/packages/relay/package.json +++ b/packages/relay/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/relay", - "version": "2.4.0", + "version": "2.4.1", "description": "ActivityPub relay support for Fedify", "keywords": [ "Fedify", diff --git a/packages/solidstart/deno.json b/packages/solidstart/deno.json index 64de12a7a..ddf159661 100644 --- a/packages/solidstart/deno.json +++ b/packages/solidstart/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/solidstart", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/index.ts" diff --git a/packages/solidstart/package.json b/packages/solidstart/package.json index de3fcdfae..3fa23a5eb 100644 --- a/packages/solidstart/package.json +++ b/packages/solidstart/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/solidstart", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with SolidStart", "keywords": [ "Fedify", diff --git a/packages/sqlite/deno.json b/packages/sqlite/deno.json index c1b1595e7..dd1032f9c 100644 --- a/packages/sqlite/deno.json +++ b/packages/sqlite/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/sqlite", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/sqlite/package.json b/packages/sqlite/package.json index 2215302f9..d9dfb49d8 100644 --- a/packages/sqlite/package.json +++ b/packages/sqlite/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/sqlite", - "version": "2.4.0", + "version": "2.4.1", "description": "SQLite drivers for Fedify", "keywords": [ "fedify", diff --git a/packages/sveltekit/deno.json b/packages/sveltekit/deno.json index f15d02f6a..03f3593ea 100644 --- a/packages/sveltekit/deno.json +++ b/packages/sveltekit/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/sveltekit", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "imports": { "@std/assert": "jsr:@std/assert@^1.0.13", diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index cf109dfe4..8f94c9ef9 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/sveltekit", - "version": "2.4.0", + "version": "2.4.1", "description": "Integrate Fedify with SvelteKit", "keywords": [ "Fedify", diff --git a/packages/testing/deno.json b/packages/testing/deno.json index 00158c2bf..964ca40e6 100644 --- a/packages/testing/deno.json +++ b/packages/testing/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/testing", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/testing/package.json b/packages/testing/package.json index af50b60e7..c2ac7487f 100644 --- a/packages/testing/package.json +++ b/packages/testing/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/testing", - "version": "2.4.0", + "version": "2.4.1", "description": "Testing utilities for Fedify applications", "keywords": [ "fedify", diff --git a/packages/uri-template/deno.json b/packages/uri-template/deno.json index 619aca320..59b2f8621 100644 --- a/packages/uri-template/deno.json +++ b/packages/uri-template/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/uri-template", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/uri-template/package.json b/packages/uri-template/package.json index b360bba8a..479b89b8b 100644 --- a/packages/uri-template/package.json +++ b/packages/uri-template/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/uri-template", - "version": "2.4.0", + "version": "2.4.1", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/vocab-runtime/deno.json b/packages/vocab-runtime/deno.json index f83b7014a..2dbea5d25 100644 --- a/packages/vocab-runtime/deno.json +++ b/packages/vocab-runtime/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-runtime", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts", diff --git a/packages/vocab-runtime/package.json b/packages/vocab-runtime/package.json index 9082861c3..0e7b62834 100644 --- a/packages/vocab-runtime/package.json +++ b/packages/vocab-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-runtime", - "version": "2.4.0", + "version": "2.4.1", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/vocab-tools/deno.json b/packages/vocab-tools/deno.json index d8c4b1b9c..4065d4f72 100644 --- a/packages/vocab-tools/deno.json +++ b/packages/vocab-tools/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-tools", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/vocab-tools/package.json b/packages/vocab-tools/package.json index ddf8c7d86..94a2996cd 100644 --- a/packages/vocab-tools/package.json +++ b/packages/vocab-tools/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab-tools", - "version": "2.4.0", + "version": "2.4.1", "description": "Code generator for Activity Vocabulary APIs", "homepage": "https://fedify.dev/", "repository": { diff --git a/packages/vocab/deno.json b/packages/vocab/deno.json index 9a19a59df..391e39c1f 100644 --- a/packages/vocab/deno.json +++ b/packages/vocab/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/vocab/package.json b/packages/vocab/package.json index 4af7b7f07..949e6daa6 100644 --- a/packages/vocab/package.json +++ b/packages/vocab/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/vocab", - "version": "2.4.0", + "version": "2.4.1", "homepage": "https://fedify.dev/", "repository": { "type": "git", diff --git a/packages/webfinger/deno.json b/packages/webfinger/deno.json index ab7cc911c..639ac405f 100644 --- a/packages/webfinger/deno.json +++ b/packages/webfinger/deno.json @@ -1,6 +1,6 @@ { "name": "@fedify/webfinger", - "version": "2.4.0", + "version": "2.4.1", "license": "MIT", "exports": { ".": "./src/mod.ts" diff --git a/packages/webfinger/package.json b/packages/webfinger/package.json index 235cace49..0ab023b5d 100644 --- a/packages/webfinger/package.json +++ b/packages/webfinger/package.json @@ -1,6 +1,6 @@ { "name": "@fedify/webfinger", - "version": "2.4.0", + "version": "2.4.1", "homepage": "https://fedify.dev/", "repository": { "type": "git", From b640ce7f4a8d31c8252fb2ff91d0a99b47067899 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 2 Oct 2026 03:59:57 +0000 Subject: [PATCH 022/184] Update sponsors --- SPONSORS.md | 2 +- packages/fedify/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SPONSORS.md b/SPONSORS.md index a10c324ab..216ae28b0 100644 --- a/SPONSORS.md +++ b/SPONSORS.md @@ -24,8 +24,8 @@ Corporate sponsors Supporters ---------- -- [tkgka](https://opencollective.com/tkgka) - [Blaine](https://opencollective.com/blaine) +- [tkgka](https://opencollective.com/tkgka) - [Erick González Aguilar](https://opencollective.com/erick-gonzalez-aguilar) - [Daniel Supernault](https://pixelfed.org/) diff --git a/packages/fedify/README.md b/packages/fedify/README.md index 866cd5fde..87955c6c4 100644 --- a/packages/fedify/README.md +++ b/packages/fedify/README.md @@ -229,8 +229,8 @@ financial contributors:[^2] ### Supporters -- [tkgka](https://opencollective.com/tkgka) - [Blaine](https://opencollective.com/blaine) +- [tkgka](https://opencollective.com/tkgka) - [Erick González Aguilar](https://opencollective.com/erick-gonzalez-aguilar) - [Daniel Supernault](https://pixelfed.org/) From cea807f9bbb5a5bc8f262d9c3a7977b6aa7d1f4a Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Fri, 2 Oct 2026 17:01:19 +0900 Subject: [PATCH 023/184] Keep vocabulary property arrays independent Clones shared property arrays with their sources, so dereferencing a clone replaced values on the original without updating its trust state or cached JSON-LD. Plural constructor and clone inputs also retained caller-owned arrays. Copy arrays at these three ownership boundaries. Keep nested objects and URLs shared, preserve sparse inputs, and retain the public API and trust policy. Cover lookup and serialization isolation, caller and frozen arrays, cache reuse, and embedded object identity in regressions. Regenerate all runtime snapshots and add changelog fragments. Fixes https://github.com/fedify-dev/fedify/issues/1207 Assisted-by: Codex:gpt-6-astra Assisted-by: Claude Code:claude-fable-5-1 --- CHANGES.md | 17 + .../vocab-tools/clone-array-ownership.md | 8 + changes.d/vocab/clone-array-ownership.md | 10 + .../src/__snapshots__/class.test.ts.deno.snap | 902 ++++++++++-------- .../src/__snapshots__/class.test.ts.node.snap | 902 ++++++++++-------- .../src/__snapshots__/class.test.ts.snap | 902 ++++++++++-------- packages/vocab-tools/src/constructor.ts | 9 +- packages/vocab/src/vocab.test.ts | 212 ++++ 8 files changed, 1704 insertions(+), 1258 deletions(-) create mode 100644 changes.d/vocab-tools/clone-array-ownership.md create mode 100644 changes.d/vocab/clone-array-ownership.md diff --git a/CHANGES.md b/CHANGES.md index c21733fd1..025e6dc1e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,23 @@ Version 2.0.31 To be released. +### @fedify/vocab + + - Fixed shared property arrays in vocabulary objects so dereferencing a + clone no longer changes its source's properties or serialization. + Constructors and `clone()` also copy supplied plural-value arrays, + allowing frozen arrays and preventing changes to the caller's arrays. + Nested objects and URLs retain their identity. [[#1207], [#1208]] + +[#1207]: https://github.com/fedify-dev/fedify/issues/1207 +[#1208]: https://github.com/fedify-dev/fedify/pull/1208 + +### @fedify/vocab-tools + + - Fixed generated constructors and `clone()` methods to copy property + arrays, preventing a clone's remote lookups from changing its source and + preserving arrays supplied by callers. [[#1207], [#1208]] + Version 2.0.30 -------------- diff --git a/changes.d/vocab-tools/clone-array-ownership.md b/changes.d/vocab-tools/clone-array-ownership.md new file mode 100644 index 000000000..f652906e1 --- /dev/null +++ b/changes.d/vocab-tools/clone-array-ownership.md @@ -0,0 +1,8 @@ +--- +links: + '#1207': https://github.com/fedify-dev/fedify/issues/1207 + '#1208': https://github.com/fedify-dev/fedify/pull/1208 +--- + - Fixed generated constructors and `clone()` methods to copy property + arrays, preventing a clone's remote lookups from changing its source and + preserving arrays supplied by callers. [[#1207], [#1208]] diff --git a/changes.d/vocab/clone-array-ownership.md b/changes.d/vocab/clone-array-ownership.md new file mode 100644 index 000000000..c6bbd8dca --- /dev/null +++ b/changes.d/vocab/clone-array-ownership.md @@ -0,0 +1,10 @@ +--- +links: + '#1207': https://github.com/fedify-dev/fedify/issues/1207 + '#1208': https://github.com/fedify-dev/fedify/pull/1208 +--- + - Fixed shared property arrays in vocabulary objects so dereferencing a + clone no longer changes its source's properties or serialization. + Constructors and `clone()` also copy supplied plural-value arrays, + allowing frozen arrays and preventing changes to the caller's arrays. + Nested objects and URLs retain their identity. [[#1207], [#1208]] diff --git a/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap b/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap index 3bd349750..0e836653c 100644 --- a/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap +++ b/packages/vocab-tools/src/__snapshots__/class.test.ts.deno.snap @@ -241,7 +241,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.attachments) && values.attachments.every(v => v instanceof Object || v instanceof Link || v instanceof PropertyValue || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = values.attachments; + this.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = values.attachments.slice(); for (let i = 0; i < values.attachments.length; i++) { this.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment.add(i); @@ -281,7 +281,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.attributions) && values.attributions.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = values.attributions; + this.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = values.attributions.slice(); for (let i = 0; i < values.attributions.length; i++) { this.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo.add(i); @@ -321,7 +321,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.audiences) && values.audiences.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = values.audiences; + this.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = values.audiences.slice(); for (let i = 0; i < values.audiences.length; i++) { this.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience.add(i); @@ -361,7 +361,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.contents) && values.contents.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents; + this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents.slice(); } else { throw new TypeError( @@ -376,7 +376,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.contexts) && values.contexts.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = values.contexts; + this.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = values.contexts.slice(); for (let i = 0; i < values.contexts.length; i++) { this.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context.add(i); @@ -416,7 +416,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.names) && values.names.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names; + this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names.slice(); } else { throw new TypeError( @@ -444,7 +444,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.generators) && values.generators.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = values.generators; + this.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = values.generators.slice(); for (let i = 0; i < values.generators.length; i++) { this.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator.add(i); @@ -484,7 +484,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.icons) && values.icons.every(v => v instanceof Image || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = values.icons; + this.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = values.icons.slice(); for (let i = 0; i < values.icons.length; i++) { this.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon.add(i); @@ -524,7 +524,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.images) && values.images.every(v => v instanceof Image || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = values.images; + this.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = values.images.slice(); for (let i = 0; i < values.images.length; i++) { this.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image.add(i); @@ -564,7 +564,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.replyTargets) && values.replyTargets.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = values.replyTargets; + this.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = values.replyTargets.slice(); for (let i = 0; i < values.replyTargets.length; i++) { this.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo.add(i); @@ -604,7 +604,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.locations) && values.locations.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = values.locations; + this.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = values.locations.slice(); for (let i = 0; i < values.locations.length; i++) { this.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location.add(i); @@ -644,7 +644,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.previews) && values.previews.every(v => v instanceof Link || v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews; + this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews.slice(); for (let i = 0; i < values.previews.length; i++) { this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview.add(i); @@ -762,7 +762,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.summaries) && values.summaries.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = values.summaries; + this.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = values.summaries.slice(); } else { throw new TypeError( @@ -777,7 +777,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.tags) && values.tags.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = values.tags; + this.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = values.tags.slice(); for (let i = 0; i < values.tags.length; i++) { this.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag.add(i); @@ -830,7 +830,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.urls) && values.urls.every(v => v instanceof URL || v instanceof Link)) { // @ts-ignore: type is checked above. - this.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = values.urls; + this.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = values.urls.slice(); } else { throw new TypeError( @@ -866,7 +866,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.tos) && values.tos.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = values.tos; + this.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = values.tos.slice(); for (let i = 0; i < values.tos.length; i++) { this.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to.add(i); @@ -906,7 +906,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.btos) && values.btos.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = values.btos; + this.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = values.btos.slice(); for (let i = 0; i < values.btos.length; i++) { this.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto.add(i); @@ -946,7 +946,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.ccs) && values.ccs.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = values.ccs; + this.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = values.ccs.slice(); for (let i = 0; i < values.ccs.length; i++) { this.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc.add(i); @@ -986,7 +986,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.bccs) && values.bccs.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = values.bccs; + this.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = values.bccs.slice(); for (let i = 0; i < values.bccs.length; i++) { this.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc.add(i); @@ -1078,7 +1078,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.proofs) && values.proofs.every(v => v instanceof DataIntegrityProof || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = values.proofs; + this.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = values.proofs.slice(); for (let i = 0; i < values.proofs.length; i++) { this.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof.add(i); @@ -1097,7 +1097,8 @@ proofs?: (DataIntegrityProof | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -1141,13 +1142,13 @@ proofs?: (DataIntegrityProof | URL)[];} { id: values.id ?? this.id }, options ); - clone.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = this.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment;clone.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment = new Set(this.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment); + clone.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = this.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment.slice();clone.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment = new Set(this.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment); if (\\"attachments\\" in values && values.attachments != null) { if (Array.isArray(values.attachments) && values.attachments.every(v => v instanceof Object || v instanceof Link || v instanceof PropertyValue || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = values.attachments; + clone.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = values.attachments.slice(); clone.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment = new Set(); for (let i = 0; i < values.attachments.length; i++) { @@ -1161,7 +1162,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = this.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo;clone.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = new Set(this.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo); + clone.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = this.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo.slice();clone.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = new Set(this.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo); if (\\"attribution\\" in values && values.attribution != null) { if (values.attribution instanceof Application || values.attribution instanceof Group || values.attribution instanceof Organization || values.attribution instanceof Person || values.attribution instanceof Service || values.attribution instanceof URL) { // @ts-ignore: type is checked above. @@ -1188,7 +1189,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.attributions) && values.attributions.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = values.attributions; + clone.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = values.attributions.slice(); clone.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = new Set(); for (let i = 0; i < values.attributions.length; i++) { @@ -1202,7 +1203,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = this.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience;clone.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = new Set(this.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience); + clone.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = this.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience.slice();clone.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = new Set(this.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience); if (\\"audience\\" in values && values.audience != null) { if (values.audience instanceof Object || values.audience instanceof URL) { // @ts-ignore: type is checked above. @@ -1229,7 +1230,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.audiences) && values.audiences.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = values.audiences; + clone.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = values.audiences.slice(); clone.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = new Set(); for (let i = 0; i < values.audiences.length; i++) { @@ -1243,7 +1244,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content; + clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content.slice(); if (\\"content\\" in values && values.content != null) { if (typeof values.content === \\"string\\" || values.content instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -1270,7 +1271,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.contents) && values.contents.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents; + clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents.slice(); } else { throw new TypeError( @@ -1279,13 +1280,13 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = this.#_3mhZzGXSpQ431mBSz2kvych22v4e_context;clone.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context = new Set(this.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context); + clone.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = this.#_3mhZzGXSpQ431mBSz2kvych22v4e_context.slice();clone.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context = new Set(this.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context); if (\\"contexts\\" in values && values.contexts != null) { if (Array.isArray(values.contexts) && values.contexts.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = values.contexts; + clone.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = values.contexts.slice(); clone.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context = new Set(); for (let i = 0; i < values.contexts.length; i++) { @@ -1299,7 +1300,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name.slice(); if (\\"name\\" in values && values.name != null) { if (typeof values.name === \\"string\\" || values.name instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -1326,7 +1327,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.names) && values.names.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names.slice(); } else { throw new TypeError( @@ -1335,7 +1336,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_219RwDanjScTv5tYCjwGZVCM7KZ9_endTime = this.#_219RwDanjScTv5tYCjwGZVCM7KZ9_endTime; + clone.#_219RwDanjScTv5tYCjwGZVCM7KZ9_endTime = this.#_219RwDanjScTv5tYCjwGZVCM7KZ9_endTime.slice(); if (\\"endTime\\" in values && values.endTime != null) { if (isTemporalInstant(values.endTime)) { // @ts-ignore: type is checked above. @@ -1348,13 +1349,13 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = this.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator;clone.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator = new Set(this.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator); + clone.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = this.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator.slice();clone.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator = new Set(this.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator); if (\\"generators\\" in values && values.generators != null) { if (Array.isArray(values.generators) && values.generators.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = values.generators; + clone.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = values.generators.slice(); clone.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator = new Set(); for (let i = 0; i < values.generators.length; i++) { @@ -1368,7 +1369,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = this.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon;clone.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = new Set(this.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon); + clone.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = this.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon.slice();clone.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = new Set(this.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon); if (\\"icon\\" in values && values.icon != null) { if (values.icon instanceof Image || values.icon instanceof URL) { // @ts-ignore: type is checked above. @@ -1395,7 +1396,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.icons) && values.icons.every(v => v instanceof Image || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = values.icons; + clone.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = values.icons.slice(); clone.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = new Set(); for (let i = 0; i < values.icons.length; i++) { @@ -1409,7 +1410,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = this.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image;clone.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = new Set(this.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image); + clone.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = this.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image.slice();clone.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = new Set(this.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image); if (\\"image\\" in values && values.image != null) { if (values.image instanceof Image || values.image instanceof URL) { // @ts-ignore: type is checked above. @@ -1436,7 +1437,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.images) && values.images.every(v => v instanceof Image || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = values.images; + clone.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = values.images.slice(); clone.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = new Set(); for (let i = 0; i < values.images.length; i++) { @@ -1450,7 +1451,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = this.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo;clone.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = new Set(this.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo); + clone.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = this.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo.slice();clone.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = new Set(this.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo); if (\\"replyTarget\\" in values && values.replyTarget != null) { if (values.replyTarget instanceof Object || values.replyTarget instanceof Link || values.replyTarget instanceof URL) { // @ts-ignore: type is checked above. @@ -1477,7 +1478,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.replyTargets) && values.replyTargets.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = values.replyTargets; + clone.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = values.replyTargets.slice(); clone.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = new Set(); for (let i = 0; i < values.replyTargets.length; i++) { @@ -1491,7 +1492,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = this.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location;clone.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = new Set(this.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location); + clone.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = this.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location.slice();clone.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = new Set(this.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location); if (\\"location\\" in values && values.location != null) { if (values.location instanceof Object || values.location instanceof Link || values.location instanceof URL) { // @ts-ignore: type is checked above. @@ -1518,7 +1519,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.locations) && values.locations.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = values.locations; + clone.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = values.locations.slice(); clone.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = new Set(); for (let i = 0; i < values.locations.length; i++) { @@ -1532,7 +1533,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview;clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview); + clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview.slice();clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview); if (\\"preview\\" in values && values.preview != null) { if (values.preview instanceof Link || values.preview instanceof Object || values.preview instanceof URL) { // @ts-ignore: type is checked above. @@ -1559,7 +1560,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.previews) && values.previews.every(v => v instanceof Link || v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews; + clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews.slice(); clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(); for (let i = 0; i < values.previews.length; i++) { @@ -1573,7 +1574,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_5e258TDXtuhaFRPZiGoDfEpjdMr_published = this.#_5e258TDXtuhaFRPZiGoDfEpjdMr_published; + clone.#_5e258TDXtuhaFRPZiGoDfEpjdMr_published = this.#_5e258TDXtuhaFRPZiGoDfEpjdMr_published.slice(); if (\\"published\\" in values && values.published != null) { if (isTemporalInstant(values.published)) { // @ts-ignore: type is checked above. @@ -1586,7 +1587,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_7UpwM3JWcXhADcscukEehBorf6k_replies = this.#_7UpwM3JWcXhADcscukEehBorf6k_replies;clone.#_trust_7UpwM3JWcXhADcscukEehBorf6k_replies = new Set(this.#_trust_7UpwM3JWcXhADcscukEehBorf6k_replies); + clone.#_7UpwM3JWcXhADcscukEehBorf6k_replies = this.#_7UpwM3JWcXhADcscukEehBorf6k_replies.slice();clone.#_trust_7UpwM3JWcXhADcscukEehBorf6k_replies = new Set(this.#_trust_7UpwM3JWcXhADcscukEehBorf6k_replies); if (\\"replies\\" in values && values.replies != null) { if (values.replies instanceof Collection || values.replies instanceof URL) { // @ts-ignore: type is checked above. @@ -1599,7 +1600,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3kAfck9PcEYt2L7xug5y99YPbANs_shares = this.#_3kAfck9PcEYt2L7xug5y99YPbANs_shares;clone.#_trust_3kAfck9PcEYt2L7xug5y99YPbANs_shares = new Set(this.#_trust_3kAfck9PcEYt2L7xug5y99YPbANs_shares); + clone.#_3kAfck9PcEYt2L7xug5y99YPbANs_shares = this.#_3kAfck9PcEYt2L7xug5y99YPbANs_shares.slice();clone.#_trust_3kAfck9PcEYt2L7xug5y99YPbANs_shares = new Set(this.#_trust_3kAfck9PcEYt2L7xug5y99YPbANs_shares); if (\\"shares\\" in values && values.shares != null) { if (values.shares instanceof Collection || values.shares instanceof URL) { // @ts-ignore: type is checked above. @@ -1612,7 +1613,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes = this.#_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes;clone.#_trust_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes = new Set(this.#_trust_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes); + clone.#_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes = this.#_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes.slice();clone.#_trust_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes = new Set(this.#_trust_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes); if (\\"likes\\" in values && values.likes != null) { if (values.likes instanceof Collection || values.likes instanceof URL) { // @ts-ignore: type is checked above. @@ -1625,7 +1626,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions = this.#_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions;clone.#_trust_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions = new Set(this.#_trust_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions); + clone.#_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions = this.#_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions.slice();clone.#_trust_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions = new Set(this.#_trust_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions); if (\\"emojiReactions\\" in values && values.emojiReactions != null) { if (values.emojiReactions instanceof Collection || values.emojiReactions instanceof URL) { // @ts-ignore: type is checked above. @@ -1638,7 +1639,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_2w3Jmue4up8iVDUA51WZqomEF438_startTime = this.#_2w3Jmue4up8iVDUA51WZqomEF438_startTime; + clone.#_2w3Jmue4up8iVDUA51WZqomEF438_startTime = this.#_2w3Jmue4up8iVDUA51WZqomEF438_startTime.slice(); if (\\"startTime\\" in values && values.startTime != null) { if (isTemporalInstant(values.startTime)) { // @ts-ignore: type is checked above. @@ -1651,7 +1652,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = this.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary; + clone.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = this.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary.slice(); if (\\"summary\\" in values && values.summary != null) { if (typeof values.summary === \\"string\\" || values.summary instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -1678,7 +1679,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.summaries) && values.summaries.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = values.summaries; + clone.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = values.summaries.slice(); } else { throw new TypeError( @@ -1687,13 +1688,13 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = this.#_5chuqj6s95p5gg2sk1HntGfarRf_tag;clone.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag = new Set(this.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag); + clone.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = this.#_5chuqj6s95p5gg2sk1HntGfarRf_tag.slice();clone.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag = new Set(this.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag); if (\\"tags\\" in values && values.tags != null) { if (Array.isArray(values.tags) && values.tags.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = values.tags; + clone.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = values.tags.slice(); clone.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag = new Set(); for (let i = 0; i < values.tags.length; i++) { @@ -1707,7 +1708,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_385aB7ySixcf5Un6z3VsWmThgCzQ_updated = this.#_385aB7ySixcf5Un6z3VsWmThgCzQ_updated; + clone.#_385aB7ySixcf5Un6z3VsWmThgCzQ_updated = this.#_385aB7ySixcf5Un6z3VsWmThgCzQ_updated.slice(); if (\\"updated\\" in values && values.updated != null) { if (isTemporalInstant(values.updated)) { // @ts-ignore: type is checked above. @@ -1720,7 +1721,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = this.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url; + clone.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = this.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url.slice(); if (\\"url\\" in values && values.url != null) { if (values.url instanceof URL || values.url instanceof Link) { // @ts-ignore: type is checked above. @@ -1747,7 +1748,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.urls) && values.urls.every(v => v instanceof URL || v instanceof Link)) { // @ts-ignore: type is checked above. - clone.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = values.urls; + clone.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = values.urls.slice(); } else { throw new TypeError( @@ -1756,7 +1757,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = this.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to;clone.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = new Set(this.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to); + clone.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = this.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to.slice();clone.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = new Set(this.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to); if (\\"to\\" in values && values.to != null) { if (values.to instanceof Object || values.to instanceof URL) { // @ts-ignore: type is checked above. @@ -1783,7 +1784,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.tos) && values.tos.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = values.tos; + clone.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = values.tos.slice(); clone.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = new Set(); for (let i = 0; i < values.tos.length; i++) { @@ -1797,7 +1798,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = this.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto;clone.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = new Set(this.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto); + clone.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = this.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto.slice();clone.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = new Set(this.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto); if (\\"bto\\" in values && values.bto != null) { if (values.bto instanceof Object || values.bto instanceof URL) { // @ts-ignore: type is checked above. @@ -1824,7 +1825,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.btos) && values.btos.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = values.btos; + clone.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = values.btos.slice(); clone.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = new Set(); for (let i = 0; i < values.btos.length; i++) { @@ -1838,7 +1839,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = this.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc;clone.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = new Set(this.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc); + clone.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = this.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc.slice();clone.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = new Set(this.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc); if (\\"cc\\" in values && values.cc != null) { if (values.cc instanceof Object || values.cc instanceof URL) { // @ts-ignore: type is checked above. @@ -1865,7 +1866,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.ccs) && values.ccs.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = values.ccs; + clone.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = values.ccs.slice(); clone.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = new Set(); for (let i = 0; i < values.ccs.length; i++) { @@ -1879,7 +1880,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = this.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc;clone.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = new Set(this.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc); + clone.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = this.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc.slice();clone.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = new Set(this.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc); if (\\"bcc\\" in values && values.bcc != null) { if (values.bcc instanceof Object || values.bcc instanceof URL) { // @ts-ignore: type is checked above. @@ -1906,7 +1907,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.bccs) && values.bccs.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = values.bccs; + clone.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = values.bccs.slice(); clone.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = new Set(); for (let i = 0; i < values.bccs.length; i++) { @@ -1920,7 +1921,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType; + clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType.slice(); if (\\"mediaType\\" in values && values.mediaType != null) { if (typeof values.mediaType === \\"string\\") { // @ts-ignore: type is checked above. @@ -1933,7 +1934,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3bNvLMBN1bCJETiTihM3wvi1B2JX_duration = this.#_3bNvLMBN1bCJETiTihM3wvi1B2JX_duration; + clone.#_3bNvLMBN1bCJETiTihM3wvi1B2JX_duration = this.#_3bNvLMBN1bCJETiTihM3wvi1B2JX_duration.slice(); if (\\"duration\\" in values && values.duration != null) { if (isTemporalDuration(values.duration)) { // @ts-ignore: type is checked above. @@ -1946,7 +1947,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_u8gdcDTtChQ4tbSQMXc4cYWyum7_sensitive = this.#_u8gdcDTtChQ4tbSQMXc4cYWyum7_sensitive; + clone.#_u8gdcDTtChQ4tbSQMXc4cYWyum7_sensitive = this.#_u8gdcDTtChQ4tbSQMXc4cYWyum7_sensitive.slice(); if (\\"sensitive\\" in values && values.sensitive != null) { if (typeof values.sensitive === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -1959,7 +1960,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_2ZwCFoS787v8y8bXKjMoE6MAbrEB_source = this.#_2ZwCFoS787v8y8bXKjMoE6MAbrEB_source; + clone.#_2ZwCFoS787v8y8bXKjMoE6MAbrEB_source = this.#_2ZwCFoS787v8y8bXKjMoE6MAbrEB_source.slice(); if (\\"source\\" in values && values.source != null) { if (values.source instanceof Source) { // @ts-ignore: type is checked above. @@ -1972,7 +1973,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = this.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof;clone.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = new Set(this.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof); + clone.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = this.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof.slice();clone.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = new Set(this.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof); if (\\"proof\\" in values && values.proof != null) { if (values.proof instanceof DataIntegrityProof || values.proof instanceof URL) { // @ts-ignore: type is checked above. @@ -1999,7 +2000,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.proofs) && values.proofs.every(v => v instanceof DataIntegrityProof || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = values.proofs; + clone.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = values.proofs.slice(); clone.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = new Set(); for (let i = 0; i < values.proofs.length; i++) { @@ -11823,7 +11824,8 @@ proofs?: (DataIntegrityProof | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -12185,7 +12187,8 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -12223,7 +12226,7 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as ChatMessage;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl; + const clone = super.clone(values, options) as unknown as ChatMessage;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl.slice(); if (\\"quoteUrl\\" in values && values.quoteUrl != null) { if (values.quoteUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -12720,7 +12723,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.actors) && values.actors.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = values.actors; + this.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = values.actors.slice(); for (let i = 0; i < values.actors.length; i++) { this.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor.add(i); @@ -12760,7 +12763,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.objects) && values.objects.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects; + this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects.slice(); for (let i = 0; i < values.objects.length; i++) { this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object.add(i); @@ -12800,7 +12803,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.targets) && values.targets.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = values.targets; + this.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = values.targets.slice(); for (let i = 0; i < values.targets.length; i++) { this.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target.add(i); @@ -12840,7 +12843,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.results) && values.results.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = values.results; + this.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = values.results.slice(); for (let i = 0; i < values.results.length; i++) { this.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result.add(i); @@ -12880,7 +12883,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.origins) && values.origins.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = values.origins; + this.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = values.origins.slice(); for (let i = 0; i < values.origins.length; i++) { this.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin.add(i); @@ -12920,7 +12923,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.instruments) && values.instruments.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = values.instruments; + this.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = values.instruments.slice(); for (let i = 0; i < values.instruments.length; i++) { this.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument.add(i); @@ -12939,7 +12942,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -12983,7 +12987,7 @@ instruments?: (Object | URL)[];} // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Activity;clone.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = this.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor;clone.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = new Set(this.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor); + const clone = super.clone(values, options) as unknown as Activity;clone.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = this.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor.slice();clone.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = new Set(this.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor); if (\\"actor\\" in values && values.actor != null) { if (values.actor instanceof Application || values.actor instanceof Group || values.actor instanceof Organization || values.actor instanceof Person || values.actor instanceof Service || values.actor instanceof URL) { // @ts-ignore: type is checked above. @@ -13010,7 +13014,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.actors) && values.actors.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = values.actors; + clone.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = values.actors.slice(); clone.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = new Set(); for (let i = 0; i < values.actors.length; i++) { @@ -13024,7 +13028,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object;clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object); + clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object.slice();clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object); if (\\"object\\" in values && values.object != null) { if (values.object instanceof Object || values.object instanceof URL) { // @ts-ignore: type is checked above. @@ -13051,7 +13055,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.objects) && values.objects.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects; + clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects.slice(); clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(); for (let i = 0; i < values.objects.length; i++) { @@ -13065,7 +13069,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = this.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target;clone.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = new Set(this.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target); + clone.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = this.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target.slice();clone.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = new Set(this.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target); if (\\"target\\" in values && values.target != null) { if (values.target instanceof Object || values.target instanceof URL) { // @ts-ignore: type is checked above. @@ -13092,7 +13096,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.targets) && values.targets.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = values.targets; + clone.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = values.targets.slice(); clone.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = new Set(); for (let i = 0; i < values.targets.length; i++) { @@ -13106,7 +13110,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = this.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result;clone.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = new Set(this.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result); + clone.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = this.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result.slice();clone.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = new Set(this.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result); if (\\"result\\" in values && values.result != null) { if (values.result instanceof Object || values.result instanceof URL) { // @ts-ignore: type is checked above. @@ -13133,7 +13137,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.results) && values.results.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = values.results; + clone.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = values.results.slice(); clone.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = new Set(); for (let i = 0; i < values.results.length; i++) { @@ -13147,7 +13151,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = this.#_25zu2s3VxVujgEKqrDycjE284XQR_origin;clone.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin = new Set(this.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin); + clone.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = this.#_25zu2s3VxVujgEKqrDycjE284XQR_origin.slice();clone.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin = new Set(this.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin); if (\\"origin\\" in values && values.origin != null) { if (values.origin instanceof Object || values.origin instanceof URL) { // @ts-ignore: type is checked above. @@ -13174,7 +13178,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.origins) && values.origins.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = values.origins; + clone.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = values.origins.slice(); clone.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin = new Set(); for (let i = 0; i < values.origins.length; i++) { @@ -13188,7 +13192,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = this.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument;clone.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = new Set(this.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument); + clone.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = this.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument.slice();clone.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = new Set(this.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument); if (\\"instrument\\" in values && values.instrument != null) { if (values.instrument instanceof Object || values.instrument instanceof URL) { // @ts-ignore: type is checked above. @@ -13215,7 +13219,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.instruments) && values.instruments.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = values.instruments; + clone.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = values.instruments.slice(); clone.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = new Set(); for (let i = 0; i < values.instruments.length; i++) { @@ -16180,7 +16184,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -16594,7 +16599,8 @@ name?: string | LanguageString | null;value?: string | LanguageString | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -16622,7 +16628,7 @@ name?: string | LanguageString | null;value?: string | LanguageString | null;} { id: values.id ?? this.id }, options ); - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name.slice(); if (\\"name\\" in values && values.name != null) { if (typeof values.name === \\"string\\" || values.name instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -16635,7 +16641,7 @@ name?: string | LanguageString | null;value?: string | LanguageString | null;} ); } } - clone.#_2cSy2magg4iZ7zLaG8U7DiJMoCkx_value = this.#_2cSy2magg4iZ7zLaG8U7DiJMoCkx_value; + clone.#_2cSy2magg4iZ7zLaG8U7DiJMoCkx_value = this.#_2cSy2magg4iZ7zLaG8U7DiJMoCkx_value.slice(); if (\\"value\\" in values && values.value != null) { if (typeof values.value === \\"string\\" || values.value instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -17233,7 +17239,7 @@ endpoints?: (URL)[];} if (Array.isArray(values.endpoints) && values.endpoints.every(v => v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = values.endpoints; + this.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = values.endpoints.slice(); } else { throw new TypeError( @@ -17248,7 +17254,8 @@ endpoints?: (URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -17277,7 +17284,7 @@ endpoints?: (URL)[];} { id: values.id ?? this.id }, options ); - clone.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = this.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint; + clone.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = this.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint.slice(); if (\\"endpoint\\" in values && values.endpoint != null) { if (values.endpoint instanceof URL) { // @ts-ignore: type is checked above. @@ -17304,7 +17311,7 @@ endpoints?: (URL)[];} if (Array.isArray(values.endpoints) && values.endpoints.every(v => v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = values.endpoints; + clone.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = values.endpoints.slice(); } else { throw new TypeError( @@ -17683,7 +17690,8 @@ endpoints?: (URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -18113,7 +18121,8 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -18141,7 +18150,7 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | { id: values.id ?? this.id }, options ); - clone.#_3RurJsa7tnptyqMFR5hDGcP9pMs5_cryptosuite = this.#_3RurJsa7tnptyqMFR5hDGcP9pMs5_cryptosuite; + clone.#_3RurJsa7tnptyqMFR5hDGcP9pMs5_cryptosuite = this.#_3RurJsa7tnptyqMFR5hDGcP9pMs5_cryptosuite.slice(); if (\\"cryptosuite\\" in values && values.cryptosuite != null) { if (values.cryptosuite == \\"eddsa-jcs-2022\\") { // @ts-ignore: type is checked above. @@ -18154,7 +18163,7 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | ); } } - clone.#_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod = this.#_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod;clone.#_trust_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod = new Set(this.#_trust_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod); + clone.#_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod = this.#_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod.slice();clone.#_trust_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod = new Set(this.#_trust_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod); if (\\"verificationMethod\\" in values && values.verificationMethod != null) { if (values.verificationMethod instanceof Multikey || values.verificationMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -18167,7 +18176,7 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | ); } } - clone.#_2AeEnPcAvVrPEuKbpmn9ZKNmWHKb_proofPurpose = this.#_2AeEnPcAvVrPEuKbpmn9ZKNmWHKb_proofPurpose; + clone.#_2AeEnPcAvVrPEuKbpmn9ZKNmWHKb_proofPurpose = this.#_2AeEnPcAvVrPEuKbpmn9ZKNmWHKb_proofPurpose.slice(); if (\\"proofPurpose\\" in values && values.proofPurpose != null) { if (values.proofPurpose === \\"assertionMethod\\" || values.proofPurpose === \\"authentication\\" || values.proofPurpose === \\"capabilityInvocation\\" || values.proofPurpose === \\"capabilityDelegation\\" || @@ -18182,7 +18191,7 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | ); } } - clone.#_3CjFK5vfKpX4HQuNh2b18TykoVLq_proofValue = this.#_3CjFK5vfKpX4HQuNh2b18TykoVLq_proofValue; + clone.#_3CjFK5vfKpX4HQuNh2b18TykoVLq_proofValue = this.#_3CjFK5vfKpX4HQuNh2b18TykoVLq_proofValue.slice(); if (\\"proofValue\\" in values && values.proofValue != null) { if (values.proofValue instanceof Uint8Array) { // @ts-ignore: type is checked above. @@ -18195,7 +18204,7 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | ); } } - clone.#_3qzP3ukEZoUziK5FEiA1RhU4aqac = this.#_3qzP3ukEZoUziK5FEiA1RhU4aqac; + clone.#_3qzP3ukEZoUziK5FEiA1RhU4aqac = this.#_3qzP3ukEZoUziK5FEiA1RhU4aqac.slice(); if (\\"created\\" in values && values.created != null) { if (isTemporalInstant(values.created)) { // @ts-ignore: type is checked above. @@ -19158,7 +19167,8 @@ owner?: Application | Group | Organization | Person | Service | URL | null;publi * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -19186,7 +19196,7 @@ owner?: Application | Group | Organization | Person | Service | URL | null;publi { id: values.id ?? this.id }, options ); - clone.#_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner = this.#_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner;clone.#_trust_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner = new Set(this.#_trust_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner); + clone.#_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner = this.#_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner.slice();clone.#_trust_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner = new Set(this.#_trust_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner); if (\\"owner\\" in values && values.owner != null) { if (values.owner instanceof Application || values.owner instanceof Group || values.owner instanceof Organization || values.owner instanceof Person || values.owner instanceof Service || values.owner instanceof URL) { // @ts-ignore: type is checked above. @@ -19199,7 +19209,7 @@ owner?: Application | Group | Organization | Person | Service | URL | null;publi ); } } - clone.#_2fE2QMDdg6KFGqa4NEC3TmjApSAD_publicKeyPem = this.#_2fE2QMDdg6KFGqa4NEC3TmjApSAD_publicKeyPem; + clone.#_2fE2QMDdg6KFGqa4NEC3TmjApSAD_publicKeyPem = this.#_2fE2QMDdg6KFGqa4NEC3TmjApSAD_publicKeyPem.slice(); if (\\"publicKey\\" in values && values.publicKey != null) { if ( // @ts-ignore: CryptoKey exists in the global scope. @@ -20073,7 +20083,8 @@ controller?: Application | Group | Organization | Person | Service | URL | null; * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -20101,7 +20112,7 @@ controller?: Application | Group | Organization | Person | Service | URL | null; { id: values.id ?? this.id }, options ); - clone.#_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller = this.#_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller;clone.#_trust_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller = new Set(this.#_trust_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller); + clone.#_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller = this.#_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller.slice();clone.#_trust_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller = new Set(this.#_trust_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller); if (\\"controller\\" in values && values.controller != null) { if (values.controller instanceof Application || values.controller instanceof Group || values.controller instanceof Organization || values.controller instanceof Person || values.controller instanceof Service || values.controller instanceof URL) { // @ts-ignore: type is checked above. @@ -20114,7 +20125,7 @@ controller?: Application | Group | Organization | Person | Service | URL | null; ); } } - clone.#_4XLHbsR2gLVWU3NpEqKt9wANzn4F_publicKeyMultibase = this.#_4XLHbsR2gLVWU3NpEqKt9wANzn4F_publicKeyMultibase; + clone.#_4XLHbsR2gLVWU3NpEqKt9wANzn4F_publicKeyMultibase = this.#_4XLHbsR2gLVWU3NpEqKt9wANzn4F_publicKeyMultibase.slice(); if (\\"publicKey\\" in values && values.publicKey != null) { if ( // @ts-ignore: CryptoKey exists in the global scope. @@ -20913,7 +20924,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -21259,7 +21271,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -21600,7 +21613,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -22006,7 +22020,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -22042,7 +22056,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -22082,7 +22096,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -22205,7 +22219,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -22323,7 +22337,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -22363,7 +22377,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -22408,7 +22422,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -22451,7 +22466,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Application;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Application;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if (\\"preferredUsername\\" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === \\"string\\" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -22478,7 +22493,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -22487,7 +22502,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if (\\"publicKey\\" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -22514,7 +22529,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -22528,7 +22543,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if (\\"assertionMethod\\" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -22555,7 +22570,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -22569,7 +22584,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if (\\"manuallyApprovesFollowers\\" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -22582,7 +22597,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if (\\"inbox\\" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -22595,7 +22610,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if (\\"outbox\\" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -22608,7 +22623,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if (\\"following\\" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -22621,7 +22636,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if (\\"followers\\" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -22634,7 +22649,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if (\\"liked\\" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -22647,7 +22662,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if (\\"featured\\" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -22660,7 +22675,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if (\\"featuredTags\\" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -22673,13 +22688,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if (\\"streams\\" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -22693,7 +22708,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if (\\"endpoints\\" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -22706,7 +22721,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if (\\"discoverable\\" in values && values.discoverable != null) { if (typeof values.discoverable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -22719,7 +22734,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if (\\"suspended\\" in values && values.suspended != null) { if (typeof values.suspended === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -22732,7 +22747,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if (\\"memorial\\" in values && values.memorial != null) { if (typeof values.memorial === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -22745,7 +22760,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if (\\"indexable\\" in values && values.indexable != null) { if (typeof values.indexable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -22758,7 +22773,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if (\\"successor\\" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -22771,7 +22786,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if (\\"alias\\" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -22798,7 +22813,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -22812,7 +22827,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if (\\"service\\" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -22839,7 +22854,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -22853,7 +22868,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if (\\"followedMessage\\" in values && values.followedMessage != null) { if (typeof values.followedMessage === \\"string\\") { // @ts-ignore: type is checked above. @@ -22866,7 +22881,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if (\\"cat\\" in values && values.cat != null) { if (typeof values.cat === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -28884,7 +28899,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -29237,7 +29253,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -29583,7 +29600,8 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -29621,7 +29639,7 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Article;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl; + const clone = super.clone(values, options) as unknown as Article;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl.slice(); if (\\"quoteUrl\\" in values && values.quoteUrl != null) { if (values.quoteUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -30096,7 +30114,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -30134,7 +30153,7 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Document;clone.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width = this.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width; + const clone = super.clone(values, options) as unknown as Document;clone.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width = this.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width.slice(); if (\\"width\\" in values && values.width != null) { if (typeof values.width === \\"number\\" && Number.isInteger(values.width) && values.width >= 0) { // @ts-ignore: type is checked above. @@ -30147,7 +30166,7 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu ); } } - clone.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height = this.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height; + clone.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height = this.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height.slice(); if (\\"height\\" in values && values.height != null) { if (typeof values.height === \\"number\\" && Number.isInteger(values.height) && values.height >= 0) { // @ts-ignore: type is checked above. @@ -30667,7 +30686,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -31018,7 +31038,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -31364,7 +31385,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -31790,7 +31812,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); for (let i = 0; i < values.items.length; i++) { this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.add(i); @@ -31913,7 +31935,8 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -31951,7 +31974,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Collection;clone.#_XDbmNDuWHmrhqH712zqtecdbv1V_totalItems = this.#_XDbmNDuWHmrhqH712zqtecdbv1V_totalItems; + const clone = super.clone(values, options) as unknown as Collection;clone.#_XDbmNDuWHmrhqH712zqtecdbv1V_totalItems = this.#_XDbmNDuWHmrhqH712zqtecdbv1V_totalItems.slice(); if (\\"totalItems\\" in values && values.totalItems != null) { if (typeof values.totalItems === \\"number\\" && Number.isInteger(values.totalItems) && values.totalItems >= 0) { // @ts-ignore: type is checked above. @@ -31964,7 +31987,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3UyUdxnyn6cDn53QKrh4MBiearma_current = this.#_3UyUdxnyn6cDn53QKrh4MBiearma_current;clone.#_trust_3UyUdxnyn6cDn53QKrh4MBiearma_current = new Set(this.#_trust_3UyUdxnyn6cDn53QKrh4MBiearma_current); + clone.#_3UyUdxnyn6cDn53QKrh4MBiearma_current = this.#_3UyUdxnyn6cDn53QKrh4MBiearma_current.slice();clone.#_trust_3UyUdxnyn6cDn53QKrh4MBiearma_current = new Set(this.#_trust_3UyUdxnyn6cDn53QKrh4MBiearma_current); if (\\"current\\" in values && values.current != null) { if (values.current instanceof CollectionPage || values.current instanceof URL) { // @ts-ignore: type is checked above. @@ -31977,7 +32000,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_J52RqweMe6hhv7RnLJMC8BExTE5_first = this.#_J52RqweMe6hhv7RnLJMC8BExTE5_first;clone.#_trust_J52RqweMe6hhv7RnLJMC8BExTE5_first = new Set(this.#_trust_J52RqweMe6hhv7RnLJMC8BExTE5_first); + clone.#_J52RqweMe6hhv7RnLJMC8BExTE5_first = this.#_J52RqweMe6hhv7RnLJMC8BExTE5_first.slice();clone.#_trust_J52RqweMe6hhv7RnLJMC8BExTE5_first = new Set(this.#_trust_J52RqweMe6hhv7RnLJMC8BExTE5_first); if (\\"first\\" in values && values.first != null) { if (values.first instanceof CollectionPage || values.first instanceof URL) { // @ts-ignore: type is checked above. @@ -31990,7 +32013,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last = this.#_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last;clone.#_trust_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last = new Set(this.#_trust_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last); + clone.#_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last = this.#_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last.slice();clone.#_trust_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last = new Set(this.#_trust_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last); if (\\"last\\" in values && values.last != null) { if (values.last instanceof CollectionPage || values.last instanceof URL) { // @ts-ignore: type is checked above. @@ -32003,13 +32026,13 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items;clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); + clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.slice();clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); if (\\"items\\" in values && values.items != null) { if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(); for (let i = 0; i < values.items.length; i++) { @@ -32023,7 +32046,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf = this.#_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf;clone.#_trust_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf = new Set(this.#_trust_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf); + clone.#_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf = this.#_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf.slice();clone.#_trust_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf = new Set(this.#_trust_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf); if (\\"likesOf\\" in values && values.likesOf != null) { if (values.likesOf instanceof Object || values.likesOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32036,7 +32059,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf = this.#_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf;clone.#_trust_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf = new Set(this.#_trust_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf); + clone.#_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf = this.#_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf.slice();clone.#_trust_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf = new Set(this.#_trust_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf); if (\\"sharesOf\\" in values && values.sharesOf != null) { if (values.sharesOf instanceof Object || values.sharesOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32049,7 +32072,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf = this.#_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf;clone.#_trust_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf = new Set(this.#_trust_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf); + clone.#_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf = this.#_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf.slice();clone.#_trust_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf = new Set(this.#_trust_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf); if (\\"repliesOf\\" in values && values.repliesOf != null) { if (values.repliesOf instanceof Object || values.repliesOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32062,7 +32085,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf = this.#_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf;clone.#_trust_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf = new Set(this.#_trust_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf); + clone.#_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf = this.#_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf.slice();clone.#_trust_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf = new Set(this.#_trust_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf); if (\\"inboxOf\\" in values && values.inboxOf != null) { if (values.inboxOf instanceof Object || values.inboxOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32075,7 +32098,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf = this.#_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf;clone.#_trust_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf = new Set(this.#_trust_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf); + clone.#_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf = this.#_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf.slice();clone.#_trust_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf = new Set(this.#_trust_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf); if (\\"outboxOf\\" in values && values.outboxOf != null) { if (values.outboxOf instanceof Object || values.outboxOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32088,7 +32111,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf = this.#_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf;clone.#_trust_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf = new Set(this.#_trust_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf); + clone.#_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf = this.#_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf.slice();clone.#_trust_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf = new Set(this.#_trust_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf); if (\\"followersOf\\" in values && values.followersOf != null) { if (values.followersOf instanceof Object || values.followersOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32101,7 +32124,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf = this.#_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf;clone.#_trust_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf = new Set(this.#_trust_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf); + clone.#_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf = this.#_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf.slice();clone.#_trust_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf = new Set(this.#_trust_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf); if (\\"followingOf\\" in values && values.followingOf != null) { if (values.followingOf instanceof Object || values.followingOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32114,7 +32137,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf = this.#_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf;clone.#_trust_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf = new Set(this.#_trust_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf); + clone.#_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf = this.#_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf.slice();clone.#_trust_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf = new Set(this.#_trust_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf); if (\\"likedOf\\" in values && values.likedOf != null) { if (values.likedOf instanceof Object || values.likedOf instanceof URL) { // @ts-ignore: type is checked above. @@ -36438,7 +36461,8 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -36476,7 +36500,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as CollectionPage;clone.#_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf = this.#_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf;clone.#_trust_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf = new Set(this.#_trust_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf); + const clone = super.clone(values, options) as unknown as CollectionPage;clone.#_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf = this.#_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf.slice();clone.#_trust_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf = new Set(this.#_trust_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf); if (\\"partOf\\" in values && values.partOf != null) { if (values.partOf instanceof Collection || values.partOf instanceof URL) { // @ts-ignore: type is checked above. @@ -36489,7 +36513,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next = this.#_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next;clone.#_trust_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next = new Set(this.#_trust_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next); + clone.#_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next = this.#_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next.slice();clone.#_trust_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next = new Set(this.#_trust_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next); if (\\"next\\" in values && values.next != null) { if (values.next instanceof CollectionPage || values.next instanceof URL) { // @ts-ignore: type is checked above. @@ -36502,7 +36526,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev = this.#_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev;clone.#_trust_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev = new Set(this.#_trust_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev); + clone.#_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev = this.#_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev.slice();clone.#_trust_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev = new Set(this.#_trust_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev); if (\\"prev\\" in values && values.prev != null) { if (values.prev instanceof CollectionPage || values.prev instanceof URL) { // @ts-ignore: type is checked above. @@ -37784,7 +37808,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -38124,7 +38149,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -38462,7 +38488,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -38932,7 +38959,8 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -38960,7 +38988,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint { id: values.id ?? this.id }, options ); - clone.#_2JCYDbSxEHCCLdBYed33cCETfGyR_proxyUrl = this.#_2JCYDbSxEHCCLdBYed33cCETfGyR_proxyUrl; + clone.#_2JCYDbSxEHCCLdBYed33cCETfGyR_proxyUrl = this.#_2JCYDbSxEHCCLdBYed33cCETfGyR_proxyUrl.slice(); if (\\"proxyUrl\\" in values && values.proxyUrl != null) { if (values.proxyUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -38973,7 +39001,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_25S6UmgzDead8hxL5sQFezZTAusd_oauthAuthorizationEndpoint = this.#_25S6UmgzDead8hxL5sQFezZTAusd_oauthAuthorizationEndpoint; + clone.#_25S6UmgzDead8hxL5sQFezZTAusd_oauthAuthorizationEndpoint = this.#_25S6UmgzDead8hxL5sQFezZTAusd_oauthAuthorizationEndpoint.slice(); if (\\"oauthAuthorizationEndpoint\\" in values && values.oauthAuthorizationEndpoint != null) { if (values.oauthAuthorizationEndpoint instanceof URL) { // @ts-ignore: type is checked above. @@ -38986,7 +39014,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_iAMxqrSba7yBCRB1FZ5kEVdKEZ3_oauthTokenEndpoint = this.#_iAMxqrSba7yBCRB1FZ5kEVdKEZ3_oauthTokenEndpoint; + clone.#_iAMxqrSba7yBCRB1FZ5kEVdKEZ3_oauthTokenEndpoint = this.#_iAMxqrSba7yBCRB1FZ5kEVdKEZ3_oauthTokenEndpoint.slice(); if (\\"oauthTokenEndpoint\\" in values && values.oauthTokenEndpoint != null) { if (values.oauthTokenEndpoint instanceof URL) { // @ts-ignore: type is checked above. @@ -38999,7 +39027,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_8Bx9qN8oU7Bpt2xi6khaxWp1gMr_provideClientKey = this.#_8Bx9qN8oU7Bpt2xi6khaxWp1gMr_provideClientKey; + clone.#_8Bx9qN8oU7Bpt2xi6khaxWp1gMr_provideClientKey = this.#_8Bx9qN8oU7Bpt2xi6khaxWp1gMr_provideClientKey.slice(); if (\\"provideClientKey\\" in values && values.provideClientKey != null) { if (values.provideClientKey instanceof URL) { // @ts-ignore: type is checked above. @@ -39012,7 +39040,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_3dU7PMVQZJpsCpo2F4RQXxBXdPmS_signClientKey = this.#_3dU7PMVQZJpsCpo2F4RQXxBXdPmS_signClientKey; + clone.#_3dU7PMVQZJpsCpo2F4RQXxBXdPmS_signClientKey = this.#_3dU7PMVQZJpsCpo2F4RQXxBXdPmS_signClientKey.slice(); if (\\"signClientKey\\" in values && values.signClientKey != null) { if (values.signClientKey instanceof URL) { // @ts-ignore: type is checked above. @@ -39025,7 +39053,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_3JprUSDLVqqX4dwHRi37qGZZCRCc_sharedInbox = this.#_3JprUSDLVqqX4dwHRi37qGZZCRCc_sharedInbox; + clone.#_3JprUSDLVqqX4dwHRi37qGZZCRCc_sharedInbox = this.#_3JprUSDLVqqX4dwHRi37qGZZCRCc_sharedInbox.slice(); if (\\"sharedInbox\\" in values && values.sharedInbox != null) { if (values.sharedInbox instanceof URL) { // @ts-ignore: type is checked above. @@ -39973,7 +40001,8 @@ proofs?: (DataIntegrityProof | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -40325,7 +40354,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -40667,7 +40697,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -41073,7 +41104,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -41109,7 +41140,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -41149,7 +41180,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -41272,7 +41303,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -41390,7 +41421,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -41430,7 +41461,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -41475,7 +41506,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -41518,7 +41550,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Group;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Group;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if (\\"preferredUsername\\" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === \\"string\\" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -41545,7 +41577,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -41554,7 +41586,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if (\\"publicKey\\" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -41581,7 +41613,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -41595,7 +41627,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if (\\"assertionMethod\\" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -41622,7 +41654,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -41636,7 +41668,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if (\\"manuallyApprovesFollowers\\" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -41649,7 +41681,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if (\\"inbox\\" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -41662,7 +41694,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if (\\"outbox\\" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -41675,7 +41707,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if (\\"following\\" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -41688,7 +41720,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if (\\"followers\\" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -41701,7 +41733,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if (\\"liked\\" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -41714,7 +41746,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if (\\"featured\\" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -41727,7 +41759,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if (\\"featuredTags\\" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -41740,13 +41772,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if (\\"streams\\" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -41760,7 +41792,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if (\\"endpoints\\" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -41773,7 +41805,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if (\\"discoverable\\" in values && values.discoverable != null) { if (typeof values.discoverable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -41786,7 +41818,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if (\\"suspended\\" in values && values.suspended != null) { if (typeof values.suspended === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -41799,7 +41831,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if (\\"memorial\\" in values && values.memorial != null) { if (typeof values.memorial === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -41812,7 +41844,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if (\\"indexable\\" in values && values.indexable != null) { if (typeof values.indexable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -41825,7 +41857,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if (\\"successor\\" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -41838,7 +41870,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if (\\"alias\\" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -41865,7 +41897,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -41879,7 +41911,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if (\\"service\\" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -41906,7 +41938,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -41920,7 +41952,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if (\\"followedMessage\\" in values && values.followedMessage != null) { if (typeof values.followedMessage === \\"string\\") { // @ts-ignore: type is checked above. @@ -41933,7 +41965,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if (\\"cat\\" in values && values.cat != null) { if (typeof values.cat === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -48050,7 +48082,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.rels) && values.rels.every(v => typeof v === \\"string\\")) { // @ts-ignore: type is checked above. - this.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = values.rels; + this.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = values.rels.slice(); } else { throw new TypeError( @@ -48099,7 +48131,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.names) && values.names.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names; + this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names.slice(); } else { throw new TypeError( @@ -48153,7 +48185,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.previews) && values.previews.every(v => v instanceof Link || v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews; + this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews.slice(); for (let i = 0; i < values.previews.length; i++) { this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview.add(i); @@ -48172,7 +48204,8 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -48202,7 +48235,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num { id: values.id ?? this.id }, options ); - clone.#_pVjLsybKQdmkjuU7MHjiVmNnuj7_href = this.#_pVjLsybKQdmkjuU7MHjiVmNnuj7_href; + clone.#_pVjLsybKQdmkjuU7MHjiVmNnuj7_href = this.#_pVjLsybKQdmkjuU7MHjiVmNnuj7_href.slice(); if (\\"href\\" in values && values.href != null) { if (values.href instanceof URL) { // @ts-ignore: type is checked above. @@ -48215,7 +48248,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = this.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel; + clone.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = this.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel.slice(); if (\\"rel\\" in values && values.rel != null) { if (typeof values.rel === \\"string\\") { // @ts-ignore: type is checked above. @@ -48242,7 +48275,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.rels) && values.rels.every(v => typeof v === \\"string\\")) { // @ts-ignore: type is checked above. - clone.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = values.rels; + clone.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = values.rels.slice(); } else { throw new TypeError( @@ -48251,7 +48284,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType; + clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType.slice(); if (\\"mediaType\\" in values && values.mediaType != null) { if (typeof values.mediaType === \\"string\\") { // @ts-ignore: type is checked above. @@ -48264,7 +48297,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name.slice(); if (\\"name\\" in values && values.name != null) { if (typeof values.name === \\"string\\" || values.name instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -48291,7 +48324,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.names) && values.names.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names.slice(); } else { throw new TypeError( @@ -48300,7 +48333,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang = this.#_f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang; + clone.#_f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang = this.#_f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang.slice(); if (\\"language\\" in values && values.language != null) { if (values.language instanceof Intl.Locale) { // @ts-ignore: type is checked above. @@ -48313,7 +48346,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height = this.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height; + clone.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height = this.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height.slice(); if (\\"height\\" in values && values.height != null) { if (typeof values.height === \\"number\\" && Number.isInteger(values.height) && values.height >= 0) { // @ts-ignore: type is checked above. @@ -48326,7 +48359,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width = this.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width; + clone.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width = this.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width.slice(); if (\\"width\\" in values && values.width != null) { if (typeof values.width === \\"number\\" && Number.isInteger(values.width) && values.width >= 0) { // @ts-ignore: type is checked above. @@ -48339,13 +48372,13 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview;clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview); + clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview.slice();clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview); if (\\"previews\\" in values && values.previews != null) { if (Array.isArray(values.previews) && values.previews.every(v => v instanceof Link || v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews; + clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews.slice(); clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(); for (let i = 0; i < values.previews.length; i++) { @@ -49697,7 +49730,8 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -50015,7 +50049,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -50367,7 +50402,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -50711,7 +50747,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -51051,7 +51088,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -51391,7 +51429,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -51731,7 +51770,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -52069,7 +52109,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -52387,7 +52428,8 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -52714,7 +52756,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -53062,7 +53105,8 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -53100,7 +53144,7 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Note;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl; + const clone = super.clone(values, options) as unknown as Note;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl.slice(); if (\\"quoteUrl\\" in values && values.quoteUrl != null) { if (values.quoteUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -53552,7 +53596,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); for (let i = 0; i < values.items.length; i++) { this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.add(i); @@ -53571,7 +53615,8 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -53609,13 +53654,13 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as OrderedCollection;clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items;clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); + const clone = super.clone(values, options) as unknown as OrderedCollection;clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.slice();clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); if (\\"items\\" in values && values.items != null) { if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(); for (let i = 0; i < values.items.length; i++) { @@ -54286,7 +54331,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); for (let i = 0; i < values.items.length; i++) { this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.add(i); @@ -54318,7 +54363,8 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -54356,13 +54402,13 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as OrderedCollectionPage;clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items;clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); + const clone = super.clone(values, options) as unknown as OrderedCollectionPage;clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.slice();clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); if (\\"items\\" in values && values.items != null) { if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(); for (let i = 0; i < values.items.length; i++) { @@ -54376,7 +54422,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2W4yinFwqmpneu2h4m1mZ3pcLADd_startIndex = this.#_2W4yinFwqmpneu2h4m1mZ3pcLADd_startIndex; + clone.#_2W4yinFwqmpneu2h4m1mZ3pcLADd_startIndex = this.#_2W4yinFwqmpneu2h4m1mZ3pcLADd_startIndex.slice(); if (\\"startIndex\\" in values && values.startIndex != null) { if (typeof values.startIndex === \\"number\\" && Number.isInteger(values.startIndex) && values.startIndex >= 0) { // @ts-ignore: type is checked above. @@ -55206,7 +55252,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -55242,7 +55288,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -55282,7 +55328,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -55405,7 +55451,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -55523,7 +55569,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -55563,7 +55609,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -55608,7 +55654,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -55651,7 +55698,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Organization;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Organization;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if (\\"preferredUsername\\" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === \\"string\\" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -55678,7 +55725,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -55687,7 +55734,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if (\\"publicKey\\" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -55714,7 +55761,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -55728,7 +55775,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if (\\"assertionMethod\\" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -55755,7 +55802,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -55769,7 +55816,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if (\\"manuallyApprovesFollowers\\" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -55782,7 +55829,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if (\\"inbox\\" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -55795,7 +55842,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if (\\"outbox\\" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -55808,7 +55855,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if (\\"following\\" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -55821,7 +55868,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if (\\"followers\\" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -55834,7 +55881,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if (\\"liked\\" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -55847,7 +55894,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if (\\"featured\\" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -55860,7 +55907,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if (\\"featuredTags\\" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -55873,13 +55920,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if (\\"streams\\" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -55893,7 +55940,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if (\\"endpoints\\" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -55906,7 +55953,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if (\\"discoverable\\" in values && values.discoverable != null) { if (typeof values.discoverable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -55919,7 +55966,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if (\\"suspended\\" in values && values.suspended != null) { if (typeof values.suspended === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -55932,7 +55979,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if (\\"memorial\\" in values && values.memorial != null) { if (typeof values.memorial === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -55945,7 +55992,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if (\\"indexable\\" in values && values.indexable != null) { if (typeof values.indexable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -55958,7 +56005,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if (\\"successor\\" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -55971,7 +56018,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if (\\"alias\\" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -55998,7 +56045,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -56012,7 +56059,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if (\\"service\\" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -56039,7 +56086,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -56053,7 +56100,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if (\\"followedMessage\\" in values && values.followedMessage != null) { if (typeof values.followedMessage === \\"string\\") { // @ts-ignore: type is checked above. @@ -56066,7 +56113,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if (\\"cat\\" in values && values.cat != null) { if (typeof values.cat === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -62075,7 +62122,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -62492,7 +62540,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -62528,7 +62576,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -62568,7 +62616,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -62691,7 +62739,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -62809,7 +62857,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -62849,7 +62897,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -62894,7 +62942,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -62937,7 +62986,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Person;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Person;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if (\\"preferredUsername\\" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === \\"string\\" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -62964,7 +63013,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -62973,7 +63022,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if (\\"publicKey\\" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -63000,7 +63049,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -63014,7 +63063,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if (\\"assertionMethod\\" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -63041,7 +63090,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -63055,7 +63104,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if (\\"manuallyApprovesFollowers\\" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -63068,7 +63117,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if (\\"inbox\\" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -63081,7 +63130,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if (\\"outbox\\" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -63094,7 +63143,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if (\\"following\\" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -63107,7 +63156,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if (\\"followers\\" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -63120,7 +63169,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if (\\"liked\\" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -63133,7 +63182,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if (\\"featured\\" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -63146,7 +63195,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if (\\"featuredTags\\" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -63159,13 +63208,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if (\\"streams\\" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -63179,7 +63228,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if (\\"endpoints\\" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -63192,7 +63241,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if (\\"discoverable\\" in values && values.discoverable != null) { if (typeof values.discoverable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -63205,7 +63254,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if (\\"suspended\\" in values && values.suspended != null) { if (typeof values.suspended === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -63218,7 +63267,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if (\\"memorial\\" in values && values.memorial != null) { if (typeof values.memorial === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -63231,7 +63280,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if (\\"indexable\\" in values && values.indexable != null) { if (typeof values.indexable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -63244,7 +63293,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if (\\"successor\\" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -63257,7 +63306,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if (\\"alias\\" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -63284,7 +63333,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -63298,7 +63347,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if (\\"service\\" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -63325,7 +63374,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -63339,7 +63388,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if (\\"followedMessage\\" in values && values.followedMessage != null) { if (typeof values.followedMessage === \\"string\\") { // @ts-ignore: type is checked above. @@ -63352,7 +63401,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if (\\"cat\\" in values && values.cat != null) { if (typeof values.cat === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -69448,7 +69497,8 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -69486,7 +69536,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Place;clone.#_3UCsHnBHvDAXJnBuzw3zw1VVs3Ne_accuracy = this.#_3UCsHnBHvDAXJnBuzw3zw1VVs3Ne_accuracy; + const clone = super.clone(values, options) as unknown as Place;clone.#_3UCsHnBHvDAXJnBuzw3zw1VVs3Ne_accuracy = this.#_3UCsHnBHvDAXJnBuzw3zw1VVs3Ne_accuracy.slice(); if (\\"accuracy\\" in values && values.accuracy != null) { if (typeof values.accuracy === \\"number\\" && !Number.isNaN(values.accuracy)) { // @ts-ignore: type is checked above. @@ -69499,7 +69549,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_3Q6KDcFQUJRRaBux1BL2yp5QWiBi_altitude = this.#_3Q6KDcFQUJRRaBux1BL2yp5QWiBi_altitude; + clone.#_3Q6KDcFQUJRRaBux1BL2yp5QWiBi_altitude = this.#_3Q6KDcFQUJRRaBux1BL2yp5QWiBi_altitude.slice(); if (\\"altitude\\" in values && values.altitude != null) { if (typeof values.altitude === \\"number\\" && !Number.isNaN(values.altitude)) { // @ts-ignore: type is checked above. @@ -69512,7 +69562,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_3g85RoKRnaNjP7DFyLSvsWDg7HGM_latitude = this.#_3g85RoKRnaNjP7DFyLSvsWDg7HGM_latitude; + clone.#_3g85RoKRnaNjP7DFyLSvsWDg7HGM_latitude = this.#_3g85RoKRnaNjP7DFyLSvsWDg7HGM_latitude.slice(); if (\\"latitude\\" in values && values.latitude != null) { if (typeof values.latitude === \\"number\\" && !Number.isNaN(values.latitude)) { // @ts-ignore: type is checked above. @@ -69525,7 +69575,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_B2GEYdS9yBAF3ho1pm1rcRg7cSf_longitude = this.#_B2GEYdS9yBAF3ho1pm1rcRg7cSf_longitude; + clone.#_B2GEYdS9yBAF3ho1pm1rcRg7cSf_longitude = this.#_B2GEYdS9yBAF3ho1pm1rcRg7cSf_longitude.slice(); if (\\"longitude\\" in values && values.longitude != null) { if (typeof values.longitude === \\"number\\" && !Number.isNaN(values.longitude)) { // @ts-ignore: type is checked above. @@ -69538,7 +69588,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_3ga86BKHUtRkGx5PHBjRiUXXzwnw_radius = this.#_3ga86BKHUtRkGx5PHBjRiUXXzwnw_radius; + clone.#_3ga86BKHUtRkGx5PHBjRiUXXzwnw_radius = this.#_3ga86BKHUtRkGx5PHBjRiUXXzwnw_radius.slice(); if (\\"radius\\" in values && values.radius != null) { if (typeof values.radius === \\"number\\" && !Number.isNaN(values.radius)) { // @ts-ignore: type is checked above. @@ -69551,7 +69601,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_oKrwxU4V8wiKhMW1QEYQibcJh8c_units = this.#_oKrwxU4V8wiKhMW1QEYQibcJh8c_units; + clone.#_oKrwxU4V8wiKhMW1QEYQibcJh8c_units = this.#_oKrwxU4V8wiKhMW1QEYQibcJh8c_units.slice(); if (\\"units\\" in values && values.units != null) { if (values.units == \\"cm\\" || values.units == \\"feet\\" || values.units == \\"inches\\" || values.units == \\"km\\" || values.units == \\"m\\" || values.units == \\"miles\\" || values.units instanceof URL) { // @ts-ignore: type is checked above. @@ -70468,7 +70518,8 @@ proofs?: (DataIntegrityProof | URL)[];describes?: Object | URL | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -70506,7 +70557,7 @@ proofs?: (DataIntegrityProof | URL)[];describes?: Object | URL | null;} // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Profile;clone.#_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes = this.#_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes;clone.#_trust_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes = new Set(this.#_trust_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes); + const clone = super.clone(values, options) as unknown as Profile;clone.#_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes = this.#_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes.slice();clone.#_trust_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes = new Set(this.#_trust_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes); if (\\"describes\\" in values && values.describes != null) { if (values.describes instanceof Object || values.describes instanceof URL) { // @ts-ignore: type is checked above. @@ -71166,7 +71217,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti if (Array.isArray(values.exclusiveOptions) && values.exclusiveOptions.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = values.exclusiveOptions; + this.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = values.exclusiveOptions.slice(); for (let i = 0; i < values.exclusiveOptions.length; i++) { this.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf.add(i); @@ -71185,7 +71236,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti if (Array.isArray(values.inclusiveOptions) && values.inclusiveOptions.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = values.inclusiveOptions; + this.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = values.inclusiveOptions.slice(); for (let i = 0; i < values.inclusiveOptions.length; i++) { this.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf.add(i); @@ -71243,7 +71294,8 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -71287,13 +71339,13 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Question;clone.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = this.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf;clone.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = new Set(this.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf); + const clone = super.clone(values, options) as unknown as Question;clone.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = this.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf.slice();clone.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = new Set(this.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf); if (\\"exclusiveOptions\\" in values && values.exclusiveOptions != null) { if (Array.isArray(values.exclusiveOptions) && values.exclusiveOptions.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = values.exclusiveOptions; + clone.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = values.exclusiveOptions.slice(); clone.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = new Set(); for (let i = 0; i < values.exclusiveOptions.length; i++) { @@ -71307,13 +71359,13 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti ); } } - clone.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = this.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf;clone.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = new Set(this.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf); + clone.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = this.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf.slice();clone.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = new Set(this.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf); if (\\"inclusiveOptions\\" in values && values.inclusiveOptions != null) { if (Array.isArray(values.inclusiveOptions) && values.inclusiveOptions.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = values.inclusiveOptions; + clone.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = values.inclusiveOptions.slice(); clone.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = new Set(); for (let i = 0; i < values.inclusiveOptions.length; i++) { @@ -71327,7 +71379,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti ); } } - clone.#_3KronwL8DiiKBRcJFKQPiEHm8xb6_closed = this.#_3KronwL8DiiKBRcJFKQPiEHm8xb6_closed; + clone.#_3KronwL8DiiKBRcJFKQPiEHm8xb6_closed = this.#_3KronwL8DiiKBRcJFKQPiEHm8xb6_closed.slice(); if (\\"closed\\" in values && values.closed != null) { if (isTemporalInstant(values.closed) || typeof values.closed === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -71340,7 +71392,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti ); } } - clone.#_3H4RdST7dxfmghccvE3rKD3KgcxG_votersCount = this.#_3H4RdST7dxfmghccvE3rKD3KgcxG_votersCount; + clone.#_3H4RdST7dxfmghccvE3rKD3KgcxG_votersCount = this.#_3H4RdST7dxfmghccvE3rKD3KgcxG_votersCount.slice(); if (\\"voters\\" in values && values.voters != null) { if (typeof values.voters === \\"number\\" && Number.isInteger(values.voters) && values.voters >= 0) { // @ts-ignore: type is checked above. @@ -71353,7 +71405,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti ); } } - clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl; + clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl.slice(); if (\\"quoteUrl\\" in values && values.quoteUrl != null) { if (values.quoteUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -72541,7 +72593,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -72881,7 +72934,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -73269,7 +73323,7 @@ relationships?: (Object | URL)[];} if (Array.isArray(values.objects) && values.objects.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects; + this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects.slice(); for (let i = 0; i < values.objects.length; i++) { this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object.add(i); @@ -73309,7 +73363,7 @@ relationships?: (Object | URL)[];} if (Array.isArray(values.relationships) && values.relationships.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = values.relationships; + this.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = values.relationships.slice(); for (let i = 0; i < values.relationships.length; i++) { this.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship.add(i); @@ -73328,7 +73382,8 @@ relationships?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -73368,7 +73423,7 @@ relationships?: (Object | URL)[];} // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Relationship;clone.#_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject = this.#_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject;clone.#_trust_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject = new Set(this.#_trust_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject); + const clone = super.clone(values, options) as unknown as Relationship;clone.#_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject = this.#_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject.slice();clone.#_trust_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject = new Set(this.#_trust_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject); if (\\"subject\\" in values && values.subject != null) { if (values.subject instanceof Object || values.subject instanceof URL) { // @ts-ignore: type is checked above. @@ -73381,7 +73436,7 @@ relationships?: (Object | URL)[];} ); } } - clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object;clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object); + clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object.slice();clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object); if (\\"object\\" in values && values.object != null) { if (values.object instanceof Object || values.object instanceof URL) { // @ts-ignore: type is checked above. @@ -73408,7 +73463,7 @@ relationships?: (Object | URL)[];} if (Array.isArray(values.objects) && values.objects.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects; + clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects.slice(); clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(); for (let i = 0; i < values.objects.length; i++) { @@ -73422,7 +73477,7 @@ relationships?: (Object | URL)[];} ); } } - clone.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = this.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship;clone.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = new Set(this.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship); + clone.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = this.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship.slice();clone.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = new Set(this.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship); if (\\"relationship\\" in values && values.relationship != null) { if (values.relationship instanceof Object || values.relationship instanceof URL) { // @ts-ignore: type is checked above. @@ -73449,7 +73504,7 @@ relationships?: (Object | URL)[];} if (Array.isArray(values.relationships) && values.relationships.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = values.relationships; + clone.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = values.relationships.slice(); clone.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = new Set(); for (let i = 0; i < values.relationships.length; i++) { @@ -74957,7 +75012,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -75363,7 +75419,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -75399,7 +75455,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -75439,7 +75495,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -75562,7 +75618,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -75680,7 +75736,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -75720,7 +75776,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -75765,7 +75821,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -75808,7 +75865,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Service;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Service;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if (\\"preferredUsername\\" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === \\"string\\" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -75835,7 +75892,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -75844,7 +75901,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if (\\"publicKey\\" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -75871,7 +75928,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -75885,7 +75942,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if (\\"assertionMethod\\" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -75912,7 +75969,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -75926,7 +75983,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if (\\"manuallyApprovesFollowers\\" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -75939,7 +75996,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if (\\"inbox\\" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -75952,7 +76009,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if (\\"outbox\\" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -75965,7 +76022,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if (\\"following\\" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -75978,7 +76035,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if (\\"followers\\" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -75991,7 +76048,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if (\\"liked\\" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -76004,7 +76061,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if (\\"featured\\" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -76017,7 +76074,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if (\\"featuredTags\\" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -76030,13 +76087,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if (\\"streams\\" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -76050,7 +76107,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if (\\"endpoints\\" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -76063,7 +76120,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if (\\"discoverable\\" in values && values.discoverable != null) { if (typeof values.discoverable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -76076,7 +76133,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if (\\"suspended\\" in values && values.suspended != null) { if (typeof values.suspended === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -76089,7 +76146,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if (\\"memorial\\" in values && values.memorial != null) { if (typeof values.memorial === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -76102,7 +76159,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if (\\"indexable\\" in values && values.indexable != null) { if (typeof values.indexable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -76115,7 +76172,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if (\\"successor\\" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -76128,7 +76185,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if (\\"alias\\" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -76155,7 +76212,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -76169,7 +76226,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if (\\"service\\" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -76196,7 +76253,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -76210,7 +76267,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if (\\"followedMessage\\" in values && values.followedMessage != null) { if (typeof values.followedMessage === \\"string\\") { // @ts-ignore: type is checked above. @@ -76223,7 +76280,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if (\\"cat\\" in values && values.cat != null) { if (typeof values.cat === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -82310,7 +82367,7 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} if (Array.isArray(values.contents) && values.contents.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents; + this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents.slice(); } else { throw new TypeError( @@ -82338,7 +82395,8 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -82367,7 +82425,7 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} { id: values.id ?? this.id }, options ); - clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content; + clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content.slice(); if (\\"content\\" in values && values.content != null) { if (typeof values.content === \\"string\\" || values.content instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -82394,7 +82452,7 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} if (Array.isArray(values.contents) && values.contents.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents; + clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents.slice(); } else { throw new TypeError( @@ -82403,7 +82461,7 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} ); } } - clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType; + clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType.slice(); if (\\"mediaType\\" in values && values.mediaType != null) { if (typeof values.mediaType === \\"string\\") { // @ts-ignore: type is checked above. @@ -82920,7 +82978,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -83260,7 +83319,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -83609,7 +83669,8 @@ proofs?: (DataIntegrityProof | URL)[];deleted?: Temporal.Instant | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -83647,7 +83708,7 @@ proofs?: (DataIntegrityProof | URL)[];deleted?: Temporal.Instant | null;} // @ts-ignore: \$warning is not recognized as a property, but it is. options = { ...options, \$warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Tombstone;clone.#_8g8g4LiVMhFTXskuDEqx4ascxUr_deleted = this.#_8g8g4LiVMhFTXskuDEqx4ascxUr_deleted; + const clone = super.clone(values, options) as unknown as Tombstone;clone.#_8g8g4LiVMhFTXskuDEqx4ascxUr_deleted = this.#_8g8g4LiVMhFTXskuDEqx4ascxUr_deleted.slice(); if (\\"deleted\\" in values && values.deleted != null) { if (isTemporalInstant(values.deleted)) { // @ts-ignore: type is checked above. @@ -84072,7 +84133,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -84417,7 +84479,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -84760,7 +84823,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -85092,7 +85156,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -85442,7 +85507,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: diff --git a/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap b/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap index 05c47acd7..e4bd0d941 100644 --- a/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap +++ b/packages/vocab-tools/src/__snapshots__/class.test.ts.node.snap @@ -239,7 +239,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.attachments) && values.attachments.every(v => v instanceof Object || v instanceof Link || v instanceof PropertyValue || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = values.attachments; + this.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = values.attachments.slice(); for (let i = 0; i < values.attachments.length; i++) { this.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment.add(i); @@ -279,7 +279,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.attributions) && values.attributions.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = values.attributions; + this.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = values.attributions.slice(); for (let i = 0; i < values.attributions.length; i++) { this.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo.add(i); @@ -319,7 +319,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.audiences) && values.audiences.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = values.audiences; + this.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = values.audiences.slice(); for (let i = 0; i < values.audiences.length; i++) { this.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience.add(i); @@ -359,7 +359,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.contents) && values.contents.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents; + this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents.slice(); } else { throw new TypeError( @@ -374,7 +374,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.contexts) && values.contexts.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = values.contexts; + this.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = values.contexts.slice(); for (let i = 0; i < values.contexts.length; i++) { this.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context.add(i); @@ -414,7 +414,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.names) && values.names.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names; + this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names.slice(); } else { throw new TypeError( @@ -442,7 +442,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.generators) && values.generators.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = values.generators; + this.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = values.generators.slice(); for (let i = 0; i < values.generators.length; i++) { this.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator.add(i); @@ -482,7 +482,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.icons) && values.icons.every(v => v instanceof Image || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = values.icons; + this.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = values.icons.slice(); for (let i = 0; i < values.icons.length; i++) { this.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon.add(i); @@ -522,7 +522,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.images) && values.images.every(v => v instanceof Image || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = values.images; + this.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = values.images.slice(); for (let i = 0; i < values.images.length; i++) { this.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image.add(i); @@ -562,7 +562,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.replyTargets) && values.replyTargets.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = values.replyTargets; + this.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = values.replyTargets.slice(); for (let i = 0; i < values.replyTargets.length; i++) { this.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo.add(i); @@ -602,7 +602,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.locations) && values.locations.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = values.locations; + this.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = values.locations.slice(); for (let i = 0; i < values.locations.length; i++) { this.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location.add(i); @@ -642,7 +642,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.previews) && values.previews.every(v => v instanceof Link || v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews; + this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews.slice(); for (let i = 0; i < values.previews.length; i++) { this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview.add(i); @@ -760,7 +760,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.summaries) && values.summaries.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = values.summaries; + this.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = values.summaries.slice(); } else { throw new TypeError( @@ -775,7 +775,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.tags) && values.tags.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = values.tags; + this.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = values.tags.slice(); for (let i = 0; i < values.tags.length; i++) { this.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag.add(i); @@ -828,7 +828,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.urls) && values.urls.every(v => v instanceof URL || v instanceof Link)) { // @ts-ignore: type is checked above. - this.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = values.urls; + this.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = values.urls.slice(); } else { throw new TypeError( @@ -864,7 +864,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.tos) && values.tos.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = values.tos; + this.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = values.tos.slice(); for (let i = 0; i < values.tos.length; i++) { this.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to.add(i); @@ -904,7 +904,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.btos) && values.btos.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = values.btos; + this.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = values.btos.slice(); for (let i = 0; i < values.btos.length; i++) { this.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto.add(i); @@ -944,7 +944,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.ccs) && values.ccs.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = values.ccs; + this.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = values.ccs.slice(); for (let i = 0; i < values.ccs.length; i++) { this.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc.add(i); @@ -984,7 +984,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.bccs) && values.bccs.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = values.bccs; + this.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = values.bccs.slice(); for (let i = 0; i < values.bccs.length; i++) { this.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc.add(i); @@ -1076,7 +1076,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.proofs) && values.proofs.every(v => v instanceof DataIntegrityProof || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = values.proofs; + this.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = values.proofs.slice(); for (let i = 0; i < values.proofs.length; i++) { this.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof.add(i); @@ -1095,7 +1095,8 @@ proofs?: (DataIntegrityProof | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -1139,13 +1140,13 @@ proofs?: (DataIntegrityProof | URL)[];} { id: values.id ?? this.id }, options ); - clone.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = this.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment;clone.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment = new Set(this.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment); + clone.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = this.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment.slice();clone.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment = new Set(this.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment); if (\\"attachments\\" in values && values.attachments != null) { if (Array.isArray(values.attachments) && values.attachments.every(v => v instanceof Object || v instanceof Link || v instanceof PropertyValue || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = values.attachments; + clone.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = values.attachments.slice(); clone.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment = new Set(); for (let i = 0; i < values.attachments.length; i++) { @@ -1159,7 +1160,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = this.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo;clone.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = new Set(this.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo); + clone.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = this.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo.slice();clone.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = new Set(this.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo); if (\\"attribution\\" in values && values.attribution != null) { if (values.attribution instanceof Application || values.attribution instanceof Group || values.attribution instanceof Organization || values.attribution instanceof Person || values.attribution instanceof Service || values.attribution instanceof URL) { // @ts-ignore: type is checked above. @@ -1186,7 +1187,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.attributions) && values.attributions.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = values.attributions; + clone.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = values.attributions.slice(); clone.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = new Set(); for (let i = 0; i < values.attributions.length; i++) { @@ -1200,7 +1201,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = this.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience;clone.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = new Set(this.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience); + clone.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = this.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience.slice();clone.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = new Set(this.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience); if (\\"audience\\" in values && values.audience != null) { if (values.audience instanceof Object || values.audience instanceof URL) { // @ts-ignore: type is checked above. @@ -1227,7 +1228,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.audiences) && values.audiences.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = values.audiences; + clone.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = values.audiences.slice(); clone.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = new Set(); for (let i = 0; i < values.audiences.length; i++) { @@ -1241,7 +1242,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content; + clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content.slice(); if (\\"content\\" in values && values.content != null) { if (typeof values.content === \\"string\\" || values.content instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -1268,7 +1269,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.contents) && values.contents.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents; + clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents.slice(); } else { throw new TypeError( @@ -1277,13 +1278,13 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = this.#_3mhZzGXSpQ431mBSz2kvych22v4e_context;clone.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context = new Set(this.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context); + clone.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = this.#_3mhZzGXSpQ431mBSz2kvych22v4e_context.slice();clone.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context = new Set(this.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context); if (\\"contexts\\" in values && values.contexts != null) { if (Array.isArray(values.contexts) && values.contexts.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = values.contexts; + clone.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = values.contexts.slice(); clone.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context = new Set(); for (let i = 0; i < values.contexts.length; i++) { @@ -1297,7 +1298,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name.slice(); if (\\"name\\" in values && values.name != null) { if (typeof values.name === \\"string\\" || values.name instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -1324,7 +1325,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.names) && values.names.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names.slice(); } else { throw new TypeError( @@ -1333,7 +1334,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_219RwDanjScTv5tYCjwGZVCM7KZ9_endTime = this.#_219RwDanjScTv5tYCjwGZVCM7KZ9_endTime; + clone.#_219RwDanjScTv5tYCjwGZVCM7KZ9_endTime = this.#_219RwDanjScTv5tYCjwGZVCM7KZ9_endTime.slice(); if (\\"endTime\\" in values && values.endTime != null) { if (isTemporalInstant(values.endTime)) { // @ts-ignore: type is checked above. @@ -1346,13 +1347,13 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = this.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator;clone.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator = new Set(this.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator); + clone.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = this.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator.slice();clone.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator = new Set(this.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator); if (\\"generators\\" in values && values.generators != null) { if (Array.isArray(values.generators) && values.generators.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = values.generators; + clone.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = values.generators.slice(); clone.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator = new Set(); for (let i = 0; i < values.generators.length; i++) { @@ -1366,7 +1367,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = this.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon;clone.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = new Set(this.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon); + clone.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = this.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon.slice();clone.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = new Set(this.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon); if (\\"icon\\" in values && values.icon != null) { if (values.icon instanceof Image || values.icon instanceof URL) { // @ts-ignore: type is checked above. @@ -1393,7 +1394,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.icons) && values.icons.every(v => v instanceof Image || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = values.icons; + clone.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = values.icons.slice(); clone.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = new Set(); for (let i = 0; i < values.icons.length; i++) { @@ -1407,7 +1408,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = this.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image;clone.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = new Set(this.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image); + clone.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = this.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image.slice();clone.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = new Set(this.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image); if (\\"image\\" in values && values.image != null) { if (values.image instanceof Image || values.image instanceof URL) { // @ts-ignore: type is checked above. @@ -1434,7 +1435,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.images) && values.images.every(v => v instanceof Image || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = values.images; + clone.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = values.images.slice(); clone.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = new Set(); for (let i = 0; i < values.images.length; i++) { @@ -1448,7 +1449,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = this.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo;clone.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = new Set(this.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo); + clone.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = this.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo.slice();clone.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = new Set(this.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo); if (\\"replyTarget\\" in values && values.replyTarget != null) { if (values.replyTarget instanceof Object || values.replyTarget instanceof Link || values.replyTarget instanceof URL) { // @ts-ignore: type is checked above. @@ -1475,7 +1476,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.replyTargets) && values.replyTargets.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = values.replyTargets; + clone.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = values.replyTargets.slice(); clone.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = new Set(); for (let i = 0; i < values.replyTargets.length; i++) { @@ -1489,7 +1490,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = this.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location;clone.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = new Set(this.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location); + clone.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = this.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location.slice();clone.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = new Set(this.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location); if (\\"location\\" in values && values.location != null) { if (values.location instanceof Object || values.location instanceof Link || values.location instanceof URL) { // @ts-ignore: type is checked above. @@ -1516,7 +1517,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.locations) && values.locations.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = values.locations; + clone.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = values.locations.slice(); clone.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = new Set(); for (let i = 0; i < values.locations.length; i++) { @@ -1530,7 +1531,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview;clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview); + clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview.slice();clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview); if (\\"preview\\" in values && values.preview != null) { if (values.preview instanceof Link || values.preview instanceof Object || values.preview instanceof URL) { // @ts-ignore: type is checked above. @@ -1557,7 +1558,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.previews) && values.previews.every(v => v instanceof Link || v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews; + clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews.slice(); clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(); for (let i = 0; i < values.previews.length; i++) { @@ -1571,7 +1572,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_5e258TDXtuhaFRPZiGoDfEpjdMr_published = this.#_5e258TDXtuhaFRPZiGoDfEpjdMr_published; + clone.#_5e258TDXtuhaFRPZiGoDfEpjdMr_published = this.#_5e258TDXtuhaFRPZiGoDfEpjdMr_published.slice(); if (\\"published\\" in values && values.published != null) { if (isTemporalInstant(values.published)) { // @ts-ignore: type is checked above. @@ -1584,7 +1585,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_7UpwM3JWcXhADcscukEehBorf6k_replies = this.#_7UpwM3JWcXhADcscukEehBorf6k_replies;clone.#_trust_7UpwM3JWcXhADcscukEehBorf6k_replies = new Set(this.#_trust_7UpwM3JWcXhADcscukEehBorf6k_replies); + clone.#_7UpwM3JWcXhADcscukEehBorf6k_replies = this.#_7UpwM3JWcXhADcscukEehBorf6k_replies.slice();clone.#_trust_7UpwM3JWcXhADcscukEehBorf6k_replies = new Set(this.#_trust_7UpwM3JWcXhADcscukEehBorf6k_replies); if (\\"replies\\" in values && values.replies != null) { if (values.replies instanceof Collection || values.replies instanceof URL) { // @ts-ignore: type is checked above. @@ -1597,7 +1598,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3kAfck9PcEYt2L7xug5y99YPbANs_shares = this.#_3kAfck9PcEYt2L7xug5y99YPbANs_shares;clone.#_trust_3kAfck9PcEYt2L7xug5y99YPbANs_shares = new Set(this.#_trust_3kAfck9PcEYt2L7xug5y99YPbANs_shares); + clone.#_3kAfck9PcEYt2L7xug5y99YPbANs_shares = this.#_3kAfck9PcEYt2L7xug5y99YPbANs_shares.slice();clone.#_trust_3kAfck9PcEYt2L7xug5y99YPbANs_shares = new Set(this.#_trust_3kAfck9PcEYt2L7xug5y99YPbANs_shares); if (\\"shares\\" in values && values.shares != null) { if (values.shares instanceof Collection || values.shares instanceof URL) { // @ts-ignore: type is checked above. @@ -1610,7 +1611,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes = this.#_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes;clone.#_trust_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes = new Set(this.#_trust_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes); + clone.#_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes = this.#_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes.slice();clone.#_trust_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes = new Set(this.#_trust_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes); if (\\"likes\\" in values && values.likes != null) { if (values.likes instanceof Collection || values.likes instanceof URL) { // @ts-ignore: type is checked above. @@ -1623,7 +1624,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions = this.#_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions;clone.#_trust_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions = new Set(this.#_trust_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions); + clone.#_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions = this.#_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions.slice();clone.#_trust_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions = new Set(this.#_trust_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions); if (\\"emojiReactions\\" in values && values.emojiReactions != null) { if (values.emojiReactions instanceof Collection || values.emojiReactions instanceof URL) { // @ts-ignore: type is checked above. @@ -1636,7 +1637,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_2w3Jmue4up8iVDUA51WZqomEF438_startTime = this.#_2w3Jmue4up8iVDUA51WZqomEF438_startTime; + clone.#_2w3Jmue4up8iVDUA51WZqomEF438_startTime = this.#_2w3Jmue4up8iVDUA51WZqomEF438_startTime.slice(); if (\\"startTime\\" in values && values.startTime != null) { if (isTemporalInstant(values.startTime)) { // @ts-ignore: type is checked above. @@ -1649,7 +1650,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = this.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary; + clone.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = this.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary.slice(); if (\\"summary\\" in values && values.summary != null) { if (typeof values.summary === \\"string\\" || values.summary instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -1676,7 +1677,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.summaries) && values.summaries.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = values.summaries; + clone.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = values.summaries.slice(); } else { throw new TypeError( @@ -1685,13 +1686,13 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = this.#_5chuqj6s95p5gg2sk1HntGfarRf_tag;clone.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag = new Set(this.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag); + clone.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = this.#_5chuqj6s95p5gg2sk1HntGfarRf_tag.slice();clone.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag = new Set(this.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag); if (\\"tags\\" in values && values.tags != null) { if (Array.isArray(values.tags) && values.tags.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = values.tags; + clone.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = values.tags.slice(); clone.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag = new Set(); for (let i = 0; i < values.tags.length; i++) { @@ -1705,7 +1706,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_385aB7ySixcf5Un6z3VsWmThgCzQ_updated = this.#_385aB7ySixcf5Un6z3VsWmThgCzQ_updated; + clone.#_385aB7ySixcf5Un6z3VsWmThgCzQ_updated = this.#_385aB7ySixcf5Un6z3VsWmThgCzQ_updated.slice(); if (\\"updated\\" in values && values.updated != null) { if (isTemporalInstant(values.updated)) { // @ts-ignore: type is checked above. @@ -1718,7 +1719,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = this.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url; + clone.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = this.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url.slice(); if (\\"url\\" in values && values.url != null) { if (values.url instanceof URL || values.url instanceof Link) { // @ts-ignore: type is checked above. @@ -1745,7 +1746,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.urls) && values.urls.every(v => v instanceof URL || v instanceof Link)) { // @ts-ignore: type is checked above. - clone.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = values.urls; + clone.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = values.urls.slice(); } else { throw new TypeError( @@ -1754,7 +1755,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = this.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to;clone.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = new Set(this.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to); + clone.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = this.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to.slice();clone.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = new Set(this.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to); if (\\"to\\" in values && values.to != null) { if (values.to instanceof Object || values.to instanceof URL) { // @ts-ignore: type is checked above. @@ -1781,7 +1782,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.tos) && values.tos.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = values.tos; + clone.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = values.tos.slice(); clone.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = new Set(); for (let i = 0; i < values.tos.length; i++) { @@ -1795,7 +1796,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = this.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto;clone.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = new Set(this.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto); + clone.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = this.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto.slice();clone.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = new Set(this.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto); if (\\"bto\\" in values && values.bto != null) { if (values.bto instanceof Object || values.bto instanceof URL) { // @ts-ignore: type is checked above. @@ -1822,7 +1823,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.btos) && values.btos.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = values.btos; + clone.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = values.btos.slice(); clone.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = new Set(); for (let i = 0; i < values.btos.length; i++) { @@ -1836,7 +1837,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = this.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc;clone.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = new Set(this.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc); + clone.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = this.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc.slice();clone.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = new Set(this.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc); if (\\"cc\\" in values && values.cc != null) { if (values.cc instanceof Object || values.cc instanceof URL) { // @ts-ignore: type is checked above. @@ -1863,7 +1864,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.ccs) && values.ccs.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = values.ccs; + clone.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = values.ccs.slice(); clone.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = new Set(); for (let i = 0; i < values.ccs.length; i++) { @@ -1877,7 +1878,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = this.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc;clone.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = new Set(this.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc); + clone.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = this.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc.slice();clone.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = new Set(this.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc); if (\\"bcc\\" in values && values.bcc != null) { if (values.bcc instanceof Object || values.bcc instanceof URL) { // @ts-ignore: type is checked above. @@ -1904,7 +1905,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.bccs) && values.bccs.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = values.bccs; + clone.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = values.bccs.slice(); clone.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = new Set(); for (let i = 0; i < values.bccs.length; i++) { @@ -1918,7 +1919,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType; + clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType.slice(); if (\\"mediaType\\" in values && values.mediaType != null) { if (typeof values.mediaType === \\"string\\") { // @ts-ignore: type is checked above. @@ -1931,7 +1932,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3bNvLMBN1bCJETiTihM3wvi1B2JX_duration = this.#_3bNvLMBN1bCJETiTihM3wvi1B2JX_duration; + clone.#_3bNvLMBN1bCJETiTihM3wvi1B2JX_duration = this.#_3bNvLMBN1bCJETiTihM3wvi1B2JX_duration.slice(); if (\\"duration\\" in values && values.duration != null) { if (isTemporalDuration(values.duration)) { // @ts-ignore: type is checked above. @@ -1944,7 +1945,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_u8gdcDTtChQ4tbSQMXc4cYWyum7_sensitive = this.#_u8gdcDTtChQ4tbSQMXc4cYWyum7_sensitive; + clone.#_u8gdcDTtChQ4tbSQMXc4cYWyum7_sensitive = this.#_u8gdcDTtChQ4tbSQMXc4cYWyum7_sensitive.slice(); if (\\"sensitive\\" in values && values.sensitive != null) { if (typeof values.sensitive === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -1957,7 +1958,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_2ZwCFoS787v8y8bXKjMoE6MAbrEB_source = this.#_2ZwCFoS787v8y8bXKjMoE6MAbrEB_source; + clone.#_2ZwCFoS787v8y8bXKjMoE6MAbrEB_source = this.#_2ZwCFoS787v8y8bXKjMoE6MAbrEB_source.slice(); if (\\"source\\" in values && values.source != null) { if (values.source instanceof Source) { // @ts-ignore: type is checked above. @@ -1970,7 +1971,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = this.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof;clone.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = new Set(this.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof); + clone.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = this.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof.slice();clone.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = new Set(this.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof); if (\\"proof\\" in values && values.proof != null) { if (values.proof instanceof DataIntegrityProof || values.proof instanceof URL) { // @ts-ignore: type is checked above. @@ -1997,7 +1998,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.proofs) && values.proofs.every(v => v instanceof DataIntegrityProof || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = values.proofs; + clone.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = values.proofs.slice(); clone.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = new Set(); for (let i = 0; i < values.proofs.length; i++) { @@ -11821,7 +11822,8 @@ proofs?: (DataIntegrityProof | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -12183,7 +12185,8 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -12221,7 +12224,7 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as ChatMessage;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl; + const clone = super.clone(values, options) as unknown as ChatMessage;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl.slice(); if (\\"quoteUrl\\" in values && values.quoteUrl != null) { if (values.quoteUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -12718,7 +12721,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.actors) && values.actors.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = values.actors; + this.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = values.actors.slice(); for (let i = 0; i < values.actors.length; i++) { this.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor.add(i); @@ -12758,7 +12761,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.objects) && values.objects.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects; + this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects.slice(); for (let i = 0; i < values.objects.length; i++) { this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object.add(i); @@ -12798,7 +12801,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.targets) && values.targets.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = values.targets; + this.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = values.targets.slice(); for (let i = 0; i < values.targets.length; i++) { this.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target.add(i); @@ -12838,7 +12841,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.results) && values.results.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = values.results; + this.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = values.results.slice(); for (let i = 0; i < values.results.length; i++) { this.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result.add(i); @@ -12878,7 +12881,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.origins) && values.origins.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = values.origins; + this.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = values.origins.slice(); for (let i = 0; i < values.origins.length; i++) { this.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin.add(i); @@ -12918,7 +12921,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.instruments) && values.instruments.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = values.instruments; + this.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = values.instruments.slice(); for (let i = 0; i < values.instruments.length; i++) { this.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument.add(i); @@ -12937,7 +12940,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -12981,7 +12985,7 @@ instruments?: (Object | URL)[];} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Activity;clone.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = this.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor;clone.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = new Set(this.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor); + const clone = super.clone(values, options) as unknown as Activity;clone.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = this.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor.slice();clone.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = new Set(this.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor); if (\\"actor\\" in values && values.actor != null) { if (values.actor instanceof Application || values.actor instanceof Group || values.actor instanceof Organization || values.actor instanceof Person || values.actor instanceof Service || values.actor instanceof URL) { // @ts-ignore: type is checked above. @@ -13008,7 +13012,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.actors) && values.actors.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = values.actors; + clone.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = values.actors.slice(); clone.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = new Set(); for (let i = 0; i < values.actors.length; i++) { @@ -13022,7 +13026,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object;clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object); + clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object.slice();clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object); if (\\"object\\" in values && values.object != null) { if (values.object instanceof Object || values.object instanceof URL) { // @ts-ignore: type is checked above. @@ -13049,7 +13053,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.objects) && values.objects.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects; + clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects.slice(); clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(); for (let i = 0; i < values.objects.length; i++) { @@ -13063,7 +13067,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = this.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target;clone.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = new Set(this.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target); + clone.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = this.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target.slice();clone.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = new Set(this.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target); if (\\"target\\" in values && values.target != null) { if (values.target instanceof Object || values.target instanceof URL) { // @ts-ignore: type is checked above. @@ -13090,7 +13094,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.targets) && values.targets.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = values.targets; + clone.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = values.targets.slice(); clone.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = new Set(); for (let i = 0; i < values.targets.length; i++) { @@ -13104,7 +13108,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = this.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result;clone.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = new Set(this.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result); + clone.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = this.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result.slice();clone.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = new Set(this.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result); if (\\"result\\" in values && values.result != null) { if (values.result instanceof Object || values.result instanceof URL) { // @ts-ignore: type is checked above. @@ -13131,7 +13135,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.results) && values.results.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = values.results; + clone.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = values.results.slice(); clone.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = new Set(); for (let i = 0; i < values.results.length; i++) { @@ -13145,7 +13149,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = this.#_25zu2s3VxVujgEKqrDycjE284XQR_origin;clone.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin = new Set(this.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin); + clone.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = this.#_25zu2s3VxVujgEKqrDycjE284XQR_origin.slice();clone.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin = new Set(this.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin); if (\\"origin\\" in values && values.origin != null) { if (values.origin instanceof Object || values.origin instanceof URL) { // @ts-ignore: type is checked above. @@ -13172,7 +13176,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.origins) && values.origins.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = values.origins; + clone.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = values.origins.slice(); clone.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin = new Set(); for (let i = 0; i < values.origins.length; i++) { @@ -13186,7 +13190,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = this.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument;clone.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = new Set(this.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument); + clone.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = this.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument.slice();clone.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = new Set(this.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument); if (\\"instrument\\" in values && values.instrument != null) { if (values.instrument instanceof Object || values.instrument instanceof URL) { // @ts-ignore: type is checked above. @@ -13213,7 +13217,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.instruments) && values.instruments.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = values.instruments; + clone.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = values.instruments.slice(); clone.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = new Set(); for (let i = 0; i < values.instruments.length; i++) { @@ -16178,7 +16182,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -16592,7 +16597,8 @@ name?: string | LanguageString | null;value?: string | LanguageString | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -16620,7 +16626,7 @@ name?: string | LanguageString | null;value?: string | LanguageString | null;} { id: values.id ?? this.id }, options ); - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name.slice(); if (\\"name\\" in values && values.name != null) { if (typeof values.name === \\"string\\" || values.name instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -16633,7 +16639,7 @@ name?: string | LanguageString | null;value?: string | LanguageString | null;} ); } } - clone.#_2cSy2magg4iZ7zLaG8U7DiJMoCkx_value = this.#_2cSy2magg4iZ7zLaG8U7DiJMoCkx_value; + clone.#_2cSy2magg4iZ7zLaG8U7DiJMoCkx_value = this.#_2cSy2magg4iZ7zLaG8U7DiJMoCkx_value.slice(); if (\\"value\\" in values && values.value != null) { if (typeof values.value === \\"string\\" || values.value instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -17231,7 +17237,7 @@ endpoints?: (URL)[];} if (Array.isArray(values.endpoints) && values.endpoints.every(v => v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = values.endpoints; + this.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = values.endpoints.slice(); } else { throw new TypeError( @@ -17246,7 +17252,8 @@ endpoints?: (URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -17275,7 +17282,7 @@ endpoints?: (URL)[];} { id: values.id ?? this.id }, options ); - clone.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = this.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint; + clone.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = this.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint.slice(); if (\\"endpoint\\" in values && values.endpoint != null) { if (values.endpoint instanceof URL) { // @ts-ignore: type is checked above. @@ -17302,7 +17309,7 @@ endpoints?: (URL)[];} if (Array.isArray(values.endpoints) && values.endpoints.every(v => v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = values.endpoints; + clone.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = values.endpoints.slice(); } else { throw new TypeError( @@ -17681,7 +17688,8 @@ endpoints?: (URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -18111,7 +18119,8 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -18139,7 +18148,7 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | { id: values.id ?? this.id }, options ); - clone.#_3RurJsa7tnptyqMFR5hDGcP9pMs5_cryptosuite = this.#_3RurJsa7tnptyqMFR5hDGcP9pMs5_cryptosuite; + clone.#_3RurJsa7tnptyqMFR5hDGcP9pMs5_cryptosuite = this.#_3RurJsa7tnptyqMFR5hDGcP9pMs5_cryptosuite.slice(); if (\\"cryptosuite\\" in values && values.cryptosuite != null) { if (values.cryptosuite == \\"eddsa-jcs-2022\\") { // @ts-ignore: type is checked above. @@ -18152,7 +18161,7 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | ); } } - clone.#_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod = this.#_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod;clone.#_trust_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod = new Set(this.#_trust_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod); + clone.#_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod = this.#_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod.slice();clone.#_trust_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod = new Set(this.#_trust_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod); if (\\"verificationMethod\\" in values && values.verificationMethod != null) { if (values.verificationMethod instanceof Multikey || values.verificationMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -18165,7 +18174,7 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | ); } } - clone.#_2AeEnPcAvVrPEuKbpmn9ZKNmWHKb_proofPurpose = this.#_2AeEnPcAvVrPEuKbpmn9ZKNmWHKb_proofPurpose; + clone.#_2AeEnPcAvVrPEuKbpmn9ZKNmWHKb_proofPurpose = this.#_2AeEnPcAvVrPEuKbpmn9ZKNmWHKb_proofPurpose.slice(); if (\\"proofPurpose\\" in values && values.proofPurpose != null) { if (values.proofPurpose === \\"assertionMethod\\" || values.proofPurpose === \\"authentication\\" || values.proofPurpose === \\"capabilityInvocation\\" || values.proofPurpose === \\"capabilityDelegation\\" || @@ -18180,7 +18189,7 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | ); } } - clone.#_3CjFK5vfKpX4HQuNh2b18TykoVLq_proofValue = this.#_3CjFK5vfKpX4HQuNh2b18TykoVLq_proofValue; + clone.#_3CjFK5vfKpX4HQuNh2b18TykoVLq_proofValue = this.#_3CjFK5vfKpX4HQuNh2b18TykoVLq_proofValue.slice(); if (\\"proofValue\\" in values && values.proofValue != null) { if (values.proofValue instanceof Uint8Array) { // @ts-ignore: type is checked above. @@ -18193,7 +18202,7 @@ cryptosuite?: \\"eddsa-jcs-2022\\" | null;verificationMethod?: Multikey | URL | ); } } - clone.#_3qzP3ukEZoUziK5FEiA1RhU4aqac = this.#_3qzP3ukEZoUziK5FEiA1RhU4aqac; + clone.#_3qzP3ukEZoUziK5FEiA1RhU4aqac = this.#_3qzP3ukEZoUziK5FEiA1RhU4aqac.slice(); if (\\"created\\" in values && values.created != null) { if (isTemporalInstant(values.created)) { // @ts-ignore: type is checked above. @@ -19156,7 +19165,8 @@ owner?: Application | Group | Organization | Person | Service | URL | null;publi * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -19184,7 +19194,7 @@ owner?: Application | Group | Organization | Person | Service | URL | null;publi { id: values.id ?? this.id }, options ); - clone.#_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner = this.#_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner;clone.#_trust_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner = new Set(this.#_trust_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner); + clone.#_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner = this.#_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner.slice();clone.#_trust_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner = new Set(this.#_trust_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner); if (\\"owner\\" in values && values.owner != null) { if (values.owner instanceof Application || values.owner instanceof Group || values.owner instanceof Organization || values.owner instanceof Person || values.owner instanceof Service || values.owner instanceof URL) { // @ts-ignore: type is checked above. @@ -19197,7 +19207,7 @@ owner?: Application | Group | Organization | Person | Service | URL | null;publi ); } } - clone.#_2fE2QMDdg6KFGqa4NEC3TmjApSAD_publicKeyPem = this.#_2fE2QMDdg6KFGqa4NEC3TmjApSAD_publicKeyPem; + clone.#_2fE2QMDdg6KFGqa4NEC3TmjApSAD_publicKeyPem = this.#_2fE2QMDdg6KFGqa4NEC3TmjApSAD_publicKeyPem.slice(); if (\\"publicKey\\" in values && values.publicKey != null) { if ( // @ts-ignore: CryptoKey exists in the global scope. @@ -20071,7 +20081,8 @@ controller?: Application | Group | Organization | Person | Service | URL | null; * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -20099,7 +20110,7 @@ controller?: Application | Group | Organization | Person | Service | URL | null; { id: values.id ?? this.id }, options ); - clone.#_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller = this.#_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller;clone.#_trust_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller = new Set(this.#_trust_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller); + clone.#_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller = this.#_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller.slice();clone.#_trust_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller = new Set(this.#_trust_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller); if (\\"controller\\" in values && values.controller != null) { if (values.controller instanceof Application || values.controller instanceof Group || values.controller instanceof Organization || values.controller instanceof Person || values.controller instanceof Service || values.controller instanceof URL) { // @ts-ignore: type is checked above. @@ -20112,7 +20123,7 @@ controller?: Application | Group | Organization | Person | Service | URL | null; ); } } - clone.#_4XLHbsR2gLVWU3NpEqKt9wANzn4F_publicKeyMultibase = this.#_4XLHbsR2gLVWU3NpEqKt9wANzn4F_publicKeyMultibase; + clone.#_4XLHbsR2gLVWU3NpEqKt9wANzn4F_publicKeyMultibase = this.#_4XLHbsR2gLVWU3NpEqKt9wANzn4F_publicKeyMultibase.slice(); if (\\"publicKey\\" in values && values.publicKey != null) { if ( // @ts-ignore: CryptoKey exists in the global scope. @@ -20911,7 +20922,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -21257,7 +21269,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -21598,7 +21611,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -22004,7 +22018,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -22040,7 +22054,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -22080,7 +22094,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -22203,7 +22217,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -22321,7 +22335,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -22361,7 +22375,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -22406,7 +22420,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -22449,7 +22464,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Application;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Application;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if (\\"preferredUsername\\" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === \\"string\\" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -22476,7 +22491,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -22485,7 +22500,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if (\\"publicKey\\" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -22512,7 +22527,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -22526,7 +22541,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if (\\"assertionMethod\\" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -22553,7 +22568,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -22567,7 +22582,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if (\\"manuallyApprovesFollowers\\" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -22580,7 +22595,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if (\\"inbox\\" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -22593,7 +22608,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if (\\"outbox\\" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -22606,7 +22621,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if (\\"following\\" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -22619,7 +22634,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if (\\"followers\\" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -22632,7 +22647,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if (\\"liked\\" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -22645,7 +22660,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if (\\"featured\\" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -22658,7 +22673,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if (\\"featuredTags\\" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -22671,13 +22686,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if (\\"streams\\" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -22691,7 +22706,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if (\\"endpoints\\" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -22704,7 +22719,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if (\\"discoverable\\" in values && values.discoverable != null) { if (typeof values.discoverable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -22717,7 +22732,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if (\\"suspended\\" in values && values.suspended != null) { if (typeof values.suspended === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -22730,7 +22745,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if (\\"memorial\\" in values && values.memorial != null) { if (typeof values.memorial === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -22743,7 +22758,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if (\\"indexable\\" in values && values.indexable != null) { if (typeof values.indexable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -22756,7 +22771,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if (\\"successor\\" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -22769,7 +22784,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if (\\"alias\\" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -22796,7 +22811,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -22810,7 +22825,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if (\\"service\\" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -22837,7 +22852,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -22851,7 +22866,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if (\\"followedMessage\\" in values && values.followedMessage != null) { if (typeof values.followedMessage === \\"string\\") { // @ts-ignore: type is checked above. @@ -22864,7 +22879,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if (\\"cat\\" in values && values.cat != null) { if (typeof values.cat === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -28882,7 +28897,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -29235,7 +29251,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -29581,7 +29598,8 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -29619,7 +29637,7 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Article;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl; + const clone = super.clone(values, options) as unknown as Article;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl.slice(); if (\\"quoteUrl\\" in values && values.quoteUrl != null) { if (values.quoteUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -30094,7 +30112,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -30132,7 +30151,7 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Document;clone.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width = this.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width; + const clone = super.clone(values, options) as unknown as Document;clone.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width = this.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width.slice(); if (\\"width\\" in values && values.width != null) { if (typeof values.width === \\"number\\" && Number.isInteger(values.width) && values.width >= 0) { // @ts-ignore: type is checked above. @@ -30145,7 +30164,7 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu ); } } - clone.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height = this.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height; + clone.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height = this.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height.slice(); if (\\"height\\" in values && values.height != null) { if (typeof values.height === \\"number\\" && Number.isInteger(values.height) && values.height >= 0) { // @ts-ignore: type is checked above. @@ -30665,7 +30684,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -31016,7 +31036,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -31362,7 +31383,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -31788,7 +31810,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); for (let i = 0; i < values.items.length; i++) { this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.add(i); @@ -31911,7 +31933,8 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -31949,7 +31972,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Collection;clone.#_XDbmNDuWHmrhqH712zqtecdbv1V_totalItems = this.#_XDbmNDuWHmrhqH712zqtecdbv1V_totalItems; + const clone = super.clone(values, options) as unknown as Collection;clone.#_XDbmNDuWHmrhqH712zqtecdbv1V_totalItems = this.#_XDbmNDuWHmrhqH712zqtecdbv1V_totalItems.slice(); if (\\"totalItems\\" in values && values.totalItems != null) { if (typeof values.totalItems === \\"number\\" && Number.isInteger(values.totalItems) && values.totalItems >= 0) { // @ts-ignore: type is checked above. @@ -31962,7 +31985,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3UyUdxnyn6cDn53QKrh4MBiearma_current = this.#_3UyUdxnyn6cDn53QKrh4MBiearma_current;clone.#_trust_3UyUdxnyn6cDn53QKrh4MBiearma_current = new Set(this.#_trust_3UyUdxnyn6cDn53QKrh4MBiearma_current); + clone.#_3UyUdxnyn6cDn53QKrh4MBiearma_current = this.#_3UyUdxnyn6cDn53QKrh4MBiearma_current.slice();clone.#_trust_3UyUdxnyn6cDn53QKrh4MBiearma_current = new Set(this.#_trust_3UyUdxnyn6cDn53QKrh4MBiearma_current); if (\\"current\\" in values && values.current != null) { if (values.current instanceof CollectionPage || values.current instanceof URL) { // @ts-ignore: type is checked above. @@ -31975,7 +31998,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_J52RqweMe6hhv7RnLJMC8BExTE5_first = this.#_J52RqweMe6hhv7RnLJMC8BExTE5_first;clone.#_trust_J52RqweMe6hhv7RnLJMC8BExTE5_first = new Set(this.#_trust_J52RqweMe6hhv7RnLJMC8BExTE5_first); + clone.#_J52RqweMe6hhv7RnLJMC8BExTE5_first = this.#_J52RqweMe6hhv7RnLJMC8BExTE5_first.slice();clone.#_trust_J52RqweMe6hhv7RnLJMC8BExTE5_first = new Set(this.#_trust_J52RqweMe6hhv7RnLJMC8BExTE5_first); if (\\"first\\" in values && values.first != null) { if (values.first instanceof CollectionPage || values.first instanceof URL) { // @ts-ignore: type is checked above. @@ -31988,7 +32011,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last = this.#_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last;clone.#_trust_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last = new Set(this.#_trust_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last); + clone.#_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last = this.#_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last.slice();clone.#_trust_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last = new Set(this.#_trust_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last); if (\\"last\\" in values && values.last != null) { if (values.last instanceof CollectionPage || values.last instanceof URL) { // @ts-ignore: type is checked above. @@ -32001,13 +32024,13 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items;clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); + clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.slice();clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); if (\\"items\\" in values && values.items != null) { if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(); for (let i = 0; i < values.items.length; i++) { @@ -32021,7 +32044,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf = this.#_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf;clone.#_trust_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf = new Set(this.#_trust_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf); + clone.#_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf = this.#_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf.slice();clone.#_trust_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf = new Set(this.#_trust_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf); if (\\"likesOf\\" in values && values.likesOf != null) { if (values.likesOf instanceof Object || values.likesOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32034,7 +32057,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf = this.#_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf;clone.#_trust_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf = new Set(this.#_trust_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf); + clone.#_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf = this.#_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf.slice();clone.#_trust_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf = new Set(this.#_trust_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf); if (\\"sharesOf\\" in values && values.sharesOf != null) { if (values.sharesOf instanceof Object || values.sharesOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32047,7 +32070,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf = this.#_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf;clone.#_trust_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf = new Set(this.#_trust_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf); + clone.#_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf = this.#_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf.slice();clone.#_trust_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf = new Set(this.#_trust_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf); if (\\"repliesOf\\" in values && values.repliesOf != null) { if (values.repliesOf instanceof Object || values.repliesOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32060,7 +32083,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf = this.#_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf;clone.#_trust_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf = new Set(this.#_trust_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf); + clone.#_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf = this.#_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf.slice();clone.#_trust_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf = new Set(this.#_trust_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf); if (\\"inboxOf\\" in values && values.inboxOf != null) { if (values.inboxOf instanceof Object || values.inboxOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32073,7 +32096,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf = this.#_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf;clone.#_trust_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf = new Set(this.#_trust_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf); + clone.#_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf = this.#_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf.slice();clone.#_trust_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf = new Set(this.#_trust_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf); if (\\"outboxOf\\" in values && values.outboxOf != null) { if (values.outboxOf instanceof Object || values.outboxOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32086,7 +32109,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf = this.#_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf;clone.#_trust_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf = new Set(this.#_trust_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf); + clone.#_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf = this.#_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf.slice();clone.#_trust_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf = new Set(this.#_trust_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf); if (\\"followersOf\\" in values && values.followersOf != null) { if (values.followersOf instanceof Object || values.followersOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32099,7 +32122,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf = this.#_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf;clone.#_trust_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf = new Set(this.#_trust_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf); + clone.#_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf = this.#_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf.slice();clone.#_trust_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf = new Set(this.#_trust_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf); if (\\"followingOf\\" in values && values.followingOf != null) { if (values.followingOf instanceof Object || values.followingOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32112,7 +32135,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf = this.#_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf;clone.#_trust_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf = new Set(this.#_trust_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf); + clone.#_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf = this.#_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf.slice();clone.#_trust_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf = new Set(this.#_trust_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf); if (\\"likedOf\\" in values && values.likedOf != null) { if (values.likedOf instanceof Object || values.likedOf instanceof URL) { // @ts-ignore: type is checked above. @@ -36436,7 +36459,8 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -36474,7 +36498,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as CollectionPage;clone.#_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf = this.#_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf;clone.#_trust_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf = new Set(this.#_trust_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf); + const clone = super.clone(values, options) as unknown as CollectionPage;clone.#_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf = this.#_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf.slice();clone.#_trust_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf = new Set(this.#_trust_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf); if (\\"partOf\\" in values && values.partOf != null) { if (values.partOf instanceof Collection || values.partOf instanceof URL) { // @ts-ignore: type is checked above. @@ -36487,7 +36511,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next = this.#_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next;clone.#_trust_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next = new Set(this.#_trust_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next); + clone.#_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next = this.#_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next.slice();clone.#_trust_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next = new Set(this.#_trust_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next); if (\\"next\\" in values && values.next != null) { if (values.next instanceof CollectionPage || values.next instanceof URL) { // @ts-ignore: type is checked above. @@ -36500,7 +36524,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev = this.#_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev;clone.#_trust_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev = new Set(this.#_trust_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev); + clone.#_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev = this.#_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev.slice();clone.#_trust_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev = new Set(this.#_trust_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev); if (\\"prev\\" in values && values.prev != null) { if (values.prev instanceof CollectionPage || values.prev instanceof URL) { // @ts-ignore: type is checked above. @@ -37782,7 +37806,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -38122,7 +38147,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -38460,7 +38486,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -38930,7 +38957,8 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -38958,7 +38986,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint { id: values.id ?? this.id }, options ); - clone.#_2JCYDbSxEHCCLdBYed33cCETfGyR_proxyUrl = this.#_2JCYDbSxEHCCLdBYed33cCETfGyR_proxyUrl; + clone.#_2JCYDbSxEHCCLdBYed33cCETfGyR_proxyUrl = this.#_2JCYDbSxEHCCLdBYed33cCETfGyR_proxyUrl.slice(); if (\\"proxyUrl\\" in values && values.proxyUrl != null) { if (values.proxyUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -38971,7 +38999,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_25S6UmgzDead8hxL5sQFezZTAusd_oauthAuthorizationEndpoint = this.#_25S6UmgzDead8hxL5sQFezZTAusd_oauthAuthorizationEndpoint; + clone.#_25S6UmgzDead8hxL5sQFezZTAusd_oauthAuthorizationEndpoint = this.#_25S6UmgzDead8hxL5sQFezZTAusd_oauthAuthorizationEndpoint.slice(); if (\\"oauthAuthorizationEndpoint\\" in values && values.oauthAuthorizationEndpoint != null) { if (values.oauthAuthorizationEndpoint instanceof URL) { // @ts-ignore: type is checked above. @@ -38984,7 +39012,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_iAMxqrSba7yBCRB1FZ5kEVdKEZ3_oauthTokenEndpoint = this.#_iAMxqrSba7yBCRB1FZ5kEVdKEZ3_oauthTokenEndpoint; + clone.#_iAMxqrSba7yBCRB1FZ5kEVdKEZ3_oauthTokenEndpoint = this.#_iAMxqrSba7yBCRB1FZ5kEVdKEZ3_oauthTokenEndpoint.slice(); if (\\"oauthTokenEndpoint\\" in values && values.oauthTokenEndpoint != null) { if (values.oauthTokenEndpoint instanceof URL) { // @ts-ignore: type is checked above. @@ -38997,7 +39025,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_8Bx9qN8oU7Bpt2xi6khaxWp1gMr_provideClientKey = this.#_8Bx9qN8oU7Bpt2xi6khaxWp1gMr_provideClientKey; + clone.#_8Bx9qN8oU7Bpt2xi6khaxWp1gMr_provideClientKey = this.#_8Bx9qN8oU7Bpt2xi6khaxWp1gMr_provideClientKey.slice(); if (\\"provideClientKey\\" in values && values.provideClientKey != null) { if (values.provideClientKey instanceof URL) { // @ts-ignore: type is checked above. @@ -39010,7 +39038,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_3dU7PMVQZJpsCpo2F4RQXxBXdPmS_signClientKey = this.#_3dU7PMVQZJpsCpo2F4RQXxBXdPmS_signClientKey; + clone.#_3dU7PMVQZJpsCpo2F4RQXxBXdPmS_signClientKey = this.#_3dU7PMVQZJpsCpo2F4RQXxBXdPmS_signClientKey.slice(); if (\\"signClientKey\\" in values && values.signClientKey != null) { if (values.signClientKey instanceof URL) { // @ts-ignore: type is checked above. @@ -39023,7 +39051,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_3JprUSDLVqqX4dwHRi37qGZZCRCc_sharedInbox = this.#_3JprUSDLVqqX4dwHRi37qGZZCRCc_sharedInbox; + clone.#_3JprUSDLVqqX4dwHRi37qGZZCRCc_sharedInbox = this.#_3JprUSDLVqqX4dwHRi37qGZZCRCc_sharedInbox.slice(); if (\\"sharedInbox\\" in values && values.sharedInbox != null) { if (values.sharedInbox instanceof URL) { // @ts-ignore: type is checked above. @@ -39971,7 +39999,8 @@ proofs?: (DataIntegrityProof | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -40323,7 +40352,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -40665,7 +40695,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -41071,7 +41102,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -41107,7 +41138,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -41147,7 +41178,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -41270,7 +41301,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -41388,7 +41419,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -41428,7 +41459,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -41473,7 +41504,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -41516,7 +41548,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Group;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Group;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if (\\"preferredUsername\\" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === \\"string\\" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -41543,7 +41575,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -41552,7 +41584,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if (\\"publicKey\\" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -41579,7 +41611,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -41593,7 +41625,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if (\\"assertionMethod\\" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -41620,7 +41652,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -41634,7 +41666,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if (\\"manuallyApprovesFollowers\\" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -41647,7 +41679,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if (\\"inbox\\" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -41660,7 +41692,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if (\\"outbox\\" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -41673,7 +41705,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if (\\"following\\" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -41686,7 +41718,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if (\\"followers\\" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -41699,7 +41731,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if (\\"liked\\" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -41712,7 +41744,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if (\\"featured\\" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -41725,7 +41757,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if (\\"featuredTags\\" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -41738,13 +41770,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if (\\"streams\\" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -41758,7 +41790,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if (\\"endpoints\\" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -41771,7 +41803,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if (\\"discoverable\\" in values && values.discoverable != null) { if (typeof values.discoverable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -41784,7 +41816,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if (\\"suspended\\" in values && values.suspended != null) { if (typeof values.suspended === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -41797,7 +41829,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if (\\"memorial\\" in values && values.memorial != null) { if (typeof values.memorial === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -41810,7 +41842,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if (\\"indexable\\" in values && values.indexable != null) { if (typeof values.indexable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -41823,7 +41855,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if (\\"successor\\" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -41836,7 +41868,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if (\\"alias\\" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -41863,7 +41895,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -41877,7 +41909,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if (\\"service\\" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -41904,7 +41936,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -41918,7 +41950,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if (\\"followedMessage\\" in values && values.followedMessage != null) { if (typeof values.followedMessage === \\"string\\") { // @ts-ignore: type is checked above. @@ -41931,7 +41963,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if (\\"cat\\" in values && values.cat != null) { if (typeof values.cat === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -48048,7 +48080,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.rels) && values.rels.every(v => typeof v === \\"string\\")) { // @ts-ignore: type is checked above. - this.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = values.rels; + this.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = values.rels.slice(); } else { throw new TypeError( @@ -48097,7 +48129,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.names) && values.names.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names; + this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names.slice(); } else { throw new TypeError( @@ -48151,7 +48183,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.previews) && values.previews.every(v => v instanceof Link || v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews; + this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews.slice(); for (let i = 0; i < values.previews.length; i++) { this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview.add(i); @@ -48170,7 +48202,8 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -48200,7 +48233,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num { id: values.id ?? this.id }, options ); - clone.#_pVjLsybKQdmkjuU7MHjiVmNnuj7_href = this.#_pVjLsybKQdmkjuU7MHjiVmNnuj7_href; + clone.#_pVjLsybKQdmkjuU7MHjiVmNnuj7_href = this.#_pVjLsybKQdmkjuU7MHjiVmNnuj7_href.slice(); if (\\"href\\" in values && values.href != null) { if (values.href instanceof URL) { // @ts-ignore: type is checked above. @@ -48213,7 +48246,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = this.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel; + clone.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = this.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel.slice(); if (\\"rel\\" in values && values.rel != null) { if (typeof values.rel === \\"string\\") { // @ts-ignore: type is checked above. @@ -48240,7 +48273,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.rels) && values.rels.every(v => typeof v === \\"string\\")) { // @ts-ignore: type is checked above. - clone.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = values.rels; + clone.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = values.rels.slice(); } else { throw new TypeError( @@ -48249,7 +48282,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType; + clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType.slice(); if (\\"mediaType\\" in values && values.mediaType != null) { if (typeof values.mediaType === \\"string\\") { // @ts-ignore: type is checked above. @@ -48262,7 +48295,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name.slice(); if (\\"name\\" in values && values.name != null) { if (typeof values.name === \\"string\\" || values.name instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -48289,7 +48322,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.names) && values.names.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names.slice(); } else { throw new TypeError( @@ -48298,7 +48331,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang = this.#_f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang; + clone.#_f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang = this.#_f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang.slice(); if (\\"language\\" in values && values.language != null) { if (values.language instanceof Intl.Locale) { // @ts-ignore: type is checked above. @@ -48311,7 +48344,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height = this.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height; + clone.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height = this.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height.slice(); if (\\"height\\" in values && values.height != null) { if (typeof values.height === \\"number\\" && Number.isInteger(values.height) && values.height >= 0) { // @ts-ignore: type is checked above. @@ -48324,7 +48357,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width = this.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width; + clone.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width = this.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width.slice(); if (\\"width\\" in values && values.width != null) { if (typeof values.width === \\"number\\" && Number.isInteger(values.width) && values.width >= 0) { // @ts-ignore: type is checked above. @@ -48337,13 +48370,13 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview;clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview); + clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview.slice();clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview); if (\\"previews\\" in values && values.previews != null) { if (Array.isArray(values.previews) && values.previews.every(v => v instanceof Link || v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews; + clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews.slice(); clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(); for (let i = 0; i < values.previews.length; i++) { @@ -49695,7 +49728,8 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -50013,7 +50047,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -50365,7 +50400,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -50709,7 +50745,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -51049,7 +51086,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -51389,7 +51427,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -51729,7 +51768,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -52067,7 +52107,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -52385,7 +52426,8 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -52712,7 +52754,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -53060,7 +53103,8 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -53098,7 +53142,7 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Note;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl; + const clone = super.clone(values, options) as unknown as Note;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl.slice(); if (\\"quoteUrl\\" in values && values.quoteUrl != null) { if (values.quoteUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -53550,7 +53594,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); for (let i = 0; i < values.items.length; i++) { this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.add(i); @@ -53569,7 +53613,8 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -53607,13 +53652,13 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as OrderedCollection;clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items;clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); + const clone = super.clone(values, options) as unknown as OrderedCollection;clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.slice();clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); if (\\"items\\" in values && values.items != null) { if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(); for (let i = 0; i < values.items.length; i++) { @@ -54284,7 +54329,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); for (let i = 0; i < values.items.length; i++) { this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.add(i); @@ -54316,7 +54361,8 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -54354,13 +54400,13 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as OrderedCollectionPage;clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items;clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); + const clone = super.clone(values, options) as unknown as OrderedCollectionPage;clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.slice();clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); if (\\"items\\" in values && values.items != null) { if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(); for (let i = 0; i < values.items.length; i++) { @@ -54374,7 +54420,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2W4yinFwqmpneu2h4m1mZ3pcLADd_startIndex = this.#_2W4yinFwqmpneu2h4m1mZ3pcLADd_startIndex; + clone.#_2W4yinFwqmpneu2h4m1mZ3pcLADd_startIndex = this.#_2W4yinFwqmpneu2h4m1mZ3pcLADd_startIndex.slice(); if (\\"startIndex\\" in values && values.startIndex != null) { if (typeof values.startIndex === \\"number\\" && Number.isInteger(values.startIndex) && values.startIndex >= 0) { // @ts-ignore: type is checked above. @@ -55204,7 +55250,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -55240,7 +55286,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -55280,7 +55326,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -55403,7 +55449,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -55521,7 +55567,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -55561,7 +55607,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -55606,7 +55652,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -55649,7 +55696,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Organization;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Organization;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if (\\"preferredUsername\\" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === \\"string\\" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -55676,7 +55723,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -55685,7 +55732,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if (\\"publicKey\\" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -55712,7 +55759,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -55726,7 +55773,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if (\\"assertionMethod\\" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -55753,7 +55800,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -55767,7 +55814,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if (\\"manuallyApprovesFollowers\\" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -55780,7 +55827,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if (\\"inbox\\" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -55793,7 +55840,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if (\\"outbox\\" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -55806,7 +55853,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if (\\"following\\" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -55819,7 +55866,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if (\\"followers\\" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -55832,7 +55879,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if (\\"liked\\" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -55845,7 +55892,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if (\\"featured\\" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -55858,7 +55905,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if (\\"featuredTags\\" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -55871,13 +55918,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if (\\"streams\\" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -55891,7 +55938,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if (\\"endpoints\\" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -55904,7 +55951,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if (\\"discoverable\\" in values && values.discoverable != null) { if (typeof values.discoverable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -55917,7 +55964,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if (\\"suspended\\" in values && values.suspended != null) { if (typeof values.suspended === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -55930,7 +55977,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if (\\"memorial\\" in values && values.memorial != null) { if (typeof values.memorial === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -55943,7 +55990,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if (\\"indexable\\" in values && values.indexable != null) { if (typeof values.indexable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -55956,7 +56003,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if (\\"successor\\" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -55969,7 +56016,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if (\\"alias\\" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -55996,7 +56043,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -56010,7 +56057,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if (\\"service\\" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -56037,7 +56084,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -56051,7 +56098,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if (\\"followedMessage\\" in values && values.followedMessage != null) { if (typeof values.followedMessage === \\"string\\") { // @ts-ignore: type is checked above. @@ -56064,7 +56111,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if (\\"cat\\" in values && values.cat != null) { if (typeof values.cat === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -62073,7 +62120,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -62490,7 +62538,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -62526,7 +62574,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -62566,7 +62614,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -62689,7 +62737,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -62807,7 +62855,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -62847,7 +62895,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -62892,7 +62940,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -62935,7 +62984,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Person;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Person;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if (\\"preferredUsername\\" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === \\"string\\" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -62962,7 +63011,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -62971,7 +63020,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if (\\"publicKey\\" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -62998,7 +63047,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -63012,7 +63061,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if (\\"assertionMethod\\" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -63039,7 +63088,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -63053,7 +63102,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if (\\"manuallyApprovesFollowers\\" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -63066,7 +63115,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if (\\"inbox\\" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -63079,7 +63128,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if (\\"outbox\\" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -63092,7 +63141,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if (\\"following\\" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -63105,7 +63154,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if (\\"followers\\" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -63118,7 +63167,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if (\\"liked\\" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -63131,7 +63180,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if (\\"featured\\" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -63144,7 +63193,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if (\\"featuredTags\\" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -63157,13 +63206,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if (\\"streams\\" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -63177,7 +63226,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if (\\"endpoints\\" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -63190,7 +63239,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if (\\"discoverable\\" in values && values.discoverable != null) { if (typeof values.discoverable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -63203,7 +63252,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if (\\"suspended\\" in values && values.suspended != null) { if (typeof values.suspended === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -63216,7 +63265,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if (\\"memorial\\" in values && values.memorial != null) { if (typeof values.memorial === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -63229,7 +63278,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if (\\"indexable\\" in values && values.indexable != null) { if (typeof values.indexable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -63242,7 +63291,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if (\\"successor\\" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -63255,7 +63304,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if (\\"alias\\" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -63282,7 +63331,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -63296,7 +63345,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if (\\"service\\" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -63323,7 +63372,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -63337,7 +63386,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if (\\"followedMessage\\" in values && values.followedMessage != null) { if (typeof values.followedMessage === \\"string\\") { // @ts-ignore: type is checked above. @@ -63350,7 +63399,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if (\\"cat\\" in values && values.cat != null) { if (typeof values.cat === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -69446,7 +69495,8 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -69484,7 +69534,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Place;clone.#_3UCsHnBHvDAXJnBuzw3zw1VVs3Ne_accuracy = this.#_3UCsHnBHvDAXJnBuzw3zw1VVs3Ne_accuracy; + const clone = super.clone(values, options) as unknown as Place;clone.#_3UCsHnBHvDAXJnBuzw3zw1VVs3Ne_accuracy = this.#_3UCsHnBHvDAXJnBuzw3zw1VVs3Ne_accuracy.slice(); if (\\"accuracy\\" in values && values.accuracy != null) { if (typeof values.accuracy === \\"number\\" && !Number.isNaN(values.accuracy)) { // @ts-ignore: type is checked above. @@ -69497,7 +69547,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_3Q6KDcFQUJRRaBux1BL2yp5QWiBi_altitude = this.#_3Q6KDcFQUJRRaBux1BL2yp5QWiBi_altitude; + clone.#_3Q6KDcFQUJRRaBux1BL2yp5QWiBi_altitude = this.#_3Q6KDcFQUJRRaBux1BL2yp5QWiBi_altitude.slice(); if (\\"altitude\\" in values && values.altitude != null) { if (typeof values.altitude === \\"number\\" && !Number.isNaN(values.altitude)) { // @ts-ignore: type is checked above. @@ -69510,7 +69560,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_3g85RoKRnaNjP7DFyLSvsWDg7HGM_latitude = this.#_3g85RoKRnaNjP7DFyLSvsWDg7HGM_latitude; + clone.#_3g85RoKRnaNjP7DFyLSvsWDg7HGM_latitude = this.#_3g85RoKRnaNjP7DFyLSvsWDg7HGM_latitude.slice(); if (\\"latitude\\" in values && values.latitude != null) { if (typeof values.latitude === \\"number\\" && !Number.isNaN(values.latitude)) { // @ts-ignore: type is checked above. @@ -69523,7 +69573,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_B2GEYdS9yBAF3ho1pm1rcRg7cSf_longitude = this.#_B2GEYdS9yBAF3ho1pm1rcRg7cSf_longitude; + clone.#_B2GEYdS9yBAF3ho1pm1rcRg7cSf_longitude = this.#_B2GEYdS9yBAF3ho1pm1rcRg7cSf_longitude.slice(); if (\\"longitude\\" in values && values.longitude != null) { if (typeof values.longitude === \\"number\\" && !Number.isNaN(values.longitude)) { // @ts-ignore: type is checked above. @@ -69536,7 +69586,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_3ga86BKHUtRkGx5PHBjRiUXXzwnw_radius = this.#_3ga86BKHUtRkGx5PHBjRiUXXzwnw_radius; + clone.#_3ga86BKHUtRkGx5PHBjRiUXXzwnw_radius = this.#_3ga86BKHUtRkGx5PHBjRiUXXzwnw_radius.slice(); if (\\"radius\\" in values && values.radius != null) { if (typeof values.radius === \\"number\\" && !Number.isNaN(values.radius)) { // @ts-ignore: type is checked above. @@ -69549,7 +69599,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_oKrwxU4V8wiKhMW1QEYQibcJh8c_units = this.#_oKrwxU4V8wiKhMW1QEYQibcJh8c_units; + clone.#_oKrwxU4V8wiKhMW1QEYQibcJh8c_units = this.#_oKrwxU4V8wiKhMW1QEYQibcJh8c_units.slice(); if (\\"units\\" in values && values.units != null) { if (values.units == \\"cm\\" || values.units == \\"feet\\" || values.units == \\"inches\\" || values.units == \\"km\\" || values.units == \\"m\\" || values.units == \\"miles\\" || values.units instanceof URL) { // @ts-ignore: type is checked above. @@ -70466,7 +70516,8 @@ proofs?: (DataIntegrityProof | URL)[];describes?: Object | URL | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -70504,7 +70555,7 @@ proofs?: (DataIntegrityProof | URL)[];describes?: Object | URL | null;} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Profile;clone.#_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes = this.#_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes;clone.#_trust_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes = new Set(this.#_trust_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes); + const clone = super.clone(values, options) as unknown as Profile;clone.#_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes = this.#_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes.slice();clone.#_trust_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes = new Set(this.#_trust_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes); if (\\"describes\\" in values && values.describes != null) { if (values.describes instanceof Object || values.describes instanceof URL) { // @ts-ignore: type is checked above. @@ -71164,7 +71215,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti if (Array.isArray(values.exclusiveOptions) && values.exclusiveOptions.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = values.exclusiveOptions; + this.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = values.exclusiveOptions.slice(); for (let i = 0; i < values.exclusiveOptions.length; i++) { this.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf.add(i); @@ -71183,7 +71234,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti if (Array.isArray(values.inclusiveOptions) && values.inclusiveOptions.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = values.inclusiveOptions; + this.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = values.inclusiveOptions.slice(); for (let i = 0; i < values.inclusiveOptions.length; i++) { this.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf.add(i); @@ -71241,7 +71292,8 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -71285,13 +71337,13 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Question;clone.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = this.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf;clone.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = new Set(this.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf); + const clone = super.clone(values, options) as unknown as Question;clone.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = this.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf.slice();clone.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = new Set(this.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf); if (\\"exclusiveOptions\\" in values && values.exclusiveOptions != null) { if (Array.isArray(values.exclusiveOptions) && values.exclusiveOptions.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = values.exclusiveOptions; + clone.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = values.exclusiveOptions.slice(); clone.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = new Set(); for (let i = 0; i < values.exclusiveOptions.length; i++) { @@ -71305,13 +71357,13 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti ); } } - clone.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = this.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf;clone.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = new Set(this.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf); + clone.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = this.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf.slice();clone.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = new Set(this.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf); if (\\"inclusiveOptions\\" in values && values.inclusiveOptions != null) { if (Array.isArray(values.inclusiveOptions) && values.inclusiveOptions.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = values.inclusiveOptions; + clone.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = values.inclusiveOptions.slice(); clone.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = new Set(); for (let i = 0; i < values.inclusiveOptions.length; i++) { @@ -71325,7 +71377,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti ); } } - clone.#_3KronwL8DiiKBRcJFKQPiEHm8xb6_closed = this.#_3KronwL8DiiKBRcJFKQPiEHm8xb6_closed; + clone.#_3KronwL8DiiKBRcJFKQPiEHm8xb6_closed = this.#_3KronwL8DiiKBRcJFKQPiEHm8xb6_closed.slice(); if (\\"closed\\" in values && values.closed != null) { if (isTemporalInstant(values.closed) || typeof values.closed === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -71338,7 +71390,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti ); } } - clone.#_3H4RdST7dxfmghccvE3rKD3KgcxG_votersCount = this.#_3H4RdST7dxfmghccvE3rKD3KgcxG_votersCount; + clone.#_3H4RdST7dxfmghccvE3rKD3KgcxG_votersCount = this.#_3H4RdST7dxfmghccvE3rKD3KgcxG_votersCount.slice(); if (\\"voters\\" in values && values.voters != null) { if (typeof values.voters === \\"number\\" && Number.isInteger(values.voters) && values.voters >= 0) { // @ts-ignore: type is checked above. @@ -71351,7 +71403,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti ); } } - clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl; + clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl.slice(); if (\\"quoteUrl\\" in values && values.quoteUrl != null) { if (values.quoteUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -72539,7 +72591,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -72879,7 +72932,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -73267,7 +73321,7 @@ relationships?: (Object | URL)[];} if (Array.isArray(values.objects) && values.objects.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects; + this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects.slice(); for (let i = 0; i < values.objects.length; i++) { this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object.add(i); @@ -73307,7 +73361,7 @@ relationships?: (Object | URL)[];} if (Array.isArray(values.relationships) && values.relationships.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = values.relationships; + this.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = values.relationships.slice(); for (let i = 0; i < values.relationships.length; i++) { this.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship.add(i); @@ -73326,7 +73380,8 @@ relationships?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -73366,7 +73421,7 @@ relationships?: (Object | URL)[];} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Relationship;clone.#_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject = this.#_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject;clone.#_trust_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject = new Set(this.#_trust_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject); + const clone = super.clone(values, options) as unknown as Relationship;clone.#_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject = this.#_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject.slice();clone.#_trust_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject = new Set(this.#_trust_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject); if (\\"subject\\" in values && values.subject != null) { if (values.subject instanceof Object || values.subject instanceof URL) { // @ts-ignore: type is checked above. @@ -73379,7 +73434,7 @@ relationships?: (Object | URL)[];} ); } } - clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object;clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object); + clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object.slice();clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object); if (\\"object\\" in values && values.object != null) { if (values.object instanceof Object || values.object instanceof URL) { // @ts-ignore: type is checked above. @@ -73406,7 +73461,7 @@ relationships?: (Object | URL)[];} if (Array.isArray(values.objects) && values.objects.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects; + clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects.slice(); clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(); for (let i = 0; i < values.objects.length; i++) { @@ -73420,7 +73475,7 @@ relationships?: (Object | URL)[];} ); } } - clone.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = this.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship;clone.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = new Set(this.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship); + clone.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = this.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship.slice();clone.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = new Set(this.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship); if (\\"relationship\\" in values && values.relationship != null) { if (values.relationship instanceof Object || values.relationship instanceof URL) { // @ts-ignore: type is checked above. @@ -73447,7 +73502,7 @@ relationships?: (Object | URL)[];} if (Array.isArray(values.relationships) && values.relationships.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = values.relationships; + clone.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = values.relationships.slice(); clone.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = new Set(); for (let i = 0; i < values.relationships.length; i++) { @@ -74955,7 +75010,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -75361,7 +75417,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -75397,7 +75453,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -75437,7 +75493,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -75560,7 +75616,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -75678,7 +75734,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -75718,7 +75774,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -75763,7 +75819,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -75806,7 +75863,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Service;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Service;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if (\\"preferredUsername\\" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === \\"string\\" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -75833,7 +75890,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -75842,7 +75899,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if (\\"publicKey\\" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -75869,7 +75926,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -75883,7 +75940,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if (\\"assertionMethod\\" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -75910,7 +75967,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -75924,7 +75981,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if (\\"manuallyApprovesFollowers\\" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -75937,7 +75994,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if (\\"inbox\\" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -75950,7 +76007,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if (\\"outbox\\" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -75963,7 +76020,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if (\\"following\\" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -75976,7 +76033,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if (\\"followers\\" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -75989,7 +76046,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if (\\"liked\\" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -76002,7 +76059,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if (\\"featured\\" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -76015,7 +76072,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if (\\"featuredTags\\" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -76028,13 +76085,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if (\\"streams\\" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -76048,7 +76105,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if (\\"endpoints\\" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -76061,7 +76118,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if (\\"discoverable\\" in values && values.discoverable != null) { if (typeof values.discoverable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -76074,7 +76131,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if (\\"suspended\\" in values && values.suspended != null) { if (typeof values.suspended === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -76087,7 +76144,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if (\\"memorial\\" in values && values.memorial != null) { if (typeof values.memorial === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -76100,7 +76157,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if (\\"indexable\\" in values && values.indexable != null) { if (typeof values.indexable === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -76113,7 +76170,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if (\\"successor\\" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -76126,7 +76183,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if (\\"alias\\" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -76153,7 +76210,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -76167,7 +76224,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if (\\"service\\" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -76194,7 +76251,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -76208,7 +76265,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if (\\"followedMessage\\" in values && values.followedMessage != null) { if (typeof values.followedMessage === \\"string\\") { // @ts-ignore: type is checked above. @@ -76221,7 +76278,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if (\\"cat\\" in values && values.cat != null) { if (typeof values.cat === \\"boolean\\") { // @ts-ignore: type is checked above. @@ -82308,7 +82365,7 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} if (Array.isArray(values.contents) && values.contents.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents; + this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents.slice(); } else { throw new TypeError( @@ -82336,7 +82393,8 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -82365,7 +82423,7 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} { id: values.id ?? this.id }, options ); - clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content; + clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content.slice(); if (\\"content\\" in values && values.content != null) { if (typeof values.content === \\"string\\" || values.content instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -82392,7 +82450,7 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} if (Array.isArray(values.contents) && values.contents.every(v => typeof v === \\"string\\" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents; + clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents.slice(); } else { throw new TypeError( @@ -82401,7 +82459,7 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} ); } } - clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType; + clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType.slice(); if (\\"mediaType\\" in values && values.mediaType != null) { if (typeof values.mediaType === \\"string\\") { // @ts-ignore: type is checked above. @@ -82918,7 +82976,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -83258,7 +83317,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -83607,7 +83667,8 @@ proofs?: (DataIntegrityProof | URL)[];deleted?: Temporal.Instant | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -83645,7 +83706,7 @@ proofs?: (DataIntegrityProof | URL)[];deleted?: Temporal.Instant | null;} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Tombstone;clone.#_8g8g4LiVMhFTXskuDEqx4ascxUr_deleted = this.#_8g8g4LiVMhFTXskuDEqx4ascxUr_deleted; + const clone = super.clone(values, options) as unknown as Tombstone;clone.#_8g8g4LiVMhFTXskuDEqx4ascxUr_deleted = this.#_8g8g4LiVMhFTXskuDEqx4ascxUr_deleted.slice(); if (\\"deleted\\" in values && values.deleted != null) { if (isTemporalInstant(values.deleted)) { // @ts-ignore: type is checked above. @@ -84070,7 +84131,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -84415,7 +84477,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -84758,7 +84821,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -85090,7 +85154,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -85440,7 +85505,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: diff --git a/packages/vocab-tools/src/__snapshots__/class.test.ts.snap b/packages/vocab-tools/src/__snapshots__/class.test.ts.snap index 4a23873a0..be1178b2e 100644 --- a/packages/vocab-tools/src/__snapshots__/class.test.ts.snap +++ b/packages/vocab-tools/src/__snapshots__/class.test.ts.snap @@ -241,7 +241,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.attachments) && values.attachments.every(v => v instanceof Object || v instanceof Link || v instanceof PropertyValue || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = values.attachments; + this.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = values.attachments.slice(); for (let i = 0; i < values.attachments.length; i++) { this.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment.add(i); @@ -281,7 +281,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.attributions) && values.attributions.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = values.attributions; + this.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = values.attributions.slice(); for (let i = 0; i < values.attributions.length; i++) { this.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo.add(i); @@ -321,7 +321,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.audiences) && values.audiences.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = values.audiences; + this.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = values.audiences.slice(); for (let i = 0; i < values.audiences.length; i++) { this.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience.add(i); @@ -361,7 +361,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.contents) && values.contents.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents; + this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents.slice(); } else { throw new TypeError( @@ -376,7 +376,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.contexts) && values.contexts.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = values.contexts; + this.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = values.contexts.slice(); for (let i = 0; i < values.contexts.length; i++) { this.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context.add(i); @@ -416,7 +416,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.names) && values.names.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names; + this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names.slice(); } else { throw new TypeError( @@ -444,7 +444,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.generators) && values.generators.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = values.generators; + this.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = values.generators.slice(); for (let i = 0; i < values.generators.length; i++) { this.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator.add(i); @@ -484,7 +484,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.icons) && values.icons.every(v => v instanceof Image || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = values.icons; + this.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = values.icons.slice(); for (let i = 0; i < values.icons.length; i++) { this.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon.add(i); @@ -524,7 +524,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.images) && values.images.every(v => v instanceof Image || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = values.images; + this.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = values.images.slice(); for (let i = 0; i < values.images.length; i++) { this.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image.add(i); @@ -564,7 +564,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.replyTargets) && values.replyTargets.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = values.replyTargets; + this.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = values.replyTargets.slice(); for (let i = 0; i < values.replyTargets.length; i++) { this.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo.add(i); @@ -604,7 +604,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.locations) && values.locations.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = values.locations; + this.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = values.locations.slice(); for (let i = 0; i < values.locations.length; i++) { this.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location.add(i); @@ -644,7 +644,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.previews) && values.previews.every(v => v instanceof Link || v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews; + this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews.slice(); for (let i = 0; i < values.previews.length; i++) { this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview.add(i); @@ -762,7 +762,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.summaries) && values.summaries.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = values.summaries; + this.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = values.summaries.slice(); } else { throw new TypeError( @@ -777,7 +777,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.tags) && values.tags.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = values.tags; + this.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = values.tags.slice(); for (let i = 0; i < values.tags.length; i++) { this.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag.add(i); @@ -830,7 +830,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.urls) && values.urls.every(v => v instanceof URL || v instanceof Link)) { // @ts-ignore: type is checked above. - this.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = values.urls; + this.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = values.urls.slice(); } else { throw new TypeError( @@ -866,7 +866,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.tos) && values.tos.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = values.tos; + this.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = values.tos.slice(); for (let i = 0; i < values.tos.length; i++) { this.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to.add(i); @@ -906,7 +906,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.btos) && values.btos.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = values.btos; + this.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = values.btos.slice(); for (let i = 0; i < values.btos.length; i++) { this.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto.add(i); @@ -946,7 +946,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.ccs) && values.ccs.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = values.ccs; + this.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = values.ccs.slice(); for (let i = 0; i < values.ccs.length; i++) { this.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc.add(i); @@ -986,7 +986,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.bccs) && values.bccs.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = values.bccs; + this.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = values.bccs.slice(); for (let i = 0; i < values.bccs.length; i++) { this.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc.add(i); @@ -1078,7 +1078,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.proofs) && values.proofs.every(v => v instanceof DataIntegrityProof || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = values.proofs; + this.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = values.proofs.slice(); for (let i = 0; i < values.proofs.length; i++) { this.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof.add(i); @@ -1097,7 +1097,8 @@ proofs?: (DataIntegrityProof | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -1141,13 +1142,13 @@ proofs?: (DataIntegrityProof | URL)[];} { id: values.id ?? this.id }, options ); - clone.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = this.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment;clone.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment = new Set(this.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment); + clone.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = this.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment.slice();clone.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment = new Set(this.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment); if ("attachments" in values && values.attachments != null) { if (Array.isArray(values.attachments) && values.attachments.every(v => v instanceof Object || v instanceof Link || v instanceof PropertyValue || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = values.attachments; + clone.#_49BipA5dq9eoH8LX8xdsVumveTca_attachment = values.attachments.slice(); clone.#_trust_49BipA5dq9eoH8LX8xdsVumveTca_attachment = new Set(); for (let i = 0; i < values.attachments.length; i++) { @@ -1161,7 +1162,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = this.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo;clone.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = new Set(this.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo); + clone.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = this.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo.slice();clone.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = new Set(this.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo); if ("attribution" in values && values.attribution != null) { if (values.attribution instanceof Application || values.attribution instanceof Group || values.attribution instanceof Organization || values.attribution instanceof Person || values.attribution instanceof Service || values.attribution instanceof URL) { // @ts-ignore: type is checked above. @@ -1188,7 +1189,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.attributions) && values.attributions.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = values.attributions; + clone.#_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = values.attributions.slice(); clone.#_trust_42CGqJ94zgQ3ZBbfHwD8Hrr2L5Py_attributedTo = new Set(); for (let i = 0; i < values.attributions.length; i++) { @@ -1202,7 +1203,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = this.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience;clone.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = new Set(this.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience); + clone.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = this.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience.slice();clone.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = new Set(this.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience); if ("audience" in values && values.audience != null) { if (values.audience instanceof Object || values.audience instanceof URL) { // @ts-ignore: type is checked above. @@ -1229,7 +1230,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.audiences) && values.audiences.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = values.audiences; + clone.#_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = values.audiences.slice(); clone.#_trust_3ocC3VVi88cEd5sPWL8djkZsvTN6_audience = new Set(); for (let i = 0; i < values.audiences.length; i++) { @@ -1243,7 +1244,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content; + clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content.slice(); if ("content" in values && values.content != null) { if (typeof values.content === "string" || values.content instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -1270,7 +1271,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.contents) && values.contents.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents; + clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents.slice(); } else { throw new TypeError( @@ -1279,13 +1280,13 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = this.#_3mhZzGXSpQ431mBSz2kvych22v4e_context;clone.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context = new Set(this.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context); + clone.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = this.#_3mhZzGXSpQ431mBSz2kvych22v4e_context.slice();clone.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context = new Set(this.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context); if ("contexts" in values && values.contexts != null) { if (Array.isArray(values.contexts) && values.contexts.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = values.contexts; + clone.#_3mhZzGXSpQ431mBSz2kvych22v4e_context = values.contexts.slice(); clone.#_trust_3mhZzGXSpQ431mBSz2kvych22v4e_context = new Set(); for (let i = 0; i < values.contexts.length; i++) { @@ -1299,7 +1300,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name.slice(); if ("name" in values && values.name != null) { if (typeof values.name === "string" || values.name instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -1326,7 +1327,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.names) && values.names.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names.slice(); } else { throw new TypeError( @@ -1335,7 +1336,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_219RwDanjScTv5tYCjwGZVCM7KZ9_endTime = this.#_219RwDanjScTv5tYCjwGZVCM7KZ9_endTime; + clone.#_219RwDanjScTv5tYCjwGZVCM7KZ9_endTime = this.#_219RwDanjScTv5tYCjwGZVCM7KZ9_endTime.slice(); if ("endTime" in values && values.endTime != null) { if (isTemporalInstant(values.endTime)) { // @ts-ignore: type is checked above. @@ -1348,13 +1349,13 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = this.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator;clone.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator = new Set(this.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator); + clone.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = this.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator.slice();clone.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator = new Set(this.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator); if ("generators" in values && values.generators != null) { if (Array.isArray(values.generators) && values.generators.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = values.generators; + clone.#_86xFhmgBapoMvYqjbjRuDPayTrS_generator = values.generators.slice(); clone.#_trust_86xFhmgBapoMvYqjbjRuDPayTrS_generator = new Set(); for (let i = 0; i < values.generators.length; i++) { @@ -1368,7 +1369,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = this.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon;clone.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = new Set(this.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon); + clone.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = this.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon.slice();clone.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = new Set(this.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon); if ("icon" in values && values.icon != null) { if (values.icon instanceof Image || values.icon instanceof URL) { // @ts-ignore: type is checked above. @@ -1395,7 +1396,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.icons) && values.icons.every(v => v instanceof Image || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = values.icons; + clone.#_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = values.icons.slice(); clone.#_trust_33CjRLy5ujtsUrwRSCrsggvGdKuR_icon = new Set(); for (let i = 0; i < values.icons.length; i++) { @@ -1409,7 +1410,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = this.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image;clone.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = new Set(this.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image); + clone.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = this.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image.slice();clone.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = new Set(this.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image); if ("image" in values && values.image != null) { if (values.image instanceof Image || values.image instanceof URL) { // @ts-ignore: type is checked above. @@ -1436,7 +1437,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.images) && values.images.every(v => v instanceof Image || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = values.images; + clone.#_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = values.images.slice(); clone.#_trust_3dXrUdkARxwyJLtJcYi1AJ92H41U_image = new Set(); for (let i = 0; i < values.images.length; i++) { @@ -1450,7 +1451,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = this.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo;clone.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = new Set(this.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo); + clone.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = this.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo.slice();clone.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = new Set(this.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo); if ("replyTarget" in values && values.replyTarget != null) { if (values.replyTarget instanceof Object || values.replyTarget instanceof Link || values.replyTarget instanceof URL) { // @ts-ignore: type is checked above. @@ -1477,7 +1478,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.replyTargets) && values.replyTargets.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = values.replyTargets; + clone.#_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = values.replyTargets.slice(); clone.#_trust_3fpbDrvZgf3Kq1a5V9aByFn8kx3s_inReplyTo = new Set(); for (let i = 0; i < values.replyTargets.length; i++) { @@ -1491,7 +1492,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = this.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location;clone.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = new Set(this.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location); + clone.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = this.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location.slice();clone.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = new Set(this.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location); if ("location" in values && values.location != null) { if (values.location instanceof Object || values.location instanceof Link || values.location instanceof URL) { // @ts-ignore: type is checked above. @@ -1518,7 +1519,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.locations) && values.locations.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = values.locations; + clone.#_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = values.locations.slice(); clone.#_trust_31k5MUZJsnsPNg8dQQJieWaXTFnR_location = new Set(); for (let i = 0; i < values.locations.length; i++) { @@ -1532,7 +1533,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview;clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview); + clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview.slice();clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview); if ("preview" in values && values.preview != null) { if (values.preview instanceof Link || values.preview instanceof Object || values.preview instanceof URL) { // @ts-ignore: type is checked above. @@ -1559,7 +1560,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.previews) && values.previews.every(v => v instanceof Link || v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews; + clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews.slice(); clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(); for (let i = 0; i < values.previews.length; i++) { @@ -1573,7 +1574,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_5e258TDXtuhaFRPZiGoDfEpjdMr_published = this.#_5e258TDXtuhaFRPZiGoDfEpjdMr_published; + clone.#_5e258TDXtuhaFRPZiGoDfEpjdMr_published = this.#_5e258TDXtuhaFRPZiGoDfEpjdMr_published.slice(); if ("published" in values && values.published != null) { if (isTemporalInstant(values.published)) { // @ts-ignore: type is checked above. @@ -1586,7 +1587,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_7UpwM3JWcXhADcscukEehBorf6k_replies = this.#_7UpwM3JWcXhADcscukEehBorf6k_replies;clone.#_trust_7UpwM3JWcXhADcscukEehBorf6k_replies = new Set(this.#_trust_7UpwM3JWcXhADcscukEehBorf6k_replies); + clone.#_7UpwM3JWcXhADcscukEehBorf6k_replies = this.#_7UpwM3JWcXhADcscukEehBorf6k_replies.slice();clone.#_trust_7UpwM3JWcXhADcscukEehBorf6k_replies = new Set(this.#_trust_7UpwM3JWcXhADcscukEehBorf6k_replies); if ("replies" in values && values.replies != null) { if (values.replies instanceof Collection || values.replies instanceof URL) { // @ts-ignore: type is checked above. @@ -1599,7 +1600,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3kAfck9PcEYt2L7xug5y99YPbANs_shares = this.#_3kAfck9PcEYt2L7xug5y99YPbANs_shares;clone.#_trust_3kAfck9PcEYt2L7xug5y99YPbANs_shares = new Set(this.#_trust_3kAfck9PcEYt2L7xug5y99YPbANs_shares); + clone.#_3kAfck9PcEYt2L7xug5y99YPbANs_shares = this.#_3kAfck9PcEYt2L7xug5y99YPbANs_shares.slice();clone.#_trust_3kAfck9PcEYt2L7xug5y99YPbANs_shares = new Set(this.#_trust_3kAfck9PcEYt2L7xug5y99YPbANs_shares); if ("shares" in values && values.shares != null) { if (values.shares instanceof Collection || values.shares instanceof URL) { // @ts-ignore: type is checked above. @@ -1612,7 +1613,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes = this.#_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes;clone.#_trust_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes = new Set(this.#_trust_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes); + clone.#_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes = this.#_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes.slice();clone.#_trust_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes = new Set(this.#_trust_S3ceDnpMdzoTRCccB9FkJWrEzYW_likes); if ("likes" in values && values.likes != null) { if (values.likes instanceof Collection || values.likes instanceof URL) { // @ts-ignore: type is checked above. @@ -1625,7 +1626,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions = this.#_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions;clone.#_trust_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions = new Set(this.#_trust_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions); + clone.#_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions = this.#_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions.slice();clone.#_trust_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions = new Set(this.#_trust_kMatyyNAuxoTD8GQMBfA5ogThMR_emojiReactions); if ("emojiReactions" in values && values.emojiReactions != null) { if (values.emojiReactions instanceof Collection || values.emojiReactions instanceof URL) { // @ts-ignore: type is checked above. @@ -1638,7 +1639,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_2w3Jmue4up8iVDUA51WZqomEF438_startTime = this.#_2w3Jmue4up8iVDUA51WZqomEF438_startTime; + clone.#_2w3Jmue4up8iVDUA51WZqomEF438_startTime = this.#_2w3Jmue4up8iVDUA51WZqomEF438_startTime.slice(); if ("startTime" in values && values.startTime != null) { if (isTemporalInstant(values.startTime)) { // @ts-ignore: type is checked above. @@ -1651,7 +1652,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = this.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary; + clone.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = this.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary.slice(); if ("summary" in values && values.summary != null) { if (typeof values.summary === "string" || values.summary instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -1678,7 +1679,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.summaries) && values.summaries.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = values.summaries; + clone.#_4LqirZspQbFWWQEbFcXAxm7tTDN1_summary = values.summaries.slice(); } else { throw new TypeError( @@ -1687,13 +1688,13 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = this.#_5chuqj6s95p5gg2sk1HntGfarRf_tag;clone.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag = new Set(this.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag); + clone.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = this.#_5chuqj6s95p5gg2sk1HntGfarRf_tag.slice();clone.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag = new Set(this.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag); if ("tags" in values && values.tags != null) { if (Array.isArray(values.tags) && values.tags.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = values.tags; + clone.#_5chuqj6s95p5gg2sk1HntGfarRf_tag = values.tags.slice(); clone.#_trust_5chuqj6s95p5gg2sk1HntGfarRf_tag = new Set(); for (let i = 0; i < values.tags.length; i++) { @@ -1707,7 +1708,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_385aB7ySixcf5Un6z3VsWmThgCzQ_updated = this.#_385aB7ySixcf5Un6z3VsWmThgCzQ_updated; + clone.#_385aB7ySixcf5Un6z3VsWmThgCzQ_updated = this.#_385aB7ySixcf5Un6z3VsWmThgCzQ_updated.slice(); if ("updated" in values && values.updated != null) { if (isTemporalInstant(values.updated)) { // @ts-ignore: type is checked above. @@ -1720,7 +1721,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = this.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url; + clone.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = this.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url.slice(); if ("url" in values && values.url != null) { if (values.url instanceof URL || values.url instanceof Link) { // @ts-ignore: type is checked above. @@ -1747,7 +1748,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.urls) && values.urls.every(v => v instanceof URL || v instanceof Link)) { // @ts-ignore: type is checked above. - clone.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = values.urls; + clone.#_2oPEH9MQ3aj8JVwyYuWkqoVwV865_url = values.urls.slice(); } else { throw new TypeError( @@ -1756,7 +1757,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = this.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to;clone.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = new Set(this.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to); + clone.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = this.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to.slice();clone.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = new Set(this.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to); if ("to" in values && values.to != null) { if (values.to instanceof Object || values.to instanceof URL) { // @ts-ignore: type is checked above. @@ -1783,7 +1784,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.tos) && values.tos.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = values.tos; + clone.#_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = values.tos.slice(); clone.#_trust_3hFbw7DTpHhq3cvVhkY8njhcsXbd_to = new Set(); for (let i = 0; i < values.tos.length; i++) { @@ -1797,7 +1798,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = this.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto;clone.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = new Set(this.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto); + clone.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = this.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto.slice();clone.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = new Set(this.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto); if ("bto" in values && values.bto != null) { if (values.bto instanceof Object || values.bto instanceof URL) { // @ts-ignore: type is checked above. @@ -1824,7 +1825,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.btos) && values.btos.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = values.btos; + clone.#_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = values.btos.slice(); clone.#_trust_aLZupjwL8XB7tzdLgCMXdjZ6qej_bto = new Set(); for (let i = 0; i < values.btos.length; i++) { @@ -1838,7 +1839,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = this.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc;clone.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = new Set(this.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc); + clone.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = this.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc.slice();clone.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = new Set(this.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc); if ("cc" in values && values.cc != null) { if (values.cc instanceof Object || values.cc instanceof URL) { // @ts-ignore: type is checked above. @@ -1865,7 +1866,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.ccs) && values.ccs.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = values.ccs; + clone.#_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = values.ccs.slice(); clone.#_trust_42a1SvBs24QSLzKcfjCyNTjW5a1g_cc = new Set(); for (let i = 0; i < values.ccs.length; i++) { @@ -1879,7 +1880,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = this.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc;clone.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = new Set(this.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc); + clone.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = this.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc.slice();clone.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = new Set(this.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc); if ("bcc" in values && values.bcc != null) { if (values.bcc instanceof Object || values.bcc instanceof URL) { // @ts-ignore: type is checked above. @@ -1906,7 +1907,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.bccs) && values.bccs.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = values.bccs; + clone.#_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = values.bccs.slice(); clone.#_trust_3qvegKUB8YLgTXRpEf8E6JZSkz2H_bcc = new Set(); for (let i = 0; i < values.bccs.length; i++) { @@ -1920,7 +1921,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType; + clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType.slice(); if ("mediaType" in values && values.mediaType != null) { if (typeof values.mediaType === "string") { // @ts-ignore: type is checked above. @@ -1933,7 +1934,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_3bNvLMBN1bCJETiTihM3wvi1B2JX_duration = this.#_3bNvLMBN1bCJETiTihM3wvi1B2JX_duration; + clone.#_3bNvLMBN1bCJETiTihM3wvi1B2JX_duration = this.#_3bNvLMBN1bCJETiTihM3wvi1B2JX_duration.slice(); if ("duration" in values && values.duration != null) { if (isTemporalDuration(values.duration)) { // @ts-ignore: type is checked above. @@ -1946,7 +1947,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_u8gdcDTtChQ4tbSQMXc4cYWyum7_sensitive = this.#_u8gdcDTtChQ4tbSQMXc4cYWyum7_sensitive; + clone.#_u8gdcDTtChQ4tbSQMXc4cYWyum7_sensitive = this.#_u8gdcDTtChQ4tbSQMXc4cYWyum7_sensitive.slice(); if ("sensitive" in values && values.sensitive != null) { if (typeof values.sensitive === "boolean") { // @ts-ignore: type is checked above. @@ -1959,7 +1960,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_2ZwCFoS787v8y8bXKjMoE6MAbrEB_source = this.#_2ZwCFoS787v8y8bXKjMoE6MAbrEB_source; + clone.#_2ZwCFoS787v8y8bXKjMoE6MAbrEB_source = this.#_2ZwCFoS787v8y8bXKjMoE6MAbrEB_source.slice(); if ("source" in values && values.source != null) { if (values.source instanceof Source) { // @ts-ignore: type is checked above. @@ -1972,7 +1973,7 @@ proofs?: (DataIntegrityProof | URL)[];} ); } } - clone.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = this.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof;clone.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = new Set(this.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof); + clone.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = this.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof.slice();clone.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = new Set(this.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof); if ("proof" in values && values.proof != null) { if (values.proof instanceof DataIntegrityProof || values.proof instanceof URL) { // @ts-ignore: type is checked above. @@ -1999,7 +2000,7 @@ proofs?: (DataIntegrityProof | URL)[];} if (Array.isArray(values.proofs) && values.proofs.every(v => v instanceof DataIntegrityProof || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = values.proofs; + clone.#_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = values.proofs.slice(); clone.#_trust_42rPnotok1ivQ2RNCKNbeFJgx8b8_proof = new Set(); for (let i = 0; i < values.proofs.length; i++) { @@ -11823,7 +11824,8 @@ proofs?: (DataIntegrityProof | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -12185,7 +12187,8 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -12223,7 +12226,7 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as ChatMessage;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl; + const clone = super.clone(values, options) as unknown as ChatMessage;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl.slice(); if ("quoteUrl" in values && values.quoteUrl != null) { if (values.quoteUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -12720,7 +12723,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.actors) && values.actors.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = values.actors; + this.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = values.actors.slice(); for (let i = 0; i < values.actors.length; i++) { this.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor.add(i); @@ -12760,7 +12763,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.objects) && values.objects.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects; + this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects.slice(); for (let i = 0; i < values.objects.length; i++) { this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object.add(i); @@ -12800,7 +12803,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.targets) && values.targets.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = values.targets; + this.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = values.targets.slice(); for (let i = 0; i < values.targets.length; i++) { this.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target.add(i); @@ -12840,7 +12843,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.results) && values.results.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = values.results; + this.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = values.results.slice(); for (let i = 0; i < values.results.length; i++) { this.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result.add(i); @@ -12880,7 +12883,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.origins) && values.origins.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = values.origins; + this.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = values.origins.slice(); for (let i = 0; i < values.origins.length; i++) { this.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin.add(i); @@ -12920,7 +12923,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.instruments) && values.instruments.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = values.instruments; + this.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = values.instruments.slice(); for (let i = 0; i < values.instruments.length; i++) { this.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument.add(i); @@ -12939,7 +12942,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -12983,7 +12987,7 @@ instruments?: (Object | URL)[];} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Activity;clone.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = this.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor;clone.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = new Set(this.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor); + const clone = super.clone(values, options) as unknown as Activity;clone.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = this.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor.slice();clone.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = new Set(this.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor); if ("actor" in values && values.actor != null) { if (values.actor instanceof Application || values.actor instanceof Group || values.actor instanceof Organization || values.actor instanceof Person || values.actor instanceof Service || values.actor instanceof URL) { // @ts-ignore: type is checked above. @@ -13010,7 +13014,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.actors) && values.actors.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = values.actors; + clone.#_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = values.actors.slice(); clone.#_trust_2DjTTboo3CNHU2a2JQqUSE2dbv9D_actor = new Set(); for (let i = 0; i < values.actors.length; i++) { @@ -13024,7 +13028,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object;clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object); + clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object.slice();clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object); if ("object" in values && values.object != null) { if (values.object instanceof Object || values.object instanceof URL) { // @ts-ignore: type is checked above. @@ -13051,7 +13055,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.objects) && values.objects.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects; + clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects.slice(); clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(); for (let i = 0; i < values.objects.length; i++) { @@ -13065,7 +13069,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = this.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target;clone.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = new Set(this.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target); + clone.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = this.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target.slice();clone.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = new Set(this.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target); if ("target" in values && values.target != null) { if (values.target instanceof Object || values.target instanceof URL) { // @ts-ignore: type is checked above. @@ -13092,7 +13096,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.targets) && values.targets.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = values.targets; + clone.#_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = values.targets.slice(); clone.#_trust_3JQCmF2Ww56Ag9EWRYoSZRDNCYtF_target = new Set(); for (let i = 0; i < values.targets.length; i++) { @@ -13106,7 +13110,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = this.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result;clone.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = new Set(this.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result); + clone.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = this.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result.slice();clone.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = new Set(this.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result); if ("result" in values && values.result != null) { if (values.result instanceof Object || values.result instanceof URL) { // @ts-ignore: type is checked above. @@ -13133,7 +13137,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.results) && values.results.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = values.results; + clone.#_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = values.results.slice(); clone.#_trust_u4QGFbRFcYmPEKGbPv1hpBR9r5G_result = new Set(); for (let i = 0; i < values.results.length; i++) { @@ -13147,7 +13151,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = this.#_25zu2s3VxVujgEKqrDycjE284XQR_origin;clone.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin = new Set(this.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin); + clone.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = this.#_25zu2s3VxVujgEKqrDycjE284XQR_origin.slice();clone.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin = new Set(this.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin); if ("origin" in values && values.origin != null) { if (values.origin instanceof Object || values.origin instanceof URL) { // @ts-ignore: type is checked above. @@ -13174,7 +13178,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.origins) && values.origins.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = values.origins; + clone.#_25zu2s3VxVujgEKqrDycjE284XQR_origin = values.origins.slice(); clone.#_trust_25zu2s3VxVujgEKqrDycjE284XQR_origin = new Set(); for (let i = 0; i < values.origins.length; i++) { @@ -13188,7 +13192,7 @@ instruments?: (Object | URL)[];} ); } } - clone.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = this.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument;clone.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = new Set(this.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument); + clone.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = this.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument.slice();clone.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = new Set(this.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument); if ("instrument" in values && values.instrument != null) { if (values.instrument instanceof Object || values.instrument instanceof URL) { // @ts-ignore: type is checked above. @@ -13215,7 +13219,7 @@ instruments?: (Object | URL)[];} if (Array.isArray(values.instruments) && values.instruments.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = values.instruments; + clone.#_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = values.instruments.slice(); clone.#_trust_3c5t2x7DYRo2shwTxpkd4kYSS5WQ_instrument = new Set(); for (let i = 0; i < values.instruments.length; i++) { @@ -16180,7 +16184,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -16594,7 +16599,8 @@ name?: string | LanguageString | null;value?: string | LanguageString | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -16622,7 +16628,7 @@ name?: string | LanguageString | null;value?: string | LanguageString | null;} { id: values.id ?? this.id }, options ); - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name.slice(); if ("name" in values && values.name != null) { if (typeof values.name === "string" || values.name instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -16635,7 +16641,7 @@ name?: string | LanguageString | null;value?: string | LanguageString | null;} ); } } - clone.#_2cSy2magg4iZ7zLaG8U7DiJMoCkx_value = this.#_2cSy2magg4iZ7zLaG8U7DiJMoCkx_value; + clone.#_2cSy2magg4iZ7zLaG8U7DiJMoCkx_value = this.#_2cSy2magg4iZ7zLaG8U7DiJMoCkx_value.slice(); if ("value" in values && values.value != null) { if (typeof values.value === "string" || values.value instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -17233,7 +17239,7 @@ endpoints?: (URL)[];} if (Array.isArray(values.endpoints) && values.endpoints.every(v => v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = values.endpoints; + this.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = values.endpoints.slice(); } else { throw new TypeError( @@ -17248,7 +17254,8 @@ endpoints?: (URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -17277,7 +17284,7 @@ endpoints?: (URL)[];} { id: values.id ?? this.id }, options ); - clone.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = this.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint; + clone.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = this.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint.slice(); if ("endpoint" in values && values.endpoint != null) { if (values.endpoint instanceof URL) { // @ts-ignore: type is checked above. @@ -17304,7 +17311,7 @@ endpoints?: (URL)[];} if (Array.isArray(values.endpoints) && values.endpoints.every(v => v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = values.endpoints; + clone.#_2KM4fetG6FTJ1cphj76rzJ8Dyv7p_serviceEndpoint = values.endpoints.slice(); } else { throw new TypeError( @@ -17683,7 +17690,8 @@ endpoints?: (URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -18113,7 +18121,8 @@ cryptosuite?: "eddsa-jcs-2022" | null;verificationMethod?: Multikey | URL | null * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -18141,7 +18150,7 @@ cryptosuite?: "eddsa-jcs-2022" | null;verificationMethod?: Multikey | URL | null { id: values.id ?? this.id }, options ); - clone.#_3RurJsa7tnptyqMFR5hDGcP9pMs5_cryptosuite = this.#_3RurJsa7tnptyqMFR5hDGcP9pMs5_cryptosuite; + clone.#_3RurJsa7tnptyqMFR5hDGcP9pMs5_cryptosuite = this.#_3RurJsa7tnptyqMFR5hDGcP9pMs5_cryptosuite.slice(); if ("cryptosuite" in values && values.cryptosuite != null) { if (values.cryptosuite == "eddsa-jcs-2022") { // @ts-ignore: type is checked above. @@ -18154,7 +18163,7 @@ cryptosuite?: "eddsa-jcs-2022" | null;verificationMethod?: Multikey | URL | null ); } } - clone.#_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod = this.#_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod;clone.#_trust_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod = new Set(this.#_trust_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod); + clone.#_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod = this.#_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod.slice();clone.#_trust_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod = new Set(this.#_trust_2mHVKxqA7zncjveJrDEo3pWpMZqg_verificationMethod); if ("verificationMethod" in values && values.verificationMethod != null) { if (values.verificationMethod instanceof Multikey || values.verificationMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -18167,7 +18176,7 @@ cryptosuite?: "eddsa-jcs-2022" | null;verificationMethod?: Multikey | URL | null ); } } - clone.#_2AeEnPcAvVrPEuKbpmn9ZKNmWHKb_proofPurpose = this.#_2AeEnPcAvVrPEuKbpmn9ZKNmWHKb_proofPurpose; + clone.#_2AeEnPcAvVrPEuKbpmn9ZKNmWHKb_proofPurpose = this.#_2AeEnPcAvVrPEuKbpmn9ZKNmWHKb_proofPurpose.slice(); if ("proofPurpose" in values && values.proofPurpose != null) { if (values.proofPurpose === "assertionMethod" || values.proofPurpose === "authentication" || values.proofPurpose === "capabilityInvocation" || values.proofPurpose === "capabilityDelegation" || @@ -18182,7 +18191,7 @@ cryptosuite?: "eddsa-jcs-2022" | null;verificationMethod?: Multikey | URL | null ); } } - clone.#_3CjFK5vfKpX4HQuNh2b18TykoVLq_proofValue = this.#_3CjFK5vfKpX4HQuNh2b18TykoVLq_proofValue; + clone.#_3CjFK5vfKpX4HQuNh2b18TykoVLq_proofValue = this.#_3CjFK5vfKpX4HQuNh2b18TykoVLq_proofValue.slice(); if ("proofValue" in values && values.proofValue != null) { if (values.proofValue instanceof Uint8Array) { // @ts-ignore: type is checked above. @@ -18195,7 +18204,7 @@ cryptosuite?: "eddsa-jcs-2022" | null;verificationMethod?: Multikey | URL | null ); } } - clone.#_3qzP3ukEZoUziK5FEiA1RhU4aqac = this.#_3qzP3ukEZoUziK5FEiA1RhU4aqac; + clone.#_3qzP3ukEZoUziK5FEiA1RhU4aqac = this.#_3qzP3ukEZoUziK5FEiA1RhU4aqac.slice(); if ("created" in values && values.created != null) { if (isTemporalInstant(values.created)) { // @ts-ignore: type is checked above. @@ -19158,7 +19167,8 @@ owner?: Application | Group | Organization | Person | Service | URL | null;publi * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -19186,7 +19196,7 @@ owner?: Application | Group | Organization | Person | Service | URL | null;publi { id: values.id ?? this.id }, options ); - clone.#_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner = this.#_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner;clone.#_trust_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner = new Set(this.#_trust_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner); + clone.#_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner = this.#_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner.slice();clone.#_trust_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner = new Set(this.#_trust_5UJq9NDh3ZHgswFwwdVxQvJxdx2_owner); if ("owner" in values && values.owner != null) { if (values.owner instanceof Application || values.owner instanceof Group || values.owner instanceof Organization || values.owner instanceof Person || values.owner instanceof Service || values.owner instanceof URL) { // @ts-ignore: type is checked above. @@ -19199,7 +19209,7 @@ owner?: Application | Group | Organization | Person | Service | URL | null;publi ); } } - clone.#_2fE2QMDdg6KFGqa4NEC3TmjApSAD_publicKeyPem = this.#_2fE2QMDdg6KFGqa4NEC3TmjApSAD_publicKeyPem; + clone.#_2fE2QMDdg6KFGqa4NEC3TmjApSAD_publicKeyPem = this.#_2fE2QMDdg6KFGqa4NEC3TmjApSAD_publicKeyPem.slice(); if ("publicKey" in values && values.publicKey != null) { if ( // @ts-ignore: CryptoKey exists in the global scope. @@ -20073,7 +20083,8 @@ controller?: Application | Group | Organization | Person | Service | URL | null; * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -20101,7 +20112,7 @@ controller?: Application | Group | Organization | Person | Service | URL | null; { id: values.id ?? this.id }, options ); - clone.#_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller = this.#_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller;clone.#_trust_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller = new Set(this.#_trust_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller); + clone.#_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller = this.#_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller.slice();clone.#_trust_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller = new Set(this.#_trust_2yr3eUBTP6cNcyaxKzAXWjFsnGzN_controller); if ("controller" in values && values.controller != null) { if (values.controller instanceof Application || values.controller instanceof Group || values.controller instanceof Organization || values.controller instanceof Person || values.controller instanceof Service || values.controller instanceof URL) { // @ts-ignore: type is checked above. @@ -20114,7 +20125,7 @@ controller?: Application | Group | Organization | Person | Service | URL | null; ); } } - clone.#_4XLHbsR2gLVWU3NpEqKt9wANzn4F_publicKeyMultibase = this.#_4XLHbsR2gLVWU3NpEqKt9wANzn4F_publicKeyMultibase; + clone.#_4XLHbsR2gLVWU3NpEqKt9wANzn4F_publicKeyMultibase = this.#_4XLHbsR2gLVWU3NpEqKt9wANzn4F_publicKeyMultibase.slice(); if ("publicKey" in values && values.publicKey != null) { if ( // @ts-ignore: CryptoKey exists in the global scope. @@ -20913,7 +20924,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -21259,7 +21271,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -21600,7 +21613,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -22006,7 +22020,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -22042,7 +22056,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -22082,7 +22096,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -22205,7 +22219,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -22323,7 +22337,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -22363,7 +22377,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -22408,7 +22422,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -22451,7 +22466,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Application;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Application;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if ("preferredUsername" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === "string" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -22478,7 +22493,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -22487,7 +22502,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if ("publicKey" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -22514,7 +22529,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -22528,7 +22543,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if ("assertionMethod" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -22555,7 +22570,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -22569,7 +22584,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if ("manuallyApprovesFollowers" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === "boolean") { // @ts-ignore: type is checked above. @@ -22582,7 +22597,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if ("inbox" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -22595,7 +22610,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if ("outbox" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -22608,7 +22623,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if ("following" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -22621,7 +22636,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if ("followers" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -22634,7 +22649,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if ("liked" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -22647,7 +22662,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if ("featured" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -22660,7 +22675,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if ("featuredTags" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -22673,13 +22688,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if ("streams" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -22693,7 +22708,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if ("endpoints" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -22706,7 +22721,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if ("discoverable" in values && values.discoverable != null) { if (typeof values.discoverable === "boolean") { // @ts-ignore: type is checked above. @@ -22719,7 +22734,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if ("suspended" in values && values.suspended != null) { if (typeof values.suspended === "boolean") { // @ts-ignore: type is checked above. @@ -22732,7 +22747,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if ("memorial" in values && values.memorial != null) { if (typeof values.memorial === "boolean") { // @ts-ignore: type is checked above. @@ -22745,7 +22760,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if ("indexable" in values && values.indexable != null) { if (typeof values.indexable === "boolean") { // @ts-ignore: type is checked above. @@ -22758,7 +22773,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if ("successor" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -22771,7 +22786,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if ("alias" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -22798,7 +22813,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -22812,7 +22827,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if ("service" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -22839,7 +22854,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -22853,7 +22868,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if ("followedMessage" in values && values.followedMessage != null) { if (typeof values.followedMessage === "string") { // @ts-ignore: type is checked above. @@ -22866,7 +22881,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if ("cat" in values && values.cat != null) { if (typeof values.cat === "boolean") { // @ts-ignore: type is checked above. @@ -28884,7 +28899,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -29237,7 +29253,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -29583,7 +29600,8 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -29621,7 +29639,7 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Article;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl; + const clone = super.clone(values, options) as unknown as Article;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl.slice(); if ("quoteUrl" in values && values.quoteUrl != null) { if (values.quoteUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -30096,7 +30114,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -30134,7 +30153,7 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Document;clone.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width = this.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width; + const clone = super.clone(values, options) as unknown as Document;clone.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width = this.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width.slice(); if ("width" in values && values.width != null) { if (typeof values.width === "number" && Number.isInteger(values.width) && values.width >= 0) { // @ts-ignore: type is checked above. @@ -30147,7 +30166,7 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu ); } } - clone.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height = this.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height; + clone.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height = this.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height.slice(); if ("height" in values && values.height != null) { if (typeof values.height === "number" && Number.isInteger(values.height) && values.height >= 0) { // @ts-ignore: type is checked above. @@ -30667,7 +30686,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -31018,7 +31038,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -31364,7 +31385,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -31790,7 +31812,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); for (let i = 0; i < values.items.length; i++) { this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.add(i); @@ -31913,7 +31935,8 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -31951,7 +31974,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Collection;clone.#_XDbmNDuWHmrhqH712zqtecdbv1V_totalItems = this.#_XDbmNDuWHmrhqH712zqtecdbv1V_totalItems; + const clone = super.clone(values, options) as unknown as Collection;clone.#_XDbmNDuWHmrhqH712zqtecdbv1V_totalItems = this.#_XDbmNDuWHmrhqH712zqtecdbv1V_totalItems.slice(); if ("totalItems" in values && values.totalItems != null) { if (typeof values.totalItems === "number" && Number.isInteger(values.totalItems) && values.totalItems >= 0) { // @ts-ignore: type is checked above. @@ -31964,7 +31987,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3UyUdxnyn6cDn53QKrh4MBiearma_current = this.#_3UyUdxnyn6cDn53QKrh4MBiearma_current;clone.#_trust_3UyUdxnyn6cDn53QKrh4MBiearma_current = new Set(this.#_trust_3UyUdxnyn6cDn53QKrh4MBiearma_current); + clone.#_3UyUdxnyn6cDn53QKrh4MBiearma_current = this.#_3UyUdxnyn6cDn53QKrh4MBiearma_current.slice();clone.#_trust_3UyUdxnyn6cDn53QKrh4MBiearma_current = new Set(this.#_trust_3UyUdxnyn6cDn53QKrh4MBiearma_current); if ("current" in values && values.current != null) { if (values.current instanceof CollectionPage || values.current instanceof URL) { // @ts-ignore: type is checked above. @@ -31977,7 +32000,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_J52RqweMe6hhv7RnLJMC8BExTE5_first = this.#_J52RqweMe6hhv7RnLJMC8BExTE5_first;clone.#_trust_J52RqweMe6hhv7RnLJMC8BExTE5_first = new Set(this.#_trust_J52RqweMe6hhv7RnLJMC8BExTE5_first); + clone.#_J52RqweMe6hhv7RnLJMC8BExTE5_first = this.#_J52RqweMe6hhv7RnLJMC8BExTE5_first.slice();clone.#_trust_J52RqweMe6hhv7RnLJMC8BExTE5_first = new Set(this.#_trust_J52RqweMe6hhv7RnLJMC8BExTE5_first); if ("first" in values && values.first != null) { if (values.first instanceof CollectionPage || values.first instanceof URL) { // @ts-ignore: type is checked above. @@ -31990,7 +32013,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last = this.#_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last;clone.#_trust_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last = new Set(this.#_trust_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last); + clone.#_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last = this.#_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last.slice();clone.#_trust_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last = new Set(this.#_trust_gyJJnyEFnuNVi1HFZKfAn3Hfn26_last); if ("last" in values && values.last != null) { if (values.last instanceof CollectionPage || values.last instanceof URL) { // @ts-ignore: type is checked above. @@ -32003,13 +32026,13 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items;clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); + clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.slice();clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); if ("items" in values && values.items != null) { if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(); for (let i = 0; i < values.items.length; i++) { @@ -32023,7 +32046,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf = this.#_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf;clone.#_trust_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf = new Set(this.#_trust_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf); + clone.#_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf = this.#_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf.slice();clone.#_trust_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf = new Set(this.#_trust_4TB9Qd9ddtcZEpMfzbHhzafE6jaJ_likesOf); if ("likesOf" in values && values.likesOf != null) { if (values.likesOf instanceof Object || values.likesOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32036,7 +32059,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf = this.#_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf;clone.#_trust_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf = new Set(this.#_trust_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf); + clone.#_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf = this.#_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf.slice();clone.#_trust_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf = new Set(this.#_trust_3manzgeKiPsugpztKGiaUUwJ3ito_sharesOf); if ("sharesOf" in values && values.sharesOf != null) { if (values.sharesOf instanceof Object || values.sharesOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32049,7 +32072,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf = this.#_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf;clone.#_trust_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf = new Set(this.#_trust_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf); + clone.#_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf = this.#_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf.slice();clone.#_trust_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf = new Set(this.#_trust_3T3oGm3twpcQUcrnMisXQtmDZ32X_repliesOf); if ("repliesOf" in values && values.repliesOf != null) { if (values.repliesOf instanceof Object || values.repliesOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32062,7 +32085,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf = this.#_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf;clone.#_trust_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf = new Set(this.#_trust_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf); + clone.#_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf = this.#_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf.slice();clone.#_trust_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf = new Set(this.#_trust_2bvRkAFZjMfVD8jiUWZJr5YokSeN_inboxOf); if ("inboxOf" in values && values.inboxOf != null) { if (values.inboxOf instanceof Object || values.inboxOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32075,7 +32098,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf = this.#_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf;clone.#_trust_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf = new Set(this.#_trust_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf); + clone.#_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf = this.#_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf.slice();clone.#_trust_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf = new Set(this.#_trust_4AHzVZDxHjK6uEWa9UiKHGK34yYm_outboxOf); if ("outboxOf" in values && values.outboxOf != null) { if (values.outboxOf instanceof Object || values.outboxOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32088,7 +32111,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf = this.#_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf;clone.#_trust_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf = new Set(this.#_trust_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf); + clone.#_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf = this.#_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf.slice();clone.#_trust_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf = new Set(this.#_trust_41aoZ5M6yRUHy3Zx8q6iuZQxtopb_followersOf); if ("followersOf" in values && values.followersOf != null) { if (values.followersOf instanceof Object || values.followersOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32101,7 +32124,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf = this.#_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf;clone.#_trust_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf = new Set(this.#_trust_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf); + clone.#_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf = this.#_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf.slice();clone.#_trust_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf = new Set(this.#_trust_2nXT2Ah42UjEEQF5oJQ39CbKB1xj_followingOf); if ("followingOf" in values && values.followingOf != null) { if (values.followingOf instanceof Object || values.followingOf instanceof URL) { // @ts-ignore: type is checked above. @@ -32114,7 +32137,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf = this.#_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf;clone.#_trust_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf = new Set(this.#_trust_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf); + clone.#_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf = this.#_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf.slice();clone.#_trust_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf = new Set(this.#_trust_2bsySzmT3qEZcrnoe3tZ5xBjXSju_likedOf); if ("likedOf" in values && values.likedOf != null) { if (values.likedOf instanceof Object || values.likedOf instanceof URL) { // @ts-ignore: type is checked above. @@ -36438,7 +36461,8 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -36476,7 +36500,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as CollectionPage;clone.#_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf = this.#_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf;clone.#_trust_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf = new Set(this.#_trust_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf); + const clone = super.clone(values, options) as unknown as CollectionPage;clone.#_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf = this.#_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf.slice();clone.#_trust_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf = new Set(this.#_trust_2kWgBhQKjEauxx8C6qF3ZQamK4Le_partOf); if ("partOf" in values && values.partOf != null) { if (values.partOf instanceof Collection || values.partOf instanceof URL) { // @ts-ignore: type is checked above. @@ -36489,7 +36513,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next = this.#_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next;clone.#_trust_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next = new Set(this.#_trust_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next); + clone.#_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next = this.#_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next.slice();clone.#_trust_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next = new Set(this.#_trust_3BT4kQLcXhHx7TAWaNDKh8nFn9eY_next); if ("next" in values && values.next != null) { if (values.next instanceof CollectionPage || values.next instanceof URL) { // @ts-ignore: type is checked above. @@ -36502,7 +36526,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev = this.#_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev;clone.#_trust_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev = new Set(this.#_trust_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev); + clone.#_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev = this.#_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev.slice();clone.#_trust_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev = new Set(this.#_trust_3b8yG8tDNzQFFEnWhCc13G8eHooA_prev); if ("prev" in values && values.prev != null) { if (values.prev instanceof CollectionPage || values.prev instanceof URL) { // @ts-ignore: type is checked above. @@ -37784,7 +37808,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -38124,7 +38149,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -38462,7 +38488,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -38932,7 +38959,8 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -38960,7 +38988,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint { id: values.id ?? this.id }, options ); - clone.#_2JCYDbSxEHCCLdBYed33cCETfGyR_proxyUrl = this.#_2JCYDbSxEHCCLdBYed33cCETfGyR_proxyUrl; + clone.#_2JCYDbSxEHCCLdBYed33cCETfGyR_proxyUrl = this.#_2JCYDbSxEHCCLdBYed33cCETfGyR_proxyUrl.slice(); if ("proxyUrl" in values && values.proxyUrl != null) { if (values.proxyUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -38973,7 +39001,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_25S6UmgzDead8hxL5sQFezZTAusd_oauthAuthorizationEndpoint = this.#_25S6UmgzDead8hxL5sQFezZTAusd_oauthAuthorizationEndpoint; + clone.#_25S6UmgzDead8hxL5sQFezZTAusd_oauthAuthorizationEndpoint = this.#_25S6UmgzDead8hxL5sQFezZTAusd_oauthAuthorizationEndpoint.slice(); if ("oauthAuthorizationEndpoint" in values && values.oauthAuthorizationEndpoint != null) { if (values.oauthAuthorizationEndpoint instanceof URL) { // @ts-ignore: type is checked above. @@ -38986,7 +39014,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_iAMxqrSba7yBCRB1FZ5kEVdKEZ3_oauthTokenEndpoint = this.#_iAMxqrSba7yBCRB1FZ5kEVdKEZ3_oauthTokenEndpoint; + clone.#_iAMxqrSba7yBCRB1FZ5kEVdKEZ3_oauthTokenEndpoint = this.#_iAMxqrSba7yBCRB1FZ5kEVdKEZ3_oauthTokenEndpoint.slice(); if ("oauthTokenEndpoint" in values && values.oauthTokenEndpoint != null) { if (values.oauthTokenEndpoint instanceof URL) { // @ts-ignore: type is checked above. @@ -38999,7 +39027,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_8Bx9qN8oU7Bpt2xi6khaxWp1gMr_provideClientKey = this.#_8Bx9qN8oU7Bpt2xi6khaxWp1gMr_provideClientKey; + clone.#_8Bx9qN8oU7Bpt2xi6khaxWp1gMr_provideClientKey = this.#_8Bx9qN8oU7Bpt2xi6khaxWp1gMr_provideClientKey.slice(); if ("provideClientKey" in values && values.provideClientKey != null) { if (values.provideClientKey instanceof URL) { // @ts-ignore: type is checked above. @@ -39012,7 +39040,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_3dU7PMVQZJpsCpo2F4RQXxBXdPmS_signClientKey = this.#_3dU7PMVQZJpsCpo2F4RQXxBXdPmS_signClientKey; + clone.#_3dU7PMVQZJpsCpo2F4RQXxBXdPmS_signClientKey = this.#_3dU7PMVQZJpsCpo2F4RQXxBXdPmS_signClientKey.slice(); if ("signClientKey" in values && values.signClientKey != null) { if (values.signClientKey instanceof URL) { // @ts-ignore: type is checked above. @@ -39025,7 +39053,7 @@ proxyUrl?: URL | null;oauthAuthorizationEndpoint?: URL | null;oauthTokenEndpoint ); } } - clone.#_3JprUSDLVqqX4dwHRi37qGZZCRCc_sharedInbox = this.#_3JprUSDLVqqX4dwHRi37qGZZCRCc_sharedInbox; + clone.#_3JprUSDLVqqX4dwHRi37qGZZCRCc_sharedInbox = this.#_3JprUSDLVqqX4dwHRi37qGZZCRCc_sharedInbox.slice(); if ("sharedInbox" in values && values.sharedInbox != null) { if (values.sharedInbox instanceof URL) { // @ts-ignore: type is checked above. @@ -39973,7 +40001,8 @@ proofs?: (DataIntegrityProof | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -40325,7 +40354,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -40667,7 +40697,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -41073,7 +41104,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -41109,7 +41140,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -41149,7 +41180,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -41272,7 +41303,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -41390,7 +41421,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -41430,7 +41461,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -41475,7 +41506,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -41518,7 +41550,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Group;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Group;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if ("preferredUsername" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === "string" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -41545,7 +41577,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -41554,7 +41586,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if ("publicKey" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -41581,7 +41613,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -41595,7 +41627,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if ("assertionMethod" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -41622,7 +41654,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -41636,7 +41668,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if ("manuallyApprovesFollowers" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === "boolean") { // @ts-ignore: type is checked above. @@ -41649,7 +41681,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if ("inbox" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -41662,7 +41694,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if ("outbox" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -41675,7 +41707,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if ("following" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -41688,7 +41720,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if ("followers" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -41701,7 +41733,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if ("liked" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -41714,7 +41746,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if ("featured" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -41727,7 +41759,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if ("featuredTags" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -41740,13 +41772,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if ("streams" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -41760,7 +41792,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if ("endpoints" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -41773,7 +41805,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if ("discoverable" in values && values.discoverable != null) { if (typeof values.discoverable === "boolean") { // @ts-ignore: type is checked above. @@ -41786,7 +41818,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if ("suspended" in values && values.suspended != null) { if (typeof values.suspended === "boolean") { // @ts-ignore: type is checked above. @@ -41799,7 +41831,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if ("memorial" in values && values.memorial != null) { if (typeof values.memorial === "boolean") { // @ts-ignore: type is checked above. @@ -41812,7 +41844,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if ("indexable" in values && values.indexable != null) { if (typeof values.indexable === "boolean") { // @ts-ignore: type is checked above. @@ -41825,7 +41857,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if ("successor" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -41838,7 +41870,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if ("alias" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -41865,7 +41897,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -41879,7 +41911,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if ("service" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -41906,7 +41938,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -41920,7 +41952,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if ("followedMessage" in values && values.followedMessage != null) { if (typeof values.followedMessage === "string") { // @ts-ignore: type is checked above. @@ -41933,7 +41965,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if ("cat" in values && values.cat != null) { if (typeof values.cat === "boolean") { // @ts-ignore: type is checked above. @@ -48050,7 +48082,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.rels) && values.rels.every(v => typeof v === "string")) { // @ts-ignore: type is checked above. - this.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = values.rels; + this.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = values.rels.slice(); } else { throw new TypeError( @@ -48099,7 +48131,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.names) && values.names.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names; + this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names.slice(); } else { throw new TypeError( @@ -48153,7 +48185,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.previews) && values.previews.every(v => v instanceof Link || v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews; + this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews.slice(); for (let i = 0; i < values.previews.length; i++) { this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview.add(i); @@ -48172,7 +48204,8 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -48202,7 +48235,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num { id: values.id ?? this.id }, options ); - clone.#_pVjLsybKQdmkjuU7MHjiVmNnuj7_href = this.#_pVjLsybKQdmkjuU7MHjiVmNnuj7_href; + clone.#_pVjLsybKQdmkjuU7MHjiVmNnuj7_href = this.#_pVjLsybKQdmkjuU7MHjiVmNnuj7_href.slice(); if ("href" in values && values.href != null) { if (values.href instanceof URL) { // @ts-ignore: type is checked above. @@ -48215,7 +48248,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = this.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel; + clone.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = this.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel.slice(); if ("rel" in values && values.rel != null) { if (typeof values.rel === "string") { // @ts-ignore: type is checked above. @@ -48242,7 +48275,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.rels) && values.rels.every(v => typeof v === "string")) { // @ts-ignore: type is checked above. - clone.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = values.rels; + clone.#_2a1c5GkfkQsnyyLybF8UXBQfFuHZ_rel = values.rels.slice(); } else { throw new TypeError( @@ -48251,7 +48284,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType; + clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType.slice(); if ("mediaType" in values && values.mediaType != null) { if (typeof values.mediaType === "string") { // @ts-ignore: type is checked above. @@ -48264,7 +48297,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = this.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name.slice(); if ("name" in values && values.name != null) { if (typeof values.name === "string" || values.name instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -48291,7 +48324,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num if (Array.isArray(values.names) && values.names.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names; + clone.#_4ZHbBuK7PrsvGgrjM8wgc6KMWjav_name = values.names.slice(); } else { throw new TypeError( @@ -48300,7 +48333,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang = this.#_f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang; + clone.#_f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang = this.#_f57HKWCp1YRBbTJE8PF12RbDJGf_hreflang.slice(); if ("language" in values && values.language != null) { if (values.language instanceof Intl.Locale) { // @ts-ignore: type is checked above. @@ -48313,7 +48346,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height = this.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height; + clone.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height = this.#_2cGKFeFJMmiNpGZFEF75mCwFQsKb_height.slice(); if ("height" in values && values.height != null) { if (typeof values.height === "number" && Number.isInteger(values.height) && values.height >= 0) { // @ts-ignore: type is checked above. @@ -48326,7 +48359,7 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width = this.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width; + clone.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width = this.#_2e9AP7WdHBJYAgXG6GEyq7nSkNMe_width.slice(); if ("width" in values && values.width != null) { if (typeof values.width === "number" && Number.isInteger(values.width) && values.width >= 0) { // @ts-ignore: type is checked above. @@ -48339,13 +48372,13 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num ); } } - clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview;clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview); + clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = this.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview.slice();clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(this.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview); if ("previews" in values && values.previews != null) { if (Array.isArray(values.previews) && values.previews.every(v => v instanceof Link || v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews; + clone.#_gCVTegXxWWCw6wWRxa1QF65zusg_preview = values.previews.slice(); clone.#_trust_gCVTegXxWWCw6wWRxa1QF65zusg_preview = new Set(); for (let i = 0; i < values.previews.length; i++) { @@ -49697,7 +49730,8 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -50015,7 +50049,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -50367,7 +50402,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -50711,7 +50747,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -51051,7 +51088,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -51391,7 +51429,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -51731,7 +51770,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -52069,7 +52109,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -52387,7 +52428,8 @@ names?: ((string | LanguageString))[];language?: Intl.Locale | null;height?: num * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -52714,7 +52756,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -53062,7 +53105,8 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -53100,7 +53144,7 @@ proofs?: (DataIntegrityProof | URL)[];quoteUrl?: URL | null;} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Note;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl; + const clone = super.clone(values, options) as unknown as Note;clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl.slice(); if ("quoteUrl" in values && values.quoteUrl != null) { if (values.quoteUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -53552,7 +53596,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); for (let i = 0; i < values.items.length; i++) { this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.add(i); @@ -53571,7 +53615,8 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -53609,13 +53654,13 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as OrderedCollection;clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items;clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); + const clone = super.clone(values, options) as unknown as OrderedCollection;clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.slice();clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); if ("items" in values && values.items != null) { if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(); for (let i = 0; i < values.items.length; i++) { @@ -54286,7 +54331,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); for (let i = 0; i < values.items.length; i++) { this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.add(i); @@ -54318,7 +54363,8 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -54356,13 +54402,13 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as OrderedCollectionPage;clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items;clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); + const clone = super.clone(values, options) as unknown as OrderedCollectionPage;clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = this.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items.slice();clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(this.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items); if ("items" in values && values.items != null) { if (Array.isArray(values.items) && values.items.every(v => v instanceof Object || v instanceof Link || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items; + clone.#_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = values.items.slice(); clone.#_trust_2JPCKWTcfBmTCcW8Tv3TpRaLVaqg_items = new Set(); for (let i = 0; i < values.items.length; i++) { @@ -54376,7 +54422,7 @@ proofs?: (DataIntegrityProof | URL)[];totalItems?: number | null;current?: Colle ); } } - clone.#_2W4yinFwqmpneu2h4m1mZ3pcLADd_startIndex = this.#_2W4yinFwqmpneu2h4m1mZ3pcLADd_startIndex; + clone.#_2W4yinFwqmpneu2h4m1mZ3pcLADd_startIndex = this.#_2W4yinFwqmpneu2h4m1mZ3pcLADd_startIndex.slice(); if ("startIndex" in values && values.startIndex != null) { if (typeof values.startIndex === "number" && Number.isInteger(values.startIndex) && values.startIndex >= 0) { // @ts-ignore: type is checked above. @@ -55206,7 +55252,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -55242,7 +55288,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -55282,7 +55328,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -55405,7 +55451,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -55523,7 +55569,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -55563,7 +55609,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -55608,7 +55654,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -55651,7 +55698,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Organization;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Organization;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if ("preferredUsername" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === "string" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -55678,7 +55725,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -55687,7 +55734,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if ("publicKey" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -55714,7 +55761,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -55728,7 +55775,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if ("assertionMethod" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -55755,7 +55802,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -55769,7 +55816,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if ("manuallyApprovesFollowers" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === "boolean") { // @ts-ignore: type is checked above. @@ -55782,7 +55829,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if ("inbox" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -55795,7 +55842,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if ("outbox" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -55808,7 +55855,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if ("following" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -55821,7 +55868,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if ("followers" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -55834,7 +55881,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if ("liked" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -55847,7 +55894,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if ("featured" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -55860,7 +55907,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if ("featuredTags" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -55873,13 +55920,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if ("streams" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -55893,7 +55940,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if ("endpoints" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -55906,7 +55953,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if ("discoverable" in values && values.discoverable != null) { if (typeof values.discoverable === "boolean") { // @ts-ignore: type is checked above. @@ -55919,7 +55966,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if ("suspended" in values && values.suspended != null) { if (typeof values.suspended === "boolean") { // @ts-ignore: type is checked above. @@ -55932,7 +55979,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if ("memorial" in values && values.memorial != null) { if (typeof values.memorial === "boolean") { // @ts-ignore: type is checked above. @@ -55945,7 +55992,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if ("indexable" in values && values.indexable != null) { if (typeof values.indexable === "boolean") { // @ts-ignore: type is checked above. @@ -55958,7 +56005,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if ("successor" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -55971,7 +56018,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if ("alias" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -55998,7 +56045,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -56012,7 +56059,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if ("service" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -56039,7 +56086,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -56053,7 +56100,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if ("followedMessage" in values && values.followedMessage != null) { if (typeof values.followedMessage === "string") { // @ts-ignore: type is checked above. @@ -56066,7 +56113,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if ("cat" in values && values.cat != null) { if (typeof values.cat === "boolean") { // @ts-ignore: type is checked above. @@ -62075,7 +62122,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -62492,7 +62540,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -62528,7 +62576,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -62568,7 +62616,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -62691,7 +62739,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -62809,7 +62857,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -62849,7 +62897,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -62894,7 +62942,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -62937,7 +62986,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Person;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Person;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if ("preferredUsername" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === "string" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -62964,7 +63013,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -62973,7 +63022,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if ("publicKey" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -63000,7 +63049,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -63014,7 +63063,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if ("assertionMethod" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -63041,7 +63090,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -63055,7 +63104,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if ("manuallyApprovesFollowers" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === "boolean") { // @ts-ignore: type is checked above. @@ -63068,7 +63117,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if ("inbox" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -63081,7 +63130,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if ("outbox" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -63094,7 +63143,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if ("following" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -63107,7 +63156,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if ("followers" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -63120,7 +63169,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if ("liked" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -63133,7 +63182,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if ("featured" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -63146,7 +63195,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if ("featuredTags" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -63159,13 +63208,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if ("streams" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -63179,7 +63228,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if ("endpoints" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -63192,7 +63241,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if ("discoverable" in values && values.discoverable != null) { if (typeof values.discoverable === "boolean") { // @ts-ignore: type is checked above. @@ -63205,7 +63254,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if ("suspended" in values && values.suspended != null) { if (typeof values.suspended === "boolean") { // @ts-ignore: type is checked above. @@ -63218,7 +63267,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if ("memorial" in values && values.memorial != null) { if (typeof values.memorial === "boolean") { // @ts-ignore: type is checked above. @@ -63231,7 +63280,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if ("indexable" in values && values.indexable != null) { if (typeof values.indexable === "boolean") { // @ts-ignore: type is checked above. @@ -63244,7 +63293,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if ("successor" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -63257,7 +63306,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if ("alias" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -63284,7 +63333,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -63298,7 +63347,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if ("service" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -63325,7 +63374,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -63339,7 +63388,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if ("followedMessage" in values && values.followedMessage != null) { if (typeof values.followedMessage === "string") { // @ts-ignore: type is checked above. @@ -63352,7 +63401,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if ("cat" in values && values.cat != null) { if (typeof values.cat === "boolean") { // @ts-ignore: type is checked above. @@ -69448,7 +69497,8 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -69486,7 +69536,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Place;clone.#_3UCsHnBHvDAXJnBuzw3zw1VVs3Ne_accuracy = this.#_3UCsHnBHvDAXJnBuzw3zw1VVs3Ne_accuracy; + const clone = super.clone(values, options) as unknown as Place;clone.#_3UCsHnBHvDAXJnBuzw3zw1VVs3Ne_accuracy = this.#_3UCsHnBHvDAXJnBuzw3zw1VVs3Ne_accuracy.slice(); if ("accuracy" in values && values.accuracy != null) { if (typeof values.accuracy === "number" && !Number.isNaN(values.accuracy)) { // @ts-ignore: type is checked above. @@ -69499,7 +69549,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_3Q6KDcFQUJRRaBux1BL2yp5QWiBi_altitude = this.#_3Q6KDcFQUJRRaBux1BL2yp5QWiBi_altitude; + clone.#_3Q6KDcFQUJRRaBux1BL2yp5QWiBi_altitude = this.#_3Q6KDcFQUJRRaBux1BL2yp5QWiBi_altitude.slice(); if ("altitude" in values && values.altitude != null) { if (typeof values.altitude === "number" && !Number.isNaN(values.altitude)) { // @ts-ignore: type is checked above. @@ -69512,7 +69562,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_3g85RoKRnaNjP7DFyLSvsWDg7HGM_latitude = this.#_3g85RoKRnaNjP7DFyLSvsWDg7HGM_latitude; + clone.#_3g85RoKRnaNjP7DFyLSvsWDg7HGM_latitude = this.#_3g85RoKRnaNjP7DFyLSvsWDg7HGM_latitude.slice(); if ("latitude" in values && values.latitude != null) { if (typeof values.latitude === "number" && !Number.isNaN(values.latitude)) { // @ts-ignore: type is checked above. @@ -69525,7 +69575,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_B2GEYdS9yBAF3ho1pm1rcRg7cSf_longitude = this.#_B2GEYdS9yBAF3ho1pm1rcRg7cSf_longitude; + clone.#_B2GEYdS9yBAF3ho1pm1rcRg7cSf_longitude = this.#_B2GEYdS9yBAF3ho1pm1rcRg7cSf_longitude.slice(); if ("longitude" in values && values.longitude != null) { if (typeof values.longitude === "number" && !Number.isNaN(values.longitude)) { // @ts-ignore: type is checked above. @@ -69538,7 +69588,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_3ga86BKHUtRkGx5PHBjRiUXXzwnw_radius = this.#_3ga86BKHUtRkGx5PHBjRiUXXzwnw_radius; + clone.#_3ga86BKHUtRkGx5PHBjRiUXXzwnw_radius = this.#_3ga86BKHUtRkGx5PHBjRiUXXzwnw_radius.slice(); if ("radius" in values && values.radius != null) { if (typeof values.radius === "number" && !Number.isNaN(values.radius)) { // @ts-ignore: type is checked above. @@ -69551,7 +69601,7 @@ proofs?: (DataIntegrityProof | URL)[];accuracy?: number | null;altitude?: number ); } } - clone.#_oKrwxU4V8wiKhMW1QEYQibcJh8c_units = this.#_oKrwxU4V8wiKhMW1QEYQibcJh8c_units; + clone.#_oKrwxU4V8wiKhMW1QEYQibcJh8c_units = this.#_oKrwxU4V8wiKhMW1QEYQibcJh8c_units.slice(); if ("units" in values && values.units != null) { if (values.units == "cm" || values.units == "feet" || values.units == "inches" || values.units == "km" || values.units == "m" || values.units == "miles" || values.units instanceof URL) { // @ts-ignore: type is checked above. @@ -70468,7 +70518,8 @@ proofs?: (DataIntegrityProof | URL)[];describes?: Object | URL | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -70506,7 +70557,7 @@ proofs?: (DataIntegrityProof | URL)[];describes?: Object | URL | null;} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Profile;clone.#_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes = this.#_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes;clone.#_trust_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes = new Set(this.#_trust_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes); + const clone = super.clone(values, options) as unknown as Profile;clone.#_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes = this.#_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes.slice();clone.#_trust_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes = new Set(this.#_trust_3CLQ1PLSXrhSQbTGGHuxNyaEFKM1_describes); if ("describes" in values && values.describes != null) { if (values.describes instanceof Object || values.describes instanceof URL) { // @ts-ignore: type is checked above. @@ -71166,7 +71217,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti if (Array.isArray(values.exclusiveOptions) && values.exclusiveOptions.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = values.exclusiveOptions; + this.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = values.exclusiveOptions.slice(); for (let i = 0; i < values.exclusiveOptions.length; i++) { this.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf.add(i); @@ -71185,7 +71236,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti if (Array.isArray(values.inclusiveOptions) && values.inclusiveOptions.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = values.inclusiveOptions; + this.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = values.inclusiveOptions.slice(); for (let i = 0; i < values.inclusiveOptions.length; i++) { this.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf.add(i); @@ -71243,7 +71294,8 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -71287,13 +71339,13 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Question;clone.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = this.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf;clone.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = new Set(this.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf); + const clone = super.clone(values, options) as unknown as Question;clone.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = this.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf.slice();clone.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = new Set(this.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf); if ("exclusiveOptions" in values && values.exclusiveOptions != null) { if (Array.isArray(values.exclusiveOptions) && values.exclusiveOptions.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = values.exclusiveOptions; + clone.#_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = values.exclusiveOptions.slice(); clone.#_trust_2N5scKaVEcdYHFmfKYYacAwUhUgQ_oneOf = new Set(); for (let i = 0; i < values.exclusiveOptions.length; i++) { @@ -71307,13 +71359,13 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti ); } } - clone.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = this.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf;clone.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = new Set(this.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf); + clone.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = this.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf.slice();clone.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = new Set(this.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf); if ("inclusiveOptions" in values && values.inclusiveOptions != null) { if (Array.isArray(values.inclusiveOptions) && values.inclusiveOptions.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = values.inclusiveOptions; + clone.#_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = values.inclusiveOptions.slice(); clone.#_trust_2mV6isMTPRKbWdLCjcpiEysq5dAY_anyOf = new Set(); for (let i = 0; i < values.inclusiveOptions.length; i++) { @@ -71327,7 +71379,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti ); } } - clone.#_3KronwL8DiiKBRcJFKQPiEHm8xb6_closed = this.#_3KronwL8DiiKBRcJFKQPiEHm8xb6_closed; + clone.#_3KronwL8DiiKBRcJFKQPiEHm8xb6_closed = this.#_3KronwL8DiiKBRcJFKQPiEHm8xb6_closed.slice(); if ("closed" in values && values.closed != null) { if (isTemporalInstant(values.closed) || typeof values.closed === "boolean") { // @ts-ignore: type is checked above. @@ -71340,7 +71392,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti ); } } - clone.#_3H4RdST7dxfmghccvE3rKD3KgcxG_votersCount = this.#_3H4RdST7dxfmghccvE3rKD3KgcxG_votersCount; + clone.#_3H4RdST7dxfmghccvE3rKD3KgcxG_votersCount = this.#_3H4RdST7dxfmghccvE3rKD3KgcxG_votersCount.slice(); if ("voters" in values && values.voters != null) { if (typeof values.voters === "number" && Number.isInteger(values.voters) && values.voters >= 0) { // @ts-ignore: type is checked above. @@ -71353,7 +71405,7 @@ instruments?: (Object | URL)[];exclusiveOptions?: (Object | URL)[];inclusiveOpti ); } } - clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl; + clone.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl = this.#_K1zrMQkQjmciFAmGdGLfaDbG925_quoteUrl.slice(); if ("quoteUrl" in values && values.quoteUrl != null) { if (values.quoteUrl instanceof URL) { // @ts-ignore: type is checked above. @@ -72541,7 +72593,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -72881,7 +72934,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -73269,7 +73323,7 @@ relationships?: (Object | URL)[];} if (Array.isArray(values.objects) && values.objects.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects; + this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects.slice(); for (let i = 0; i < values.objects.length; i++) { this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object.add(i); @@ -73309,7 +73363,7 @@ relationships?: (Object | URL)[];} if (Array.isArray(values.relationships) && values.relationships.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = values.relationships; + this.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = values.relationships.slice(); for (let i = 0; i < values.relationships.length; i++) { this.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship.add(i); @@ -73328,7 +73382,8 @@ relationships?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -73368,7 +73423,7 @@ relationships?: (Object | URL)[];} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Relationship;clone.#_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject = this.#_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject;clone.#_trust_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject = new Set(this.#_trust_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject); + const clone = super.clone(values, options) as unknown as Relationship;clone.#_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject = this.#_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject.slice();clone.#_trust_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject = new Set(this.#_trust_2Zqdmi46ZnDQsECS6mzwhrv3rUKq_subject); if ("subject" in values && values.subject != null) { if (values.subject instanceof Object || values.subject instanceof URL) { // @ts-ignore: type is checked above. @@ -73381,7 +73436,7 @@ relationships?: (Object | URL)[];} ); } } - clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object;clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object); + clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = this.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object.slice();clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(this.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object); if ("object" in values && values.object != null) { if (values.object instanceof Object || values.object instanceof URL) { // @ts-ignore: type is checked above. @@ -73408,7 +73463,7 @@ relationships?: (Object | URL)[];} if (Array.isArray(values.objects) && values.objects.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects; + clone.#_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = values.objects.slice(); clone.#_trust_2MH19yxjn1wnHsNfa5n4JBhJzxyc_object = new Set(); for (let i = 0; i < values.objects.length; i++) { @@ -73422,7 +73477,7 @@ relationships?: (Object | URL)[];} ); } } - clone.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = this.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship;clone.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = new Set(this.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship); + clone.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = this.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship.slice();clone.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = new Set(this.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship); if ("relationship" in values && values.relationship != null) { if (values.relationship instanceof Object || values.relationship instanceof URL) { // @ts-ignore: type is checked above. @@ -73449,7 +73504,7 @@ relationships?: (Object | URL)[];} if (Array.isArray(values.relationships) && values.relationships.every(v => v instanceof Object || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = values.relationships; + clone.#_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = values.relationships.slice(); clone.#_trust_4Lzz89F9qipAQSGkWyX9DGWiUojG_relationship = new Set(); for (let i = 0; i < values.relationships.length; i++) { @@ -74957,7 +75012,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -75363,7 +75419,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -75399,7 +75455,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); for (let i = 0; i < values.publicKeys.length; i++) { this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey.add(i); @@ -75439,7 +75495,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); for (let i = 0; i < values.assertionMethods.length; i++) { this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.add(i); @@ -75562,7 +75618,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); for (let i = 0; i < values.streams.length; i++) { this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.add(i); @@ -75680,7 +75736,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); for (let i = 0; i < values.aliases.length; i++) { this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.add(i); @@ -75720,7 +75776,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); for (let i = 0; i < values.services.length; i++) { this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.add(i); @@ -75765,7 +75821,8 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -75808,7 +75865,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Service;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername; + const clone = super.clone(values, options) as unknown as Service;clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = this.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername.slice(); if ("preferredUsername" in values && values.preferredUsername != null) { if (typeof values.preferredUsername === "string" || values.preferredUsername instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -75835,7 +75892,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.preferredUsernames) && values.preferredUsernames.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames; + clone.#_3isuDgRAKSntq9XdbjiNxjwyPZAf_preferredUsername = values.preferredUsernames.slice(); } else { throw new TypeError( @@ -75844,7 +75901,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey;clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = this.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey.slice();clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(this.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey); if ("publicKey" in values && values.publicKey != null) { if (values.publicKey instanceof CryptographicKey || values.publicKey instanceof URL) { // @ts-ignore: type is checked above. @@ -75871,7 +75928,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.publicKeys) && values.publicKeys.every(v => v instanceof CryptographicKey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys; + clone.#_axq166E2eZADq34V4MYUc8KMZdC_publicKey = values.publicKeys.slice(); clone.#_trust_axq166E2eZADq34V4MYUc8KMZdC_publicKey = new Set(); for (let i = 0; i < values.publicKeys.length; i++) { @@ -75885,7 +75942,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod;clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = this.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod.slice();clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(this.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod); if ("assertionMethod" in values && values.assertionMethod != null) { if (values.assertionMethod instanceof Multikey || values.assertionMethod instanceof URL) { // @ts-ignore: type is checked above. @@ -75912,7 +75969,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.assertionMethods) && values.assertionMethods.every(v => v instanceof Multikey || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods; + clone.#_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = values.assertionMethods.slice(); clone.#_trust_4EHQFWZSz1k1d4LmPrQiMba2GbP3_assertionMethod = new Set(); for (let i = 0; i < values.assertionMethods.length; i++) { @@ -75926,7 +75983,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers; + clone.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers = this.#_36QNc9MxfkKf6h8sEUQSHnV9NZA_manuallyApprovesFollowers.slice(); if ("manuallyApprovesFollowers" in values && values.manuallyApprovesFollowers != null) { if (typeof values.manuallyApprovesFollowers === "boolean") { // @ts-ignore: type is checked above. @@ -75939,7 +75996,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox;clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); + clone.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = this.#_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox.slice();clone.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox = new Set(this.#_trust_3ghX3VfZXXbLvhCRH7QJqpzLrXjB_inbox); if ("inbox" in values && values.inbox != null) { if (values.inbox instanceof OrderedCollection || values.inbox instanceof OrderedCollectionPage || values.inbox instanceof URL) { // @ts-ignore: type is checked above. @@ -75952,7 +76009,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox;clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); + clone.#_41QwhqJouoLg3h8dRPKat21brynC_outbox = this.#_41QwhqJouoLg3h8dRPKat21brynC_outbox.slice();clone.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox = new Set(this.#_trust_41QwhqJouoLg3h8dRPKat21brynC_outbox); if ("outbox" in values && values.outbox != null) { if (values.outbox instanceof OrderedCollection || values.outbox instanceof OrderedCollectionPage || values.outbox instanceof URL) { // @ts-ignore: type is checked above. @@ -75965,7 +76022,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following;clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); + clone.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = this.#_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following.slice();clone.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following = new Set(this.#_trust_3yAv8jymNfNuJUDuBzJ1NQhdbAee_following); if ("following" in values && values.following != null) { if (values.following instanceof Collection || values.following instanceof URL) { // @ts-ignore: type is checked above. @@ -75978,7 +76035,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers;clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); + clone.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = this.#_BBCTgfphhsFzpVfKTykGSpBNwoA_followers.slice();clone.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers = new Set(this.#_trust_BBCTgfphhsFzpVfKTykGSpBNwoA_followers); if ("followers" in values && values.followers != null) { if (values.followers instanceof Collection || values.followers instanceof URL) { // @ts-ignore: type is checked above. @@ -75991,7 +76048,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked;clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); + clone.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = this.#_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked.slice();clone.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked = new Set(this.#_trust_3bgkPwJanyTCoVFM9ovRcus8tKkU_liked); if ("liked" in values && values.liked != null) { if (values.liked instanceof Collection || values.liked instanceof URL) { // @ts-ignore: type is checked above. @@ -76004,7 +76061,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured;clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); + clone.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured = this.#_4N1vBJzXDf8NbBumeECQMFvKetja_featured.slice();clone.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured = new Set(this.#_trust_4N1vBJzXDf8NbBumeECQMFvKetja_featured); if ("featured" in values && values.featured != null) { if (values.featured instanceof Collection || values.featured instanceof URL) { // @ts-ignore: type is checked above. @@ -76017,7 +76074,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags;clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); + clone.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = this.#_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags.slice();clone.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags = new Set(this.#_trust_2MxnRRLq9iPzx5CFq2NPrXdUDCac_featuredTags); if ("featuredTags" in values && values.featuredTags != null) { if (values.featuredTags instanceof Collection || values.featuredTags instanceof URL) { // @ts-ignore: type is checked above. @@ -76030,13 +76087,13 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams;clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = this.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams.slice();clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(this.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams); if ("streams" in values && values.streams != null) { if (Array.isArray(values.streams) && values.streams.every(v => v instanceof Collection || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams; + clone.#_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = values.streams.slice(); clone.#_trust_3sG2Hdwn9qzKGu9mpYkqakAMUkH9_streams = new Set(); for (let i = 0; i < values.streams.length; i++) { @@ -76050,7 +76107,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints; + clone.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints = this.#_sEoQwUbfk4hEfugzNQ2ZiDcLMkG_endpoints.slice(); if ("endpoints" in values && values.endpoints != null) { if (values.endpoints instanceof Endpoints) { // @ts-ignore: type is checked above. @@ -76063,7 +76120,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable; + clone.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable = this.#_gAJzg1QDc4rcefFsUzGSYmyXvNH_discoverable.slice(); if ("discoverable" in values && values.discoverable != null) { if (typeof values.discoverable === "boolean") { // @ts-ignore: type is checked above. @@ -76076,7 +76133,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended; + clone.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended = this.#_2kGKkJtoFWg8c18PaVSqj9NKP4t7_suspended.slice(); if ("suspended" in values && values.suspended != null) { if (typeof values.suspended === "boolean") { // @ts-ignore: type is checked above. @@ -76089,7 +76146,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial; + clone.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial = this.#_79S8K4f5J9MWUgCxziRyUe6PTHZ_memorial.slice(); if ("memorial" in values && values.memorial != null) { if (typeof values.memorial === "boolean") { // @ts-ignore: type is checked above. @@ -76102,7 +76159,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable; + clone.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable = this.#_2diCorzqPGQQqftp6e4SrCEwEnyk_indexable.slice(); if ("indexable" in values && values.indexable != null) { if (typeof values.indexable === "boolean") { // @ts-ignore: type is checked above. @@ -76115,7 +76172,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo;clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); + clone.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = this.#_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo.slice();clone.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo = new Set(this.#_trust_2ZNWDhuNdSXBwEmrB5kwffdKGzok_movedTo); if ("successor" in values && values.successor != null) { if (values.successor instanceof Application || values.successor instanceof Group || values.successor instanceof Organization || values.successor instanceof Person || values.successor instanceof Service || values.successor instanceof URL) { // @ts-ignore: type is checked above. @@ -76128,7 +76185,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs;clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = this.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs.slice();clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(this.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs); if ("alias" in values && values.alias != null) { if (values.alias instanceof Application || values.alias instanceof Group || values.alias instanceof Organization || values.alias instanceof Person || values.alias instanceof Service || values.alias instanceof URL) { // @ts-ignore: type is checked above. @@ -76155,7 +76212,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.aliases) && values.aliases.every(v => v instanceof Application || v instanceof Group || v instanceof Organization || v instanceof Person || v instanceof Service || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases; + clone.#_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = values.aliases.slice(); clone.#_trust_3NV7TGNhuABbryNjNi4wib4DgNpY_alsoKnownAs = new Set(); for (let i = 0; i < values.aliases.length; i++) { @@ -76169,7 +76226,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service;clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = this.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service.slice();clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(this.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service); if ("service" in values && values.service != null) { if (values.service instanceof DidService || values.service instanceof URL) { // @ts-ignore: type is checked above. @@ -76196,7 +76253,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | if (Array.isArray(values.services) && values.services.every(v => v instanceof DidService || v instanceof URL)) { // @ts-ignore: type is checked above. - clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services; + clone.#_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = values.services.slice(); clone.#_trust_4Q6NrKH6bazBGtxwG8vyG77ir7Tg_service = new Set(); for (let i = 0; i < values.services.length; i++) { @@ -76210,7 +76267,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage; + clone.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage = this.#_QuxorEK1txp7jGjq8BRQfTPvUwp__misskey_followedMessage.slice(); if ("followedMessage" in values && values.followedMessage != null) { if (typeof values.followedMessage === "string") { // @ts-ignore: type is checked above. @@ -76223,7 +76280,7 @@ services?: (DidService | URL)[];followedMessage?: string | null;cat?: boolean | ); } } - clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat; + clone.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat = this.#_2xEU4QtkC53RAun67T81Egqt9vmL_isCat.slice(); if ("cat" in values && values.cat != null) { if (typeof values.cat === "boolean") { // @ts-ignore: type is checked above. @@ -82310,7 +82367,7 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} if (Array.isArray(values.contents) && values.contents.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents; + this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents.slice(); } else { throw new TypeError( @@ -82338,7 +82395,8 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ clone( values: @@ -82367,7 +82425,7 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} { id: values.id ?? this.id }, options ); - clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content; + clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = this.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content.slice(); if ("content" in values && values.content != null) { if (typeof values.content === "string" || values.content instanceof LanguageString) { // @ts-ignore: type is checked above. @@ -82394,7 +82452,7 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} if (Array.isArray(values.contents) && values.contents.every(v => typeof v === "string" || v instanceof LanguageString)) { // @ts-ignore: type is checked above. - clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents; + clone.#_4HuuRSdSrXq8Jj2J9gcdYfoCzeuz_content = values.contents.slice(); } else { throw new TypeError( @@ -82403,7 +82461,7 @@ contents?: ((string | LanguageString))[];mediaType?: string | null;} ); } } - clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType; + clone.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType = this.#_3BLrzmscsjHCw8TF5BHRW9WkPnX8_mediaType.slice(); if ("mediaType" in values && values.mediaType != null) { if (typeof values.mediaType === "string") { // @ts-ignore: type is checked above. @@ -82920,7 +82978,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -83260,7 +83319,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -83609,7 +83669,8 @@ proofs?: (DataIntegrityProof | URL)[];deleted?: Temporal.Instant | null;} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -83647,7 +83708,7 @@ proofs?: (DataIntegrityProof | URL)[];deleted?: Temporal.Instant | null;} // @ts-ignore: $warning is not recognized as a property, but it is. options = { ...options, $warning: this._warning }; } - const clone = super.clone(values, options) as unknown as Tombstone;clone.#_8g8g4LiVMhFTXskuDEqx4ascxUr_deleted = this.#_8g8g4LiVMhFTXskuDEqx4ascxUr_deleted; + const clone = super.clone(values, options) as unknown as Tombstone;clone.#_8g8g4LiVMhFTXskuDEqx4ascxUr_deleted = this.#_8g8g4LiVMhFTXskuDEqx4ascxUr_deleted.slice(); if ("deleted" in values && values.deleted != null) { if (isTemporalInstant(values.deleted)) { // @ts-ignore: type is checked above. @@ -84072,7 +84133,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -84417,7 +84479,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -84760,7 +84823,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -85092,7 +85156,8 @@ proofs?: (DataIntegrityProof | URL)[];width?: number | null;height?: number | nu * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: @@ -85442,7 +85507,8 @@ instruments?: (Object | URL)[];} * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ override clone( values: diff --git a/packages/vocab-tools/src/constructor.ts b/packages/vocab-tools/src/constructor.ts index 575e7b449..ff3180f03 100644 --- a/packages/vocab-tools/src/constructor.ts +++ b/packages/vocab-tools/src/constructor.ts @@ -175,7 +175,7 @@ export async function* generateConstructor( if (Array.isArray(values.${property.pluralName}) && values.${property.pluralName}.every(v => ${typeGuards})) { // @ts-ignore: type is checked above. - this.${fieldName} = values.${property.pluralName}; + this.${fieldName} = values.${property.pluralName}.slice(); `; if (!allScalarTypes) { yield ` @@ -208,7 +208,8 @@ export async function* generateCloner( * Clones this instance, optionally updating it with the given values. * @param values The values to update the clone with. * @param options The options to use for cloning. - * @returns The cloned instance. + * @returns The cloned instance with its own property arrays. Nested objects + * and URLs are shared with this instance. */ ${emitOverride(typeUri, types)} clone( values: @@ -245,7 +246,7 @@ export async function* generateCloner( const fieldName = await getFieldName(property.uri); const trustFieldName = await getFieldName(property.uri, "#_trust"); const allScalarTypes = areAllScalarTypes(property.range, types); - yield `clone.${fieldName} = this.${fieldName};`; + yield `clone.${fieldName} = this.${fieldName}.slice();`; if (!allScalarTypes) { yield `clone.${trustFieldName} = new Set(this.${trustFieldName});`; } @@ -309,7 +310,7 @@ export async function* generateCloner( if (Array.isArray(values.${property.pluralName}) && values.${property.pluralName}.every(v => ${typeGuards})) { // @ts-ignore: type is checked above. - clone.${fieldName} = values.${property.pluralName}; + clone.${fieldName} = values.${property.pluralName}.slice(); `; if (!allScalarTypes) { yield ` diff --git a/packages/vocab/src/vocab.test.ts b/packages/vocab/src/vocab.test.ts index c6b0fc545..d130f3b78 100644 --- a/packages/vocab/src/vocab.test.ts +++ b/packages/vocab/src/vocab.test.ts @@ -12,11 +12,13 @@ import { notDeepStrictEqual, ok, rejects, + strictEqual, throws, } from "node:assert/strict"; import { assertInstanceOf } from "./utils.ts"; import * as vocab from "./vocab.ts"; import { + Accept, Activity, Announce, Collection, @@ -1279,6 +1281,216 @@ test("FEP-fe34: Trust tracking in object cloning", () => { ); }); +for (const property of ["object", "attachment"] as const) { + for (const fetchOriginal of [false, true]) { + test( + `clone() isolates ${property} dereferencing (${ + fetchOriginal ? "original" : "clone" + } first)`, + async () => { + const embedded = { + id: "https://b.example/notes/1", + type: "Note", + content: "embedded", + }; + const json = { + "@context": "https://www.w3.org/ns/activitystreams", + id: "https://a.example/activities/1", + type: "Create", + [property]: embedded, + }; + const original = await Create.fromJsonLd(json, { + contextLoader: mockDocumentLoader, + }); + const copy = original.clone(); + const fetching = fetchOriginal ? original : copy; + const untouched = fetchOriginal ? copy : original; + let fetches = 0; + // deno-lint-ignore require-await + const documentLoader = async (url: string) => { + fetches++; + return { + contextUrl: null, + documentUrl: url, + document: { + "@context": "https://www.w3.org/ns/activitystreams", + ...embedded, + content: "fetched", + }, + }; + }; + const options = { documentLoader, contextLoader: mockDocumentLoader }; + const fetched = property === "object" + ? await fetching.getObject(options) + : (await Array.fromAsync(fetching.getAttachments(options)))[0]; + assertInstanceOf(fetched, Note); + deepStrictEqual(fetched.content, "fetched"); + + // Inspect the other instance before it fetches anything itself. + const trusted = { crossOrigin: "trust" as const }; + const preserved = property === "object" + ? await untouched.getObject(trusted) + : (await Array.fromAsync(untouched.getAttachments(trusted)))[0]; + assertInstanceOf(preserved, Note); + deepStrictEqual(preserved.content, "embedded"); + const serialized = await original.toJsonLd() as Record; + deepStrictEqual( + serialized[property], + fetchOriginal ? { ...embedded, content: "fetched" } : embedded, + ); + const accept = new Accept({ object: untouched }); + const acceptJson = await accept.toJsonLd() as { + object: Record; + }; + const nested = acceptJson.object; + deepStrictEqual(nested[property], embedded); + + // Successful lookups and their trust metadata belong to each instance. + const cached = property === "object" + ? await fetching.getObject(options) + : (await Array.fromAsync(fetching.getAttachments(options)))[0]; + strictEqual(cached, fetched); + deepStrictEqual(fetches, 1); + const independentlyFetched = property === "object" + ? await untouched.getObject(options) + : (await Array.fromAsync(untouched.getAttachments(options)))[0]; + assertInstanceOf(independentlyFetched, Note); + deepStrictEqual(independentlyFetched.content, "fetched"); + deepStrictEqual(fetches, 2); + const warmedClone = fetching.clone(); + strictEqual( + property === "object" + ? await warmedClone.getObject(options) + : (await Array.fromAsync(warmedClone.getAttachments(options)))[0], + fetched, + ); + deepStrictEqual(fetches, 2); + }, + ); + } +} + +for (const clone of [false, true]) { + for (const frozen of [false, true]) { + test( + `${clone ? "clone()" : "constructor"} copies ${ + frozen ? "frozen" : "mutable" + } plural arrays`, + async () => { + const items = [ + new URL("https://example.com/object"), + new URL("https://example.com/object"), + ]; + const before = items.slice(); + if (frozen) globalThis.Object.freeze(items); + const base = new Collection({}); + const collection = clone + ? base.clone({ items }) + : new Collection({ items }); + const sibling = clone + ? base.clone({ items }) + : new Collection({ items }); + const fetched = await Array.fromAsync(collection.getItems({ + documentLoader: mockDocumentLoader, + contextLoader: mockDocumentLoader, + })); + deepStrictEqual(fetched.length, 2); + deepStrictEqual(fetched.map((item) => item.name), [ + "Fetched object", + "Fetched object", + ]); + deepStrictEqual(items, before); + strictEqual(items[0], before[0]); + strictEqual(items[1], before[1]); + const siblingJson = await sibling.toJsonLd() as { items: unknown }; + deepStrictEqual(siblingJson.items, before.map(String)); + if (!frozen) { + items.push(new URL("https://example.com/extra")); + deepStrictEqual(collection.itemIds, before); + deepStrictEqual(sibling.itemIds, before); + } + }, + ); + } +} + +test("clone() copies scalar arrays without changing sparse inputs", () => { + const names = ["original"]; + const original = new Object({ names }); + names.push("caller mutation"); + deepStrictEqual(original.names, ["original"]); + const copy = original.clone(); + copy.names.push("clone mutation"); + deepStrictEqual(original.names, ["original"]); + deepStrictEqual(copy.names, ["original", "clone mutation"]); + const replacements = ["replacement"]; + const replaced = original.clone({ names: replacements }); + replacements.push("caller mutation"); + deepStrictEqual(replaced.names, ["replacement"]); + + const sparseNames = new Array(2); + sparseNames[1] = "kept"; + const sparse = new Object({ names: sparseNames }); + for ( + const instance of [ + sparse, + sparse.clone(), + sparse.clone({ names: sparse.names }), + ] + ) { + deepStrictEqual(instance.names.length, 2); + deepStrictEqual(0 in instance.names, false); + deepStrictEqual(instance.names[1], "kept"); + } +}); + +test("clone() preserves embedded object identity and trust", async () => { + const note = new Note({ id: new URL("https://b.example/note") }); + const original = new Create({ + id: new URL("https://a.example/create"), + object: note, + }); + // deno-lint-ignore require-await + const documentLoader = async () => { + throw new Error("Trusted embedded objects must not be fetched."); + }; + for ( + const instance of [ + original, + original.clone(), + original.clone({ objects: [note] }), + ] + ) { + strictEqual(await instance.getObject({ documentLoader }), note); + strictEqual(instance.objectId, note.id); + } +}); + +test("clone() isolates crossOrigin trust when fetching", async () => { + const original = new Create({ + id: new URL("https://a.example/create"), + object: new URL("https://b.example/note"), + }); + const copy = original.clone(); + // deno-lint-ignore require-await + const documentLoader = async (url: string) => ({ + contextUrl: null, + documentUrl: url, + document: { + "@context": "https://www.w3.org/ns/activitystreams", + id: "https://other.example/note", + type: "Note", + content: "cross-origin", + }, + }); + const options = { documentLoader, contextLoader: mockDocumentLoader }; + const trusted = await copy.getObject({ ...options, crossOrigin: "trust" }); + assertInstanceOf(trusted, Note); + deepStrictEqual(trusted.content, "cross-origin"); + deepStrictEqual(await original.getObject(options), null); + deepStrictEqual(original.objectId, new URL("https://b.example/note")); +}); + test("FEP-fe34: crossOrigin ignore behavior (default)", async () => { // Create a mock document loader that returns objects with different origins // deno-lint-ignore require-await From 49d937e23b7e8227cd3053c6454d21d2fa63f3dd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 2 Oct 2026 17:26:46 +0000 Subject: [PATCH 024/184] Update sponsors --- SPONSORS.md | 2 +- packages/fedify/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SPONSORS.md b/SPONSORS.md index 216ae28b0..a10c324ab 100644 --- a/SPONSORS.md +++ b/SPONSORS.md @@ -24,8 +24,8 @@ Corporate sponsors Supporters ---------- -- [Blaine](https://opencollective.com/blaine) - [tkgka](https://opencollective.com/tkgka) +- [Blaine](https://opencollective.com/blaine) - [Erick González Aguilar](https://opencollective.com/erick-gonzalez-aguilar) - [Daniel Supernault](https://pixelfed.org/) diff --git a/packages/fedify/README.md b/packages/fedify/README.md index 87955c6c4..866cd5fde 100644 --- a/packages/fedify/README.md +++ b/packages/fedify/README.md @@ -229,8 +229,8 @@ financial contributors:[^2] ### Supporters -- [Blaine](https://opencollective.com/blaine) - [tkgka](https://opencollective.com/tkgka) +- [Blaine](https://opencollective.com/blaine) - [Erick González Aguilar](https://opencollective.com/erick-gonzalez-aguilar) - [Daniel Supernault](https://pixelfed.org/) From da40616caa9d7266d66d7728cdcfd3bebd99cd70 Mon Sep 17 00:00:00 2001 From: userjmmm Date: Wed, 30 Sep 2026 15:45:47 +0900 Subject: [PATCH 025/184] Add favicon selection tests for `getFaviconUrl()` Cover the common favicon cases described in the issue: case-insensitive `.svg` suffixes, `type="image/svg+xml"`, `sizes="any"`, and multiple `rel` tokens. Reset fetch-mock in an `afterEach` hook so the cleanup runs even when a test fails, keeping each test isolated from the others. Assisted-by: Claude Code:claude-opus-4-8 --- packages/cli/src/nodeinfo.test.ts | 107 +++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/nodeinfo.test.ts b/packages/cli/src/nodeinfo.test.ts index 5e0d2f111..3dba827b6 100644 --- a/packages/cli/src/nodeinfo.test.ts +++ b/packages/cli/src/nodeinfo.test.ts @@ -1,7 +1,7 @@ -import assert from "node:assert/strict"; -import { test } from "node:test"; import { Chalk } from "chalk"; import fetchMock from "fetch-mock"; +import assert from "node:assert/strict"; +import { afterEach, test } from "node:test"; import { getAsciiArt, getFaviconUrl, @@ -10,6 +10,10 @@ import { rgbTo256Color, } from "./nodeinfo.ts"; +afterEach(() => { + fetchMock.hardReset(); +}); + const HTML_WITH_SMALL_ICON = ` @@ -137,6 +141,105 @@ test("getFaviconUrl - uppercase svg icons with query and hash fall back to /favi fetchMock.hardReset(); }); +const HTML_WITH_SVG_TYPE_ONLY = ` + + + + Test Site + + +Test + +`; + +test("getFaviconUrl - svg icons with type attribute only falls back to /favicon.ico", async () => { + fetchMock.spyGlobal(); + + fetchMock.get("https://example.com/", { + body: HTML_WITH_SVG_TYPE_ONLY, + headers: { "Content-Type": "text/html" }, + }); + + const result = await getFaviconUrl("https://example.com/"); + assert.equal(result.href, "https://example.com/favicon.ico"); +}); + +const HTML_WITH_SIZES_ANY_ICON = ` + + + + Test Site + + +Test + +`; + +test("getFaviconUrl - icons with sizes='any' is selected", async () => { + fetchMock.spyGlobal(); + + fetchMock.get("https://example.com/", { + body: HTML_WITH_SIZES_ANY_ICON, + headers: { "Content-Type": "text/html" }, + }); + + const result = await getFaviconUrl("https://example.com/"); + assert.equal(result.href, "https://example.com/favicon.png"); + + fetchMock.hardReset(); +}); + +const HTML_WITH_PREFERRED_BITMAP_ICON = ` + + + + Test Site + + + +Test + +`; + +test("getFaviconUrl - prefer bitmap icons", async () => { + fetchMock.spyGlobal(); + + fetchMock.get("https://example.com/", { + body: HTML_WITH_PREFERRED_BITMAP_ICON, + headers: { "Content-Type": "text/html" }, + }); + + const result = await getFaviconUrl("https://example.com/"); + assert.equal(result.href, "https://example.com/favicon.png"); + + fetchMock.hardReset(); +}); + +const HTML_WITH_MULTIPLE_REL_TOKENS = ` + + + + Test Site + + +Test + +`; + +test("getFaviconUrl - icon with multiple rel tokens", async () => { + fetchMock.spyGlobal(); + + fetchMock.get("https://example.com/", { + body: HTML_WITH_MULTIPLE_REL_TOKENS, + headers: { "Content-Type": "text/html" }, + }); + + const result = await getFaviconUrl("https://example.com/"); + assert.equal(result.href, "https://example.com/favicon.png"); + + fetchMock.hardReset(); +}); + const HTML_WITHOUT_ICON = ` From c17003bafee4f4c54611fe876ec37ea5a5daf8d7 Mon Sep 17 00:00:00 2001 From: userjmmm Date: Wed, 30 Sep 2026 16:20:51 +0900 Subject: [PATCH 026/184] Detect SVG favicons declared via type attribute --- packages/cli/src/nodeinfo.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/cli/src/nodeinfo.ts b/packages/cli/src/nodeinfo.ts index 1ed07e136..6caffc3db 100644 --- a/packages/cli/src/nodeinfo.ts +++ b/packages/cli/src/nodeinfo.ts @@ -378,6 +378,7 @@ export async function getFaviconUrl( if ("href" in attrs) { const parsedUrl = new URL(attrs.href, response.url); if (parsedUrl.pathname.toLowerCase().endsWith(".svg")) continue; + if (attrs.type?.toLowerCase()?.trim() === "image/svg+xml") continue; return parsedUrl; } } From 7a5dfa9806b85e5425c2292be37c59f782ad241f Mon Sep 17 00:00:00 2001 From: userjmmm Date: Wed, 30 Sep 2026 17:09:58 +0900 Subject: [PATCH 027/184] Add changelog entry for favicon selection --- changes.d/cli/improve-favicon-selection.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 changes.d/cli/improve-favicon-selection.md diff --git a/changes.d/cli/improve-favicon-selection.md b/changes.d/cli/improve-favicon-selection.md new file mode 100644 index 000000000..54f4dd9ed --- /dev/null +++ b/changes.d/cli/improve-favicon-selection.md @@ -0,0 +1,3 @@ + - Changed the `fedify nodeinfo` favicon selector to skip SVG icons declared + with `type="image/svg+xml"`, not just those with a `.svg` URL, so it + renders a usable bitmap icon instead. [[#893] by Lee Jeongmin] From 31c0628863e6edb7093ed88814f260ccdb3ba271 Mon Sep 17 00:00:00 2001 From: userjmmm Date: Sat, 3 Oct 2026 16:25:09 +0900 Subject: [PATCH 028/184] Remove redundant `fetchMock.hardReset()` per test --- packages/cli/src/nodeinfo.test.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/packages/cli/src/nodeinfo.test.ts b/packages/cli/src/nodeinfo.test.ts index 3dba827b6..44627b842 100644 --- a/packages/cli/src/nodeinfo.test.ts +++ b/packages/cli/src/nodeinfo.test.ts @@ -36,8 +36,6 @@ test("getFaviconUrl - small favicon.ico and apple-touch-icon.png", async () => { const result = await getFaviconUrl("https://example.com/"); assert.equal(result.href, "https://example.com/apple-touch-icon.png"); - - fetchMock.hardReset(); }); const HTML_WITH_ICON = ` @@ -62,8 +60,6 @@ test("getFaviconUrl - favicon.ico and apple-touch-icon.png", async () => { const result = await getFaviconUrl("https://example.com/"); assert.equal(result.href, "https://example.com/favicon.ico"); - - fetchMock.hardReset(); }); const HTML_WITH_SVG_ONLY = ` @@ -87,8 +83,6 @@ test("getFaviconUrl - svg icons only falls back to /favicon.ico", async () => { const result = await getFaviconUrl("https://example.com/"); assert.equal(result.href, "https://example.com/favicon.ico"); - - fetchMock.hardReset(); }); const HTML_WITH_UPPERCASE_SVG_ONLY = ` @@ -112,8 +106,6 @@ test("getFaviconUrl - uppercase svg icons only falls back to /favicon.ico", asyn const result = await getFaviconUrl("https://example.com/"); assert.equal(result.href, "https://example.com/favicon.ico"); - - fetchMock.hardReset(); }); const HTML_WITH_UPPERCASE_SVG_WITH_QUERY = ` @@ -137,8 +129,6 @@ test("getFaviconUrl - uppercase svg icons with query and hash fall back to /favi const result = await getFaviconUrl("https://example.com/"); assert.equal(result.href, "https://example.com/favicon.ico"); - - fetchMock.hardReset(); }); const HTML_WITH_SVG_TYPE_ONLY = ` @@ -185,8 +175,6 @@ test("getFaviconUrl - icons with sizes='any' is selected", async () => { const result = await getFaviconUrl("https://example.com/"); assert.equal(result.href, "https://example.com/favicon.png"); - - fetchMock.hardReset(); }); const HTML_WITH_PREFERRED_BITMAP_ICON = ` @@ -211,8 +199,6 @@ test("getFaviconUrl - prefer bitmap icons", async () => { const result = await getFaviconUrl("https://example.com/"); assert.equal(result.href, "https://example.com/favicon.png"); - - fetchMock.hardReset(); }); const HTML_WITH_MULTIPLE_REL_TOKENS = ` @@ -236,8 +222,6 @@ test("getFaviconUrl - icon with multiple rel tokens", async () => { const result = await getFaviconUrl("https://example.com/"); assert.equal(result.href, "https://example.com/favicon.png"); - - fetchMock.hardReset(); }); const HTML_WITHOUT_ICON = ` @@ -260,8 +244,6 @@ test("getFaviconUrl - falls back to /favicon.ico", async () => { const result = await getFaviconUrl("https://example.com/"); assert.equal(result.href, "https://example.com/favicon.ico"); - - fetchMock.hardReset(); }); test("rgbTo256Color - check RGB cube", () => { From 795115a7e256f49eca7d26a5ef9f1191a9f39129 Mon Sep 17 00:00:00 2001 From: userjmmm Date: Sat, 3 Oct 2026 18:45:49 +0900 Subject: [PATCH 029/184] Add favicon selection test for multiple sizes --- packages/cli/src/nodeinfo.test.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/cli/src/nodeinfo.test.ts b/packages/cli/src/nodeinfo.test.ts index 44627b842..f572fce78 100644 --- a/packages/cli/src/nodeinfo.test.ts +++ b/packages/cli/src/nodeinfo.test.ts @@ -177,6 +177,30 @@ test("getFaviconUrl - icons with sizes='any' is selected", async () => { assert.equal(result.href, "https://example.com/favicon.png"); }); +const HTML_WITH_MULTI_SIZE_ICON = ` + + + + Test Site + + + +Test + +`; + +test("getFaviconUrl - icons with multiple sizes", async () => { + fetchMock.spyGlobal(); + + fetchMock.get("https://example.com/", { + body: HTML_WITH_MULTI_SIZE_ICON, + headers: { "Content-Type": "text/html" }, + }); + + const result = await getFaviconUrl("https://example.com/"); + assert.equal(result.href, "https://example.com/favicon.ico"); +}); + const HTML_WITH_PREFERRED_BITMAP_ICON = ` From 06116737b5f439390a4bf8eccd7a692ba862895d Mon Sep 17 00:00:00 2001 From: userjmmm Date: Sat, 3 Oct 2026 19:06:57 +0900 Subject: [PATCH 030/184] Consider all declared favicon sizes - Adds the `g` flag so every declared size is matched, not just the first. - Rewrites the size check to keep the icon when any single size is large enough. Assisted-by: Claude Code:claude-opus-4-8 --- packages/cli/src/nodeinfo.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/nodeinfo.ts b/packages/cli/src/nodeinfo.ts index 6caffc3db..fde225eca 100644 --- a/packages/cli/src/nodeinfo.ts +++ b/packages/cli/src/nodeinfo.ts @@ -371,10 +371,13 @@ export async function getFaviconUrl( } const rel = attrs.rel?.toLowerCase()?.trim()?.split(/\s+/) ?? []; if (!rel.includes("icon") && !rel.includes("apple-touch-icon")) continue; - if ("sizes" in attrs && attrs.sizes.match(/\d+x\d+/)) { - const [w, h] = attrs.sizes.split("x").map((v) => Number.parseInt(v)); - if (w < 38 || h < 19) continue; - } + const tokens = attrs.sizes?.match(/\d+x\d+/g); + if ( + tokens != null && !tokens.some((token) => { + const [w, h] = token.split("x").map((v) => Number.parseInt(v)); + return w >= 38 && h >= 19; + }) + ) continue; if ("href" in attrs) { const parsedUrl = new URL(attrs.href, response.url); if (parsedUrl.pathname.toLowerCase().endsWith(".svg")) continue; From 405a837792d2318fe012349628a0b61c7a7d9bbf Mon Sep 17 00:00:00 2001 From: userjmmm Date: Sat, 3 Oct 2026 19:50:11 +0900 Subject: [PATCH 031/184] Place the favicon changelog under 2.5.0 and add PR reference --- CHANGES.md | 12 ++++++++++++ changes.d/cli/improve-favicon-selection.md | 9 ++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index cdac996b2..db8b4bc88 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,18 @@ Version 2.5.0 To be released. +### @fedify/cli + + - Changed the `fedify nodeinfo` favicon selector to pick a usable bitmap + icon more often. It now skips SVG icons declared with + `type="image/svg+xml"`, not just those with a `.svg` URL, and it considers + every declared size instead of only the first, so an icon offering a large + size is no longer discarded because its smallest size is too small. + [[#893], [#1187] by Lee Jeongmin\] + +[#893]: https://github.com/fedify-dev/fedify/issues/893 +[#1187]: https://github.com/fedify-dev/fedify/issues/1187 + Version 2.4.0 ------------- diff --git a/changes.d/cli/improve-favicon-selection.md b/changes.d/cli/improve-favicon-selection.md index 54f4dd9ed..48c86c53f 100644 --- a/changes.d/cli/improve-favicon-selection.md +++ b/changes.d/cli/improve-favicon-selection.md @@ -1,3 +1,6 @@ - - Changed the `fedify nodeinfo` favicon selector to skip SVG icons declared - with `type="image/svg+xml"`, not just those with a `.svg` URL, so it - renders a usable bitmap icon instead. [[#893] by Lee Jeongmin] + - Changed the `fedify nodeinfo` favicon selector to pick a usable bitmap + icon more often. It now skips SVG icons declared with + `type="image/svg+xml"`, not just those with a `.svg` URL, and it considers + every declared size instead of only the first, so an icon offering a large + size is no longer discarded because its smallest size is too small. + [[#893], [#1187] by Lee Jeongmin] From a824ac92dd91b2c94aab79d7badc2bed73b5aba0 Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Sat, 3 Oct 2026 16:45:18 +0900 Subject: [PATCH 032/184] Preload the FEP-6757 context Bundle the upstream context unchanged so Codeberg Pages outages no longer prevent documents with license metadata from being parsed. Verify offline loading and expansion of both terms without a fetch, and update the preloaded-context documentation and changelog. Fixes https://github.com/fedify-dev/fedify/issues/1211 Assisted-by: Codex:gpt-6.1-sol --- CHANGES.md | 11 +++++ changes.d/vocab-runtime/fep-6757-context.md | 11 +++++ packages/vocab-runtime/src/contexts.ts | 8 ++++ .../vocab-runtime/src/contexts/fep-6757.json | 12 ++++++ packages/vocab-runtime/src/docloader.test.ts | 42 +++++++++++++++++++ packages/vocab-runtime/src/docloader.ts | 1 + 6 files changed, 85 insertions(+) create mode 100644 changes.d/vocab-runtime/fep-6757-context.md create mode 100644 packages/vocab-runtime/src/contexts/fep-6757.json diff --git a/CHANGES.md b/CHANGES.md index 025e6dc1e..48550eedf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,17 @@ To be released. [#1207]: https://github.com/fedify-dev/fedify/issues/1207 [#1208]: https://github.com/fedify-dev/fedify/pull/1208 +### @fedify/vocab-runtime + + - Added the [FEP-6757] context to the preloaded JSON-LD contexts. The default + document loader now resolves locally, so + transient Codeberg Pages outages no longer prevent otherwise valid inbound + documents from being parsed or verified. [[#1211], [#1216]] + +[FEP-6757]: https://w3id.org/fep/6757 +[#1211]: https://github.com/fedify-dev/fedify/issues/1211 +[#1216]: https://github.com/fedify-dev/fedify/pull/1216 + ### @fedify/vocab-tools - Fixed generated constructors and `clone()` methods to copy property diff --git a/changes.d/vocab-runtime/fep-6757-context.md b/changes.d/vocab-runtime/fep-6757-context.md new file mode 100644 index 000000000..5ad4e0368 --- /dev/null +++ b/changes.d/vocab-runtime/fep-6757-context.md @@ -0,0 +1,11 @@ +--- +links: + '#1211': https://github.com/fedify-dev/fedify/issues/1211 + '#1216': https://github.com/fedify-dev/fedify/pull/1216 +--- + - Added the [FEP-6757] context to the preloaded JSON-LD contexts. The default + document loader now resolves locally, so + transient Codeberg Pages outages no longer prevent otherwise valid inbound + documents from being parsed or verified. [[#1211], [#1216]] + +[FEP-6757]: https://w3id.org/fep/6757 diff --git a/packages/vocab-runtime/src/contexts.ts b/packages/vocab-runtime/src/contexts.ts index 7aac34f96..f4159ef0f 100644 --- a/packages/vocab-runtime/src/contexts.ts +++ b/packages/vocab-runtime/src/contexts.ts @@ -3,6 +3,7 @@ // cSpell: disable import cidV1Context from "./contexts/cid-v1.json" with { type: "json" }; +import fep6757 from "./contexts/fep-6757.json" with { type: "json" }; import fep7aa9 from "./contexts/fep-7aa9.json" with { type: "json" }; import fepEf61 from "./contexts/fep-ef61.json" with { type: "json" }; import joinLemmyContext from "./contexts/join-lemmy.json" with { type: "json" }; @@ -4345,6 +4346,13 @@ const preloadedContexts: Record = { // https://github.com/fedify-dev/fedify/issues/1078 "https://w3id.org/fep/7aa9": fep7aa9, + // The FEP-6757 context is hosted on Codeberg Pages, whose outages can + // prevent documents with license metadata from being parsed. Resolve it + // locally so parsing does not depend on the remote context server. + // See: https://w3id.org/fep/6757 + // https://github.com/fedify-dev/fedify/issues/1211 + "https://w3id.org/fep/6757": fep6757, + // Lemmy's context document is served as application/json without the JSON-LD // context Link header. The default document loader treats that as a regular // JSON response instead of a JSON-LD context, so every Lemmy activity that diff --git a/packages/vocab-runtime/src/contexts/fep-6757.json b/packages/vocab-runtime/src/contexts/fep-6757.json new file mode 100644 index 000000000..f3e00f587 --- /dev/null +++ b/packages/vocab-runtime/src/contexts/fep-6757.json @@ -0,0 +1,12 @@ +{ + "@context": { + "license": { + "@id": "http://purl.org/dc/terms/license", + "@type": "@id" + }, + "preferredLicense": { + "@id": "https://w3id.org/fep/6757#preferredLicense", + "@type": "@id" + } + } +} diff --git a/packages/vocab-runtime/src/docloader.test.ts b/packages/vocab-runtime/src/docloader.test.ts index 9e19de16f..0a1221cd8 100644 --- a/packages/vocab-runtime/src/docloader.test.ts +++ b/packages/vocab-runtime/src/docloader.test.ts @@ -8,6 +8,7 @@ import { gzipSync } from "node:zlib"; import preloadedContexts from "./contexts.ts"; import cidV1Context from "./contexts/cid-v1.json" with { type: "json" }; import { getDocumentLoader, getRemoteDocument } from "./docloader.ts"; +import jsonld from "./jsonld.ts"; import { FetchError } from "./request.ts"; import { UrlError } from "./url.ts"; @@ -367,6 +368,47 @@ test("getDocumentLoader()", async (t) => { deepStrictEqual(fetchMock.callHistory.calls(url).length, 0); }); + // A Codeberg Pages outage must not prevent loading or expanding FEP-6757. + // See: https://github.com/fedify-dev/fedify/issues/1211 + fetchMock.get("https://w3id.org/fep/6757", { status: 502 }); + await t.test("preloaded FEP-6757 context", async () => { + const url = "https://w3id.org/fep/6757"; + deepStrictEqual(await fetchDocumentLoader(url), { + contextUrl: null, + documentUrl: url, + document: { + "@context": { + license: { + "@id": "http://purl.org/dc/terms/license", + "@type": "@id", + }, + preferredLicense: { + "@id": "https://w3id.org/fep/6757#preferredLicense", + "@type": "@id", + }, + }, + }, + }); + deepStrictEqual( + await jsonld.expand({ + "@context": ["https://www.w3.org/ns/activitystreams", url], + type: "Person", + license: "https://creativecommons.org/licenses/by/4.0/", + preferredLicense: "https://creativecommons.org/licenses/by-nc/4.0/", + }, { documentLoader: fetchDocumentLoader }), + [{ + "@type": ["https://www.w3.org/ns/activitystreams#Person"], + "http://purl.org/dc/terms/license": [{ + "@id": "https://creativecommons.org/licenses/by/4.0/", + }], + "https://w3id.org/fep/6757#preferredLicense": [{ + "@id": "https://creativecommons.org/licenses/by-nc/4.0/", + }], + }], + ); + deepStrictEqual(fetchMock.callHistory.calls(url).length, 0); + }); + await t.test("deny non-HTTP/HTTPS", async () => { await rejects( () => fetchDocumentLoader("ftp://localhost"), diff --git a/packages/vocab-runtime/src/docloader.ts b/packages/vocab-runtime/src/docloader.ts index f89586cad..5827e176b 100644 --- a/packages/vocab-runtime/src/docloader.ts +++ b/packages/vocab-runtime/src/docloader.ts @@ -280,6 +280,7 @@ export interface GetDocumentLoaderOptions extends DocumentLoaderFactoryOptions { * - * - * - + * - * - * - * @param options Options for the document loader. From 1af83de38d015bced8e982f032e6ffbff4a232cf Mon Sep 17 00:00:00 2001 From: Lumia1108 Date: Sat, 3 Oct 2026 23:05:45 +0900 Subject: [PATCH 033/184] Test Express response forwarding Add regression coverage for forwarding response status, headers, and every streamed body chunk to Express. Codex was used to explain the relevant code and review the test. I personally wrote and verified the implementation. Assisted-by: Codex:GPT-5.6 --- packages/express/src/index.test.ts | 62 +++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 6 deletions(-) diff --git a/packages/express/src/index.test.ts b/packages/express/src/index.test.ts index 04cc600cf..d6de2ddf9 100644 --- a/packages/express/src/index.test.ts +++ b/packages/express/src/index.test.ts @@ -1,5 +1,10 @@ +import { createFederation, MemoryKvStore } from "@fedify/fedify"; import type { Request as ERequest, Response as EResponse } from "express"; +import express from "express"; +import { strict as assert } from "node:assert"; +import type { AddressInfo } from "node:net"; import { describe, test } from "node:test"; +import { integrateFederation } from "./index.ts"; interface MockFederation { fetch(request: Request, options: unknown): Promise; @@ -19,8 +24,15 @@ function createMockResponse(): { response: EResponse; ended: Promise; getBody(): string; + getHeader( + name: string, + ): string | number | readonly string[] | undefined; } { let body = ""; + const headers = new Map< + string, + string | number | readonly string[] + >(); let resolveEnded: () => void; const ended = new Promise((resolve) => { resolveEnded = resolve; @@ -31,7 +43,11 @@ function createMockResponse(): { response.statusCode = code; return response; }, - setHeader() { + setHeader( + name: string, + value: string | number | readonly string[], + ) { + headers.set(name.toLowerCase(), value); return response; }, write(chunk: Buffer | string) { @@ -47,6 +63,7 @@ function createMockResponse(): { response: response as unknown as EResponse, ended, getBody: () => body, + getHeader: (name) => headers.get(name.toLowerCase()), }; } @@ -113,12 +130,45 @@ describe("integrateFederation()", () => { await ended; assert.strictEqual(response.statusCode, 406); }); + + test("forwards the Fedify response status, headers, and streamed body to the Express response", async () => { + const encoder = new TextEncoder(); + const body = new ReadableStream({ + start(controller) { + controller.enqueue(encoder.encode("Hello ")); + controller.enqueue(encoder.encode("World")); + controller.close(); + }, + }); + + const mockFederation: MockFederation = { + fetch() { + return Promise.resolve( + new Response(body, { + status: 201, + headers: { + "Header-Test": "yes", + }, + }), + ); + }, + }; + + const middleware = integrateFederation( + mockFederation as never, + () => undefined, + ); + + const req = createMockRequest(); + const { response, ended, getBody, getHeader } = createMockResponse(); + + middleware(req, response, () => {}); + await ended; + assert.strictEqual(response.statusCode, 201); + assert.strictEqual(getHeader("Header-Test"), "yes"); + assert.strictEqual(getBody(), "Hello World"); + }); }); -import { createFederation, MemoryKvStore } from "@fedify/fedify"; -import express from "express"; -import { strict as assert } from "node:assert"; -import type { AddressInfo } from "node:net"; -import { integrateFederation } from "./index.ts"; // Large enough to fill the stream buffers that used to stall; see // . From f365df58a0d74658ea540744feb936061e72e04a Mon Sep 17 00:00:00 2001 From: Hong Minhee Date: Sun, 4 Oct 2026 01:34:56 +0900 Subject: [PATCH 034/184] Make multi-recipient inbox bench test deterministic The "rotates deliveries across multiple recipients" test failed intermittently on CI with only Alice's inbox hit. It ran a closed-loop load for a 300ms real-clock window with the default pipeline signing mode, and neither part guaranteed that Bob's inbox would see a delivery: - The closed-loop workers stop dispatching once the real-time deadline passes, so a slow first round (a cold target dereferencing the synthetic actors, the baseline stats request, CI scheduling) could leave only one or two deliveries. - The runner allocates recipients round-robin by signing index, but pipeline mode fills its buffer from four concurrent signers in completion order, so the prefix actually dispatched can contain only one recipient's requests. The runner itself allocates correctly; only the test's assumptions were wrong. The test now makes a fixed number of attempts: four constant open-loop arrivals (10/s over 400ms) under a fake clock, so the count no longer depends on real time. It runs once with jit signing and once with presign signing. In both modes each attempt consumes exactly one allocation index (presign signs exactly the four requests and the run consumes them all), so the deliveries split exactly two per recipient regardless of completion order. The target now counts POSTs per inbox path so the test can assert that exact split. Fixes https://github.com/fedify-dev/fedify/issues/1218 Changelog: none Assisted-by: Claude Code:claude-opus-5-5 Assisted-by: Codex:gpt-6-astra --- .../cli/src/bench/scenarios/inbox.test.ts | 62 ++++++++++++++----- 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/packages/cli/src/bench/scenarios/inbox.test.ts b/packages/cli/src/bench/scenarios/inbox.test.ts index 57df0e970..ac10a8912 100644 --- a/packages/cli/src/bench/scenarios/inbox.test.ts +++ b/packages/cli/src/bench/scenarios/inbox.test.ts @@ -9,6 +9,7 @@ import test from "node:test"; import { serve } from "srvx"; import { getContextLoader, getDocumentLoader } from "../../docloader.ts"; import { buildFleet } from "../actor/fleet.ts"; +import type { Clock } from "../load/clock.ts"; import { normalizeSuite } from "../scenario/normalize.ts"; import type { Suite } from "../scenario/types.ts"; import { spawnSyntheticServer } from "../server/synthetic.ts"; @@ -60,16 +61,17 @@ async function spawnBenchmarkTarget(usernames: string[] = ["alice"]) { received++; }); - // Record every inbox path that was POSTed to, so a test can confirm that - // deliveries were spread across multiple recipients' personal inboxes. - const inboxHits = new Set(); + // Count POSTs per inbox path, so a test can confirm how deliveries were + // allocated across multiple recipients' personal inboxes. + const inboxHits = new Map(); const server = serve({ port: 0, hostname: "127.0.0.1", silent: true, fetch: (request: Request) => { if (request.method === "POST") { - inboxHits.add(new URL(request.url).pathname); + const path = new URL(request.url).pathname; + inboxHits.set(path, (inboxHits.get(path) ?? 0) + 1); } return federation.fetch(request, { contextData: undefined }); }, @@ -192,7 +194,13 @@ test("inboxRunner - reports server metrics scoped past the warm-up", async () => } }); -test("inboxRunner - rotates deliveries across multiple recipients", async () => { +// Recipients are allocated round-robin by signing index, so the run makes a +// fixed number of attempts rather than however many fit in a real-time window: +// four constant arrivals under a fake clock, each consuming one allocation +// index, split exactly two per recipient whatever order they complete in. +async function assertAllocatesAcrossRecipients( + signing: "jit" | "presign", +): Promise { const target = await spawnBenchmarkTarget(["alice", "bob"]); let fleet: Awaited> | undefined; try { @@ -214,11 +222,22 @@ test("inboxRunner - rotates deliveries across multiple recipients", async () => ], // Personal inboxes so each recipient's deliveries hit a distinct path. inbox: "personal", - load: { concurrency: 2 }, - duration: "300ms", + // 10/s over 400ms schedules exactly four arrivals (0, 100, 200, and + // 300ms), which is also the batch size presign signs up front. + load: { rate: 10, maxInFlight: 2 }, + duration: "400ms", + signing, }], }; const scenario = normalizeSuite(suite).scenarios[0]; + let now = 0; + const clock: Clock = { + now: () => now, + sleepUntil: (timeMs) => { + now = Math.max(now, timeMs); + return Promise.resolve(); + }, + }; const measurement = await inboxRunner.run({ scenario, target: target.url, @@ -226,8 +245,10 @@ test("inboxRunner - rotates deliveries across multiple recipients", async () => contextLoader: await getContextLoader({ allowPrivateAddress: true }), allowPrivateAddress: true, fleet, + clock, }); + assert.strictEqual(measurement.requests.total, 4); assert.strictEqual( measurement.requests.successRate, 1, @@ -235,15 +256,10 @@ test("inboxRunner - rotates deliveries across multiple recipients", async () => JSON.stringify(measurement.errors) }`, ); - // Both recipients' personal inboxes received deliveries. - const hits = target.inboxHits(); - assert.ok( - hits.has("/users/alice/inbox"), - `expected alice's inbox to be hit; hits: ${JSON.stringify([...hits])}`, - ); - assert.ok( - hits.has("/users/bob/inbox"), - `expected bob's inbox to be hit; hits: ${JSON.stringify([...hits])}`, + // Each recipient's personal inbox received exactly half of the deliveries. + assert.deepStrictEqual( + Object.fromEntries(target.inboxHits()), + { "/users/alice/inbox": 2, "/users/bob/inbox": 2 }, ); } finally { try { @@ -252,7 +268,19 @@ test("inboxRunner - rotates deliveries across multiple recipients", async () => await target.close(); } } -}); +} + +test( + "inboxRunner - allocates jit deliveries across multiple recipients", + { timeout: 60_000 }, + () => assertAllocatesAcrossRecipients("jit"), +); + +test( + "inboxRunner - allocates presigned deliveries across multiple recipients", + { timeout: 60_000 }, + () => assertAllocatesAcrossRecipients("presign"), +); test("inboxRunner.validate - rejects activity options it cannot honor", () => { function resolve(activity: Record) { From 47546c6104557ac769c056ab5cefae6fee0b3cb8 Mon Sep 17 00:00:00 2001 From: userjmmm Date: Sun, 4 Oct 2026 15:05:57 +0900 Subject: [PATCH 035/184] Test uppercase .SVG suffix independently of MIME --- packages/cli/src/nodeinfo.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/nodeinfo.test.ts b/packages/cli/src/nodeinfo.test.ts index f572fce78..08ce279ab 100644 --- a/packages/cli/src/nodeinfo.test.ts +++ b/packages/cli/src/nodeinfo.test.ts @@ -90,7 +90,7 @@ const HTML_WITH_UPPERCASE_SVG_ONLY = ` Test Site - + Test @@ -113,7 +113,7 @@ const HTML_WITH_UPPERCASE_SVG_WITH_QUERY = ` Test Site - + Test From de6ba714a669b20bc56b75d1a66f8fa9793994b5 Mon Sep 17 00:00:00 2001 From: userjmmm Date: Sun, 4 Oct 2026 15:22:09 +0900 Subject: [PATCH 036/184] Use a distinct candidate URL in multi-size test --- packages/cli/src/nodeinfo.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/nodeinfo.test.ts b/packages/cli/src/nodeinfo.test.ts index 08ce279ab..0ebd2b8f4 100644 --- a/packages/cli/src/nodeinfo.test.ts +++ b/packages/cli/src/nodeinfo.test.ts @@ -182,7 +182,7 @@ const HTML_WITH_MULTI_SIZE_ICON = ` Test Site - + Test @@ -198,7 +198,7 @@ test("getFaviconUrl - icons with multiple sizes", async () => { }); const result = await getFaviconUrl("https://example.com/"); - assert.equal(result.href, "https://example.com/favicon.ico"); + assert.equal(result.href, "https://example.com/multi-size-icon.ico"); }); const HTML_WITH_PREFERRED_BITMAP_ICON = ` From bbfad72ede17f8b35aae82434e9fc10bf30ec5aa Mon Sep 17 00:00:00 2001 From: userjmmm Date: Sun, 4 Oct 2026 15:29:39 +0900 Subject: [PATCH 037/184] Point the changelog PR reference to its PR URL --- CHANGES.md | 2 +- changes.d/cli/improve-favicon-selection.md | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index db8b4bc88..42690e03a 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -18,7 +18,7 @@ To be released. [[#893], [#1187] by Lee Jeongmin\] [#893]: https://github.com/fedify-dev/fedify/issues/893 -[#1187]: https://github.com/fedify-dev/fedify/issues/1187 +[#1187]: https://github.com/fedify-dev/fedify/pull/1187 Version 2.4.0 diff --git a/changes.d/cli/improve-favicon-selection.md b/changes.d/cli/improve-favicon-selection.md index 48c86c53f..af631d7fe 100644 --- a/changes.d/cli/improve-favicon-selection.md +++ b/changes.d/cli/improve-favicon-selection.md @@ -1,3 +1,8 @@ +--- +links: + '#1187': https://github.com/fedify-dev/fedify/pull/1187 + '#893': https://github.com/fedify-dev/fedify/issues/893 +--- - Changed the `fedify nodeinfo` favicon selector to pick a usable bitmap icon more often. It now skips SVG icons declared with `type="image/svg+xml"`, not just those with a `.svg` URL, and it considers From eafa73a9272fb913206f2d2119d277ba6791391b Mon Sep 17 00:00:00 2001 From: Jae-Hyuk-Jang Date: Thu, 1 Oct 2026 15:01:13 +0900 Subject: [PATCH 038/184] Add filtering controls to the debug dashboard Once a federated app has produced more than a few traces, it gets hard to find one failed activity or one noisy log category by scrolling. The traces list page gains a checkbox filter over the activity types it already displays, and the trace detail page gains a filter for its log table by category, level, and a case-insensitive text search. Both filters are plain GET forms, so they work without JavaScript and keep selections in the URL. The trace list's existing live-poll script now forwards the active filter to /api/traces so a filtered view does not trigger a reload loop from comparing against an unfiltered count. The issue's suggestion to also filter by delivery status or request path does not map to data the dashboard currently captures without extending FedifySpanExporter in the main package, so this stays scoped to what packages/debugger already has. https://github.com/fedify-dev/fedify/issues/896 Assisted-by: Claude Code:claude-sonnet-5 --- packages/debugger/src/mod.test.ts | 230 +++++++++++++++++++ packages/debugger/src/routes.tsx | 93 +++++++- packages/debugger/src/views/layout.tsx | 9 + packages/debugger/src/views/trace-detail.tsx | 102 +++++++- packages/debugger/src/views/traces-list.tsx | 49 +++- 5 files changed, 471 insertions(+), 12 deletions(-) diff --git a/packages/debugger/src/mod.test.ts b/packages/debugger/src/mod.test.ts index 3f131c24c..f2e4a2bbd 100644 --- a/packages/debugger/src/mod.test.ts +++ b/packages/debugger/src/mod.test.ts @@ -17,6 +17,7 @@ import type { TraceActivityRecord, TraceSummary, } from "@fedify/fedify/otel"; +import type { Sink } from "@logtape/logtape"; import { trace } from "@opentelemetry/api"; function createMockExporter( @@ -1251,3 +1252,232 @@ test("trace detail page shows empty log message", async () => { const html = await response.text(); ok(html.includes("No logs captured for this trace.")); }); + +// ---------- Trace list filtering tests ---------- + +function threeTypedTraces(): TraceSummary[] { + return [ + { + traceId: "a".repeat(32), + timestamp: "2026-01-01T00:00:00Z", + activityCount: 1, + activityTypes: ["Create"], + }, + { + traceId: "b".repeat(32), + timestamp: "2026-01-02T00:00:00Z", + activityCount: 1, + activityTypes: ["Follow"], + }, + { + traceId: "c".repeat(32), + timestamp: "2026-01-03T00:00:00Z", + activityCount: 1, + activityTypes: ["Like"], + }, + ]; +} + +test("traces list page filters by a single activity type", async () => { + const { federation } = createMockFederation(); + const { exporter, kv } = createMockExporter(threeTypedTraces()); + const dbg = createFederationDebugger(federation, { exporter, kv }); + const request = new Request("https://example.com/__debug__/?type=Follow"); + const response = await dbg.fetch(request, { contextData: undefined }); + const html = await response.text(); + ok(html.includes("1")); + ok(html.includes("bbbbbbbb")); + ok(!html.includes("aaaaaaaa")); + ok(!html.includes("cccccccc")); +}); + +test("traces list page filters by multiple activity types with OR semantics", async () => { + const { federation } = createMockFederation(); + const { exporter, kv } = createMockExporter(threeTypedTraces()); + const dbg = createFederationDebugger(federation, { exporter, kv }); + const request = new Request( + "https://example.com/__debug__/?type=Create&type=Like", + ); + const response = await dbg.fetch(request, { contextData: undefined }); + const html = await response.text(); + ok(html.includes("2")); + ok(html.includes("aaaaaaaa")); + ok(html.includes("cccccccc")); + ok(!html.includes("bbbbbbbb")); +}); + +test("traces list page shows filter-specific empty message when nothing matches", async () => { + const { federation } = createMockFederation(); + const { exporter, kv } = createMockExporter(threeTypedTraces()); + const dbg = createFederationDebugger(federation, { exporter, kv }); + const request = new Request("https://example.com/__debug__/?type=Nope"); + const response = await dbg.fetch(request, { contextData: undefined }); + const html = await response.text(); + ok(html.includes("No traces match the selected filters.")); + ok(!html.includes("No traces captured yet.")); +}); + +test("traces list page filter form retains the selected checkbox and shows a clear link", async () => { + const { federation } = createMockFederation(); + const { exporter, kv } = createMockExporter(threeTypedTraces()); + const dbg = createFederationDebugger(federation, { exporter, kv }); + const request = new Request("https://example.com/__debug__/?type=Follow"); + const response = await dbg.fetch(request, { contextData: undefined }); + const html = await response.text(); + ok(html.includes('value="Follow" checked')); + ok(!html.includes('value="Create" checked')); + ok(!html.includes('value="Like" checked')); + ok(html.includes("Clear filters")); +}); + +test("traces list page filter form has no clear link when nothing is selected", async () => { + const { federation } = createMockFederation(); + const { exporter, kv } = createMockExporter(threeTypedTraces()); + const dbg = createFederationDebugger(federation, { exporter, kv }); + const request = new Request("https://example.com/__debug__/"); + const response = await dbg.fetch(request, { contextData: undefined }); + const html = await response.text(); + ok(!html.includes("Clear filters")); +}); + +test("JSON traces API filters by type", async () => { + const { federation } = createMockFederation(); + const { exporter, kv } = createMockExporter(threeTypedTraces()); + const dbg = createFederationDebugger(federation, { exporter, kv }); + const request = new Request( + "https://example.com/__debug__/api/traces?type=Follow", + ); + const response = await dbg.fetch(request, { contextData: undefined }); + const body = (await response.json()) as TraceSummary[]; + strictEqual(body.length, 1); + strictEqual(body[0].traceId, "b".repeat(32)); +}); + +// ---------- Log filtering tests ---------- + +function sinkTwoDistinctLogs( + dbg: Federation & { sink: Sink }, + traceId: string, +): void { + dbg.sink({ + category: ["fedify", "federation"], + level: "info", + message: ["hello world"], + rawMessage: "hello world", + timestamp: Date.now(), + properties: { traceId, spanId: "1".repeat(16) }, + }); + dbg.sink({ + category: ["fedify", "outbox"], + level: "error", + message: ["boom happened"], + rawMessage: "boom happened", + timestamp: Date.now(), + properties: { traceId, spanId: "2".repeat(16) }, + }); +} + +test("trace detail page filters logs by category", async () => { + const { federation } = createMockFederation(); + const { exporter, kv } = createMockExporter(); + const dbg = createFederationDebugger(federation, { exporter, kv }); + const traceId = "aaaa1111bbbb2222cccc3333dddd4444"; + sinkTwoDistinctLogs(dbg, traceId); + + const request = new Request( + `https://example.com/__debug__/traces/${traceId}?category=fedify.federation`, + ); + const response = await dbg.fetch(request, { contextData: undefined }); + const html = await response.text(); + ok(html.includes("hello world")); + ok(!html.includes("boom happened")); +}); + +test("trace detail page filters logs by level", async () => { + const { federation } = createMockFederation(); + const { exporter, kv } = createMockExporter(); + const dbg = createFederationDebugger(federation, { exporter, kv }); + const traceId = "aaaa1111bbbb2222cccc3333dddd4444"; + sinkTwoDistinctLogs(dbg, traceId); + + const request = new Request( + `https://example.com/__debug__/traces/${traceId}?level=error`, + ); + const response = await dbg.fetch(request, { contextData: undefined }); + const html = await response.text(); + ok(html.includes("boom happened")); + ok(!html.includes("hello world")); +}); + +test("trace detail page filters logs by a case-insensitive text search", async () => { + const { federation } = createMockFederation(); + const { exporter, kv } = createMockExporter(); + const dbg = createFederationDebugger(federation, { exporter, kv }); + const traceId = "aaaa1111bbbb2222cccc3333dddd4444"; + sinkTwoDistinctLogs(dbg, traceId); + + const request = new Request( + `https://example.com/__debug__/traces/${traceId}?q=BOOM`, + ); + const response = await dbg.fetch(request, { contextData: undefined }); + const html = await response.text(); + ok(html.includes("boom happened")); + ok(!html.includes("hello world")); +}); + +test("trace detail page combines log filters with AND semantics", async () => { + const { federation } = createMockFederation(); + const { exporter, kv } = createMockExporter(); + const dbg = createFederationDebugger(federation, { exporter, kv }); + const traceId = "aaaa1111bbbb2222cccc3333dddd4444"; + sinkTwoDistinctLogs(dbg, traceId); + + // "hello world" is level info, not error, so this combination matches none. + const request = new Request( + `https://example.com/__debug__/traces/${traceId}` + + "?category=fedify.federation&level=error", + ); + const response = await dbg.fetch(request, { contextData: undefined }); + const html = await response.text(); + ok(!html.includes("hello world")); + ok(!html.includes("boom happened")); + ok(html.includes("No logs match the selected filters.")); +}); + +test("trace detail page log filter form retains selected values", async () => { + const { federation } = createMockFederation(); + const { exporter, kv } = createMockExporter(); + const dbg = createFederationDebugger(federation, { exporter, kv }); + const traceId = "aaaa1111bbbb2222cccc3333dddd4444"; + sinkTwoDistinctLogs(dbg, traceId); + + const request = new Request( + `https://example.com/__debug__/traces/${traceId}` + + "?category=fedify.federation&level=info&q=hello", + ); + const response = await dbg.fetch(request, { contextData: undefined }); + const html = await response.text(); + ok(html.includes('value="fedify.federation" selected')); + ok(html.includes('value="info" selected')); + ok(html.includes('value="hello"')); + ok(html.includes("Clear filters")); +}); + +test("trace detail page escapes a malicious search query in the filter form", async () => { + const { federation } = createMockFederation(); + const { exporter, kv } = createMockExporter(); + const dbg = createFederationDebugger(federation, { exporter, kv }); + const traceId = "aaaa1111bbbb2222cccc3333dddd4444"; + sinkTwoDistinctLogs(dbg, traceId); + + const malicious = '">'; + const request = new Request( + `https://example.com/__debug__/traces/${traceId}?q=${ + encodeURIComponent(malicious) + }`, + ); + const response = await dbg.fetch(request, { contextData: undefined }); + const html = await response.text(); + ok(!html.includes("")); + ok(html.includes("<script>")); +}); diff --git a/packages/debugger/src/routes.tsx b/packages/debugger/src/routes.tsx index 15e196df5..0c101666d 100644 --- a/packages/debugger/src/routes.tsx +++ b/packages/debugger/src/routes.tsx @@ -5,7 +5,7 @@ * * @module */ -import type { FedifySpanExporter } from "@fedify/fedify/otel"; +import type { FedifySpanExporter, TraceSummary } from "@fedify/fedify/otel"; import { Hono } from "hono"; import { getCookie } from "hono/cookie"; import { @@ -16,11 +16,78 @@ import { signSession, verifySession, } from "./auth.ts"; -import type { LogStore } from "./log-store.ts"; +import type { LogStore, SerializedLogRecord } from "./log-store.ts"; import { LoginPage } from "./views/login.tsx"; import { TraceDetailPage } from "./views/trace-detail.tsx"; import { TracesListPage } from "./views/traces-list.tsx"; +/** Collects the distinct activity types across all traces, sorted. */ +function distinctActivityTypes(traces: readonly TraceSummary[]): string[] { + const types = new Set(); + for (const trace of traces) { + for (const type of trace.activityTypes) types.add(type); + } + return [...types].sort(); +} + +/** + * Keeps only the traces whose `activityTypes` include at least one of the + * given `types`. An empty `types` list means "no filter"—all traces pass + * through unchanged. + */ +function filterTracesByTypes( + traces: readonly TraceSummary[], + types: readonly string[], +): TraceSummary[] { + if (types.length === 0) return [...traces]; + return traces.filter((trace) => + trace.activityTypes.some((type) => types.includes(type)) + ); +} + +/** Collects the distinct dot-joined log categories, sorted. */ +function distinctLogCategories( + logs: readonly SerializedLogRecord[], +): string[] { + const categories = new Set(); + for (const log of logs) categories.add(log.category.join(".")); + return [...categories].sort(); +} + +/** + * Criteria for narrowing down a trace's log records on the trace detail + * page. Every present field must match (AND); an absent or empty field + * is not applied. + */ +interface LogFilter { + readonly category?: string; + readonly level?: string; + readonly q?: string; +} + +/** Applies a {@link LogFilter} to a list of log records. */ +function filterLogs( + logs: readonly SerializedLogRecord[], + filter: LogFilter, +): readonly SerializedLogRecord[] { + let filtered = logs; + if (filter.category) { + const category = filter.category; + filtered = filtered.filter((log) => log.category.join(".") === category); + } + if (filter.level) { + const level = filter.level; + filtered = filtered.filter((log) => log.level === level); + } + if (filter.q) { + const needle = filter.q.toLowerCase(); + filtered = filtered.filter((log) => + log.message.toLowerCase().includes(needle) + ); + } + return filtered; +} + export function createDebugApp( pathPrefix: string, exporter: FedifySpanExporter, @@ -133,7 +200,8 @@ export function createDebugApp( app.get("/api/traces", async (c) => { const traces = await exporter.getRecentTraces(); - return c.json(traces); + const types = c.req.queries("type") ?? []; + return c.json(filterTracesByTypes(traces, types)); }); app.get("/api/logs/:traceId", async (c) => { @@ -148,11 +216,20 @@ export function createDebugApp( await logStore.flush(); const activities = await exporter.getActivitiesByTraceId(traceId); const logs = await logStore.get(traceId); + const logFilter: LogFilter = { + category: c.req.query("category"), + level: c.req.query("level"), + q: c.req.query("q"), + }; return c.html( , ); @@ -160,8 +237,14 @@ export function createDebugApp( app.get("/", async (c) => { const traces = await exporter.getRecentTraces(); + const selectedTypes = c.req.queries("type") ?? []; return c.html( - , + , ); }); diff --git a/packages/debugger/src/views/layout.tsx b/packages/debugger/src/views/layout.tsx index 038c07c96..11d20a0f1 100644 --- a/packages/debugger/src/views/layout.tsx +++ b/packages/debugger/src/views/layout.tsx @@ -57,6 +57,13 @@ export const Layout: FC> = ( pre { background: #f6f8fa; padding: 1rem; overflow-x: auto; border-radius: 6px; font-size: 0.8125rem; } .empty { color: #888; font-style: italic; } nav a { margin-right: 0.5rem; } + .filter-form { border: 1px solid #ddd; border-radius: 6px; padding: 0.75rem 1rem; margin-bottom: 1rem; } + .filter-form fieldset { border: none; padding: 0; margin: 0; } + .filter-form legend { font-size: 0.8125rem; color: #666; padding: 0; margin-bottom: 0.5rem; } + .filter-form label { display: inline-flex; align-items: center; gap: 0.3rem; margin: 0 1rem 0.5rem 0; font-size: 0.875rem; } + .filter-form select, .filter-form input[type="text"] { font-size: 0.875rem; padding: 0.25rem 0.4rem; } + .filter-actions { display: flex; align-items: center; gap: 1rem; margin-top: 0.25rem; } + .filter-actions button { font-size: 0.8125rem; padding: 0.3rem 0.75rem; cursor: pointer; } .log-table td { font-size: 0.8125rem; vertical-align: top; } .log-table time { font-family: monospace; white-space: nowrap; } .badge-debug { background: #e8e8e8; color: #666; } @@ -80,6 +87,8 @@ export const Layout: FC> = ( .detail-section h2 { border-bottom-color: #21262d; } pre { background: #161b22; } .empty { color: #9198a1; } + .filter-form { border-color: #30363d; } + .filter-form legend { color: #9198a1; } .badge-debug { background: #21262d; color: #9198a1; } .badge-info { background: #122d42; color: #58a6ff; } .badge-warning { background: #2e2a1f; color: #d29922; } diff --git a/packages/debugger/src/views/trace-detail.tsx b/packages/debugger/src/views/trace-detail.tsx index 2277709a3..a2a4720b2 100644 --- a/packages/debugger/src/views/trace-detail.tsx +++ b/packages/debugger/src/views/trace-detail.tsx @@ -5,6 +5,9 @@ import type { TraceActivityRecord } from "@fedify/fedify/otel"; import type { SerializedLogRecord } from "../mod.tsx"; import { Layout } from "./layout.tsx"; +/** The fixed set of log levels the filter form offers, in severity order. */ +const LOG_LEVELS = ["debug", "info", "warning", "error", "fatal"] as const; + /** * Safely formats a timestamp (milliseconds since epoch) as an ISO string. * Returns `"(invalid)"` if the timestamp is not a finite number or produces @@ -34,10 +37,33 @@ export interface TraceDetailPageProps { activities: TraceActivityRecord[]; /** - * The list of log records for this trace. + * The list of log records for this trace, already filtered by + * {@link selectedCategory}, {@link selectedLevel}, and + * {@link selectedQuery} when any of them is set. */ logs: readonly SerializedLogRecord[]; + /** + * The distinct log categories available to filter by, derived from the + * unfiltered log set for this trace. + */ + availableCategories: readonly string[]; + + /** + * The category currently selected in the filter form, if any. + */ + selectedCategory?: string; + + /** + * The log level currently selected in the filter form, if any. + */ + selectedLevel?: string; + + /** + * The free-text search term currently entered in the filter form, if any. + */ + selectedQuery?: string; + /** * The path prefix for the debug dashboard. */ @@ -48,8 +74,19 @@ export interface TraceDetailPageProps { * The trace detail page of the debug dashboard. */ export const TraceDetailPage: FC = ( - { traceId, activities, logs, pathPrefix }, + { + traceId, + activities, + logs, + availableCategories, + selectedCategory, + selectedLevel, + selectedQuery, + pathPrefix, + }, ) => { + const filtered = Boolean(selectedCategory) || Boolean(selectedLevel) || + Boolean(selectedQuery); return (