@enbox/dwn-sdk-js 0.0.1
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 +201 -0
- package/README.md +352 -0
- package/dist/bundles/dwn.js +153 -0
- package/dist/cjs/index.js +36749 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/generated/precompiled-validators.js +11973 -0
- package/dist/esm/generated/precompiled-validators.js.map +1 -0
- package/dist/esm/json-schemas/definitions.json +23 -0
- package/dist/esm/src/core/abstract-message.js +47 -0
- package/dist/esm/src/core/abstract-message.js.map +1 -0
- package/dist/esm/src/core/auth.js +39 -0
- package/dist/esm/src/core/auth.js.map +1 -0
- package/dist/esm/src/core/dwn-constant.js +10 -0
- package/dist/esm/src/core/dwn-constant.js.map +1 -0
- package/dist/esm/src/core/dwn-error.js +169 -0
- package/dist/esm/src/core/dwn-error.js.map +1 -0
- package/dist/esm/src/core/grant-authorization.js +97 -0
- package/dist/esm/src/core/grant-authorization.js.map +1 -0
- package/dist/esm/src/core/message-reply.js +5 -0
- package/dist/esm/src/core/message-reply.js.map +1 -0
- package/dist/esm/src/core/message.js +233 -0
- package/dist/esm/src/core/message.js.map +1 -0
- package/dist/esm/src/core/messages-grant-authorization.js +101 -0
- package/dist/esm/src/core/messages-grant-authorization.js.map +1 -0
- package/dist/esm/src/core/protocol-authorization.js +608 -0
- package/dist/esm/src/core/protocol-authorization.js.map +1 -0
- package/dist/esm/src/core/protocols-grant-authorization.js +66 -0
- package/dist/esm/src/core/protocols-grant-authorization.js.map +1 -0
- package/dist/esm/src/core/records-grant-authorization.js +132 -0
- package/dist/esm/src/core/records-grant-authorization.js.map +1 -0
- package/dist/esm/src/core/resumable-task-manager.js +109 -0
- package/dist/esm/src/core/resumable-task-manager.js.map +1 -0
- package/dist/esm/src/core/tenant-gate.js +20 -0
- package/dist/esm/src/core/tenant-gate.js.map +1 -0
- package/dist/esm/src/dwn.js +164 -0
- package/dist/esm/src/dwn.js.map +1 -0
- package/dist/esm/src/enums/dwn-interface-method.js +16 -0
- package/dist/esm/src/enums/dwn-interface-method.js.map +1 -0
- package/dist/esm/src/event-log/event-emitter-stream.js +60 -0
- package/dist/esm/src/event-log/event-emitter-stream.js.map +1 -0
- package/dist/esm/src/event-log/event-log-level.js +63 -0
- package/dist/esm/src/event-log/event-log-level.js.map +1 -0
- package/dist/esm/src/handlers/messages-query.js +71 -0
- package/dist/esm/src/handlers/messages-query.js.map +1 -0
- package/dist/esm/src/handlers/messages-read.js +102 -0
- package/dist/esm/src/handlers/messages-read.js.map +1 -0
- package/dist/esm/src/handlers/messages-subscribe.js +81 -0
- package/dist/esm/src/handlers/messages-subscribe.js.map +1 -0
- package/dist/esm/src/handlers/protocols-configure.js +133 -0
- package/dist/esm/src/handlers/protocols-configure.js.map +1 -0
- package/dist/esm/src/handlers/protocols-query.js +73 -0
- package/dist/esm/src/handlers/protocols-query.js.map +1 -0
- package/dist/esm/src/handlers/records-delete.js +107 -0
- package/dist/esm/src/handlers/records-delete.js.map +1 -0
- package/dist/esm/src/handlers/records-query.js +210 -0
- package/dist/esm/src/handlers/records-query.js.map +1 -0
- package/dist/esm/src/handlers/records-read.js +169 -0
- package/dist/esm/src/handlers/records-read.js.map +1 -0
- package/dist/esm/src/handlers/records-subscribe.js +172 -0
- package/dist/esm/src/handlers/records-subscribe.js.map +1 -0
- package/dist/esm/src/handlers/records-write.js +344 -0
- package/dist/esm/src/handlers/records-write.js.map +1 -0
- package/dist/esm/src/index.js +49 -0
- package/dist/esm/src/index.js.map +1 -0
- package/dist/esm/src/interfaces/messages-query.js +53 -0
- package/dist/esm/src/interfaces/messages-query.js.map +1 -0
- package/dist/esm/src/interfaces/messages-read.js +61 -0
- package/dist/esm/src/interfaces/messages-read.js.map +1 -0
- package/dist/esm/src/interfaces/messages-subscribe.js +58 -0
- package/dist/esm/src/interfaces/messages-subscribe.js.map +1 -0
- package/dist/esm/src/interfaces/protocols-configure.js +271 -0
- package/dist/esm/src/interfaces/protocols-configure.js.map +1 -0
- package/dist/esm/src/interfaces/protocols-query.js +84 -0
- package/dist/esm/src/interfaces/protocols-query.js.map +1 -0
- package/dist/esm/src/interfaces/records-delete.js +89 -0
- package/dist/esm/src/interfaces/records-delete.js.map +1 -0
- package/dist/esm/src/interfaces/records-query.js +104 -0
- package/dist/esm/src/interfaces/records-query.js.map +1 -0
- package/dist/esm/src/interfaces/records-read.js +84 -0
- package/dist/esm/src/interfaces/records-read.js.map +1 -0
- package/dist/esm/src/interfaces/records-subscribe.js +91 -0
- package/dist/esm/src/interfaces/records-subscribe.js.map +1 -0
- package/dist/esm/src/interfaces/records-write.js +795 -0
- package/dist/esm/src/interfaces/records-write.js.map +1 -0
- package/dist/esm/src/jose/algorithms/signing/ed25519.js +51 -0
- package/dist/esm/src/jose/algorithms/signing/ed25519.js.map +1 -0
- package/dist/esm/src/jose/algorithms/signing/signature-algorithms.js +20 -0
- package/dist/esm/src/jose/algorithms/signing/signature-algorithms.js.map +1 -0
- package/dist/esm/src/jose/jws/general/builder.js +47 -0
- package/dist/esm/src/jose/jws/general/builder.js.map +1 -0
- package/dist/esm/src/jose/jws/general/verifier.js +97 -0
- package/dist/esm/src/jose/jws/general/verifier.js.map +1 -0
- package/dist/esm/src/protocols/permission-grant.js +39 -0
- package/dist/esm/src/protocols/permission-grant.js.map +1 -0
- package/dist/esm/src/protocols/permission-request.js +35 -0
- package/dist/esm/src/protocols/permission-request.js.map +1 -0
- package/dist/esm/src/protocols/permissions.js +357 -0
- package/dist/esm/src/protocols/permissions.js.map +1 -0
- package/dist/esm/src/schema-validator.js +37 -0
- package/dist/esm/src/schema-validator.js.map +1 -0
- package/dist/esm/src/store/blockstore-level.js +187 -0
- package/dist/esm/src/store/blockstore-level.js.map +1 -0
- package/dist/esm/src/store/blockstore-mock.js +168 -0
- package/dist/esm/src/store/blockstore-mock.js.map +1 -0
- package/dist/esm/src/store/data-store-level.js +136 -0
- package/dist/esm/src/store/data-store-level.js.map +1 -0
- package/dist/esm/src/store/index-level.js +660 -0
- package/dist/esm/src/store/index-level.js.map +1 -0
- package/dist/esm/src/store/level-wrapper.js +305 -0
- package/dist/esm/src/store/level-wrapper.js.map +1 -0
- package/dist/esm/src/store/message-store-level.js +159 -0
- package/dist/esm/src/store/message-store-level.js.map +1 -0
- package/dist/esm/src/store/resumable-task-store-level.js +131 -0
- package/dist/esm/src/store/resumable-task-store-level.js.map +1 -0
- package/dist/esm/src/store/storage-controller.js +184 -0
- package/dist/esm/src/store/storage-controller.js.map +1 -0
- package/dist/esm/src/types/cache.js +2 -0
- package/dist/esm/src/types/cache.js.map +1 -0
- package/dist/esm/src/types/data-store.js +2 -0
- package/dist/esm/src/types/data-store.js.map +1 -0
- package/dist/esm/src/types/event-log.js +2 -0
- package/dist/esm/src/types/event-log.js.map +1 -0
- package/dist/esm/src/types/jose-types.js +2 -0
- package/dist/esm/src/types/jose-types.js.map +1 -0
- package/dist/esm/src/types/jws-types.js +2 -0
- package/dist/esm/src/types/jws-types.js.map +1 -0
- package/dist/esm/src/types/message-interface.js +2 -0
- package/dist/esm/src/types/message-interface.js.map +1 -0
- package/dist/esm/src/types/message-store.js +2 -0
- package/dist/esm/src/types/message-store.js.map +1 -0
- package/dist/esm/src/types/message-types.js +3 -0
- package/dist/esm/src/types/message-types.js.map +1 -0
- package/dist/esm/src/types/messages-types.js +2 -0
- package/dist/esm/src/types/messages-types.js.map +1 -0
- package/dist/esm/src/types/method-handler.js +2 -0
- package/dist/esm/src/types/method-handler.js.map +1 -0
- package/dist/esm/src/types/permission-types.js +6 -0
- package/dist/esm/src/types/permission-types.js.map +1 -0
- package/dist/esm/src/types/protocols-types.js +20 -0
- package/dist/esm/src/types/protocols-types.js.map +1 -0
- package/dist/esm/src/types/query-types.js +6 -0
- package/dist/esm/src/types/query-types.js.map +1 -0
- package/dist/esm/src/types/records-types.js +8 -0
- package/dist/esm/src/types/records-types.js.map +1 -0
- package/dist/esm/src/types/resumable-task-store.js +2 -0
- package/dist/esm/src/types/resumable-task-store.js.map +1 -0
- package/dist/esm/src/types/signer.js +2 -0
- package/dist/esm/src/types/signer.js.map +1 -0
- package/dist/esm/src/types/subscriptions.js +2 -0
- package/dist/esm/src/types/subscriptions.js.map +1 -0
- package/dist/esm/src/utils/abort.js +40 -0
- package/dist/esm/src/utils/abort.js.map +1 -0
- package/dist/esm/src/utils/array.js +72 -0
- package/dist/esm/src/utils/array.js.map +1 -0
- package/dist/esm/src/utils/cid.js +130 -0
- package/dist/esm/src/utils/cid.js.map +1 -0
- package/dist/esm/src/utils/data-stream.js +100 -0
- package/dist/esm/src/utils/data-stream.js.map +1 -0
- package/dist/esm/src/utils/encoder.js +45 -0
- package/dist/esm/src/utils/encoder.js.map +1 -0
- package/dist/esm/src/utils/encryption.js +128 -0
- package/dist/esm/src/utils/encryption.js.map +1 -0
- package/dist/esm/src/utils/filter.js +229 -0
- package/dist/esm/src/utils/filter.js.map +1 -0
- package/dist/esm/src/utils/hd-key.js +114 -0
- package/dist/esm/src/utils/hd-key.js.map +1 -0
- package/dist/esm/src/utils/jws.js +89 -0
- package/dist/esm/src/utils/jws.js.map +1 -0
- package/dist/esm/src/utils/memory-cache.js +41 -0
- package/dist/esm/src/utils/memory-cache.js.map +1 -0
- package/dist/esm/src/utils/messages.js +84 -0
- package/dist/esm/src/utils/messages.js.map +1 -0
- package/dist/esm/src/utils/object.js +40 -0
- package/dist/esm/src/utils/object.js.map +1 -0
- package/dist/esm/src/utils/private-key-signer.js +43 -0
- package/dist/esm/src/utils/private-key-signer.js.map +1 -0
- package/dist/esm/src/utils/protocols.js +51 -0
- package/dist/esm/src/utils/protocols.js.map +1 -0
- package/dist/esm/src/utils/records.js +454 -0
- package/dist/esm/src/utils/records.js.map +1 -0
- package/dist/esm/src/utils/secp256k1.js +166 -0
- package/dist/esm/src/utils/secp256k1.js.map +1 -0
- package/dist/esm/src/utils/secp256r1.js +120 -0
- package/dist/esm/src/utils/secp256r1.js.map +1 -0
- package/dist/esm/src/utils/string.js +16 -0
- package/dist/esm/src/utils/string.js.map +1 -0
- package/dist/esm/src/utils/time.js +85 -0
- package/dist/esm/src/utils/time.js.map +1 -0
- package/dist/esm/src/utils/url.js +62 -0
- package/dist/esm/src/utils/url.js.map +1 -0
- package/dist/esm/tests/core/auth.spec.js +22 -0
- package/dist/esm/tests/core/auth.spec.js.map +1 -0
- package/dist/esm/tests/core/message-reply.spec.js +16 -0
- package/dist/esm/tests/core/message-reply.spec.js.map +1 -0
- package/dist/esm/tests/core/message.spec.js +146 -0
- package/dist/esm/tests/core/message.spec.js.map +1 -0
- package/dist/esm/tests/core/protocol-authorization.spec.js +48 -0
- package/dist/esm/tests/core/protocol-authorization.spec.js.map +1 -0
- package/dist/esm/tests/dwn.spec.js +166 -0
- package/dist/esm/tests/dwn.spec.js.map +1 -0
- package/dist/esm/tests/event-log/event-emitter-stream.spec.js +78 -0
- package/dist/esm/tests/event-log/event-emitter-stream.spec.js.map +1 -0
- package/dist/esm/tests/event-log/event-log-level.spec.js +44 -0
- package/dist/esm/tests/event-log/event-log-level.spec.js.map +1 -0
- package/dist/esm/tests/event-log/event-log.spec.js +236 -0
- package/dist/esm/tests/event-log/event-log.spec.js.map +1 -0
- package/dist/esm/tests/event-log/event-stream.spec.js +125 -0
- package/dist/esm/tests/event-log/event-stream.spec.js.map +1 -0
- package/dist/esm/tests/features/author-delegated-grant.spec.js +1273 -0
- package/dist/esm/tests/features/author-delegated-grant.spec.js.map +1 -0
- package/dist/esm/tests/features/owner-delegated-grant.spec.js +584 -0
- package/dist/esm/tests/features/owner-delegated-grant.spec.js.map +1 -0
- package/dist/esm/tests/features/owner-signature.spec.js +192 -0
- package/dist/esm/tests/features/owner-signature.spec.js.map +1 -0
- package/dist/esm/tests/features/permissions.spec.js +815 -0
- package/dist/esm/tests/features/permissions.spec.js.map +1 -0
- package/dist/esm/tests/features/protocol-create-action.spec.js +248 -0
- package/dist/esm/tests/features/protocol-create-action.spec.js.map +1 -0
- package/dist/esm/tests/features/protocol-delete-action.spec.js +492 -0
- package/dist/esm/tests/features/protocol-delete-action.spec.js.map +1 -0
- package/dist/esm/tests/features/protocol-update-action.spec.js +572 -0
- package/dist/esm/tests/features/protocol-update-action.spec.js.map +1 -0
- package/dist/esm/tests/features/records-prune.spec.js +812 -0
- package/dist/esm/tests/features/records-prune.spec.js.map +1 -0
- package/dist/esm/tests/features/records-tags.spec.js +2516 -0
- package/dist/esm/tests/features/records-tags.spec.js.map +1 -0
- package/dist/esm/tests/features/resumable-tasks.spec.js +349 -0
- package/dist/esm/tests/features/resumable-tasks.spec.js.map +1 -0
- package/dist/esm/tests/handlers/messages-query.spec.js +349 -0
- package/dist/esm/tests/handlers/messages-query.spec.js.map +1 -0
- package/dist/esm/tests/handlers/messages-read.spec.js +647 -0
- package/dist/esm/tests/handlers/messages-read.spec.js.map +1 -0
- package/dist/esm/tests/handlers/messages-subscribe.spec.js +432 -0
- package/dist/esm/tests/handlers/messages-subscribe.spec.js.map +1 -0
- package/dist/esm/tests/handlers/protocols-configure.spec.js +608 -0
- package/dist/esm/tests/handlers/protocols-configure.spec.js.map +1 -0
- package/dist/esm/tests/handlers/protocols-query.spec.js +454 -0
- package/dist/esm/tests/handlers/protocols-query.spec.js.map +1 -0
- package/dist/esm/tests/handlers/records-delete.spec.js +662 -0
- package/dist/esm/tests/handlers/records-delete.spec.js.map +1 -0
- package/dist/esm/tests/handlers/records-query.spec.js +2695 -0
- package/dist/esm/tests/handlers/records-query.spec.js.map +1 -0
- package/dist/esm/tests/handlers/records-read.spec.js +1724 -0
- package/dist/esm/tests/handlers/records-read.spec.js.map +1 -0
- package/dist/esm/tests/handlers/records-subscribe.spec.js +684 -0
- package/dist/esm/tests/handlers/records-subscribe.spec.js.map +1 -0
- package/dist/esm/tests/handlers/records-write.spec.js +3637 -0
- package/dist/esm/tests/handlers/records-write.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/messages-get.spec.js +78 -0
- package/dist/esm/tests/interfaces/messages-get.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js +30 -0
- package/dist/esm/tests/interfaces/messages-subscribe.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/messagess-query.spec.js +127 -0
- package/dist/esm/tests/interfaces/messagess-query.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/protocols-configure.spec.js +489 -0
- package/dist/esm/tests/interfaces/protocols-configure.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/protocols-query.spec.js +46 -0
- package/dist/esm/tests/interfaces/protocols-query.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/records-delete.spec.js +39 -0
- package/dist/esm/tests/interfaces/records-delete.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/records-query.spec.js +85 -0
- package/dist/esm/tests/interfaces/records-query.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/records-read.spec.js +62 -0
- package/dist/esm/tests/interfaces/records-read.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/records-subscribe.spec.js +72 -0
- package/dist/esm/tests/interfaces/records-subscribe.spec.js.map +1 -0
- package/dist/esm/tests/interfaces/records-write.spec.js +423 -0
- package/dist/esm/tests/interfaces/records-write.spec.js.map +1 -0
- package/dist/esm/tests/jose/jws/general.spec.js +243 -0
- package/dist/esm/tests/jose/jws/general.spec.js.map +1 -0
- package/dist/esm/tests/protocols/permission-request.spec.js +40 -0
- package/dist/esm/tests/protocols/permission-request.spec.js.map +1 -0
- package/dist/esm/tests/protocols/permissions.spec.js +123 -0
- package/dist/esm/tests/protocols/permissions.spec.js.map +1 -0
- package/dist/esm/tests/scenarios/aggregator.spec.js +670 -0
- package/dist/esm/tests/scenarios/aggregator.spec.js.map +1 -0
- package/dist/esm/tests/scenarios/deleted-record.spec.js +102 -0
- package/dist/esm/tests/scenarios/deleted-record.spec.js.map +1 -0
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js +220 -0
- package/dist/esm/tests/scenarios/end-to-end-tests.spec.js.map +1 -0
- package/dist/esm/tests/scenarios/messages-query.spec.js +395 -0
- package/dist/esm/tests/scenarios/messages-query.spec.js.map +1 -0
- package/dist/esm/tests/scenarios/nested-roles.spec.js +300 -0
- package/dist/esm/tests/scenarios/nested-roles.spec.js.map +1 -0
- package/dist/esm/tests/scenarios/subscriptions.spec.js +886 -0
- package/dist/esm/tests/scenarios/subscriptions.spec.js.map +1 -0
- package/dist/esm/tests/store/blockstore-mock.spec.js +192 -0
- package/dist/esm/tests/store/blockstore-mock.spec.js.map +1 -0
- package/dist/esm/tests/store/data-store-level.spec.js +146 -0
- package/dist/esm/tests/store/data-store-level.spec.js.map +1 -0
- package/dist/esm/tests/store/index-level.spec.js +1208 -0
- package/dist/esm/tests/store/index-level.spec.js.map +1 -0
- package/dist/esm/tests/store/message-store-level.spec.js +48 -0
- package/dist/esm/tests/store/message-store-level.spec.js.map +1 -0
- package/dist/esm/tests/store/message-store.spec.js +404 -0
- package/dist/esm/tests/store/message-store.spec.js.map +1 -0
- package/dist/esm/tests/store-dependent-tests.spec.js +5 -0
- package/dist/esm/tests/store-dependent-tests.spec.js.map +1 -0
- package/dist/esm/tests/test-event-stream.js +25 -0
- package/dist/esm/tests/test-event-stream.js.map +1 -0
- package/dist/esm/tests/test-stores.js +45 -0
- package/dist/esm/tests/test-stores.js.map +1 -0
- package/dist/esm/tests/test-suite.js +88 -0
- package/dist/esm/tests/test-suite.js.map +1 -0
- package/dist/esm/tests/utils/cid.spec.js +80 -0
- package/dist/esm/tests/utils/cid.spec.js.map +1 -0
- package/dist/esm/tests/utils/data-stream.spec.js +27 -0
- package/dist/esm/tests/utils/data-stream.spec.js.map +1 -0
- package/dist/esm/tests/utils/encryption.spec.js +148 -0
- package/dist/esm/tests/utils/encryption.spec.js.map +1 -0
- package/dist/esm/tests/utils/filters.spec.js +295 -0
- package/dist/esm/tests/utils/filters.spec.js.map +1 -0
- package/dist/esm/tests/utils/hd-key.spec.js +35 -0
- package/dist/esm/tests/utils/hd-key.spec.js.map +1 -0
- package/dist/esm/tests/utils/jws.spec.js +8 -0
- package/dist/esm/tests/utils/jws.spec.js.map +1 -0
- package/dist/esm/tests/utils/memory-cache.spec.js +35 -0
- package/dist/esm/tests/utils/memory-cache.spec.js.map +1 -0
- package/dist/esm/tests/utils/messages.spec.js +101 -0
- package/dist/esm/tests/utils/messages.spec.js.map +1 -0
- package/dist/esm/tests/utils/object.spec.js +36 -0
- package/dist/esm/tests/utils/object.spec.js.map +1 -0
- package/dist/esm/tests/utils/poller.js +49 -0
- package/dist/esm/tests/utils/poller.js.map +1 -0
- package/dist/esm/tests/utils/private-key-signer.spec.js +44 -0
- package/dist/esm/tests/utils/private-key-signer.spec.js.map +1 -0
- package/dist/esm/tests/utils/records.spec.js +53 -0
- package/dist/esm/tests/utils/records.spec.js.map +1 -0
- package/dist/esm/tests/utils/secp256k1.spec.js +50 -0
- package/dist/esm/tests/utils/secp256k1.spec.js.map +1 -0
- package/dist/esm/tests/utils/secp256r1.spec.js +56 -0
- package/dist/esm/tests/utils/secp256r1.spec.js.map +1 -0
- package/dist/esm/tests/utils/test-data-generator.js +643 -0
- package/dist/esm/tests/utils/test-data-generator.js.map +1 -0
- package/dist/esm/tests/utils/test-stub-generator.js +39 -0
- package/dist/esm/tests/utils/test-stub-generator.js.map +1 -0
- package/dist/esm/tests/utils/time.spec.js +64 -0
- package/dist/esm/tests/utils/time.spec.js.map +1 -0
- package/dist/esm/tests/utils/url.spec.js +43 -0
- package/dist/esm/tests/utils/url.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js +33 -0
- package/dist/esm/tests/validation/json-schemas/definitions.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js +50 -0
- package/dist/esm/tests/validation/json-schemas/jwk/general-jwk.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js +36 -0
- package/dist/esm/tests/validation/json-schemas/jwk/public-jwk.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js +82 -0
- package/dist/esm/tests/validation/json-schemas/jwk-verification-method.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js +75 -0
- package/dist/esm/tests/validation/json-schemas/protocols/protocols-configure.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js +148 -0
- package/dist/esm/tests/validation/json-schemas/records/records-query.spec.js.map +1 -0
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js +421 -0
- package/dist/esm/tests/validation/json-schemas/records/records-write.spec.js.map +1 -0
- package/dist/esm/tests/vectors/protocol-definitions/anyone-collaborate.json +21 -0
- package/dist/esm/tests/vectors/protocol-definitions/author-can.json +33 -0
- package/dist/esm/tests/vectors/protocol-definitions/chat.json +70 -0
- package/dist/esm/tests/vectors/protocol-definitions/credential-issuance.json +41 -0
- package/dist/esm/tests/vectors/protocol-definitions/dex.json +58 -0
- package/dist/esm/tests/vectors/protocol-definitions/email.json +62 -0
- package/dist/esm/tests/vectors/protocol-definitions/free-for-all.json +45 -0
- package/dist/esm/tests/vectors/protocol-definitions/friend-role.json +48 -0
- package/dist/esm/tests/vectors/protocol-definitions/message.json +37 -0
- package/dist/esm/tests/vectors/protocol-definitions/minimal.json +10 -0
- package/dist/esm/tests/vectors/protocol-definitions/nested.json +31 -0
- package/dist/esm/tests/vectors/protocol-definitions/private-protocol.json +15 -0
- package/dist/esm/tests/vectors/protocol-definitions/recipient-can.json +33 -0
- package/dist/esm/tests/vectors/protocol-definitions/slack.json +242 -0
- package/dist/esm/tests/vectors/protocol-definitions/social-media.json +106 -0
- package/dist/esm/tests/vectors/protocol-definitions/thread-role.json +70 -0
- package/dist/types/generated/precompiled-validators.d.ts +597 -0
- package/dist/types/generated/precompiled-validators.d.ts.map +1 -0
- package/dist/types/src/core/abstract-message.d.ts +25 -0
- package/dist/types/src/core/abstract-message.d.ts.map +1 -0
- package/dist/types/src/core/auth.d.ts +9 -0
- package/dist/types/src/core/auth.d.ts.map +1 -0
- package/dist/types/src/core/dwn-constant.d.ts +10 -0
- package/dist/types/src/core/dwn-constant.d.ts.map +1 -0
- package/dist/types/src/core/dwn-error.d.ts +164 -0
- package/dist/types/src/core/dwn-error.d.ts.map +1 -0
- package/dist/types/src/core/grant-authorization.d.ts +43 -0
- package/dist/types/src/core/grant-authorization.d.ts.map +1 -0
- package/dist/types/src/core/message-reply.d.ts +32 -0
- package/dist/types/src/core/message-reply.d.ts.map +1 -0
- package/dist/types/src/core/message.d.ts +94 -0
- package/dist/types/src/core/message.d.ts.map +1 -0
- package/dist/types/src/core/messages-grant-authorization.d.ts +34 -0
- package/dist/types/src/core/messages-grant-authorization.d.ts.map +1 -0
- package/dist/types/src/core/protocol-authorization.d.ts +103 -0
- package/dist/types/src/core/protocol-authorization.d.ts.map +1 -0
- package/dist/types/src/core/protocols-grant-authorization.d.ts +31 -0
- package/dist/types/src/core/protocols-grant-authorization.d.ts.map +1 -0
- package/dist/types/src/core/records-grant-authorization.d.ts +60 -0
- package/dist/types/src/core/records-grant-authorization.d.ts.map +1 -0
- package/dist/types/src/core/resumable-task-manager.d.ts +43 -0
- package/dist/types/src/core/resumable-task-manager.d.ts.map +1 -0
- package/dist/types/src/core/tenant-gate.d.ts +29 -0
- package/dist/types/src/core/tenant-gate.d.ts.map +1 -0
- package/dist/types/src/dwn.d.ts +85 -0
- package/dist/types/src/dwn.d.ts.map +1 -0
- package/dist/types/src/enums/dwn-interface-method.d.ts +14 -0
- package/dist/types/src/enums/dwn-interface-method.d.ts.map +1 -0
- package/dist/types/src/event-log/event-emitter-stream.d.ts +23 -0
- package/dist/types/src/event-log/event-emitter-stream.d.ts.map +1 -0
- package/dist/types/src/event-log/event-log-level.d.ts +35 -0
- package/dist/types/src/event-log/event-log-level.d.ts.map +1 -0
- package/dist/types/src/handlers/messages-query.d.ts +17 -0
- package/dist/types/src/handlers/messages-query.d.ts.map +1 -0
- package/dist/types/src/handlers/messages-read.d.ts +22 -0
- package/dist/types/src/handlers/messages-read.d.ts.map +1 -0
- package/dist/types/src/handlers/messages-subscribe.d.ts +18 -0
- package/dist/types/src/handlers/messages-subscribe.d.ts.map +1 -0
- package/dist/types/src/handlers/protocols-configure.d.ts +24 -0
- package/dist/types/src/handlers/protocols-configure.d.ts.map +1 -0
- package/dist/types/src/handlers/protocols-query.d.ts +20 -0
- package/dist/types/src/handlers/protocols-query.d.ts.map +1 -0
- package/dist/types/src/handlers/records-delete.d.ts +23 -0
- package/dist/types/src/handlers/records-delete.d.ts.map +1 -0
- package/dist/types/src/handlers/records-query.d.ts +70 -0
- package/dist/types/src/handlers/records-query.d.ts.map +1 -0
- package/dist/types/src/handlers/records-read.d.ts +20 -0
- package/dist/types/src/handlers/records-read.d.ts.map +1 -0
- package/dist/types/src/handlers/records-subscribe.d.ts +62 -0
- package/dist/types/src/handlers/records-subscribe.d.ts.map +1 -0
- package/dist/types/src/handlers/records-write.d.ts +51 -0
- package/dist/types/src/handlers/records-write.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +63 -0
- package/dist/types/src/index.d.ts.map +1 -0
- package/dist/types/src/interfaces/messages-query.d.ts +16 -0
- package/dist/types/src/interfaces/messages-query.d.ts.map +1 -0
- package/dist/types/src/interfaces/messages-read.d.ts +20 -0
- package/dist/types/src/interfaces/messages-read.d.ts.map +1 -0
- package/dist/types/src/interfaces/messages-subscribe.d.ts +20 -0
- package/dist/types/src/interfaces/messages-subscribe.d.ts.map +1 -0
- package/dist/types/src/interfaces/protocols-configure.d.ts +40 -0
- package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -0
- package/dist/types/src/interfaces/protocols-query.d.ts +17 -0
- package/dist/types/src/interfaces/protocols-query.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-delete.d.ts +34 -0
- package/dist/types/src/interfaces/records-delete.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-query.d.ts +31 -0
- package/dist/types/src/interfaces/records-query.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-read.d.ts +36 -0
- package/dist/types/src/interfaces/records-read.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-subscribe.d.ts +27 -0
- package/dist/types/src/interfaces/records-subscribe.d.ts.map +1 -0
- package/dist/types/src/interfaces/records-write.d.ts +309 -0
- package/dist/types/src/interfaces/records-write.d.ts.map +1 -0
- package/dist/types/src/jose/algorithms/signing/ed25519.d.ts +3 -0
- package/dist/types/src/jose/algorithms/signing/ed25519.d.ts.map +1 -0
- package/dist/types/src/jose/algorithms/signing/signature-algorithms.d.ts +3 -0
- package/dist/types/src/jose/algorithms/signing/signature-algorithms.d.ts.map +1 -0
- package/dist/types/src/jose/jws/general/builder.d.ts +10 -0
- package/dist/types/src/jose/jws/general/builder.d.ts.map +1 -0
- package/dist/types/src/jose/jws/general/verifier.d.ts +32 -0
- package/dist/types/src/jose/jws/general/verifier.d.ts.map +1 -0
- package/dist/types/src/protocols/permission-grant.d.ts +50 -0
- package/dist/types/src/protocols/permission-grant.d.ts.map +1 -0
- package/dist/types/src/protocols/permission-request.d.ts +35 -0
- package/dist/types/src/protocols/permission-request.d.ts.map +1 -0
- package/dist/types/src/protocols/permissions.d.ts +150 -0
- package/dist/types/src/protocols/permissions.d.ts.map +1 -0
- package/dist/types/src/schema-validator.d.ts +8 -0
- package/dist/types/src/schema-validator.d.ts.map +1 -0
- package/dist/types/src/store/blockstore-level.d.ts +34 -0
- package/dist/types/src/store/blockstore-level.d.ts.map +1 -0
- package/dist/types/src/store/blockstore-mock.d.ts +27 -0
- package/dist/types/src/store/blockstore-mock.d.ts.map +1 -0
- package/dist/types/src/store/data-store-level.d.ts +34 -0
- package/dist/types/src/store/data-store-level.d.ts.map +1 -0
- package/dist/types/src/store/index-level.d.ts +171 -0
- package/dist/types/src/store/index-level.d.ts.map +1 -0
- package/dist/types/src/store/level-wrapper.d.ts +48 -0
- package/dist/types/src/store/level-wrapper.d.ts.map +1 -0
- package/dist/types/src/store/message-store-level.d.ts +46 -0
- package/dist/types/src/store/message-store-level.d.ts.map +1 -0
- package/dist/types/src/store/resumable-task-store-level.d.ts +28 -0
- package/dist/types/src/store/resumable-task-store-level.d.ts.map +1 -0
- package/dist/types/src/store/storage-controller.d.ts +46 -0
- package/dist/types/src/store/storage-controller.d.ts.map +1 -0
- package/dist/types/src/types/cache.d.ts +16 -0
- package/dist/types/src/types/cache.d.ts.map +1 -0
- package/dist/types/src/types/data-store.d.ts +57 -0
- package/dist/types/src/types/data-store.d.ts.map +1 -0
- package/dist/types/src/types/event-log.d.ts +52 -0
- package/dist/types/src/types/event-log.d.ts.map +1 -0
- package/dist/types/src/types/jose-types.d.ts +75 -0
- package/dist/types/src/types/jose-types.d.ts.map +1 -0
- package/dist/types/src/types/jws-types.d.ts +27 -0
- package/dist/types/src/types/jws-types.d.ts.map +1 -0
- package/dist/types/src/types/message-interface.d.ts +27 -0
- package/dist/types/src/types/message-interface.d.ts.map +1 -0
- package/dist/types/src/types/message-store.d.ts +42 -0
- package/dist/types/src/types/message-store.d.ts.map +1 -0
- package/dist/types/src/types/message-types.d.ts +116 -0
- package/dist/types/src/types/message-types.d.ts.map +1 -0
- package/dist/types/src/types/messages-types.d.ts +65 -0
- package/dist/types/src/types/messages-types.d.ts.map +1 -0
- package/dist/types/src/types/method-handler.d.ts +19 -0
- package/dist/types/src/types/method-handler.d.ts.map +1 -0
- package/dist/types/src/types/permission-types.d.ts +93 -0
- package/dist/types/src/types/permission-types.d.ts.map +1 -0
- package/dist/types/src/types/protocols-types.d.ts +154 -0
- package/dist/types/src/types/protocols-types.d.ts.map +1 -0
- package/dist/types/src/types/query-types.d.ts +66 -0
- package/dist/types/src/types/query-types.d.ts.map +1 -0
- package/dist/types/src/types/records-types.d.ts +230 -0
- package/dist/types/src/types/records-types.d.ts.map +1 -0
- package/dist/types/src/types/resumable-task-store.d.ts +89 -0
- package/dist/types/src/types/resumable-task-store.d.ts.map +1 -0
- package/dist/types/src/types/signer.d.ts +26 -0
- package/dist/types/src/types/signer.d.ts.map +1 -0
- package/dist/types/src/types/subscriptions.d.ts +30 -0
- package/dist/types/src/types/subscriptions.d.ts.map +1 -0
- package/dist/types/src/utils/abort.d.ts +5 -0
- package/dist/types/src/utils/abort.d.ts.map +1 -0
- package/dist/types/src/utils/array.d.ts +18 -0
- package/dist/types/src/utils/array.d.ts.map +1 -0
- package/dist/types/src/utils/cid.d.ts +30 -0
- package/dist/types/src/utils/cid.d.ts.map +1 -0
- package/dist/types/src/utils/data-stream.d.ts +31 -0
- package/dist/types/src/utils/data-stream.d.ts.map +1 -0
- package/dist/types/src/utils/encoder.d.ts +14 -0
- package/dist/types/src/utils/encoder.d.ts.map +1 -0
- package/dist/types/src/utils/encryption.d.ts +44 -0
- package/dist/types/src/utils/encryption.d.ts.map +1 -0
- package/dist/types/src/utils/filter.d.ts +60 -0
- package/dist/types/src/utils/filter.d.ts.map +1 -0
- package/dist/types/src/utils/hd-key.d.ts +54 -0
- package/dist/types/src/utils/hd-key.d.ts.map +1 -0
- package/dist/types/src/utils/jws.d.ts +39 -0
- package/dist/types/src/utils/jws.d.ts.map +1 -0
- package/dist/types/src/utils/memory-cache.d.ts +15 -0
- package/dist/types/src/utils/memory-cache.d.ts.map +1 -0
- package/dist/types/src/utils/messages.d.ts +27 -0
- package/dist/types/src/utils/messages.d.ts.map +1 -0
- package/dist/types/src/utils/object.d.ts +13 -0
- package/dist/types/src/utils/object.d.ts.map +1 -0
- package/dist/types/src/utils/private-key-signer.d.ts +34 -0
- package/dist/types/src/utils/private-key-signer.d.ts.map +1 -0
- package/dist/types/src/utils/protocols.d.ts +14 -0
- package/dist/types/src/utils/protocols.d.ts.map +1 -0
- package/dist/types/src/utils/records.d.ts +122 -0
- package/dist/types/src/utils/records.d.ts.map +1 -0
- package/dist/types/src/utils/secp256k1.d.ts +59 -0
- package/dist/types/src/utils/secp256k1.d.ts.map +1 -0
- package/dist/types/src/utils/secp256r1.d.ts +39 -0
- package/dist/types/src/utils/secp256r1.d.ts.map +1 -0
- package/dist/types/src/utils/string.d.ts +6 -0
- package/dist/types/src/utils/string.d.ts.map +1 -0
- package/dist/types/src/utils/time.d.ts +50 -0
- package/dist/types/src/utils/time.d.ts.map +1 -0
- package/dist/types/src/utils/url.d.ts +5 -0
- package/dist/types/src/utils/url.d.ts.map +1 -0
- package/dist/types/tests/core/auth.spec.d.ts +2 -0
- package/dist/types/tests/core/auth.spec.d.ts.map +1 -0
- package/dist/types/tests/core/message-reply.spec.d.ts +2 -0
- package/dist/types/tests/core/message-reply.spec.d.ts.map +1 -0
- package/dist/types/tests/core/message.spec.d.ts +2 -0
- package/dist/types/tests/core/message.spec.d.ts.map +1 -0
- package/dist/types/tests/core/protocol-authorization.spec.d.ts +2 -0
- package/dist/types/tests/core/protocol-authorization.spec.d.ts.map +1 -0
- package/dist/types/tests/dwn.spec.d.ts +2 -0
- package/dist/types/tests/dwn.spec.d.ts.map +1 -0
- package/dist/types/tests/event-log/event-emitter-stream.spec.d.ts +2 -0
- package/dist/types/tests/event-log/event-emitter-stream.spec.d.ts.map +1 -0
- package/dist/types/tests/event-log/event-log-level.spec.d.ts +2 -0
- package/dist/types/tests/event-log/event-log-level.spec.d.ts.map +1 -0
- package/dist/types/tests/event-log/event-log.spec.d.ts +2 -0
- package/dist/types/tests/event-log/event-log.spec.d.ts.map +1 -0
- package/dist/types/tests/event-log/event-stream.spec.d.ts +2 -0
- package/dist/types/tests/event-log/event-stream.spec.d.ts.map +1 -0
- package/dist/types/tests/features/author-delegated-grant.spec.d.ts +2 -0
- package/dist/types/tests/features/author-delegated-grant.spec.d.ts.map +1 -0
- package/dist/types/tests/features/owner-delegated-grant.spec.d.ts +2 -0
- package/dist/types/tests/features/owner-delegated-grant.spec.d.ts.map +1 -0
- package/dist/types/tests/features/owner-signature.spec.d.ts +2 -0
- package/dist/types/tests/features/owner-signature.spec.d.ts.map +1 -0
- package/dist/types/tests/features/permissions.spec.d.ts +2 -0
- package/dist/types/tests/features/permissions.spec.d.ts.map +1 -0
- package/dist/types/tests/features/protocol-create-action.spec.d.ts +2 -0
- package/dist/types/tests/features/protocol-create-action.spec.d.ts.map +1 -0
- package/dist/types/tests/features/protocol-delete-action.spec.d.ts +2 -0
- package/dist/types/tests/features/protocol-delete-action.spec.d.ts.map +1 -0
- package/dist/types/tests/features/protocol-update-action.spec.d.ts +2 -0
- package/dist/types/tests/features/protocol-update-action.spec.d.ts.map +1 -0
- package/dist/types/tests/features/records-prune.spec.d.ts +2 -0
- package/dist/types/tests/features/records-prune.spec.d.ts.map +1 -0
- package/dist/types/tests/features/records-tags.spec.d.ts +2 -0
- package/dist/types/tests/features/records-tags.spec.d.ts.map +1 -0
- package/dist/types/tests/features/resumable-tasks.spec.d.ts +2 -0
- package/dist/types/tests/features/resumable-tasks.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/messages-query.spec.d.ts +2 -0
- package/dist/types/tests/handlers/messages-query.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/messages-read.spec.d.ts +2 -0
- package/dist/types/tests/handlers/messages-read.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/messages-subscribe.spec.d.ts +2 -0
- package/dist/types/tests/handlers/messages-subscribe.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/protocols-configure.spec.d.ts +2 -0
- package/dist/types/tests/handlers/protocols-configure.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/protocols-query.spec.d.ts +2 -0
- package/dist/types/tests/handlers/protocols-query.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/records-delete.spec.d.ts +2 -0
- package/dist/types/tests/handlers/records-delete.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/records-query.spec.d.ts +2 -0
- package/dist/types/tests/handlers/records-query.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/records-read.spec.d.ts +2 -0
- package/dist/types/tests/handlers/records-read.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/records-subscribe.spec.d.ts +2 -0
- package/dist/types/tests/handlers/records-subscribe.spec.d.ts.map +1 -0
- package/dist/types/tests/handlers/records-write.spec.d.ts +2 -0
- package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/messages-get.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/messages-get.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/messages-subscribe.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/messages-subscribe.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/messagess-query.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/messagess-query.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/protocols-configure.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/protocols-configure.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/protocols-query.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/protocols-query.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/records-delete.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/records-delete.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/records-query.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/records-query.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/records-read.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/records-read.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/records-subscribe.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/records-subscribe.spec.d.ts.map +1 -0
- package/dist/types/tests/interfaces/records-write.spec.d.ts +2 -0
- package/dist/types/tests/interfaces/records-write.spec.d.ts.map +1 -0
- package/dist/types/tests/jose/jws/general.spec.d.ts +2 -0
- package/dist/types/tests/jose/jws/general.spec.d.ts.map +1 -0
- package/dist/types/tests/protocols/permission-request.spec.d.ts +2 -0
- package/dist/types/tests/protocols/permission-request.spec.d.ts.map +1 -0
- package/dist/types/tests/protocols/permissions.spec.d.ts +2 -0
- package/dist/types/tests/protocols/permissions.spec.d.ts.map +1 -0
- package/dist/types/tests/scenarios/aggregator.spec.d.ts +2 -0
- package/dist/types/tests/scenarios/aggregator.spec.d.ts.map +1 -0
- package/dist/types/tests/scenarios/deleted-record.spec.d.ts +2 -0
- package/dist/types/tests/scenarios/deleted-record.spec.d.ts.map +1 -0
- package/dist/types/tests/scenarios/end-to-end-tests.spec.d.ts +2 -0
- package/dist/types/tests/scenarios/end-to-end-tests.spec.d.ts.map +1 -0
- package/dist/types/tests/scenarios/messages-query.spec.d.ts +2 -0
- package/dist/types/tests/scenarios/messages-query.spec.d.ts.map +1 -0
- package/dist/types/tests/scenarios/nested-roles.spec.d.ts +2 -0
- package/dist/types/tests/scenarios/nested-roles.spec.d.ts.map +1 -0
- package/dist/types/tests/scenarios/subscriptions.spec.d.ts +2 -0
- package/dist/types/tests/scenarios/subscriptions.spec.d.ts.map +1 -0
- package/dist/types/tests/store/blockstore-mock.spec.d.ts +2 -0
- package/dist/types/tests/store/blockstore-mock.spec.d.ts.map +1 -0
- package/dist/types/tests/store/data-store-level.spec.d.ts +2 -0
- package/dist/types/tests/store/data-store-level.spec.d.ts.map +1 -0
- package/dist/types/tests/store/index-level.spec.d.ts +2 -0
- package/dist/types/tests/store/index-level.spec.d.ts.map +1 -0
- package/dist/types/tests/store/message-store-level.spec.d.ts +2 -0
- package/dist/types/tests/store/message-store-level.spec.d.ts.map +1 -0
- package/dist/types/tests/store/message-store.spec.d.ts +2 -0
- package/dist/types/tests/store/message-store.spec.d.ts.map +1 -0
- package/dist/types/tests/store-dependent-tests.spec.d.ts +2 -0
- package/dist/types/tests/store-dependent-tests.spec.d.ts.map +1 -0
- package/dist/types/tests/test-event-stream.d.ts +22 -0
- package/dist/types/tests/test-event-stream.d.ts.map +1 -0
- package/dist/types/tests/test-stores.d.ts +33 -0
- package/dist/types/tests/test-stores.d.ts.map +1 -0
- package/dist/types/tests/test-suite.d.ts +18 -0
- package/dist/types/tests/test-suite.d.ts.map +1 -0
- package/dist/types/tests/utils/cid.spec.d.ts +2 -0
- package/dist/types/tests/utils/cid.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/data-stream.spec.d.ts +2 -0
- package/dist/types/tests/utils/data-stream.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/encryption.spec.d.ts +2 -0
- package/dist/types/tests/utils/encryption.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/filters.spec.d.ts +2 -0
- package/dist/types/tests/utils/filters.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/hd-key.spec.d.ts +2 -0
- package/dist/types/tests/utils/hd-key.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/jws.spec.d.ts +2 -0
- package/dist/types/tests/utils/jws.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/memory-cache.spec.d.ts +2 -0
- package/dist/types/tests/utils/memory-cache.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/messages.spec.d.ts +2 -0
- package/dist/types/tests/utils/messages.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/object.spec.d.ts +2 -0
- package/dist/types/tests/utils/object.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/poller.d.ts +21 -0
- package/dist/types/tests/utils/poller.d.ts.map +1 -0
- package/dist/types/tests/utils/private-key-signer.spec.d.ts +2 -0
- package/dist/types/tests/utils/private-key-signer.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/records.spec.d.ts +2 -0
- package/dist/types/tests/utils/records.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/secp256k1.spec.d.ts +2 -0
- package/dist/types/tests/utils/secp256k1.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/secp256r1.spec.d.ts +2 -0
- package/dist/types/tests/utils/secp256r1.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/test-data-generator.d.ts +342 -0
- package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -0
- package/dist/types/tests/utils/test-stub-generator.d.ts +16 -0
- package/dist/types/tests/utils/test-stub-generator.d.ts.map +1 -0
- package/dist/types/tests/utils/time.spec.d.ts +2 -0
- package/dist/types/tests/utils/time.spec.d.ts.map +1 -0
- package/dist/types/tests/utils/url.spec.d.ts +2 -0
- package/dist/types/tests/utils/url.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/definitions.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/definitions.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/jwk/general-jwk.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/jwk/general-jwk.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/jwk/public-jwk.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/jwk/public-jwk.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/jwk-verification-method.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/jwk-verification-method.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/protocols/protocols-configure.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/protocols/protocols-configure.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/records/records-query.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/records/records-query.spec.d.ts.map +1 -0
- package/dist/types/tests/validation/json-schemas/records/records-write.spec.d.ts +2 -0
- package/dist/types/tests/validation/json-schemas/records/records-write.spec.d.ts.map +1 -0
- package/package.json +167 -0
- package/src/core/abstract-message.ts +62 -0
- package/src/core/auth.ts +36 -0
- package/src/core/dwn-constant.ts +9 -0
- package/src/core/dwn-error.ts +167 -0
- package/src/core/grant-authorization.ts +148 -0
- package/src/core/message-reply.ts +41 -0
- package/src/core/message.ts +259 -0
- package/src/core/messages-grant-authorization.ts +134 -0
- package/src/core/protocol-authorization.ts +903 -0
- package/src/core/protocols-grant-authorization.ts +88 -0
- package/src/core/records-grant-authorization.ts +197 -0
- package/src/core/resumable-task-manager.ts +114 -0
- package/src/core/tenant-gate.ts +33 -0
- package/src/dwn.ts +264 -0
- package/src/enums/dwn-interface-method.ts +14 -0
- package/src/event-log/event-emitter-stream.ts +69 -0
- package/src/event-log/event-log-level.ts +72 -0
- package/src/handlers/messages-query.ts +67 -0
- package/src/handlers/messages-read.ts +103 -0
- package/src/handlers/messages-subscribe.ts +89 -0
- package/src/handlers/protocols-configure.ts +137 -0
- package/src/handlers/protocols-query.ts +82 -0
- package/src/handlers/records-delete.ts +124 -0
- package/src/handlers/records-query.ts +262 -0
- package/src/handlers/records-read.ts +187 -0
- package/src/handlers/records-subscribe.ts +218 -0
- package/src/handlers/records-write.ts +404 -0
- package/src/index.ts +67 -0
- package/src/interfaces/messages-query.ts +60 -0
- package/src/interfaces/messages-read.ts +63 -0
- package/src/interfaces/messages-subscribe.ts +64 -0
- package/src/interfaces/protocols-configure.ts +340 -0
- package/src/interfaces/protocols-query.ts +96 -0
- package/src/interfaces/records-delete.ts +117 -0
- package/src/interfaces/records-query.ts +131 -0
- package/src/interfaces/records-read.ts +100 -0
- package/src/interfaces/records-subscribe.ts +104 -0
- package/src/interfaces/records-write.ts +1072 -0
- package/src/jose/algorithms/signing/ed25519.ts +58 -0
- package/src/jose/algorithms/signing/signature-algorithms.ts +22 -0
- package/src/jose/jws/general/builder.ts +48 -0
- package/src/jose/jws/general/verifier.ts +112 -0
- package/src/protocols/permission-grant.ts +86 -0
- package/src/protocols/permission-request.ts +63 -0
- package/src/protocols/permissions.ts +508 -0
- package/src/schema-validator.ts +46 -0
- package/src/store/blockstore-level.ts +113 -0
- package/src/store/blockstore-mock.ts +80 -0
- package/src/store/data-store-level.ts +120 -0
- package/src/store/index-level.ts +691 -0
- package/src/store/level-wrapper.ts +272 -0
- package/src/store/message-store-level.ts +195 -0
- package/src/store/resumable-task-store-level.ts +120 -0
- package/src/store/storage-controller.ts +240 -0
- package/src/types/cache.ts +16 -0
- package/src/types/data-store.ts +64 -0
- package/src/types/event-log.ts +52 -0
- package/src/types/jose-types.ts +76 -0
- package/src/types/jws-types.ts +28 -0
- package/src/types/message-interface.ts +30 -0
- package/src/types/message-store.ts +57 -0
- package/src/types/message-types.ts +132 -0
- package/src/types/messages-types.ts +77 -0
- package/src/types/method-handler.ts +19 -0
- package/src/types/permission-types.ts +110 -0
- package/src/types/protocols-types.ts +177 -0
- package/src/types/query-types.ts +61 -0
- package/src/types/records-types.ts +263 -0
- package/src/types/resumable-task-store.ts +96 -0
- package/src/types/signer.ts +27 -0
- package/src/types/subscriptions.ts +34 -0
- package/src/utils/abort.ts +31 -0
- package/src/utils/array.ts +39 -0
- package/src/utils/cid.ts +101 -0
- package/src/utils/data-stream.ts +99 -0
- package/src/utils/encoder.ts +54 -0
- package/src/utils/encryption.ts +145 -0
- package/src/utils/filter.ts +245 -0
- package/src/utils/hd-key.ts +126 -0
- package/src/utils/jws.ts +95 -0
- package/src/utils/memory-cache.ts +31 -0
- package/src/utils/messages.ts +109 -0
- package/src/utils/object.ts +43 -0
- package/src/utils/private-key-signer.ts +72 -0
- package/src/utils/protocols.ts +50 -0
- package/src/utils/records.ts +559 -0
- package/src/utils/secp256k1.ts +157 -0
- package/src/utils/secp256r1.ts +142 -0
- package/src/utils/string.ts +13 -0
- package/src/utils/time.ts +78 -0
- package/src/utils/url.ts +65 -0
|
@@ -0,0 +1,2516 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import chaiAsPromised from 'chai-as-promised';
|
|
11
|
+
import sinon from 'sinon';
|
|
12
|
+
import chai, { expect } from 'chai';
|
|
13
|
+
import { DidKey } from '@enbox/dids';
|
|
14
|
+
import { Dwn } from '../../src/dwn.js';
|
|
15
|
+
import { DwnErrorCode } from '../../src/core/dwn-error.js';
|
|
16
|
+
import { Jws } from '../../src/utils/jws.js';
|
|
17
|
+
import { Records } from '../../src/utils/records.js';
|
|
18
|
+
import { RecordsRead } from '../../src/interfaces/records-read.js';
|
|
19
|
+
import { RecordsWrite } from '../../src/interfaces/records-write.js';
|
|
20
|
+
import { TestDataGenerator } from '../utils/test-data-generator.js';
|
|
21
|
+
import { TestEventStream } from '../test-event-stream.js';
|
|
22
|
+
import { TestStores } from '../test-stores.js';
|
|
23
|
+
import { UniversalResolver } from '@enbox/dids';
|
|
24
|
+
import { DwnInterfaceName, DwnMethodName, Message, Time } from '../../src/index.js';
|
|
25
|
+
chai.use(chaiAsPromised);
|
|
26
|
+
export function testRecordsTags() {
|
|
27
|
+
describe('Records Tags', () => {
|
|
28
|
+
let didResolver;
|
|
29
|
+
let messageStore;
|
|
30
|
+
let dataStore;
|
|
31
|
+
let resumableTaskStore;
|
|
32
|
+
let eventLog;
|
|
33
|
+
let eventStream;
|
|
34
|
+
let dwn;
|
|
35
|
+
// important to follow the `before` and `after` pattern to initialize and clean the stores in tests
|
|
36
|
+
// so that different test suites can reuse the same backend store for testing
|
|
37
|
+
before(() => __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
didResolver = new UniversalResolver({ didResolvers: [DidKey] });
|
|
39
|
+
const stores = TestStores.get();
|
|
40
|
+
messageStore = stores.messageStore;
|
|
41
|
+
dataStore = stores.dataStore;
|
|
42
|
+
resumableTaskStore = stores.resumableTaskStore;
|
|
43
|
+
eventLog = stores.eventLog;
|
|
44
|
+
eventStream = TestEventStream.get();
|
|
45
|
+
dwn = yield Dwn.create({ didResolver, messageStore, dataStore, eventLog, eventStream, resumableTaskStore });
|
|
46
|
+
}));
|
|
47
|
+
beforeEach(() => __awaiter(this, void 0, void 0, function* () {
|
|
48
|
+
sinon.restore(); // wipe all previous stubs/spies/mocks/fakes
|
|
49
|
+
// clean up before each test rather than after so that a test does not depend on other tests to do the clean up
|
|
50
|
+
yield messageStore.clear();
|
|
51
|
+
yield dataStore.clear();
|
|
52
|
+
yield resumableTaskStore.clear();
|
|
53
|
+
yield eventLog.clear();
|
|
54
|
+
}));
|
|
55
|
+
after(() => __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
yield dwn.close();
|
|
57
|
+
}));
|
|
58
|
+
describe('RecordsWrite with tags', () => {
|
|
59
|
+
describe('protocol rules', () => {
|
|
60
|
+
describe('ProtocolsConfigure', () => {
|
|
61
|
+
it('should support protocol tag types of string, number, integer, boolean and array types of numbers, integers and strings', () => __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
63
|
+
// configure a protocol with tags of string, number, boolean and array types of numbers and strings
|
|
64
|
+
const protocolDefinition = {
|
|
65
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
66
|
+
published: true,
|
|
67
|
+
types: {
|
|
68
|
+
foo: {}
|
|
69
|
+
},
|
|
70
|
+
structure: {
|
|
71
|
+
foo: {
|
|
72
|
+
$tags: {
|
|
73
|
+
stringTag: {
|
|
74
|
+
type: 'string',
|
|
75
|
+
},
|
|
76
|
+
numberType: {
|
|
77
|
+
type: 'number',
|
|
78
|
+
},
|
|
79
|
+
integerType: {
|
|
80
|
+
type: 'integer',
|
|
81
|
+
},
|
|
82
|
+
booleanType: {
|
|
83
|
+
type: 'boolean',
|
|
84
|
+
},
|
|
85
|
+
stringArray: {
|
|
86
|
+
type: 'array',
|
|
87
|
+
items: {
|
|
88
|
+
type: 'string',
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
numberArray: {
|
|
92
|
+
type: 'array',
|
|
93
|
+
items: {
|
|
94
|
+
type: 'number',
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
integerArray: {
|
|
98
|
+
type: 'array',
|
|
99
|
+
items: {
|
|
100
|
+
type: 'integer',
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
108
|
+
author: alice,
|
|
109
|
+
protocolDefinition,
|
|
110
|
+
});
|
|
111
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
112
|
+
expect(configureReply.status.code).to.equal(202);
|
|
113
|
+
}));
|
|
114
|
+
it('should reject tags that have invalid schema definitions during create', () => __awaiter(this, void 0, void 0, function* () {
|
|
115
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
116
|
+
// protocol definition with an invalid schema
|
|
117
|
+
const invalidSchemaProtocol = {
|
|
118
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
119
|
+
published: true,
|
|
120
|
+
types: {
|
|
121
|
+
foo: {}
|
|
122
|
+
},
|
|
123
|
+
structure: {
|
|
124
|
+
foo: {
|
|
125
|
+
$tags: {
|
|
126
|
+
invalidTag: {
|
|
127
|
+
type: 'array',
|
|
128
|
+
items: {
|
|
129
|
+
type: 'number'
|
|
130
|
+
},
|
|
131
|
+
contains: {
|
|
132
|
+
type: 'number',
|
|
133
|
+
minimum: 'ten', // should be a number
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
const protocolConfigure = TestDataGenerator.generateProtocolsConfigure({
|
|
141
|
+
author: alice,
|
|
142
|
+
protocolDefinition: invalidSchemaProtocol,
|
|
143
|
+
});
|
|
144
|
+
yield expect(protocolConfigure).to.eventually.be.rejectedWith(DwnErrorCode.ProtocolsConfigureInvalidTagSchema);
|
|
145
|
+
}));
|
|
146
|
+
it('should reject tags that have invalid schema definitions during process', () => __awaiter(this, void 0, void 0, function* () {
|
|
147
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
148
|
+
// protocol definition with an invalid schema
|
|
149
|
+
const invalidSchemaProtocol = {
|
|
150
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
151
|
+
published: true,
|
|
152
|
+
types: {
|
|
153
|
+
foo: {}
|
|
154
|
+
},
|
|
155
|
+
structure: {
|
|
156
|
+
foo: {
|
|
157
|
+
$tags: {
|
|
158
|
+
invalidTag: {
|
|
159
|
+
type: 'array',
|
|
160
|
+
items: {
|
|
161
|
+
type: 'number'
|
|
162
|
+
},
|
|
163
|
+
contains: {
|
|
164
|
+
type: 'number',
|
|
165
|
+
minimum: 'ten', // should be a number
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
// manually craft the invalid ProtocolsConfigure message because our library will not let you create an invalid definition
|
|
173
|
+
const descriptor = {
|
|
174
|
+
interface: DwnInterfaceName.Protocols,
|
|
175
|
+
method: DwnMethodName.Configure,
|
|
176
|
+
messageTimestamp: Time.getCurrentTimestamp(),
|
|
177
|
+
definition: invalidSchemaProtocol
|
|
178
|
+
};
|
|
179
|
+
const authorization = yield Message.createAuthorization({
|
|
180
|
+
descriptor,
|
|
181
|
+
signer: Jws.createSigner(alice)
|
|
182
|
+
});
|
|
183
|
+
const protocolsConfigureMessage = { descriptor, authorization };
|
|
184
|
+
const protocolsConfigureReply = yield dwn.processMessage(alice.did, protocolsConfigureMessage);
|
|
185
|
+
expect(protocolsConfigureReply.status.code).to.equal(400);
|
|
186
|
+
expect(protocolsConfigureReply.status.detail).to.contain(DwnErrorCode.ProtocolsConfigureInvalidTagSchema);
|
|
187
|
+
expect(protocolsConfigureReply.status.detail).to.contain(`foo/$tags/invalidTag/contains/minimum must be number`);
|
|
188
|
+
}));
|
|
189
|
+
describe('should reject invalid tag types', () => {
|
|
190
|
+
it('object', () => __awaiter(this, void 0, void 0, function* () {
|
|
191
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
192
|
+
// protocol definition with unsupported tag type of object
|
|
193
|
+
const objectTagsType = {
|
|
194
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
195
|
+
published: true,
|
|
196
|
+
types: {
|
|
197
|
+
foo: {}
|
|
198
|
+
},
|
|
199
|
+
structure: {
|
|
200
|
+
foo: {
|
|
201
|
+
$tags: {
|
|
202
|
+
objectTag: {
|
|
203
|
+
type: 'object',
|
|
204
|
+
},
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
// manually craft the invalid ProtocolsConfigure message because our library will not let you create an invalid definition
|
|
210
|
+
const descriptor = {
|
|
211
|
+
interface: DwnInterfaceName.Protocols,
|
|
212
|
+
method: DwnMethodName.Configure,
|
|
213
|
+
messageTimestamp: Time.getCurrentTimestamp(),
|
|
214
|
+
definition: objectTagsType
|
|
215
|
+
};
|
|
216
|
+
const authorization = yield Message.createAuthorization({
|
|
217
|
+
descriptor,
|
|
218
|
+
signer: Jws.createSigner(alice)
|
|
219
|
+
});
|
|
220
|
+
const protocolsConfigureMessage = { descriptor, authorization };
|
|
221
|
+
const objectTagsTypeConfigureReply = yield dwn.processMessage(alice.did, protocolsConfigureMessage);
|
|
222
|
+
expect(objectTagsTypeConfigureReply.status.code).to.equal(400);
|
|
223
|
+
}));
|
|
224
|
+
it('array of objects', () => __awaiter(this, void 0, void 0, function* () {
|
|
225
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
226
|
+
// protocol definition with unsupported tag type array of objects
|
|
227
|
+
const objectArrayTagsType = {
|
|
228
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
229
|
+
published: true,
|
|
230
|
+
types: {
|
|
231
|
+
foo: {}
|
|
232
|
+
},
|
|
233
|
+
structure: {
|
|
234
|
+
foo: {
|
|
235
|
+
$tags: {
|
|
236
|
+
objectArrayTag: {
|
|
237
|
+
type: 'array',
|
|
238
|
+
items: {
|
|
239
|
+
type: 'object',
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
// manually craft the invalid ProtocolsConfigure message because our library will not let you create an invalid definition
|
|
247
|
+
const descriptor = {
|
|
248
|
+
interface: DwnInterfaceName.Protocols,
|
|
249
|
+
method: DwnMethodName.Configure,
|
|
250
|
+
messageTimestamp: Time.getCurrentTimestamp(),
|
|
251
|
+
definition: objectArrayTagsType
|
|
252
|
+
};
|
|
253
|
+
const authorization = yield Message.createAuthorization({
|
|
254
|
+
descriptor,
|
|
255
|
+
signer: Jws.createSigner(alice)
|
|
256
|
+
});
|
|
257
|
+
const protocolsConfigureMessage = { descriptor, authorization };
|
|
258
|
+
const objectArrayTagsTypeConfigureReply = yield dwn.processMessage(alice.did, protocolsConfigureMessage);
|
|
259
|
+
expect(objectArrayTagsTypeConfigureReply.status.code).to.equal(400);
|
|
260
|
+
}));
|
|
261
|
+
it('array of booleans', () => __awaiter(this, void 0, void 0, function* () {
|
|
262
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
263
|
+
// protocol definition with unsupported tag type array of booleans
|
|
264
|
+
const booleanArrayTagsType = {
|
|
265
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
266
|
+
published: true,
|
|
267
|
+
types: {
|
|
268
|
+
foo: {}
|
|
269
|
+
},
|
|
270
|
+
structure: {
|
|
271
|
+
foo: {
|
|
272
|
+
$tags: {
|
|
273
|
+
booleanArrayTag: {
|
|
274
|
+
type: 'array',
|
|
275
|
+
items: {
|
|
276
|
+
type: 'boolean',
|
|
277
|
+
}
|
|
278
|
+
},
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
};
|
|
283
|
+
const descriptor = {
|
|
284
|
+
interface: DwnInterfaceName.Protocols,
|
|
285
|
+
method: DwnMethodName.Configure,
|
|
286
|
+
messageTimestamp: Time.getCurrentTimestamp(),
|
|
287
|
+
definition: booleanArrayTagsType
|
|
288
|
+
};
|
|
289
|
+
const authorization = yield Message.createAuthorization({
|
|
290
|
+
descriptor,
|
|
291
|
+
signer: Jws.createSigner(alice)
|
|
292
|
+
});
|
|
293
|
+
const protocolsConfigureMessage = { descriptor, authorization };
|
|
294
|
+
const booleanArrayTagsTypeConfigureReply = yield dwn.processMessage(alice.did, protocolsConfigureMessage);
|
|
295
|
+
expect(booleanArrayTagsTypeConfigureReply.status.code).to.equal(400);
|
|
296
|
+
}));
|
|
297
|
+
});
|
|
298
|
+
});
|
|
299
|
+
it('should reject a record with a tag property that does not match the protocol definition tags', () => __awaiter(this, void 0, void 0, function* () {
|
|
300
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
301
|
+
// has a `knownTag` tag in the protocol definition
|
|
302
|
+
const protocolDefinition = {
|
|
303
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
304
|
+
published: true,
|
|
305
|
+
types: {
|
|
306
|
+
foo: {}
|
|
307
|
+
},
|
|
308
|
+
structure: {
|
|
309
|
+
foo: {
|
|
310
|
+
$tags: {
|
|
311
|
+
knownTag: {
|
|
312
|
+
type: 'string',
|
|
313
|
+
},
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
};
|
|
318
|
+
// configure tags protocol
|
|
319
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
320
|
+
author: alice,
|
|
321
|
+
protocolDefinition,
|
|
322
|
+
});
|
|
323
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
324
|
+
expect(configureReply.status.code).to.equal(202);
|
|
325
|
+
// write a foo record with an `unknownTag` tag.
|
|
326
|
+
const fooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
327
|
+
author: alice,
|
|
328
|
+
published: true,
|
|
329
|
+
protocol: protocolDefinition.protocol,
|
|
330
|
+
protocolPath: 'foo',
|
|
331
|
+
tags: {
|
|
332
|
+
unknownTag: 'some-value'
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
const fooRecordReply = yield dwn.processMessage(alice.did, fooRecord.message, { dataStream: fooRecord.dataStream });
|
|
336
|
+
expect(fooRecordReply.status.code).to.equal(400);
|
|
337
|
+
expect(fooRecordReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
338
|
+
// ensure the correct tag descriptor is in the error message
|
|
339
|
+
expect(fooRecordReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags must NOT have additional properties`);
|
|
340
|
+
// write a foo record with a `knownTag` tag.
|
|
341
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
342
|
+
author: alice,
|
|
343
|
+
published: true,
|
|
344
|
+
protocol: protocolDefinition.protocol,
|
|
345
|
+
protocolPath: 'foo',
|
|
346
|
+
tags: {
|
|
347
|
+
knownTag: 'some-value'
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
// should pass
|
|
351
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
352
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
353
|
+
}));
|
|
354
|
+
it('should reject a tag value that does not match the boolean type', () => __awaiter(this, void 0, void 0, function* () {
|
|
355
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
356
|
+
// protocol with a boolean type for a tag
|
|
357
|
+
const protocolDefinition = {
|
|
358
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
359
|
+
published: true,
|
|
360
|
+
types: {
|
|
361
|
+
foo: {}
|
|
362
|
+
},
|
|
363
|
+
structure: {
|
|
364
|
+
foo: {
|
|
365
|
+
$tags: {
|
|
366
|
+
draft: {
|
|
367
|
+
type: 'boolean'
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
},
|
|
372
|
+
};
|
|
373
|
+
// configure tags protocol
|
|
374
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
375
|
+
author: alice,
|
|
376
|
+
protocolDefinition
|
|
377
|
+
});
|
|
378
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
379
|
+
expect(configureReply.status.code).to.equal(202);
|
|
380
|
+
// `draft` should be a boolean type, but we are passing a string
|
|
381
|
+
const fooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
382
|
+
author: alice,
|
|
383
|
+
published: true,
|
|
384
|
+
protocol: protocolDefinition.protocol,
|
|
385
|
+
protocolPath: 'foo',
|
|
386
|
+
tags: {
|
|
387
|
+
draft: 'true'
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
const fooRecordReply = yield dwn.processMessage(alice.did, fooRecord.message, { dataStream: fooRecord.dataStream });
|
|
391
|
+
expect(fooRecordReply.status.code).to.equal(400);
|
|
392
|
+
expect(fooRecordReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
393
|
+
expect(fooRecordReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags/draft must be boolean`);
|
|
394
|
+
// positive test with a boolean
|
|
395
|
+
const fooRecord2 = yield TestDataGenerator.generateRecordsWrite({
|
|
396
|
+
author: alice,
|
|
397
|
+
published: true,
|
|
398
|
+
protocol: protocolDefinition.protocol,
|
|
399
|
+
protocolPath: 'foo',
|
|
400
|
+
tags: {
|
|
401
|
+
draft: true
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
const fooRecord2Reply = yield dwn.processMessage(alice.did, fooRecord2.message, { dataStream: fooRecord2.dataStream });
|
|
405
|
+
expect(fooRecord2Reply.status.code).to.equal(202);
|
|
406
|
+
}));
|
|
407
|
+
it('should reject a tag value that does not match the number type', () => __awaiter(this, void 0, void 0, function* () {
|
|
408
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
409
|
+
// protocol with a number type for a tag
|
|
410
|
+
const protocolDefinition = {
|
|
411
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
412
|
+
published: true,
|
|
413
|
+
types: {
|
|
414
|
+
foo: {}
|
|
415
|
+
},
|
|
416
|
+
structure: {
|
|
417
|
+
foo: {
|
|
418
|
+
$tags: {
|
|
419
|
+
numberType: {
|
|
420
|
+
type: 'number'
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
};
|
|
426
|
+
// configure tags protocol
|
|
427
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
428
|
+
author: alice,
|
|
429
|
+
protocolDefinition
|
|
430
|
+
});
|
|
431
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
432
|
+
expect(configureReply.status.code).to.equal(202);
|
|
433
|
+
// `numberType` should be a number type, but we are passing a string
|
|
434
|
+
const fooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
435
|
+
author: alice,
|
|
436
|
+
published: true,
|
|
437
|
+
protocol: protocolDefinition.protocol,
|
|
438
|
+
protocolPath: 'foo',
|
|
439
|
+
tags: {
|
|
440
|
+
numberType: '1'
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
const fooRecordReply = yield dwn.processMessage(alice.did, fooRecord.message, { dataStream: fooRecord.dataStream });
|
|
444
|
+
expect(fooRecordReply.status.code).to.equal(400);
|
|
445
|
+
expect(fooRecordReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
446
|
+
expect(fooRecordReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags/numberType must be number`);
|
|
447
|
+
// positive tests with an integer number
|
|
448
|
+
const fooRecord2 = yield TestDataGenerator.generateRecordsWrite({
|
|
449
|
+
author: alice,
|
|
450
|
+
published: true,
|
|
451
|
+
protocol: protocolDefinition.protocol,
|
|
452
|
+
protocolPath: 'foo',
|
|
453
|
+
tags: {
|
|
454
|
+
numberType: 1
|
|
455
|
+
}
|
|
456
|
+
});
|
|
457
|
+
const fooRecord2Reply = yield dwn.processMessage(alice.did, fooRecord2.message, { dataStream: fooRecord2.dataStream });
|
|
458
|
+
expect(fooRecord2Reply.status.code).to.equal(202);
|
|
459
|
+
// positive tests with a decimal number
|
|
460
|
+
const fooRecord3 = yield TestDataGenerator.generateRecordsWrite({
|
|
461
|
+
author: alice,
|
|
462
|
+
published: true,
|
|
463
|
+
protocol: protocolDefinition.protocol,
|
|
464
|
+
protocolPath: 'foo',
|
|
465
|
+
tags: {
|
|
466
|
+
numberType: 1.5
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
const fooRecord3Reply = yield dwn.processMessage(alice.did, fooRecord3.message, { dataStream: fooRecord3.dataStream });
|
|
470
|
+
expect(fooRecord3Reply.status.code).to.equal(202);
|
|
471
|
+
}));
|
|
472
|
+
it('should reject a tag value that does not match the integer type', () => __awaiter(this, void 0, void 0, function* () {
|
|
473
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
474
|
+
// protocol with an integer type for a tag
|
|
475
|
+
const protocolDefinition = {
|
|
476
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
477
|
+
published: true,
|
|
478
|
+
types: {
|
|
479
|
+
foo: {}
|
|
480
|
+
},
|
|
481
|
+
structure: {
|
|
482
|
+
foo: {
|
|
483
|
+
$tags: {
|
|
484
|
+
count: {
|
|
485
|
+
type: 'integer',
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
},
|
|
490
|
+
};
|
|
491
|
+
// configure tags protocol
|
|
492
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
493
|
+
author: alice,
|
|
494
|
+
protocolDefinition
|
|
495
|
+
});
|
|
496
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
497
|
+
expect(configureReply.status.code).to.equal(202);
|
|
498
|
+
// `count` should be an integer type, but we are passing decimal number
|
|
499
|
+
const fooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
500
|
+
author: alice,
|
|
501
|
+
published: true,
|
|
502
|
+
protocol: protocolDefinition.protocol,
|
|
503
|
+
protocolPath: 'foo',
|
|
504
|
+
tags: {
|
|
505
|
+
count: 1.5
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
const fooRecordReply = yield dwn.processMessage(alice.did, fooRecord.message, { dataStream: fooRecord.dataStream });
|
|
509
|
+
expect(fooRecordReply.status.code).to.equal(400);
|
|
510
|
+
expect(fooRecordReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
511
|
+
expect(fooRecordReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags/count must be integer`);
|
|
512
|
+
// positive test with an integer
|
|
513
|
+
const fooRecord2 = yield TestDataGenerator.generateRecordsWrite({
|
|
514
|
+
author: alice,
|
|
515
|
+
published: true,
|
|
516
|
+
protocol: protocolDefinition.protocol,
|
|
517
|
+
protocolPath: 'foo',
|
|
518
|
+
tags: {
|
|
519
|
+
count: 1
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
const fooRecord2Reply = yield dwn.processMessage(alice.did, fooRecord2.message, { dataStream: fooRecord2.dataStream });
|
|
523
|
+
expect(fooRecord2Reply.status.code).to.equal(202);
|
|
524
|
+
}));
|
|
525
|
+
it('should reject a record with a tag value that does not match a given enum in the protocol definition', () => __awaiter(this, void 0, void 0, function* () {
|
|
526
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
527
|
+
// protocol with an enum for a tag
|
|
528
|
+
const protocolDefinition = {
|
|
529
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
530
|
+
published: true,
|
|
531
|
+
types: {
|
|
532
|
+
foo: {}
|
|
533
|
+
},
|
|
534
|
+
structure: {
|
|
535
|
+
foo: {
|
|
536
|
+
$tags: {
|
|
537
|
+
status: {
|
|
538
|
+
type: 'string',
|
|
539
|
+
enum: ['draft', 'published', 'archived']
|
|
540
|
+
},
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
},
|
|
544
|
+
};
|
|
545
|
+
// configure tags protocol
|
|
546
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
547
|
+
author: alice,
|
|
548
|
+
protocolDefinition,
|
|
549
|
+
});
|
|
550
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
551
|
+
expect(configureReply.status.code).to.equal(202);
|
|
552
|
+
// write a foo record with an `unknown_status` tag value.
|
|
553
|
+
const fooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
554
|
+
author: alice,
|
|
555
|
+
published: true,
|
|
556
|
+
protocol: protocolDefinition.protocol,
|
|
557
|
+
protocolPath: 'foo',
|
|
558
|
+
tags: {
|
|
559
|
+
status: 'unknown_status'
|
|
560
|
+
}
|
|
561
|
+
});
|
|
562
|
+
const fooRecordReply = yield dwn.processMessage(alice.did, fooRecord.message, { dataStream: fooRecord.dataStream });
|
|
563
|
+
expect(fooRecordReply.status.code).to.equal(400);
|
|
564
|
+
expect(fooRecordReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
565
|
+
expect(fooRecordReply.status.detail).to
|
|
566
|
+
.contain(`${protocolDefinition.protocol}/foo/$tags/status must be equal to one of the allowed values`);
|
|
567
|
+
// ensure the correct tag descriptor path is in the error message
|
|
568
|
+
expect(fooRecordReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags/status`);
|
|
569
|
+
// write a foo record with a valid `status` tag value.
|
|
570
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
571
|
+
author: alice,
|
|
572
|
+
published: true,
|
|
573
|
+
protocol: protocolDefinition.protocol,
|
|
574
|
+
protocolPath: 'foo',
|
|
575
|
+
tags: {
|
|
576
|
+
status: 'draft'
|
|
577
|
+
}
|
|
578
|
+
});
|
|
579
|
+
// should pass
|
|
580
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
581
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
582
|
+
}));
|
|
583
|
+
it('should reject a record with a tag value that is not within the `minimum` and `maximum` range', () => __awaiter(this, void 0, void 0, function* () {
|
|
584
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
585
|
+
// protocol with minimum and maximum for a number
|
|
586
|
+
const protocolDefinition = {
|
|
587
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
588
|
+
published: true,
|
|
589
|
+
types: {
|
|
590
|
+
foo: {}
|
|
591
|
+
},
|
|
592
|
+
structure: {
|
|
593
|
+
foo: {
|
|
594
|
+
$tags: {
|
|
595
|
+
score: {
|
|
596
|
+
type: 'number',
|
|
597
|
+
minimum: 0,
|
|
598
|
+
maximum: 100
|
|
599
|
+
},
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
},
|
|
603
|
+
};
|
|
604
|
+
// configure tags protocol
|
|
605
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
606
|
+
author: alice,
|
|
607
|
+
protocolDefinition,
|
|
608
|
+
});
|
|
609
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
610
|
+
expect(configureReply.status.code).to.equal(202);
|
|
611
|
+
// write a foo record with an `score` value less than 0.
|
|
612
|
+
const fooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
613
|
+
author: alice,
|
|
614
|
+
published: true,
|
|
615
|
+
protocol: protocolDefinition.protocol,
|
|
616
|
+
protocolPath: 'foo',
|
|
617
|
+
tags: {
|
|
618
|
+
score: -1,
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
// should fail
|
|
622
|
+
const fooRecordReply = yield dwn.processMessage(alice.did, fooRecord.message, { dataStream: fooRecord.dataStream });
|
|
623
|
+
expect(fooRecordReply.status.code).to.equal(400);
|
|
624
|
+
expect(fooRecordReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
625
|
+
expect(fooRecordReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags/score must be >= 0`);
|
|
626
|
+
// write a foo record with an `score` value greater than 100.
|
|
627
|
+
const fooRecord2 = yield TestDataGenerator.generateRecordsWrite({
|
|
628
|
+
author: alice,
|
|
629
|
+
published: true,
|
|
630
|
+
protocol: protocolDefinition.protocol,
|
|
631
|
+
protocolPath: 'foo',
|
|
632
|
+
tags: {
|
|
633
|
+
score: 101,
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
// should fail
|
|
637
|
+
const fooRecord2Reply = yield dwn.processMessage(alice.did, fooRecord2.message, { dataStream: fooRecord2.dataStream });
|
|
638
|
+
expect(fooRecord2Reply.status.code).to.equal(400);
|
|
639
|
+
expect(fooRecord2Reply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
640
|
+
expect(fooRecord2Reply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags/score must be <= 100`);
|
|
641
|
+
// write a foo record with a maximum `score` of 100.
|
|
642
|
+
const validFooMaxRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
643
|
+
author: alice,
|
|
644
|
+
published: true,
|
|
645
|
+
protocol: protocolDefinition.protocol,
|
|
646
|
+
protocolPath: 'foo',
|
|
647
|
+
tags: {
|
|
648
|
+
score: 100,
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
// should pass
|
|
652
|
+
const validFooMaxRecordReply = yield dwn.processMessage(alice.did, validFooMaxRecord.message, { dataStream: validFooMaxRecord.dataStream });
|
|
653
|
+
expect(validFooMaxRecordReply.status.code).to.equal(202);
|
|
654
|
+
// write a foo record with a maximum `score` of 0.
|
|
655
|
+
const validFooMinRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
656
|
+
author: alice,
|
|
657
|
+
published: true,
|
|
658
|
+
protocol: protocolDefinition.protocol,
|
|
659
|
+
protocolPath: 'foo',
|
|
660
|
+
tags: {
|
|
661
|
+
score: 0,
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
// should pass
|
|
665
|
+
const validFooMinRecordReply = yield dwn.processMessage(alice.did, validFooMinRecord.message, { dataStream: validFooMinRecord.dataStream });
|
|
666
|
+
expect(validFooMinRecordReply.status.code).to.equal(202);
|
|
667
|
+
// write a foo record within the range
|
|
668
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
669
|
+
author: alice,
|
|
670
|
+
published: true,
|
|
671
|
+
protocol: protocolDefinition.protocol,
|
|
672
|
+
protocolPath: 'foo',
|
|
673
|
+
tags: {
|
|
674
|
+
score: 50,
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
// should pass
|
|
678
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
679
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
680
|
+
}));
|
|
681
|
+
it('should reject a record with a tag value that is not within the `exclusiveMinimum` and `exclusiveMaximum` range', () => __awaiter(this, void 0, void 0, function* () {
|
|
682
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
683
|
+
// protocol with exclusiveMinimum and exclusiveMaximum for a number
|
|
684
|
+
const protocolDefinition = {
|
|
685
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
686
|
+
published: true,
|
|
687
|
+
types: {
|
|
688
|
+
foo: {}
|
|
689
|
+
},
|
|
690
|
+
structure: {
|
|
691
|
+
foo: {
|
|
692
|
+
$tags: {
|
|
693
|
+
hours: {
|
|
694
|
+
type: 'number',
|
|
695
|
+
exclusiveMinimum: 0,
|
|
696
|
+
exclusiveMaximum: 24
|
|
697
|
+
},
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
},
|
|
701
|
+
};
|
|
702
|
+
// configure tags protocol
|
|
703
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
704
|
+
author: alice,
|
|
705
|
+
protocolDefinition,
|
|
706
|
+
});
|
|
707
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
708
|
+
expect(configureReply.status.code).to.equal(202);
|
|
709
|
+
// write a foo record with an hour at the exclusiveMaximum
|
|
710
|
+
const exclusiveMaxRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
711
|
+
author: alice,
|
|
712
|
+
published: true,
|
|
713
|
+
protocol: protocolDefinition.protocol,
|
|
714
|
+
protocolPath: 'foo',
|
|
715
|
+
tags: {
|
|
716
|
+
hours: 24,
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
// should fail
|
|
720
|
+
const exclusiveMaxReply = yield dwn.processMessage(alice.did, exclusiveMaxRecord.message, { dataStream: exclusiveMaxRecord.dataStream });
|
|
721
|
+
expect(exclusiveMaxReply.status.code).to.equal(400);
|
|
722
|
+
expect(exclusiveMaxReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
723
|
+
expect(exclusiveMaxReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags/hours must be < 24`);
|
|
724
|
+
// write a foo record with an hour at the exclusiveMinimum
|
|
725
|
+
const exclusiveMinRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
726
|
+
author: alice,
|
|
727
|
+
published: true,
|
|
728
|
+
protocol: protocolDefinition.protocol,
|
|
729
|
+
protocolPath: 'foo',
|
|
730
|
+
tags: {
|
|
731
|
+
hours: 0,
|
|
732
|
+
}
|
|
733
|
+
});
|
|
734
|
+
// should fail
|
|
735
|
+
const exclusiveMinReply = yield dwn.processMessage(alice.did, exclusiveMinRecord.message, { dataStream: exclusiveMinRecord.dataStream });
|
|
736
|
+
expect(exclusiveMinReply.status.code).to.equal(400);
|
|
737
|
+
expect(exclusiveMinReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
738
|
+
expect(exclusiveMinReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags/hours must be > 0`);
|
|
739
|
+
// write a foo record with an `hour` value within the range.
|
|
740
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
741
|
+
author: alice,
|
|
742
|
+
published: true,
|
|
743
|
+
protocol: protocolDefinition.protocol,
|
|
744
|
+
protocolPath: 'foo',
|
|
745
|
+
tags: {
|
|
746
|
+
hours: 12,
|
|
747
|
+
}
|
|
748
|
+
});
|
|
749
|
+
// should pass
|
|
750
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
751
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
752
|
+
}));
|
|
753
|
+
it('should reject tag values that are not within the `minLength` and `maxLength` values', () => __awaiter(this, void 0, void 0, function* () {
|
|
754
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
755
|
+
// protocol with minLength and maxLength for a string
|
|
756
|
+
const protocolDefinition = {
|
|
757
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
758
|
+
published: true,
|
|
759
|
+
types: {
|
|
760
|
+
foo: {}
|
|
761
|
+
},
|
|
762
|
+
structure: {
|
|
763
|
+
foo: {
|
|
764
|
+
$tags: {
|
|
765
|
+
stringWithLimit: {
|
|
766
|
+
type: 'string',
|
|
767
|
+
maxLength: 10,
|
|
768
|
+
minLength: 5
|
|
769
|
+
},
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
},
|
|
773
|
+
};
|
|
774
|
+
// configure tags protocol
|
|
775
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
776
|
+
author: alice,
|
|
777
|
+
protocolDefinition,
|
|
778
|
+
});
|
|
779
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
780
|
+
expect(configureReply.status.code).to.equal(202);
|
|
781
|
+
// write a foo record with a `stringWithLimit` value less than the minimum length
|
|
782
|
+
const minLengthRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
783
|
+
author: alice,
|
|
784
|
+
published: true,
|
|
785
|
+
protocol: protocolDefinition.protocol,
|
|
786
|
+
protocolPath: 'foo',
|
|
787
|
+
tags: {
|
|
788
|
+
stringWithLimit: 'a', // less than 5
|
|
789
|
+
}
|
|
790
|
+
});
|
|
791
|
+
// should fail
|
|
792
|
+
const minLengthReply = yield dwn.processMessage(alice.did, minLengthRecord.message, { dataStream: minLengthRecord.dataStream });
|
|
793
|
+
expect(minLengthReply.status.code).to.equal(400);
|
|
794
|
+
expect(minLengthReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
795
|
+
expect(minLengthReply.status.detail).to
|
|
796
|
+
.contain(`${protocolDefinition.protocol}/foo/$tags/stringWithLimit must NOT have fewer than 5 characters`);
|
|
797
|
+
// write a foo record with a `stringWithLimit` value greater than the maximum length
|
|
798
|
+
const maxLengthRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
799
|
+
author: alice,
|
|
800
|
+
published: true,
|
|
801
|
+
protocol: protocolDefinition.protocol,
|
|
802
|
+
protocolPath: 'foo',
|
|
803
|
+
tags: {
|
|
804
|
+
stringWithLimit: 'abcdefghijklmnopqrstuvwxyz', //more than 10
|
|
805
|
+
}
|
|
806
|
+
});
|
|
807
|
+
// should fail
|
|
808
|
+
const maxLengthReply = yield dwn.processMessage(alice.did, maxLengthRecord.message, { dataStream: maxLengthRecord.dataStream });
|
|
809
|
+
expect(maxLengthReply.status.code).to.equal(400);
|
|
810
|
+
expect(maxLengthReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
811
|
+
expect(maxLengthReply.status.detail).to
|
|
812
|
+
.contain(`${protocolDefinition.protocol}/foo/$tags/stringWithLimit must NOT have more than 10 characters`);
|
|
813
|
+
// write a foo record with a `stringWithLimit` value within the range
|
|
814
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
815
|
+
author: alice,
|
|
816
|
+
published: true,
|
|
817
|
+
protocol: protocolDefinition.protocol,
|
|
818
|
+
protocolPath: 'foo',
|
|
819
|
+
tags: {
|
|
820
|
+
stringWithLimit: 'abcdef', // more than 5 less than 10
|
|
821
|
+
}
|
|
822
|
+
});
|
|
823
|
+
// should pass
|
|
824
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
825
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
826
|
+
}));
|
|
827
|
+
it('should reject tag values that do not contain the number of items within the `minItems` and `maxItems` values', () => __awaiter(this, void 0, void 0, function* () {
|
|
828
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
829
|
+
// protocol with minItems and maxItems for an array of numbers
|
|
830
|
+
const protocolDefinition = {
|
|
831
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
832
|
+
published: true,
|
|
833
|
+
types: {
|
|
834
|
+
foo: {}
|
|
835
|
+
},
|
|
836
|
+
structure: {
|
|
837
|
+
foo: {
|
|
838
|
+
$tags: {
|
|
839
|
+
numberArray: {
|
|
840
|
+
type: 'array',
|
|
841
|
+
minItems: 2,
|
|
842
|
+
maxItems: 3,
|
|
843
|
+
items: {
|
|
844
|
+
type: 'number',
|
|
845
|
+
}
|
|
846
|
+
},
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
},
|
|
850
|
+
};
|
|
851
|
+
// configure tags protocol
|
|
852
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
853
|
+
author: alice,
|
|
854
|
+
protocolDefinition,
|
|
855
|
+
});
|
|
856
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
857
|
+
expect(configureReply.status.code).to.equal(202);
|
|
858
|
+
// write a foo record with a `numberArray` value with only 1 item, less than the `minItems` specified of 2
|
|
859
|
+
const minLengthRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
860
|
+
author: alice,
|
|
861
|
+
published: true,
|
|
862
|
+
protocol: protocolDefinition.protocol,
|
|
863
|
+
protocolPath: 'foo',
|
|
864
|
+
tags: {
|
|
865
|
+
numberArray: [1] // less than 2
|
|
866
|
+
}
|
|
867
|
+
});
|
|
868
|
+
// should fail
|
|
869
|
+
const minLengthReply = yield dwn.processMessage(alice.did, minLengthRecord.message, { dataStream: minLengthRecord.dataStream });
|
|
870
|
+
expect(minLengthReply.status.code).to.equal(400);
|
|
871
|
+
expect(minLengthReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
872
|
+
expect(minLengthReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags/numberArray must NOT have fewer than 2 items`);
|
|
873
|
+
// write a foo record with a `numberArray` value with 4 items, more than the `maxItems` specified of 3
|
|
874
|
+
const maxLengthRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
875
|
+
author: alice,
|
|
876
|
+
published: true,
|
|
877
|
+
protocol: protocolDefinition.protocol,
|
|
878
|
+
protocolPath: 'foo',
|
|
879
|
+
tags: {
|
|
880
|
+
numberArray: [2, 4, 6, 8] // more than 3
|
|
881
|
+
}
|
|
882
|
+
});
|
|
883
|
+
// should fail
|
|
884
|
+
const maxLengthReply = yield dwn.processMessage(alice.did, maxLengthRecord.message, { dataStream: maxLengthRecord.dataStream });
|
|
885
|
+
expect(maxLengthReply.status.code).to.equal(400);
|
|
886
|
+
expect(maxLengthReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
887
|
+
expect(maxLengthReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags/numberArray must NOT have more than 3 items`);
|
|
888
|
+
// write a foo record with a `numberArray` value with 3 items, within the range
|
|
889
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
890
|
+
author: alice,
|
|
891
|
+
published: true,
|
|
892
|
+
protocol: protocolDefinition.protocol,
|
|
893
|
+
protocolPath: 'foo',
|
|
894
|
+
tags: {
|
|
895
|
+
numberArray: [2, 3, 4] // within the range
|
|
896
|
+
}
|
|
897
|
+
});
|
|
898
|
+
// should pass
|
|
899
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
900
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
901
|
+
}));
|
|
902
|
+
it('should reject a value within an array that should only include numbers', () => __awaiter(this, void 0, void 0, function* () {
|
|
903
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
904
|
+
// protocol with an array of numbers
|
|
905
|
+
const protocolDefinition = {
|
|
906
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
907
|
+
published: true,
|
|
908
|
+
types: {
|
|
909
|
+
foo: {}
|
|
910
|
+
},
|
|
911
|
+
structure: {
|
|
912
|
+
foo: {
|
|
913
|
+
$tags: {
|
|
914
|
+
numberArray: {
|
|
915
|
+
type: 'array',
|
|
916
|
+
items: {
|
|
917
|
+
type: 'number',
|
|
918
|
+
}
|
|
919
|
+
},
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
},
|
|
923
|
+
};
|
|
924
|
+
// configure tags protocol
|
|
925
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
926
|
+
author: alice,
|
|
927
|
+
protocolDefinition
|
|
928
|
+
});
|
|
929
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
930
|
+
expect(configureReply.status.code).to.equal(202);
|
|
931
|
+
// write a foo record with a `numberArray` value with a string
|
|
932
|
+
const fooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
933
|
+
author: alice,
|
|
934
|
+
published: true,
|
|
935
|
+
protocol: protocolDefinition.protocol,
|
|
936
|
+
protocolPath: 'foo',
|
|
937
|
+
tags: {
|
|
938
|
+
numberArray: ['a']
|
|
939
|
+
}
|
|
940
|
+
});
|
|
941
|
+
// should fail
|
|
942
|
+
const fooRecordReply = yield dwn.processMessage(alice.did, fooRecord.message, { dataStream: fooRecord.dataStream });
|
|
943
|
+
expect(fooRecordReply.status.code).to.equal(400);
|
|
944
|
+
expect(fooRecordReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
945
|
+
expect(fooRecordReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags/numberArray/0 must be number`);
|
|
946
|
+
// write a foo record with a `numberArray` value with a number (both integer and decimal)
|
|
947
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
948
|
+
author: alice,
|
|
949
|
+
published: true,
|
|
950
|
+
protocol: protocolDefinition.protocol,
|
|
951
|
+
protocolPath: 'foo',
|
|
952
|
+
tags: {
|
|
953
|
+
numberArray: [1, 1.5]
|
|
954
|
+
}
|
|
955
|
+
});
|
|
956
|
+
// should pass
|
|
957
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
958
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
959
|
+
}));
|
|
960
|
+
it('should reject a value within an array that should only include integers', () => __awaiter(this, void 0, void 0, function* () {
|
|
961
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
962
|
+
// protocol with an array of numbers
|
|
963
|
+
const protocolDefinition = {
|
|
964
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
965
|
+
published: true,
|
|
966
|
+
types: {
|
|
967
|
+
foo: {}
|
|
968
|
+
},
|
|
969
|
+
structure: {
|
|
970
|
+
foo: {
|
|
971
|
+
$tags: {
|
|
972
|
+
numberArray: {
|
|
973
|
+
type: 'array',
|
|
974
|
+
items: {
|
|
975
|
+
type: 'integer',
|
|
976
|
+
}
|
|
977
|
+
},
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
},
|
|
981
|
+
};
|
|
982
|
+
// configure tags protocol
|
|
983
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
984
|
+
author: alice,
|
|
985
|
+
protocolDefinition
|
|
986
|
+
});
|
|
987
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
988
|
+
expect(configureReply.status.code).to.equal(202);
|
|
989
|
+
// write a foo record with a `numberArray` value with a decimal
|
|
990
|
+
const fooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
991
|
+
author: alice,
|
|
992
|
+
published: true,
|
|
993
|
+
protocol: protocolDefinition.protocol,
|
|
994
|
+
protocolPath: 'foo',
|
|
995
|
+
tags: {
|
|
996
|
+
numberArray: [1, 1.5]
|
|
997
|
+
}
|
|
998
|
+
});
|
|
999
|
+
// should fail
|
|
1000
|
+
const fooRecordReply = yield dwn.processMessage(alice.did, fooRecord.message, { dataStream: fooRecord.dataStream });
|
|
1001
|
+
expect(fooRecordReply.status.code).to.equal(400);
|
|
1002
|
+
expect(fooRecordReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1003
|
+
expect(fooRecordReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags/numberArray/1 must be integer`);
|
|
1004
|
+
// write a foo record with a `numberArray` value with values of integers
|
|
1005
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1006
|
+
author: alice,
|
|
1007
|
+
published: true,
|
|
1008
|
+
protocol: protocolDefinition.protocol,
|
|
1009
|
+
protocolPath: 'foo',
|
|
1010
|
+
tags: {
|
|
1011
|
+
numberArray: [1, 2]
|
|
1012
|
+
}
|
|
1013
|
+
});
|
|
1014
|
+
// should pass
|
|
1015
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
1016
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
1017
|
+
}));
|
|
1018
|
+
it('should reject tag values that do not contain the number of items within the `minContains` and `maxContains` values', () => __awaiter(this, void 0, void 0, function* () {
|
|
1019
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1020
|
+
// protocol with minContains and maxContains for an array of numbers
|
|
1021
|
+
const protocolDefinition = {
|
|
1022
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
1023
|
+
published: true,
|
|
1024
|
+
types: {
|
|
1025
|
+
foo: {}
|
|
1026
|
+
},
|
|
1027
|
+
structure: {
|
|
1028
|
+
foo: {
|
|
1029
|
+
$tags: {
|
|
1030
|
+
numberArray: {
|
|
1031
|
+
type: 'array',
|
|
1032
|
+
items: {
|
|
1033
|
+
type: 'number',
|
|
1034
|
+
},
|
|
1035
|
+
contains: {
|
|
1036
|
+
type: 'number',
|
|
1037
|
+
minimum: 80,
|
|
1038
|
+
maximum: 100
|
|
1039
|
+
},
|
|
1040
|
+
minContains: 2,
|
|
1041
|
+
maxContains: 4
|
|
1042
|
+
},
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
},
|
|
1046
|
+
};
|
|
1047
|
+
// configure tags protocol
|
|
1048
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1049
|
+
author: alice,
|
|
1050
|
+
protocolDefinition,
|
|
1051
|
+
});
|
|
1052
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
1053
|
+
expect(configureReply.status.code).to.equal(202);
|
|
1054
|
+
// write a foo record with a `numberArray` value with only 1 item that matches contains contraint, less than the `minContains` of 2
|
|
1055
|
+
// but additional items that would equal more than 2 items
|
|
1056
|
+
const minLengthRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1057
|
+
author: alice,
|
|
1058
|
+
published: true,
|
|
1059
|
+
protocol: protocolDefinition.protocol,
|
|
1060
|
+
protocolPath: 'foo',
|
|
1061
|
+
tags: {
|
|
1062
|
+
numberArray: [1, 2, 81] // only 1 item that matches contains constraint
|
|
1063
|
+
}
|
|
1064
|
+
});
|
|
1065
|
+
// should fail
|
|
1066
|
+
const minLengthReply = yield dwn.processMessage(alice.did, minLengthRecord.message, { dataStream: minLengthRecord.dataStream });
|
|
1067
|
+
expect(minLengthReply.status.code).to.equal(400);
|
|
1068
|
+
expect(minLengthReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1069
|
+
expect(minLengthReply.status.detail)
|
|
1070
|
+
.to.contain(`${protocolDefinition.protocol}/foo/$tags/numberArray must contain at least 2 and no more than 4 valid item(s)`);
|
|
1071
|
+
// write a foo record with a `numberArray` value with 4 items, more than the `maxItems` specified of 3
|
|
1072
|
+
const maxLengthRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1073
|
+
author: alice,
|
|
1074
|
+
published: true,
|
|
1075
|
+
protocol: protocolDefinition.protocol,
|
|
1076
|
+
protocolPath: 'foo',
|
|
1077
|
+
tags: {
|
|
1078
|
+
numberArray: [81, 82, 83, 84, 85] // more than 4 match the contains constraint
|
|
1079
|
+
}
|
|
1080
|
+
});
|
|
1081
|
+
// should fail
|
|
1082
|
+
const maxLengthReply = yield dwn.processMessage(alice.did, maxLengthRecord.message, { dataStream: maxLengthRecord.dataStream });
|
|
1083
|
+
expect(maxLengthReply.status.code).to.equal(400);
|
|
1084
|
+
expect(maxLengthReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1085
|
+
expect(maxLengthReply.status.detail)
|
|
1086
|
+
.to.contain(`${protocolDefinition.protocol}/foo/$tags/numberArray must contain at least 2 and no more than 4 valid item(s)`);
|
|
1087
|
+
// write a foo record with a `numberArray` value with 3 items, within the range
|
|
1088
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1089
|
+
author: alice,
|
|
1090
|
+
published: true,
|
|
1091
|
+
protocol: protocolDefinition.protocol,
|
|
1092
|
+
protocolPath: 'foo',
|
|
1093
|
+
tags: {
|
|
1094
|
+
numberArray: [1, 2, 81, 82, 83] // 3 items match contains constraint, within the range
|
|
1095
|
+
}
|
|
1096
|
+
});
|
|
1097
|
+
// should pass
|
|
1098
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
1099
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
1100
|
+
}));
|
|
1101
|
+
it('should reject tag values that do not follow the constraints of the `uniqueItems` value', () => __awaiter(this, void 0, void 0, function* () {
|
|
1102
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1103
|
+
// protocol with uniqueItems for an array of strings
|
|
1104
|
+
const protocolDefinition = {
|
|
1105
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
1106
|
+
published: true,
|
|
1107
|
+
types: {
|
|
1108
|
+
foo: {}
|
|
1109
|
+
},
|
|
1110
|
+
structure: {
|
|
1111
|
+
foo: {
|
|
1112
|
+
$tags: {
|
|
1113
|
+
uniqueStrings: {
|
|
1114
|
+
type: 'array',
|
|
1115
|
+
uniqueItems: true,
|
|
1116
|
+
items: {
|
|
1117
|
+
type: 'string',
|
|
1118
|
+
}
|
|
1119
|
+
},
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
},
|
|
1123
|
+
};
|
|
1124
|
+
// configure tags protocol
|
|
1125
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1126
|
+
author: alice,
|
|
1127
|
+
protocolDefinition,
|
|
1128
|
+
});
|
|
1129
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
1130
|
+
expect(configureReply.status.code).to.equal(202);
|
|
1131
|
+
// write a foo record with a `uniqueStrings` value with duplicate items
|
|
1132
|
+
const duplicateItemsRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1133
|
+
author: alice,
|
|
1134
|
+
published: true,
|
|
1135
|
+
protocol: protocolDefinition.protocol,
|
|
1136
|
+
protocolPath: 'foo',
|
|
1137
|
+
tags: {
|
|
1138
|
+
uniqueStrings: ['a', 'a'] // duplicate items
|
|
1139
|
+
}
|
|
1140
|
+
});
|
|
1141
|
+
// should fail
|
|
1142
|
+
const duplicateItemsReply = yield dwn.processMessage(alice.did, duplicateItemsRecord.message, { dataStream: duplicateItemsRecord.dataStream });
|
|
1143
|
+
expect(duplicateItemsReply.status.code).to.equal(400);
|
|
1144
|
+
// write a foo record with a `uniqueStrings` value with unique items
|
|
1145
|
+
const uniqueItemsRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1146
|
+
author: alice,
|
|
1147
|
+
published: true,
|
|
1148
|
+
protocol: protocolDefinition.protocol,
|
|
1149
|
+
protocolPath: 'foo',
|
|
1150
|
+
tags: {
|
|
1151
|
+
uniqueStrings: ['a', 'b'] // unique items
|
|
1152
|
+
}
|
|
1153
|
+
});
|
|
1154
|
+
// should pass
|
|
1155
|
+
const uniqueItemsReply = yield dwn.processMessage(alice.did, uniqueItemsRecord.message, { dataStream: uniqueItemsRecord.dataStream });
|
|
1156
|
+
expect(uniqueItemsReply.status.code).to.equal(202);
|
|
1157
|
+
}));
|
|
1158
|
+
it('should only accept a record containing tags required by $requiredTags', () => __awaiter(this, void 0, void 0, function* () {
|
|
1159
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1160
|
+
// protocol with a required tag
|
|
1161
|
+
const protocolDefinition = {
|
|
1162
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
1163
|
+
published: true,
|
|
1164
|
+
types: {
|
|
1165
|
+
foo: {}
|
|
1166
|
+
},
|
|
1167
|
+
structure: {
|
|
1168
|
+
foo: {
|
|
1169
|
+
$tags: {
|
|
1170
|
+
$requiredTags: ['someRequiredTag'],
|
|
1171
|
+
someRequiredTag: {
|
|
1172
|
+
type: 'string',
|
|
1173
|
+
},
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
},
|
|
1177
|
+
};
|
|
1178
|
+
// configure tags protocol
|
|
1179
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1180
|
+
author: alice,
|
|
1181
|
+
protocolDefinition,
|
|
1182
|
+
});
|
|
1183
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
1184
|
+
expect(configureReply.status.code).to.equal(202);
|
|
1185
|
+
// write a foo record without the required tag
|
|
1186
|
+
const fooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1187
|
+
author: alice,
|
|
1188
|
+
published: true,
|
|
1189
|
+
protocol: protocolDefinition.protocol,
|
|
1190
|
+
protocolPath: 'foo',
|
|
1191
|
+
});
|
|
1192
|
+
const fooRecordReply = yield dwn.processMessage(alice.did, fooRecord.message, { dataStream: fooRecord.dataStream });
|
|
1193
|
+
expect(fooRecordReply.status.code).to.equal(400);
|
|
1194
|
+
expect(fooRecordReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1195
|
+
expect(fooRecordReply.status.detail).to.contain(`${protocolDefinition.protocol}/foo/$tags must have required property 'someRequiredTag'`);
|
|
1196
|
+
// write a foo record with the required tag
|
|
1197
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1198
|
+
author: alice,
|
|
1199
|
+
published: true,
|
|
1200
|
+
protocol: protocolDefinition.protocol,
|
|
1201
|
+
protocolPath: 'foo',
|
|
1202
|
+
tags: {
|
|
1203
|
+
someRequiredTag: 'some-value'
|
|
1204
|
+
}
|
|
1205
|
+
});
|
|
1206
|
+
// should pass
|
|
1207
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
1208
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
1209
|
+
}));
|
|
1210
|
+
it('should accept any tag if $allowUndefinedTags is set to true', () => __awaiter(this, void 0, void 0, function* () {
|
|
1211
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1212
|
+
// protocol with no required tags
|
|
1213
|
+
const protocolDefinition = {
|
|
1214
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
1215
|
+
published: true,
|
|
1216
|
+
types: {
|
|
1217
|
+
foo: {}
|
|
1218
|
+
},
|
|
1219
|
+
structure: {
|
|
1220
|
+
foo: {
|
|
1221
|
+
$tags: {
|
|
1222
|
+
$allowUndefinedTags: true,
|
|
1223
|
+
optionalTag: {
|
|
1224
|
+
type: 'string',
|
|
1225
|
+
},
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
},
|
|
1229
|
+
};
|
|
1230
|
+
// configure tags protocol
|
|
1231
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1232
|
+
author: alice,
|
|
1233
|
+
protocolDefinition,
|
|
1234
|
+
});
|
|
1235
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
1236
|
+
expect(configureReply.status.code).to.equal(202);
|
|
1237
|
+
// write a foo record without the required tag
|
|
1238
|
+
const fooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1239
|
+
author: alice,
|
|
1240
|
+
published: true,
|
|
1241
|
+
protocol: protocolDefinition.protocol,
|
|
1242
|
+
protocolPath: 'foo',
|
|
1243
|
+
tags: {
|
|
1244
|
+
randomTag: 'some-value'
|
|
1245
|
+
}
|
|
1246
|
+
});
|
|
1247
|
+
const fooRecordReply = yield dwn.processMessage(alice.did, fooRecord.message, { dataStream: fooRecord.dataStream });
|
|
1248
|
+
expect(fooRecordReply.status.code).to.equal(202);
|
|
1249
|
+
}));
|
|
1250
|
+
describe('contains', () => {
|
|
1251
|
+
it('should reject a record tag that does not contain a value specified within the `enum` definition', () => __awaiter(this, void 0, void 0, function* () {
|
|
1252
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1253
|
+
// protocol with `enum` definition within `contains`
|
|
1254
|
+
const protocolDefinition = {
|
|
1255
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
1256
|
+
published: true,
|
|
1257
|
+
types: {
|
|
1258
|
+
foo: {}
|
|
1259
|
+
},
|
|
1260
|
+
structure: {
|
|
1261
|
+
foo: {
|
|
1262
|
+
$tags: {
|
|
1263
|
+
status: {
|
|
1264
|
+
type: 'array',
|
|
1265
|
+
items: {
|
|
1266
|
+
type: 'string'
|
|
1267
|
+
},
|
|
1268
|
+
contains: {
|
|
1269
|
+
type: 'string',
|
|
1270
|
+
enum: ['complete', 'in-progress', 'backlog']
|
|
1271
|
+
}
|
|
1272
|
+
},
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
},
|
|
1276
|
+
};
|
|
1277
|
+
// configure tags protocol
|
|
1278
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1279
|
+
author: alice,
|
|
1280
|
+
protocolDefinition,
|
|
1281
|
+
});
|
|
1282
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
1283
|
+
expect(configureReply.status.code).to.equal(202);
|
|
1284
|
+
// write a foo record with a `status` value that is not represented in the `enum`
|
|
1285
|
+
const invalidEnumRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1286
|
+
author: alice,
|
|
1287
|
+
published: true,
|
|
1288
|
+
protocol: protocolDefinition.protocol,
|
|
1289
|
+
protocolPath: 'foo',
|
|
1290
|
+
tags: {
|
|
1291
|
+
status: ['blocked'] // 'blocked' is not in the enum
|
|
1292
|
+
}
|
|
1293
|
+
});
|
|
1294
|
+
// should fail
|
|
1295
|
+
const invalidEnumReply = yield dwn.processMessage(alice.did, invalidEnumRecord.message, { dataStream: invalidEnumRecord.dataStream });
|
|
1296
|
+
expect(invalidEnumReply.status.code).to.equal(400);
|
|
1297
|
+
expect(invalidEnumReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1298
|
+
expect(invalidEnumReply.status.detail)
|
|
1299
|
+
.to.contain(`${protocolDefinition.protocol}/foo/$tags/status must contain at least 1 valid item(s)`);
|
|
1300
|
+
// write a foo record that now adds a valid `status` value to the array
|
|
1301
|
+
const validEnumRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1302
|
+
author: alice,
|
|
1303
|
+
published: true,
|
|
1304
|
+
protocol: protocolDefinition.protocol,
|
|
1305
|
+
protocolPath: 'foo',
|
|
1306
|
+
tags: {
|
|
1307
|
+
status: ['blocked', 'in-progress'] // at least one is within the array
|
|
1308
|
+
}
|
|
1309
|
+
});
|
|
1310
|
+
// should pass
|
|
1311
|
+
const validEnumReply = yield dwn.processMessage(alice.did, validEnumRecord.message, { dataStream: validEnumRecord.dataStream });
|
|
1312
|
+
expect(validEnumReply.status.code).to.equal(202);
|
|
1313
|
+
}));
|
|
1314
|
+
it('should reject a record tag that does not contain a value within the `minimum` and `maximum` range ', () => __awaiter(this, void 0, void 0, function* () {
|
|
1315
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1316
|
+
// protocol with `minimum` and `maximum` definitions within `contains`
|
|
1317
|
+
const protocolDefinition = {
|
|
1318
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
1319
|
+
published: true,
|
|
1320
|
+
types: {
|
|
1321
|
+
foo: {}
|
|
1322
|
+
},
|
|
1323
|
+
structure: {
|
|
1324
|
+
foo: {
|
|
1325
|
+
$tags: {
|
|
1326
|
+
containsNumbers: {
|
|
1327
|
+
type: 'array',
|
|
1328
|
+
items: {
|
|
1329
|
+
type: 'number'
|
|
1330
|
+
},
|
|
1331
|
+
contains: {
|
|
1332
|
+
type: 'number',
|
|
1333
|
+
minimum: 80,
|
|
1334
|
+
maximum: 100
|
|
1335
|
+
}
|
|
1336
|
+
},
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
},
|
|
1340
|
+
};
|
|
1341
|
+
// configure tags protocol
|
|
1342
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1343
|
+
author: alice,
|
|
1344
|
+
protocolDefinition,
|
|
1345
|
+
});
|
|
1346
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
1347
|
+
expect(configureReply.status.code).to.equal(202);
|
|
1348
|
+
// write a foo record with a `containsNumbers` value that does not have a number within the range
|
|
1349
|
+
const minContainsRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1350
|
+
author: alice,
|
|
1351
|
+
published: true,
|
|
1352
|
+
protocol: protocolDefinition.protocol,
|
|
1353
|
+
protocolPath: 'foo',
|
|
1354
|
+
tags: {
|
|
1355
|
+
containsNumbers: [50, 101] // does not contain any numbers within the range
|
|
1356
|
+
}
|
|
1357
|
+
});
|
|
1358
|
+
// should fail
|
|
1359
|
+
const minContainsReply = yield dwn.processMessage(alice.did, minContainsRecord.message, { dataStream: minContainsRecord.dataStream });
|
|
1360
|
+
expect(minContainsReply.status.code).to.equal(400);
|
|
1361
|
+
expect(minContainsReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1362
|
+
expect(minContainsReply.status.detail)
|
|
1363
|
+
.to.contain(`${protocolDefinition.protocol}/foo/$tags/containsNumbers must contain at least 1 valid item(s)`);
|
|
1364
|
+
// write a foo record with a `containsNumbers` value that has a number within the range
|
|
1365
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1366
|
+
author: alice,
|
|
1367
|
+
published: true,
|
|
1368
|
+
protocol: protocolDefinition.protocol,
|
|
1369
|
+
protocolPath: 'foo',
|
|
1370
|
+
tags: {
|
|
1371
|
+
containsNumbers: [50, 90, 101] // at least one number is within range
|
|
1372
|
+
}
|
|
1373
|
+
});
|
|
1374
|
+
// should pass
|
|
1375
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
1376
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
1377
|
+
}));
|
|
1378
|
+
it('should reject a record tag that does not contain a value within the `exclusiveMinimum` and `exclusiveMaximum` range ', () => __awaiter(this, void 0, void 0, function* () {
|
|
1379
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1380
|
+
// protocol with `minimum` and `maximum` definitions within `contains`
|
|
1381
|
+
const protocolDefinition = {
|
|
1382
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
1383
|
+
published: true,
|
|
1384
|
+
types: {
|
|
1385
|
+
foo: {}
|
|
1386
|
+
},
|
|
1387
|
+
structure: {
|
|
1388
|
+
foo: {
|
|
1389
|
+
$tags: {
|
|
1390
|
+
containsNumbers: {
|
|
1391
|
+
type: 'array',
|
|
1392
|
+
items: {
|
|
1393
|
+
type: 'number'
|
|
1394
|
+
},
|
|
1395
|
+
contains: {
|
|
1396
|
+
type: 'number',
|
|
1397
|
+
exclusiveMinimum: 80,
|
|
1398
|
+
exclusiveMaximum: 100
|
|
1399
|
+
}
|
|
1400
|
+
},
|
|
1401
|
+
}
|
|
1402
|
+
}
|
|
1403
|
+
},
|
|
1404
|
+
};
|
|
1405
|
+
// configure tags protocol
|
|
1406
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1407
|
+
author: alice,
|
|
1408
|
+
protocolDefinition,
|
|
1409
|
+
});
|
|
1410
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
1411
|
+
expect(configureReply.status.code).to.equal(202);
|
|
1412
|
+
// write a foo record with a `containsNumbers` value that does not have a number within the range
|
|
1413
|
+
const minContainsRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1414
|
+
author: alice,
|
|
1415
|
+
published: true,
|
|
1416
|
+
protocol: protocolDefinition.protocol,
|
|
1417
|
+
protocolPath: 'foo',
|
|
1418
|
+
tags: {
|
|
1419
|
+
containsNumbers: [80, 100] // does not contain any numbers within the range
|
|
1420
|
+
}
|
|
1421
|
+
});
|
|
1422
|
+
// should fail
|
|
1423
|
+
const minContainsReply = yield dwn.processMessage(alice.did, minContainsRecord.message, { dataStream: minContainsRecord.dataStream });
|
|
1424
|
+
expect(minContainsReply.status.code).to.equal(400);
|
|
1425
|
+
expect(minContainsReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1426
|
+
expect(minContainsReply.status.detail)
|
|
1427
|
+
.to.contain(`${protocolDefinition.protocol}/foo/$tags/containsNumbers must contain at least 1 valid item(s)`);
|
|
1428
|
+
// write a foo record with a `containsNumbers` value that has a number within the range
|
|
1429
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1430
|
+
author: alice,
|
|
1431
|
+
published: true,
|
|
1432
|
+
protocol: protocolDefinition.protocol,
|
|
1433
|
+
protocolPath: 'foo',
|
|
1434
|
+
tags: {
|
|
1435
|
+
containsNumbers: [80, 90, 100] // at least one number is within range
|
|
1436
|
+
}
|
|
1437
|
+
});
|
|
1438
|
+
// should pass
|
|
1439
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
1440
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
1441
|
+
}));
|
|
1442
|
+
it('should reject a record tag that does not contain a value within the `minLength` and `maxLength` range ', () => __awaiter(this, void 0, void 0, function* () {
|
|
1443
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1444
|
+
// protocol with `minLength` and `maxLength` definitions within `contains`
|
|
1445
|
+
const protocolDefinition = {
|
|
1446
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
1447
|
+
published: true,
|
|
1448
|
+
types: {
|
|
1449
|
+
foo: {}
|
|
1450
|
+
},
|
|
1451
|
+
structure: {
|
|
1452
|
+
foo: {
|
|
1453
|
+
$tags: {
|
|
1454
|
+
nickNames: {
|
|
1455
|
+
type: 'array',
|
|
1456
|
+
items: {
|
|
1457
|
+
type: 'string'
|
|
1458
|
+
},
|
|
1459
|
+
contains: {
|
|
1460
|
+
type: 'string',
|
|
1461
|
+
maxLength: 10,
|
|
1462
|
+
minLength: 2,
|
|
1463
|
+
}
|
|
1464
|
+
},
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
},
|
|
1468
|
+
};
|
|
1469
|
+
// configure tags protocol
|
|
1470
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1471
|
+
author: alice,
|
|
1472
|
+
protocolDefinition,
|
|
1473
|
+
});
|
|
1474
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
1475
|
+
expect(configureReply.status.code).to.equal(202);
|
|
1476
|
+
// write a foo record with a `firstName` value that does not have a string within the range
|
|
1477
|
+
const minContainsRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1478
|
+
author: alice,
|
|
1479
|
+
published: true,
|
|
1480
|
+
protocol: protocolDefinition.protocol,
|
|
1481
|
+
protocolPath: 'foo',
|
|
1482
|
+
tags: {
|
|
1483
|
+
nickNames: ['a', 'b'] // only contains first initial, will fail
|
|
1484
|
+
}
|
|
1485
|
+
});
|
|
1486
|
+
// should fail
|
|
1487
|
+
const minContainsReply = yield dwn.processMessage(alice.did, minContainsRecord.message, { dataStream: minContainsRecord.dataStream });
|
|
1488
|
+
expect(minContainsReply.status.code).to.equal(400);
|
|
1489
|
+
expect(minContainsReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1490
|
+
expect(minContainsReply.status.detail).to
|
|
1491
|
+
.contain(`${protocolDefinition.protocol}/foo/$tags/nickNames must contain at least 1 valid item(s)`);
|
|
1492
|
+
// write a foo record with a `nickNames` value that has a string within the range
|
|
1493
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1494
|
+
author: alice,
|
|
1495
|
+
published: true,
|
|
1496
|
+
protocol: protocolDefinition.protocol,
|
|
1497
|
+
protocolPath: 'foo',
|
|
1498
|
+
tags: {
|
|
1499
|
+
nickNames: ['ali', 'a'] // at least one string is within range
|
|
1500
|
+
}
|
|
1501
|
+
});
|
|
1502
|
+
// should pass
|
|
1503
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
1504
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
1505
|
+
}));
|
|
1506
|
+
});
|
|
1507
|
+
describe('items', () => {
|
|
1508
|
+
it('should reject a record tag that includes a value not specified within the `enum` definition', () => __awaiter(this, void 0, void 0, function* () {
|
|
1509
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1510
|
+
// protocol with `enum` definition within `items`
|
|
1511
|
+
const protocolDefinition = {
|
|
1512
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
1513
|
+
published: true,
|
|
1514
|
+
types: {
|
|
1515
|
+
foo: {}
|
|
1516
|
+
},
|
|
1517
|
+
structure: {
|
|
1518
|
+
foo: {
|
|
1519
|
+
$tags: {
|
|
1520
|
+
status: {
|
|
1521
|
+
type: 'array',
|
|
1522
|
+
items: {
|
|
1523
|
+
type: 'string',
|
|
1524
|
+
enum: ['complete', 'in-progress', 'backlog', 'approved']
|
|
1525
|
+
},
|
|
1526
|
+
},
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
},
|
|
1530
|
+
};
|
|
1531
|
+
// configure tags protocol
|
|
1532
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1533
|
+
author: alice,
|
|
1534
|
+
protocolDefinition,
|
|
1535
|
+
});
|
|
1536
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
1537
|
+
expect(configureReply.status.code).to.equal(202);
|
|
1538
|
+
// write a foo record with a `status` value that is not represented in the `enum`
|
|
1539
|
+
const invalidEnumRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1540
|
+
author: alice,
|
|
1541
|
+
published: true,
|
|
1542
|
+
protocol: protocolDefinition.protocol,
|
|
1543
|
+
protocolPath: 'foo',
|
|
1544
|
+
tags: {
|
|
1545
|
+
status: ['in-progress', 'blocked'] // 'blocked' is not in the enum
|
|
1546
|
+
}
|
|
1547
|
+
});
|
|
1548
|
+
// should fail
|
|
1549
|
+
const invalidEnumReply = yield dwn.processMessage(alice.did, invalidEnumRecord.message, { dataStream: invalidEnumRecord.dataStream });
|
|
1550
|
+
expect(invalidEnumReply.status.code).to.equal(400);
|
|
1551
|
+
expect(invalidEnumReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1552
|
+
expect(invalidEnumReply.status.detail)
|
|
1553
|
+
.to.contain(`${protocolDefinition.protocol}/foo/$tags/status/1 must be equal to one of the allowed values`);
|
|
1554
|
+
// write a foo record that now includes only valid `status` values
|
|
1555
|
+
const validEnumRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1556
|
+
author: alice,
|
|
1557
|
+
published: true,
|
|
1558
|
+
protocol: protocolDefinition.protocol,
|
|
1559
|
+
protocolPath: 'foo',
|
|
1560
|
+
tags: {
|
|
1561
|
+
status: ['complete', 'approved'] // both are in the enum
|
|
1562
|
+
}
|
|
1563
|
+
});
|
|
1564
|
+
// should pass
|
|
1565
|
+
const validEnumReply = yield dwn.processMessage(alice.did, validEnumRecord.message, { dataStream: validEnumRecord.dataStream });
|
|
1566
|
+
expect(validEnumReply.status.code).to.equal(202);
|
|
1567
|
+
}));
|
|
1568
|
+
it('should reject a record tag which all items do not have a value within the `minimum` and `maximum` range ', () => __awaiter(this, void 0, void 0, function* () {
|
|
1569
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1570
|
+
// protocol with minContains and maxContains for an array of numbers
|
|
1571
|
+
const protocolDefinition = {
|
|
1572
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
1573
|
+
published: true,
|
|
1574
|
+
types: {
|
|
1575
|
+
foo: {}
|
|
1576
|
+
},
|
|
1577
|
+
structure: {
|
|
1578
|
+
foo: {
|
|
1579
|
+
$tags: {
|
|
1580
|
+
numbers: {
|
|
1581
|
+
type: 'array',
|
|
1582
|
+
items: {
|
|
1583
|
+
type: 'number',
|
|
1584
|
+
minimum: 80,
|
|
1585
|
+
maximum: 100
|
|
1586
|
+
},
|
|
1587
|
+
},
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
},
|
|
1591
|
+
};
|
|
1592
|
+
// configure tags protocol
|
|
1593
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1594
|
+
author: alice,
|
|
1595
|
+
protocolDefinition,
|
|
1596
|
+
});
|
|
1597
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
1598
|
+
expect(configureReply.status.code).to.equal(202);
|
|
1599
|
+
// write a foo record with a `numbers` value that is less than the minimum
|
|
1600
|
+
const minItemssRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1601
|
+
author: alice,
|
|
1602
|
+
published: true,
|
|
1603
|
+
protocol: protocolDefinition.protocol,
|
|
1604
|
+
protocolPath: 'foo',
|
|
1605
|
+
tags: {
|
|
1606
|
+
numbers: [50, 90] // contains an item less than the minimum
|
|
1607
|
+
}
|
|
1608
|
+
});
|
|
1609
|
+
// should fail
|
|
1610
|
+
const minItemsReply = yield dwn.processMessage(alice.did, minItemssRecord.message, { dataStream: minItemssRecord.dataStream });
|
|
1611
|
+
expect(minItemsReply.status.code).to.equal(400);
|
|
1612
|
+
expect(minItemsReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1613
|
+
expect(minItemsReply.status.detail)
|
|
1614
|
+
.to.contain(`${protocolDefinition.protocol}/foo/$tags/numbers/0 must be >= 80`);
|
|
1615
|
+
// write a foo record with a `numbers` value that is more than the maximum
|
|
1616
|
+
const maxItemssRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1617
|
+
author: alice,
|
|
1618
|
+
published: true,
|
|
1619
|
+
protocol: protocolDefinition.protocol,
|
|
1620
|
+
protocolPath: 'foo',
|
|
1621
|
+
tags: {
|
|
1622
|
+
numbers: [85, 105] // contains an item more than the maximum
|
|
1623
|
+
}
|
|
1624
|
+
});
|
|
1625
|
+
// should fail
|
|
1626
|
+
const maxItemsReply = yield dwn.processMessage(alice.did, maxItemssRecord.message, { dataStream: maxItemssRecord.dataStream });
|
|
1627
|
+
expect(maxItemsReply.status.code).to.equal(400);
|
|
1628
|
+
expect(maxItemsReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1629
|
+
expect(maxItemsReply.status.detail)
|
|
1630
|
+
.to.contain(`${protocolDefinition.protocol}/foo/$tags/numbers/1 must be <= 100`);
|
|
1631
|
+
// write a foo record with a `numbers` value that are within the range
|
|
1632
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1633
|
+
author: alice,
|
|
1634
|
+
published: true,
|
|
1635
|
+
protocol: protocolDefinition.protocol,
|
|
1636
|
+
protocolPath: 'foo',
|
|
1637
|
+
tags: {
|
|
1638
|
+
numbers: [85, 90] // both items within range
|
|
1639
|
+
}
|
|
1640
|
+
});
|
|
1641
|
+
// should pass
|
|
1642
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
1643
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
1644
|
+
}));
|
|
1645
|
+
it('should reject a record tag which all items do not have a value within the `exclusiveMinimum` and `exclusiveMaximum` range ', () => __awaiter(this, void 0, void 0, function* () {
|
|
1646
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1647
|
+
// protocol with minContains and maxContains for an array of numbers
|
|
1648
|
+
const protocolDefinition = {
|
|
1649
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
1650
|
+
published: true,
|
|
1651
|
+
types: {
|
|
1652
|
+
foo: {}
|
|
1653
|
+
},
|
|
1654
|
+
structure: {
|
|
1655
|
+
foo: {
|
|
1656
|
+
$tags: {
|
|
1657
|
+
numbers: {
|
|
1658
|
+
type: 'array',
|
|
1659
|
+
items: {
|
|
1660
|
+
type: 'number',
|
|
1661
|
+
exclusiveMinimum: 80,
|
|
1662
|
+
exclusiveMaximum: 100
|
|
1663
|
+
},
|
|
1664
|
+
},
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
},
|
|
1668
|
+
};
|
|
1669
|
+
// configure tags protocol
|
|
1670
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1671
|
+
author: alice,
|
|
1672
|
+
protocolDefinition,
|
|
1673
|
+
});
|
|
1674
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
1675
|
+
expect(configureReply.status.code).to.equal(202);
|
|
1676
|
+
// write a foo record with a `numbers` value that is equal to than the exclusive minimum
|
|
1677
|
+
const minItemsRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1678
|
+
author: alice,
|
|
1679
|
+
published: true,
|
|
1680
|
+
protocol: protocolDefinition.protocol,
|
|
1681
|
+
protocolPath: 'foo',
|
|
1682
|
+
tags: {
|
|
1683
|
+
numbers: [80, 90] // contains an item equal to the exclusive minimum
|
|
1684
|
+
}
|
|
1685
|
+
});
|
|
1686
|
+
// should fail
|
|
1687
|
+
const minItemsReply = yield dwn.processMessage(alice.did, minItemsRecord.message, { dataStream: minItemsRecord.dataStream });
|
|
1688
|
+
expect(minItemsReply.status.code).to.equal(400);
|
|
1689
|
+
expect(minItemsReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1690
|
+
expect(minItemsReply.status.detail)
|
|
1691
|
+
.to.contain(`${protocolDefinition.protocol}/foo/$tags/numbers/0 must be > 80`);
|
|
1692
|
+
// write a foo record with a `numbers` value that is equal to than the exclusive maximum
|
|
1693
|
+
const maxContainsRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1694
|
+
author: alice,
|
|
1695
|
+
published: true,
|
|
1696
|
+
protocol: protocolDefinition.protocol,
|
|
1697
|
+
protocolPath: 'foo',
|
|
1698
|
+
tags: {
|
|
1699
|
+
numbers: [90, 100] // contains an item that is equal to the exclusive maximum
|
|
1700
|
+
}
|
|
1701
|
+
});
|
|
1702
|
+
// should fail
|
|
1703
|
+
const maxItemsReply = yield dwn.processMessage(alice.did, maxContainsRecord.message, { dataStream: maxContainsRecord.dataStream });
|
|
1704
|
+
expect(maxItemsReply.status.code).to.equal(400);
|
|
1705
|
+
expect(maxItemsReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1706
|
+
expect(maxItemsReply.status.detail)
|
|
1707
|
+
.to.contain(`${protocolDefinition.protocol}/foo/$tags/numbers/1 must be < 100`);
|
|
1708
|
+
// write a foo record with a `numbers` value that are within the range
|
|
1709
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1710
|
+
author: alice,
|
|
1711
|
+
published: true,
|
|
1712
|
+
protocol: protocolDefinition.protocol,
|
|
1713
|
+
protocolPath: 'foo',
|
|
1714
|
+
tags: {
|
|
1715
|
+
numbers: [81, 99] // both items within range
|
|
1716
|
+
}
|
|
1717
|
+
});
|
|
1718
|
+
// should pass
|
|
1719
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
1720
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
1721
|
+
}));
|
|
1722
|
+
it('should reject a record tag that does not contain a value within the `minLength` and `maxLength` range ', () => __awaiter(this, void 0, void 0, function* () {
|
|
1723
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1724
|
+
// protocol with `minLength` and `maxLength` definitions within `contains`
|
|
1725
|
+
const protocolDefinition = {
|
|
1726
|
+
protocol: 'http://example.com/protocol/withTags',
|
|
1727
|
+
published: true,
|
|
1728
|
+
types: {
|
|
1729
|
+
foo: {}
|
|
1730
|
+
},
|
|
1731
|
+
structure: {
|
|
1732
|
+
foo: {
|
|
1733
|
+
$tags: {
|
|
1734
|
+
nickNames: {
|
|
1735
|
+
type: 'array',
|
|
1736
|
+
items: {
|
|
1737
|
+
type: 'string',
|
|
1738
|
+
maxLength: 10,
|
|
1739
|
+
minLength: 2,
|
|
1740
|
+
},
|
|
1741
|
+
},
|
|
1742
|
+
}
|
|
1743
|
+
}
|
|
1744
|
+
},
|
|
1745
|
+
};
|
|
1746
|
+
// configure tags protocol
|
|
1747
|
+
const protocolConfigure = yield TestDataGenerator.generateProtocolsConfigure({
|
|
1748
|
+
author: alice,
|
|
1749
|
+
protocolDefinition,
|
|
1750
|
+
});
|
|
1751
|
+
const configureReply = yield dwn.processMessage(alice.did, protocolConfigure.message);
|
|
1752
|
+
expect(configureReply.status.code).to.equal(202);
|
|
1753
|
+
// write a foo record with a `firstName` value that does not have a string within the range
|
|
1754
|
+
const minItemsRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1755
|
+
author: alice,
|
|
1756
|
+
published: true,
|
|
1757
|
+
protocol: protocolDefinition.protocol,
|
|
1758
|
+
protocolPath: 'foo',
|
|
1759
|
+
tags: {
|
|
1760
|
+
nickNames: ['ali', 'a'] // 'a' is too short
|
|
1761
|
+
}
|
|
1762
|
+
});
|
|
1763
|
+
// should fail
|
|
1764
|
+
const minItemsReply = yield dwn.processMessage(alice.did, minItemsRecord.message, { dataStream: minItemsRecord.dataStream });
|
|
1765
|
+
expect(minItemsReply.status.code).to.equal(400);
|
|
1766
|
+
expect(minItemsReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1767
|
+
expect(minItemsReply.status.detail).to
|
|
1768
|
+
.contain(`${protocolDefinition.protocol}/foo/$tags/nickNames/1 must NOT have fewer than 2 characters`);
|
|
1769
|
+
// write a foo record with a `nickname` value this is too long
|
|
1770
|
+
const maxItemsRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1771
|
+
author: alice,
|
|
1772
|
+
published: true,
|
|
1773
|
+
protocol: protocolDefinition.protocol,
|
|
1774
|
+
protocolPath: 'foo',
|
|
1775
|
+
tags: {
|
|
1776
|
+
nickNames: ['ali', 'alice-jane-mary'] // 'alice-jane-mary' is too long
|
|
1777
|
+
}
|
|
1778
|
+
});
|
|
1779
|
+
// should fail
|
|
1780
|
+
const maxItemsReply = yield dwn.processMessage(alice.did, maxItemsRecord.message, { dataStream: maxItemsRecord.dataStream });
|
|
1781
|
+
expect(maxItemsReply.status.code).to.equal(400);
|
|
1782
|
+
expect(maxItemsReply.status.detail).to.contain(DwnErrorCode.ProtocolAuthorizationTagsInvalidSchema);
|
|
1783
|
+
expect(maxItemsReply.status.detail).to
|
|
1784
|
+
.contain(`${protocolDefinition.protocol}/foo/$tags/nickNames/1 must NOT have more than 10 characters`);
|
|
1785
|
+
// write a foo record with a `nickNames` value that has a string within the range
|
|
1786
|
+
const validFooRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
1787
|
+
author: alice,
|
|
1788
|
+
published: true,
|
|
1789
|
+
protocol: protocolDefinition.protocol,
|
|
1790
|
+
protocolPath: 'foo',
|
|
1791
|
+
tags: {
|
|
1792
|
+
nickNames: ['ali', 'allie'] // both items within range
|
|
1793
|
+
}
|
|
1794
|
+
});
|
|
1795
|
+
// should pass
|
|
1796
|
+
const validFooRecordReply = yield dwn.processMessage(alice.did, validFooRecord.message, { dataStream: validFooRecord.dataStream });
|
|
1797
|
+
expect(validFooRecordReply.status.code).to.equal(202);
|
|
1798
|
+
}));
|
|
1799
|
+
});
|
|
1800
|
+
});
|
|
1801
|
+
it('should be able to write a Record with tags', () => __awaiter(this, void 0, void 0, function* () {
|
|
1802
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1803
|
+
// create tags that represent `string[]`, `number[]`, `string`, `number`, or `boolean` values.
|
|
1804
|
+
const stringTag = 'string-value';
|
|
1805
|
+
const stringArrayTag = ['string-value', 'string-value2'];
|
|
1806
|
+
const numberTag = 54566975;
|
|
1807
|
+
const numberArrayTag = [0, 1, 2];
|
|
1808
|
+
const booleanTag = false;
|
|
1809
|
+
const tagsRecord1 = yield TestDataGenerator.generateRecordsWrite({
|
|
1810
|
+
author: alice,
|
|
1811
|
+
published: true,
|
|
1812
|
+
schema: 'post',
|
|
1813
|
+
tags: {
|
|
1814
|
+
stringTag,
|
|
1815
|
+
numberTag,
|
|
1816
|
+
booleanTag,
|
|
1817
|
+
stringArrayTag,
|
|
1818
|
+
numberArrayTag,
|
|
1819
|
+
}
|
|
1820
|
+
});
|
|
1821
|
+
const tagsRecord1Reply = yield dwn.processMessage(alice.did, tagsRecord1.message, { dataStream: tagsRecord1.dataStream });
|
|
1822
|
+
expect(tagsRecord1Reply.status.code).to.equal(202);
|
|
1823
|
+
// verify the record was written
|
|
1824
|
+
const tagsRecord1Read = yield RecordsRead.create({
|
|
1825
|
+
filter: {
|
|
1826
|
+
recordId: tagsRecord1.message.recordId,
|
|
1827
|
+
},
|
|
1828
|
+
signer: Jws.createSigner(alice)
|
|
1829
|
+
});
|
|
1830
|
+
const tagsRecord1ReadReply = yield dwn.processMessage(alice.did, tagsRecord1Read.message);
|
|
1831
|
+
expect(tagsRecord1ReadReply.status.code).to.equal(200);
|
|
1832
|
+
expect(tagsRecord1ReadReply.entry.recordsWrite).to.not.be.undefined;
|
|
1833
|
+
expect(tagsRecord1ReadReply.entry.recordsWrite.descriptor.tags)
|
|
1834
|
+
.to.deep.equal({ stringTag, numberTag, booleanTag, stringArrayTag, numberArrayTag });
|
|
1835
|
+
}));
|
|
1836
|
+
it('should overwrite tags when updating a Record', () => __awaiter(this, void 0, void 0, function* () {
|
|
1837
|
+
var _a, _b;
|
|
1838
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1839
|
+
const tagsRecord1 = yield TestDataGenerator.generateRecordsWrite({
|
|
1840
|
+
author: alice,
|
|
1841
|
+
published: true,
|
|
1842
|
+
schema: 'post',
|
|
1843
|
+
tags: {
|
|
1844
|
+
stringTag: 'string-value',
|
|
1845
|
+
numberTag: 54566975,
|
|
1846
|
+
booleanTag: false,
|
|
1847
|
+
stringArrayTag: ['string-value', 'string-value2'],
|
|
1848
|
+
numberArrayTag: [0, 1, 2],
|
|
1849
|
+
}
|
|
1850
|
+
});
|
|
1851
|
+
// write the record
|
|
1852
|
+
const tagsRecord1Reply = yield dwn.processMessage(alice.did, tagsRecord1.message, { dataStream: tagsRecord1.dataStream });
|
|
1853
|
+
expect(tagsRecord1Reply.status.code).to.equal(202);
|
|
1854
|
+
// verify the record was written
|
|
1855
|
+
const tagsRecord1Read = yield RecordsRead.create({
|
|
1856
|
+
filter: {
|
|
1857
|
+
recordId: tagsRecord1.message.recordId,
|
|
1858
|
+
},
|
|
1859
|
+
signer: Jws.createSigner(alice)
|
|
1860
|
+
});
|
|
1861
|
+
const tagsRecord1ReadReply = yield dwn.processMessage(alice.did, tagsRecord1Read.message);
|
|
1862
|
+
expect(tagsRecord1ReadReply.status.code).to.equal(200);
|
|
1863
|
+
expect(tagsRecord1ReadReply.entry.recordsWrite).to.not.be.undefined;
|
|
1864
|
+
expect(tagsRecord1ReadReply.entry.recordsWrite.descriptor.tags).to.deep.equal({
|
|
1865
|
+
stringTag: 'string-value',
|
|
1866
|
+
numberTag: 54566975,
|
|
1867
|
+
booleanTag: false,
|
|
1868
|
+
stringArrayTag: ['string-value', 'string-value2'],
|
|
1869
|
+
numberArrayTag: [0, 1, 2],
|
|
1870
|
+
});
|
|
1871
|
+
// Sanity: Query for a tag value
|
|
1872
|
+
const tagsQueryMatch = yield TestDataGenerator.generateRecordsQuery({
|
|
1873
|
+
author: alice,
|
|
1874
|
+
filter: {
|
|
1875
|
+
tags: {
|
|
1876
|
+
stringTag: 'string-value'
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
});
|
|
1880
|
+
const tagsQueryMatchReply = yield dwn.processMessage(alice.did, tagsQueryMatch.message);
|
|
1881
|
+
expect(tagsQueryMatchReply.status.code).to.equal(200);
|
|
1882
|
+
expect((_a = tagsQueryMatchReply.entries) === null || _a === void 0 ? void 0 : _a.length).to.equal(1);
|
|
1883
|
+
expect(tagsQueryMatchReply.entries[0].recordId).to.equal(tagsRecord1.message.recordId);
|
|
1884
|
+
// update the record with new tags
|
|
1885
|
+
const updatedRecord = yield TestDataGenerator.generateFromRecordsWrite({
|
|
1886
|
+
author: alice,
|
|
1887
|
+
existingWrite: tagsRecord1.recordsWrite,
|
|
1888
|
+
tags: { newTag: 'new-value' }
|
|
1889
|
+
});
|
|
1890
|
+
const updatedRecordReply = yield dwn.processMessage(alice.did, updatedRecord.message, { dataStream: updatedRecord.dataStream });
|
|
1891
|
+
expect(updatedRecordReply.status.code).to.equal(202, updatedRecordReply.status.detail);
|
|
1892
|
+
const updatedRecordReadReply = yield dwn.processMessage(alice.did, tagsRecord1Read.message);
|
|
1893
|
+
expect(updatedRecordReadReply.status.code).to.equal(200);
|
|
1894
|
+
expect(updatedRecordReadReply.entry.recordsWrite).to.exist;
|
|
1895
|
+
expect(updatedRecordReadReply.entry.recordsWrite.descriptor.tags).to.deep.equal({ newTag: 'new-value' });
|
|
1896
|
+
// Sanity: Query for the old tag value should return no results
|
|
1897
|
+
const tagsQueryMatchReply2 = yield dwn.processMessage(alice.did, tagsQueryMatch.message);
|
|
1898
|
+
expect(tagsQueryMatchReply2.status.code).to.equal(200);
|
|
1899
|
+
expect((_b = tagsQueryMatchReply2.entries) === null || _b === void 0 ? void 0 : _b.length).to.equal(0);
|
|
1900
|
+
}));
|
|
1901
|
+
it('should not index tags when the record is not `latestBaseState`', () => __awaiter(this, void 0, void 0, function* () {
|
|
1902
|
+
const buildTagIndexSpy = sinon.spy(Records, 'buildTagIndexes');
|
|
1903
|
+
const constructIndexesSpy = sinon.spy(RecordsWrite.prototype, 'constructIndexes');
|
|
1904
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1905
|
+
// write a record with tags, this should trigger the `buildTagIndexes` method
|
|
1906
|
+
const tagsRecord1 = yield TestDataGenerator.generateRecordsWrite({
|
|
1907
|
+
author: alice,
|
|
1908
|
+
published: true,
|
|
1909
|
+
schema: 'post',
|
|
1910
|
+
tags: {
|
|
1911
|
+
stringTag: 'string-value',
|
|
1912
|
+
numberTag: 54566975,
|
|
1913
|
+
booleanTag: false,
|
|
1914
|
+
stringArrayTag: ['string-value', 'string-value2'],
|
|
1915
|
+
numberArrayTag: [0, 1, 2],
|
|
1916
|
+
}
|
|
1917
|
+
});
|
|
1918
|
+
// write the record
|
|
1919
|
+
const tagsRecord1Reply = yield dwn.processMessage(alice.did, tagsRecord1.message, { dataStream: tagsRecord1.dataStream });
|
|
1920
|
+
expect(tagsRecord1Reply.status.code).to.equal(202);
|
|
1921
|
+
// verify that construct Indexes was called
|
|
1922
|
+
expect(constructIndexesSpy.callCount).to.equal(1);
|
|
1923
|
+
// verify that buildTagIndexes was called
|
|
1924
|
+
expect(buildTagIndexSpy.callCount).to.equal(1);
|
|
1925
|
+
// reset counters
|
|
1926
|
+
constructIndexesSpy.resetHistory();
|
|
1927
|
+
buildTagIndexSpy.resetHistory();
|
|
1928
|
+
// update the record without any tags this time
|
|
1929
|
+
const updatedRecord = yield TestDataGenerator.generateFromRecordsWrite({
|
|
1930
|
+
author: alice,
|
|
1931
|
+
existingWrite: tagsRecord1.recordsWrite,
|
|
1932
|
+
});
|
|
1933
|
+
const updatedRecordReply = yield dwn.processMessage(alice.did, updatedRecord.message, { dataStream: updatedRecord.dataStream });
|
|
1934
|
+
expect(updatedRecordReply.status.code).to.equal(202);
|
|
1935
|
+
// construct Indexes should be called once for the `initialWrite` and once for the updated write
|
|
1936
|
+
expect(constructIndexesSpy.callCount).to.equal(2);
|
|
1937
|
+
// verify that buildTagIndexes was not called at all
|
|
1938
|
+
expect(buildTagIndexSpy.callCount).to.equal(0);
|
|
1939
|
+
}));
|
|
1940
|
+
});
|
|
1941
|
+
describe('RecordsQuery filter for tags', () => {
|
|
1942
|
+
it('should be able to filter by string match', () => __awaiter(this, void 0, void 0, function* () {
|
|
1943
|
+
var _a, _b, _c;
|
|
1944
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1945
|
+
const stringTag = 'string-value';
|
|
1946
|
+
const tagsRecord1 = yield TestDataGenerator.generateRecordsWrite({
|
|
1947
|
+
author: alice,
|
|
1948
|
+
published: true,
|
|
1949
|
+
schema: 'post',
|
|
1950
|
+
tags: {
|
|
1951
|
+
stringTag,
|
|
1952
|
+
}
|
|
1953
|
+
});
|
|
1954
|
+
const tagsRecord1Reply = yield dwn.processMessage(alice.did, tagsRecord1.message, { dataStream: tagsRecord1.dataStream });
|
|
1955
|
+
expect(tagsRecord1Reply.status.code).to.equal(202);
|
|
1956
|
+
const tagsQueryMatch = yield TestDataGenerator.generateRecordsQuery({
|
|
1957
|
+
author: alice,
|
|
1958
|
+
filter: {
|
|
1959
|
+
tags: {
|
|
1960
|
+
stringTag: 'string-value'
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
});
|
|
1964
|
+
const tagsQueryMatchReply = yield dwn.processMessage(alice.did, tagsQueryMatch.message);
|
|
1965
|
+
expect(tagsQueryMatchReply.status.code).to.equal(200);
|
|
1966
|
+
expect((_a = tagsQueryMatchReply.entries) === null || _a === void 0 ? void 0 : _a.length).to.equal(1);
|
|
1967
|
+
expect(tagsQueryMatchReply.entries[0].recordId).to.equal(tagsRecord1.message.recordId);
|
|
1968
|
+
// negative result same tag different value
|
|
1969
|
+
let tagsQueryNegative = yield TestDataGenerator.generateRecordsQuery({
|
|
1970
|
+
author: alice,
|
|
1971
|
+
filter: {
|
|
1972
|
+
tags: {
|
|
1973
|
+
stringTag: 'other-value'
|
|
1974
|
+
}
|
|
1975
|
+
}
|
|
1976
|
+
});
|
|
1977
|
+
let tagsQueryNegativeReply = yield dwn.processMessage(alice.did, tagsQueryNegative.message);
|
|
1978
|
+
expect(tagsQueryNegativeReply.status.code).to.equal(200);
|
|
1979
|
+
expect((_b = tagsQueryNegativeReply.entries) === null || _b === void 0 ? void 0 : _b.length).to.equal(0);
|
|
1980
|
+
// negative result different tag same value
|
|
1981
|
+
tagsQueryNegative = yield TestDataGenerator.generateRecordsQuery({
|
|
1982
|
+
author: alice,
|
|
1983
|
+
filter: {
|
|
1984
|
+
tags: {
|
|
1985
|
+
otherTag: 'string-value'
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
});
|
|
1989
|
+
tagsQueryNegativeReply = yield dwn.processMessage(alice.did, tagsQueryNegative.message);
|
|
1990
|
+
expect(tagsQueryNegativeReply.status.code).to.equal(200);
|
|
1991
|
+
expect((_c = tagsQueryNegativeReply.entries) === null || _c === void 0 ? void 0 : _c.length).to.equal(0);
|
|
1992
|
+
}));
|
|
1993
|
+
it('should be able to filter by number match', () => __awaiter(this, void 0, void 0, function* () {
|
|
1994
|
+
var _a, _b, _c;
|
|
1995
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
1996
|
+
const numberTag = 54566975;
|
|
1997
|
+
// write a record with a numerical value tag
|
|
1998
|
+
const tagsRecord1 = yield TestDataGenerator.generateRecordsWrite({
|
|
1999
|
+
author: alice,
|
|
2000
|
+
published: true,
|
|
2001
|
+
schema: 'post',
|
|
2002
|
+
tags: {
|
|
2003
|
+
numberTag,
|
|
2004
|
+
}
|
|
2005
|
+
});
|
|
2006
|
+
const tagsRecord1Reply = yield dwn.processMessage(alice.did, tagsRecord1.message, { dataStream: tagsRecord1.dataStream });
|
|
2007
|
+
expect(tagsRecord1Reply.status.code).to.equal(202);
|
|
2008
|
+
// do an exact match for the tag value
|
|
2009
|
+
const tagsQueryMatch = yield TestDataGenerator.generateRecordsQuery({
|
|
2010
|
+
author: alice,
|
|
2011
|
+
filter: {
|
|
2012
|
+
tags: {
|
|
2013
|
+
numberTag: 54566975,
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
});
|
|
2017
|
+
const tagsQueryMatchReply = yield dwn.processMessage(alice.did, tagsQueryMatch.message);
|
|
2018
|
+
expect(tagsQueryMatchReply.status.code).to.equal(200);
|
|
2019
|
+
expect((_a = tagsQueryMatchReply.entries) === null || _a === void 0 ? void 0 : _a.length).to.equal(1);
|
|
2020
|
+
expect(tagsQueryMatchReply.entries[0].recordId).to.equal(tagsRecord1.message.recordId);
|
|
2021
|
+
// negative result same tag different value
|
|
2022
|
+
let tagsQueryNegative = yield TestDataGenerator.generateRecordsQuery({
|
|
2023
|
+
author: alice,
|
|
2024
|
+
filter: {
|
|
2025
|
+
tags: {
|
|
2026
|
+
numberTag: 54566974, // off by one
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
});
|
|
2030
|
+
let tagsQueryNegativeReply = yield dwn.processMessage(alice.did, tagsQueryNegative.message);
|
|
2031
|
+
expect(tagsQueryNegativeReply.status.code).to.equal(200);
|
|
2032
|
+
expect((_b = tagsQueryNegativeReply.entries) === null || _b === void 0 ? void 0 : _b.length).to.equal(0);
|
|
2033
|
+
// negative result different tag same value
|
|
2034
|
+
tagsQueryNegative = yield TestDataGenerator.generateRecordsQuery({
|
|
2035
|
+
author: alice,
|
|
2036
|
+
filter: {
|
|
2037
|
+
tags: {
|
|
2038
|
+
otherTag: 54566975,
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
});
|
|
2042
|
+
tagsQueryNegativeReply = yield dwn.processMessage(alice.did, tagsQueryNegative.message);
|
|
2043
|
+
expect(tagsQueryNegativeReply.status.code).to.equal(200);
|
|
2044
|
+
expect((_c = tagsQueryNegativeReply.entries) === null || _c === void 0 ? void 0 : _c.length).to.equal(0);
|
|
2045
|
+
}));
|
|
2046
|
+
it('should be able to filter by boolean match', () => __awaiter(this, void 0, void 0, function* () {
|
|
2047
|
+
// 1. Write a record with a boolean tag `booleanTag` set to true
|
|
2048
|
+
// 2. Write a record with a boolean tag `booleanTag` set to false.
|
|
2049
|
+
// 3. Query for records with a `booleanTag` set to true, and validate the result.
|
|
2050
|
+
// 4. Query for records with a `booleanTag` set to false, and validate the result.
|
|
2051
|
+
// 5. Query for records with a non existent boolean tag, should not return a result.
|
|
2052
|
+
var _a, _b, _c;
|
|
2053
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
2054
|
+
// write a record with a true boolean value tag
|
|
2055
|
+
const tagsRecordTrue = yield TestDataGenerator.generateRecordsWrite({
|
|
2056
|
+
author: alice,
|
|
2057
|
+
published: true,
|
|
2058
|
+
schema: 'post',
|
|
2059
|
+
tags: {
|
|
2060
|
+
booleanTag: true,
|
|
2061
|
+
}
|
|
2062
|
+
});
|
|
2063
|
+
const tagsRecordTrueReply = yield dwn.processMessage(alice.did, tagsRecordTrue.message, { dataStream: tagsRecordTrue.dataStream });
|
|
2064
|
+
expect(tagsRecordTrueReply.status.code).to.equal(202);
|
|
2065
|
+
// write a record with a false boolean value tag
|
|
2066
|
+
const tagsRecordFalse = yield TestDataGenerator.generateRecordsWrite({
|
|
2067
|
+
author: alice,
|
|
2068
|
+
published: true,
|
|
2069
|
+
schema: 'post',
|
|
2070
|
+
tags: {
|
|
2071
|
+
booleanTag: false,
|
|
2072
|
+
}
|
|
2073
|
+
});
|
|
2074
|
+
const tagsRecordFalseReply = yield dwn.processMessage(alice.did, tagsRecordFalse.message, { dataStream: tagsRecordFalse.dataStream });
|
|
2075
|
+
expect(tagsRecordFalseReply.status.code).to.equal(202);
|
|
2076
|
+
// query for records with a `booleanTag` set to true, should return the record with the true tag
|
|
2077
|
+
const tagsQueryMatchTrue = yield TestDataGenerator.generateRecordsQuery({
|
|
2078
|
+
author: alice,
|
|
2079
|
+
filter: {
|
|
2080
|
+
tags: {
|
|
2081
|
+
booleanTag: true
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2084
|
+
});
|
|
2085
|
+
const tagsQueryMatchTrueReply = yield dwn.processMessage(alice.did, tagsQueryMatchTrue.message);
|
|
2086
|
+
expect(tagsQueryMatchTrueReply.status.code).to.equal(200);
|
|
2087
|
+
expect((_a = tagsQueryMatchTrueReply.entries) === null || _a === void 0 ? void 0 : _a.length).to.equal(1);
|
|
2088
|
+
expect(tagsQueryMatchTrueReply.entries[0].recordId).to.equal(tagsRecordTrue.message.recordId);
|
|
2089
|
+
// query for records with a `booleanTag` set to false, should return the record with the false tag
|
|
2090
|
+
const tagsQueryMatchFalse = yield TestDataGenerator.generateRecordsQuery({
|
|
2091
|
+
author: alice,
|
|
2092
|
+
filter: {
|
|
2093
|
+
tags: {
|
|
2094
|
+
booleanTag: false
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
});
|
|
2098
|
+
const tagsQueryMatchFalseReply = yield dwn.processMessage(alice.did, tagsQueryMatchFalse.message);
|
|
2099
|
+
expect(tagsQueryMatchFalseReply.status.code).to.equal(200);
|
|
2100
|
+
expect((_b = tagsQueryMatchFalseReply.entries) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
2101
|
+
expect(tagsQueryMatchFalseReply.entries[0].recordId).to.equal(tagsRecordFalse.message.recordId);
|
|
2102
|
+
// negative result for a non existent boolean tag.
|
|
2103
|
+
const tagsQueryNegative = yield TestDataGenerator.generateRecordsQuery({
|
|
2104
|
+
author: alice,
|
|
2105
|
+
filter: {
|
|
2106
|
+
tags: {
|
|
2107
|
+
otherTag: true,
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
});
|
|
2111
|
+
const tagsQueryNegativeReply = yield dwn.processMessage(alice.did, tagsQueryNegative.message);
|
|
2112
|
+
expect(tagsQueryNegativeReply.status.code).to.equal(200);
|
|
2113
|
+
expect((_c = tagsQueryNegativeReply.entries) === null || _c === void 0 ? void 0 : _c.length).to.equal(0);
|
|
2114
|
+
}));
|
|
2115
|
+
it('should be able to range filter by string value', () => __awaiter(this, void 0, void 0, function* () {
|
|
2116
|
+
var _a, _b, _c, _d;
|
|
2117
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
2118
|
+
// create four records with different first names
|
|
2119
|
+
const aliceRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
2120
|
+
author: alice,
|
|
2121
|
+
published: true,
|
|
2122
|
+
schema: 'post',
|
|
2123
|
+
tags: {
|
|
2124
|
+
firstName: 'alice'
|
|
2125
|
+
}
|
|
2126
|
+
});
|
|
2127
|
+
const bobRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
2128
|
+
author: alice,
|
|
2129
|
+
published: true,
|
|
2130
|
+
schema: 'post',
|
|
2131
|
+
tags: {
|
|
2132
|
+
firstName: 'bob',
|
|
2133
|
+
}
|
|
2134
|
+
});
|
|
2135
|
+
const carolRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
2136
|
+
author: alice,
|
|
2137
|
+
published: true,
|
|
2138
|
+
schema: 'post',
|
|
2139
|
+
tags: {
|
|
2140
|
+
firstName: 'carol',
|
|
2141
|
+
}
|
|
2142
|
+
});
|
|
2143
|
+
const danielRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
2144
|
+
author: alice,
|
|
2145
|
+
published: true,
|
|
2146
|
+
schema: 'post',
|
|
2147
|
+
tags: {
|
|
2148
|
+
firstName: 'daniel',
|
|
2149
|
+
}
|
|
2150
|
+
});
|
|
2151
|
+
const aliceReply = yield dwn.processMessage(alice.did, aliceRecord.message, { dataStream: aliceRecord.dataStream });
|
|
2152
|
+
expect(aliceReply.status.code).to.equal(202);
|
|
2153
|
+
const bobReply = yield dwn.processMessage(alice.did, bobRecord.message, { dataStream: bobRecord.dataStream });
|
|
2154
|
+
expect(bobReply.status.code).to.equal(202);
|
|
2155
|
+
const carolReply = yield dwn.processMessage(alice.did, carolRecord.message, { dataStream: carolRecord.dataStream });
|
|
2156
|
+
expect(carolReply.status.code).to.equal(202);
|
|
2157
|
+
const danielReply = yield dwn.processMessage(alice.did, danielRecord.message, { dataStream: danielRecord.dataStream });
|
|
2158
|
+
expect(danielReply.status.code).to.equal(202);
|
|
2159
|
+
// sanity query for all
|
|
2160
|
+
const queryForAll = yield TestDataGenerator.generateRecordsQuery({
|
|
2161
|
+
author: alice,
|
|
2162
|
+
filter: {
|
|
2163
|
+
schema: 'post'
|
|
2164
|
+
}
|
|
2165
|
+
});
|
|
2166
|
+
const queryForAllReply = yield dwn.processMessage(alice.did, queryForAll.message);
|
|
2167
|
+
expect(queryForAllReply.status.code).to.equal(200);
|
|
2168
|
+
expect((_a = queryForAllReply.entries) === null || _a === void 0 ? void 0 : _a.length).to.equal(4); // all 4 records
|
|
2169
|
+
// query for first names that begin with 'a' and 'b'
|
|
2170
|
+
const queryForAtoB = yield TestDataGenerator.generateRecordsQuery({
|
|
2171
|
+
author: alice,
|
|
2172
|
+
filter: {
|
|
2173
|
+
schema: 'post',
|
|
2174
|
+
tags: {
|
|
2175
|
+
firstName: { gte: 'a', lt: 'c' }
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
});
|
|
2179
|
+
const queryForAtoBReply = yield dwn.processMessage(alice.did, queryForAtoB.message);
|
|
2180
|
+
expect(queryForAtoBReply.status.code).to.equal(200);
|
|
2181
|
+
expect((_b = queryForAtoBReply.entries) === null || _b === void 0 ? void 0 : _b.length).to.equal(2);
|
|
2182
|
+
const atobRecordIds = queryForAtoBReply.entries.map(entry => entry.recordId);
|
|
2183
|
+
expect(atobRecordIds).to.have.members([aliceRecord.message.recordId, bobRecord.message.recordId]);
|
|
2184
|
+
// query for first names greater than 'bob'(exclusive of), and less than but inclusive of 'daniel'
|
|
2185
|
+
const queryForBtoD = yield TestDataGenerator.generateRecordsQuery({
|
|
2186
|
+
author: alice,
|
|
2187
|
+
filter: {
|
|
2188
|
+
schema: 'post',
|
|
2189
|
+
tags: {
|
|
2190
|
+
firstName: { gt: 'bob', lte: 'daniel' }
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
});
|
|
2194
|
+
const queryForBtoDReply = yield dwn.processMessage(alice.did, queryForBtoD.message);
|
|
2195
|
+
expect(queryForBtoDReply.status.code).to.equal(200);
|
|
2196
|
+
expect((_c = queryForBtoDReply.entries) === null || _c === void 0 ? void 0 : _c.length).to.equal(2);
|
|
2197
|
+
const btodRecordIds = queryForBtoDReply.entries.map(entry => entry.recordId);
|
|
2198
|
+
expect(btodRecordIds).to.have.members([carolRecord.message.recordId, danielRecord.message.recordId]);
|
|
2199
|
+
// query for first names that begin with 'carol' onward (inclusive).
|
|
2200
|
+
const queryForCarolOnward = yield TestDataGenerator.generateRecordsQuery({
|
|
2201
|
+
author: alice,
|
|
2202
|
+
filter: {
|
|
2203
|
+
schema: 'post',
|
|
2204
|
+
tags: {
|
|
2205
|
+
firstName: { gte: 'carol' }
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
});
|
|
2209
|
+
const queryForCarolOnwardReply = yield dwn.processMessage(alice.did, queryForCarolOnward.message);
|
|
2210
|
+
expect(queryForCarolOnwardReply.status.code).to.equal(200);
|
|
2211
|
+
expect((_d = queryForCarolOnwardReply.entries) === null || _d === void 0 ? void 0 : _d.length).to.equal(2);
|
|
2212
|
+
const onwardResults = queryForCarolOnwardReply.entries.map(entry => entry.recordId);
|
|
2213
|
+
expect(onwardResults).to.have.members([carolRecord.message.recordId, danielRecord.message.recordId]);
|
|
2214
|
+
}));
|
|
2215
|
+
it('should be able to filter by string prefix', () => __awaiter(this, void 0, void 0, function* () {
|
|
2216
|
+
var _a, _b;
|
|
2217
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
2218
|
+
// create two records that match the prefix 'string-'
|
|
2219
|
+
const tagsRecord1 = yield TestDataGenerator.generateRecordsWrite({
|
|
2220
|
+
author: alice,
|
|
2221
|
+
published: true,
|
|
2222
|
+
schema: 'post',
|
|
2223
|
+
tags: {
|
|
2224
|
+
stringTag: 'string-foo',
|
|
2225
|
+
}
|
|
2226
|
+
});
|
|
2227
|
+
const tagsRecord2 = yield TestDataGenerator.generateRecordsWrite({
|
|
2228
|
+
author: alice,
|
|
2229
|
+
published: true,
|
|
2230
|
+
schema: 'post',
|
|
2231
|
+
tags: {
|
|
2232
|
+
stringTag: 'string-bar',
|
|
2233
|
+
}
|
|
2234
|
+
});
|
|
2235
|
+
const tagsRecord1Reply = yield dwn.processMessage(alice.did, tagsRecord1.message, { dataStream: tagsRecord1.dataStream });
|
|
2236
|
+
expect(tagsRecord1Reply.status.code).to.equal(202);
|
|
2237
|
+
const tagsRecord2Reply = yield dwn.processMessage(alice.did, tagsRecord2.message, { dataStream: tagsRecord2.dataStream });
|
|
2238
|
+
expect(tagsRecord2Reply.status.code).to.equal(202);
|
|
2239
|
+
// control record that has a different prefix
|
|
2240
|
+
const tagsRecord3 = yield TestDataGenerator.generateRecordsWrite({
|
|
2241
|
+
author: alice,
|
|
2242
|
+
published: true,
|
|
2243
|
+
schema: 'post',
|
|
2244
|
+
tags: {
|
|
2245
|
+
stringTag: 'zaz-string', // comes after `string-` lexicographically
|
|
2246
|
+
}
|
|
2247
|
+
});
|
|
2248
|
+
const tagsRecord3Reply = yield dwn.processMessage(alice.did, tagsRecord3.message, { dataStream: tagsRecord3.dataStream });
|
|
2249
|
+
expect(tagsRecord3Reply.status.code).to.equal(202);
|
|
2250
|
+
// a prefix search will return only the records matching the prefix
|
|
2251
|
+
const tagsQueryMatch = yield TestDataGenerator.generateRecordsQuery({
|
|
2252
|
+
author: alice,
|
|
2253
|
+
filter: {
|
|
2254
|
+
tags: {
|
|
2255
|
+
stringTag: { startsWith: 'string-' }
|
|
2256
|
+
}
|
|
2257
|
+
}
|
|
2258
|
+
});
|
|
2259
|
+
const tagsQueryMatchReply = yield dwn.processMessage(alice.did, tagsQueryMatch.message);
|
|
2260
|
+
expect(tagsQueryMatchReply.status.code).to.equal(200);
|
|
2261
|
+
expect((_a = tagsQueryMatchReply.entries) === null || _a === void 0 ? void 0 : _a.length).to.equal(2);
|
|
2262
|
+
const matchedRecords = tagsQueryMatchReply.entries.map(entry => entry.recordId);
|
|
2263
|
+
expect(matchedRecords).to.have.members([tagsRecord1.message.recordId, tagsRecord2.message.recordId]);
|
|
2264
|
+
// sanity/control: a regular range query will return all
|
|
2265
|
+
// since `zaz-string` comes lexicographically after `string-` it will appear in the result set
|
|
2266
|
+
const tagsQueryRange = yield TestDataGenerator.generateRecordsQuery({
|
|
2267
|
+
author: alice,
|
|
2268
|
+
filter: {
|
|
2269
|
+
tags: {
|
|
2270
|
+
stringTag: { gte: 'string-' } // range query instead of prefix
|
|
2271
|
+
}
|
|
2272
|
+
}
|
|
2273
|
+
});
|
|
2274
|
+
const tagsQueryRangeReply = yield dwn.processMessage(alice.did, tagsQueryRange.message);
|
|
2275
|
+
expect(tagsQueryRangeReply.status.code).to.equal(200);
|
|
2276
|
+
expect((_b = tagsQueryRangeReply.entries) === null || _b === void 0 ? void 0 : _b.length).to.equal(3); // returned all 3 records
|
|
2277
|
+
}));
|
|
2278
|
+
it('should be able to range filter by number value', () => __awaiter(this, void 0, void 0, function* () {
|
|
2279
|
+
var _a, _b, _c, _d, _e;
|
|
2280
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
2281
|
+
// create four records with different test scores
|
|
2282
|
+
const aliceRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
2283
|
+
author: alice,
|
|
2284
|
+
published: true,
|
|
2285
|
+
schema: 'test',
|
|
2286
|
+
tags: {
|
|
2287
|
+
firstName: 'alice',
|
|
2288
|
+
score: 75,
|
|
2289
|
+
}
|
|
2290
|
+
});
|
|
2291
|
+
const bobRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
2292
|
+
author: alice,
|
|
2293
|
+
published: true,
|
|
2294
|
+
schema: 'test',
|
|
2295
|
+
tags: {
|
|
2296
|
+
firstName: 'bob',
|
|
2297
|
+
score: 80,
|
|
2298
|
+
}
|
|
2299
|
+
});
|
|
2300
|
+
const carolRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
2301
|
+
author: alice,
|
|
2302
|
+
published: true,
|
|
2303
|
+
schema: 'test',
|
|
2304
|
+
tags: {
|
|
2305
|
+
firstName: 'carol',
|
|
2306
|
+
score: 65,
|
|
2307
|
+
}
|
|
2308
|
+
});
|
|
2309
|
+
const danielRecord = yield TestDataGenerator.generateRecordsWrite({
|
|
2310
|
+
author: alice,
|
|
2311
|
+
published: true,
|
|
2312
|
+
schema: 'test',
|
|
2313
|
+
tags: {
|
|
2314
|
+
firstName: 'daniel',
|
|
2315
|
+
score: 100,
|
|
2316
|
+
}
|
|
2317
|
+
});
|
|
2318
|
+
const aliceReply = yield dwn.processMessage(alice.did, aliceRecord.message, { dataStream: aliceRecord.dataStream });
|
|
2319
|
+
expect(aliceReply.status.code).to.equal(202);
|
|
2320
|
+
const bobReply = yield dwn.processMessage(alice.did, bobRecord.message, { dataStream: bobRecord.dataStream });
|
|
2321
|
+
expect(bobReply.status.code).to.equal(202);
|
|
2322
|
+
const carolReply = yield dwn.processMessage(alice.did, carolRecord.message, { dataStream: carolRecord.dataStream });
|
|
2323
|
+
expect(carolReply.status.code).to.equal(202);
|
|
2324
|
+
const danielReply = yield dwn.processMessage(alice.did, danielRecord.message, { dataStream: danielRecord.dataStream });
|
|
2325
|
+
expect(danielReply.status.code).to.equal(202);
|
|
2326
|
+
// sanity query for all
|
|
2327
|
+
const queryForAll = yield TestDataGenerator.generateRecordsQuery({
|
|
2328
|
+
author: alice,
|
|
2329
|
+
filter: {
|
|
2330
|
+
schema: 'test'
|
|
2331
|
+
}
|
|
2332
|
+
});
|
|
2333
|
+
const queryForAllReply = yield dwn.processMessage(alice.did, queryForAll.message);
|
|
2334
|
+
expect(queryForAllReply.status.code).to.equal(200);
|
|
2335
|
+
expect((_a = queryForAllReply.entries) === null || _a === void 0 ? void 0 : _a.length).to.equal(4); // all 4 records
|
|
2336
|
+
// query for all records that received higher than(not including) an 80
|
|
2337
|
+
// only one record should match
|
|
2338
|
+
const queryForHighGrade = yield TestDataGenerator.generateRecordsQuery({
|
|
2339
|
+
author: alice,
|
|
2340
|
+
filter: {
|
|
2341
|
+
schema: 'test',
|
|
2342
|
+
tags: {
|
|
2343
|
+
score: { gt: 80 }
|
|
2344
|
+
}
|
|
2345
|
+
}
|
|
2346
|
+
});
|
|
2347
|
+
const queryForHighReply = yield dwn.processMessage(alice.did, queryForHighGrade.message);
|
|
2348
|
+
expect(queryForHighReply.status.code).to.equal(200);
|
|
2349
|
+
expect((_b = queryForHighReply.entries) === null || _b === void 0 ? void 0 : _b.length).to.equal(1);
|
|
2350
|
+
expect(queryForHighReply.entries[0].recordId).to.equal(danielRecord.message.recordId);
|
|
2351
|
+
// query for all records that received higher (and including) a 75
|
|
2352
|
+
// three records should match
|
|
2353
|
+
const queryForPassingGrade = yield TestDataGenerator.generateRecordsQuery({
|
|
2354
|
+
author: alice,
|
|
2355
|
+
filter: {
|
|
2356
|
+
schema: 'test',
|
|
2357
|
+
tags: {
|
|
2358
|
+
score: { gte: 75 }
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
});
|
|
2362
|
+
const queryForPassingGradeReply = yield dwn.processMessage(alice.did, queryForPassingGrade.message);
|
|
2363
|
+
expect(queryForPassingGradeReply.status.code).to.equal(200);
|
|
2364
|
+
expect((_c = queryForPassingGradeReply.entries) === null || _c === void 0 ? void 0 : _c.length).to.equal(3);
|
|
2365
|
+
const passingRecords = queryForPassingGradeReply.entries.map(entry => entry.recordId);
|
|
2366
|
+
expect(passingRecords).to.have.members([danielRecord.message.recordId, bobRecord.message.recordId, aliceRecord.message.recordId]);
|
|
2367
|
+
// query for poorly performing grades (65 and below, inclusive)
|
|
2368
|
+
const queryForPoorGrades = yield TestDataGenerator.generateRecordsQuery({
|
|
2369
|
+
author: alice,
|
|
2370
|
+
filter: {
|
|
2371
|
+
schema: 'test',
|
|
2372
|
+
tags: {
|
|
2373
|
+
score: { lte: 65 }
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
});
|
|
2377
|
+
const queryForPoorGradesReply = yield dwn.processMessage(alice.did, queryForPoorGrades.message);
|
|
2378
|
+
expect(queryForPoorGradesReply.status.code).to.equal(200);
|
|
2379
|
+
expect((_d = queryForPoorGradesReply.entries) === null || _d === void 0 ? void 0 : _d.length).to.equal(1);
|
|
2380
|
+
expect(queryForPoorGradesReply.entries[0].recordId).to.equal(carolRecord.message.recordId);
|
|
2381
|
+
// query for passing grades that were not perfect scores
|
|
2382
|
+
const queryForRange = yield TestDataGenerator.generateRecordsQuery({
|
|
2383
|
+
author: alice,
|
|
2384
|
+
filter: {
|
|
2385
|
+
schema: 'test',
|
|
2386
|
+
tags: {
|
|
2387
|
+
score: { lt: 100, gte: 75 }
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
});
|
|
2391
|
+
const queryForRangeReply = yield dwn.processMessage(alice.did, queryForRange.message);
|
|
2392
|
+
expect(queryForRangeReply.status.code).to.equal(200);
|
|
2393
|
+
expect((_e = queryForRangeReply.entries) === null || _e === void 0 ? void 0 : _e.length).to.equal(2);
|
|
2394
|
+
const rangeRecords = queryForRangeReply.entries.map(entry => entry.recordId);
|
|
2395
|
+
expect(rangeRecords).to.have.members([bobRecord.message.recordId, aliceRecord.message.recordId]);
|
|
2396
|
+
}));
|
|
2397
|
+
it('should return results based on the latest tag values', () => __awaiter(this, void 0, void 0, function* () {
|
|
2398
|
+
var _a, _b;
|
|
2399
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
2400
|
+
const tagsRecord1 = yield TestDataGenerator.generateRecordsWrite({
|
|
2401
|
+
author: alice,
|
|
2402
|
+
published: true,
|
|
2403
|
+
schema: 'post',
|
|
2404
|
+
tags: {
|
|
2405
|
+
stringTag: 'string-value',
|
|
2406
|
+
}
|
|
2407
|
+
});
|
|
2408
|
+
const tagsRecord1Reply = yield dwn.processMessage(alice.did, tagsRecord1.message, { dataStream: tagsRecord1.dataStream });
|
|
2409
|
+
expect(tagsRecord1Reply.status.code).to.equal(202);
|
|
2410
|
+
const tagsQueryMatch = yield TestDataGenerator.generateRecordsQuery({
|
|
2411
|
+
author: alice,
|
|
2412
|
+
filter: {
|
|
2413
|
+
tags: {
|
|
2414
|
+
stringTag: 'string-value'
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
});
|
|
2418
|
+
const tagsQueryMatchReply = yield dwn.processMessage(alice.did, tagsQueryMatch.message);
|
|
2419
|
+
expect(tagsQueryMatchReply.status.code).to.equal(200);
|
|
2420
|
+
expect((_a = tagsQueryMatchReply.entries) === null || _a === void 0 ? void 0 : _a.length).to.equal(1);
|
|
2421
|
+
expect(tagsQueryMatchReply.entries[0].recordId).to.equal(tagsRecord1.message.recordId);
|
|
2422
|
+
// update the record with new tags
|
|
2423
|
+
const updatedRecord = yield TestDataGenerator.generateFromRecordsWrite({
|
|
2424
|
+
author: alice,
|
|
2425
|
+
existingWrite: tagsRecord1.recordsWrite,
|
|
2426
|
+
tags: { otherTag: 'other-value' } // new tags
|
|
2427
|
+
});
|
|
2428
|
+
const updatedRecordReply = yield dwn.processMessage(alice.did, updatedRecord.message, { dataStream: updatedRecord.dataStream });
|
|
2429
|
+
expect(updatedRecordReply.status.code).to.equal(202);
|
|
2430
|
+
// issuing the same query should return no results
|
|
2431
|
+
const tagsQueryMatchReply2 = yield dwn.processMessage(alice.did, tagsQueryMatch.message);
|
|
2432
|
+
expect(tagsQueryMatchReply2.status.code).to.equal(200);
|
|
2433
|
+
expect((_b = tagsQueryMatchReply2.entries) === null || _b === void 0 ? void 0 : _b.length).to.equal(0);
|
|
2434
|
+
}));
|
|
2435
|
+
it('should not return results if the record was updated with empty tags', () => __awaiter(this, void 0, void 0, function* () {
|
|
2436
|
+
var _a, _b;
|
|
2437
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
2438
|
+
const tagsRecord1 = yield TestDataGenerator.generateRecordsWrite({
|
|
2439
|
+
author: alice,
|
|
2440
|
+
published: true,
|
|
2441
|
+
schema: 'post',
|
|
2442
|
+
tags: {
|
|
2443
|
+
stringTag: 'string-value',
|
|
2444
|
+
}
|
|
2445
|
+
});
|
|
2446
|
+
const tagsRecord1Reply = yield dwn.processMessage(alice.did, tagsRecord1.message, { dataStream: tagsRecord1.dataStream });
|
|
2447
|
+
expect(tagsRecord1Reply.status.code).to.equal(202);
|
|
2448
|
+
const tagsQueryMatch = yield TestDataGenerator.generateRecordsQuery({
|
|
2449
|
+
author: alice,
|
|
2450
|
+
filter: {
|
|
2451
|
+
tags: {
|
|
2452
|
+
stringTag: 'string-value'
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
});
|
|
2456
|
+
const tagsQueryMatchReply = yield dwn.processMessage(alice.did, tagsQueryMatch.message);
|
|
2457
|
+
expect(tagsQueryMatchReply.status.code).to.equal(200);
|
|
2458
|
+
expect((_a = tagsQueryMatchReply.entries) === null || _a === void 0 ? void 0 : _a.length).to.equal(1);
|
|
2459
|
+
expect(tagsQueryMatchReply.entries[0].recordId).to.equal(tagsRecord1.message.recordId);
|
|
2460
|
+
// update the record without any tags
|
|
2461
|
+
const updatedRecord = yield TestDataGenerator.generateFromRecordsWrite({
|
|
2462
|
+
author: alice,
|
|
2463
|
+
existingWrite: tagsRecord1.recordsWrite,
|
|
2464
|
+
});
|
|
2465
|
+
const updatedRecordReply = yield dwn.processMessage(alice.did, updatedRecord.message, { dataStream: updatedRecord.dataStream });
|
|
2466
|
+
expect(updatedRecordReply.status.code).to.equal(202);
|
|
2467
|
+
// issuing the same query should return no results
|
|
2468
|
+
const tagsQueryMatchReply2 = yield dwn.processMessage(alice.did, tagsQueryMatch.message);
|
|
2469
|
+
expect(tagsQueryMatchReply2.status.code).to.equal(200);
|
|
2470
|
+
expect((_b = tagsQueryMatchReply2.entries) === null || _b === void 0 ? void 0 : _b.length).to.equal(0);
|
|
2471
|
+
}));
|
|
2472
|
+
});
|
|
2473
|
+
describe('RecordsDelete with tags', () => {
|
|
2474
|
+
it('should delete record with tags', () => __awaiter(this, void 0, void 0, function* () {
|
|
2475
|
+
var _a, _b;
|
|
2476
|
+
const alice = yield TestDataGenerator.generateDidKeyPersona();
|
|
2477
|
+
// create a record with a tag
|
|
2478
|
+
const tagsRecord1 = yield TestDataGenerator.generateRecordsWrite({
|
|
2479
|
+
author: alice,
|
|
2480
|
+
published: true,
|
|
2481
|
+
schema: 'post',
|
|
2482
|
+
tags: {
|
|
2483
|
+
stringTag: 'string-value',
|
|
2484
|
+
}
|
|
2485
|
+
});
|
|
2486
|
+
const tagsRecord1Reply = yield dwn.processMessage(alice.did, tagsRecord1.message, { dataStream: tagsRecord1.dataStream });
|
|
2487
|
+
expect(tagsRecord1Reply.status.code).to.equal(202);
|
|
2488
|
+
//sanity: query for the record
|
|
2489
|
+
const tagsQueryMatch = yield TestDataGenerator.generateRecordsQuery({
|
|
2490
|
+
author: alice,
|
|
2491
|
+
filter: {
|
|
2492
|
+
tags: {
|
|
2493
|
+
stringTag: 'string-value'
|
|
2494
|
+
}
|
|
2495
|
+
}
|
|
2496
|
+
});
|
|
2497
|
+
const tagsQueryMatchReply = yield dwn.processMessage(alice.did, tagsQueryMatch.message);
|
|
2498
|
+
expect(tagsQueryMatchReply.status.code).to.equal(200);
|
|
2499
|
+
expect((_a = tagsQueryMatchReply.entries) === null || _a === void 0 ? void 0 : _a.length).to.equal(1);
|
|
2500
|
+
expect(tagsQueryMatchReply.entries[0].recordId).to.equal(tagsRecord1.message.recordId);
|
|
2501
|
+
// delete the record
|
|
2502
|
+
const recordDelete = yield TestDataGenerator.generateRecordsDelete({
|
|
2503
|
+
author: alice,
|
|
2504
|
+
recordId: tagsRecord1.message.recordId,
|
|
2505
|
+
});
|
|
2506
|
+
const recordDeleteReply = yield dwn.processMessage(alice.did, recordDelete.message);
|
|
2507
|
+
expect(recordDeleteReply.status.code).to.equal(202);
|
|
2508
|
+
// issue the the same query should return no results
|
|
2509
|
+
const tagsQueryMatchReply2 = yield dwn.processMessage(alice.did, tagsQueryMatch.message);
|
|
2510
|
+
expect(tagsQueryMatchReply2.status.code).to.equal(200);
|
|
2511
|
+
expect((_b = tagsQueryMatchReply2.entries) === null || _b === void 0 ? void 0 : _b.length).to.equal(0);
|
|
2512
|
+
}));
|
|
2513
|
+
});
|
|
2514
|
+
});
|
|
2515
|
+
}
|
|
2516
|
+
//# sourceMappingURL=records-tags.spec.js.map
|