@fedify/botkit 0.3.0-dev.113 → 0.3.0-dev.117
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bot-impl.d.ts.map +1 -1
- package/dist/bot-impl.js +24 -16
- package/dist/bot-impl.js.map +1 -1
- package/dist/deno.js +2 -2
- package/dist/deno.js.map +1 -1
- package/dist/repository.d.ts +50 -0
- package/dist/repository.d.ts.map +1 -1
- package/dist/repository.js +106 -0
- package/dist/repository.js.map +1 -1
- package/dist/repository.test.js +57 -0
- package/dist/repository.test.js.map +1 -1
- package/dist/session-impl.d.ts.map +1 -1
- package/dist/session-impl.js +3 -0
- package/dist/session-impl.js.map +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository.test.js","names":["factories: Record<string, () => Repository>","keyPairs: CryptoKeyPair[]","messageC"],"sources":["../src/repository.test.ts"],"sourcesContent":["// BotKit by Fedify: A framework for creating ActivityPub bots\n// Copyright (C) 2025 Hong Minhee <https://hongminhee.org/>\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as\n// published by the Free Software Foundation, either version 3 of the\n// License, or (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see <https://www.gnu.org/licenses/>.\nimport { MemoryKvStore } from \"@fedify/fedify/federation\";\nimport { importJwk } from \"@fedify/fedify/sig\";\nimport {\n Create,\n Follow,\n Note,\n Person,\n PUBLIC_COLLECTION,\n} from \"@fedify/fedify/vocab\";\nimport assert from \"node:assert\";\nimport { describe, test } from \"node:test\";\nimport {\n KvRepository,\n MemoryCachedRepository,\n MemoryRepository,\n type Repository,\n} from \"./repository.ts\";\n\nfunction createKvRepository(): Repository {\n return new KvRepository(new MemoryKvStore());\n}\n\nfunction createMemoryRepository(): Repository {\n return new MemoryRepository();\n}\n\nfunction createMemoryCachedRepository(): Repository {\n return new MemoryCachedRepository(createKvRepository());\n}\n\nconst factories: Record<string, () => Repository> = {\n KvRepository: createKvRepository,\n MemoryRepository: createMemoryRepository,\n MemoryCachedRepository: createMemoryCachedRepository,\n};\n\nconst keyPairs: CryptoKeyPair[] = [\n {\n publicKey: await importJwk({\n kty: \"RSA\",\n alg: \"RS256\",\n // cSpell: disable\n n: \"1NZblYSc2beQqDmDUF_VDMeS7bUXShvIMK6NHd9OB-7ivBwad8vUcmqKwWj_ivqZva6EgD-n0549t0Pzn5xTArqEJ-c1DTyhC7TNtof0KIbU75qziHwHOqcyYCHusQgDm_TT7frDuxLqHJQ1UrdADMyCVDPFfcstPHhHp3NYStGeNcBo5B05DB_wkgqX2QF2MamQwkdRRMdZkVees38AsC6GTGoOFRI2lvJuUODtndpyjGAKOkLfkr9XzAcggRYx9ddsHBd5wylffwKhtUtWHkdVBdVAiEX8sZ38LhqNYm161PE83nfEvut6_lCCQ7DlPJ8Tp6SY-f2JTXA-C9sN0uJF8_YGhaCPgolv5Pk2UerQmvhMhql9MLDen1AvZrw0u1CWic0GQeIDA6Op9Exd5azhhdm4iKeYzAekUHFDi6WZRRZRCYgHaEEzXyFt9W3N3paolMYVOh1008d-aIgbYnZMToiwH897uQsNGkd1FVIutycXdeuhAbqB7AtLrzuD78wkKLO8k3DFcix2qaHRqiBKC3lUlDCD_I5yzinY_SOcagdpRxczvi6JN1ahUg39ZKYRtJIxUOp1H3iRrebbaOoxM19-axKH1om0sYtyX4JqYfN9QrSf3cO1I6CGnJY8hIkQ6CDH5Tmk_4VRRKdzphq4jZiiOYfR94WODPKDjTM\",\n e: \"AQAB\",\n // cSpell: enable\n key_ops: [\"verify\"],\n ext: true,\n }, \"public\"),\n privateKey: await importJwk({\n kty: \"RSA\",\n alg: \"RS256\",\n // cSpell: disable\n n: \"1NZblYSc2beQqDmDUF_VDMeS7bUXShvIMK6NHd9OB-7ivBwad8vUcmqKwWj_ivqZva6EgD-n0549t0Pzn5xTArqEJ-c1DTyhC7TNtof0KIbU75qziHwHOqcyYCHusQgDm_TT7frDuxLqHJQ1UrdADMyCVDPFfcstPHhHp3NYStGeNcBo5B05DB_wkgqX2QF2MamQwkdRRMdZkVees38AsC6GTGoOFRI2lvJuUODtndpyjGAKOkLfkr9XzAcggRYx9ddsHBd5wylffwKhtUtWHkdVBdVAiEX8sZ38LhqNYm161PE83nfEvut6_lCCQ7DlPJ8Tp6SY-f2JTXA-C9sN0uJF8_YGhaCPgolv5Pk2UerQmvhMhql9MLDen1AvZrw0u1CWic0GQeIDA6Op9Exd5azhhdm4iKeYzAekUHFDi6WZRRZRCYgHaEEzXyFt9W3N3paolMYVOh1008d-aIgbYnZMToiwH897uQsNGkd1FVIutycXdeuhAbqB7AtLrzuD78wkKLO8k3DFcix2qaHRqiBKC3lUlDCD_I5yzinY_SOcagdpRxczvi6JN1ahUg39ZKYRtJIxUOp1H3iRrebbaOoxM19-axKH1om0sYtyX4JqYfN9QrSf3cO1I6CGnJY8hIkQ6CDH5Tmk_4VRRKdzphq4jZiiOYfR94WODPKDjTM\",\n e: \"AQAB\",\n d: \"Yl3DrCHDIDhfifAyyWXRIHvoYyZL4jte1WkG3WSEOtRkRA41CWLSCCNHh8YQPNo_TdQnduJ0nTBIU7f7E6x7DQrI42xPL5Py1mc0oATLiiNurGJyUUUJTklR1e440-bhTCXmANnhtkcyngy9bEI3PvMR1PqsbswFVyo76586kjG5DhykHbGH2Ru14rk0nt23E5LLzY6Kd-AufCbjuQ-ccNC_zvdBFOn7At5-r7CVAVyhjlEgyPZ5P-hhGnG8ywxIANgUJhOPeexYL2o29IQiBBJxsCV0EsdN14UttN0etPvmRh5MRIFUE-zfRkRNQB20hMT8n4FKFlfgKkMS2gXep91h9VVyfYPHAt9jGJgUbIcbx_igeLK3nQlaUXaePf2bAuVRM1kW3P2UR0FOoUKDI5FZmi9XBoEtt0taQYySdKbPSXKaJWO2vKQ4SPyVXzzz-obfVe2zIe1msQ3Tco5RFoHfnufbvvnLC_WUAC9LSfp4jrPvr5lY3uoCFmPma56R-E3mVd2q87Ybk6mqvSh4yWHjid7sfzQ8Ovh9OhZlq_7Mfa3q3M92vNL98iHs8xYkJbE0DJs691UdgX45iNi4DVD-hJ7EbKQQgePsYNovWA611kM-cartevQWk7TBBggy9VYqmdWN0QuVQX9bsHFeYjjKSXg24bV5vYQW3EPkqZk\",\n p: \"9DeEDfMVdV605MbHCtHnw5xEbzTHd7vK-qAQNIjz5i4EmFC0tK7dvUiSn0WeyMNYJkuxVxTMHoDbWXzXq45tzbTEYuzEo5wsxyoVvldfFnnJIwMu6Hb7PWjyWfpBcbwLISr8fAJaGPzgcFsJE__KxrvLA66m1q_4k1y1L9CvXWfHDvFqb7VLGzKWXXp2wlbsACZuqx2Ff3THcWoOWb-wSww6AGsYAc3zC_DiYvAaTn9MxszZ0UYuMeJIHjLA1dmjL-Nksvq5GukjFxSSTpUS87zJ08fHoB0FzTKIIjJGpMRf6ebReLqbYCdo2Kr7eC7lbcTfwQTPI6gnHSKgPIYF5Q\",\n q: \"3xtArH_4MQjwRpl7JVivzQUZgDTARkynMpX-4Gvyny6Gxx0QLhHH0lQMRhtFWlI6qLZxCCLC9zhXPmGlqW-QWya8-xE80mX45JTrQlwBHISpTWTV3sI2Lp5dg7CW8Sc40CE4kB4Q2rHhf7V-Aimgmqhnl1uguzH2DXfr3RaCor0ge44k6gi1LXEJN_aFQIIFYL8HQOM0ctdY147Kr2rVHLchRnh8Q4GzBAJvpOcfvEDk9HF09NVxeaivLMXChpuSUHqbEGg_lVkotLnCMb-fUWk8QmO8EFFVU0pyOFDqHKIgrHOLSHjgUvV8moBwnMGQxMgu7rpY3g-9cXfsCoKVNw\",\n dp:\n \"bL1vajqrelhSGW-83r95_-pLumx4yIJwrcmpjYrRdtNUrnF5FN6r0wVGa-629dOtI1gevZSAErDzelQRP80qbSapLxcXs3XtpjzB87-5kitl-NYJA-8-jSh2iMPacgb1ua4HQDxX27p1QPH4B9SkeHrTuW8B0KQH_a2Q65pzCxcTVj7-UoEZ0SFkPHkz-fJ0INj7--soLwlTaNd9Tk8A81mdVeRZiywlpVJ7quwX-o3KJNa_weQK26FS1Udp_45pkAAjLWJgG3BldHhvcNgF2UtdXpQc-dkSZTyzyu4x8FmUD3T8HlKQrm69y4POdsQC2i6IJsy6YrkTuXBagrh2VQ\",\n dq:\n \"j0CQZjJEyjdTEAG8cF5hguKjXQ6B5qGROYnV_YNSZaMaJv8iRHJmO0Z8GwenoDbsMyfxq6emR9aFLijEleZsahqVfR-0TePry9lStWkdzZHgozD7oexRnd1Rbh0UzgLBF-I8z0x-xe0xPS7rmbfgx20aFrVentOViVBWwb6SYqvND4hVa2_r5SGPKb_AD4tsqJH_tkosgxCCmuW0fq256JYtZ3I1V6MPrqNhzCAa4GVKnSm8Tvg9xD_rOnRAUu3RJJuUtRQ6v0pgOKqNZiQDx-IqLvaa6l9OygwjCsXpjDkNga0u4Xm7j4jQWOPfasdejPt8Jwy_wtWYbiLyDE2MQQ\",\n qi:\n \"Th3TS6fHquqNljwZU2Vg7ndI0SmJidIwSTS2LlhM-Y2bxaAUF-orpS504xDVk1xjRYBrdxiTOmohbtoKtiWhLveOUAWVoNilMqgEU7lwnhaE3yfiUoE1x8df_wLP_YiAccFKeMZwsQp29aKLxuYQtO2dRSSQkN0IuxMGchnJtGOGNTbyA44O25IwggV1nlJN7OTX-nsJCSCe1XMojnGezhnD4xXGeSuR3S07oDDiWpvAO7qtRphEavVTtXdJWIr27tBvnUytbpb4uq6A3J4-TZ6X9uzlOw6jBSQhbL7fc83Z9E_wjPTnxfHufiC_AtXow6sK7lCy10aJGHp3jnGVdQ\",\n // cSpell: enable\n key_ops: [\"sign\"],\n ext: true,\n }, \"private\"),\n },\n {\n privateKey: await importJwk({\n kty: \"OKP\",\n crv: \"Ed25519\",\n // cSpell: disable-next-line\n x: \"CwcwyY7tu4wVzVW3KKX7AnBO8HakA2pg0rhAiMbGtfk\",\n key_ops: [\"sign\"],\n ext: true,\n // cSpell: disable-next-line\n d: \"K64nFsAPt892l7rr10uDsBXCW151CUM29SugU6l4ZzE\",\n }, \"private\"),\n publicKey: await importJwk({\n kty: \"OKP\",\n crv: \"Ed25519\",\n // cSpell: disable-next-line\n x: \"CwcwyY7tu4wVzVW3KKX7AnBO8HakA2pg0rhAiMbGtfk\",\n key_ops: [\"verify\"],\n ext: true,\n }, \"public\"),\n },\n];\n\nfor (const name in factories) {\n const factory = factories[name];\n\n describe(name, () => {\n const repo = factory();\n\n test(\"key pairs\", async () => {\n assert.deepStrictEqual(await repo.getKeyPairs(), undefined);\n await repo.setKeyPairs(keyPairs);\n assert.deepStrictEqual(await repo.getKeyPairs(), keyPairs);\n });\n\n test(\"messages\", async () => {\n assert.deepStrictEqual(await repo.countMessages(), 0);\n assert.deepStrictEqual(\n await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"),\n undefined,\n );\n assert.deepStrictEqual(await Array.fromAsync(repo.getMessages()), []);\n\n const messageA = new Create({\n id: new URL(\n \"https://example.com/ap/create/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n });\n const messageB = new Create({\n id: new URL(\n \"https://example.com/ap/create/0194244f-d800-7873-8993-ef71ccd47306\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n });\n const messageC = new Create({\n id: new URL(\n \"https://example.com/ap/create/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n });\n const messageD = new Create({\n id: new URL(\n \"https://example.com/ap/create/01942e9c-9000-7480-a553-7a6ce737ce14\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-04T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-04T00:00:00Z\"),\n });\n const messageC2 = new Create({\n id: new URL(\n \"https://example.com/ap/create/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hi, world!\",\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n updated: Temporal.Instant.from(\"2025-01-03T12:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n updated: Temporal.Instant.from(\"2025-01-03T12:00:00Z\"),\n });\n\n await repo.addMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\", messageA);\n assert.deepStrictEqual(await repo.countMessages(), 1);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"),\n undefined,\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages())).map((m) => m.toJsonLd()),\n ),\n [await messageA.toJsonLd()],\n );\n\n await repo.addMessage(\"0194244f-d800-7873-8993-ef71ccd47306\", messageB);\n assert.deepStrictEqual(await repo.countMessages(), 2);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"))\n ?.toJsonLd(),\n await messageB.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"),\n undefined,\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages())).map((m) => m.toJsonLd()),\n ),\n [await messageB.toJsonLd(), await messageA.toJsonLd()],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages({ order: \"oldest\" }))).map((\n m,\n ) => m.toJsonLd()),\n ),\n [await messageA.toJsonLd(), await messageB.toJsonLd()],\n );\n\n await repo.addMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\", messageC);\n assert.deepStrictEqual(await repo.countMessages(), 3);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"))\n ?.toJsonLd(),\n await messageB.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"))\n ?.toJsonLd(),\n await messageC.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"),\n undefined,\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages({ order: \"newest\" }))).map((\n m,\n ) => m.toJsonLd()),\n ),\n [\n await messageC.toJsonLd(),\n await messageB.toJsonLd(),\n await messageA.toJsonLd(),\n ],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages({ order: \"oldest\" }))).map((\n m,\n ) => m.toJsonLd()),\n ),\n [\n await messageA.toJsonLd(),\n await messageB.toJsonLd(),\n await messageC.toJsonLd(),\n ],\n );\n\n await repo.addMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\", messageD);\n assert.deepStrictEqual(await repo.countMessages(), 4);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"))\n ?.toJsonLd(),\n await messageB.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"))\n ?.toJsonLd(),\n await messageC.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"))\n ?.toJsonLd(),\n await messageD.toJsonLd(),\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages())).map((\n m,\n ) => m.toJsonLd()),\n ),\n [\n await messageD.toJsonLd(),\n await messageC.toJsonLd(),\n await messageB.toJsonLd(),\n await messageA.toJsonLd(),\n ],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(\n repo.getMessages({\n order: \"oldest\",\n until: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n }),\n )).map((m) => m.toJsonLd()),\n ),\n [\n await messageA.toJsonLd(),\n await messageB.toJsonLd(),\n await messageC.toJsonLd(),\n ],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(\n repo.getMessages({\n since: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n }),\n )).map((m) => m.toJsonLd()),\n ),\n [\n await messageD.toJsonLd(),\n await messageC.toJsonLd(),\n await messageB.toJsonLd(),\n ],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(\n repo.getMessages({\n until: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n since: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n }),\n )).map((m) => m.toJsonLd()),\n ),\n [\n await messageC.toJsonLd(),\n await messageB.toJsonLd(),\n ],\n );\n\n const removed = await repo.removeMessage(\n \"0194244f-d800-7873-8993-ef71ccd47306\",\n );\n assert.deepStrictEqual(\n await removed?.toJsonLd(),\n await messageB.toJsonLd(),\n );\n assert.deepStrictEqual(await repo.countMessages(), 3);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"),\n undefined,\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"))\n ?.toJsonLd(),\n await messageC.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"))\n ?.toJsonLd(),\n await messageD.toJsonLd(),\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages({ order: \"newest\" }))).map((\n m,\n ) => m.toJsonLd()),\n ),\n [\n await messageD.toJsonLd(),\n await messageC.toJsonLd(),\n await messageA.toJsonLd(),\n ],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages({ order: \"oldest\" }))).map((\n m,\n ) => m.toJsonLd()),\n ),\n [\n await messageA.toJsonLd(),\n await messageC.toJsonLd(),\n await messageD.toJsonLd(),\n ],\n );\n\n await repo.updateMessage(\n \"01942976-3400-7f34-872e-2cbf0f9eeac4\",\n async (messageC) =>\n messageC.clone({\n object: await messageC2.getObject(),\n updated: messageC2.updated,\n }),\n );\n assert.deepStrictEqual(await repo.countMessages(), 3);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"),\n undefined,\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"))\n ?.toJsonLd(),\n await messageC2.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"))\n ?.toJsonLd(),\n await messageD.toJsonLd(),\n );\n\n let updaterCalled = false;\n const updated = await repo.updateMessage(\n \"00000000-0000-0000-0000-000000000000\",\n (message) => {\n updaterCalled = true;\n return message;\n },\n );\n assert.deepStrictEqual(updated, false);\n assert.deepStrictEqual(updaterCalled, false);\n assert.deepStrictEqual(await repo.countMessages(), 3);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"),\n undefined,\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"))\n ?.toJsonLd(),\n await messageC2.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"))\n ?.toJsonLd(),\n await messageD.toJsonLd(),\n );\n\n const updated2 = await repo.updateMessage(\n \"01942e9c-9000-7480-a553-7a6ce737ce14\",\n (_) => undefined,\n );\n assert.deepStrictEqual(updated2, false);\n assert.deepStrictEqual(await repo.countMessages(), 3);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"),\n undefined,\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"))\n ?.toJsonLd(),\n await messageC2.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"))\n ?.toJsonLd(),\n await messageD.toJsonLd(),\n );\n });\n\n test(\"followers\", async () => {\n const followerA = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n });\n const followFromA = new URL(\n \"https://example.com/ap/follow/be2da56a-0ea3-4a6a-9dff-2a1837be67e0\",\n );\n const followerB = new Person({\n id: new URL(\"https://example.com/ap/actor/jane\"),\n preferredUsername: \"jane\",\n });\n const followFromB = new URL(\n \"https://example.com/ap/follow/8b76286d-5eef-4f02-8a16-080ff2b0e2ca\",\n );\n\n assert.deepStrictEqual(await repo.countFollowers(), 0);\n assert.deepStrictEqual(await repo.hasFollower(followerA.id!), false);\n assert.deepStrictEqual(await repo.hasFollower(followerB.id!), false);\n assert.deepStrictEqual(await Array.fromAsync(repo.getFollowers()), []);\n\n await repo.addFollower(followFromA, followerA);\n assert.deepStrictEqual(await repo.countFollowers(), 1);\n assert.ok(await repo.hasFollower(followerA.id!));\n assert.deepStrictEqual(await repo.hasFollower(followerB.id!), false);\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getFollowers())).map((f) => f.toJsonLd()),\n ),\n [await followerA.toJsonLd()],\n );\n\n await repo.addFollower(followFromB, followerB);\n assert.deepStrictEqual(await repo.countFollowers(), 2);\n assert.ok(await repo.hasFollower(followerA.id!));\n assert.ok(await repo.hasFollower(followerB.id!));\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getFollowers())).map((f) => f.toJsonLd()),\n ),\n [await followerA.toJsonLd(), await followerB.toJsonLd()],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getFollowers({ offset: 1 }))).map((f) =>\n f.toJsonLd()\n ),\n ),\n [await followerB.toJsonLd()],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getFollowers({ limit: 1 }))).map((f) =>\n f.toJsonLd()\n ),\n ),\n [await followerA.toJsonLd()],\n );\n\n assert.deepStrictEqual(\n await repo.removeFollower(followFromA, followerB.id!),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.removeFollower(followFromB, followerA.id!),\n undefined,\n );\n assert.deepStrictEqual(await repo.countFollowers(), 2);\n assert.ok(await repo.hasFollower(followerA.id!));\n assert.ok(await repo.hasFollower(followerB.id!));\n\n await repo.removeFollower(followFromA, followerA.id!);\n assert.deepStrictEqual(await repo.countFollowers(), 1);\n assert.deepStrictEqual(await repo.hasFollower(followerA.id!), false);\n assert.ok(await repo.hasFollower(followerB.id!));\n\n await repo.removeFollower(followFromB, followerB.id!);\n assert.deepStrictEqual(await repo.countFollowers(), 0);\n assert.deepStrictEqual(await repo.hasFollower(followerA.id!), false);\n assert.deepStrictEqual(await repo.hasFollower(followerB.id!), false);\n });\n\n test(\"sent follows\", async () => {\n const follow = new Follow({\n id: new URL(\n \"https://example.com/ap/follow/03a395a2-353a-4894-afdb-2cab31a7b004\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new URL(\"https://example.com/ap/actor/john\"),\n });\n\n assert.deepStrictEqual(\n await repo.getSentFollow(\"03a395a2-353a-4894-afdb-2cab31a7b004\"),\n undefined,\n );\n\n await repo.addSentFollow(\"03a395a2-353a-4894-afdb-2cab31a7b004\", follow);\n assert.deepStrictEqual(\n await (await repo.getSentFollow(\"03a395a2-353a-4894-afdb-2cab31a7b004\"))\n ?.toJsonLd(),\n await follow.toJsonLd(),\n );\n\n await repo.removeSentFollow(\"03a395a2-353a-4894-afdb-2cab31a7b004\");\n assert.deepStrictEqual(\n await repo.getSentFollow(\"03a395a2-353a-4894-afdb-2cab31a7b004\"),\n undefined,\n );\n });\n\n test(\"followees\", async () => {\n const followeeId = new URL(\"https://example.com/ap/actor/john\");\n const follow = new Follow({\n id: new URL(\n \"https://example.com/ap/follow/03a395a2-353a-4894-afdb-2cab31a7b004\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: followeeId,\n });\n\n assert.deepStrictEqual(await repo.getFollowee(followeeId), undefined);\n\n await repo.addFollowee(followeeId, follow);\n assert.deepStrictEqual(\n await (await repo.getFollowee(followeeId))?.toJsonLd(),\n await follow.toJsonLd(),\n );\n\n await repo.removeFollowee(followeeId);\n assert.deepStrictEqual(await repo.getFollowee(followeeId), undefined);\n });\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"repository.test.js","names":["factories: Record<string, () => Repository>","keyPairs: CryptoKeyPair[]","messageC"],"sources":["../src/repository.test.ts"],"sourcesContent":["// BotKit by Fedify: A framework for creating ActivityPub bots\n// Copyright (C) 2025 Hong Minhee <https://hongminhee.org/>\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as\n// published by the Free Software Foundation, either version 3 of the\n// License, or (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see <https://www.gnu.org/licenses/>.\nimport { MemoryKvStore } from \"@fedify/fedify/federation\";\nimport { importJwk } from \"@fedify/fedify/sig\";\nimport {\n Create,\n Follow,\n Note,\n Person,\n PUBLIC_COLLECTION,\n} from \"@fedify/fedify/vocab\";\nimport assert from \"node:assert\";\nimport { describe, test } from \"node:test\";\nimport {\n KvRepository,\n MemoryCachedRepository,\n MemoryRepository,\n type Repository,\n} from \"./repository.ts\";\n\nfunction createKvRepository(): Repository {\n return new KvRepository(new MemoryKvStore());\n}\n\nfunction createMemoryRepository(): Repository {\n return new MemoryRepository();\n}\n\nfunction createMemoryCachedRepository(): Repository {\n return new MemoryCachedRepository(createKvRepository());\n}\n\nconst factories: Record<string, () => Repository> = {\n KvRepository: createKvRepository,\n MemoryRepository: createMemoryRepository,\n MemoryCachedRepository: createMemoryCachedRepository,\n};\n\nconst keyPairs: CryptoKeyPair[] = [\n {\n publicKey: await importJwk({\n kty: \"RSA\",\n alg: \"RS256\",\n // cSpell: disable\n n: \"1NZblYSc2beQqDmDUF_VDMeS7bUXShvIMK6NHd9OB-7ivBwad8vUcmqKwWj_ivqZva6EgD-n0549t0Pzn5xTArqEJ-c1DTyhC7TNtof0KIbU75qziHwHOqcyYCHusQgDm_TT7frDuxLqHJQ1UrdADMyCVDPFfcstPHhHp3NYStGeNcBo5B05DB_wkgqX2QF2MamQwkdRRMdZkVees38AsC6GTGoOFRI2lvJuUODtndpyjGAKOkLfkr9XzAcggRYx9ddsHBd5wylffwKhtUtWHkdVBdVAiEX8sZ38LhqNYm161PE83nfEvut6_lCCQ7DlPJ8Tp6SY-f2JTXA-C9sN0uJF8_YGhaCPgolv5Pk2UerQmvhMhql9MLDen1AvZrw0u1CWic0GQeIDA6Op9Exd5azhhdm4iKeYzAekUHFDi6WZRRZRCYgHaEEzXyFt9W3N3paolMYVOh1008d-aIgbYnZMToiwH897uQsNGkd1FVIutycXdeuhAbqB7AtLrzuD78wkKLO8k3DFcix2qaHRqiBKC3lUlDCD_I5yzinY_SOcagdpRxczvi6JN1ahUg39ZKYRtJIxUOp1H3iRrebbaOoxM19-axKH1om0sYtyX4JqYfN9QrSf3cO1I6CGnJY8hIkQ6CDH5Tmk_4VRRKdzphq4jZiiOYfR94WODPKDjTM\",\n e: \"AQAB\",\n // cSpell: enable\n key_ops: [\"verify\"],\n ext: true,\n }, \"public\"),\n privateKey: await importJwk({\n kty: \"RSA\",\n alg: \"RS256\",\n // cSpell: disable\n n: \"1NZblYSc2beQqDmDUF_VDMeS7bUXShvIMK6NHd9OB-7ivBwad8vUcmqKwWj_ivqZva6EgD-n0549t0Pzn5xTArqEJ-c1DTyhC7TNtof0KIbU75qziHwHOqcyYCHusQgDm_TT7frDuxLqHJQ1UrdADMyCVDPFfcstPHhHp3NYStGeNcBo5B05DB_wkgqX2QF2MamQwkdRRMdZkVees38AsC6GTGoOFRI2lvJuUODtndpyjGAKOkLfkr9XzAcggRYx9ddsHBd5wylffwKhtUtWHkdVBdVAiEX8sZ38LhqNYm161PE83nfEvut6_lCCQ7DlPJ8Tp6SY-f2JTXA-C9sN0uJF8_YGhaCPgolv5Pk2UerQmvhMhql9MLDen1AvZrw0u1CWic0GQeIDA6Op9Exd5azhhdm4iKeYzAekUHFDi6WZRRZRCYgHaEEzXyFt9W3N3paolMYVOh1008d-aIgbYnZMToiwH897uQsNGkd1FVIutycXdeuhAbqB7AtLrzuD78wkKLO8k3DFcix2qaHRqiBKC3lUlDCD_I5yzinY_SOcagdpRxczvi6JN1ahUg39ZKYRtJIxUOp1H3iRrebbaOoxM19-axKH1om0sYtyX4JqYfN9QrSf3cO1I6CGnJY8hIkQ6CDH5Tmk_4VRRKdzphq4jZiiOYfR94WODPKDjTM\",\n e: \"AQAB\",\n d: \"Yl3DrCHDIDhfifAyyWXRIHvoYyZL4jte1WkG3WSEOtRkRA41CWLSCCNHh8YQPNo_TdQnduJ0nTBIU7f7E6x7DQrI42xPL5Py1mc0oATLiiNurGJyUUUJTklR1e440-bhTCXmANnhtkcyngy9bEI3PvMR1PqsbswFVyo76586kjG5DhykHbGH2Ru14rk0nt23E5LLzY6Kd-AufCbjuQ-ccNC_zvdBFOn7At5-r7CVAVyhjlEgyPZ5P-hhGnG8ywxIANgUJhOPeexYL2o29IQiBBJxsCV0EsdN14UttN0etPvmRh5MRIFUE-zfRkRNQB20hMT8n4FKFlfgKkMS2gXep91h9VVyfYPHAt9jGJgUbIcbx_igeLK3nQlaUXaePf2bAuVRM1kW3P2UR0FOoUKDI5FZmi9XBoEtt0taQYySdKbPSXKaJWO2vKQ4SPyVXzzz-obfVe2zIe1msQ3Tco5RFoHfnufbvvnLC_WUAC9LSfp4jrPvr5lY3uoCFmPma56R-E3mVd2q87Ybk6mqvSh4yWHjid7sfzQ8Ovh9OhZlq_7Mfa3q3M92vNL98iHs8xYkJbE0DJs691UdgX45iNi4DVD-hJ7EbKQQgePsYNovWA611kM-cartevQWk7TBBggy9VYqmdWN0QuVQX9bsHFeYjjKSXg24bV5vYQW3EPkqZk\",\n p: \"9DeEDfMVdV605MbHCtHnw5xEbzTHd7vK-qAQNIjz5i4EmFC0tK7dvUiSn0WeyMNYJkuxVxTMHoDbWXzXq45tzbTEYuzEo5wsxyoVvldfFnnJIwMu6Hb7PWjyWfpBcbwLISr8fAJaGPzgcFsJE__KxrvLA66m1q_4k1y1L9CvXWfHDvFqb7VLGzKWXXp2wlbsACZuqx2Ff3THcWoOWb-wSww6AGsYAc3zC_DiYvAaTn9MxszZ0UYuMeJIHjLA1dmjL-Nksvq5GukjFxSSTpUS87zJ08fHoB0FzTKIIjJGpMRf6ebReLqbYCdo2Kr7eC7lbcTfwQTPI6gnHSKgPIYF5Q\",\n q: \"3xtArH_4MQjwRpl7JVivzQUZgDTARkynMpX-4Gvyny6Gxx0QLhHH0lQMRhtFWlI6qLZxCCLC9zhXPmGlqW-QWya8-xE80mX45JTrQlwBHISpTWTV3sI2Lp5dg7CW8Sc40CE4kB4Q2rHhf7V-Aimgmqhnl1uguzH2DXfr3RaCor0ge44k6gi1LXEJN_aFQIIFYL8HQOM0ctdY147Kr2rVHLchRnh8Q4GzBAJvpOcfvEDk9HF09NVxeaivLMXChpuSUHqbEGg_lVkotLnCMb-fUWk8QmO8EFFVU0pyOFDqHKIgrHOLSHjgUvV8moBwnMGQxMgu7rpY3g-9cXfsCoKVNw\",\n dp:\n \"bL1vajqrelhSGW-83r95_-pLumx4yIJwrcmpjYrRdtNUrnF5FN6r0wVGa-629dOtI1gevZSAErDzelQRP80qbSapLxcXs3XtpjzB87-5kitl-NYJA-8-jSh2iMPacgb1ua4HQDxX27p1QPH4B9SkeHrTuW8B0KQH_a2Q65pzCxcTVj7-UoEZ0SFkPHkz-fJ0INj7--soLwlTaNd9Tk8A81mdVeRZiywlpVJ7quwX-o3KJNa_weQK26FS1Udp_45pkAAjLWJgG3BldHhvcNgF2UtdXpQc-dkSZTyzyu4x8FmUD3T8HlKQrm69y4POdsQC2i6IJsy6YrkTuXBagrh2VQ\",\n dq:\n \"j0CQZjJEyjdTEAG8cF5hguKjXQ6B5qGROYnV_YNSZaMaJv8iRHJmO0Z8GwenoDbsMyfxq6emR9aFLijEleZsahqVfR-0TePry9lStWkdzZHgozD7oexRnd1Rbh0UzgLBF-I8z0x-xe0xPS7rmbfgx20aFrVentOViVBWwb6SYqvND4hVa2_r5SGPKb_AD4tsqJH_tkosgxCCmuW0fq256JYtZ3I1V6MPrqNhzCAa4GVKnSm8Tvg9xD_rOnRAUu3RJJuUtRQ6v0pgOKqNZiQDx-IqLvaa6l9OygwjCsXpjDkNga0u4Xm7j4jQWOPfasdejPt8Jwy_wtWYbiLyDE2MQQ\",\n qi:\n \"Th3TS6fHquqNljwZU2Vg7ndI0SmJidIwSTS2LlhM-Y2bxaAUF-orpS504xDVk1xjRYBrdxiTOmohbtoKtiWhLveOUAWVoNilMqgEU7lwnhaE3yfiUoE1x8df_wLP_YiAccFKeMZwsQp29aKLxuYQtO2dRSSQkN0IuxMGchnJtGOGNTbyA44O25IwggV1nlJN7OTX-nsJCSCe1XMojnGezhnD4xXGeSuR3S07oDDiWpvAO7qtRphEavVTtXdJWIr27tBvnUytbpb4uq6A3J4-TZ6X9uzlOw6jBSQhbL7fc83Z9E_wjPTnxfHufiC_AtXow6sK7lCy10aJGHp3jnGVdQ\",\n // cSpell: enable\n key_ops: [\"sign\"],\n ext: true,\n }, \"private\"),\n },\n {\n privateKey: await importJwk({\n kty: \"OKP\",\n crv: \"Ed25519\",\n // cSpell: disable-next-line\n x: \"CwcwyY7tu4wVzVW3KKX7AnBO8HakA2pg0rhAiMbGtfk\",\n key_ops: [\"sign\"],\n ext: true,\n // cSpell: disable-next-line\n d: \"K64nFsAPt892l7rr10uDsBXCW151CUM29SugU6l4ZzE\",\n }, \"private\"),\n publicKey: await importJwk({\n kty: \"OKP\",\n crv: \"Ed25519\",\n // cSpell: disable-next-line\n x: \"CwcwyY7tu4wVzVW3KKX7AnBO8HakA2pg0rhAiMbGtfk\",\n key_ops: [\"verify\"],\n ext: true,\n }, \"public\"),\n },\n];\n\nfor (const name in factories) {\n const factory = factories[name];\n\n describe(name, () => {\n const repo = factory();\n\n test(\"key pairs\", async () => {\n assert.deepStrictEqual(await repo.getKeyPairs(), undefined);\n await repo.setKeyPairs(keyPairs);\n assert.deepStrictEqual(await repo.getKeyPairs(), keyPairs);\n });\n\n test(\"messages\", async () => {\n assert.deepStrictEqual(await repo.countMessages(), 0);\n assert.deepStrictEqual(\n await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"),\n undefined,\n );\n assert.deepStrictEqual(await Array.fromAsync(repo.getMessages()), []);\n\n const messageA = new Create({\n id: new URL(\n \"https://example.com/ap/create/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01941f29-7c00-7fe8-ab0a-7b593990a3c0\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-01T00:00:00Z\"),\n });\n const messageB = new Create({\n id: new URL(\n \"https://example.com/ap/create/0194244f-d800-7873-8993-ef71ccd47306\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/0194244f-d800-7873-8993-ef71ccd47306\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n });\n const messageC = new Create({\n id: new URL(\n \"https://example.com/ap/create/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n });\n const messageD = new Create({\n id: new URL(\n \"https://example.com/ap/create/01942e9c-9000-7480-a553-7a6ce737ce14\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01942e9c-9000-7480-a553-7a6ce737ce14\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hello, world!\",\n published: Temporal.Instant.from(\"2025-01-04T00:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-04T00:00:00Z\"),\n });\n const messageC2 = new Create({\n id: new URL(\n \"https://example.com/ap/create/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n object: new Note({\n id: new URL(\n \"https://example.com/ap/note/01942976-3400-7f34-872e-2cbf0f9eeac4\",\n ),\n attribution: new URL(\"https://example.com/ap/actor/bot\"),\n to: new URL(\"https://example.com/ap/actor/bot/followers\"),\n cc: PUBLIC_COLLECTION,\n content: \"Hi, world!\",\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n updated: Temporal.Instant.from(\"2025-01-03T12:00:00Z\"),\n }),\n published: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n updated: Temporal.Instant.from(\"2025-01-03T12:00:00Z\"),\n });\n\n await repo.addMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\", messageA);\n assert.deepStrictEqual(await repo.countMessages(), 1);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"),\n undefined,\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages())).map((m) => m.toJsonLd()),\n ),\n [await messageA.toJsonLd()],\n );\n\n await repo.addMessage(\"0194244f-d800-7873-8993-ef71ccd47306\", messageB);\n assert.deepStrictEqual(await repo.countMessages(), 2);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"))\n ?.toJsonLd(),\n await messageB.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"),\n undefined,\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages())).map((m) => m.toJsonLd()),\n ),\n [await messageB.toJsonLd(), await messageA.toJsonLd()],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages({ order: \"oldest\" }))).map((\n m,\n ) => m.toJsonLd()),\n ),\n [await messageA.toJsonLd(), await messageB.toJsonLd()],\n );\n\n await repo.addMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\", messageC);\n assert.deepStrictEqual(await repo.countMessages(), 3);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"))\n ?.toJsonLd(),\n await messageB.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"))\n ?.toJsonLd(),\n await messageC.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"),\n undefined,\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages({ order: \"newest\" }))).map((\n m,\n ) => m.toJsonLd()),\n ),\n [\n await messageC.toJsonLd(),\n await messageB.toJsonLd(),\n await messageA.toJsonLd(),\n ],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages({ order: \"oldest\" }))).map((\n m,\n ) => m.toJsonLd()),\n ),\n [\n await messageA.toJsonLd(),\n await messageB.toJsonLd(),\n await messageC.toJsonLd(),\n ],\n );\n\n await repo.addMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\", messageD);\n assert.deepStrictEqual(await repo.countMessages(), 4);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"))\n ?.toJsonLd(),\n await messageB.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"))\n ?.toJsonLd(),\n await messageC.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"))\n ?.toJsonLd(),\n await messageD.toJsonLd(),\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages())).map((\n m,\n ) => m.toJsonLd()),\n ),\n [\n await messageD.toJsonLd(),\n await messageC.toJsonLd(),\n await messageB.toJsonLd(),\n await messageA.toJsonLd(),\n ],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(\n repo.getMessages({\n order: \"oldest\",\n until: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n }),\n )).map((m) => m.toJsonLd()),\n ),\n [\n await messageA.toJsonLd(),\n await messageB.toJsonLd(),\n await messageC.toJsonLd(),\n ],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(\n repo.getMessages({\n since: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n }),\n )).map((m) => m.toJsonLd()),\n ),\n [\n await messageD.toJsonLd(),\n await messageC.toJsonLd(),\n await messageB.toJsonLd(),\n ],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(\n repo.getMessages({\n until: Temporal.Instant.from(\"2025-01-03T00:00:00Z\"),\n since: Temporal.Instant.from(\"2025-01-02T00:00:00Z\"),\n }),\n )).map((m) => m.toJsonLd()),\n ),\n [\n await messageC.toJsonLd(),\n await messageB.toJsonLd(),\n ],\n );\n\n const removed = await repo.removeMessage(\n \"0194244f-d800-7873-8993-ef71ccd47306\",\n );\n assert.deepStrictEqual(\n await removed?.toJsonLd(),\n await messageB.toJsonLd(),\n );\n assert.deepStrictEqual(await repo.countMessages(), 3);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"),\n undefined,\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"))\n ?.toJsonLd(),\n await messageC.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"))\n ?.toJsonLd(),\n await messageD.toJsonLd(),\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages({ order: \"newest\" }))).map((\n m,\n ) => m.toJsonLd()),\n ),\n [\n await messageD.toJsonLd(),\n await messageC.toJsonLd(),\n await messageA.toJsonLd(),\n ],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getMessages({ order: \"oldest\" }))).map((\n m,\n ) => m.toJsonLd()),\n ),\n [\n await messageA.toJsonLd(),\n await messageC.toJsonLd(),\n await messageD.toJsonLd(),\n ],\n );\n\n await repo.updateMessage(\n \"01942976-3400-7f34-872e-2cbf0f9eeac4\",\n async (messageC) =>\n messageC.clone({\n object: await messageC2.getObject(),\n updated: messageC2.updated,\n }),\n );\n assert.deepStrictEqual(await repo.countMessages(), 3);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"),\n undefined,\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"))\n ?.toJsonLd(),\n await messageC2.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"))\n ?.toJsonLd(),\n await messageD.toJsonLd(),\n );\n\n let updaterCalled = false;\n const updated = await repo.updateMessage(\n \"00000000-0000-0000-0000-000000000000\",\n (message) => {\n updaterCalled = true;\n return message;\n },\n );\n assert.deepStrictEqual(updated, false);\n assert.deepStrictEqual(updaterCalled, false);\n assert.deepStrictEqual(await repo.countMessages(), 3);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"),\n undefined,\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"))\n ?.toJsonLd(),\n await messageC2.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"))\n ?.toJsonLd(),\n await messageD.toJsonLd(),\n );\n\n const updated2 = await repo.updateMessage(\n \"01942e9c-9000-7480-a553-7a6ce737ce14\",\n (_) => undefined,\n );\n assert.deepStrictEqual(updated2, false);\n assert.deepStrictEqual(await repo.countMessages(), 3);\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01941f29-7c00-7fe8-ab0a-7b593990a3c0\"))\n ?.toJsonLd(),\n await messageA.toJsonLd(),\n );\n assert.deepStrictEqual(\n await repo.getMessage(\"0194244f-d800-7873-8993-ef71ccd47306\"),\n undefined,\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942976-3400-7f34-872e-2cbf0f9eeac4\"))\n ?.toJsonLd(),\n await messageC2.toJsonLd(),\n );\n assert.deepStrictEqual(\n await (await repo.getMessage(\"01942e9c-9000-7480-a553-7a6ce737ce14\"))\n ?.toJsonLd(),\n await messageD.toJsonLd(),\n );\n });\n\n test(\"followers\", async () => {\n const followerA = new Person({\n id: new URL(\"https://example.com/ap/actor/john\"),\n preferredUsername: \"john\",\n });\n const followFromA = new URL(\n \"https://example.com/ap/follow/be2da56a-0ea3-4a6a-9dff-2a1837be67e0\",\n );\n const followerB = new Person({\n id: new URL(\"https://example.com/ap/actor/jane\"),\n preferredUsername: \"jane\",\n });\n const followFromB = new URL(\n \"https://example.com/ap/follow/8b76286d-5eef-4f02-8a16-080ff2b0e2ca\",\n );\n\n assert.deepStrictEqual(await repo.countFollowers(), 0);\n assert.deepStrictEqual(await repo.hasFollower(followerA.id!), false);\n assert.deepStrictEqual(await repo.hasFollower(followerB.id!), false);\n assert.deepStrictEqual(await Array.fromAsync(repo.getFollowers()), []);\n\n await repo.addFollower(followFromA, followerA);\n assert.deepStrictEqual(await repo.countFollowers(), 1);\n assert.ok(await repo.hasFollower(followerA.id!));\n assert.deepStrictEqual(await repo.hasFollower(followerB.id!), false);\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getFollowers())).map((f) => f.toJsonLd()),\n ),\n [await followerA.toJsonLd()],\n );\n\n await repo.addFollower(followFromB, followerB);\n assert.deepStrictEqual(await repo.countFollowers(), 2);\n assert.ok(await repo.hasFollower(followerA.id!));\n assert.ok(await repo.hasFollower(followerB.id!));\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getFollowers())).map((f) => f.toJsonLd()),\n ),\n [await followerA.toJsonLd(), await followerB.toJsonLd()],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getFollowers({ offset: 1 }))).map((f) =>\n f.toJsonLd()\n ),\n ),\n [await followerB.toJsonLd()],\n );\n assert.deepStrictEqual(\n await Promise.all(\n (await Array.fromAsync(repo.getFollowers({ limit: 1 }))).map((f) =>\n f.toJsonLd()\n ),\n ),\n [await followerA.toJsonLd()],\n );\n\n assert.deepStrictEqual(\n await repo.removeFollower(followFromA, followerB.id!),\n undefined,\n );\n assert.deepStrictEqual(\n await repo.removeFollower(followFromB, followerA.id!),\n undefined,\n );\n assert.deepStrictEqual(await repo.countFollowers(), 2);\n assert.ok(await repo.hasFollower(followerA.id!));\n assert.ok(await repo.hasFollower(followerB.id!));\n\n await repo.removeFollower(followFromA, followerA.id!);\n assert.deepStrictEqual(await repo.countFollowers(), 1);\n assert.deepStrictEqual(await repo.hasFollower(followerA.id!), false);\n assert.ok(await repo.hasFollower(followerB.id!));\n\n await repo.removeFollower(followFromB, followerB.id!);\n assert.deepStrictEqual(await repo.countFollowers(), 0);\n assert.deepStrictEqual(await repo.hasFollower(followerA.id!), false);\n assert.deepStrictEqual(await repo.hasFollower(followerB.id!), false);\n });\n\n test(\"sent follows\", async () => {\n const follow = new Follow({\n id: new URL(\n \"https://example.com/ap/follow/03a395a2-353a-4894-afdb-2cab31a7b004\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: new URL(\"https://example.com/ap/actor/john\"),\n });\n\n assert.deepStrictEqual(\n await repo.getSentFollow(\"03a395a2-353a-4894-afdb-2cab31a7b004\"),\n undefined,\n );\n\n await repo.addSentFollow(\"03a395a2-353a-4894-afdb-2cab31a7b004\", follow);\n assert.deepStrictEqual(\n await (await repo.getSentFollow(\"03a395a2-353a-4894-afdb-2cab31a7b004\"))\n ?.toJsonLd(),\n await follow.toJsonLd(),\n );\n\n await repo.removeSentFollow(\"03a395a2-353a-4894-afdb-2cab31a7b004\");\n assert.deepStrictEqual(\n await repo.getSentFollow(\"03a395a2-353a-4894-afdb-2cab31a7b004\"),\n undefined,\n );\n });\n\n test(\"followees\", async () => {\n const followeeId = new URL(\"https://example.com/ap/actor/john\");\n const follow = new Follow({\n id: new URL(\n \"https://example.com/ap/follow/03a395a2-353a-4894-afdb-2cab31a7b004\",\n ),\n actor: new URL(\"https://example.com/ap/actor/bot\"),\n object: followeeId,\n });\n\n assert.deepStrictEqual(await repo.getFollowee(followeeId), undefined);\n\n await repo.addFollowee(followeeId, follow);\n assert.deepStrictEqual(\n await (await repo.getFollowee(followeeId))?.toJsonLd(),\n await follow.toJsonLd(),\n );\n\n await repo.removeFollowee(followeeId);\n assert.deepStrictEqual(await repo.getFollowee(followeeId), undefined);\n });\n\n test(\"poll voting\", async () => {\n const messageId1 = \"01945678-1234-7890-abcd-ef0123456789\";\n const messageId2 = \"01945678-5678-7890-abcd-ef0123456789\";\n const voter1 = new URL(\"https://example.com/ap/actor/alice\");\n const voter2 = new URL(\"https://example.com/ap/actor/bob\");\n const voter3 = new URL(\"https://example.com/ap/actor/charlie\");\n\n // Initially, no votes exist\n assert.deepStrictEqual(await repo.countVoters(messageId1), 0);\n assert.deepStrictEqual(await repo.countVotes(messageId1), {});\n assert.deepStrictEqual(await repo.countVoters(messageId2), 0);\n assert.deepStrictEqual(await repo.countVotes(messageId2), {});\n\n // Single voter, single option\n await repo.vote(messageId1, voter1, \"option1\");\n assert.deepStrictEqual(await repo.countVoters(messageId1), 1);\n assert.deepStrictEqual(await repo.countVotes(messageId1), {\n \"option1\": 1,\n });\n\n // Same voter votes for same option again (should be ignored)\n await repo.vote(messageId1, voter1, \"option1\");\n assert.deepStrictEqual(await repo.countVoters(messageId1), 1);\n assert.deepStrictEqual(await repo.countVotes(messageId1), {\n \"option1\": 1,\n });\n\n // Same voter votes for different option (multiple choice)\n await repo.vote(messageId1, voter1, \"option2\");\n assert.deepStrictEqual(await repo.countVoters(messageId1), 1);\n assert.deepStrictEqual(await repo.countVotes(messageId1), {\n \"option1\": 1,\n \"option2\": 1,\n });\n\n // Different voter votes for same option\n await repo.vote(messageId1, voter2, \"option1\");\n assert.deepStrictEqual(await repo.countVoters(messageId1), 2);\n assert.deepStrictEqual(await repo.countVotes(messageId1), {\n \"option1\": 2,\n \"option2\": 1,\n });\n\n // Third voter votes for new option\n await repo.vote(messageId1, voter3, \"option3\");\n assert.deepStrictEqual(await repo.countVoters(messageId1), 3);\n assert.deepStrictEqual(await repo.countVotes(messageId1), {\n \"option1\": 2,\n \"option2\": 1,\n \"option3\": 1,\n });\n\n // Votes for different message should be separate\n await repo.vote(messageId2, voter1, \"optionA\");\n await repo.vote(messageId2, voter2, \"optionB\");\n assert.deepStrictEqual(await repo.countVoters(messageId2), 2);\n assert.deepStrictEqual(await repo.countVotes(messageId2), {\n \"optionA\": 1,\n \"optionB\": 1,\n });\n\n // Original message votes should remain unchanged\n assert.deepStrictEqual(await repo.countVoters(messageId1), 3);\n assert.deepStrictEqual(await repo.countVotes(messageId1), {\n \"option1\": 2,\n \"option2\": 1,\n \"option3\": 1,\n });\n\n // Test with empty options (edge case)\n await repo.vote(messageId1, voter1, \"\");\n assert.deepStrictEqual(await repo.countVoters(messageId1), 3);\n assert.deepStrictEqual(await repo.countVotes(messageId1), {\n \"option1\": 2,\n \"option2\": 1,\n \"option3\": 1,\n \"\": 1,\n });\n });\n });\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-impl.d.ts","names":[],"sources":["../src/session-impl.ts"],"sourcesContent":[],"mappings":";;;;;;;;;UAkDiB,gDACP,sBAAsB;gBAChB,QAAQ,cAAc;;UAGrB,6CACL,oCAGV,+BAA+B,GAAG,eAClC,0BAA0B;UAGX,4DAEb,kCAAkC,eAClC,mCAAmC,UAAU,eAhBjD;AAA0C,cAmB7B,WAnB6B,CAAA,YAAA,CAAA,YAmBQ,OAnBR,CAmBgB,YAnBhB,CAAA,CAAA;EAAA,SACV,GAAA,EAmBhB,OAnBgB,CAmBR,YAnBQ,CAAA;EAAY,SACpB,OAAA,EAmBJ,OAnBI,CAmBI,YAnBJ,CAAA;EAAY,WAAE,CAAA,GAAA,EAqBnB,OArBmB,CAqBX,YArBW,CAAA,EAAA,OAAA,EAqBa,OArBb,CAqBqB,YArBrB,CAAA;EAAY,IAAlC,OAAA,CAAA,CAAA,EA0BH,GA1BG;EAAO,IADb,WAAA,CAAA,CAAA,EAAA,IAAA,MAAA,IAAA,MAAA,EAAA;EAAqB,QAAA,CAAA,CAAA,EAmCX,OAnCW,CAmCH,KAnCG,CAAA;EAId,MAAA,CAAA,KAAA,EAmCK,KAnCL,GAmCa,GAnCb,GAAA,MAAA,CAAA,EAmC4B,OAnCM,CAAA,IAAA,CAAA;EAAA,QAAA,CAAA,KAAA,EAgF3B,KAhF2B,GAgFnB,GAhFmB,GAAA,MAAA,CAAA,EAgFJ,OAhFI,CAAA,IAAA,CAAA;EAAA,OACvC,CAAA,KAAA,EA4HW,KA5HX,GA4HmB,GA5HnB,GAAA,MAAA,CAAA,EA4HkC,OA5HlC,CAAA,OAAA,CAAA;EAAY,OAGS,CAAA,OAAA,EA0JpB,IA1JoB,CAAA,OAAA,EA0JN,YA1JM,CAAA,EAAA,OAAA,CAAA,EA2JnB,yBA3JmB,CA2JO,YA3JP,CAAA,CAAA,EA4J5B,OA5J4B,CA4JpB,iBA5JoB,CA4JF,IA5JE,EA4JI,YA5JJ,CAAA,CAAA;EAAC,OAAE,CAAA,UA6JV,YA7JU,CAAA,CAAA,OAAA,EA8JvB,IA9JuB,CAAA,OAAA,EA8JT,YA9JS,CAAA,EAAA,OAAA,EA+JvB,kCA/JuB,CA+JY,CA/JZ,EA+Je,YA/Jf,CAAA,CAAA,EAgK/B,OAhK+B,CAgKvB,iBAhKuB,CAgKL,CAhKK,EAgKF,YAhKE,CAAA,CAAA;EAAY,OACpB,CAAA,OAAA,EAiKf,IAjKe,CAAA,OAAA,EAiKD,YAjKC,CAAA,EAAA,OAAA,EAkKf,qCAlKe,CAkKuB,YAlKvB,CAAA,CAAA,EAmKvB,OAnKuB,CAmKf,iBAnKe,CAmKG,QAnKH,EAmKa,YAnKb,CAAA,CAAA;EAAY,SADtC,CAAA,OAAA,CAAA,
|
|
1
|
+
{"version":3,"file":"session-impl.d.ts","names":[],"sources":["../src/session-impl.ts"],"sourcesContent":[],"mappings":";;;;;;;;;UAkDiB,gDACP,sBAAsB;gBAChB,QAAQ,cAAc;;UAGrB,6CACL,oCAGV,+BAA+B,GAAG,eAClC,0BAA0B;UAGX,4DAEb,kCAAkC,eAClC,mCAAmC,UAAU,eAhBjD;AAA0C,cAmB7B,WAnB6B,CAAA,YAAA,CAAA,YAmBQ,OAnBR,CAmBgB,YAnBhB,CAAA,CAAA;EAAA,SACV,GAAA,EAmBhB,OAnBgB,CAmBR,YAnBQ,CAAA;EAAY,SACpB,OAAA,EAmBJ,OAnBI,CAmBI,YAnBJ,CAAA;EAAY,WAAE,CAAA,GAAA,EAqBnB,OArBmB,CAqBX,YArBW,CAAA,EAAA,OAAA,EAqBa,OArBb,CAqBqB,YArBrB,CAAA;EAAY,IAAlC,OAAA,CAAA,CAAA,EA0BH,GA1BG;EAAO,IADb,WAAA,CAAA,CAAA,EAAA,IAAA,MAAA,IAAA,MAAA,EAAA;EAAqB,QAAA,CAAA,CAAA,EAmCX,OAnCW,CAmCH,KAnCG,CAAA;EAId,MAAA,CAAA,KAAA,EAmCK,KAnCL,GAmCa,GAnCb,GAAA,MAAA,CAAA,EAmC4B,OAnCM,CAAA,IAAA,CAAA;EAAA,QAAA,CAAA,KAAA,EAgF3B,KAhF2B,GAgFnB,GAhFmB,GAAA,MAAA,CAAA,EAgFJ,OAhFI,CAAA,IAAA,CAAA;EAAA,OACvC,CAAA,KAAA,EA4HW,KA5HX,GA4HmB,GA5HnB,GAAA,MAAA,CAAA,EA4HkC,OA5HlC,CAAA,OAAA,CAAA;EAAY,OAGS,CAAA,OAAA,EA0JpB,IA1JoB,CAAA,OAAA,EA0JN,YA1JM,CAAA,EAAA,OAAA,CAAA,EA2JnB,yBA3JmB,CA2JO,YA3JP,CAAA,CAAA,EA4J5B,OA5J4B,CA4JpB,iBA5JoB,CA4JF,IA5JE,EA4JI,YA5JJ,CAAA,CAAA;EAAC,OAAE,CAAA,UA6JV,YA7JU,CAAA,CAAA,OAAA,EA8JvB,IA9JuB,CAAA,OAAA,EA8JT,YA9JS,CAAA,EAAA,OAAA,EA+JvB,kCA/JuB,CA+JY,CA/JZ,EA+Je,YA/Jf,CAAA,CAAA,EAgK/B,OAhK+B,CAgKvB,iBAhKuB,CAgKL,CAhKK,EAgKF,YAhKE,CAAA,CAAA;EAAY,OACpB,CAAA,OAAA,EAiKf,IAjKe,CAAA,OAAA,EAiKD,YAjKC,CAAA,EAAA,OAAA,EAkKf,qCAlKe,CAkKuB,YAlKvB,CAAA,CAAA,EAmKvB,OAnKuB,CAmKf,iBAnKe,CAmKG,QAnKH,EAmKa,YAnKb,CAAA,CAAA;EAAY,SADtC,CAAA,OAAA,CAAA,EA4UW,uBA5UX,CAAA,EA6UG,aA7UH,CA6UiB,iBA7UjB,CA6UmC,YA7UnC,EA6UiD,YA7UjD,CAAA,CAAA;;AACyB"}
|
package/dist/session-impl.js
CHANGED
|
@@ -121,6 +121,9 @@ var SessionImpl = class {
|
|
|
121
121
|
let voters = null;
|
|
122
122
|
let endTime = null;
|
|
123
123
|
if ("class" in options && options.class === Question && "poll" in options) {
|
|
124
|
+
if (options.poll.options.length < 2) throw new TypeError("At least two options are required in a poll.");
|
|
125
|
+
else if (new Set(options.poll.options).size != options.poll.options.length) throw new TypeError("Duplicate options are not allowed in a poll.");
|
|
126
|
+
else if (options.poll.options.some((o) => o.trim() === "")) throw new TypeError("Poll options cannot be empty.");
|
|
124
127
|
const pollOptions = options.poll.options.map((option) => new Note$1({
|
|
125
128
|
name: option,
|
|
126
129
|
replies: new Collection({ totalItems: 0 })
|
package/dist/session-impl.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-impl.js","names":["bot: BotImpl<TContextData>","context: Context<TContextData>","actor: Actor | URL | string","actorId: URL","content: Text<\"block\", TContextData>","options:\n | SessionImplPublishOptions<TContextData>\n | SessionImplPublishOptionsWithClass<MessageClass, TContextData>\n | SessionImplPublishOptionsWithQuestion<TContextData>","Note","mentionedActorIds: URL[]","Mention","inclusiveOptions: Note[]","exclusiveOptions: Note[]","voters: number | null","endTime: Temporal.Instant | null","PUBLIC_COLLECTION","Create","cachedObjects: Record<string, Object>","promises: Promise<Object | null>[]","isActor","options: SessionGetOutboxOptions","object: Object | null"],"sources":["../src/session-impl.ts"],"sourcesContent":["// BotKit by Fedify: A framework for creating ActivityPub bots\n// Copyright (C) 2025 Hong Minhee <https://hongminhee.org/>\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as\n// published by the Free Software Foundation, either version 3 of the\n// License, or (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see <https://www.gnu.org/licenses/>.\nimport {\n type Actor,\n type Context,\n Create,\n isActor,\n LanguageString,\n Mention,\n Note,\n type Object,\n PUBLIC_COLLECTION,\n} from \"@fedify/fedify\";\nimport { Collection, Follow, Link, Undo } from \"@fedify/fedify/vocab\";\nimport { getLogger } from \"@logtape/logtape\";\nimport { encode } from \"html-entities\";\nimport { v7 as uuidv7 } from \"uuid\";\nimport type { BotImpl } from \"./bot-impl.ts\";\nimport { createMessage, isMessageObject } from \"./message-impl.ts\";\nimport {\n type AuthorizedMessage,\n type Message,\n type MessageClass,\n Question,\n} from \"./message.ts\";\nimport type { Uuid } from \"./repository.ts\";\nimport type {\n Session,\n SessionGetOutboxOptions,\n SessionPublishOptions,\n SessionPublishOptionsWithClass,\n SessionPublishOptionsWithQuestion,\n} from \"./session.ts\";\nimport type { Text } from \"./text.ts\";\n\nconst logger = getLogger([\"botkit\", \"session\"]);\n\nexport interface SessionImplPublishOptions<TContextData>\n extends SessionPublishOptions<TContextData> {\n replyTarget?: Message<MessageClass, TContextData>;\n}\n\nexport interface SessionImplPublishOptionsWithClass<\n T extends MessageClass,\n TContextData,\n> extends\n SessionPublishOptionsWithClass<T, TContextData>,\n SessionImplPublishOptions<TContextData> {\n}\n\nexport interface SessionImplPublishOptionsWithQuestion<TContextData>\n extends\n SessionPublishOptionsWithQuestion<TContextData>,\n SessionImplPublishOptionsWithClass<Question, TContextData> {\n}\n\nexport class SessionImpl<TContextData> implements Session<TContextData> {\n readonly bot: BotImpl<TContextData>;\n readonly context: Context<TContextData>;\n\n constructor(bot: BotImpl<TContextData>, context: Context<TContextData>) {\n this.bot = bot;\n this.context = context;\n }\n\n get actorId() {\n return this.context.getActorUri(this.bot.identifier);\n }\n\n get actorHandle() {\n return `@${this.bot.username}@${this.context.host}` as const;\n }\n\n async getActor(): Promise<Actor> {\n return (await this.bot.dispatchActor(this.context, this.bot.identifier))!;\n }\n\n async follow(actor: Actor | URL | string): Promise<void> {\n if (actor instanceof URL || typeof actor === \"string\") {\n if (\n actor instanceof URL && actor.href === this.actorId.href ||\n typeof actor === \"string\" &&\n (actor === this.actorId.href || actor === this.actorHandle)\n ) {\n throw new TypeError(\"The bot cannot follow itself.\");\n }\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n const object = await this.context.lookupObject(actor, { documentLoader });\n if (!isActor(object)) {\n throw new TypeError(\"The resolved object is not an Actor.\");\n }\n actor = object;\n }\n if (actor.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n } else if (actor.id.href === this.actorId.href) {\n throw new TypeError(\"The bot cannot follow itself.\");\n }\n const followee = await this.bot.repository.getFollowee(actor.id);\n if (followee != null) {\n logger.warn(\n \"The bot is already following the actor {actor}.\",\n { actor: actor.id.href },\n );\n return;\n }\n const id = uuidv7() as Uuid;\n const follow = new Follow({\n id: this.context.getObjectUri(Follow, { id }),\n actor: this.context.getActorUri(this.bot.identifier),\n object: actor.id,\n to: actor.id,\n });\n await this.bot.repository.addSentFollow(id, follow);\n await this.context.sendActivity(\n this.bot,\n actor,\n follow,\n { excludeBaseUris: [new URL(this.context.origin)] },\n );\n }\n\n async unfollow(actor: Actor | URL | string): Promise<void> {\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n if (actor instanceof URL || typeof actor === \"string\") {\n if (\n actor instanceof URL && actor.href === this.actorId.href ||\n typeof actor === \"string\" &&\n (actor === this.actorId.href || actor === this.actorHandle)\n ) {\n throw new TypeError(\"The bot cannot unfollow itself.\");\n }\n const object = await this.context.lookupObject(actor, { documentLoader });\n if (!isActor(object)) {\n throw new TypeError(\"The resolved object is not an Actor.\");\n }\n actor = object;\n }\n if (actor.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n } else if (actor.id.href === this.actorId.href) {\n throw new TypeError(\"The bot cannot unfollow itself.\");\n }\n const follow = await this.bot.repository.getFollowee(actor.id);\n if (follow == null) {\n logger.warn(\n \"The bot is not following the actor {actor}.\",\n { actor: actor.id.href },\n );\n return;\n }\n await this.bot.repository.removeFollowee(actor.id);\n if (follow.id != null && follow.objectId?.href === actor.id.href) {\n await this.context.sendActivity(\n this.bot,\n actor,\n new Undo({\n id: new URL(\"#undo\", follow.id),\n actor: this.context.getActorUri(this.bot.identifier),\n object: follow,\n to: actor.id,\n }),\n { excludeBaseUris: [new URL(this.context.origin)] },\n );\n }\n }\n\n async follows(actor: Actor | URL | string): Promise<boolean> {\n let actorId: URL;\n if (isActor(actor)) {\n if (actor.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n }\n actorId = actor.id;\n } else if (actor instanceof URL) {\n actorId = actor;\n } else {\n if (actor.startsWith(\"http://\") || actor.startsWith(\"https://\")) {\n actorId = new URL(actor);\n } else {\n if (actor === this.actorHandle) return false;\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n const object = await this.context.lookupObject(actor, {\n documentLoader,\n });\n if (!isActor(object)) {\n throw new TypeError(\"The resolved object is not an Actor.\");\n }\n if (object.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n }\n actorId = object.id;\n }\n }\n if (actorId.href === this.actorId.href) return false;\n const follow = await this.bot.repository.getFollowee(actorId);\n return follow != null;\n }\n\n async publish(\n content: Text<\"block\", TContextData>,\n options?: SessionImplPublishOptions<TContextData>,\n ): Promise<AuthorizedMessage<Note, TContextData>>;\n async publish<T extends MessageClass>(\n content: Text<\"block\", TContextData>,\n options: SessionImplPublishOptionsWithClass<T, TContextData>,\n ): Promise<AuthorizedMessage<T, TContextData>>;\n async publish(\n content: Text<\"block\", TContextData>,\n options: SessionImplPublishOptionsWithQuestion<TContextData>,\n ): Promise<AuthorizedMessage<Question, TContextData>>;\n async publish(\n content: Text<\"block\", TContextData>,\n options:\n | SessionImplPublishOptions<TContextData>\n | SessionImplPublishOptionsWithClass<MessageClass, TContextData>\n | SessionImplPublishOptionsWithQuestion<TContextData> = {},\n ): Promise<AuthorizedMessage<MessageClass, TContextData>> {\n const published = new Date();\n const id = uuidv7({ msecs: +published }) as Uuid;\n const cls = \"class\" in options ? options.class : Note;\n const visibility = options.visibility ?? \"public\";\n let contentHtml = \"\";\n for await (const chunk of content.getHtml(this)) {\n contentHtml += chunk;\n }\n const tags = await Array.fromAsync(content.getTags(this));\n const mentionedActorIds: URL[] = [];\n for (const tag of tags) {\n if (tag instanceof Mention && tag.href != null) {\n mentionedActorIds.push(tag.href);\n }\n }\n if (options.quoteTarget != null) {\n let url = options.quoteTarget.raw.url ?? options.quoteTarget.id;\n if (url instanceof Link) url = url.href ?? options.quoteTarget.id;\n contentHtml += `\\n\\n<p class=\"quote-inline\"><br>RE: <a href=\"${\n encode(url.href)\n }\">${encode(url.href)}</a></p>`;\n tags.push(\n new Link({\n mediaType:\n 'application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"',\n rel: \"https://misskey-hub.net/ns#_misskey_quote\",\n href: options.quoteTarget.id,\n name: `RE: ${url.href}`,\n }),\n );\n }\n let inclusiveOptions: Note[] = [];\n let exclusiveOptions: Note[] = [];\n let voters: number | null = null;\n let endTime: Temporal.Instant | null = null;\n if (\"class\" in options && options.class === Question && \"poll\" in options) {\n const pollOptions = options.poll.options.map((option) =>\n new Note({\n name: option,\n replies: new Collection({ totalItems: 0 }),\n })\n );\n if (options.poll.multiple) inclusiveOptions = pollOptions;\n else exclusiveOptions = pollOptions;\n voters = 0;\n endTime = options.poll.endTime;\n }\n const msg = new cls({\n id: this.context.getObjectUri<MessageClass>(cls, { id }),\n contents: options.language == null\n ? [contentHtml]\n : [new LanguageString(contentHtml, options.language), contentHtml],\n replyTarget: options.replyTarget?.id,\n quoteUrl: options.quoteTarget?.id,\n tags,\n attribution: this.context.getActorUri(this.bot.identifier),\n attachments: options.attachments ?? [],\n inclusiveOptions,\n exclusiveOptions,\n voters,\n endTime,\n tos: visibility === \"public\"\n ? [PUBLIC_COLLECTION, ...mentionedActorIds]\n : visibility === \"unlisted\" || visibility === \"followers\"\n ? [\n this.context.getFollowersUri(this.bot.identifier),\n ...mentionedActorIds,\n ]\n : mentionedActorIds,\n ccs: visibility === \"public\"\n ? [this.context.getFollowersUri(this.bot.identifier)]\n : visibility === \"unlisted\"\n ? [PUBLIC_COLLECTION]\n : [],\n published: published.toTemporalInstant(),\n url: new URL(`/message/${id}`, this.context.origin),\n });\n const activity = new Create({\n id: this.context.getObjectUri(Create, { id }),\n actors: msg.attributionIds,\n tos: msg.toIds,\n ccs: msg.ccIds,\n object: msg,\n published: published.toTemporalInstant(),\n });\n await this.bot.repository.addMessage(id, activity);\n const preferSharedInbox = visibility === \"public\" ||\n visibility === \"unlisted\" || visibility === \"followers\";\n const excludeBaseUris = [new URL(this.context.origin)];\n if (preferSharedInbox) {\n await this.context.sendActivity(\n this.bot,\n \"followers\",\n activity,\n { preferSharedInbox, excludeBaseUris },\n );\n }\n const cachedObjects: Record<string, Object> = {};\n for (const cachedObject of content.getCachedObjects()) {\n if (cachedObject.id == null) continue;\n cachedObjects[cachedObject.id.href] = cachedObject;\n }\n if (mentionedActorIds.length > 0) {\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n const promises: Promise<Object | null>[] = [];\n for (const mentionedActorId of mentionedActorIds) {\n const cachedObject = cachedObjects[mentionedActorId.href];\n const promise = cachedObject == null\n ? this.context.lookupObject(\n mentionedActorId,\n { documentLoader },\n )\n : Promise.resolve(cachedObject);\n promises.push(promise);\n }\n const objects = await Promise.all(promises);\n const mentionedActors = objects.filter(isActor);\n await this.context.sendActivity(\n this.bot,\n mentionedActors,\n activity,\n { preferSharedInbox, excludeBaseUris },\n );\n }\n if (options.replyTarget != null) {\n await this.context.sendActivity(\n this.bot,\n options.replyTarget.actor,\n activity,\n { preferSharedInbox, excludeBaseUris, fanout: \"skip\" },\n );\n }\n if (options.quoteTarget != null) {\n await this.context.sendActivity(\n this.bot,\n options.quoteTarget.actor,\n activity,\n { preferSharedInbox, excludeBaseUris, fanout: \"skip\" },\n );\n }\n return await createMessage(\n msg,\n this,\n cachedObjects,\n options.replyTarget,\n options.quoteTarget,\n true,\n );\n }\n\n async *getOutbox(\n options: SessionGetOutboxOptions = {},\n ): AsyncIterable<AuthorizedMessage<MessageClass, TContextData>> {\n for await (const activity of this.bot.repository.getMessages(options)) {\n let object: Object | null;\n try {\n object = await activity.getObject(this.context);\n } catch {\n continue;\n }\n if (object == null || !isMessageObject(object)) continue;\n const message = await createMessage(object, this, {});\n yield message;\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"session-impl.js","names":["bot: BotImpl<TContextData>","context: Context<TContextData>","actor: Actor | URL | string","actorId: URL","content: Text<\"block\", TContextData>","options:\n | SessionImplPublishOptions<TContextData>\n | SessionImplPublishOptionsWithClass<MessageClass, TContextData>\n | SessionImplPublishOptionsWithQuestion<TContextData>","Note","mentionedActorIds: URL[]","Mention","inclusiveOptions: Note[]","exclusiveOptions: Note[]","voters: number | null","endTime: Temporal.Instant | null","PUBLIC_COLLECTION","Create","cachedObjects: Record<string, Object>","promises: Promise<Object | null>[]","isActor","options: SessionGetOutboxOptions","object: Object | null"],"sources":["../src/session-impl.ts"],"sourcesContent":["// BotKit by Fedify: A framework for creating ActivityPub bots\n// Copyright (C) 2025 Hong Minhee <https://hongminhee.org/>\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as\n// published by the Free Software Foundation, either version 3 of the\n// License, or (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see <https://www.gnu.org/licenses/>.\nimport {\n type Actor,\n type Context,\n Create,\n isActor,\n LanguageString,\n Mention,\n Note,\n type Object,\n PUBLIC_COLLECTION,\n} from \"@fedify/fedify\";\nimport { Collection, Follow, Link, Undo } from \"@fedify/fedify/vocab\";\nimport { getLogger } from \"@logtape/logtape\";\nimport { encode } from \"html-entities\";\nimport { v7 as uuidv7 } from \"uuid\";\nimport type { BotImpl } from \"./bot-impl.ts\";\nimport { createMessage, isMessageObject } from \"./message-impl.ts\";\nimport {\n type AuthorizedMessage,\n type Message,\n type MessageClass,\n Question,\n} from \"./message.ts\";\nimport type { Uuid } from \"./repository.ts\";\nimport type {\n Session,\n SessionGetOutboxOptions,\n SessionPublishOptions,\n SessionPublishOptionsWithClass,\n SessionPublishOptionsWithQuestion,\n} from \"./session.ts\";\nimport type { Text } from \"./text.ts\";\n\nconst logger = getLogger([\"botkit\", \"session\"]);\n\nexport interface SessionImplPublishOptions<TContextData>\n extends SessionPublishOptions<TContextData> {\n replyTarget?: Message<MessageClass, TContextData>;\n}\n\nexport interface SessionImplPublishOptionsWithClass<\n T extends MessageClass,\n TContextData,\n> extends\n SessionPublishOptionsWithClass<T, TContextData>,\n SessionImplPublishOptions<TContextData> {\n}\n\nexport interface SessionImplPublishOptionsWithQuestion<TContextData>\n extends\n SessionPublishOptionsWithQuestion<TContextData>,\n SessionImplPublishOptionsWithClass<Question, TContextData> {\n}\n\nexport class SessionImpl<TContextData> implements Session<TContextData> {\n readonly bot: BotImpl<TContextData>;\n readonly context: Context<TContextData>;\n\n constructor(bot: BotImpl<TContextData>, context: Context<TContextData>) {\n this.bot = bot;\n this.context = context;\n }\n\n get actorId() {\n return this.context.getActorUri(this.bot.identifier);\n }\n\n get actorHandle() {\n return `@${this.bot.username}@${this.context.host}` as const;\n }\n\n async getActor(): Promise<Actor> {\n return (await this.bot.dispatchActor(this.context, this.bot.identifier))!;\n }\n\n async follow(actor: Actor | URL | string): Promise<void> {\n if (actor instanceof URL || typeof actor === \"string\") {\n if (\n actor instanceof URL && actor.href === this.actorId.href ||\n typeof actor === \"string\" &&\n (actor === this.actorId.href || actor === this.actorHandle)\n ) {\n throw new TypeError(\"The bot cannot follow itself.\");\n }\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n const object = await this.context.lookupObject(actor, { documentLoader });\n if (!isActor(object)) {\n throw new TypeError(\"The resolved object is not an Actor.\");\n }\n actor = object;\n }\n if (actor.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n } else if (actor.id.href === this.actorId.href) {\n throw new TypeError(\"The bot cannot follow itself.\");\n }\n const followee = await this.bot.repository.getFollowee(actor.id);\n if (followee != null) {\n logger.warn(\n \"The bot is already following the actor {actor}.\",\n { actor: actor.id.href },\n );\n return;\n }\n const id = uuidv7() as Uuid;\n const follow = new Follow({\n id: this.context.getObjectUri(Follow, { id }),\n actor: this.context.getActorUri(this.bot.identifier),\n object: actor.id,\n to: actor.id,\n });\n await this.bot.repository.addSentFollow(id, follow);\n await this.context.sendActivity(\n this.bot,\n actor,\n follow,\n { excludeBaseUris: [new URL(this.context.origin)] },\n );\n }\n\n async unfollow(actor: Actor | URL | string): Promise<void> {\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n if (actor instanceof URL || typeof actor === \"string\") {\n if (\n actor instanceof URL && actor.href === this.actorId.href ||\n typeof actor === \"string\" &&\n (actor === this.actorId.href || actor === this.actorHandle)\n ) {\n throw new TypeError(\"The bot cannot unfollow itself.\");\n }\n const object = await this.context.lookupObject(actor, { documentLoader });\n if (!isActor(object)) {\n throw new TypeError(\"The resolved object is not an Actor.\");\n }\n actor = object;\n }\n if (actor.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n } else if (actor.id.href === this.actorId.href) {\n throw new TypeError(\"The bot cannot unfollow itself.\");\n }\n const follow = await this.bot.repository.getFollowee(actor.id);\n if (follow == null) {\n logger.warn(\n \"The bot is not following the actor {actor}.\",\n { actor: actor.id.href },\n );\n return;\n }\n await this.bot.repository.removeFollowee(actor.id);\n if (follow.id != null && follow.objectId?.href === actor.id.href) {\n await this.context.sendActivity(\n this.bot,\n actor,\n new Undo({\n id: new URL(\"#undo\", follow.id),\n actor: this.context.getActorUri(this.bot.identifier),\n object: follow,\n to: actor.id,\n }),\n { excludeBaseUris: [new URL(this.context.origin)] },\n );\n }\n }\n\n async follows(actor: Actor | URL | string): Promise<boolean> {\n let actorId: URL;\n if (isActor(actor)) {\n if (actor.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n }\n actorId = actor.id;\n } else if (actor instanceof URL) {\n actorId = actor;\n } else {\n if (actor.startsWith(\"http://\") || actor.startsWith(\"https://\")) {\n actorId = new URL(actor);\n } else {\n if (actor === this.actorHandle) return false;\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n const object = await this.context.lookupObject(actor, {\n documentLoader,\n });\n if (!isActor(object)) {\n throw new TypeError(\"The resolved object is not an Actor.\");\n }\n if (object.id == null) {\n throw new TypeError(\"The actor does not have an ID.\");\n }\n actorId = object.id;\n }\n }\n if (actorId.href === this.actorId.href) return false;\n const follow = await this.bot.repository.getFollowee(actorId);\n return follow != null;\n }\n\n async publish(\n content: Text<\"block\", TContextData>,\n options?: SessionImplPublishOptions<TContextData>,\n ): Promise<AuthorizedMessage<Note, TContextData>>;\n async publish<T extends MessageClass>(\n content: Text<\"block\", TContextData>,\n options: SessionImplPublishOptionsWithClass<T, TContextData>,\n ): Promise<AuthorizedMessage<T, TContextData>>;\n async publish(\n content: Text<\"block\", TContextData>,\n options: SessionImplPublishOptionsWithQuestion<TContextData>,\n ): Promise<AuthorizedMessage<Question, TContextData>>;\n async publish(\n content: Text<\"block\", TContextData>,\n options:\n | SessionImplPublishOptions<TContextData>\n | SessionImplPublishOptionsWithClass<MessageClass, TContextData>\n | SessionImplPublishOptionsWithQuestion<TContextData> = {},\n ): Promise<AuthorizedMessage<MessageClass, TContextData>> {\n const published = new Date();\n const id = uuidv7({ msecs: +published }) as Uuid;\n const cls = \"class\" in options ? options.class : Note;\n const visibility = options.visibility ?? \"public\";\n let contentHtml = \"\";\n for await (const chunk of content.getHtml(this)) {\n contentHtml += chunk;\n }\n const tags = await Array.fromAsync(content.getTags(this));\n const mentionedActorIds: URL[] = [];\n for (const tag of tags) {\n if (tag instanceof Mention && tag.href != null) {\n mentionedActorIds.push(tag.href);\n }\n }\n if (options.quoteTarget != null) {\n let url = options.quoteTarget.raw.url ?? options.quoteTarget.id;\n if (url instanceof Link) url = url.href ?? options.quoteTarget.id;\n contentHtml += `\\n\\n<p class=\"quote-inline\"><br>RE: <a href=\"${\n encode(url.href)\n }\">${encode(url.href)}</a></p>`;\n tags.push(\n new Link({\n mediaType:\n 'application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"',\n rel: \"https://misskey-hub.net/ns#_misskey_quote\",\n href: options.quoteTarget.id,\n name: `RE: ${url.href}`,\n }),\n );\n }\n let inclusiveOptions: Note[] = [];\n let exclusiveOptions: Note[] = [];\n let voters: number | null = null;\n let endTime: Temporal.Instant | null = null;\n if (\"class\" in options && options.class === Question && \"poll\" in options) {\n if (options.poll.options.length < 2) {\n throw new TypeError(\"At least two options are required in a poll.\");\n } else if (\n new Set(options.poll.options).size != options.poll.options.length\n ) {\n throw new TypeError(\"Duplicate options are not allowed in a poll.\");\n } else if (options.poll.options.some((o) => o.trim() === \"\")) {\n throw new TypeError(\"Poll options cannot be empty.\");\n }\n const pollOptions = options.poll.options.map((option) =>\n new Note({\n name: option,\n replies: new Collection({ totalItems: 0 }),\n })\n );\n if (options.poll.multiple) inclusiveOptions = pollOptions;\n else exclusiveOptions = pollOptions;\n voters = 0;\n endTime = options.poll.endTime;\n }\n const msg = new cls({\n id: this.context.getObjectUri<MessageClass>(cls, { id }),\n contents: options.language == null\n ? [contentHtml]\n : [new LanguageString(contentHtml, options.language), contentHtml],\n replyTarget: options.replyTarget?.id,\n quoteUrl: options.quoteTarget?.id,\n tags,\n attribution: this.context.getActorUri(this.bot.identifier),\n attachments: options.attachments ?? [],\n inclusiveOptions,\n exclusiveOptions,\n voters,\n endTime,\n tos: visibility === \"public\"\n ? [PUBLIC_COLLECTION, ...mentionedActorIds]\n : visibility === \"unlisted\" || visibility === \"followers\"\n ? [\n this.context.getFollowersUri(this.bot.identifier),\n ...mentionedActorIds,\n ]\n : mentionedActorIds,\n ccs: visibility === \"public\"\n ? [this.context.getFollowersUri(this.bot.identifier)]\n : visibility === \"unlisted\"\n ? [PUBLIC_COLLECTION]\n : [],\n published: published.toTemporalInstant(),\n url: new URL(`/message/${id}`, this.context.origin),\n });\n const activity = new Create({\n id: this.context.getObjectUri(Create, { id }),\n actors: msg.attributionIds,\n tos: msg.toIds,\n ccs: msg.ccIds,\n object: msg,\n published: published.toTemporalInstant(),\n });\n await this.bot.repository.addMessage(id, activity);\n const preferSharedInbox = visibility === \"public\" ||\n visibility === \"unlisted\" || visibility === \"followers\";\n const excludeBaseUris = [new URL(this.context.origin)];\n if (preferSharedInbox) {\n await this.context.sendActivity(\n this.bot,\n \"followers\",\n activity,\n { preferSharedInbox, excludeBaseUris },\n );\n }\n const cachedObjects: Record<string, Object> = {};\n for (const cachedObject of content.getCachedObjects()) {\n if (cachedObject.id == null) continue;\n cachedObjects[cachedObject.id.href] = cachedObject;\n }\n if (mentionedActorIds.length > 0) {\n const documentLoader = await this.context.getDocumentLoader(this.bot);\n const promises: Promise<Object | null>[] = [];\n for (const mentionedActorId of mentionedActorIds) {\n const cachedObject = cachedObjects[mentionedActorId.href];\n const promise = cachedObject == null\n ? this.context.lookupObject(\n mentionedActorId,\n { documentLoader },\n )\n : Promise.resolve(cachedObject);\n promises.push(promise);\n }\n const objects = await Promise.all(promises);\n const mentionedActors = objects.filter(isActor);\n await this.context.sendActivity(\n this.bot,\n mentionedActors,\n activity,\n { preferSharedInbox, excludeBaseUris },\n );\n }\n if (options.replyTarget != null) {\n await this.context.sendActivity(\n this.bot,\n options.replyTarget.actor,\n activity,\n { preferSharedInbox, excludeBaseUris, fanout: \"skip\" },\n );\n }\n if (options.quoteTarget != null) {\n await this.context.sendActivity(\n this.bot,\n options.quoteTarget.actor,\n activity,\n { preferSharedInbox, excludeBaseUris, fanout: \"skip\" },\n );\n }\n return await createMessage(\n msg,\n this,\n cachedObjects,\n options.replyTarget,\n options.quoteTarget,\n true,\n );\n }\n\n async *getOutbox(\n options: SessionGetOutboxOptions = {},\n ): AsyncIterable<AuthorizedMessage<MessageClass, TContextData>> {\n for await (const activity of this.bot.repository.getMessages(options)) {\n let object: Object | null;\n try {\n object = await activity.getObject(this.context);\n } catch {\n continue;\n }\n if (object == null || !isMessageObject(object)) continue;\n const message = await createMessage(object, this, {});\n yield message;\n }\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fedify/botkit",
|
|
3
|
-
"version": "0.3.0-dev.
|
|
3
|
+
"version": "0.3.0-dev.117+4eae51f5",
|
|
4
4
|
"description": "A framework for creating ActivityPub bots",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"author": {
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"README.md"
|
|
129
129
|
],
|
|
130
130
|
"dependencies": {
|
|
131
|
-
"@fedify/fedify": "^1.
|
|
131
|
+
"@fedify/fedify": "^1.8.0-dev.910",
|
|
132
132
|
"@fedify/markdown-it-hashtag": "^0.3.0",
|
|
133
133
|
"@fedify/markdown-it-mention": "^0.3.0",
|
|
134
134
|
"@js-temporal/polyfill": "^0.5.1",
|