@pkcprotocol/pkc-js 0.0.11
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/LICENSE +339 -0
- package/README.md +1663 -0
- package/dist/browser/challenges.d.ts +1 -0
- package/dist/browser/challenges.js +2 -0
- package/dist/browser/challenges.js.map +1 -0
- package/dist/browser/clients/base-client-manager.d.ts +126 -0
- package/dist/browser/clients/base-client-manager.js +673 -0
- package/dist/browser/clients/base-client-manager.js.map +1 -0
- package/dist/browser/clients/name-resolver-client.d.ts +8 -0
- package/dist/browser/clients/name-resolver-client.js +10 -0
- package/dist/browser/clients/name-resolver-client.js.map +1 -0
- package/dist/browser/clients/pkc-typed-emitter.d.ts +9 -0
- package/dist/browser/clients/pkc-typed-emitter.js +52 -0
- package/dist/browser/clients/pkc-typed-emitter.js.map +1 -0
- package/dist/browser/clients/rpc-client/decode-rpc-response-util.d.ts +8 -0
- package/dist/browser/clients/rpc-client/decode-rpc-response-util.js +53 -0
- package/dist/browser/clients/rpc-client/decode-rpc-response-util.js.map +1 -0
- package/dist/browser/clients/rpc-client/pkc-rpc-client.d.ts +68 -0
- package/dist/browser/clients/rpc-client/pkc-rpc-client.js +404 -0
- package/dist/browser/clients/rpc-client/pkc-rpc-client.js.map +1 -0
- package/dist/browser/clients/rpc-client/rpc-schema-util.d.ts +147 -0
- package/dist/browser/clients/rpc-client/rpc-schema-util.js +11 -0
- package/dist/browser/clients/rpc-client/rpc-schema-util.js.map +1 -0
- package/dist/browser/clients/rpc-client/schema.d.ts +433 -0
- package/dist/browser/clients/rpc-client/schema.js +49 -0
- package/dist/browser/clients/rpc-client/schema.js.map +1 -0
- package/dist/browser/clients/rpc-client/types.d.ts +8 -0
- package/dist/browser/clients/rpc-client/types.js +2 -0
- package/dist/browser/clients/rpc-client/types.js.map +1 -0
- package/dist/browser/community/community-client-manager.d.ts +60 -0
- package/dist/browser/community/community-client-manager.js +717 -0
- package/dist/browser/community/community-client-manager.js.map +1 -0
- package/dist/browser/community/community-clients.d.ts +18 -0
- package/dist/browser/community/community-clients.js +12 -0
- package/dist/browser/community/community-clients.js.map +1 -0
- package/dist/browser/community/community-wire.d.ts +20 -0
- package/dist/browser/community/community-wire.js +38 -0
- package/dist/browser/community/community-wire.js.map +1 -0
- package/dist/browser/community/remote-community.d.ts +110 -0
- package/dist/browser/community/remote-community.js +555 -0
- package/dist/browser/community/remote-community.js.map +1 -0
- package/dist/browser/community/rpc-local-community.d.ts +41 -0
- package/dist/browser/community/rpc-local-community.js +289 -0
- package/dist/browser/community/rpc-local-community.js.map +1 -0
- package/dist/browser/community/rpc-remote-community.d.ts +18 -0
- package/dist/browser/community/rpc-remote-community.js +286 -0
- package/dist/browser/community/rpc-remote-community.js.map +1 -0
- package/dist/browser/community/schema.d.ts +4217 -0
- package/dist/browser/community/schema.js +289 -0
- package/dist/browser/community/schema.js.map +1 -0
- package/dist/browser/community/types.d.ts +135 -0
- package/dist/browser/community/types.js +2 -0
- package/dist/browser/community/types.js.map +1 -0
- package/dist/browser/constants.d.ts +6 -0
- package/dist/browser/constants.js +9 -0
- package/dist/browser/constants.js.map +1 -0
- package/dist/browser/decorator-util.d.ts +1 -0
- package/dist/browser/decorator-util.js +35 -0
- package/dist/browser/decorator-util.js.map +1 -0
- package/dist/browser/errors.d.ts +343 -0
- package/dist/browser/errors.js +358 -0
- package/dist/browser/errors.js.map +1 -0
- package/dist/browser/general-util/limited-set.d.ts +15 -0
- package/dist/browser/general-util/limited-set.js +66 -0
- package/dist/browser/general-util/limited-set.js.map +1 -0
- package/dist/browser/generated-version.d.ts +1 -0
- package/dist/browser/generated-version.js +3 -0
- package/dist/browser/generated-version.js.map +1 -0
- package/dist/browser/generic-state-client.d.ts +6 -0
- package/dist/browser/generic-state-client.js +11 -0
- package/dist/browser/generic-state-client.js.map +1 -0
- package/dist/browser/helia/helia-for-pkc.d.ts +3 -0
- package/dist/browser/helia/helia-for-pkc.js +255 -0
- package/dist/browser/helia/helia-for-pkc.js.map +1 -0
- package/dist/browser/helia/ipns-over-pubsub-with-fetch.d.ts +36 -0
- package/dist/browser/helia/ipns-over-pubsub-with-fetch.js +229 -0
- package/dist/browser/helia/ipns-over-pubsub-with-fetch.js.map +1 -0
- package/dist/browser/helia/libp2pjsClient.d.ts +27 -0
- package/dist/browser/helia/libp2pjsClient.js +15 -0
- package/dist/browser/helia/libp2pjsClient.js.map +1 -0
- package/dist/browser/helia/types.d.ts +19 -0
- package/dist/browser/helia/types.js +2 -0
- package/dist/browser/helia/types.js.map +1 -0
- package/dist/browser/helia/util.d.ts +13 -0
- package/dist/browser/helia/util.js +98 -0
- package/dist/browser/helia/util.js.map +1 -0
- package/dist/browser/index.d.ts +244 -0
- package/dist/browser/index.js +36 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/logger.d.ts +12 -0
- package/dist/browser/logger.js +11 -0
- package/dist/browser/logger.js.map +1 -0
- package/dist/browser/pages/pages-client-manager.d.ts +159 -0
- package/dist/browser/pages/pages-client-manager.js +334 -0
- package/dist/browser/pages/pages-client-manager.js.map +1 -0
- package/dist/browser/pages/pages-clients.d.ts +11 -0
- package/dist/browser/pages/pages-clients.js +10 -0
- package/dist/browser/pages/pages-clients.js.map +1 -0
- package/dist/browser/pages/pages.d.ts +107 -0
- package/dist/browser/pages/pages.js +262 -0
- package/dist/browser/pages/pages.js.map +1 -0
- package/dist/browser/pages/schema-util.d.ts +3 -0
- package/dist/browser/pages/schema-util.js +3 -0
- package/dist/browser/pages/schema-util.js.map +1 -0
- package/dist/browser/pages/schema.d.ts +719 -0
- package/dist/browser/pages/schema.js +32 -0
- package/dist/browser/pages/schema.js.map +1 -0
- package/dist/browser/pages/types.d.ts +44 -0
- package/dist/browser/pages/types.js +2 -0
- package/dist/browser/pages/types.js.map +1 -0
- package/dist/browser/pages/util.d.ts +56 -0
- package/dist/browser/pages/util.js +446 -0
- package/dist/browser/pages/util.js.map +1 -0
- package/dist/browser/pkc/pkc-client-manager.d.ts +44 -0
- package/dist/browser/pkc/pkc-client-manager.js +156 -0
- package/dist/browser/pkc/pkc-client-manager.js.map +1 -0
- package/dist/browser/pkc/pkc-clients.d.ts +11 -0
- package/dist/browser/pkc/pkc-clients.js +8 -0
- package/dist/browser/pkc/pkc-clients.js.map +1 -0
- package/dist/browser/pkc/pkc-with-rpc-client.d.ts +19 -0
- package/dist/browser/pkc/pkc-with-rpc-client.js +128 -0
- package/dist/browser/pkc/pkc-with-rpc-client.js.map +1 -0
- package/dist/browser/pkc/pkc.d.ts +137 -0
- package/dist/browser/pkc/pkc.js +888 -0
- package/dist/browser/pkc/pkc.js.map +1 -0
- package/dist/browser/pkc/tracked-instance-registry-util.d.ts +44 -0
- package/dist/browser/pkc/tracked-instance-registry-util.js +106 -0
- package/dist/browser/pkc/tracked-instance-registry-util.js.map +1 -0
- package/dist/browser/pkc/tracked-instance-registry.d.ts +18 -0
- package/dist/browser/pkc/tracked-instance-registry.js +134 -0
- package/dist/browser/pkc/tracked-instance-registry.js.map +1 -0
- package/dist/browser/pkc-error.d.ts +65 -0
- package/dist/browser/pkc-error.js +137 -0
- package/dist/browser/pkc-error.js.map +1 -0
- package/dist/browser/publications/comment/comment-client-manager.d.ts +86 -0
- package/dist/browser/publications/comment/comment-client-manager.js +908 -0
- package/dist/browser/publications/comment/comment-client-manager.js.map +1 -0
- package/dist/browser/publications/comment/comment-clients.d.ts +19 -0
- package/dist/browser/publications/comment/comment-clients.js +12 -0
- package/dist/browser/publications/comment/comment-clients.js.map +1 -0
- package/dist/browser/publications/comment/comment-util.d.ts +10 -0
- package/dist/browser/publications/comment/comment-util.js +202 -0
- package/dist/browser/publications/comment/comment-util.js.map +1 -0
- package/dist/browser/publications/comment/comment.d.ts +147 -0
- package/dist/browser/publications/comment/comment.js +1044 -0
- package/dist/browser/publications/comment/comment.js.map +1 -0
- package/dist/browser/publications/comment/schema.d.ts +1237 -0
- package/dist/browser/publications/comment/schema.js +184 -0
- package/dist/browser/publications/comment/schema.js.map +1 -0
- package/dist/browser/publications/comment/types.d.ts +100 -0
- package/dist/browser/publications/comment/types.js +2 -0
- package/dist/browser/publications/comment/types.js.map +1 -0
- package/dist/browser/publications/comment-edit/comment-edit.d.ts +41 -0
- package/dist/browser/publications/comment-edit/comment-edit.js +63 -0
- package/dist/browser/publications/comment-edit/comment-edit.js.map +1 -0
- package/dist/browser/publications/comment-edit/schema.d.ts +295 -0
- package/dist/browser/publications/comment-edit/schema.js +55 -0
- package/dist/browser/publications/comment-edit/schema.js.map +1 -0
- package/dist/browser/publications/comment-edit/types.d.ts +25 -0
- package/dist/browser/publications/comment-edit/types.js +2 -0
- package/dist/browser/publications/comment-edit/types.js.map +1 -0
- package/dist/browser/publications/comment-moderation/comment-moderation.d.ts +36 -0
- package/dist/browser/publications/comment-moderation/comment-moderation.js +53 -0
- package/dist/browser/publications/comment-moderation/comment-moderation.js.map +1 -0
- package/dist/browser/publications/comment-moderation/schema.d.ts +315 -0
- package/dist/browser/publications/comment-moderation/schema.js +62 -0
- package/dist/browser/publications/comment-moderation/schema.js.map +1 -0
- package/dist/browser/publications/comment-moderation/types.d.ts +22 -0
- package/dist/browser/publications/comment-moderation/types.js +2 -0
- package/dist/browser/publications/comment-moderation/types.js.map +1 -0
- package/dist/browser/publications/community-edit/community-edit.d.ts +35 -0
- package/dist/browser/publications/community-edit/community-edit.js +50 -0
- package/dist/browser/publications/community-edit/community-edit.js.map +1 -0
- package/dist/browser/publications/community-edit/schema.d.ts +467 -0
- package/dist/browser/publications/community-edit/schema.js +36 -0
- package/dist/browser/publications/community-edit/schema.js.map +1 -0
- package/dist/browser/publications/community-edit/types.d.ts +19 -0
- package/dist/browser/publications/community-edit/types.js +2 -0
- package/dist/browser/publications/community-edit/types.js.map +1 -0
- package/dist/browser/publications/publication-author.d.ts +22 -0
- package/dist/browser/publications/publication-author.js +66 -0
- package/dist/browser/publications/publication-author.js.map +1 -0
- package/dist/browser/publications/publication-client-manager.d.ts +62 -0
- package/dist/browser/publications/publication-client-manager.js +257 -0
- package/dist/browser/publications/publication-client-manager.js.map +1 -0
- package/dist/browser/publications/publication-clients.d.ts +19 -0
- package/dist/browser/publications/publication-clients.js +12 -0
- package/dist/browser/publications/publication-clients.js.map +1 -0
- package/dist/browser/publications/publication-community.d.ts +55 -0
- package/dist/browser/publications/publication-community.js +87 -0
- package/dist/browser/publications/publication-community.js.map +1 -0
- package/dist/browser/publications/publication.d.ts +120 -0
- package/dist/browser/publications/publication.js +950 -0
- package/dist/browser/publications/publication.js.map +1 -0
- package/dist/browser/publications/types.d.ts +26 -0
- package/dist/browser/publications/types.js +2 -0
- package/dist/browser/publications/types.js.map +1 -0
- package/dist/browser/publications/vote/schema.d.ts +150 -0
- package/dist/browser/publications/vote/schema.js +44 -0
- package/dist/browser/publications/vote/schema.js.map +1 -0
- package/dist/browser/publications/vote/types.d.ts +21 -0
- package/dist/browser/publications/vote/types.js +2 -0
- package/dist/browser/publications/vote/types.js.map +1 -0
- package/dist/browser/publications/vote/vote.d.ts +36 -0
- package/dist/browser/publications/vote/vote.js +49 -0
- package/dist/browser/publications/vote/vote.js.map +1 -0
- package/dist/browser/pubsub-messages/schema.d.ts +964 -0
- package/dist/browser/pubsub-messages/schema.js +98 -0
- package/dist/browser/pubsub-messages/schema.js.map +1 -0
- package/dist/browser/pubsub-messages/types.d.ts +81 -0
- package/dist/browser/pubsub-messages/types.js +2 -0
- package/dist/browser/pubsub-messages/types.js.map +1 -0
- package/dist/browser/rpc/src/index.d.ts +483 -0
- package/dist/browser/rpc/src/index.js +1267 -0
- package/dist/browser/rpc/src/index.js.map +1 -0
- package/dist/browser/rpc/src/json-rpc-util.d.ts +1 -0
- package/dist/browser/rpc/src/json-rpc-util.js +19 -0
- package/dist/browser/rpc/src/json-rpc-util.js.map +1 -0
- package/dist/browser/rpc/src/lib/pkc-js/index.d.ts +132 -0
- package/dist/browser/rpc/src/lib/pkc-js/index.js +29 -0
- package/dist/browser/rpc/src/lib/pkc-js/index.js.map +1 -0
- package/dist/browser/rpc/src/lib/pkc-js/pkc-js-mock.d.ts +1 -0
- package/dist/browser/rpc/src/lib/pkc-js/pkc-js-mock.js +472 -0
- package/dist/browser/rpc/src/lib/pkc-js/pkc-js-mock.js.map +1 -0
- package/dist/browser/rpc/src/schema.d.ts +843 -0
- package/dist/browser/rpc/src/schema.js +28 -0
- package/dist/browser/rpc/src/schema.js.map +1 -0
- package/dist/browser/rpc/src/types.d.ts +24 -0
- package/dist/browser/rpc/src/types.js +2 -0
- package/dist/browser/rpc/src/types.js.map +1 -0
- package/dist/browser/rpc/src/utils.d.ts +7 -0
- package/dist/browser/rpc/src/utils.js +58 -0
- package/dist/browser/rpc/src/utils.js.map +1 -0
- package/dist/browser/runtime/browser/community/challenges/index.d.ts +6 -0
- package/dist/browser/runtime/browser/community/challenges/index.js +7 -0
- package/dist/browser/runtime/browser/community/challenges/index.js.map +1 -0
- package/dist/browser/runtime/browser/community/local-community.d.ts +3 -0
- package/dist/browser/runtime/browser/community/local-community.js +6 -0
- package/dist/browser/runtime/browser/community/local-community.js.map +1 -0
- package/dist/browser/runtime/browser/db-handler.d.ts +4 -0
- package/dist/browser/runtime/browser/db-handler.js +8 -0
- package/dist/browser/runtime/browser/db-handler.js.map +1 -0
- package/dist/browser/runtime/browser/localforage-lru.d.ts +15 -0
- package/dist/browser/runtime/browser/localforage-lru.js +140 -0
- package/dist/browser/runtime/browser/localforage-lru.js.map +1 -0
- package/dist/browser/runtime/browser/lru-storage.d.ts +14 -0
- package/dist/browser/runtime/browser/lru-storage.js +34 -0
- package/dist/browser/runtime/browser/lru-storage.js.map +1 -0
- package/dist/browser/runtime/browser/native-functions.d.ts +3 -0
- package/dist/browser/runtime/browser/native-functions.js +6 -0
- package/dist/browser/runtime/browser/native-functions.js.map +1 -0
- package/dist/browser/runtime/browser/polyfill.d.ts +3 -0
- package/dist/browser/runtime/browser/polyfill.js +37 -0
- package/dist/browser/runtime/browser/polyfill.js.map +1 -0
- package/dist/browser/runtime/browser/setup-kubo-address-rewriter-and-http-router.d.ts +1 -0
- package/dist/browser/runtime/browser/setup-kubo-address-rewriter-and-http-router.js +4 -0
- package/dist/browser/runtime/browser/setup-kubo-address-rewriter-and-http-router.js.map +1 -0
- package/dist/browser/runtime/browser/storage.d.ts +13 -0
- package/dist/browser/runtime/browser/storage.js +37 -0
- package/dist/browser/runtime/browser/storage.js.map +1 -0
- package/dist/browser/runtime/browser/util.d.ts +14 -0
- package/dist/browser/runtime/browser/util.js +61 -0
- package/dist/browser/runtime/browser/util.js.map +1 -0
- package/dist/browser/runtime/node/address-rewriter-db.d.ts +31 -0
- package/dist/browser/runtime/node/address-rewriter-db.js +156 -0
- package/dist/browser/runtime/node/address-rewriter-db.js.map +1 -0
- package/dist/browser/runtime/node/addresses-rewriter-proxy-server.d.ts +45 -0
- package/dist/browser/runtime/node/addresses-rewriter-proxy-server.js +493 -0
- package/dist/browser/runtime/node/addresses-rewriter-proxy-server.js.map +1 -0
- package/dist/browser/runtime/node/community/challenges/exclude/exclude.d.ts +8 -0
- package/dist/browser/runtime/node/community/challenges/exclude/exclude.js +280 -0
- package/dist/browser/runtime/node/community/challenges/exclude/exclude.js.map +1 -0
- package/dist/browser/runtime/node/community/challenges/exclude/index.d.ts +3 -0
- package/dist/browser/runtime/node/community/challenges/exclude/index.js +4 -0
- package/dist/browser/runtime/node/community/challenges/exclude/index.js.map +1 -0
- package/dist/browser/runtime/node/community/challenges/exclude/rate-limiter.d.ts +5 -0
- package/dist/browser/runtime/node/community/challenges/exclude/rate-limiter.js +127 -0
- package/dist/browser/runtime/node/community/challenges/exclude/rate-limiter.js.map +1 -0
- package/dist/browser/runtime/node/community/challenges/exclude/utils.d.ts +13 -0
- package/dist/browser/runtime/node/community/challenges/exclude/utils.js +52 -0
- package/dist/browser/runtime/node/community/challenges/exclude/utils.js.map +1 -0
- package/dist/browser/runtime/node/community/challenges/index.d.ts +32 -0
- package/dist/browser/runtime/node/community/challenges/index.js +307 -0
- package/dist/browser/runtime/node/community/challenges/index.js.map +1 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/blacklist.d.ts +5 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/blacklist.js +118 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/blacklist.js.map +1 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/fail.d.ts +5 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/fail.js +26 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/fail.js.map +1 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/publication-match.d.ts +5 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/publication-match.js +135 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/publication-match.js.map +1 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/question.d.ts +5 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/question.js +66 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/question.js.map +1 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/text-math.d.ts +5 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/text-math.js +61 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/text-math.js.map +1 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/whitelist.d.ts +5 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/whitelist.js +118 -0
- package/dist/browser/runtime/node/community/challenges/pkc-js-challenges/whitelist.js.map +1 -0
- package/dist/browser/runtime/node/community/db-handler-types.d.ts +19 -0
- package/dist/browser/runtime/node/community/db-handler-types.js +2 -0
- package/dist/browser/runtime/node/community/db-handler-types.js.map +1 -0
- package/dist/browser/runtime/node/community/db-handler.d.ts +226 -0
- package/dist/browser/runtime/node/community/db-handler.js +2462 -0
- package/dist/browser/runtime/node/community/db-handler.js.map +1 -0
- package/dist/browser/runtime/node/community/db-row-parser.d.ts +19 -0
- package/dist/browser/runtime/node/community/db-row-parser.js +40 -0
- package/dist/browser/runtime/node/community/db-row-parser.js.map +1 -0
- package/dist/browser/runtime/node/community/keyv-better-sqlite3.d.ts +68 -0
- package/dist/browser/runtime/node/community/keyv-better-sqlite3.js +251 -0
- package/dist/browser/runtime/node/community/keyv-better-sqlite3.js.map +1 -0
- package/dist/browser/runtime/node/community/local-community.d.ts +129 -0
- package/dist/browser/runtime/node/community/local-community.js +2978 -0
- package/dist/browser/runtime/node/community/local-community.js.map +1 -0
- package/dist/browser/runtime/node/community/page-generator.d.ts +433 -0
- package/dist/browser/runtime/node/community/page-generator.js +441 -0
- package/dist/browser/runtime/node/community/page-generator.js.map +1 -0
- package/dist/browser/runtime/node/lru-storage.d.ts +14 -0
- package/dist/browser/runtime/node/lru-storage.js +40 -0
- package/dist/browser/runtime/node/lru-storage.js.map +1 -0
- package/dist/browser/runtime/node/native-functions.d.ts +3 -0
- package/dist/browser/runtime/node/native-functions.js +7 -0
- package/dist/browser/runtime/node/native-functions.js.map +1 -0
- package/dist/browser/runtime/node/polyfill.d.ts +3 -0
- package/dist/browser/runtime/node/polyfill.js +20 -0
- package/dist/browser/runtime/node/polyfill.js.map +1 -0
- package/dist/browser/runtime/node/setup-kubo-address-rewriter-and-http-router.d.ts +4 -0
- package/dist/browser/runtime/node/setup-kubo-address-rewriter-and-http-router.js +240 -0
- package/dist/browser/runtime/node/setup-kubo-address-rewriter-and-http-router.js.map +1 -0
- package/dist/browser/runtime/node/sqlite-lru-cache.d.ts +52 -0
- package/dist/browser/runtime/node/sqlite-lru-cache.js +127 -0
- package/dist/browser/runtime/node/sqlite-lru-cache.js.map +1 -0
- package/dist/browser/runtime/node/storage.d.ts +14 -0
- package/dist/browser/runtime/node/storage.js +52 -0
- package/dist/browser/runtime/node/storage.js.map +1 -0
- package/dist/browser/runtime/node/test/helpers/hanging-runner.d.ts +1 -0
- package/dist/browser/runtime/node/test/helpers/hanging-runner.js +157 -0
- package/dist/browser/runtime/node/test/helpers/hanging-runner.js.map +1 -0
- package/dist/browser/runtime/node/test/helpers/run-hanging-node.d.ts +7 -0
- package/dist/browser/runtime/node/test/helpers/run-hanging-node.js +68 -0
- package/dist/browser/runtime/node/test/helpers/run-hanging-node.js.map +1 -0
- package/dist/browser/runtime/node/test/mock-http-router.d.ts +54 -0
- package/dist/browser/runtime/node/test/mock-http-router.js +397 -0
- package/dist/browser/runtime/node/test/mock-http-router.js.map +1 -0
- package/dist/browser/runtime/node/util.d.ts +43 -0
- package/dist/browser/runtime/node/util.js +384 -0
- package/dist/browser/runtime/node/util.js.map +1 -0
- package/dist/browser/schema/schema-util.d.ts +2751 -0
- package/dist/browser/schema/schema-util.js +562 -0
- package/dist/browser/schema/schema-util.js.map +1 -0
- package/dist/browser/schema/schema.d.ts +237 -0
- package/dist/browser/schema/schema.js +128 -0
- package/dist/browser/schema/schema.js.map +1 -0
- package/dist/browser/schema.d.ts +1142 -0
- package/dist/browser/schema.js +104 -0
- package/dist/browser/schema.js.map +1 -0
- package/dist/browser/signer/constants.d.ts +2 -0
- package/dist/browser/signer/constants.js +3 -0
- package/dist/browser/signer/constants.js.map +1 -0
- package/dist/browser/signer/encryption.d.ts +21 -0
- package/dist/browser/signer/encryption.js +122 -0
- package/dist/browser/signer/encryption.js.map +1 -0
- package/dist/browser/signer/index.d.ts +21 -0
- package/dist/browser/signer/index.js +49 -0
- package/dist/browser/signer/index.js.map +1 -0
- package/dist/browser/signer/signatures.d.ts +200 -0
- package/dist/browser/signer/signatures.js +594 -0
- package/dist/browser/signer/signatures.js.map +1 -0
- package/dist/browser/signer/types.d.ts +20 -0
- package/dist/browser/signer/types.js +2 -0
- package/dist/browser/signer/types.js.map +1 -0
- package/dist/browser/signer/util.d.ts +14 -0
- package/dist/browser/signer/util.js +156 -0
- package/dist/browser/signer/util.js.map +1 -0
- package/dist/browser/stats.d.ts +15 -0
- package/dist/browser/stats.js +64 -0
- package/dist/browser/stats.js.map +1 -0
- package/dist/browser/test/mock-ipfs-client.d.ts +34 -0
- package/dist/browser/test/mock-ipfs-client.js +208 -0
- package/dist/browser/test/mock-ipfs-client.js.map +1 -0
- package/dist/browser/test/node/hanging-test/scenarios/comment-publish-pending.scenario.d.ts +8 -0
- package/dist/browser/test/node/hanging-test/scenarios/comment-publish-pending.scenario.js +21 -0
- package/dist/browser/test/node/hanging-test/scenarios/comment-publish-pending.scenario.js.map +1 -0
- package/dist/browser/test/node/hanging-test/scenarios/comment-publish.scenario.d.ts +8 -0
- package/dist/browser/test/node/hanging-test/scenarios/comment-publish.scenario.js +19 -0
- package/dist/browser/test/node/hanging-test/scenarios/comment-publish.scenario.js.map +1 -0
- package/dist/browser/test/node/hanging-test/scenarios/comment-update.scenario.d.ts +8 -0
- package/dist/browser/test/node/hanging-test/scenarios/comment-update.scenario.js +22 -0
- package/dist/browser/test/node/hanging-test/scenarios/comment-update.scenario.js.map +1 -0
- package/dist/browser/test/node/hanging-test/scenarios/community-start.scenario.d.ts +8 -0
- package/dist/browser/test/node/hanging-test/scenarios/community-start.scenario.js +23 -0
- package/dist/browser/test/node/hanging-test/scenarios/community-start.scenario.js.map +1 -0
- package/dist/browser/test/node/hanging-test/scenarios/community-update.scenario.d.ts +8 -0
- package/dist/browser/test/node/hanging-test/scenarios/community-update.scenario.js +21 -0
- package/dist/browser/test/node/hanging-test/scenarios/community-update.scenario.js.map +1 -0
- package/dist/browser/test/node/hanging-test/scenarios/destroy-only.scenario.d.ts +7 -0
- package/dist/browser/test/node/hanging-test/scenarios/destroy-only.scenario.js +15 -0
- package/dist/browser/test/node/hanging-test/scenarios/destroy-only.scenario.js.map +1 -0
- package/dist/browser/test/node/hanging-test/scenarios/hanging-test-util.d.ts +30 -0
- package/dist/browser/test/node/hanging-test/scenarios/hanging-test-util.js +46 -0
- package/dist/browser/test/node/hanging-test/scenarios/hanging-test-util.js.map +1 -0
- package/dist/browser/test/test-util.d.ts +1019 -0
- package/dist/browser/test/test-util.js +1886 -0
- package/dist/browser/test/test-util.js.map +1 -0
- package/dist/browser/types.d.ts +165 -0
- package/dist/browser/types.js +2 -0
- package/dist/browser/types.js.map +1 -0
- package/dist/browser/util/inflight-fetch-manager.d.ts +11 -0
- package/dist/browser/util/inflight-fetch-manager.js +41 -0
- package/dist/browser/util/inflight-fetch-manager.js.map +1 -0
- package/dist/browser/util.d.ts +120 -0
- package/dist/browser/util.js +816 -0
- package/dist/browser/util.js.map +1 -0
- package/dist/browser/version.d.ts +7 -0
- package/dist/browser/version.js +12 -0
- package/dist/browser/version.js.map +1 -0
- package/dist/browser/zod-error-map.d.ts +1 -0
- package/dist/browser/zod-error-map.js +10 -0
- package/dist/browser/zod-error-map.js.map +1 -0
- package/dist/node/challenges.d.ts +1 -0
- package/dist/node/challenges.js +2 -0
- package/dist/node/challenges.js.map +1 -0
- package/dist/node/clients/base-client-manager.d.ts +126 -0
- package/dist/node/clients/base-client-manager.js +673 -0
- package/dist/node/clients/base-client-manager.js.map +1 -0
- package/dist/node/clients/name-resolver-client.d.ts +8 -0
- package/dist/node/clients/name-resolver-client.js +10 -0
- package/dist/node/clients/name-resolver-client.js.map +1 -0
- package/dist/node/clients/pkc-typed-emitter.d.ts +9 -0
- package/dist/node/clients/pkc-typed-emitter.js +52 -0
- package/dist/node/clients/pkc-typed-emitter.js.map +1 -0
- package/dist/node/clients/rpc-client/decode-rpc-response-util.d.ts +8 -0
- package/dist/node/clients/rpc-client/decode-rpc-response-util.js +53 -0
- package/dist/node/clients/rpc-client/decode-rpc-response-util.js.map +1 -0
- package/dist/node/clients/rpc-client/pkc-rpc-client.d.ts +68 -0
- package/dist/node/clients/rpc-client/pkc-rpc-client.js +404 -0
- package/dist/node/clients/rpc-client/pkc-rpc-client.js.map +1 -0
- package/dist/node/clients/rpc-client/rpc-schema-util.d.ts +147 -0
- package/dist/node/clients/rpc-client/rpc-schema-util.js +11 -0
- package/dist/node/clients/rpc-client/rpc-schema-util.js.map +1 -0
- package/dist/node/clients/rpc-client/schema.d.ts +433 -0
- package/dist/node/clients/rpc-client/schema.js +49 -0
- package/dist/node/clients/rpc-client/schema.js.map +1 -0
- package/dist/node/clients/rpc-client/types.d.ts +8 -0
- package/dist/node/clients/rpc-client/types.js +2 -0
- package/dist/node/clients/rpc-client/types.js.map +1 -0
- package/dist/node/community/community-client-manager.d.ts +60 -0
- package/dist/node/community/community-client-manager.js +717 -0
- package/dist/node/community/community-client-manager.js.map +1 -0
- package/dist/node/community/community-clients.d.ts +18 -0
- package/dist/node/community/community-clients.js +12 -0
- package/dist/node/community/community-clients.js.map +1 -0
- package/dist/node/community/community-wire.d.ts +20 -0
- package/dist/node/community/community-wire.js +38 -0
- package/dist/node/community/community-wire.js.map +1 -0
- package/dist/node/community/remote-community.d.ts +110 -0
- package/dist/node/community/remote-community.js +555 -0
- package/dist/node/community/remote-community.js.map +1 -0
- package/dist/node/community/rpc-local-community.d.ts +41 -0
- package/dist/node/community/rpc-local-community.js +289 -0
- package/dist/node/community/rpc-local-community.js.map +1 -0
- package/dist/node/community/rpc-remote-community.d.ts +18 -0
- package/dist/node/community/rpc-remote-community.js +286 -0
- package/dist/node/community/rpc-remote-community.js.map +1 -0
- package/dist/node/community/schema.d.ts +4217 -0
- package/dist/node/community/schema.js +289 -0
- package/dist/node/community/schema.js.map +1 -0
- package/dist/node/community/types.d.ts +135 -0
- package/dist/node/community/types.js +2 -0
- package/dist/node/community/types.js.map +1 -0
- package/dist/node/constants.d.ts +6 -0
- package/dist/node/constants.js +9 -0
- package/dist/node/constants.js.map +1 -0
- package/dist/node/decorator-util.d.ts +1 -0
- package/dist/node/decorator-util.js +35 -0
- package/dist/node/decorator-util.js.map +1 -0
- package/dist/node/errors.d.ts +343 -0
- package/dist/node/errors.js +358 -0
- package/dist/node/errors.js.map +1 -0
- package/dist/node/general-util/limited-set.d.ts +15 -0
- package/dist/node/general-util/limited-set.js +66 -0
- package/dist/node/general-util/limited-set.js.map +1 -0
- package/dist/node/generated-version.d.ts +1 -0
- package/dist/node/generated-version.js +3 -0
- package/dist/node/generated-version.js.map +1 -0
- package/dist/node/generic-state-client.d.ts +6 -0
- package/dist/node/generic-state-client.js +11 -0
- package/dist/node/generic-state-client.js.map +1 -0
- package/dist/node/helia/helia-for-pkc.d.ts +3 -0
- package/dist/node/helia/helia-for-pkc.js +255 -0
- package/dist/node/helia/helia-for-pkc.js.map +1 -0
- package/dist/node/helia/ipns-over-pubsub-with-fetch.d.ts +36 -0
- package/dist/node/helia/ipns-over-pubsub-with-fetch.js +229 -0
- package/dist/node/helia/ipns-over-pubsub-with-fetch.js.map +1 -0
- package/dist/node/helia/libp2pjsClient.d.ts +27 -0
- package/dist/node/helia/libp2pjsClient.js +15 -0
- package/dist/node/helia/libp2pjsClient.js.map +1 -0
- package/dist/node/helia/types.d.ts +19 -0
- package/dist/node/helia/types.js +2 -0
- package/dist/node/helia/types.js.map +1 -0
- package/dist/node/helia/util.d.ts +13 -0
- package/dist/node/helia/util.js +98 -0
- package/dist/node/helia/util.js.map +1 -0
- package/dist/node/index.d.ts +244 -0
- package/dist/node/index.js +36 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/logger.d.ts +12 -0
- package/dist/node/logger.js +11 -0
- package/dist/node/logger.js.map +1 -0
- package/dist/node/pages/pages-client-manager.d.ts +159 -0
- package/dist/node/pages/pages-client-manager.js +334 -0
- package/dist/node/pages/pages-client-manager.js.map +1 -0
- package/dist/node/pages/pages-clients.d.ts +11 -0
- package/dist/node/pages/pages-clients.js +10 -0
- package/dist/node/pages/pages-clients.js.map +1 -0
- package/dist/node/pages/pages.d.ts +107 -0
- package/dist/node/pages/pages.js +262 -0
- package/dist/node/pages/pages.js.map +1 -0
- package/dist/node/pages/schema-util.d.ts +3 -0
- package/dist/node/pages/schema-util.js +3 -0
- package/dist/node/pages/schema-util.js.map +1 -0
- package/dist/node/pages/schema.d.ts +719 -0
- package/dist/node/pages/schema.js +32 -0
- package/dist/node/pages/schema.js.map +1 -0
- package/dist/node/pages/types.d.ts +44 -0
- package/dist/node/pages/types.js +2 -0
- package/dist/node/pages/types.js.map +1 -0
- package/dist/node/pages/util.d.ts +56 -0
- package/dist/node/pages/util.js +446 -0
- package/dist/node/pages/util.js.map +1 -0
- package/dist/node/pkc/pkc-client-manager.d.ts +44 -0
- package/dist/node/pkc/pkc-client-manager.js +156 -0
- package/dist/node/pkc/pkc-client-manager.js.map +1 -0
- package/dist/node/pkc/pkc-clients.d.ts +11 -0
- package/dist/node/pkc/pkc-clients.js +8 -0
- package/dist/node/pkc/pkc-clients.js.map +1 -0
- package/dist/node/pkc/pkc-with-rpc-client.d.ts +19 -0
- package/dist/node/pkc/pkc-with-rpc-client.js +128 -0
- package/dist/node/pkc/pkc-with-rpc-client.js.map +1 -0
- package/dist/node/pkc/pkc.d.ts +137 -0
- package/dist/node/pkc/pkc.js +888 -0
- package/dist/node/pkc/pkc.js.map +1 -0
- package/dist/node/pkc/tracked-instance-registry-util.d.ts +44 -0
- package/dist/node/pkc/tracked-instance-registry-util.js +106 -0
- package/dist/node/pkc/tracked-instance-registry-util.js.map +1 -0
- package/dist/node/pkc/tracked-instance-registry.d.ts +18 -0
- package/dist/node/pkc/tracked-instance-registry.js +134 -0
- package/dist/node/pkc/tracked-instance-registry.js.map +1 -0
- package/dist/node/pkc-error.d.ts +65 -0
- package/dist/node/pkc-error.js +137 -0
- package/dist/node/pkc-error.js.map +1 -0
- package/dist/node/publications/comment/comment-client-manager.d.ts +86 -0
- package/dist/node/publications/comment/comment-client-manager.js +908 -0
- package/dist/node/publications/comment/comment-client-manager.js.map +1 -0
- package/dist/node/publications/comment/comment-clients.d.ts +19 -0
- package/dist/node/publications/comment/comment-clients.js +12 -0
- package/dist/node/publications/comment/comment-clients.js.map +1 -0
- package/dist/node/publications/comment/comment-util.d.ts +10 -0
- package/dist/node/publications/comment/comment-util.js +202 -0
- package/dist/node/publications/comment/comment-util.js.map +1 -0
- package/dist/node/publications/comment/comment.d.ts +147 -0
- package/dist/node/publications/comment/comment.js +1044 -0
- package/dist/node/publications/comment/comment.js.map +1 -0
- package/dist/node/publications/comment/schema.d.ts +1237 -0
- package/dist/node/publications/comment/schema.js +184 -0
- package/dist/node/publications/comment/schema.js.map +1 -0
- package/dist/node/publications/comment/types.d.ts +100 -0
- package/dist/node/publications/comment/types.js +2 -0
- package/dist/node/publications/comment/types.js.map +1 -0
- package/dist/node/publications/comment-edit/comment-edit.d.ts +41 -0
- package/dist/node/publications/comment-edit/comment-edit.js +63 -0
- package/dist/node/publications/comment-edit/comment-edit.js.map +1 -0
- package/dist/node/publications/comment-edit/schema.d.ts +295 -0
- package/dist/node/publications/comment-edit/schema.js +55 -0
- package/dist/node/publications/comment-edit/schema.js.map +1 -0
- package/dist/node/publications/comment-edit/types.d.ts +25 -0
- package/dist/node/publications/comment-edit/types.js +2 -0
- package/dist/node/publications/comment-edit/types.js.map +1 -0
- package/dist/node/publications/comment-moderation/comment-moderation.d.ts +36 -0
- package/dist/node/publications/comment-moderation/comment-moderation.js +53 -0
- package/dist/node/publications/comment-moderation/comment-moderation.js.map +1 -0
- package/dist/node/publications/comment-moderation/schema.d.ts +315 -0
- package/dist/node/publications/comment-moderation/schema.js +62 -0
- package/dist/node/publications/comment-moderation/schema.js.map +1 -0
- package/dist/node/publications/comment-moderation/types.d.ts +22 -0
- package/dist/node/publications/comment-moderation/types.js +2 -0
- package/dist/node/publications/comment-moderation/types.js.map +1 -0
- package/dist/node/publications/community-edit/community-edit.d.ts +35 -0
- package/dist/node/publications/community-edit/community-edit.js +50 -0
- package/dist/node/publications/community-edit/community-edit.js.map +1 -0
- package/dist/node/publications/community-edit/schema.d.ts +467 -0
- package/dist/node/publications/community-edit/schema.js +36 -0
- package/dist/node/publications/community-edit/schema.js.map +1 -0
- package/dist/node/publications/community-edit/types.d.ts +19 -0
- package/dist/node/publications/community-edit/types.js +2 -0
- package/dist/node/publications/community-edit/types.js.map +1 -0
- package/dist/node/publications/publication-author.d.ts +22 -0
- package/dist/node/publications/publication-author.js +66 -0
- package/dist/node/publications/publication-author.js.map +1 -0
- package/dist/node/publications/publication-client-manager.d.ts +62 -0
- package/dist/node/publications/publication-client-manager.js +257 -0
- package/dist/node/publications/publication-client-manager.js.map +1 -0
- package/dist/node/publications/publication-clients.d.ts +19 -0
- package/dist/node/publications/publication-clients.js +12 -0
- package/dist/node/publications/publication-clients.js.map +1 -0
- package/dist/node/publications/publication-community.d.ts +55 -0
- package/dist/node/publications/publication-community.js +87 -0
- package/dist/node/publications/publication-community.js.map +1 -0
- package/dist/node/publications/publication.d.ts +120 -0
- package/dist/node/publications/publication.js +950 -0
- package/dist/node/publications/publication.js.map +1 -0
- package/dist/node/publications/types.d.ts +26 -0
- package/dist/node/publications/types.js +2 -0
- package/dist/node/publications/types.js.map +1 -0
- package/dist/node/publications/vote/schema.d.ts +150 -0
- package/dist/node/publications/vote/schema.js +44 -0
- package/dist/node/publications/vote/schema.js.map +1 -0
- package/dist/node/publications/vote/types.d.ts +21 -0
- package/dist/node/publications/vote/types.js +2 -0
- package/dist/node/publications/vote/types.js.map +1 -0
- package/dist/node/publications/vote/vote.d.ts +36 -0
- package/dist/node/publications/vote/vote.js +49 -0
- package/dist/node/publications/vote/vote.js.map +1 -0
- package/dist/node/pubsub-messages/schema.d.ts +964 -0
- package/dist/node/pubsub-messages/schema.js +98 -0
- package/dist/node/pubsub-messages/schema.js.map +1 -0
- package/dist/node/pubsub-messages/types.d.ts +81 -0
- package/dist/node/pubsub-messages/types.js +2 -0
- package/dist/node/pubsub-messages/types.js.map +1 -0
- package/dist/node/rpc/src/index.d.ts +483 -0
- package/dist/node/rpc/src/index.js +1267 -0
- package/dist/node/rpc/src/index.js.map +1 -0
- package/dist/node/rpc/src/json-rpc-util.d.ts +1 -0
- package/dist/node/rpc/src/json-rpc-util.js +19 -0
- package/dist/node/rpc/src/json-rpc-util.js.map +1 -0
- package/dist/node/rpc/src/lib/pkc-js/index.d.ts +132 -0
- package/dist/node/rpc/src/lib/pkc-js/index.js +29 -0
- package/dist/node/rpc/src/lib/pkc-js/index.js.map +1 -0
- package/dist/node/rpc/src/lib/pkc-js/pkc-js-mock.d.ts +1 -0
- package/dist/node/rpc/src/lib/pkc-js/pkc-js-mock.js +472 -0
- package/dist/node/rpc/src/lib/pkc-js/pkc-js-mock.js.map +1 -0
- package/dist/node/rpc/src/schema.d.ts +843 -0
- package/dist/node/rpc/src/schema.js +28 -0
- package/dist/node/rpc/src/schema.js.map +1 -0
- package/dist/node/rpc/src/types.d.ts +24 -0
- package/dist/node/rpc/src/types.js +2 -0
- package/dist/node/rpc/src/types.js.map +1 -0
- package/dist/node/rpc/src/utils.d.ts +7 -0
- package/dist/node/rpc/src/utils.js +58 -0
- package/dist/node/rpc/src/utils.js.map +1 -0
- package/dist/node/runtime/browser/community/challenges/index.d.ts +6 -0
- package/dist/node/runtime/browser/community/challenges/index.js +7 -0
- package/dist/node/runtime/browser/community/challenges/index.js.map +1 -0
- package/dist/node/runtime/browser/community/local-community.d.ts +3 -0
- package/dist/node/runtime/browser/community/local-community.js +6 -0
- package/dist/node/runtime/browser/community/local-community.js.map +1 -0
- package/dist/node/runtime/browser/db-handler.d.ts +4 -0
- package/dist/node/runtime/browser/db-handler.js +8 -0
- package/dist/node/runtime/browser/db-handler.js.map +1 -0
- package/dist/node/runtime/browser/localforage-lru.d.ts +15 -0
- package/dist/node/runtime/browser/localforage-lru.js +140 -0
- package/dist/node/runtime/browser/localforage-lru.js.map +1 -0
- package/dist/node/runtime/browser/lru-storage.d.ts +14 -0
- package/dist/node/runtime/browser/lru-storage.js +34 -0
- package/dist/node/runtime/browser/lru-storage.js.map +1 -0
- package/dist/node/runtime/browser/native-functions.d.ts +3 -0
- package/dist/node/runtime/browser/native-functions.js +6 -0
- package/dist/node/runtime/browser/native-functions.js.map +1 -0
- package/dist/node/runtime/browser/polyfill.d.ts +3 -0
- package/dist/node/runtime/browser/polyfill.js +37 -0
- package/dist/node/runtime/browser/polyfill.js.map +1 -0
- package/dist/node/runtime/browser/setup-kubo-address-rewriter-and-http-router.d.ts +1 -0
- package/dist/node/runtime/browser/setup-kubo-address-rewriter-and-http-router.js +4 -0
- package/dist/node/runtime/browser/setup-kubo-address-rewriter-and-http-router.js.map +1 -0
- package/dist/node/runtime/browser/storage.d.ts +13 -0
- package/dist/node/runtime/browser/storage.js +37 -0
- package/dist/node/runtime/browser/storage.js.map +1 -0
- package/dist/node/runtime/browser/util.d.ts +14 -0
- package/dist/node/runtime/browser/util.js +61 -0
- package/dist/node/runtime/browser/util.js.map +1 -0
- package/dist/node/runtime/node/address-rewriter-db.d.ts +31 -0
- package/dist/node/runtime/node/address-rewriter-db.js +156 -0
- package/dist/node/runtime/node/address-rewriter-db.js.map +1 -0
- package/dist/node/runtime/node/addresses-rewriter-proxy-server.d.ts +45 -0
- package/dist/node/runtime/node/addresses-rewriter-proxy-server.js +493 -0
- package/dist/node/runtime/node/addresses-rewriter-proxy-server.js.map +1 -0
- package/dist/node/runtime/node/community/challenges/exclude/exclude.d.ts +8 -0
- package/dist/node/runtime/node/community/challenges/exclude/exclude.js +280 -0
- package/dist/node/runtime/node/community/challenges/exclude/exclude.js.map +1 -0
- package/dist/node/runtime/node/community/challenges/exclude/index.d.ts +3 -0
- package/dist/node/runtime/node/community/challenges/exclude/index.js +4 -0
- package/dist/node/runtime/node/community/challenges/exclude/index.js.map +1 -0
- package/dist/node/runtime/node/community/challenges/exclude/rate-limiter.d.ts +5 -0
- package/dist/node/runtime/node/community/challenges/exclude/rate-limiter.js +127 -0
- package/dist/node/runtime/node/community/challenges/exclude/rate-limiter.js.map +1 -0
- package/dist/node/runtime/node/community/challenges/exclude/utils.d.ts +13 -0
- package/dist/node/runtime/node/community/challenges/exclude/utils.js +52 -0
- package/dist/node/runtime/node/community/challenges/exclude/utils.js.map +1 -0
- package/dist/node/runtime/node/community/challenges/index.d.ts +32 -0
- package/dist/node/runtime/node/community/challenges/index.js +307 -0
- package/dist/node/runtime/node/community/challenges/index.js.map +1 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/blacklist.d.ts +5 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/blacklist.js +118 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/blacklist.js.map +1 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/fail.d.ts +5 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/fail.js +26 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/fail.js.map +1 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/publication-match.d.ts +5 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/publication-match.js +135 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/publication-match.js.map +1 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/question.d.ts +5 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/question.js +66 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/question.js.map +1 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/text-math.d.ts +5 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/text-math.js +61 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/text-math.js.map +1 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/whitelist.d.ts +5 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/whitelist.js +118 -0
- package/dist/node/runtime/node/community/challenges/pkc-js-challenges/whitelist.js.map +1 -0
- package/dist/node/runtime/node/community/db-handler-types.d.ts +19 -0
- package/dist/node/runtime/node/community/db-handler-types.js +2 -0
- package/dist/node/runtime/node/community/db-handler-types.js.map +1 -0
- package/dist/node/runtime/node/community/db-handler.d.ts +226 -0
- package/dist/node/runtime/node/community/db-handler.js +2462 -0
- package/dist/node/runtime/node/community/db-handler.js.map +1 -0
- package/dist/node/runtime/node/community/db-row-parser.d.ts +19 -0
- package/dist/node/runtime/node/community/db-row-parser.js +40 -0
- package/dist/node/runtime/node/community/db-row-parser.js.map +1 -0
- package/dist/node/runtime/node/community/keyv-better-sqlite3.d.ts +68 -0
- package/dist/node/runtime/node/community/keyv-better-sqlite3.js +251 -0
- package/dist/node/runtime/node/community/keyv-better-sqlite3.js.map +1 -0
- package/dist/node/runtime/node/community/local-community.d.ts +129 -0
- package/dist/node/runtime/node/community/local-community.js +2978 -0
- package/dist/node/runtime/node/community/local-community.js.map +1 -0
- package/dist/node/runtime/node/community/page-generator.d.ts +433 -0
- package/dist/node/runtime/node/community/page-generator.js +441 -0
- package/dist/node/runtime/node/community/page-generator.js.map +1 -0
- package/dist/node/runtime/node/lru-storage.d.ts +14 -0
- package/dist/node/runtime/node/lru-storage.js +40 -0
- package/dist/node/runtime/node/lru-storage.js.map +1 -0
- package/dist/node/runtime/node/native-functions.d.ts +3 -0
- package/dist/node/runtime/node/native-functions.js +7 -0
- package/dist/node/runtime/node/native-functions.js.map +1 -0
- package/dist/node/runtime/node/polyfill.d.ts +3 -0
- package/dist/node/runtime/node/polyfill.js +20 -0
- package/dist/node/runtime/node/polyfill.js.map +1 -0
- package/dist/node/runtime/node/setup-kubo-address-rewriter-and-http-router.d.ts +4 -0
- package/dist/node/runtime/node/setup-kubo-address-rewriter-and-http-router.js +240 -0
- package/dist/node/runtime/node/setup-kubo-address-rewriter-and-http-router.js.map +1 -0
- package/dist/node/runtime/node/sqlite-lru-cache.d.ts +52 -0
- package/dist/node/runtime/node/sqlite-lru-cache.js +127 -0
- package/dist/node/runtime/node/sqlite-lru-cache.js.map +1 -0
- package/dist/node/runtime/node/storage.d.ts +14 -0
- package/dist/node/runtime/node/storage.js +52 -0
- package/dist/node/runtime/node/storage.js.map +1 -0
- package/dist/node/runtime/node/test/helpers/hanging-runner.d.ts +1 -0
- package/dist/node/runtime/node/test/helpers/hanging-runner.js +157 -0
- package/dist/node/runtime/node/test/helpers/hanging-runner.js.map +1 -0
- package/dist/node/runtime/node/test/helpers/run-hanging-node.d.ts +7 -0
- package/dist/node/runtime/node/test/helpers/run-hanging-node.js +68 -0
- package/dist/node/runtime/node/test/helpers/run-hanging-node.js.map +1 -0
- package/dist/node/runtime/node/test/mock-http-router.d.ts +54 -0
- package/dist/node/runtime/node/test/mock-http-router.js +397 -0
- package/dist/node/runtime/node/test/mock-http-router.js.map +1 -0
- package/dist/node/runtime/node/util.d.ts +43 -0
- package/dist/node/runtime/node/util.js +384 -0
- package/dist/node/runtime/node/util.js.map +1 -0
- package/dist/node/schema/schema-util.d.ts +2751 -0
- package/dist/node/schema/schema-util.js +562 -0
- package/dist/node/schema/schema-util.js.map +1 -0
- package/dist/node/schema/schema.d.ts +237 -0
- package/dist/node/schema/schema.js +128 -0
- package/dist/node/schema/schema.js.map +1 -0
- package/dist/node/schema.d.ts +1142 -0
- package/dist/node/schema.js +104 -0
- package/dist/node/schema.js.map +1 -0
- package/dist/node/signer/constants.d.ts +2 -0
- package/dist/node/signer/constants.js +3 -0
- package/dist/node/signer/constants.js.map +1 -0
- package/dist/node/signer/encryption.d.ts +21 -0
- package/dist/node/signer/encryption.js +122 -0
- package/dist/node/signer/encryption.js.map +1 -0
- package/dist/node/signer/index.d.ts +21 -0
- package/dist/node/signer/index.js +49 -0
- package/dist/node/signer/index.js.map +1 -0
- package/dist/node/signer/signatures.d.ts +200 -0
- package/dist/node/signer/signatures.js +594 -0
- package/dist/node/signer/signatures.js.map +1 -0
- package/dist/node/signer/types.d.ts +20 -0
- package/dist/node/signer/types.js +2 -0
- package/dist/node/signer/types.js.map +1 -0
- package/dist/node/signer/util.d.ts +14 -0
- package/dist/node/signer/util.js +156 -0
- package/dist/node/signer/util.js.map +1 -0
- package/dist/node/stats.d.ts +15 -0
- package/dist/node/stats.js +64 -0
- package/dist/node/stats.js.map +1 -0
- package/dist/node/test/mock-ipfs-client.d.ts +34 -0
- package/dist/node/test/mock-ipfs-client.js +208 -0
- package/dist/node/test/mock-ipfs-client.js.map +1 -0
- package/dist/node/test/node/hanging-test/scenarios/comment-publish-pending.scenario.d.ts +8 -0
- package/dist/node/test/node/hanging-test/scenarios/comment-publish-pending.scenario.js +21 -0
- package/dist/node/test/node/hanging-test/scenarios/comment-publish-pending.scenario.js.map +1 -0
- package/dist/node/test/node/hanging-test/scenarios/comment-publish.scenario.d.ts +8 -0
- package/dist/node/test/node/hanging-test/scenarios/comment-publish.scenario.js +19 -0
- package/dist/node/test/node/hanging-test/scenarios/comment-publish.scenario.js.map +1 -0
- package/dist/node/test/node/hanging-test/scenarios/comment-update.scenario.d.ts +8 -0
- package/dist/node/test/node/hanging-test/scenarios/comment-update.scenario.js +22 -0
- package/dist/node/test/node/hanging-test/scenarios/comment-update.scenario.js.map +1 -0
- package/dist/node/test/node/hanging-test/scenarios/community-start.scenario.d.ts +8 -0
- package/dist/node/test/node/hanging-test/scenarios/community-start.scenario.js +23 -0
- package/dist/node/test/node/hanging-test/scenarios/community-start.scenario.js.map +1 -0
- package/dist/node/test/node/hanging-test/scenarios/community-update.scenario.d.ts +8 -0
- package/dist/node/test/node/hanging-test/scenarios/community-update.scenario.js +21 -0
- package/dist/node/test/node/hanging-test/scenarios/community-update.scenario.js.map +1 -0
- package/dist/node/test/node/hanging-test/scenarios/destroy-only.scenario.d.ts +7 -0
- package/dist/node/test/node/hanging-test/scenarios/destroy-only.scenario.js +15 -0
- package/dist/node/test/node/hanging-test/scenarios/destroy-only.scenario.js.map +1 -0
- package/dist/node/test/node/hanging-test/scenarios/hanging-test-util.d.ts +30 -0
- package/dist/node/test/node/hanging-test/scenarios/hanging-test-util.js +46 -0
- package/dist/node/test/node/hanging-test/scenarios/hanging-test-util.js.map +1 -0
- package/dist/node/test/test-util.d.ts +1019 -0
- package/dist/node/test/test-util.js +1886 -0
- package/dist/node/test/test-util.js.map +1 -0
- package/dist/node/types.d.ts +165 -0
- package/dist/node/types.js +2 -0
- package/dist/node/types.js.map +1 -0
- package/dist/node/util/inflight-fetch-manager.d.ts +11 -0
- package/dist/node/util/inflight-fetch-manager.js +41 -0
- package/dist/node/util/inflight-fetch-manager.js.map +1 -0
- package/dist/node/util.d.ts +120 -0
- package/dist/node/util.js +816 -0
- package/dist/node/util.js.map +1 -0
- package/dist/node/version.d.ts +7 -0
- package/dist/node/version.js +12 -0
- package/dist/node/version.js.map +1 -0
- package/dist/node/zod-error-map.d.ts +1 -0
- package/dist/node/zod-error-map.js +10 -0
- package/dist/node/zod-error-map.js.map +1 -0
- package/package.json +212 -0
|
@@ -0,0 +1,1886 @@
|
|
|
1
|
+
import PKCIndex from "../index.js";
|
|
2
|
+
import { calculateStringSizeSameAsIpfsAddCidV0, removeUndefinedValuesRecursively, retryKuboIpfsAdd, timestamp } from "../util.js";
|
|
3
|
+
import { getCommunityAddressFromRecord } from "../publications/publication-community.js";
|
|
4
|
+
import assert from "assert";
|
|
5
|
+
import { stringify as deterministicStringify } from "safe-stable-stringify";
|
|
6
|
+
import { v4 as uuidv4 } from "uuid";
|
|
7
|
+
import { createMockPubsubClient } from "./mock-ipfs-client.js";
|
|
8
|
+
import Logger from "../logger.js";
|
|
9
|
+
import * as remeda from "remeda";
|
|
10
|
+
import { LocalCommunity } from "../runtime/node/community/local-community.js";
|
|
11
|
+
import { findUpdatingComment, findUpdatingCommunity } from "../pkc/tracked-instance-registry-util.js";
|
|
12
|
+
import pTimeout from "p-timeout";
|
|
13
|
+
import { signComment, _signJson, signCommentEdit, cleanUpBeforePublishing, _signPubsubMsg, signChallengeVerification, signCommunity } from "../signer/signatures.js";
|
|
14
|
+
import { findCommentInHierarchicalPageIpfsRecursively, findCommentInPageInstance, mapPageIpfsCommentToPageJsonComment, TIMEFRAMES_TO_SECONDS } from "../pages/util.js";
|
|
15
|
+
import { importSignerIntoKuboNode } from "../runtime/node/util.js";
|
|
16
|
+
import { getIpfsKeyFromPrivateKey, getPKCAddressFromPublicKeySync } from "../signer/util.js";
|
|
17
|
+
import { Buffer } from "buffer";
|
|
18
|
+
import { encryptEd25519AesGcm, encryptEd25519AesGcmPublicKeyBuffer } from "../signer/encryption.js";
|
|
19
|
+
import env from "../version.js";
|
|
20
|
+
import { PKCError } from "../pkc-error.js";
|
|
21
|
+
import last from "it-last";
|
|
22
|
+
import { buildRuntimeAuthor } from "../publications/publication-author.js";
|
|
23
|
+
const defaultMockResolverRecords = new Map([
|
|
24
|
+
["plebbit.eth", "12D3KooWNMYPSuNadceoKsJ6oUQcxGcfiAsHNpVTt1RQ1zSrKKpo"],
|
|
25
|
+
["plebbit.bso", "12D3KooWNMYPSuNadceoKsJ6oUQcxGcfiAsHNpVTt1RQ1zSrKKpo"],
|
|
26
|
+
["rpc-edit-test.eth", "12D3KooWMZPQsQdYtrakc4D1XtzGXwN1X3DBnAobcCjcPYYXTB6o"],
|
|
27
|
+
["rpc-edit-test.bso", "12D3KooWMZPQsQdYtrakc4D1XtzGXwN1X3DBnAobcCjcPYYXTB6o"],
|
|
28
|
+
// Resolves to signers[0] — used by key migration tests where record is signed by a different key
|
|
29
|
+
["migration-test.bso", "12D3KooWN5rLmRJ8fWMwTtkDN7w2RgPPGRM4mtWTnfbjpi1Sh7zR"],
|
|
30
|
+
["migrating.bso", "12D3KooWN5rLmRJ8fWMwTtkDN7w2RgPPGRM4mtWTnfbjpi1Sh7zR"],
|
|
31
|
+
// Resolves to signers[3] but record has name "plebbit.bso" — used by name mismatch rejection test
|
|
32
|
+
["wrong-name.bso", "12D3KooWNMYPSuNadceoKsJ6oUQcxGcfiAsHNpVTt1RQ1zSrKKpo"],
|
|
33
|
+
// Resolves to signers[4] — used by resolver tests where client signs with signers[6] but server resolves to a different key
|
|
34
|
+
["testgibbreish.bso", "12D3KooWJrsheZoiATwG4Z6EJpNqo1v11wpHLcnMECqa4mneZiho"]
|
|
35
|
+
]);
|
|
36
|
+
function getMockResolverRecord(records, name) {
|
|
37
|
+
if (records instanceof Map)
|
|
38
|
+
return { found: records.has(name), value: records.get(name) };
|
|
39
|
+
if (records && Object.prototype.hasOwnProperty.call(records, name))
|
|
40
|
+
return { found: true, value: records[name] };
|
|
41
|
+
return { found: false, value: undefined };
|
|
42
|
+
}
|
|
43
|
+
export function createMockNameResolver({ records, includeDefaultRecords = false, key = "mock-resolver", provider = "mock", canResolve, resolveFunction } = {}) {
|
|
44
|
+
return {
|
|
45
|
+
key,
|
|
46
|
+
canResolve: canResolve || (() => true),
|
|
47
|
+
resolve: resolveFunction ||
|
|
48
|
+
(async ({ name }) => {
|
|
49
|
+
console.log(`Attempting to mock resolve address (${name})`);
|
|
50
|
+
const record = getMockResolverRecord(records, name);
|
|
51
|
+
if (record.found)
|
|
52
|
+
return record.value ? { publicKey: record.value } : undefined;
|
|
53
|
+
const defaultRecord = includeDefaultRecords ? getMockResolverRecord(defaultMockResolverRecords, name) : undefined;
|
|
54
|
+
if (defaultRecord?.found)
|
|
55
|
+
return defaultRecord.value ? { publicKey: defaultRecord.value } : undefined;
|
|
56
|
+
return undefined;
|
|
57
|
+
}),
|
|
58
|
+
provider
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function createPendingApprovalChallenge(overrides = {}) {
|
|
62
|
+
const { options, exclude, ...rest } = overrides;
|
|
63
|
+
return {
|
|
64
|
+
...rest,
|
|
65
|
+
name: rest.name ?? "question",
|
|
66
|
+
options: {
|
|
67
|
+
question: "Pending approval password?",
|
|
68
|
+
answer: "pending",
|
|
69
|
+
...(options ?? {})
|
|
70
|
+
},
|
|
71
|
+
pendingApproval: rest.pendingApproval ?? true,
|
|
72
|
+
exclude: exclude ?? [{ role: ["moderator"] }]
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function generateRandomTimestamp(parentTimestamp) {
|
|
76
|
+
const [lowerLimit, upperLimit] = [typeof parentTimestamp === "number" && parentTimestamp > 2 ? parentTimestamp : 2, timestamp()];
|
|
77
|
+
let randomTimestamp = -1;
|
|
78
|
+
while (randomTimestamp === -1) {
|
|
79
|
+
const randomTimeframeIndex = (remeda.keys.strict(TIMEFRAMES_TO_SECONDS).length * Math.random()) << 0;
|
|
80
|
+
const tempTimestamp = lowerLimit + Object.values(TIMEFRAMES_TO_SECONDS)[randomTimeframeIndex];
|
|
81
|
+
if (tempTimestamp >= lowerLimit && tempTimestamp <= upperLimit)
|
|
82
|
+
randomTimestamp = tempTimestamp;
|
|
83
|
+
}
|
|
84
|
+
return randomTimestamp;
|
|
85
|
+
}
|
|
86
|
+
export async function generateMockPost({ communityAddress, pkc, randomTimestamp = false, postProps = {} }) {
|
|
87
|
+
const postTimestamp = (randomTimestamp && generateRandomTimestamp()) || timestamp();
|
|
88
|
+
const postStartTestTime = Date.now() / 1000 + Math.random();
|
|
89
|
+
const signer = postProps?.signer || (await pkc.createSigner());
|
|
90
|
+
const baseProps = {
|
|
91
|
+
communityAddress,
|
|
92
|
+
author: { displayName: `Mock Author - ${postStartTestTime}` },
|
|
93
|
+
title: `Mock Post - ${postStartTestTime}`,
|
|
94
|
+
content: `Mock content - ${postStartTestTime}`,
|
|
95
|
+
signer,
|
|
96
|
+
timestamp: postTimestamp
|
|
97
|
+
};
|
|
98
|
+
const finalPostProps = remeda.mergeDeep(baseProps, postProps);
|
|
99
|
+
const post = await pkc.createComment(finalPostProps);
|
|
100
|
+
return post;
|
|
101
|
+
}
|
|
102
|
+
// TODO rework this
|
|
103
|
+
export async function generateMockComment(parentPostOrComment, pkc, randomTimestamp = false, commentProps = {}) {
|
|
104
|
+
const commentTimestamp = (randomTimestamp && generateRandomTimestamp(parentPostOrComment.timestamp)) || timestamp();
|
|
105
|
+
const commentTime = Date.now() / 1000 + Math.random();
|
|
106
|
+
const signer = commentProps?.signer || (await pkc.createSigner());
|
|
107
|
+
const comment = await pkc.createComment({
|
|
108
|
+
author: { displayName: `Mock Author - ${commentTime}` },
|
|
109
|
+
signer: signer,
|
|
110
|
+
content: `Mock comment - ${commentTime}`,
|
|
111
|
+
parentCid: parentPostOrComment.cid,
|
|
112
|
+
postCid: parentPostOrComment.postCid,
|
|
113
|
+
communityAddress: getCommunityAddressFromRecord(parentPostOrComment),
|
|
114
|
+
timestamp: commentTimestamp,
|
|
115
|
+
...commentProps
|
|
116
|
+
});
|
|
117
|
+
return comment;
|
|
118
|
+
}
|
|
119
|
+
export async function generateMockVote(parentPostOrComment, vote, pkc, signer) {
|
|
120
|
+
const voteTime = Date.now() / 1000;
|
|
121
|
+
const commentCid = parentPostOrComment.cid;
|
|
122
|
+
if (typeof commentCid !== "string")
|
|
123
|
+
throw Error(`generateMockVote: commentCid (${commentCid}) is not a valid CID`);
|
|
124
|
+
signer = signer || (await pkc.createSigner());
|
|
125
|
+
const voteObj = await pkc.createVote({
|
|
126
|
+
author: { displayName: `Mock Author - ${voteTime}` },
|
|
127
|
+
signer: signer,
|
|
128
|
+
commentCid,
|
|
129
|
+
vote,
|
|
130
|
+
communityAddress: getCommunityAddressFromRecord(parentPostOrComment)
|
|
131
|
+
});
|
|
132
|
+
return voteObj;
|
|
133
|
+
}
|
|
134
|
+
export async function loadAllPages(pageCid, pagesInstance) {
|
|
135
|
+
if (!pageCid)
|
|
136
|
+
throw Error("Can't load all pages with undefined pageCid");
|
|
137
|
+
let sortedCommentsPage = await pagesInstance.getPage({ cid: pageCid });
|
|
138
|
+
let sortedComments = sortedCommentsPage.comments;
|
|
139
|
+
while (sortedCommentsPage.nextCid) {
|
|
140
|
+
sortedCommentsPage = await pagesInstance.getPage({ cid: sortedCommentsPage.nextCid });
|
|
141
|
+
sortedComments = sortedComments.concat(sortedCommentsPage.comments);
|
|
142
|
+
}
|
|
143
|
+
return sortedComments;
|
|
144
|
+
}
|
|
145
|
+
export async function loadAllPagesBySortName(pageSortName, pagesInstance) {
|
|
146
|
+
if (!pageSortName)
|
|
147
|
+
throw Error("Can't load all pages with undefined pageSortName");
|
|
148
|
+
if (Object.keys(pagesInstance.pageCids).length === 0 && pagesInstance.pages && pagesInstance.pages[pageSortName])
|
|
149
|
+
return pagesInstance.pages[pageSortName].comments;
|
|
150
|
+
let sortedCommentsPage = (pagesInstance.pages && pagesInstance.pages[pageSortName]) ||
|
|
151
|
+
(await pagesInstance.getPage({ cid: pagesInstance.pageCids[pageSortName] }));
|
|
152
|
+
let sortedComments = sortedCommentsPage.comments;
|
|
153
|
+
while (sortedCommentsPage.nextCid) {
|
|
154
|
+
sortedCommentsPage = await pagesInstance.getPage({ cid: sortedCommentsPage.nextCid });
|
|
155
|
+
//@ts-expect-error
|
|
156
|
+
sortedComments = sortedComments.concat(sortedCommentsPage.comments);
|
|
157
|
+
}
|
|
158
|
+
return sortedComments;
|
|
159
|
+
}
|
|
160
|
+
export async function loadAllUniquePostsUnderCommunity(community) {
|
|
161
|
+
if (Object.keys(community.posts.pageCids).length === 0 && Object.keys(community.posts.pages).length === 0)
|
|
162
|
+
return [];
|
|
163
|
+
const allCommentsInPreloadedPages = Object.keys(community.posts.pageCids).length === 0 && Object.keys(community.posts.pages).length > 0;
|
|
164
|
+
if (allCommentsInPreloadedPages) {
|
|
165
|
+
const allComments = community.posts.pages.hot?.comments;
|
|
166
|
+
if (!allComments)
|
|
167
|
+
throw Error("No comments found under community.posts.pages.hot");
|
|
168
|
+
return allComments;
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
// we have multiple pages, need to load all pages and merge them
|
|
172
|
+
return loadAllPages(community.posts.pageCids.new, community.posts);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
export async function loadAllUniqueCommentsUnderCommentInstance(comment) {
|
|
176
|
+
if (Object.keys(comment.replies.pageCids).length === 0 && Object.keys(comment.replies.pages).length === 0)
|
|
177
|
+
throw Error("Comment replies instance has no comments under it");
|
|
178
|
+
const allCommentsInPreloadedPages = Object.keys(comment.replies.pageCids).length === 0 && Object.keys(comment.replies.pages).length > 0;
|
|
179
|
+
if (allCommentsInPreloadedPages) {
|
|
180
|
+
const allComments = comment.replies.pages.best?.comments;
|
|
181
|
+
if (!allComments)
|
|
182
|
+
throw Error("No comments found under comment.replies.pages.best");
|
|
183
|
+
return allComments;
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
// we have multiple pages, need to load all pages and merge them
|
|
187
|
+
return loadAllPages(comment.replies.pageCids.new, comment.replies);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async function _mockCommunityPKC(signer, pkcOptions) {
|
|
191
|
+
const pkc = await mockPKC({ ...pkcOptions, pubsubKuboRpcClientsOptions: ["http://localhost:15002/api/v0"] }, true);
|
|
192
|
+
return pkc;
|
|
193
|
+
}
|
|
194
|
+
async function _startMathCliCommunity(signer, pkc) {
|
|
195
|
+
const community = await pkc.createCommunity({ signer });
|
|
196
|
+
await community.edit({ settings: { challenges: [{ name: "question", options: { question: "1+1=?", answer: "2" } }] } });
|
|
197
|
+
await community.start();
|
|
198
|
+
return community;
|
|
199
|
+
}
|
|
200
|
+
async function _startEnsCommunity(signers, pkc) {
|
|
201
|
+
const signer = await pkc.createSigner(signers[3]);
|
|
202
|
+
const community = (await createSubWithNoChallenge({ signer }, pkc));
|
|
203
|
+
await community.edit({
|
|
204
|
+
roles: {
|
|
205
|
+
[signers[1].address]: { role: "owner" },
|
|
206
|
+
[signers[2].address]: { role: "admin" },
|
|
207
|
+
[signers[3].address]: { role: "moderator" }
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
await community.start();
|
|
211
|
+
await community.edit({ address: "plebbit.bso" });
|
|
212
|
+
assert.equal(community.address, "plebbit.bso");
|
|
213
|
+
return community;
|
|
214
|
+
}
|
|
215
|
+
async function _publishPosts(communityAddress, numOfPosts, pkc) {
|
|
216
|
+
return Promise.all(new Array(numOfPosts).fill(null).map(() => publishRandomPost({ communityAddress, pkc })));
|
|
217
|
+
}
|
|
218
|
+
async function _publishReplies(parentComment, numOfReplies, pkc) {
|
|
219
|
+
return Promise.all(new Array(numOfReplies).fill(null).map(() => publishRandomReply({ parentComment, pkc })));
|
|
220
|
+
}
|
|
221
|
+
async function _publishVotesOnOneComment(comment, votesPerCommentToPublish, pkc) {
|
|
222
|
+
return Promise.all(new Array(votesPerCommentToPublish).fill(null).map(() => publishVote({
|
|
223
|
+
commentCid: comment.cid,
|
|
224
|
+
communityAddress: comment.communityAddress,
|
|
225
|
+
vote: Math.random() > 0.5 ? 1 : -1,
|
|
226
|
+
pkc
|
|
227
|
+
})));
|
|
228
|
+
}
|
|
229
|
+
async function _publishVotes(comments, votesPerCommentToPublish, pkc) {
|
|
230
|
+
const votes = remeda.flattenDeep(await Promise.all(comments.map((comment) => _publishVotesOnOneComment(comment, votesPerCommentToPublish, pkc))));
|
|
231
|
+
assert.equal(votes.length, votesPerCommentToPublish * comments.length);
|
|
232
|
+
console.log(`${votes.length} votes for ${comments.length} ${comments[0].depth === 0 ? "posts" : "replies"} have been published`);
|
|
233
|
+
return votes;
|
|
234
|
+
}
|
|
235
|
+
async function _populateCommunity(community, props) {
|
|
236
|
+
await community.edit({
|
|
237
|
+
roles: {
|
|
238
|
+
[props.signers[1].address]: { role: "owner" },
|
|
239
|
+
[props.signers[2].address]: { role: "admin" },
|
|
240
|
+
[props.signers[3].address]: { role: "moderator" }
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
if (props.numOfPostsToPublish === 0)
|
|
244
|
+
return;
|
|
245
|
+
await new Promise((resolve) => community.once("update", resolve));
|
|
246
|
+
const posts = await _publishPosts(community.address, props.numOfPostsToPublish, community._pkc); // If no comment[] is provided, we publish posts
|
|
247
|
+
console.log(`Have successfully published ${posts.length} posts`);
|
|
248
|
+
const replies = await _publishReplies(posts[0], props.numOfCommentsToPublish, community._pkc);
|
|
249
|
+
console.log(`Have sucessfully published ${replies.length} replies`);
|
|
250
|
+
const postVotes = await _publishVotes(posts, props.votesPerCommentToPublish, community._pkc);
|
|
251
|
+
console.log(`Have sucessfully published ${postVotes.length} votes on ${posts.length} posts`);
|
|
252
|
+
const repliesVotes = await _publishVotes(replies, props.votesPerCommentToPublish, community._pkc);
|
|
253
|
+
console.log(`Have successfully published ${repliesVotes.length} votes on ${replies.length} replies`);
|
|
254
|
+
}
|
|
255
|
+
export async function startOnlineCommunity() {
|
|
256
|
+
const onlinePKC = await createOnlinePKC();
|
|
257
|
+
const onlineCommunity = await onlinePKC.createCommunity(); // Will create a new community that is on the ipfs network
|
|
258
|
+
await onlineCommunity.edit({ settings: { challenges: [{ name: "question", options: { question: "1+1=?", answer: "2" } }] } });
|
|
259
|
+
await onlineCommunity.start();
|
|
260
|
+
await new Promise((resolve) => onlineCommunity.once("update", resolve));
|
|
261
|
+
console.log("Online community is online on address", onlineCommunity.address);
|
|
262
|
+
return onlineCommunity;
|
|
263
|
+
}
|
|
264
|
+
export async function startCommunities(props) {
|
|
265
|
+
const pkc = await _mockCommunityPKC(props.signers, {
|
|
266
|
+
...remeda.pick(props, ["noData", "dataPath"]),
|
|
267
|
+
publishInterval: 1000,
|
|
268
|
+
updateInterval: 1000
|
|
269
|
+
});
|
|
270
|
+
const mainCommunity = (await createSubWithNoChallenge({ signer: props.signers[0] }, pkc)); // most publications will be on this community
|
|
271
|
+
// Enable flair features and set allowed flairs for flair tests
|
|
272
|
+
await mainCommunity.edit({
|
|
273
|
+
features: { postFlairs: true },
|
|
274
|
+
flairs: {
|
|
275
|
+
post: [{ text: "Author Flair" }, { text: "Discussion" }, { text: "Updated" }, { text: "Important", backgroundColor: "#ff0000" }]
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
await mainCommunity.start();
|
|
279
|
+
const mathSub = await _startMathCliCommunity(props.signers[1], pkc);
|
|
280
|
+
const ensSub = await _startEnsCommunity(props.signers, pkc);
|
|
281
|
+
console.time("populate");
|
|
282
|
+
await _populateCommunity(mainCommunity, props);
|
|
283
|
+
console.timeEnd("populate");
|
|
284
|
+
let onlineSub;
|
|
285
|
+
if (props.startOnlineSub)
|
|
286
|
+
onlineSub = await startOnlineCommunity();
|
|
287
|
+
console.log("All communities and ipfs nodes have been started. You are ready to run the tests");
|
|
288
|
+
const subWithNoResponse = (await createSubWithNoChallenge({ signer: props.signers[4] }, pkc));
|
|
289
|
+
await subWithNoResponse.start();
|
|
290
|
+
await new Promise((resolve) => subWithNoResponse.once("update", resolve));
|
|
291
|
+
await subWithNoResponse.stop();
|
|
292
|
+
const pkcNoMockedSub = await mockPKC({ kuboRpcClientsOptions: ["http://localhost:15002/api/v0"], pubsubKuboRpcClientsOptions: ["http://localhost:15002/api/v0"] }, false, true, true);
|
|
293
|
+
const mathCliSubWithNoMockedPubsub = await _startMathCliCommunity(props.signers[5], pkcNoMockedSub);
|
|
294
|
+
await new Promise((resolve) => mathCliSubWithNoMockedPubsub.once("update", resolve));
|
|
295
|
+
const subForPurge = (await createSubWithNoChallenge({ signer: props.signers[6] }, pkc));
|
|
296
|
+
await subForPurge.edit({
|
|
297
|
+
roles: {
|
|
298
|
+
[props.signers[1].address]: { role: "owner" },
|
|
299
|
+
[props.signers[2].address]: { role: "admin" },
|
|
300
|
+
[props.signers[3].address]: { role: "moderator" }
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
await subForPurge.start();
|
|
304
|
+
await new Promise((resolve) => subForPurge.once("update", resolve));
|
|
305
|
+
const subForRemove = (await createSubWithNoChallenge({ signer: props.signers[7] }, pkc));
|
|
306
|
+
await subForRemove.edit({
|
|
307
|
+
roles: {
|
|
308
|
+
[props.signers[1].address]: { role: "owner" },
|
|
309
|
+
[props.signers[2].address]: { role: "admin" },
|
|
310
|
+
[props.signers[3].address]: { role: "moderator" }
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
await subForRemove.start();
|
|
314
|
+
await new Promise((resolve) => subForRemove.once("update", resolve));
|
|
315
|
+
const subForDelete = (await createSubWithNoChallenge({ signer: props.signers[8] }, pkc));
|
|
316
|
+
await subForDelete.edit({
|
|
317
|
+
roles: {
|
|
318
|
+
[props.signers[1].address]: { role: "owner" },
|
|
319
|
+
[props.signers[2].address]: { role: "admin" },
|
|
320
|
+
[props.signers[3].address]: { role: "moderator" }
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
await subForDelete.start();
|
|
324
|
+
await new Promise((resolve) => subForDelete.once("update", resolve));
|
|
325
|
+
const subForChainProviders = (await createSubWithNoChallenge({ signer: props.signers[9] }, pkc));
|
|
326
|
+
await subForChainProviders.start();
|
|
327
|
+
await new Promise((resolve) => subForChainProviders.once("update", resolve));
|
|
328
|
+
const subForEditContent = (await createSubWithNoChallenge({ signer: props.signers[10] }, pkc));
|
|
329
|
+
await subForEditContent.edit({
|
|
330
|
+
roles: {
|
|
331
|
+
[props.signers[1].address]: { role: "owner" },
|
|
332
|
+
[props.signers[2].address]: { role: "admin" },
|
|
333
|
+
[props.signers[3].address]: { role: "moderator" }
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
await subForEditContent.start();
|
|
337
|
+
await new Promise((resolve) => subForEditContent.once("update", resolve));
|
|
338
|
+
const subForLocked = (await createSubWithNoChallenge({ signer: props.signers[11] }, pkc));
|
|
339
|
+
await subForLocked.edit({
|
|
340
|
+
roles: {
|
|
341
|
+
[props.signers[1].address]: { role: "owner" },
|
|
342
|
+
[props.signers[2].address]: { role: "admin" },
|
|
343
|
+
[props.signers[3].address]: { role: "moderator" }
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
await subForLocked.start();
|
|
347
|
+
await new Promise((resolve) => subForLocked.once("update", resolve));
|
|
348
|
+
return {
|
|
349
|
+
onlineSub: onlineSub,
|
|
350
|
+
mathSub: mathSub,
|
|
351
|
+
ensSub: ensSub,
|
|
352
|
+
mainSub: mainCommunity,
|
|
353
|
+
NoPubsubResponseSub: subWithNoResponse,
|
|
354
|
+
mathCliSubWithNoMockedPubsub: mathCliSubWithNoMockedPubsub,
|
|
355
|
+
subForPurge: subForPurge,
|
|
356
|
+
subForRemove: subForRemove,
|
|
357
|
+
subForDelete: subForDelete,
|
|
358
|
+
subForChainProviders: subForChainProviders,
|
|
359
|
+
subForEditContent: subForEditContent,
|
|
360
|
+
subForLocked: subForLocked
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
export async function fetchTestServerSubs() {
|
|
364
|
+
const res = await fetch("http://localhost:14953");
|
|
365
|
+
const resWithType = await res.json();
|
|
366
|
+
return resWithType;
|
|
367
|
+
}
|
|
368
|
+
export function mockDefaultOptionsForNodeAndBrowserTests() {
|
|
369
|
+
const shouldUseRPC = isRpcFlagOn();
|
|
370
|
+
if (shouldUseRPC)
|
|
371
|
+
return { pkcRpcClientsOptions: ["ws://localhost:39652"], httpRoutersOptions: [] };
|
|
372
|
+
else
|
|
373
|
+
return {
|
|
374
|
+
kuboRpcClientsOptions: ["http://localhost:15001/api/v0"],
|
|
375
|
+
pubsubKuboRpcClientsOptions: [
|
|
376
|
+
`http://localhost:15002/api/v0`,
|
|
377
|
+
`http://localhost:42234/api/v0`,
|
|
378
|
+
`http://localhost:42254/api/v0`
|
|
379
|
+
],
|
|
380
|
+
httpRoutersOptions: []
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
export async function mockPKCV2({ pkcOptions, forceMockPubsub, stubStorage, mockResolve, remotePKC } = {}) {
|
|
384
|
+
if (remotePKC)
|
|
385
|
+
pkcOptions = { dataPath: undefined, ...pkcOptions };
|
|
386
|
+
const pkc = await mockPKC(pkcOptions, forceMockPubsub, stubStorage, mockResolve);
|
|
387
|
+
return pkc;
|
|
388
|
+
}
|
|
389
|
+
export async function mockPKC(pkcOptions, forceMockPubsub = false, stubStorage = true, mockResolve = true) {
|
|
390
|
+
const log = Logger("pkc-js:test-util:mockPKC");
|
|
391
|
+
if (pkcOptions?.pkcRpcClientsOptions && pkcOptions?.kuboRpcClientsOptions)
|
|
392
|
+
throw Error("Can't have both kubo and RPC config. Is this a mistake?");
|
|
393
|
+
if (pkcOptions?.pkcRpcClientsOptions && pkcOptions?.libp2pJsClientsOptions)
|
|
394
|
+
throw Error("Can't have both libp2p and RPC config. Is this a mistake?");
|
|
395
|
+
const mockNameResolvers = mockResolve ? [createMockNameResolver({ includeDefaultRecords: true })] : undefined;
|
|
396
|
+
const pkc = await PKCIndex({
|
|
397
|
+
...mockDefaultOptionsForNodeAndBrowserTests(),
|
|
398
|
+
resolveAuthorNames: true,
|
|
399
|
+
publishInterval: 1000,
|
|
400
|
+
validatePages: false,
|
|
401
|
+
updateInterval: 500,
|
|
402
|
+
nameResolvers: mockNameResolvers,
|
|
403
|
+
...pkcOptions
|
|
404
|
+
});
|
|
405
|
+
if (stubStorage) {
|
|
406
|
+
pkc._storage.getItem = async () => undefined;
|
|
407
|
+
pkc._storage.setItem = async () => undefined;
|
|
408
|
+
}
|
|
409
|
+
// TODO should have multiple pubsub providers here to emulate a real browser/mobile environment
|
|
410
|
+
if (!pkcOptions?.pubsubKuboRpcClientsOptions || forceMockPubsub)
|
|
411
|
+
for (const pubsubUrl of remeda.keys.strict(pkc.clients.pubsubKuboRpcClients)) {
|
|
412
|
+
const mockClient = createMockPubsubClient();
|
|
413
|
+
pkc.clients.pubsubKuboRpcClients[pubsubUrl]._client = mockClient;
|
|
414
|
+
pkc.clients.pubsubKuboRpcClients[pubsubUrl].destroy = mockClient.destroy.bind(mockClient);
|
|
415
|
+
}
|
|
416
|
+
pkc.on("error", (e) => {
|
|
417
|
+
log.error("PKC error", e);
|
|
418
|
+
});
|
|
419
|
+
return pkc;
|
|
420
|
+
}
|
|
421
|
+
// name should be changed to mockBrowserPKC
|
|
422
|
+
export async function mockRemotePKC(opts) {
|
|
423
|
+
// Mock browser environment
|
|
424
|
+
const pkc = await mockPKCV2({ ...opts, pkcOptions: { dataPath: undefined, ...opts?.pkcOptions } });
|
|
425
|
+
pkc._canCreateNewLocalCommunity = () => false;
|
|
426
|
+
return pkc;
|
|
427
|
+
}
|
|
428
|
+
export async function createOnlinePKC(pkcOptions) {
|
|
429
|
+
const pkc = await PKCIndex({
|
|
430
|
+
kuboRpcClientsOptions: ["http://localhost:15003/api/v0"],
|
|
431
|
+
pubsubKuboRpcClientsOptions: ["http://localhost:15003/api/v0"],
|
|
432
|
+
...pkcOptions
|
|
433
|
+
}); // use online ipfs node
|
|
434
|
+
return pkc;
|
|
435
|
+
}
|
|
436
|
+
export async function mockPKCNoDataPathWithOnlyKuboClient(opts) {
|
|
437
|
+
const pkc = await mockPKCV2({
|
|
438
|
+
...opts,
|
|
439
|
+
pkcOptions: {
|
|
440
|
+
kuboRpcClientsOptions: ["http://localhost:15001/api/v0"],
|
|
441
|
+
pkcRpcClientsOptions: undefined,
|
|
442
|
+
dataPath: undefined,
|
|
443
|
+
...opts?.pkcOptions
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
return pkc;
|
|
447
|
+
}
|
|
448
|
+
export async function mockPKCNoDataPathWithOnlyKuboClientNoAdd(opts) {
|
|
449
|
+
const pkc = await mockPKCV2({
|
|
450
|
+
...opts,
|
|
451
|
+
pkcOptions: {
|
|
452
|
+
kuboRpcClientsOptions: ["http://localhost:15001/api/v0"],
|
|
453
|
+
pkcRpcClientsOptions: undefined,
|
|
454
|
+
dataPath: undefined,
|
|
455
|
+
...opts?.pkcOptions
|
|
456
|
+
}
|
|
457
|
+
});
|
|
458
|
+
Object.values(pkc.clients.kuboRpcClients)[0]._client.add = () => {
|
|
459
|
+
throw Error("Add is not supported");
|
|
460
|
+
};
|
|
461
|
+
return pkc;
|
|
462
|
+
}
|
|
463
|
+
export async function mockRpcServerPKC(pkcOptions) {
|
|
464
|
+
const pkc = await mockPKCV2({
|
|
465
|
+
pkcOptions: {
|
|
466
|
+
kuboRpcClientsOptions: ["http://localhost:15001/api/v0"],
|
|
467
|
+
...pkcOptions,
|
|
468
|
+
pkcRpcClientsOptions: undefined
|
|
469
|
+
},
|
|
470
|
+
mockResolve: true,
|
|
471
|
+
forceMockPubsub: true,
|
|
472
|
+
remotePKC: false,
|
|
473
|
+
stubStorage: true // we want storage to force new resolve-community-address states
|
|
474
|
+
});
|
|
475
|
+
pkc.removeAllListeners("error"); // for rpc server, we want to test the error handling
|
|
476
|
+
return pkc;
|
|
477
|
+
}
|
|
478
|
+
export async function mockRpcRemotePKC(opts) {
|
|
479
|
+
if (!isRpcFlagOn())
|
|
480
|
+
throw Error("This function should only be used when the rpc flag is on");
|
|
481
|
+
// This instance will connect to an rpc server that has no local subs
|
|
482
|
+
const pkc = await mockPKCV2({
|
|
483
|
+
...opts,
|
|
484
|
+
pkcOptions: {
|
|
485
|
+
pkcRpcClientsOptions: ["ws://localhost:39653"],
|
|
486
|
+
dataPath: undefined,
|
|
487
|
+
...opts?.pkcOptions
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
return pkc;
|
|
491
|
+
}
|
|
492
|
+
export async function mockRPCLocalPKC(pkcOptions) {
|
|
493
|
+
if (!isRpcFlagOn())
|
|
494
|
+
throw Error("This function should only be used when the rpc flag is on");
|
|
495
|
+
// This instance will connect to an rpc server that local subs
|
|
496
|
+
return mockPKC({ pkcRpcClientsOptions: ["ws://localhost:39652"], ...pkcOptions });
|
|
497
|
+
}
|
|
498
|
+
export async function mockGatewayPKC(opts) {
|
|
499
|
+
// Keep only pubsub and gateway
|
|
500
|
+
const pkc = await mockPKCV2({
|
|
501
|
+
...opts,
|
|
502
|
+
pkcOptions: {
|
|
503
|
+
ipfsGatewayUrls: ["http://localhost:18080"],
|
|
504
|
+
pkcRpcClientsOptions: undefined,
|
|
505
|
+
kuboRpcClientsOptions: undefined,
|
|
506
|
+
pubsubKuboRpcClientsOptions: undefined,
|
|
507
|
+
libp2pJsClientsOptions: undefined,
|
|
508
|
+
...opts?.pkcOptions
|
|
509
|
+
},
|
|
510
|
+
remotePKC: true
|
|
511
|
+
});
|
|
512
|
+
return pkc;
|
|
513
|
+
}
|
|
514
|
+
export async function publishRandomReply({ parentComment, pkc, commentProps }) {
|
|
515
|
+
const reply = await generateMockComment(parentComment, pkc, false, {
|
|
516
|
+
content: `Content ${uuidv4()}`,
|
|
517
|
+
...commentProps
|
|
518
|
+
});
|
|
519
|
+
await publishWithExpectedResult({ publication: reply, expectedChallengeSuccess: true });
|
|
520
|
+
return reply;
|
|
521
|
+
}
|
|
522
|
+
export async function publishRandomPost({ communityAddress, pkc, postProps }) {
|
|
523
|
+
const post = await generateMockPost({
|
|
524
|
+
communityAddress,
|
|
525
|
+
pkc,
|
|
526
|
+
postProps: {
|
|
527
|
+
content: `Random post Content ${uuidv4()}`,
|
|
528
|
+
title: `Random post Title ${uuidv4()}`,
|
|
529
|
+
...postProps
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
await publishWithExpectedResult({ publication: post, expectedChallengeSuccess: true });
|
|
533
|
+
return post;
|
|
534
|
+
}
|
|
535
|
+
export async function publishVote({ commentCid, communityAddress, vote, pkc, voteProps }) {
|
|
536
|
+
const voteObj = await pkc.createVote({
|
|
537
|
+
commentCid,
|
|
538
|
+
vote,
|
|
539
|
+
communityAddress,
|
|
540
|
+
signer: voteProps?.signer || (await pkc.createSigner()),
|
|
541
|
+
...voteProps
|
|
542
|
+
});
|
|
543
|
+
await publishWithExpectedResult({ publication: voteObj, expectedChallengeSuccess: true });
|
|
544
|
+
return voteObj;
|
|
545
|
+
}
|
|
546
|
+
async function _publishWithExpectedResultOnce({ publication, expectedChallengeSuccess, expectedReason }) {
|
|
547
|
+
const emittedErrors = [];
|
|
548
|
+
const timeoutMs = 60000;
|
|
549
|
+
const summarizePublication = () => removeUndefinedValuesRecursively({
|
|
550
|
+
type: publication.constructor?.name,
|
|
551
|
+
cid: publication.cid,
|
|
552
|
+
parentCid: publication.parentCid,
|
|
553
|
+
communityAddress: publication.communityAddress,
|
|
554
|
+
signerAddress: publication.signer?.address,
|
|
555
|
+
commentModeration: publication.commentModeration
|
|
556
|
+
? remeda.pick(publication.commentModeration, ["approved", "reason", "spoiler", "nsfw", "pinned", "removed"])
|
|
557
|
+
: undefined
|
|
558
|
+
});
|
|
559
|
+
publication.on("error", (err) => emittedErrors.push(err));
|
|
560
|
+
let cleanupChallengeVerificationListener;
|
|
561
|
+
const challengeVerificationPromise = new Promise((resolve, reject) => {
|
|
562
|
+
const challengeVerificationListener = (verificationMsg) => {
|
|
563
|
+
if (verificationMsg.challengeSuccess !== expectedChallengeSuccess) {
|
|
564
|
+
const msg = `Expected challengeSuccess to be (${expectedChallengeSuccess}) and got (${verificationMsg.challengeSuccess}). Reason (${verificationMsg.reason}): ${JSON.stringify(remeda.omit(verificationMsg, ["encrypted", "signature", "challengeRequestId"]))}`;
|
|
565
|
+
reject(msg);
|
|
566
|
+
}
|
|
567
|
+
else if (expectedReason && expectedReason !== verificationMsg.reason) {
|
|
568
|
+
const msg = `Expected reason to be (${expectedReason}) and got (${verificationMsg.reason}): ${JSON.stringify(remeda.omit(verificationMsg, ["encrypted", "signature", "challengeRequestId"]))}`;
|
|
569
|
+
reject(msg);
|
|
570
|
+
}
|
|
571
|
+
else
|
|
572
|
+
resolve(1);
|
|
573
|
+
};
|
|
574
|
+
publication.on("challengeverification", challengeVerificationListener);
|
|
575
|
+
cleanupChallengeVerificationListener = () => {
|
|
576
|
+
if (typeof publication.off === "function")
|
|
577
|
+
publication.off("challengeverification", challengeVerificationListener);
|
|
578
|
+
else
|
|
579
|
+
publication.removeListener("challengeverification", challengeVerificationListener);
|
|
580
|
+
};
|
|
581
|
+
});
|
|
582
|
+
const error = new Error("Publication did not receive response");
|
|
583
|
+
//@ts-expect-error
|
|
584
|
+
error.details = {
|
|
585
|
+
publication: summarizePublication(),
|
|
586
|
+
expectedChallengeSuccess,
|
|
587
|
+
expectedReason,
|
|
588
|
+
waitTime: timeoutMs,
|
|
589
|
+
emittedErrorsOnPublicationInstance: emittedErrors
|
|
590
|
+
};
|
|
591
|
+
const validateResponsePromise = pTimeout(challengeVerificationPromise, {
|
|
592
|
+
milliseconds: timeoutMs,
|
|
593
|
+
message: error
|
|
594
|
+
});
|
|
595
|
+
await publication.publish();
|
|
596
|
+
try {
|
|
597
|
+
await validateResponsePromise;
|
|
598
|
+
}
|
|
599
|
+
catch (error) {
|
|
600
|
+
throw error;
|
|
601
|
+
}
|
|
602
|
+
finally {
|
|
603
|
+
cleanupChallengeVerificationListener?.();
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
const retriableSubLoadingCodes = new Set([
|
|
607
|
+
"ERR_FAILED_TO_FETCH_IPFS_CID_VIA_IPFS_P2P",
|
|
608
|
+
"ERR_GET_COMMUNITY_TIMED_OUT",
|
|
609
|
+
"ERR_FAILED_TO_FETCH_COMMUNITY_FROM_GATEWAYS"
|
|
610
|
+
]);
|
|
611
|
+
export async function publishWithExpectedResult({ publication, expectedChallengeSuccess, expectedReason }) {
|
|
612
|
+
const maxAttempts = 3;
|
|
613
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
614
|
+
try {
|
|
615
|
+
await _publishWithExpectedResultOnce({ publication, expectedChallengeSuccess, expectedReason });
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
catch (error) {
|
|
619
|
+
const isRetriable = error instanceof PKCError && retriableSubLoadingCodes.has(error.code);
|
|
620
|
+
if (!isRetriable || attempt === maxAttempts)
|
|
621
|
+
throw error;
|
|
622
|
+
console.log(`publishWithExpectedResult: retrying (attempt ${attempt + 1}/${maxAttempts}) after retriable error: ${error.code}`);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
export async function iterateThroughPageCidToFindComment(commentCid, pageCid, pages) {
|
|
627
|
+
if (!commentCid)
|
|
628
|
+
throw Error("Can't find comment with undefined commentCid");
|
|
629
|
+
if (!pageCid)
|
|
630
|
+
throw Error("Can't find comment with undefined pageCid");
|
|
631
|
+
let currentPageCid = remeda.clone(pageCid);
|
|
632
|
+
while (currentPageCid) {
|
|
633
|
+
const loadedPage = (await pages.getPage({ cid: currentPageCid }));
|
|
634
|
+
const commentInPage = loadedPage.comments.find((c) => c.cid === commentCid);
|
|
635
|
+
if (commentInPage)
|
|
636
|
+
return commentInPage;
|
|
637
|
+
currentPageCid = loadedPage.nextCid;
|
|
638
|
+
}
|
|
639
|
+
return undefined;
|
|
640
|
+
}
|
|
641
|
+
export async function findCommentInCommunityInstancePagesPreloadedAndPageCids(opts) {
|
|
642
|
+
// TODO need to handle, what if the comment is nested deep down the community.posts tree and doesn't appear in preloaded page
|
|
643
|
+
// code below doesn't handle it
|
|
644
|
+
const { community, comment } = opts;
|
|
645
|
+
if (!community)
|
|
646
|
+
throw Error("Failed to provide opts.community");
|
|
647
|
+
if (!comment)
|
|
648
|
+
throw Error("Failed to provde opts.comment");
|
|
649
|
+
if (Object.keys(community.posts.pageCids).length === 0 && Object.keys(community.posts.pages).length > 0) {
|
|
650
|
+
// it's a single preloaded page
|
|
651
|
+
const loadedAllHotPagesComments = (await loadAllPagesBySortName(Object.keys(community.posts.pages)[0], community.posts));
|
|
652
|
+
const pageIpfs = {
|
|
653
|
+
comments: loadedAllHotPagesComments.map((c) => c.raw)
|
|
654
|
+
};
|
|
655
|
+
const postInPage = findCommentInHierarchicalPageIpfsRecursively(pageIpfs, comment.cid);
|
|
656
|
+
if (postInPage)
|
|
657
|
+
return mapPageIpfsCommentToPageJsonComment(postInPage);
|
|
658
|
+
else
|
|
659
|
+
return undefined;
|
|
660
|
+
}
|
|
661
|
+
else if (Object.keys(community.posts?.pageCids).length > 0) {
|
|
662
|
+
const postsNewPageCid = community.posts.pageCids.new;
|
|
663
|
+
const postInPageCid = await iterateThroughPageCidToFindComment(comment.cid, postsNewPageCid, community.posts);
|
|
664
|
+
return postInPageCid;
|
|
665
|
+
}
|
|
666
|
+
else
|
|
667
|
+
return undefined;
|
|
668
|
+
}
|
|
669
|
+
export async function findReplyInParentCommentPagesInstancePreloadedAndPageCids(opts) {
|
|
670
|
+
const { parentComment, reply } = opts;
|
|
671
|
+
const log = Logger("pkc-js:test-util:waitTillReplyInParentPagesInstance");
|
|
672
|
+
if (reply?.parentCid !== parentComment?.cid)
|
|
673
|
+
throw Error("You need to provide a reply that's direct child of parentComment");
|
|
674
|
+
log("waiting for reply", reply.cid, "in parent comment", parentComment.cid, "replyCount of parent comment", parentComment.replyCount);
|
|
675
|
+
// Handle intermediate state where both pageCids and pages are empty
|
|
676
|
+
// This happens during early update events before CommentUpdate with replies is received
|
|
677
|
+
if (Object.keys(parentComment.replies.pageCids).length === 0 && Object.keys(parentComment.replies.pages).length === 0) {
|
|
678
|
+
// No pages loaded yet - this is a valid intermediate state, not an error
|
|
679
|
+
return undefined;
|
|
680
|
+
}
|
|
681
|
+
if (Object.keys(parentComment.replies.pageCids).length === 0 && Object.keys(parentComment.replies.pages).length > 0) {
|
|
682
|
+
// it's a single preloaded page
|
|
683
|
+
const loadedAllBestPagesComments = (await loadAllPagesBySortName(Object.keys(parentComment.replies.pages)[0], parentComment.replies));
|
|
684
|
+
const pageIpfs = {
|
|
685
|
+
comments: loadedAllBestPagesComments.map((c) => c.raw)
|
|
686
|
+
};
|
|
687
|
+
const replyInPage = findCommentInHierarchicalPageIpfsRecursively(pageIpfs, reply.cid);
|
|
688
|
+
if (replyInPage)
|
|
689
|
+
return mapPageIpfsCommentToPageJsonComment(replyInPage);
|
|
690
|
+
else
|
|
691
|
+
return undefined;
|
|
692
|
+
}
|
|
693
|
+
else {
|
|
694
|
+
if (!("new" in parentComment.replies.pageCids)) {
|
|
695
|
+
console.error("no new page", "parentComment.replies.pageCids", parentComment.replies.pageCids);
|
|
696
|
+
return undefined;
|
|
697
|
+
}
|
|
698
|
+
const commentNewPageCid = parentComment.replies.pageCids.new;
|
|
699
|
+
const replyInPage = await iterateThroughPageCidToFindComment(reply.cid, commentNewPageCid, parentComment.replies);
|
|
700
|
+
return replyInPage;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
703
|
+
export async function waitTillPostInCommunityInstancePages(post, community) {
|
|
704
|
+
if (community.state === "stopped")
|
|
705
|
+
await community.update();
|
|
706
|
+
await resolveWhenConditionIsTrue({
|
|
707
|
+
toUpdate: community,
|
|
708
|
+
predicate: async () => Boolean(await findCommentInCommunityInstancePagesPreloadedAndPageCids({ comment: post, community }))
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
export async function waitTillPostInCommunityPages(post, pkc) {
|
|
712
|
+
const community = await pkc.createCommunity({ address: post.communityAddress });
|
|
713
|
+
await waitTillPostInCommunityInstancePages(post, community);
|
|
714
|
+
await community.stop();
|
|
715
|
+
}
|
|
716
|
+
export async function iterateThroughPagesToFindCommentInParentPagesInstance(commentCid, pages) {
|
|
717
|
+
const preloadedPage = Object.keys(pages.pages)[0];
|
|
718
|
+
const commentInPage = findCommentInPageInstance(pages, commentCid);
|
|
719
|
+
if (commentInPage)
|
|
720
|
+
return mapPageIpfsCommentToPageJsonComment(commentInPage);
|
|
721
|
+
if (pages.pages[preloadedPage]?.nextCid || pages.pageCids.new) {
|
|
722
|
+
// means we have multiple pages
|
|
723
|
+
return iterateThroughPageCidToFindComment(commentCid, pages.pageCids.new, pages);
|
|
724
|
+
}
|
|
725
|
+
else
|
|
726
|
+
return undefined;
|
|
727
|
+
}
|
|
728
|
+
export async function waitTillReplyInParentPagesInstance(reply, parentComment) {
|
|
729
|
+
if (parentComment.state === "stopped")
|
|
730
|
+
throw Error("Parent comment is stopped, can't wait for reply in parent pages");
|
|
731
|
+
if (!reply.cid)
|
|
732
|
+
throw Error("reply.cid need to be defined so we can find it in parent pages");
|
|
733
|
+
await resolveWhenConditionIsTrue({
|
|
734
|
+
toUpdate: parentComment,
|
|
735
|
+
predicate: async () => Boolean(await findReplyInParentCommentPagesInstancePreloadedAndPageCids({ reply, parentComment }))
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
export async function waitTillReplyInParentPages(reply, pkc) {
|
|
739
|
+
const parentComment = await pkc.createComment({ cid: reply.parentCid });
|
|
740
|
+
await parentComment.update();
|
|
741
|
+
await waitTillReplyInParentPagesInstance(reply, parentComment);
|
|
742
|
+
await parentComment.stop();
|
|
743
|
+
}
|
|
744
|
+
export async function createSubWithNoChallenge(props, pkc) {
|
|
745
|
+
const community = await pkc.createCommunity(props);
|
|
746
|
+
await community.edit({ settings: { challenges: [] } }); // No challenge
|
|
747
|
+
return community;
|
|
748
|
+
}
|
|
749
|
+
export async function generatePostToAnswerMathQuestion(props, pkc) {
|
|
750
|
+
const mockPost = await generateMockPost({ communityAddress: props.communityAddress, pkc, postProps: props });
|
|
751
|
+
mockPost.removeAllListeners("challenge");
|
|
752
|
+
mockPost.once("challenge", (challengeMessage) => {
|
|
753
|
+
mockPost.publishChallengeAnswers(["2"]);
|
|
754
|
+
});
|
|
755
|
+
return mockPost;
|
|
756
|
+
}
|
|
757
|
+
export function isRpcFlagOn() {
|
|
758
|
+
const isPartOfProcessEnv = globalThis?.["process"]?.env?.["USE_RPC"] === "1";
|
|
759
|
+
// const isPartOfKarmaArgs = globalThis?.["__karma__"]?.config?.config?.["USE_RPC"] === "1";
|
|
760
|
+
return isPartOfProcessEnv;
|
|
761
|
+
}
|
|
762
|
+
export function isRunningInBrowser() {
|
|
763
|
+
const hasWindow = typeof globalThis["window"] !== "undefined";
|
|
764
|
+
const hasDocument = typeof globalThis["window"]?.["document"] !== "undefined";
|
|
765
|
+
const isNodeProcess = typeof globalThis["process"] !== "undefined" && Boolean(globalThis["process"]?.versions?.node);
|
|
766
|
+
const isJsDom = typeof globalThis["navigator"]?.userAgent === "string" && globalThis["navigator"].userAgent.includes("jsdom");
|
|
767
|
+
return hasWindow && hasDocument && !isNodeProcess && !isJsDom;
|
|
768
|
+
}
|
|
769
|
+
export async function resolveWhenConditionIsTrue(options) {
|
|
770
|
+
if (!options) {
|
|
771
|
+
throw Error("resolveWhenConditionIsTrue requires an options object");
|
|
772
|
+
}
|
|
773
|
+
const { toUpdate, predicate, eventName = "update" } = options;
|
|
774
|
+
if (!toUpdate) {
|
|
775
|
+
throw Error("resolveWhenConditionIsTrue options.toUpdate is required");
|
|
776
|
+
}
|
|
777
|
+
if (typeof predicate !== "function") {
|
|
778
|
+
throw Error("resolveWhenConditionIsTrue options.predicate must be a function");
|
|
779
|
+
}
|
|
780
|
+
const normalizedEventName = eventName || "update";
|
|
781
|
+
await new Promise((resolve, reject) => {
|
|
782
|
+
const listener = async () => {
|
|
783
|
+
try {
|
|
784
|
+
const conditionStatus = await predicate();
|
|
785
|
+
if (conditionStatus) {
|
|
786
|
+
toUpdate.removeListener(normalizedEventName, listener);
|
|
787
|
+
resolve();
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
catch (error) {
|
|
791
|
+
toUpdate.removeListener(normalizedEventName, listener);
|
|
792
|
+
reject(error);
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
toUpdate.on(normalizedEventName, listener);
|
|
796
|
+
listener(); // initial check — no await, errors flow through reject()
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
export async function disableValidationOfSignatureBeforePublishing(publication) {
|
|
800
|
+
//@ts-expect-error
|
|
801
|
+
publication._validateSignatureHook = async () => { };
|
|
802
|
+
}
|
|
803
|
+
export async function overrideCommentInstancePropsAndSign(comment, props) {
|
|
804
|
+
if (!comment.signer)
|
|
805
|
+
throw Error("Need comment.signer to overwrite the signature");
|
|
806
|
+
// If deferred signing hasn't populated pubsubMessageToPublish yet,
|
|
807
|
+
// modify the unsigned options so publish() will sign with the overridden props
|
|
808
|
+
const unsignedOpts = comment.raw.unsignedPublicationOptions;
|
|
809
|
+
if (!comment.raw.pubsubMessageToPublish && unsignedOpts) {
|
|
810
|
+
for (const optionKey of remeda.keys.strict(props)) {
|
|
811
|
+
//@ts-expect-error
|
|
812
|
+
comment[optionKey] = unsignedOpts[optionKey] = props[optionKey];
|
|
813
|
+
}
|
|
814
|
+
disableValidationOfSignatureBeforePublishing(comment);
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
const pubsubPublication = remeda.clone(comment.raw.pubsubMessageToPublish);
|
|
818
|
+
for (const optionKey of remeda.keys.strict(props)) {
|
|
819
|
+
//@ts-expect-error
|
|
820
|
+
comment[optionKey] = pubsubPublication[optionKey] = props[optionKey];
|
|
821
|
+
}
|
|
822
|
+
comment.signature = pubsubPublication.signature = await signComment({
|
|
823
|
+
comment: removeUndefinedValuesRecursively({
|
|
824
|
+
...pubsubPublication,
|
|
825
|
+
signer: comment.signer,
|
|
826
|
+
communityAddress: comment.communityAddress
|
|
827
|
+
}),
|
|
828
|
+
pkc: comment._pkc
|
|
829
|
+
});
|
|
830
|
+
comment.raw.pubsubMessageToPublish = pubsubPublication;
|
|
831
|
+
disableValidationOfSignatureBeforePublishing(comment);
|
|
832
|
+
}
|
|
833
|
+
export async function overrideCommentEditInstancePropsAndSign(commentEdit, props) {
|
|
834
|
+
if (!commentEdit.signer)
|
|
835
|
+
throw Error("Need commentEdit.signer to overwrite the signature");
|
|
836
|
+
//@ts-expect-error
|
|
837
|
+
for (const optionKey of Object.keys(props))
|
|
838
|
+
commentEdit[optionKey] = props[optionKey];
|
|
839
|
+
commentEdit.signature = await signCommentEdit({
|
|
840
|
+
edit: removeUndefinedValuesRecursively({
|
|
841
|
+
...commentEdit.raw.pubsubMessageToPublish,
|
|
842
|
+
signer: commentEdit.signer,
|
|
843
|
+
communityAddress: commentEdit.communityAddress
|
|
844
|
+
}),
|
|
845
|
+
pkc: commentEdit._pkc
|
|
846
|
+
});
|
|
847
|
+
disableValidationOfSignatureBeforePublishing(commentEdit);
|
|
848
|
+
}
|
|
849
|
+
export async function ensurePublicationIsSigned(publication, community) {
|
|
850
|
+
if (!publication.raw.pubsubMessageToPublish) {
|
|
851
|
+
publication._community = {
|
|
852
|
+
address: community.address,
|
|
853
|
+
publicKey: community.signer?.address ?? community.address,
|
|
854
|
+
name: community.name,
|
|
855
|
+
encryption: community.encryption,
|
|
856
|
+
pubsubTopic: community.pubsubTopic
|
|
857
|
+
};
|
|
858
|
+
await publication._signPublicationWithCommunityFields();
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
export async function setExtraPropOnCommentAndSign(comment, extraProps, includeExtraPropInSignedPropertyNames) {
|
|
862
|
+
const log = Logger("pkc-js:test-util:setExtraPropOnVoteAndSign");
|
|
863
|
+
// With deferred signing, the publication may not be signed yet
|
|
864
|
+
if (!comment.raw.pubsubMessageToPublish) {
|
|
865
|
+
await comment._initCommunity();
|
|
866
|
+
await comment._signPublicationWithCommunityFields();
|
|
867
|
+
}
|
|
868
|
+
const publicationWithExtraProp = { ...comment.raw.pubsubMessageToPublish, ...extraProps };
|
|
869
|
+
if (includeExtraPropInSignedPropertyNames)
|
|
870
|
+
publicationWithExtraProp.signature = await _signJson([...comment.signature.signedPropertyNames, ...remeda.keys.strict(extraProps)], cleanUpBeforePublishing(publicationWithExtraProp), comment.signer, log);
|
|
871
|
+
comment.raw.pubsubMessageToPublish = publicationWithExtraProp;
|
|
872
|
+
disableValidationOfSignatureBeforePublishing(comment);
|
|
873
|
+
Object.assign(comment, publicationWithExtraProp, {
|
|
874
|
+
author: buildRuntimeAuthor({
|
|
875
|
+
author: publicationWithExtraProp.author,
|
|
876
|
+
signaturePublicKey: publicationWithExtraProp.signature.publicKey
|
|
877
|
+
})
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
export async function setExtraPropOnVoteAndSign(vote, extraProps, includeExtraPropInSignedPropertyNames) {
|
|
881
|
+
const log = Logger("pkc-js:test-util:setExtraPropOnVoteAndSign");
|
|
882
|
+
// With deferred signing, the publication may not be signed yet
|
|
883
|
+
if (!vote.raw.pubsubMessageToPublish) {
|
|
884
|
+
await vote._initCommunity();
|
|
885
|
+
await vote._signPublicationWithCommunityFields();
|
|
886
|
+
}
|
|
887
|
+
const publicationWithExtraProp = { ...vote.raw.pubsubMessageToPublish, ...extraProps };
|
|
888
|
+
if (includeExtraPropInSignedPropertyNames)
|
|
889
|
+
publicationWithExtraProp.signature = await _signJson([...vote.signature.signedPropertyNames, ...Object.keys(extraProps)], cleanUpBeforePublishing(publicationWithExtraProp), vote.signer, log);
|
|
890
|
+
vote.raw.pubsubMessageToPublish = publicationWithExtraProp;
|
|
891
|
+
disableValidationOfSignatureBeforePublishing(vote);
|
|
892
|
+
Object.assign(vote, publicationWithExtraProp, {
|
|
893
|
+
author: buildRuntimeAuthor({
|
|
894
|
+
author: publicationWithExtraProp.author,
|
|
895
|
+
signaturePublicKey: publicationWithExtraProp.signature.publicKey
|
|
896
|
+
})
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
export async function setExtraPropOnCommentEditAndSign(commentEdit, extraProps, includeExtraPropInSignedPropertyNames) {
|
|
900
|
+
const log = Logger("pkc-js:test-util:setExtraPropOnCommentEditAndSign");
|
|
901
|
+
// With deferred signing, the publication may not be signed yet
|
|
902
|
+
if (!commentEdit.raw.pubsubMessageToPublish) {
|
|
903
|
+
await commentEdit._initCommunity();
|
|
904
|
+
await commentEdit._signPublicationWithCommunityFields();
|
|
905
|
+
}
|
|
906
|
+
const publicationWithExtraProp = { ...commentEdit.raw.pubsubMessageToPublish, ...extraProps };
|
|
907
|
+
if (includeExtraPropInSignedPropertyNames)
|
|
908
|
+
publicationWithExtraProp.signature = await _signJson([...commentEdit.signature.signedPropertyNames, ...Object.keys(extraProps)], cleanUpBeforePublishing(publicationWithExtraProp), commentEdit.signer, log);
|
|
909
|
+
commentEdit.raw.pubsubMessageToPublish = publicationWithExtraProp;
|
|
910
|
+
disableValidationOfSignatureBeforePublishing(commentEdit);
|
|
911
|
+
Object.assign(commentEdit, publicationWithExtraProp, {
|
|
912
|
+
author: buildRuntimeAuthor({
|
|
913
|
+
author: publicationWithExtraProp.author,
|
|
914
|
+
signaturePublicKey: publicationWithExtraProp.signature.publicKey
|
|
915
|
+
})
|
|
916
|
+
});
|
|
917
|
+
}
|
|
918
|
+
export async function setExtraPropOnCommentModerationAndSign(commentModeration, extraProps, includeExtraPropInSignedPropertyNames) {
|
|
919
|
+
const log = Logger("pkc-js:test-util:setExtraPropOnCommentModerationAndSign");
|
|
920
|
+
if (!commentModeration.raw.pubsubMessageToPublish) {
|
|
921
|
+
await commentModeration._initCommunity();
|
|
922
|
+
await commentModeration._signPublicationWithCommunityFields();
|
|
923
|
+
}
|
|
924
|
+
const newPubsubPublicationWithExtraProp = (remeda.mergeDeep(commentModeration.raw.pubsubMessageToPublish, extraProps));
|
|
925
|
+
if (includeExtraPropInSignedPropertyNames)
|
|
926
|
+
newPubsubPublicationWithExtraProp.signature = await _signJson([...commentModeration.signature.signedPropertyNames, ...Object.keys(extraProps)], cleanUpBeforePublishing(newPubsubPublicationWithExtraProp), commentModeration.signer, log);
|
|
927
|
+
commentModeration.raw.pubsubMessageToPublish = newPubsubPublicationWithExtraProp;
|
|
928
|
+
disableValidationOfSignatureBeforePublishing(commentModeration);
|
|
929
|
+
Object.assign(commentModeration, newPubsubPublicationWithExtraProp, {
|
|
930
|
+
author: buildRuntimeAuthor({
|
|
931
|
+
author: newPubsubPublicationWithExtraProp.author,
|
|
932
|
+
signaturePublicKey: newPubsubPublicationWithExtraProp.signature.publicKey
|
|
933
|
+
})
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
export async function setExtraPropOnChallengeRequestAndSign({ publication, extraProps, includeExtraPropsInRequestSignedPropertyNames }) {
|
|
937
|
+
const log = Logger("pkc-js:test-util:setExtraPropOnChallengeRequestAndSign");
|
|
938
|
+
//@ts-expect-error
|
|
939
|
+
publication._signAndValidateChallengeRequestBeforePublishing = async (requestWithoutSignature, signer) => {
|
|
940
|
+
const signedPropertyNames = Object.keys(requestWithoutSignature);
|
|
941
|
+
if (includeExtraPropsInRequestSignedPropertyNames)
|
|
942
|
+
signedPropertyNames.push(...Object.keys(extraProps));
|
|
943
|
+
const requestWithExtraProps = { ...requestWithoutSignature, ...extraProps };
|
|
944
|
+
const signature = await _signPubsubMsg({ signedPropertyNames, msg: requestWithExtraProps, signer, log });
|
|
945
|
+
return { ...requestWithExtraProps, signature };
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
export async function publishChallengeAnswerMessageWithExtraProps({ publication, challengeAnswers, extraProps, includeExtraPropsInChallengeSignedPropertyNames }) {
|
|
949
|
+
// we're crafting a challenge answer from scratch here
|
|
950
|
+
const log = Logger("pkc-js:test-util:setExtraPropsOnChallengeAnswerMessageAndSign");
|
|
951
|
+
const signer = Object.values(publication._challengeExchanges)[0].signer;
|
|
952
|
+
if (!signer)
|
|
953
|
+
throw Error("Signer is undefined for this challenge exchange");
|
|
954
|
+
const encryptedChallengeAnswers = await encryptEd25519AesGcm(JSON.stringify({ challengeAnswers }), signer.privateKey, publication._community.encryption.publicKey);
|
|
955
|
+
const toSignAnswer = cleanUpBeforePublishing({
|
|
956
|
+
type: "CHALLENGEANSWER",
|
|
957
|
+
challengeRequestId: Object.values(publication._challengeExchanges)[0].challengeRequest.challengeRequestId,
|
|
958
|
+
encrypted: encryptedChallengeAnswers,
|
|
959
|
+
userAgent: publication._pkc.userAgent,
|
|
960
|
+
protocolVersion: env.PROTOCOL_VERSION,
|
|
961
|
+
timestamp: timestamp()
|
|
962
|
+
});
|
|
963
|
+
const signedPropertyNames = remeda.keys.strict(toSignAnswer);
|
|
964
|
+
//@ts-expect-error
|
|
965
|
+
if (includeExtraPropsInChallengeSignedPropertyNames)
|
|
966
|
+
signedPropertyNames.push(...Object.keys(extraProps));
|
|
967
|
+
Object.assign(toSignAnswer, extraProps);
|
|
968
|
+
const signature = await _signPubsubMsg({ signedPropertyNames, msg: toSignAnswer, signer, log });
|
|
969
|
+
await publishOverPubsub(publication._community.pubsubTopic, { ...toSignAnswer, signature });
|
|
970
|
+
}
|
|
971
|
+
export async function publishChallengeMessageWithExtraProps({ publication, pubsubSigner, extraProps, includeExtraPropsInChallengeSignedPropertyNames }) {
|
|
972
|
+
const log = Logger("pkc-js:test-util:publishChallengeMessageWithExtraProps");
|
|
973
|
+
const encryptedChallenges = await encryptEd25519AesGcmPublicKeyBuffer(deterministicStringify({ challenges: [] }), pubsubSigner.privateKey, Object.values(publication._challengeExchanges)[0].challengeRequest.signature.publicKey);
|
|
974
|
+
const toSignChallenge = cleanUpBeforePublishing({
|
|
975
|
+
type: "CHALLENGE",
|
|
976
|
+
challengeRequestId: Object.values(publication._challengeExchanges)[0].challengeRequest.challengeRequestId,
|
|
977
|
+
encrypted: encryptedChallenges,
|
|
978
|
+
userAgent: publication._pkc.userAgent,
|
|
979
|
+
protocolVersion: env.PROTOCOL_VERSION,
|
|
980
|
+
timestamp: timestamp()
|
|
981
|
+
});
|
|
982
|
+
const signedPropertyNames = remeda.keys.strict(toSignChallenge);
|
|
983
|
+
//@ts-expect-error
|
|
984
|
+
if (includeExtraPropsInChallengeSignedPropertyNames)
|
|
985
|
+
signedPropertyNames.push(...Object.keys(extraProps));
|
|
986
|
+
Object.assign(toSignChallenge, extraProps);
|
|
987
|
+
const signature = await _signPubsubMsg({
|
|
988
|
+
signedPropertyNames: signedPropertyNames,
|
|
989
|
+
msg: toSignChallenge,
|
|
990
|
+
signer: pubsubSigner,
|
|
991
|
+
log
|
|
992
|
+
});
|
|
993
|
+
await publishOverPubsub(pubsubSigner.address, { ...toSignChallenge, signature });
|
|
994
|
+
}
|
|
995
|
+
export async function publishChallengeVerificationMessageWithExtraProps({ publication, pubsubSigner, extraProps, includeExtraPropsInChallengeSignedPropertyNames }) {
|
|
996
|
+
const log = Logger("pkc-js:test-util:publishChallengeVerificationMessageWithExtraProps");
|
|
997
|
+
const toSignChallengeVerification = cleanUpBeforePublishing({
|
|
998
|
+
type: "CHALLENGEVERIFICATION",
|
|
999
|
+
challengeRequestId: Object.values(publication._challengeExchanges)[0].challengeRequest.challengeRequestId,
|
|
1000
|
+
challengeSuccess: false,
|
|
1001
|
+
reason: "Random reason",
|
|
1002
|
+
userAgent: publication._pkc.userAgent,
|
|
1003
|
+
protocolVersion: env.PROTOCOL_VERSION,
|
|
1004
|
+
timestamp: timestamp()
|
|
1005
|
+
});
|
|
1006
|
+
const signedPropertyNames = remeda.keys.strict(toSignChallengeVerification);
|
|
1007
|
+
//@ts-expect-error
|
|
1008
|
+
if (includeExtraPropsInChallengeSignedPropertyNames)
|
|
1009
|
+
signedPropertyNames.push(...Object.keys(extraProps));
|
|
1010
|
+
Object.assign(toSignChallengeVerification, extraProps);
|
|
1011
|
+
const signature = await _signPubsubMsg({
|
|
1012
|
+
signedPropertyNames: signedPropertyNames,
|
|
1013
|
+
msg: toSignChallengeVerification,
|
|
1014
|
+
signer: pubsubSigner,
|
|
1015
|
+
log
|
|
1016
|
+
});
|
|
1017
|
+
await publishOverPubsub(pubsubSigner.address, { ...toSignChallengeVerification, signature });
|
|
1018
|
+
}
|
|
1019
|
+
export async function publishChallengeVerificationMessageWithEncryption(publication, pubsubSigner, toEncrypt, verificationProps) {
|
|
1020
|
+
const log = Logger("pkc-js:test-util:publishChallengeVerificationMessageWithExtraProps");
|
|
1021
|
+
const challengeRequest = Object.values(publication._challengeExchanges)[0].challengeRequest;
|
|
1022
|
+
const toSignChallengeVerification = cleanUpBeforePublishing({
|
|
1023
|
+
type: "CHALLENGEVERIFICATION",
|
|
1024
|
+
challengeRequestId: challengeRequest.challengeRequestId,
|
|
1025
|
+
challengeSuccess: true,
|
|
1026
|
+
userAgent: publication._pkc.userAgent,
|
|
1027
|
+
protocolVersion: env.PROTOCOL_VERSION,
|
|
1028
|
+
timestamp: timestamp(),
|
|
1029
|
+
...verificationProps
|
|
1030
|
+
});
|
|
1031
|
+
const publicKey = Buffer.from(challengeRequest.signature.publicKey).toString("base64");
|
|
1032
|
+
const encrypted = await encryptEd25519AesGcm(JSON.stringify(toEncrypt), pubsubSigner.privateKey, publicKey);
|
|
1033
|
+
toSignChallengeVerification.encrypted = encrypted;
|
|
1034
|
+
const signature = await signChallengeVerification({ challengeVerification: toSignChallengeVerification, signer: pubsubSigner });
|
|
1035
|
+
await publishOverPubsub(pubsubSigner.address, { ...toSignChallengeVerification, signature });
|
|
1036
|
+
}
|
|
1037
|
+
export async function addStringToIpfs(content) {
|
|
1038
|
+
const pkc = await mockPKCNoDataPathWithOnlyKuboClient();
|
|
1039
|
+
const ipfsClient = pkc._clientsManager.getDefaultKuboRpcClient();
|
|
1040
|
+
const cid = (await retryKuboIpfsAdd({ content, ipfsClient: ipfsClient._client, log: Logger("pkc-js:test-util:addStringToIpfs") })).path;
|
|
1041
|
+
await pkc.destroy();
|
|
1042
|
+
return cid;
|
|
1043
|
+
}
|
|
1044
|
+
export async function publishOverPubsub(pubsubTopic, jsonToPublish) {
|
|
1045
|
+
const pkc = await mockPKCNoDataPathWithOnlyKuboClient();
|
|
1046
|
+
await pkc._clientsManager.pubsubPublish(pubsubTopic, jsonToPublish);
|
|
1047
|
+
await pkc.destroy();
|
|
1048
|
+
}
|
|
1049
|
+
export async function mockPKCWithHeliaConfig(opts) {
|
|
1050
|
+
const key = "Helia config default for testing(remote)" + String(opts?.forceMockPubsub ? "" : Math.random());
|
|
1051
|
+
const forceMockPubsub = typeof opts?.forceMockPubsub === "boolean" ? opts.forceMockPubsub : true;
|
|
1052
|
+
const heliaPKC = await mockPKCV2({
|
|
1053
|
+
forceMockPubsub,
|
|
1054
|
+
...opts,
|
|
1055
|
+
pkcOptions: {
|
|
1056
|
+
libp2pJsClientsOptions: [{ key, libp2pOptions: { connectionGater: { denyDialMultiaddr: async () => false } } }],
|
|
1057
|
+
pubsubKuboRpcClientsOptions: [],
|
|
1058
|
+
kuboRpcClientsOptions: [],
|
|
1059
|
+
pkcRpcClientsOptions: undefined,
|
|
1060
|
+
httpRoutersOptions: ["http://localhost:20001"], // this http router transmits the addresses of kubo node of test-server.js
|
|
1061
|
+
dataPath: undefined,
|
|
1062
|
+
...opts?.pkcOptions
|
|
1063
|
+
}
|
|
1064
|
+
});
|
|
1065
|
+
if (forceMockPubsub) {
|
|
1066
|
+
const mockedPubsubClient = createMockPubsubClient();
|
|
1067
|
+
const heliaLibp2pJsClient = heliaPKC.clients.libp2pJsClients[Object.keys(heliaPKC.clients.libp2pJsClients)[0]];
|
|
1068
|
+
heliaLibp2pJsClient.heliaWithKuboRpcClientFunctions.pubsub = mockedPubsubClient.pubsub; // that should work for publishing/subscribing
|
|
1069
|
+
const originalStop = heliaLibp2pJsClient._helia.stop.bind(heliaLibp2pJsClient._helia);
|
|
1070
|
+
heliaLibp2pJsClient._helia.stop = async () => {
|
|
1071
|
+
await originalStop();
|
|
1072
|
+
await mockedPubsubClient.destroy();
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
return heliaPKC;
|
|
1076
|
+
}
|
|
1077
|
+
const testConfigCodeToPKCInstanceWithHumanName = {
|
|
1078
|
+
"remote-kubo-rpc": {
|
|
1079
|
+
pkcInstancePromise: (args) => mockPKCNoDataPathWithOnlyKuboClient(args),
|
|
1080
|
+
name: "Kubo Node with no datapath (remote)",
|
|
1081
|
+
testConfigCode: "remote-kubo-rpc"
|
|
1082
|
+
},
|
|
1083
|
+
"remote-ipfs-gateway": {
|
|
1084
|
+
pkcInstancePromise: (args) => mockGatewayPKC(args),
|
|
1085
|
+
name: "IPFS Gateway",
|
|
1086
|
+
testConfigCode: "remote-ipfs-gateway"
|
|
1087
|
+
},
|
|
1088
|
+
"remote-pkc-rpc": {
|
|
1089
|
+
pkcInstancePromise: (args) => mockRpcRemotePKC(args),
|
|
1090
|
+
name: "PKC RPC Remote",
|
|
1091
|
+
testConfigCode: "remote-pkc-rpc"
|
|
1092
|
+
},
|
|
1093
|
+
"local-kubo-rpc": {
|
|
1094
|
+
pkcInstancePromise: (args) => mockPKCV2({
|
|
1095
|
+
...args,
|
|
1096
|
+
pkcOptions: {
|
|
1097
|
+
...args?.pkcOptions,
|
|
1098
|
+
pkcRpcClientsOptions: undefined,
|
|
1099
|
+
kuboRpcClientsOptions: ["http://localhost:15001/api/v0"],
|
|
1100
|
+
pubsubKuboRpcClientsOptions: ["http://localhost:15001/api/v0"],
|
|
1101
|
+
ipfsGatewayUrls: undefined
|
|
1102
|
+
}
|
|
1103
|
+
}),
|
|
1104
|
+
name: "Kubo node with datapath (local)",
|
|
1105
|
+
testConfigCode: "local-kubo-rpc"
|
|
1106
|
+
},
|
|
1107
|
+
"remote-libp2pjs": {
|
|
1108
|
+
pkcInstancePromise: (args) => mockPKCWithHeliaConfig(args),
|
|
1109
|
+
name: "Libp2pJS client with no datapath (remote)",
|
|
1110
|
+
testConfigCode: "remote-libp2pjs"
|
|
1111
|
+
}
|
|
1112
|
+
};
|
|
1113
|
+
let pkcConfigs = [];
|
|
1114
|
+
export function setPKCConfigs(configs) {
|
|
1115
|
+
if (configs.length === 0)
|
|
1116
|
+
throw Error("No configs were provided");
|
|
1117
|
+
// Make sure each config exists in the mapper
|
|
1118
|
+
for (const config of configs)
|
|
1119
|
+
if (!testConfigCodeToPKCInstanceWithHumanName[config])
|
|
1120
|
+
throw new Error(`Config "${config}" does not exist in the mapper. Available configs are: ${Object.keys(testConfigCodeToPKCInstanceWithHumanName)}`);
|
|
1121
|
+
pkcConfigs = configs.map((config) => testConfigCodeToPKCInstanceWithHumanName[config]);
|
|
1122
|
+
if (globalThis.window) {
|
|
1123
|
+
globalThis.window.addEventListener("uncaughtException", (err) => {
|
|
1124
|
+
console.error("uncaughtException", JSON.stringify(err, ["message", "arguments", "type", "name"]));
|
|
1125
|
+
});
|
|
1126
|
+
globalThis.window.addEventListener("unhandledrejection", (err) => {
|
|
1127
|
+
console.error("unhandledRejection", JSON.stringify(err, ["message", "arguments", "type", "name"]));
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
else if (process) {
|
|
1131
|
+
process.setMaxListeners(100);
|
|
1132
|
+
process.on("uncaughtException", (...err) => {
|
|
1133
|
+
console.error("uncaughtException", ...err);
|
|
1134
|
+
});
|
|
1135
|
+
process.on("unhandledRejection", (...err) => {
|
|
1136
|
+
console.error("unhandledRejection", ...err);
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
export function getAvailablePKCConfigsToTestAgainst(opts) {
|
|
1141
|
+
if (opts?.includeAllPossibleConfigOnEnv) {
|
|
1142
|
+
// if node, ["local-kubo-rpc", "remote-kubo-rpc", "remote-ipfs-gateway"], also 'remote-pkc-rpc' if isRpcFlagOn()
|
|
1143
|
+
// if browser, ["remote-kubo-rpc", "remote-ipfs-gateway"]
|
|
1144
|
+
// NOTE: "remote-libp2pjs" is temporarily disabled due to stability issues
|
|
1145
|
+
const isBrowser = isRunningInBrowser();
|
|
1146
|
+
const pkcConfigCodes = isBrowser
|
|
1147
|
+
? ["remote-kubo-rpc", "remote-ipfs-gateway"]
|
|
1148
|
+
: ["local-kubo-rpc", "remote-kubo-rpc", "remote-ipfs-gateway"];
|
|
1149
|
+
if (!isBrowser && isRpcFlagOn())
|
|
1150
|
+
pkcConfigCodes.push("remote-pkc-rpc");
|
|
1151
|
+
const availableConfigs = remeda.pick(testConfigCodeToPKCInstanceWithHumanName, pkcConfigCodes);
|
|
1152
|
+
if (opts.includeOnlyTheseTests?.length) {
|
|
1153
|
+
return Object.values(remeda.pick(availableConfigs, opts.includeOnlyTheseTests));
|
|
1154
|
+
}
|
|
1155
|
+
return Object.values(availableConfigs);
|
|
1156
|
+
}
|
|
1157
|
+
// Check if configs are passed via environment variable
|
|
1158
|
+
const pkcConfigsFromEnv = process?.env?.PKC_CONFIGS;
|
|
1159
|
+
if (pkcConfigsFromEnv) {
|
|
1160
|
+
const configs = pkcConfigsFromEnv.split(",");
|
|
1161
|
+
// Set the configs if they're coming from the environment variable
|
|
1162
|
+
setPKCConfigs(configs);
|
|
1163
|
+
}
|
|
1164
|
+
//@ts-expect-error
|
|
1165
|
+
const pkcConfigsFromWindow = globalThis["window"]?.["PKC_CONFIGS"];
|
|
1166
|
+
if (pkcConfigsFromWindow) {
|
|
1167
|
+
const configs = pkcConfigsFromWindow.split(",");
|
|
1168
|
+
// Set the configs if they're coming from the environment variable
|
|
1169
|
+
setPKCConfigs(configs);
|
|
1170
|
+
}
|
|
1171
|
+
if (pkcConfigs.length === 0)
|
|
1172
|
+
throw Error("No remote pkc configs set, " + pkcConfigsFromEnv + " " + pkcConfigsFromWindow);
|
|
1173
|
+
if (opts?.includeOnlyTheseTests) {
|
|
1174
|
+
opts.includeOnlyTheseTests.forEach((config) => {
|
|
1175
|
+
if (!testConfigCodeToPKCInstanceWithHumanName[config])
|
|
1176
|
+
throw new Error(`Config "${config}" does not exist in the mapper. Available configs are: ${pkcConfigs.map((c) => c.name).join(", ")}`);
|
|
1177
|
+
});
|
|
1178
|
+
const filteredKeys = remeda.keys
|
|
1179
|
+
.strict(testConfigCodeToPKCInstanceWithHumanName)
|
|
1180
|
+
.filter((config) => opts.includeOnlyTheseTests.includes(config) &&
|
|
1181
|
+
pkcConfigs.find((c) => c.name === testConfigCodeToPKCInstanceWithHumanName[config].name));
|
|
1182
|
+
const configs = filteredKeys.map((config) => testConfigCodeToPKCInstanceWithHumanName[config]);
|
|
1183
|
+
return configs;
|
|
1184
|
+
}
|
|
1185
|
+
return pkcConfigs;
|
|
1186
|
+
}
|
|
1187
|
+
export async function createNewIpns() {
|
|
1188
|
+
const pkc = await mockPKCNoDataPathWithOnlyKuboClient({});
|
|
1189
|
+
const ipfsClient = pkc._clientsManager.getDefaultKuboRpcClient();
|
|
1190
|
+
const signer = await pkc.createSigner();
|
|
1191
|
+
signer.ipfsKey = new Uint8Array(await getIpfsKeyFromPrivateKey(signer.privateKey));
|
|
1192
|
+
await importSignerIntoKuboNode(signer.address, signer.ipfsKey, {
|
|
1193
|
+
url: pkc.kuboRpcClientsOptions[0].url.toString(),
|
|
1194
|
+
headers: pkc.kuboRpcClientsOptions[0].headers
|
|
1195
|
+
});
|
|
1196
|
+
const publishToIpns = async (content) => {
|
|
1197
|
+
const cid = await addStringToIpfs(content);
|
|
1198
|
+
await ipfsClient._client.name.publish(cid, {
|
|
1199
|
+
key: signer.address,
|
|
1200
|
+
allowOffline: true
|
|
1201
|
+
});
|
|
1202
|
+
// Verify the IPNS record is resolvable before returning
|
|
1203
|
+
// This ensures Kubo's cache is properly synced for RPC tests
|
|
1204
|
+
const resolvedCid = await last(ipfsClient._client.name.resolve(signer.address, {
|
|
1205
|
+
nocache: false, // Allow cache to be used
|
|
1206
|
+
timeout: 5000 // 5 second timeout for verification
|
|
1207
|
+
}));
|
|
1208
|
+
if (!resolvedCid) {
|
|
1209
|
+
throw new Error(`Failed to verify IPNS resolution for ${signer.address}`);
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
return {
|
|
1213
|
+
signer,
|
|
1214
|
+
publishToIpns,
|
|
1215
|
+
pkc
|
|
1216
|
+
};
|
|
1217
|
+
}
|
|
1218
|
+
async function getTemplateCommunityRecord(pkc) {
|
|
1219
|
+
const community = await pkc.createCommunity({ address: "12D3KooWANwdyPERMQaCgiMnTT1t3Lr4XLFbK1z4ptFVhW2ozg1z" });
|
|
1220
|
+
await community.update();
|
|
1221
|
+
await resolveWhenConditionIsTrue({ toUpdate: community, predicate: async () => typeof community.updatedAt === "number" });
|
|
1222
|
+
const result = community.raw.communityIpfs;
|
|
1223
|
+
await community.stop();
|
|
1224
|
+
return result;
|
|
1225
|
+
}
|
|
1226
|
+
export async function publishCommunityRecordWithExtraProp(opts) {
|
|
1227
|
+
const ipnsObj = await createNewIpns();
|
|
1228
|
+
const communityRecord = JSON.parse(JSON.stringify(await getTemplateCommunityRecord(ipnsObj.pkc)));
|
|
1229
|
+
communityRecord.pubsubTopic = ipnsObj.signer.address;
|
|
1230
|
+
delete communityRecord.posts;
|
|
1231
|
+
if (opts?.extraProps)
|
|
1232
|
+
Object.assign(communityRecord, opts.extraProps);
|
|
1233
|
+
const signedPropertyNames = communityRecord.signature.signedPropertyNames;
|
|
1234
|
+
if (opts?.includeExtraPropInSignedPropertyNames)
|
|
1235
|
+
signedPropertyNames.push("extraProp");
|
|
1236
|
+
communityRecord.signature = await _signJson(signedPropertyNames, communityRecord, ipnsObj.signer, Logger("pkc-js:test-util:publishCommunityRecordWithExtraProp"));
|
|
1237
|
+
await ipnsObj.publishToIpns(JSON.stringify(communityRecord));
|
|
1238
|
+
return { communityRecord, ipnsObj };
|
|
1239
|
+
}
|
|
1240
|
+
export async function createMockedCommunityIpns(communityOpts) {
|
|
1241
|
+
const ipnsObj = await createNewIpns();
|
|
1242
|
+
const communityAddress = ipnsObj.signer.address;
|
|
1243
|
+
const communityRecord = {
|
|
1244
|
+
...(await getTemplateCommunityRecord(ipnsObj.pkc)),
|
|
1245
|
+
posts: undefined,
|
|
1246
|
+
pubsubTopic: communityAddress,
|
|
1247
|
+
...communityOpts
|
|
1248
|
+
}; // default community, will be using its props
|
|
1249
|
+
if (!communityRecord.posts)
|
|
1250
|
+
delete communityRecord.posts;
|
|
1251
|
+
communityRecord.signature = await signCommunity({ community: communityRecord, signer: ipnsObj.signer });
|
|
1252
|
+
await ipnsObj.publishToIpns(JSON.stringify(communityRecord));
|
|
1253
|
+
await ipnsObj.pkc.destroy();
|
|
1254
|
+
return { communityRecord, communityAddress, ipnsObj };
|
|
1255
|
+
}
|
|
1256
|
+
export async function createStaticCommunityRecordForComment(opts) {
|
|
1257
|
+
const { pkc, commentOptions = {}, invalidateCommunitySignature = false } = opts || {};
|
|
1258
|
+
if (commentOptions.parentCid && !commentOptions.postCid)
|
|
1259
|
+
throw Error("postCid must be provided when parentCid is supplied for a reply");
|
|
1260
|
+
const ipnsObj = await createNewIpns();
|
|
1261
|
+
const communityAddress = ipnsObj.signer.address;
|
|
1262
|
+
const commentPKC = pkc || (await mockPKCNoDataPathWithOnlyKuboClient());
|
|
1263
|
+
const shouldDestroyCommentPKC = !pkc;
|
|
1264
|
+
try {
|
|
1265
|
+
const communityRecord = {
|
|
1266
|
+
...(await getTemplateCommunityRecord(ipnsObj.pkc)),
|
|
1267
|
+
posts: undefined,
|
|
1268
|
+
pubsubTopic: communityAddress
|
|
1269
|
+
};
|
|
1270
|
+
if (!communityRecord.posts)
|
|
1271
|
+
delete communityRecord.posts;
|
|
1272
|
+
// Always publish a valid record first so the IPNS key is established for gateway discovery
|
|
1273
|
+
communityRecord.signature = await signCommunity({ community: communityRecord, signer: ipnsObj.signer });
|
|
1274
|
+
await ipnsObj.publishToIpns(JSON.stringify(communityRecord));
|
|
1275
|
+
const commentToPublish = await commentPKC.createComment({
|
|
1276
|
+
...commentOptions,
|
|
1277
|
+
signer: commentOptions.signer || (await commentPKC.createSigner()),
|
|
1278
|
+
communityAddress: communityAddress,
|
|
1279
|
+
title: commentOptions.title ?? `Mock Post - ${Date.now()}`,
|
|
1280
|
+
content: commentOptions.content ?? `Mock content - ${Date.now()}`
|
|
1281
|
+
});
|
|
1282
|
+
const depth = typeof commentOptions.depth === "number" ? commentOptions.depth : commentOptions.parentCid ? 1 : 0;
|
|
1283
|
+
if (!commentToPublish.raw.pubsubMessageToPublish) {
|
|
1284
|
+
// Directly set _community from in-memory data to avoid fetching from the gateway.
|
|
1285
|
+
// This prevents caching the valid community record in dedicatedPKC's memory,
|
|
1286
|
+
// which would otherwise cause the subsequent update() to get the cached valid record
|
|
1287
|
+
// instead of fetching the (possibly invalid) record from the gateway.
|
|
1288
|
+
commentToPublish["_community"] = {
|
|
1289
|
+
address: communityAddress,
|
|
1290
|
+
publicKey: getPKCAddressFromPublicKeySync(communityRecord.signature.publicKey),
|
|
1291
|
+
encryption: communityRecord.encryption,
|
|
1292
|
+
pubsubTopic: communityRecord.pubsubTopic
|
|
1293
|
+
};
|
|
1294
|
+
await commentToPublish._signPublicationWithCommunityFields();
|
|
1295
|
+
}
|
|
1296
|
+
const commentIpfs = { ...commentToPublish.raw.pubsubMessageToPublish, depth };
|
|
1297
|
+
if (commentOptions.parentCid) {
|
|
1298
|
+
commentIpfs.parentCid = commentOptions.parentCid;
|
|
1299
|
+
commentIpfs.postCid = commentOptions.postCid;
|
|
1300
|
+
}
|
|
1301
|
+
const commentCid = await addStringToIpfs(JSON.stringify(commentIpfs));
|
|
1302
|
+
// Optionally re-publish with invalid signature after comment is already created
|
|
1303
|
+
if (invalidateCommunitySignature) {
|
|
1304
|
+
communityRecord.updatedAt = (communityRecord.updatedAt || timestamp()) + 1234;
|
|
1305
|
+
await ipnsObj.publishToIpns(JSON.stringify(communityRecord));
|
|
1306
|
+
}
|
|
1307
|
+
return { commentCid, communityAddress: communityAddress };
|
|
1308
|
+
}
|
|
1309
|
+
finally {
|
|
1310
|
+
await ipnsObj.pkc.destroy();
|
|
1311
|
+
if (shouldDestroyCommentPKC)
|
|
1312
|
+
await commentPKC.destroy();
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
function _stripNameResolvedFromPages(pagesContainer) {
|
|
1316
|
+
if (!pagesContainer?.pages)
|
|
1317
|
+
return;
|
|
1318
|
+
for (const page of Object.values(pagesContainer.pages)) {
|
|
1319
|
+
if (!page || !page.comments)
|
|
1320
|
+
continue;
|
|
1321
|
+
for (const c of page.comments) {
|
|
1322
|
+
if (c?.author)
|
|
1323
|
+
delete c.author.nameResolved;
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
export function jsonifyCommunityAndRemoveInternalProps(community) {
|
|
1328
|
+
const jsonfied = JSON.parse(JSON.stringify(community));
|
|
1329
|
+
delete jsonfied["posts"]["clients"];
|
|
1330
|
+
delete jsonfied["modQueue"]["clients"];
|
|
1331
|
+
delete jsonfied["raw"]["runtimeFieldsFromRpc"];
|
|
1332
|
+
delete jsonfied["raw"]["localCommunity"];
|
|
1333
|
+
// Normalize old raw key to new key for backward compat comparison
|
|
1334
|
+
if (jsonfied["raw"]["subplebbitIpfs"] && !jsonfied["raw"]["communityIpfs"]) {
|
|
1335
|
+
jsonfied["raw"]["communityIpfs"] = jsonfied["raw"]["subplebbitIpfs"];
|
|
1336
|
+
delete jsonfied["raw"]["subplebbitIpfs"];
|
|
1337
|
+
}
|
|
1338
|
+
_stripNameResolvedFromPages(jsonfied["posts"]);
|
|
1339
|
+
_stripNameResolvedFromPages(jsonfied["modQueue"]);
|
|
1340
|
+
return remeda.omit(jsonfied, ["startedState", "started", "signer", "settings", "editable", "clients", "updatingState", "state"]);
|
|
1341
|
+
}
|
|
1342
|
+
export function jsonifyLocalCommunityWithNoInternalProps(community) {
|
|
1343
|
+
const localJson = JSON.parse(JSON.stringify(community));
|
|
1344
|
+
//@ts-expect-error
|
|
1345
|
+
delete localJson["posts"]["clients"];
|
|
1346
|
+
return remeda.omit(localJson, ["startedState", "started", "clients", "state", "updatingState"]);
|
|
1347
|
+
}
|
|
1348
|
+
export function jsonifyCommentAndRemoveInstanceProps(comment) {
|
|
1349
|
+
const jsonfied = cleanUpBeforePublishing(JSON.parse(JSON.stringify(comment)));
|
|
1350
|
+
if ("replies" in jsonfied)
|
|
1351
|
+
delete jsonfied["replies"]["clients"];
|
|
1352
|
+
if ("replies" in jsonfied && remeda.isEmpty(jsonfied.replies))
|
|
1353
|
+
delete jsonfied["replies"];
|
|
1354
|
+
// nameResolved is runtime-only — strip it like jsonifyCommunityAndRemoveInternalProps does
|
|
1355
|
+
if (jsonfied.author?.nameResolved !== undefined)
|
|
1356
|
+
delete jsonfied.author.nameResolved;
|
|
1357
|
+
_stripNameResolvedFromPages(jsonfied["replies"]);
|
|
1358
|
+
return remeda.omit(jsonfied, ["clients", "state", "updatingState", "state", "publishingState", "raw"]);
|
|
1359
|
+
}
|
|
1360
|
+
export async function waitUntilPKCCommunitiesIncludeSubAddress(pkc, subAddress) {
|
|
1361
|
+
return pkc._awaitCommunitiesToIncludeCommunity(subAddress);
|
|
1362
|
+
}
|
|
1363
|
+
export function isPKCFetchingUsingGateways(pkc) {
|
|
1364
|
+
return (!pkc._pkcRpcClient && Object.keys(pkc.clients.kuboRpcClients).length === 0 && Object.keys(pkc.clients.libp2pJsClients).length === 0);
|
|
1365
|
+
}
|
|
1366
|
+
export function mockRpcServerForTests(pkcWs) {
|
|
1367
|
+
const functionsToBind = [
|
|
1368
|
+
"_createCommentModerationInstanceFromPublishCommentModerationParams",
|
|
1369
|
+
"_createCommentEditInstanceFromPublishCommentEditParams",
|
|
1370
|
+
"_createVoteInstanceFromPublishVoteParams",
|
|
1371
|
+
"_createCommentInstanceFromPublishCommentParams",
|
|
1372
|
+
"_createCommunityEditInstanceFromPublishCommunityEditParams"
|
|
1373
|
+
];
|
|
1374
|
+
// disable validation of signature before publishing
|
|
1375
|
+
// reduce threshold for publishing
|
|
1376
|
+
for (const funcBind of functionsToBind) {
|
|
1377
|
+
const originalFunc = pkcWs[funcBind].bind(pkcWs);
|
|
1378
|
+
pkcWs[funcBind] = async (...args) => {
|
|
1379
|
+
const pubInstance = await originalFunc(...args);
|
|
1380
|
+
disableValidationOfSignatureBeforePublishing(pubInstance);
|
|
1381
|
+
pubInstance._publishToDifferentProviderThresholdSeconds = 5;
|
|
1382
|
+
pubInstance._setProviderFailureThresholdSeconds = 10;
|
|
1383
|
+
return pubInstance;
|
|
1384
|
+
};
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
export function disablePreloadPagesOnSub({ community }) {
|
|
1388
|
+
if (!(community instanceof LocalCommunity))
|
|
1389
|
+
throw Error("You need to provide LocalCommunity instance");
|
|
1390
|
+
//@ts-expect-error
|
|
1391
|
+
const pageGenerator = community._pageGenerator;
|
|
1392
|
+
const originalCommunityPostsFunc = pageGenerator.generateCommunityPosts.bind(pageGenerator);
|
|
1393
|
+
const originalPostRepliesFunc = pageGenerator.generatePostPages.bind(pageGenerator);
|
|
1394
|
+
const originalReplyRepliesFunc = pageGenerator.generateReplyPages.bind(pageGenerator);
|
|
1395
|
+
const originalChunkComments = pageGenerator._chunkComments.bind(pageGenerator);
|
|
1396
|
+
pageGenerator.generateCommunityPosts = async (preloadedPageSortName, preloadedPageSize) => {
|
|
1397
|
+
return originalCommunityPostsFunc(preloadedPageSortName, preloadedPageSize); // should force community to publish to pageCids
|
|
1398
|
+
};
|
|
1399
|
+
pageGenerator.generatePostPages = async (comment, preloadedPageSortName, preloadedPageSize) => {
|
|
1400
|
+
return originalPostRepliesFunc(comment, preloadedPageSortName, preloadedPageSize); // should force community to publish to pageCids
|
|
1401
|
+
};
|
|
1402
|
+
pageGenerator.generateReplyPages = async (comment, preloadedPageSortName, preloadedPageSize) => {
|
|
1403
|
+
return originalReplyRepliesFunc(comment, preloadedPageSortName, preloadedPageSize);
|
|
1404
|
+
};
|
|
1405
|
+
//@ts-expect-error
|
|
1406
|
+
pageGenerator._chunkComments = async (opts) => {
|
|
1407
|
+
const res = await originalChunkComments(opts);
|
|
1408
|
+
return [[], ...res];
|
|
1409
|
+
};
|
|
1410
|
+
const cleanup = () => {
|
|
1411
|
+
pageGenerator.generateCommunityPosts = originalCommunityPostsFunc;
|
|
1412
|
+
pageGenerator.generatePostPages = originalPostRepliesFunc;
|
|
1413
|
+
pageGenerator.generateReplyPages = originalReplyRepliesFunc;
|
|
1414
|
+
pageGenerator._chunkComments = originalChunkComments;
|
|
1415
|
+
};
|
|
1416
|
+
return { cleanup };
|
|
1417
|
+
}
|
|
1418
|
+
export function mockPostToReturnSpecificCommentUpdate(commentToBeMocked, commentUpdateRecordString) {
|
|
1419
|
+
const updatingPostComment = findUpdatingComment(commentToBeMocked._pkc, { cid: commentToBeMocked.cid });
|
|
1420
|
+
if (!updatingPostComment)
|
|
1421
|
+
throw Error("Post should be updating before starting to mock");
|
|
1422
|
+
if (commentToBeMocked._pkc._pkcRpcClient)
|
|
1423
|
+
throw Error("Can't mock Post to return specific CommentUpdate record when pkc is using RPC");
|
|
1424
|
+
delete updatingPostComment.updatedAt;
|
|
1425
|
+
delete updatingPostComment.raw.commentUpdate;
|
|
1426
|
+
//@ts-expect-error
|
|
1427
|
+
delete updatingPostComment._communityForUpdating?.community?.updateCid;
|
|
1428
|
+
//@ts-expect-error
|
|
1429
|
+
if (updatingPostComment._communityForUpdating?.community?._clientsManager?._updateCidsAlreadyLoaded)
|
|
1430
|
+
//@ts-expect-error
|
|
1431
|
+
updatingPostComment._communityForUpdating.community._clientsManager._updateCidsAlreadyLoaded = new Set();
|
|
1432
|
+
mockCommentToNotUsePagesForUpdates(commentToBeMocked);
|
|
1433
|
+
if (isPKCFetchingUsingGateways(updatingPostComment._pkc)) {
|
|
1434
|
+
const originalFetch = updatingPostComment._clientsManager.fetchFromMultipleGateways.bind(updatingPostComment._clientsManager);
|
|
1435
|
+
updatingPostComment._clientsManager.fetchFromMultipleGateways = async (...args) => {
|
|
1436
|
+
const commentUpdateCid = await addStringToIpfs(commentUpdateRecordString);
|
|
1437
|
+
if (args[0].recordPKCType === "comment-update")
|
|
1438
|
+
return originalFetch({
|
|
1439
|
+
...args[0],
|
|
1440
|
+
root: commentUpdateCid,
|
|
1441
|
+
path: undefined
|
|
1442
|
+
});
|
|
1443
|
+
else
|
|
1444
|
+
return originalFetch(...args);
|
|
1445
|
+
};
|
|
1446
|
+
}
|
|
1447
|
+
else {
|
|
1448
|
+
// we're using kubo/helia
|
|
1449
|
+
const originalFetch = updatingPostComment._clientsManager._fetchCidP2P.bind(updatingPostComment._clientsManager);
|
|
1450
|
+
//@ts-expect-error
|
|
1451
|
+
updatingPostComment._clientsManager._fetchCidP2P = (...args) => {
|
|
1452
|
+
if (args[0].endsWith("/update")) {
|
|
1453
|
+
return commentUpdateRecordString;
|
|
1454
|
+
}
|
|
1455
|
+
else
|
|
1456
|
+
return originalFetch(...args);
|
|
1457
|
+
};
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
export function mockPostToFailToLoadFromPostUpdates(postToBeMocked) {
|
|
1461
|
+
const updatingPostComment = findUpdatingComment(postToBeMocked._pkc, { cid: postToBeMocked.cid });
|
|
1462
|
+
if (!updatingPostComment)
|
|
1463
|
+
throw Error("Post should be updating before starting to mock");
|
|
1464
|
+
if (postToBeMocked._pkc._pkcRpcClient)
|
|
1465
|
+
throw Error("Can't mock Post to to fail loading post from postUpdates when pkc is using RPC");
|
|
1466
|
+
mockCommentToNotUsePagesForUpdates(postToBeMocked);
|
|
1467
|
+
updatingPostComment._clientsManager._fetchPostCommentUpdateIpfsP2P =
|
|
1468
|
+
updatingPostComment._clientsManager._fetchPostCommentUpdateFromGateways = async () => {
|
|
1469
|
+
throw new PKCError("ERR_FAILED_TO_FETCH_COMMENT_UPDATE_FROM_ALL_POST_UPDATES_RANGES");
|
|
1470
|
+
};
|
|
1471
|
+
}
|
|
1472
|
+
export function mockPostToHaveCommunityWithNoPostUpdates(postToBeMocked) {
|
|
1473
|
+
const updatingPostComment = findUpdatingComment(postToBeMocked._pkc, { cid: postToBeMocked.cid });
|
|
1474
|
+
if (!updatingPostComment)
|
|
1475
|
+
throw Error("Post should be updating before starting to mock");
|
|
1476
|
+
if (postToBeMocked._pkc._pkcRpcClient)
|
|
1477
|
+
throw Error("Can't mock Post to to fail loading post from postUpdates when pkc is using RPC");
|
|
1478
|
+
mockCommentToNotUsePagesForUpdates(postToBeMocked);
|
|
1479
|
+
const originalCommunityUpdateHandle = updatingPostComment._clientsManager.handleUpdateEventFromCommunity.bind(updatingPostComment._clientsManager);
|
|
1480
|
+
updatingPostComment._clientsManager.handleUpdateEventFromCommunity = (community) => {
|
|
1481
|
+
delete community.postUpdates;
|
|
1482
|
+
delete community.raw.communityIpfs.postUpdates;
|
|
1483
|
+
return originalCommunityUpdateHandle(community);
|
|
1484
|
+
};
|
|
1485
|
+
}
|
|
1486
|
+
export async function createCommentUpdateWithInvalidSignature(commentCid) {
|
|
1487
|
+
const pkc = await mockPKCNoDataPathWithOnlyKuboClient({});
|
|
1488
|
+
const comment = await pkc.getComment({ cid: commentCid });
|
|
1489
|
+
await comment.update();
|
|
1490
|
+
await resolveWhenConditionIsTrue({ toUpdate: comment, predicate: async () => typeof comment.updatedAt === "number" });
|
|
1491
|
+
const invalidCommentUpdateJson = comment.raw.commentUpdate;
|
|
1492
|
+
await comment.stop();
|
|
1493
|
+
invalidCommentUpdateJson.updatedAt += 1234; // Invalidate CommentUpdate signature
|
|
1494
|
+
return invalidCommentUpdateJson;
|
|
1495
|
+
}
|
|
1496
|
+
export function mockPKCToTimeoutFetchingCid(pkc) {
|
|
1497
|
+
const originalFetch = pkc._clientsManager._fetchCidP2P;
|
|
1498
|
+
const restoreFns = [];
|
|
1499
|
+
for (const ipfsClient of Object.values(pkc.clients.kuboRpcClients)) {
|
|
1500
|
+
const originalCat = ipfsClient._client.cat;
|
|
1501
|
+
ipfsClient._client.cat = async function* (ipfsPath, options) {
|
|
1502
|
+
await new Promise((resolve) => setTimeout(resolve, pkc._timeouts["community-ipfs"] * 2));
|
|
1503
|
+
return undefined;
|
|
1504
|
+
};
|
|
1505
|
+
restoreFns.push(() => {
|
|
1506
|
+
ipfsClient._client.cat = originalCat;
|
|
1507
|
+
});
|
|
1508
|
+
}
|
|
1509
|
+
for (const libp2pJsClient of Object.values(pkc.clients.libp2pJsClients)) {
|
|
1510
|
+
const originalCat = libp2pJsClient.heliaWithKuboRpcClientFunctions.cat;
|
|
1511
|
+
libp2pJsClient.heliaWithKuboRpcClientFunctions.cat = async function* (ipfsPath, options) {
|
|
1512
|
+
await new Promise((resolve) => setTimeout(resolve, pkc._timeouts["community-ipfs"] * 2));
|
|
1513
|
+
return undefined;
|
|
1514
|
+
};
|
|
1515
|
+
restoreFns.push(() => {
|
|
1516
|
+
libp2pJsClient.heliaWithKuboRpcClientFunctions.cat = originalCat;
|
|
1517
|
+
});
|
|
1518
|
+
}
|
|
1519
|
+
// TODO mock for gateway
|
|
1520
|
+
// pkc._clientsManager._fetchCidP2P = async (...args) => {
|
|
1521
|
+
// await new Promise((resolve) => setTimeout(resolve, pkc._timeouts["community-ipfs"] * 2));
|
|
1522
|
+
// return undefined;
|
|
1523
|
+
// };
|
|
1524
|
+
return {
|
|
1525
|
+
cleanUp: () => {
|
|
1526
|
+
pkc._clientsManager._fetchCidP2P = originalFetch;
|
|
1527
|
+
for (const restore of restoreFns)
|
|
1528
|
+
restore();
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
}
|
|
1532
|
+
export function mockCommentToNotUsePagesForUpdates(comment) {
|
|
1533
|
+
const updatingComment = findUpdatingComment(comment._pkc, { cid: comment.cid });
|
|
1534
|
+
if (!updatingComment)
|
|
1535
|
+
throw Error("Comment should be updating before starting to mock");
|
|
1536
|
+
if (comment._pkc._pkcRpcClient)
|
|
1537
|
+
throw Error("Can't mock comment _findCommentInPagesOfUpdatingCommentsCommunity with pkc rpc clients");
|
|
1538
|
+
delete updatingComment.raw.commentUpdate;
|
|
1539
|
+
delete updatingComment.updatedAt;
|
|
1540
|
+
updatingComment._clientsManager._findCommentInPagesOfUpdatingCommentsOrCommunity = () => undefined;
|
|
1541
|
+
}
|
|
1542
|
+
const FORCE_COMMUNITY_MIN_POST_CONTENT_BYTES = 30 * 1024;
|
|
1543
|
+
function ensureLocalCommunityForForcedChunking(community) {
|
|
1544
|
+
if (!community)
|
|
1545
|
+
throw Error("Local community instance is required to force reply pages to use page cids");
|
|
1546
|
+
if (!(community instanceof LocalCommunity))
|
|
1547
|
+
throw Error("Forcing reply page chunking is only supported when using a LocalCommunity");
|
|
1548
|
+
}
|
|
1549
|
+
export async function forceLocalSubPagesToAlwaysGenerateMultipleChunks({ community, parentComment, forcedPreloadedPageSizeBytes = 1, parentCommentReplyProps, communityPostsCommentProps }) {
|
|
1550
|
+
if (!parentComment) {
|
|
1551
|
+
await forceCommunityToGenerateAllPostsPages(community, communityPostsCommentProps);
|
|
1552
|
+
return { cleanup: () => { } };
|
|
1553
|
+
}
|
|
1554
|
+
ensureLocalCommunityForForcedChunking(community);
|
|
1555
|
+
const parentCid = parentComment.cid;
|
|
1556
|
+
if (!parentCid)
|
|
1557
|
+
throw Error("parent comment cid is required to force chunking to multiple pages");
|
|
1558
|
+
const localCommunity = community;
|
|
1559
|
+
const communityWithGenerator = localCommunity;
|
|
1560
|
+
const pageGenerator = communityWithGenerator["_pageGenerator"];
|
|
1561
|
+
if (!pageGenerator)
|
|
1562
|
+
throw Error("Local community page generator is not initialized");
|
|
1563
|
+
const isPost = parentComment.depth === 0;
|
|
1564
|
+
const originalGenerateReplyPages = pageGenerator.generateReplyPages;
|
|
1565
|
+
const originalGeneratePostPages = pageGenerator.generatePostPages;
|
|
1566
|
+
if (isPost) {
|
|
1567
|
+
if (typeof originalGeneratePostPages !== "function")
|
|
1568
|
+
throw Error("Page generator post pages function is not available");
|
|
1569
|
+
pageGenerator.generatePostPages = (async (comment, preloadedReplyPageSortName, preloadedPageSizeBytes) => {
|
|
1570
|
+
const shouldForce = comment?.cid === parentCid;
|
|
1571
|
+
const effectivePageSizeBytes = shouldForce
|
|
1572
|
+
? Math.min(preloadedPageSizeBytes, forcedPreloadedPageSizeBytes)
|
|
1573
|
+
: preloadedPageSizeBytes;
|
|
1574
|
+
return originalGeneratePostPages.call(pageGenerator, comment, preloadedReplyPageSortName, effectivePageSizeBytes);
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
else {
|
|
1578
|
+
if (typeof originalGenerateReplyPages !== "function")
|
|
1579
|
+
throw Error("Page generator reply pages function is not available");
|
|
1580
|
+
pageGenerator.generateReplyPages = (async (comment, preloadedReplyPageSortName, preloadedPageSizeBytes) => {
|
|
1581
|
+
const shouldForce = comment?.cid === parentCid;
|
|
1582
|
+
const effectivePageSizeBytes = shouldForce
|
|
1583
|
+
? Math.min(preloadedPageSizeBytes, forcedPreloadedPageSizeBytes)
|
|
1584
|
+
: preloadedPageSizeBytes;
|
|
1585
|
+
return originalGenerateReplyPages.call(pageGenerator, comment, preloadedReplyPageSortName, effectivePageSizeBytes);
|
|
1586
|
+
});
|
|
1587
|
+
}
|
|
1588
|
+
const cleanup = () => {
|
|
1589
|
+
if (isPost && originalGeneratePostPages)
|
|
1590
|
+
pageGenerator.generatePostPages = originalGeneratePostPages;
|
|
1591
|
+
if (!isPost && originalGenerateReplyPages)
|
|
1592
|
+
pageGenerator.generateReplyPages = originalGenerateReplyPages;
|
|
1593
|
+
};
|
|
1594
|
+
try {
|
|
1595
|
+
if (Object.keys(parentComment.replies.pageCids).length === 0)
|
|
1596
|
+
await ensureParentCommentHasPageCidsForChunking(parentComment, {
|
|
1597
|
+
commentProps: parentCommentReplyProps,
|
|
1598
|
+
publishWithPKC: localCommunity._pkc
|
|
1599
|
+
});
|
|
1600
|
+
}
|
|
1601
|
+
catch (err) {
|
|
1602
|
+
cleanup();
|
|
1603
|
+
throw err;
|
|
1604
|
+
}
|
|
1605
|
+
return { cleanup };
|
|
1606
|
+
}
|
|
1607
|
+
async function ensureParentCommentHasPageCidsForChunking(parentComment, options) {
|
|
1608
|
+
if (!parentComment?.cid)
|
|
1609
|
+
throw Error("parent comment cid should be defined before ensuring page cids");
|
|
1610
|
+
const hasPageCids = () => Object.keys(parentComment.replies.pageCids).length > 0;
|
|
1611
|
+
if (hasPageCids())
|
|
1612
|
+
return;
|
|
1613
|
+
const { commentProps, publishWithPKC } = options ?? {};
|
|
1614
|
+
const MAX_REPLIES_TO_PUBLISH = 5;
|
|
1615
|
+
for (let i = 0; i < MAX_REPLIES_TO_PUBLISH && !hasPageCids(); i++) {
|
|
1616
|
+
const replyProps = {
|
|
1617
|
+
...commentProps,
|
|
1618
|
+
content: commentProps?.content ?? `force pagination reply ${i} ${Date.now()}`
|
|
1619
|
+
};
|
|
1620
|
+
const publishingPKC = publishWithPKC ?? parentComment._pkc;
|
|
1621
|
+
await publishRandomReply({
|
|
1622
|
+
parentComment: parentComment,
|
|
1623
|
+
pkc: publishingPKC,
|
|
1624
|
+
commentProps: replyProps
|
|
1625
|
+
});
|
|
1626
|
+
await parentComment.update();
|
|
1627
|
+
await resolveWhenConditionIsTrue({
|
|
1628
|
+
toUpdate: parentComment,
|
|
1629
|
+
predicate: async () => hasPageCids()
|
|
1630
|
+
});
|
|
1631
|
+
}
|
|
1632
|
+
if (!hasPageCids())
|
|
1633
|
+
throw Error(`Failed to force parent comment ${parentComment.cid} to have replies.pageCids`);
|
|
1634
|
+
}
|
|
1635
|
+
export async function findOrPublishCommentWithDepth({ depth, community, pkc }) {
|
|
1636
|
+
const pkcWithDefault = pkc || community._pkc;
|
|
1637
|
+
let commentFromPreloadedPages;
|
|
1638
|
+
if (community.posts.pages.hot) {
|
|
1639
|
+
processAllCommentsRecursively(community.posts.pages.hot.comments, (comment) => {
|
|
1640
|
+
if (comment.depth === depth) {
|
|
1641
|
+
commentFromPreloadedPages = comment;
|
|
1642
|
+
}
|
|
1643
|
+
});
|
|
1644
|
+
}
|
|
1645
|
+
if (commentFromPreloadedPages)
|
|
1646
|
+
return pkcWithDefault.createComment(commentFromPreloadedPages);
|
|
1647
|
+
let curComment;
|
|
1648
|
+
let closestCommentFromHot;
|
|
1649
|
+
if (community.posts.pages.hot) {
|
|
1650
|
+
let maxDepthFound = -1;
|
|
1651
|
+
processAllCommentsRecursively(community.posts.pages.hot.comments, (comment) => {
|
|
1652
|
+
const commentDepth = comment.depth ?? 0;
|
|
1653
|
+
if (commentDepth <= depth && commentDepth > maxDepthFound) {
|
|
1654
|
+
maxDepthFound = commentDepth;
|
|
1655
|
+
closestCommentFromHot = comment;
|
|
1656
|
+
}
|
|
1657
|
+
});
|
|
1658
|
+
}
|
|
1659
|
+
if (closestCommentFromHot) {
|
|
1660
|
+
curComment = await pkcWithDefault.createComment(closestCommentFromHot);
|
|
1661
|
+
}
|
|
1662
|
+
else {
|
|
1663
|
+
curComment = await publishRandomPost({ communityAddress: community.address, pkc: pkcWithDefault });
|
|
1664
|
+
}
|
|
1665
|
+
if (curComment.depth === depth)
|
|
1666
|
+
return curComment;
|
|
1667
|
+
while (curComment.depth < depth) {
|
|
1668
|
+
curComment = await publishRandomReply({ parentComment: curComment, pkc: pkcWithDefault });
|
|
1669
|
+
if (curComment.depth === depth)
|
|
1670
|
+
return curComment;
|
|
1671
|
+
}
|
|
1672
|
+
throw Error("Failed to find or publish comment with depth");
|
|
1673
|
+
}
|
|
1674
|
+
export async function findOrPublishCommentWithDepthWithHttpServerShortcut({ depth, community, pkc }) {
|
|
1675
|
+
const pkcWithDefault = pkc || community._pkc;
|
|
1676
|
+
const queryUrl = `http://localhost:14953/find-comment-with-depth?subAddress=${community.address}&commentDepth=${depth}`;
|
|
1677
|
+
const commentWithSameDepthOrClosest = await (await fetch(queryUrl)).json();
|
|
1678
|
+
if (commentWithSameDepthOrClosest.depth === depth) {
|
|
1679
|
+
return pkcWithDefault.createComment(commentWithSameDepthOrClosest);
|
|
1680
|
+
}
|
|
1681
|
+
let curComment = await publishRandomReply({ parentComment: commentWithSameDepthOrClosest, pkc: pkcWithDefault });
|
|
1682
|
+
while (curComment.depth < depth) {
|
|
1683
|
+
curComment = await publishRandomReply({ parentComment: curComment, pkc: pkcWithDefault });
|
|
1684
|
+
if (curComment.depth === depth)
|
|
1685
|
+
return curComment;
|
|
1686
|
+
}
|
|
1687
|
+
throw Error("Failed to find or publish comment with depth");
|
|
1688
|
+
}
|
|
1689
|
+
export async function publishCommentWithDepth({ depth, community }) {
|
|
1690
|
+
if (depth === 0) {
|
|
1691
|
+
return publishRandomPost({ communityAddress: community.address, pkc: community._pkc });
|
|
1692
|
+
}
|
|
1693
|
+
else {
|
|
1694
|
+
const parentComment = await publishCommentWithDepth({ depth: depth - 1, community });
|
|
1695
|
+
let curComment = await publishRandomReply({
|
|
1696
|
+
parentComment: parentComment,
|
|
1697
|
+
pkc: community._pkc
|
|
1698
|
+
});
|
|
1699
|
+
if (curComment.depth === depth)
|
|
1700
|
+
return curComment;
|
|
1701
|
+
while (curComment.depth < depth) {
|
|
1702
|
+
curComment = await publishRandomReply({ parentComment: curComment, pkc: community._pkc });
|
|
1703
|
+
if (curComment.depth === depth)
|
|
1704
|
+
return curComment;
|
|
1705
|
+
}
|
|
1706
|
+
throw Error("Failed to publish comment with depth");
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
export async function getCommentWithCommentUpdateProps({ cid, pkc }) {
|
|
1710
|
+
const comment = await pkc.createComment({ cid });
|
|
1711
|
+
await comment.update();
|
|
1712
|
+
await resolveWhenConditionIsTrue({ toUpdate: comment, predicate: async () => Boolean(comment.updatedAt) });
|
|
1713
|
+
return comment;
|
|
1714
|
+
}
|
|
1715
|
+
export async function publishCommentToModQueue({ community, pkc, parentComment, commentProps }) {
|
|
1716
|
+
if (!commentProps?.challengeRequest?.challengeAnswers)
|
|
1717
|
+
throw Error("You need to challengeRequest.challengeAnswers to pass the challenge and get to pending approval");
|
|
1718
|
+
const remotePKC = pkc || (await mockGatewayPKC({ forceMockPubsub: true, remotePKC: true })); // this pkc is not connected to kubo rpc client of community
|
|
1719
|
+
const pendingComment = parentComment
|
|
1720
|
+
? await generateMockComment(parentComment, remotePKC, false, {
|
|
1721
|
+
content: "Pending reply" + " " + Math.random(),
|
|
1722
|
+
...commentProps
|
|
1723
|
+
})
|
|
1724
|
+
: await generateMockPost({
|
|
1725
|
+
communityAddress: community.address,
|
|
1726
|
+
pkc: remotePKC,
|
|
1727
|
+
postProps: {
|
|
1728
|
+
content: "Pending post" + " " + Math.random(),
|
|
1729
|
+
...commentProps
|
|
1730
|
+
}
|
|
1731
|
+
});
|
|
1732
|
+
pendingComment.once("challenge", async () => {
|
|
1733
|
+
throw Error("Should not received challenge with challengeRequest props");
|
|
1734
|
+
});
|
|
1735
|
+
const challengeVerificationPromise = new Promise((resolve) => pendingComment.once("challengeverification", resolve));
|
|
1736
|
+
await publishWithExpectedResult({ publication: pendingComment, expectedChallengeSuccess: true }); // a pending approval is technically challengeSucess = true
|
|
1737
|
+
if (!pendingComment.pendingApproval)
|
|
1738
|
+
throw Error("The comment did not go to pending approval");
|
|
1739
|
+
return { comment: pendingComment, challengeVerification: await challengeVerificationPromise };
|
|
1740
|
+
}
|
|
1741
|
+
export async function publishToModQueueWithDepth({ community, depth, pkc, modCommentProps, commentProps }) {
|
|
1742
|
+
if (!commentProps?.challengeRequest?.challengeAnswers)
|
|
1743
|
+
throw Error("You need to challengeRequest.challengeAnswers to pass the challenge and get to pending approval");
|
|
1744
|
+
if (depth === 0)
|
|
1745
|
+
return publishCommentToModQueue({ community, pkc, commentProps });
|
|
1746
|
+
else {
|
|
1747
|
+
// we assume mod can publish comments without mod queue
|
|
1748
|
+
const remotePKC = pkc || community._pkc;
|
|
1749
|
+
const commentsPublishedByMod = [
|
|
1750
|
+
await publishRandomPost({ communityAddress: community.address, pkc: remotePKC, postProps: modCommentProps })
|
|
1751
|
+
];
|
|
1752
|
+
for (let i = 1; i < depth; i++) {
|
|
1753
|
+
commentsPublishedByMod.push(await publishRandomReply({
|
|
1754
|
+
parentComment: commentsPublishedByMod[i - 1],
|
|
1755
|
+
pkc: remotePKC,
|
|
1756
|
+
commentProps: modCommentProps
|
|
1757
|
+
}));
|
|
1758
|
+
}
|
|
1759
|
+
// we have created a tree of comments and now we can publish the pending comment underneath it
|
|
1760
|
+
const pendingReply = await generateMockComment(commentsPublishedByMod[commentsPublishedByMod.length - 1], remotePKC, false, {
|
|
1761
|
+
content: "Pending reply" + " " + Math.random(),
|
|
1762
|
+
...commentProps
|
|
1763
|
+
});
|
|
1764
|
+
pendingReply.once("challenge", () => {
|
|
1765
|
+
throw Error("Should not received challenge with challengeRequest props");
|
|
1766
|
+
});
|
|
1767
|
+
const challengeVerificationPromise = new Promise((resolve) => pendingReply.once("challengeverification", resolve));
|
|
1768
|
+
await publishWithExpectedResult({ publication: pendingReply, expectedChallengeSuccess: true }); // a pending approval is technically challengeSucess = true
|
|
1769
|
+
if (!pendingReply.pendingApproval)
|
|
1770
|
+
throw Error("The reply did not go to pending approval");
|
|
1771
|
+
return { comment: pendingReply, challengeVerification: await challengeVerificationPromise };
|
|
1772
|
+
}
|
|
1773
|
+
}
|
|
1774
|
+
// This may not be needed
|
|
1775
|
+
export async function forceCommunityToGenerateAllPostsPages(community, commentProps) {
|
|
1776
|
+
// max comment size is 40kb = 40000
|
|
1777
|
+
const rawCommunityRecord = community.raw.communityIpfs;
|
|
1778
|
+
if (!rawCommunityRecord)
|
|
1779
|
+
throw Error("Community should be updating before forcing to generate all pages");
|
|
1780
|
+
community.setMaxListeners(100);
|
|
1781
|
+
if (Object.keys(community.posts.pageCids).length > 0)
|
|
1782
|
+
return;
|
|
1783
|
+
const curRecordSize = await calculateStringSizeSameAsIpfsAddCidV0(JSON.stringify(rawCommunityRecord));
|
|
1784
|
+
const maxCommentSize = 30000;
|
|
1785
|
+
const defaultContent = "x".repeat(FORCE_COMMUNITY_MIN_POST_CONTENT_BYTES); // 30kb
|
|
1786
|
+
const paddedContent = typeof commentProps?.content === "string"
|
|
1787
|
+
? commentProps.content.padEnd(FORCE_COMMUNITY_MIN_POST_CONTENT_BYTES, "x")
|
|
1788
|
+
: defaultContent;
|
|
1789
|
+
const estimatedCommentSize = Math.max(maxCommentSize, Buffer.byteLength(paddedContent, "utf8"));
|
|
1790
|
+
const adjustedCommentProps = { ...commentProps, content: paddedContent };
|
|
1791
|
+
const numOfCommentsToPublish = Math.round((1024 * 1024 - curRecordSize) / estimatedCommentSize) + 1;
|
|
1792
|
+
let lastPublishedPost = await publishRandomPost({
|
|
1793
|
+
communityAddress: community.address,
|
|
1794
|
+
pkc: community._pkc,
|
|
1795
|
+
postProps: adjustedCommentProps
|
|
1796
|
+
});
|
|
1797
|
+
await Promise.all(new Array(numOfCommentsToPublish).fill(null).map(async () => {
|
|
1798
|
+
const post = await publishRandomPost({
|
|
1799
|
+
communityAddress: community.address,
|
|
1800
|
+
pkc: community._pkc,
|
|
1801
|
+
postProps: adjustedCommentProps
|
|
1802
|
+
});
|
|
1803
|
+
lastPublishedPost = post;
|
|
1804
|
+
}));
|
|
1805
|
+
await waitTillPostInCommunityPages(lastPublishedPost, community._pkc);
|
|
1806
|
+
const newCommunity = await community._pkc.createCommunity({ address: community.address });
|
|
1807
|
+
await newCommunity.update();
|
|
1808
|
+
await resolveWhenConditionIsTrue({ toUpdate: newCommunity, predicate: async () => typeof newCommunity.updatedAt === "number" });
|
|
1809
|
+
if (Object.keys(newCommunity.posts.pageCids).length === 0)
|
|
1810
|
+
throw Error("Failed to force the community to load all pages");
|
|
1811
|
+
await newCommunity.stop();
|
|
1812
|
+
}
|
|
1813
|
+
export function mockReplyToUseParentPagesForUpdates(reply) {
|
|
1814
|
+
const updatingComment = findUpdatingComment(reply._pkc, { cid: reply.cid });
|
|
1815
|
+
if (!updatingComment)
|
|
1816
|
+
throw Error("Reply should be updating before starting to mock");
|
|
1817
|
+
if (updatingComment.depth === 0)
|
|
1818
|
+
throw Error("Should not call this function on a post");
|
|
1819
|
+
delete updatingComment.raw.commentUpdate;
|
|
1820
|
+
delete updatingComment.updatedAt;
|
|
1821
|
+
mockCommentToNotUsePagesForUpdates(reply);
|
|
1822
|
+
const originalFunc = updatingComment._clientsManager.handleUpdateEventFromPostToFetchReplyCommentUpdate.bind(updatingComment._clientsManager);
|
|
1823
|
+
updatingComment._clientsManager.handleUpdateEventFromPostToFetchReplyCommentUpdate = (postInstance) => {
|
|
1824
|
+
// this should stop pkc-js from assuming the post replies is a single preloaded page
|
|
1825
|
+
const updatingCommunityInstance = findUpdatingCommunity(reply._pkc, { address: postInstance.communityAddress });
|
|
1826
|
+
const updatingParentInstance = findUpdatingComment(reply._pkc, { cid: reply.parentCid });
|
|
1827
|
+
if (postInstance.replies.pages)
|
|
1828
|
+
Object.keys(postInstance.replies.pages).forEach((preloadedPageKey) => {
|
|
1829
|
+
if (postInstance.replies.pages[preloadedPageKey]?.comments)
|
|
1830
|
+
postInstance.replies.pages[preloadedPageKey].comments = [];
|
|
1831
|
+
});
|
|
1832
|
+
if (updatingCommunityInstance?.posts.pages)
|
|
1833
|
+
Object.keys(updatingCommunityInstance.posts.pages).forEach((preloadedPageKey) => {
|
|
1834
|
+
if (updatingCommunityInstance.posts.pages[preloadedPageKey]?.comments)
|
|
1835
|
+
updatingCommunityInstance.posts.pages[preloadedPageKey].comments = [];
|
|
1836
|
+
});
|
|
1837
|
+
if (updatingParentInstance?.replies?.pages)
|
|
1838
|
+
Object.keys(updatingParentInstance.replies.pages).forEach((preloadedPageKey) => {
|
|
1839
|
+
if (updatingParentInstance.replies.pages[preloadedPageKey]?.comments)
|
|
1840
|
+
updatingParentInstance.replies.pages[preloadedPageKey].comments = [];
|
|
1841
|
+
});
|
|
1842
|
+
return originalFunc(postInstance);
|
|
1843
|
+
};
|
|
1844
|
+
}
|
|
1845
|
+
export function mockUpdatingCommentResolvingAuthor(comment, mockFunction) {
|
|
1846
|
+
const updatingComment = findUpdatingComment(comment._pkc, { cid: comment.cid });
|
|
1847
|
+
if (!updatingComment)
|
|
1848
|
+
throw Error("Comment should be updating before starting to mock");
|
|
1849
|
+
if (comment._pkc._pkcRpcClient)
|
|
1850
|
+
throw Error("Can't mock cache with pkc rpc clients");
|
|
1851
|
+
updatingComment._clientsManager.resolveAuthorNameIfNeeded = mockFunction;
|
|
1852
|
+
}
|
|
1853
|
+
export async function getRandomPostCidFromSub(communityAddress, pkc) {
|
|
1854
|
+
const community = await pkc.createCommunity({ address: communityAddress });
|
|
1855
|
+
await community.update();
|
|
1856
|
+
await resolveWhenConditionIsTrue({ toUpdate: community, predicate: async () => typeof community.updatedAt === "number" });
|
|
1857
|
+
const lastPostCid = community.lastPostCid;
|
|
1858
|
+
await community.stop();
|
|
1859
|
+
if (!lastPostCid)
|
|
1860
|
+
throw Error("Community should have a last post cid");
|
|
1861
|
+
return lastPostCid;
|
|
1862
|
+
}
|
|
1863
|
+
const skipFunction = (_) => { };
|
|
1864
|
+
skipFunction.skip = () => { };
|
|
1865
|
+
//@ts-expect-error
|
|
1866
|
+
export const describeSkipIfRpc = globalThis["describe"]?.runIf(!isRpcFlagOn());
|
|
1867
|
+
//@ts-expect-error
|
|
1868
|
+
export const describeIfRpc = globalThis["describe"]?.runIf(isRpcFlagOn());
|
|
1869
|
+
//@ts-expect-error
|
|
1870
|
+
export const itSkipIfRpc = globalThis["it"]?.runIf(!isRpcFlagOn());
|
|
1871
|
+
//@ts-expect-error
|
|
1872
|
+
export const itIfRpc = globalThis["it"]?.runIf(isRpcFlagOn());
|
|
1873
|
+
export function mockNameResolvers({ pkc, resolveFunction }) {
|
|
1874
|
+
if (pkc._pkcRpcClient)
|
|
1875
|
+
throw Error("Can't mock name resolvers with pkc rpc clients");
|
|
1876
|
+
pkc.nameResolvers = [createMockNameResolver({ resolveFunction: (opts) => resolveFunction(opts) })];
|
|
1877
|
+
}
|
|
1878
|
+
export function processAllCommentsRecursively(comments, processor) {
|
|
1879
|
+
if (!comments || comments.length === 0)
|
|
1880
|
+
return;
|
|
1881
|
+
comments.forEach((comment) => processor(comment));
|
|
1882
|
+
for (const comment of comments)
|
|
1883
|
+
if (comment.replies?.pages?.best?.comments)
|
|
1884
|
+
processAllCommentsRecursively(comment.replies.pages.best.comments, processor);
|
|
1885
|
+
}
|
|
1886
|
+
//# sourceMappingURL=test-util.js.map
|