@sempdev/semp 0.4.3
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 +21 -0
- package/README.md +59 -0
- package/dist/brief/address.d.ts +77 -0
- package/dist/brief/address.d.ts.map +1 -0
- package/dist/brief/address.js +217 -0
- package/dist/brief/address.js.map +1 -0
- package/dist/brief/brief.d.ts +75 -0
- package/dist/brief/brief.d.ts.map +1 -0
- package/dist/brief/brief.js +56 -0
- package/dist/brief/brief.js.map +1 -0
- package/dist/brief/index.d.ts +11 -0
- package/dist/brief/index.d.ts.map +1 -0
- package/dist/brief/index.js +11 -0
- package/dist/brief/index.js.map +1 -0
- package/dist/canonical/index.d.ts +8 -0
- package/dist/canonical/index.d.ts.map +1 -0
- package/dist/canonical/index.js +8 -0
- package/dist/canonical/index.js.map +1 -0
- package/dist/canonical/marshal.d.ts +35 -0
- package/dist/canonical/marshal.d.ts.map +1 -0
- package/dist/canonical/marshal.js +107 -0
- package/dist/canonical/marshal.js.map +1 -0
- package/dist/clockskew/index.d.ts +52 -0
- package/dist/clockskew/index.d.ts.map +1 -0
- package/dist/clockskew/index.js +62 -0
- package/dist/clockskew/index.js.map +1 -0
- package/dist/closure/closure.d.ts +106 -0
- package/dist/closure/closure.d.ts.map +1 -0
- package/dist/closure/closure.js +152 -0
- package/dist/closure/closure.js.map +1 -0
- package/dist/closure/driver.d.ts +103 -0
- package/dist/closure/driver.d.ts.map +1 -0
- package/dist/closure/driver.js +126 -0
- package/dist/closure/driver.js.map +1 -0
- package/dist/closure/index.d.ts +13 -0
- package/dist/closure/index.d.ts.map +1 -0
- package/dist/closure/index.js +13 -0
- package/dist/closure/index.js.map +1 -0
- package/dist/closure/store.d.ts +80 -0
- package/dist/closure/store.d.ts.map +1 -0
- package/dist/closure/store.js +89 -0
- package/dist/closure/store.js.map +1 -0
- package/dist/crypto/aead.d.ts +29 -0
- package/dist/crypto/aead.d.ts.map +1 -0
- package/dist/crypto/aead.js +48 -0
- package/dist/crypto/aead.js.map +1 -0
- package/dist/crypto/argon2.d.ts +20 -0
- package/dist/crypto/argon2.d.ts.map +1 -0
- package/dist/crypto/argon2.js +28 -0
- package/dist/crypto/argon2.js.map +1 -0
- package/dist/crypto/index.d.ts +14 -0
- package/dist/crypto/index.d.ts.map +1 -0
- package/dist/crypto/index.js +14 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/kdf.d.ts +96 -0
- package/dist/crypto/kdf.d.ts.map +1 -0
- package/dist/crypto/kdf.js +122 -0
- package/dist/crypto/kdf.js.map +1 -0
- package/dist/crypto/kem.d.ts +85 -0
- package/dist/crypto/kem.d.ts.map +1 -0
- package/dist/crypto/kem.js +130 -0
- package/dist/crypto/kem.js.map +1 -0
- package/dist/crypto/mac.d.ts +19 -0
- package/dist/crypto/mac.d.ts.map +1 -0
- package/dist/crypto/mac.js +32 -0
- package/dist/crypto/mac.js.map +1 -0
- package/dist/delivery/ack.d.ts +125 -0
- package/dist/delivery/ack.d.ts.map +1 -0
- package/dist/delivery/ack.js +141 -0
- package/dist/delivery/ack.js.map +1 -0
- package/dist/delivery/blocklist.d.ts +87 -0
- package/dist/delivery/blocklist.d.ts.map +1 -0
- package/dist/delivery/blocklist.js +107 -0
- package/dist/delivery/blocklist.js.map +1 -0
- package/dist/delivery/cancel.d.ts +60 -0
- package/dist/delivery/cancel.d.ts.map +1 -0
- package/dist/delivery/cancel.js +43 -0
- package/dist/delivery/cancel.js.map +1 -0
- package/dist/delivery/disposition.d.ts +106 -0
- package/dist/delivery/disposition.d.ts.map +1 -0
- package/dist/delivery/disposition.js +105 -0
- package/dist/delivery/disposition.js.map +1 -0
- package/dist/delivery/fetch.d.ts +59 -0
- package/dist/delivery/fetch.d.ts.map +1 -0
- package/dist/delivery/fetch.js +47 -0
- package/dist/delivery/fetch.js.map +1 -0
- package/dist/delivery/forwarder.d.ts +106 -0
- package/dist/delivery/forwarder.d.ts.map +1 -0
- package/dist/delivery/forwarder.js +251 -0
- package/dist/delivery/forwarder.js.map +1 -0
- package/dist/delivery/inbox.d.ts +42 -0
- package/dist/delivery/inbox.d.ts.map +1 -0
- package/dist/delivery/inbox.js +68 -0
- package/dist/delivery/inbox.js.map +1 -0
- package/dist/delivery/index.d.ts +31 -0
- package/dist/delivery/index.d.ts.map +1 -0
- package/dist/delivery/index.js +31 -0
- package/dist/delivery/index.js.map +1 -0
- package/dist/delivery/internalroute.d.ts +50 -0
- package/dist/delivery/internalroute.d.ts.map +1 -0
- package/dist/delivery/internalroute.js +23 -0
- package/dist/delivery/internalroute.js.map +1 -0
- package/dist/delivery/pipeline.d.ts +153 -0
- package/dist/delivery/pipeline.d.ts.map +1 -0
- package/dist/delivery/pipeline.js +356 -0
- package/dist/delivery/pipeline.js.map +1 -0
- package/dist/delivery/policy_state.d.ts +105 -0
- package/dist/delivery/policy_state.d.ts.map +1 -0
- package/dist/delivery/policy_state.js +293 -0
- package/dist/delivery/policy_state.js.map +1 -0
- package/dist/delivery/queue.d.ts +47 -0
- package/dist/delivery/queue.d.ts.map +1 -0
- package/dist/delivery/queue.js +33 -0
- package/dist/delivery/queue.js.map +1 -0
- package/dist/delivery/receipt.d.ts +137 -0
- package/dist/delivery/receipt.d.ts.map +1 -0
- package/dist/delivery/receipt.js +181 -0
- package/dist/delivery/receipt.js.map +1 -0
- package/dist/delivery/receipt_store.d.ts +81 -0
- package/dist/delivery/receipt_store.d.ts.map +1 -0
- package/dist/delivery/receipt_store.js +74 -0
- package/dist/delivery/receipt_store.js.map +1 -0
- package/dist/delivery/retry.d.ts +78 -0
- package/dist/delivery/retry.d.ts.map +1 -0
- package/dist/delivery/retry.js +132 -0
- package/dist/delivery/retry.js.map +1 -0
- package/dist/delivery/scheduler.d.ts +156 -0
- package/dist/delivery/scheduler.d.ts.map +1 -0
- package/dist/delivery/scheduler.js +349 -0
- package/dist/delivery/scheduler.js.map +1 -0
- package/dist/delivery/stage_partition.d.ts +87 -0
- package/dist/delivery/stage_partition.d.ts.map +1 -0
- package/dist/delivery/stage_partition.js +122 -0
- package/dist/delivery/stage_partition.js.map +1 -0
- package/dist/delivery/staged_runner.d.ts +100 -0
- package/dist/delivery/staged_runner.d.ts.map +1 -0
- package/dist/delivery/staged_runner.js +277 -0
- package/dist/delivery/staged_runner.js.map +1 -0
- package/dist/delivery/submission.d.ts +72 -0
- package/dist/delivery/submission.d.ts.map +1 -0
- package/dist/delivery/submission.js +58 -0
- package/dist/delivery/submission.js.map +1 -0
- package/dist/delivery/sync.d.ts +68 -0
- package/dist/delivery/sync.d.ts.map +1 -0
- package/dist/delivery/sync.js +99 -0
- package/dist/delivery/sync.js.map +1 -0
- package/dist/delivery/user_policy.d.ts +74 -0
- package/dist/delivery/user_policy.d.ts.map +1 -0
- package/dist/delivery/user_policy.js +140 -0
- package/dist/delivery/user_policy.js.map +1 -0
- package/dist/discovery/cache.d.ts +37 -0
- package/dist/discovery/cache.d.ts.map +1 -0
- package/dist/discovery/cache.js +45 -0
- package/dist/discovery/cache.js.map +1 -0
- package/dist/discovery/configuration.d.ts +97 -0
- package/dist/discovery/configuration.d.ts.map +1 -0
- package/dist/discovery/configuration.js +146 -0
- package/dist/discovery/configuration.js.map +1 -0
- package/dist/discovery/dns.d.ts +56 -0
- package/dist/discovery/dns.d.ts.map +1 -0
- package/dist/discovery/dns.js +120 -0
- package/dist/discovery/dns.js.map +1 -0
- package/dist/discovery/domain_keys.d.ts +62 -0
- package/dist/discovery/domain_keys.d.ts.map +1 -0
- package/dist/discovery/domain_keys.js +89 -0
- package/dist/discovery/domain_keys.js.map +1 -0
- package/dist/discovery/index.d.ts +19 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +19 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/lookup.d.ts +72 -0
- package/dist/discovery/lookup.d.ts.map +1 -0
- package/dist/discovery/lookup.js +121 -0
- package/dist/discovery/lookup.js.map +1 -0
- package/dist/discovery/onion.d.ts +34 -0
- package/dist/discovery/onion.d.ts.map +1 -0
- package/dist/discovery/onion.js +61 -0
- package/dist/discovery/onion.js.map +1 -0
- package/dist/discovery/partition.d.ts +96 -0
- package/dist/discovery/partition.d.ts.map +1 -0
- package/dist/discovery/partition.js +247 -0
- package/dist/discovery/partition.js.map +1 -0
- package/dist/discovery/resolver.d.ts +113 -0
- package/dist/discovery/resolver.d.ts.map +1 -0
- package/dist/discovery/resolver.js +176 -0
- package/dist/discovery/resolver.js.map +1 -0
- package/dist/discovery/txt.d.ts +39 -0
- package/dist/discovery/txt.d.ts.map +1 -0
- package/dist/discovery/txt.js +71 -0
- package/dist/discovery/txt.js.map +1 -0
- package/dist/enclosure/forwarding.d.ts +128 -0
- package/dist/enclosure/forwarding.d.ts.map +1 -0
- package/dist/enclosure/forwarding.js +119 -0
- package/dist/enclosure/forwarding.js.map +1 -0
- package/dist/enclosure/index.d.ts +11 -0
- package/dist/enclosure/index.d.ts.map +1 -0
- package/dist/enclosure/index.js +11 -0
- package/dist/enclosure/index.js.map +1 -0
- package/dist/envelope/buckets.d.ts +38 -0
- package/dist/envelope/buckets.d.ts.map +1 -0
- package/dist/envelope/buckets.js +73 -0
- package/dist/envelope/buckets.js.map +1 -0
- package/dist/envelope/canonical.d.ts +28 -0
- package/dist/envelope/canonical.d.ts.map +1 -0
- package/dist/envelope/canonical.js +54 -0
- package/dist/envelope/canonical.js.map +1 -0
- package/dist/envelope/compose.d.ts +171 -0
- package/dist/envelope/compose.d.ts.map +1 -0
- package/dist/envelope/compose.js +237 -0
- package/dist/envelope/compose.js.map +1 -0
- package/dist/envelope/encode.d.ts +41 -0
- package/dist/envelope/encode.d.ts.map +1 -0
- package/dist/envelope/encode.js +69 -0
- package/dist/envelope/encode.js.map +1 -0
- package/dist/envelope/index.d.ts +20 -0
- package/dist/envelope/index.d.ts.map +1 -0
- package/dist/envelope/index.js +20 -0
- package/dist/envelope/index.js.map +1 -0
- package/dist/envelope/open_any.d.ts +48 -0
- package/dist/envelope/open_any.d.ts.map +1 -0
- package/dist/envelope/open_any.js +81 -0
- package/dist/envelope/open_any.js.map +1 -0
- package/dist/envelope/open_verified.d.ts +59 -0
- package/dist/envelope/open_verified.d.ts.map +1 -0
- package/dist/envelope/open_verified.js +67 -0
- package/dist/envelope/open_verified.js.map +1 -0
- package/dist/envelope/padding.d.ts +55 -0
- package/dist/envelope/padding.d.ts.map +1 -0
- package/dist/envelope/padding.js +162 -0
- package/dist/envelope/padding.js.map +1 -0
- package/dist/envelope/rejection.d.ts +22 -0
- package/dist/envelope/rejection.d.ts.map +1 -0
- package/dist/envelope/rejection.js +30 -0
- package/dist/envelope/rejection.js.map +1 -0
- package/dist/envelope/sendtime.d.ts +49 -0
- package/dist/envelope/sendtime.d.ts.map +1 -0
- package/dist/envelope/sendtime.js +87 -0
- package/dist/envelope/sendtime.js.map +1 -0
- package/dist/envelope/verify.d.ts +29 -0
- package/dist/envelope/verify.d.ts.map +1 -0
- package/dist/envelope/verify.js +90 -0
- package/dist/envelope/verify.js.map +1 -0
- package/dist/extensions/index.d.ts +7 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +7 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/limits.d.ts +101 -0
- package/dist/extensions/limits.d.ts.map +1 -0
- package/dist/extensions/limits.js +175 -0
- package/dist/extensions/limits.js.map +1 -0
- package/dist/handshake/abort.d.ts +49 -0
- package/dist/handshake/abort.d.ts.map +1 -0
- package/dist/handshake/abort.js +82 -0
- package/dist/handshake/abort.js.map +1 -0
- package/dist/handshake/capabilities.d.ts +46 -0
- package/dist/handshake/capabilities.d.ts.map +1 -0
- package/dist/handshake/capabilities.js +114 -0
- package/dist/handshake/capabilities.js.map +1 -0
- package/dist/handshake/client_state.d.ts +186 -0
- package/dist/handshake/client_state.d.ts.map +1 -0
- package/dist/handshake/client_state.js +520 -0
- package/dist/handshake/client_state.js.map +1 -0
- package/dist/handshake/confirm.d.ts +21 -0
- package/dist/handshake/confirm.d.ts.map +1 -0
- package/dist/handshake/confirm.js +27 -0
- package/dist/handshake/confirm.js.map +1 -0
- package/dist/handshake/driver.d.ts +126 -0
- package/dist/handshake/driver.d.ts.map +1 -0
- package/dist/handshake/driver.js +251 -0
- package/dist/handshake/driver.js.map +1 -0
- package/dist/handshake/federation.d.ts +365 -0
- package/dist/handshake/federation.d.ts.map +1 -0
- package/dist/handshake/federation.js +664 -0
- package/dist/handshake/federation.js.map +1 -0
- package/dist/handshake/first_contact.d.ts +57 -0
- package/dist/handshake/first_contact.d.ts.map +1 -0
- package/dist/handshake/first_contact.js +124 -0
- package/dist/handshake/first_contact.js.map +1 -0
- package/dist/handshake/identity.d.ts +101 -0
- package/dist/handshake/identity.d.ts.map +1 -0
- package/dist/handshake/identity.js +117 -0
- package/dist/handshake/identity.js.map +1 -0
- package/dist/handshake/index.d.ts +21 -0
- package/dist/handshake/index.d.ts.map +1 -0
- package/dist/handshake/index.js +21 -0
- package/dist/handshake/index.js.map +1 -0
- package/dist/handshake/messages.d.ts +176 -0
- package/dist/handshake/messages.d.ts.map +1 -0
- package/dist/handshake/messages.js +125 -0
- package/dist/handshake/messages.js.map +1 -0
- package/dist/handshake/pow.d.ts +53 -0
- package/dist/handshake/pow.d.ts.map +1 -0
- package/dist/handshake/pow.js +142 -0
- package/dist/handshake/pow.js.map +1 -0
- package/dist/handshake/resume_driver.d.ts +56 -0
- package/dist/handshake/resume_driver.d.ts.map +1 -0
- package/dist/handshake/resume_driver.js +75 -0
- package/dist/handshake/resume_driver.js.map +1 -0
- package/dist/handshake/server.d.ts +112 -0
- package/dist/handshake/server.d.ts.map +1 -0
- package/dist/handshake/server.js +247 -0
- package/dist/handshake/server.js.map +1 -0
- package/dist/handshake/server_state.d.ts +102 -0
- package/dist/handshake/server_state.d.ts.map +1 -0
- package/dist/handshake/server_state.js +278 -0
- package/dist/handshake/server_state.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/keys/compromise.d.ts +118 -0
- package/dist/keys/compromise.d.ts.map +1 -0
- package/dist/keys/compromise.js +218 -0
- package/dist/keys/compromise.js.map +1 -0
- package/dist/keys/device_certificate.d.ts +166 -0
- package/dist/keys/device_certificate.d.ts.map +1 -0
- package/dist/keys/device_certificate.js +328 -0
- package/dist/keys/device_certificate.js.map +1 -0
- package/dist/keys/device_records.d.ts +175 -0
- package/dist/keys/device_records.d.ts.map +1 -0
- package/dist/keys/device_records.js +418 -0
- package/dist/keys/device_records.js.map +1 -0
- package/dist/keys/directory_cache.d.ts +64 -0
- package/dist/keys/directory_cache.d.ts.map +1 -0
- package/dist/keys/directory_cache.js +98 -0
- package/dist/keys/directory_cache.js.map +1 -0
- package/dist/keys/directory_state.d.ts +79 -0
- package/dist/keys/directory_state.d.ts.map +1 -0
- package/dist/keys/directory_state.js +155 -0
- package/dist/keys/directory_state.js.map +1 -0
- package/dist/keys/index.d.ts +18 -0
- package/dist/keys/index.d.ts.map +1 -0
- package/dist/keys/index.js +18 -0
- package/dist/keys/index.js.map +1 -0
- package/dist/keys/key_revocation.d.ts +61 -0
- package/dist/keys/key_revocation.d.ts.map +1 -0
- package/dist/keys/key_revocation.js +88 -0
- package/dist/keys/key_revocation.js.map +1 -0
- package/dist/keys/request.d.ts +124 -0
- package/dist/keys/request.d.ts.map +1 -0
- package/dist/keys/request.js +130 -0
- package/dist/keys/request.js.map +1 -0
- package/dist/keys/sign.d.ts +49 -0
- package/dist/keys/sign.d.ts.map +1 -0
- package/dist/keys/sign.js +80 -0
- package/dist/keys/sign.js.map +1 -0
- package/dist/keys/signed.d.ts +80 -0
- package/dist/keys/signed.d.ts.map +1 -0
- package/dist/keys/signed.js +138 -0
- package/dist/keys/signed.js.map +1 -0
- package/dist/keys/store.d.ts +138 -0
- package/dist/keys/store.d.ts.map +1 -0
- package/dist/keys/store.js +107 -0
- package/dist/keys/store.js.map +1 -0
- package/dist/largeattachment/crypto.d.ts +47 -0
- package/dist/largeattachment/crypto.d.ts.map +1 -0
- package/dist/largeattachment/crypto.js +235 -0
- package/dist/largeattachment/crypto.js.map +1 -0
- package/dist/largeattachment/enclosure.d.ts +48 -0
- package/dist/largeattachment/enclosure.d.ts.map +1 -0
- package/dist/largeattachment/enclosure.js +102 -0
- package/dist/largeattachment/enclosure.js.map +1 -0
- package/dist/largeattachment/index.d.ts +15 -0
- package/dist/largeattachment/index.d.ts.map +1 -0
- package/dist/largeattachment/index.js +15 -0
- package/dist/largeattachment/index.js.map +1 -0
- package/dist/largeattachment/store.d.ts +36 -0
- package/dist/largeattachment/store.d.ts.map +1 -0
- package/dist/largeattachment/store.js +37 -0
- package/dist/largeattachment/store.js.map +1 -0
- package/dist/largeattachment/types.d.ts +56 -0
- package/dist/largeattachment/types.d.ts.map +1 -0
- package/dist/largeattachment/types.js +31 -0
- package/dist/largeattachment/types.js.map +1 -0
- package/dist/largeattachment/upload.d.ts +62 -0
- package/dist/largeattachment/upload.d.ts.map +1 -0
- package/dist/largeattachment/upload.js +166 -0
- package/dist/largeattachment/upload.js.map +1 -0
- package/dist/migration/index.d.ts +17 -0
- package/dist/migration/index.d.ts.map +1 -0
- package/dist/migration/index.js +17 -0
- package/dist/migration/index.js.map +1 -0
- package/dist/migration/lockout.d.ts +48 -0
- package/dist/migration/lockout.d.ts.map +1 -0
- package/dist/migration/lockout.js +57 -0
- package/dist/migration/lockout.js.map +1 -0
- package/dist/migration/migration.d.ts +48 -0
- package/dist/migration/migration.d.ts.map +1 -0
- package/dist/migration/migration.js +58 -0
- package/dist/migration/migration.js.map +1 -0
- package/dist/migration/notice.d.ts +33 -0
- package/dist/migration/notice.d.ts.map +1 -0
- package/dist/migration/notice.js +85 -0
- package/dist/migration/notice.js.map +1 -0
- package/dist/migration/orchestrate.d.ts +109 -0
- package/dist/migration/orchestrate.d.ts.map +1 -0
- package/dist/migration/orchestrate.js +212 -0
- package/dist/migration/orchestrate.js.map +1 -0
- package/dist/migration/publication_store.d.ts +34 -0
- package/dist/migration/publication_store.d.ts.map +1 -0
- package/dist/migration/publication_store.js +44 -0
- package/dist/migration/publication_store.js.map +1 -0
- package/dist/migration/sign.d.ts +65 -0
- package/dist/migration/sign.d.ts.map +1 -0
- package/dist/migration/sign.js +331 -0
- package/dist/migration/sign.js.map +1 -0
- package/dist/migration/types.d.ts +92 -0
- package/dist/migration/types.d.ts.map +1 -0
- package/dist/migration/types.js +26 -0
- package/dist/migration/types.js.map +1 -0
- package/dist/reasoncodes.d.ts +42 -0
- package/dist/reasoncodes.d.ts.map +1 -0
- package/dist/reasoncodes.js +80 -0
- package/dist/reasoncodes.js.map +1 -0
- package/dist/recovery/bundle.d.ts +34 -0
- package/dist/recovery/bundle.d.ts.map +1 -0
- package/dist/recovery/bundle.js +144 -0
- package/dist/recovery/bundle.js.map +1 -0
- package/dist/recovery/bundle_crypto.d.ts +60 -0
- package/dist/recovery/bundle_crypto.d.ts.map +1 -0
- package/dist/recovery/bundle_crypto.js +179 -0
- package/dist/recovery/bundle_crypto.js.map +1 -0
- package/dist/recovery/bundle_store.d.ts +57 -0
- package/dist/recovery/bundle_store.d.ts.map +1 -0
- package/dist/recovery/bundle_store.js +104 -0
- package/dist/recovery/bundle_store.js.map +1 -0
- package/dist/recovery/index.d.ts +19 -0
- package/dist/recovery/index.d.ts.map +1 -0
- package/dist/recovery/index.js +19 -0
- package/dist/recovery/index.js.map +1 -0
- package/dist/recovery/manifest_crosscheck.d.ts +59 -0
- package/dist/recovery/manifest_crosscheck.d.ts.map +1 -0
- package/dist/recovery/manifest_crosscheck.js +59 -0
- package/dist/recovery/manifest_crosscheck.js.map +1 -0
- package/dist/recovery/shamir.d.ts +51 -0
- package/dist/recovery/shamir.d.ts.map +1 -0
- package/dist/recovery/shamir.js +181 -0
- package/dist/recovery/shamir.js.map +1 -0
- package/dist/recovery/sign.d.ts +61 -0
- package/dist/recovery/sign.d.ts.map +1 -0
- package/dist/recovery/sign.js +359 -0
- package/dist/recovery/sign.js.map +1 -0
- package/dist/recovery/types.d.ts +180 -0
- package/dist/recovery/types.d.ts.map +1 -0
- package/dist/recovery/types.js +31 -0
- package/dist/recovery/types.js.map +1 -0
- package/dist/reputation/abuse_report.d.ts +62 -0
- package/dist/reputation/abuse_report.d.ts.map +1 -0
- package/dist/reputation/abuse_report.js +111 -0
- package/dist/reputation/abuse_report.js.map +1 -0
- package/dist/reputation/bucketize.d.ts +31 -0
- package/dist/reputation/bucketize.d.ts.map +1 -0
- package/dist/reputation/bucketize.js +77 -0
- package/dist/reputation/bucketize.js.map +1 -0
- package/dist/reputation/gossip.d.ts +24 -0
- package/dist/reputation/gossip.d.ts.map +1 -0
- package/dist/reputation/gossip.js +64 -0
- package/dist/reputation/gossip.js.map +1 -0
- package/dist/reputation/gossip_fetch.d.ts +64 -0
- package/dist/reputation/gossip_fetch.d.ts.map +1 -0
- package/dist/reputation/gossip_fetch.js +114 -0
- package/dist/reputation/gossip_fetch.js.map +1 -0
- package/dist/reputation/index.d.ts +20 -0
- package/dist/reputation/index.d.ts.map +1 -0
- package/dist/reputation/index.js +20 -0
- package/dist/reputation/index.js.map +1 -0
- package/dist/reputation/observation_store.d.ts +67 -0
- package/dist/reputation/observation_store.d.ts.map +1 -0
- package/dist/reputation/observation_store.js +171 -0
- package/dist/reputation/observation_store.js.map +1 -0
- package/dist/reputation/pow.d.ts +91 -0
- package/dist/reputation/pow.d.ts.map +1 -0
- package/dist/reputation/pow.js +209 -0
- package/dist/reputation/pow.js.map +1 -0
- package/dist/reputation/sign.d.ts +40 -0
- package/dist/reputation/sign.d.ts.map +1 -0
- package/dist/reputation/sign.js +202 -0
- package/dist/reputation/sign.js.map +1 -0
- package/dist/reputation/types.d.ts +133 -0
- package/dist/reputation/types.d.ts.map +1 -0
- package/dist/reputation/types.js +33 -0
- package/dist/reputation/types.js.map +1 -0
- package/dist/reputation/whois.d.ts +25 -0
- package/dist/reputation/whois.d.ts.map +1 -0
- package/dist/reputation/whois.js +20 -0
- package/dist/reputation/whois.js.map +1 -0
- package/dist/seal/index.d.ts +8 -0
- package/dist/seal/index.d.ts.map +1 -0
- package/dist/seal/index.js +8 -0
- package/dist/seal/index.js.map +1 -0
- package/dist/seal/wrap.d.ts +74 -0
- package/dist/seal/wrap.d.ts.map +1 -0
- package/dist/seal/wrap.js +213 -0
- package/dist/seal/wrap.js.map +1 -0
- package/dist/session/dispatcher.d.ts +65 -0
- package/dist/session/dispatcher.d.ts.map +1 -0
- package/dist/session/dispatcher.js +96 -0
- package/dist/session/dispatcher.js.map +1 -0
- package/dist/session/index.d.ts +15 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +15 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/rekey.d.ts +108 -0
- package/dist/session/rekey.d.ts.map +1 -0
- package/dist/session/rekey.js +207 -0
- package/dist/session/rekey.js.map +1 -0
- package/dist/session/rekey_seal.d.ts +66 -0
- package/dist/session/rekey_seal.d.ts.map +1 -0
- package/dist/session/rekey_seal.js +153 -0
- package/dist/session/rekey_seal.js.map +1 -0
- package/dist/session/resume.d.ts +125 -0
- package/dist/session/resume.d.ts.map +1 -0
- package/dist/session/resume.js +263 -0
- package/dist/session/resume.js.map +1 -0
- package/dist/session/session.d.ts +136 -0
- package/dist/session/session.d.ts.map +1 -0
- package/dist/session/session.js +188 -0
- package/dist/session/session.js.map +1 -0
- package/dist/transparency/index.d.ts +13 -0
- package/dist/transparency/index.d.ts.map +1 -0
- package/dist/transparency/index.js +13 -0
- package/dist/transparency/index.js.map +1 -0
- package/dist/transparency/log.d.ts +61 -0
- package/dist/transparency/log.d.ts.map +1 -0
- package/dist/transparency/log.js +133 -0
- package/dist/transparency/log.js.map +1 -0
- package/dist/transparency/merkle.d.ts +59 -0
- package/dist/transparency/merkle.d.ts.map +1 -0
- package/dist/transparency/merkle.js +314 -0
- package/dist/transparency/merkle.js.map +1 -0
- package/dist/transparency/sign.d.ts +48 -0
- package/dist/transparency/sign.d.ts.map +1 -0
- package/dist/transparency/sign.js +140 -0
- package/dist/transparency/sign.js.map +1 -0
- package/dist/transparency/types.d.ts +97 -0
- package/dist/transparency/types.d.ts.map +1 -0
- package/dist/transparency/types.js +25 -0
- package/dist/transparency/types.js.map +1 -0
- package/dist/transport/h2.d.ts +163 -0
- package/dist/transport/h2.d.ts.map +1 -0
- package/dist/transport/h2.js +397 -0
- package/dist/transport/h2.js.map +1 -0
- package/dist/transport/index.d.ts +15 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +15 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/memory.d.ts +21 -0
- package/dist/transport/memory.d.ts.map +1 -0
- package/dist/transport/memory.js +112 -0
- package/dist/transport/memory.js.map +1 -0
- package/dist/transport/transport.d.ts +54 -0
- package/dist/transport/transport.d.ts.map +1 -0
- package/dist/transport/transport.js +20 -0
- package/dist/transport/transport.js.map +1 -0
- package/dist/transport/ws.d.ts +40 -0
- package/dist/transport/ws.d.ts.map +1 -0
- package/dist/transport/ws.js +204 -0
- package/dist/transport/ws.js.map +1 -0
- package/package.json +147 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SEMP_DISCOVERY signed lookup per DISCOVERY.md §4.
|
|
3
|
+
*
|
|
4
|
+
* Wire shape:
|
|
5
|
+
* - Request body: `{type, step="request", version, id, timestamp,
|
|
6
|
+
* addresses, extensions?}`
|
|
7
|
+
* - Response body: `{type, step="response", version, id, timestamp,
|
|
8
|
+
* results, signature, extensions?}`
|
|
9
|
+
*
|
|
10
|
+
* The response is signed by the answering server's domain signing
|
|
11
|
+
* key with the `SEMP-DISCOVERY:` prefix per ENVELOPE.md §4.3.
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
import { signSignedDoc, verifySignedDoc } from "../keys/index.js";
|
|
16
|
+
/** Wire-level constants. */
|
|
17
|
+
export const DiscoveryMessageType = "SEMP_DISCOVERY";
|
|
18
|
+
export const DiscoveryStepRequest = "request";
|
|
19
|
+
export const DiscoveryStepResponse = "response";
|
|
20
|
+
export const DiscoveryRecordVersion = "1.0.0";
|
|
21
|
+
export const DiscoverySignaturePrefix = "SEMP-DISCOVERY:";
|
|
22
|
+
/** Sign a {@link DiscoveryResponse} under the answering domain's signing key. */
|
|
23
|
+
export function signDiscoveryResponse(resp, domainPriv, domainKeyId) {
|
|
24
|
+
if (domainKeyId === "") {
|
|
25
|
+
throw new Error("discovery: empty domain key_id");
|
|
26
|
+
}
|
|
27
|
+
validateDiscoveryResponse(resp, { skipSignatureCheck: true });
|
|
28
|
+
resp.signature.algorithm = "ed25519";
|
|
29
|
+
resp.signature.key_id = domainKeyId;
|
|
30
|
+
resp.signature.value = "";
|
|
31
|
+
const { signedJSON, signatureB64 } = signSignedDoc({
|
|
32
|
+
preSignJSON: resp,
|
|
33
|
+
seed: domainPriv,
|
|
34
|
+
signaturePath: "signature.value",
|
|
35
|
+
prefix: DiscoverySignaturePrefix,
|
|
36
|
+
});
|
|
37
|
+
resp.signature.value = signedJSON.signature.value;
|
|
38
|
+
return signatureB64;
|
|
39
|
+
}
|
|
40
|
+
/** Verify a {@link DiscoveryResponse} under the answering domain's public key. */
|
|
41
|
+
export function verifyDiscoveryResponse(resp, domainPub) {
|
|
42
|
+
validateDiscoveryResponse(resp);
|
|
43
|
+
if (resp.signature.value === "") {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const { ok } = verifySignedDoc({
|
|
47
|
+
signedJSON: resp,
|
|
48
|
+
publicKey: domainPub,
|
|
49
|
+
signaturePath: "signature.value",
|
|
50
|
+
prefix: DiscoverySignaturePrefix,
|
|
51
|
+
});
|
|
52
|
+
return ok;
|
|
53
|
+
}
|
|
54
|
+
/** Structural validation of a {@link DiscoveryRequest}. Throws on first violation. */
|
|
55
|
+
export function validateDiscoveryRequest(req) {
|
|
56
|
+
if (req.type !== DiscoveryMessageType) {
|
|
57
|
+
throw new Error(`discovery: request type ${JSON.stringify(req.type)}, want ${DiscoveryMessageType}`);
|
|
58
|
+
}
|
|
59
|
+
if (req.step !== DiscoveryStepRequest) {
|
|
60
|
+
throw new Error(`discovery: request step ${JSON.stringify(req.step)}, want ${DiscoveryStepRequest}`);
|
|
61
|
+
}
|
|
62
|
+
for (const f of ["version", "id", "timestamp"]) {
|
|
63
|
+
if (typeof req[f] !== "string" || req[f] === "") {
|
|
64
|
+
throw new Error(`discovery: request missing ${f}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (Number.isNaN(Date.parse(req.timestamp))) {
|
|
68
|
+
throw new Error("discovery: request timestamp is not ISO 8601");
|
|
69
|
+
}
|
|
70
|
+
if (!Array.isArray(req.addresses) || req.addresses.length === 0) {
|
|
71
|
+
throw new Error("discovery: request addresses must be a non-empty array");
|
|
72
|
+
}
|
|
73
|
+
for (let i = 0; i < req.addresses.length; i++) {
|
|
74
|
+
if (typeof req.addresses[i] !== "string" || req.addresses[i] === "") {
|
|
75
|
+
throw new Error(`discovery: request addresses[${i}] missing`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/** Structural validation of a {@link DiscoveryResponse}. Throws on first violation. */
|
|
80
|
+
export function validateDiscoveryResponse(resp, opts = {}) {
|
|
81
|
+
if (resp.type !== DiscoveryMessageType) {
|
|
82
|
+
throw new Error(`discovery: response type ${JSON.stringify(resp.type)}, want ${DiscoveryMessageType}`);
|
|
83
|
+
}
|
|
84
|
+
if (resp.step !== DiscoveryStepResponse) {
|
|
85
|
+
throw new Error(`discovery: response step ${JSON.stringify(resp.step)}, want ${DiscoveryStepResponse}`);
|
|
86
|
+
}
|
|
87
|
+
for (const f of ["version", "id", "timestamp"]) {
|
|
88
|
+
if (typeof resp[f] !== "string" || resp[f] === "") {
|
|
89
|
+
throw new Error(`discovery: response missing ${f}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (Number.isNaN(Date.parse(resp.timestamp))) {
|
|
93
|
+
throw new Error("discovery: response timestamp is not ISO 8601");
|
|
94
|
+
}
|
|
95
|
+
if (!Array.isArray(resp.results)) {
|
|
96
|
+
throw new Error("discovery: response results must be an array");
|
|
97
|
+
}
|
|
98
|
+
for (let i = 0; i < resp.results.length; i++) {
|
|
99
|
+
const r = resp.results[i];
|
|
100
|
+
if (typeof r.address !== "string" || r.address === "") {
|
|
101
|
+
throw new Error(`discovery: response results[${i}] missing address`);
|
|
102
|
+
}
|
|
103
|
+
if (r.status !== "found" &&
|
|
104
|
+
r.status !== "not_found" &&
|
|
105
|
+
r.status !== "unsupported" &&
|
|
106
|
+
r.status !== "rate_limited" &&
|
|
107
|
+
r.status !== "deferred") {
|
|
108
|
+
throw new Error(`discovery: response results[${i}] status ${JSON.stringify(r.status)} is invalid`);
|
|
109
|
+
}
|
|
110
|
+
if (!Number.isInteger(r.ttl) || r.ttl < 0) {
|
|
111
|
+
throw new Error(`discovery: response results[${i}] ttl ${r.ttl} MUST be >= 0`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (typeof resp.signature?.value !== "string") {
|
|
115
|
+
throw new Error("discovery: response signature.value must be a string");
|
|
116
|
+
}
|
|
117
|
+
if (!opts.skipSignatureCheck && resp.signature.value === "") {
|
|
118
|
+
throw new Error("discovery: response is unsigned");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=lookup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../../src/discovery/lookup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tor onion-service domain validation per DISCOVERY.md §2.5.1.
|
|
3
|
+
*
|
|
4
|
+
* v2 onion addresses (16-character labels) are cryptographically
|
|
5
|
+
* deprecated and MUST NOT be used. Only v3 (56-character base32
|
|
6
|
+
* labels) is permitted by the spec.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
/** The label that marks a Tor onion-service domain. */
|
|
11
|
+
export declare const OnionSuffix = ".onion";
|
|
12
|
+
/** Character count of a v3 onion-service identifier (the only permitted version). */
|
|
13
|
+
export declare const OnionV3LabelLength = 56;
|
|
14
|
+
/**
|
|
15
|
+
* Whether `d` ends in `.onion`. Case-insensitive per the standard
|
|
16
|
+
* convention for the `.onion` TLD.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isOnionDomain(d: string): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Validate `d` as a Tor v3 onion domain. Throws on the first
|
|
21
|
+
* violation; returns nothing on success.
|
|
22
|
+
*
|
|
23
|
+
* Rejects:
|
|
24
|
+
* - non-`.onion` domains
|
|
25
|
+
* - empty labels
|
|
26
|
+
* - v2 (16-char) onion addresses (cryptographically deprecated)
|
|
27
|
+
* - any other length than 56 chars
|
|
28
|
+
* - any character outside the v3 base32 alphabet (`a-z` + `2-7`)
|
|
29
|
+
*
|
|
30
|
+
* Multi-label onion domains (`sub.<v3-label>.onion`) are accepted
|
|
31
|
+
* when the rightmost label before `.onion` is the v3 identifier.
|
|
32
|
+
*/
|
|
33
|
+
export declare function validateOnionDomain(d: string): void;
|
|
34
|
+
//# sourceMappingURL=onion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onion.d.ts","sourceRoot":"","sources":["../../src/discovery/onion.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,uDAAuD;AACvD,eAAO,MAAM,WAAW,WAAW,CAAC;AAEpC,qFAAqF;AACrF,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC;;;GAGG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEhD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CA+BnD"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tor onion-service domain validation per DISCOVERY.md §2.5.1.
|
|
3
|
+
*
|
|
4
|
+
* v2 onion addresses (16-character labels) are cryptographically
|
|
5
|
+
* deprecated and MUST NOT be used. Only v3 (56-character base32
|
|
6
|
+
* labels) is permitted by the spec.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
/** The label that marks a Tor onion-service domain. */
|
|
11
|
+
export const OnionSuffix = ".onion";
|
|
12
|
+
/** Character count of a v3 onion-service identifier (the only permitted version). */
|
|
13
|
+
export const OnionV3LabelLength = 56;
|
|
14
|
+
/**
|
|
15
|
+
* Whether `d` ends in `.onion`. Case-insensitive per the standard
|
|
16
|
+
* convention for the `.onion` TLD.
|
|
17
|
+
*/
|
|
18
|
+
export function isOnionDomain(d) {
|
|
19
|
+
return d.toLowerCase().endsWith(OnionSuffix);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Validate `d` as a Tor v3 onion domain. Throws on the first
|
|
23
|
+
* violation; returns nothing on success.
|
|
24
|
+
*
|
|
25
|
+
* Rejects:
|
|
26
|
+
* - non-`.onion` domains
|
|
27
|
+
* - empty labels
|
|
28
|
+
* - v2 (16-char) onion addresses (cryptographically deprecated)
|
|
29
|
+
* - any other length than 56 chars
|
|
30
|
+
* - any character outside the v3 base32 alphabet (`a-z` + `2-7`)
|
|
31
|
+
*
|
|
32
|
+
* Multi-label onion domains (`sub.<v3-label>.onion`) are accepted
|
|
33
|
+
* when the rightmost label before `.onion` is the v3 identifier.
|
|
34
|
+
*/
|
|
35
|
+
export function validateOnionDomain(d) {
|
|
36
|
+
if (!isOnionDomain(d)) {
|
|
37
|
+
throw new Error("discovery: not an .onion domain");
|
|
38
|
+
}
|
|
39
|
+
const lower = d.toLowerCase();
|
|
40
|
+
const trimmed = lower.slice(0, lower.length - OnionSuffix.length);
|
|
41
|
+
if (trimmed === "") {
|
|
42
|
+
throw new Error("discovery: .onion domain has empty label");
|
|
43
|
+
}
|
|
44
|
+
const labels = trimmed.split(".");
|
|
45
|
+
const onionLabel = labels[labels.length - 1] ?? "";
|
|
46
|
+
if (onionLabel.length === 16) {
|
|
47
|
+
throw new Error("discovery: version-2 .onion addresses are not supported; use a v3 address (56-character label)");
|
|
48
|
+
}
|
|
49
|
+
if (onionLabel.length !== OnionV3LabelLength) {
|
|
50
|
+
throw new Error("discovery: .onion label is not a valid v3 identifier (expected 56 characters)");
|
|
51
|
+
}
|
|
52
|
+
for (let i = 0; i < onionLabel.length; i++) {
|
|
53
|
+
const c = onionLabel.charCodeAt(i);
|
|
54
|
+
const isLower = c >= 0x61 /* a */ && c <= 0x7a /* z */;
|
|
55
|
+
const isDigit2to7 = c >= 0x32 /* 2 */ && c <= 0x37 /* 7 */;
|
|
56
|
+
if (!isLower && !isDigit2to7) {
|
|
57
|
+
throw new Error("discovery: .onion label contains characters outside the v3 base32 alphabet");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=onion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onion.js","sourceRoot":"","sources":["../../src/discovery/onion.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,uDAAuD;AACvD,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC;AAEpC,qFAAqF;AACrF,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAErC;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,CAAS;IACrC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAAC,CAAS;IAC3C,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAClE,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACnD,IAAI,UAAU,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CACb,gGAAgG,CACjG,CAAC;IACJ,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,KAAK,kBAAkB,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,+EAA+E,CAChF,CAAC;IACJ,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,CAAC,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC;QACvD,MAAM,WAAW,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC;QAC3D,IAAI,CAAC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,4EAA4E,CAC7E,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User-partitioning strategy per DISCOVERY.md §2.4.
|
|
3
|
+
*
|
|
4
|
+
* Large domains advertise a partition strategy via a
|
|
5
|
+
* `_semp-partition.<domain>` TXT record. Three strategies are
|
|
6
|
+
* defined: `alpha` (split alphabetically), `hash` (SHA-256 mod N),
|
|
7
|
+
* and `lookup` (delegate to a designated partition server).
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { type DNSLookup } from "./dns.js";
|
|
12
|
+
/** Partition strategy enum per §2.4. */
|
|
13
|
+
export type PartitionStrategy = "alpha" | "hash" | "lookup";
|
|
14
|
+
/** Inclusive lowercase ASCII range mapped to a server hostname. */
|
|
15
|
+
export interface AlphaRange {
|
|
16
|
+
/** Inclusive starting char code in `[a, z]`. */
|
|
17
|
+
start_char: string;
|
|
18
|
+
/** Inclusive ending char code in `[a, z]`. */
|
|
19
|
+
end_char: string;
|
|
20
|
+
server?: string;
|
|
21
|
+
}
|
|
22
|
+
/** Parsed `_semp-partition.<domain>` TXT record. */
|
|
23
|
+
export interface PartitionConfig {
|
|
24
|
+
/** SEMP partition protocol version. Always `"semp1"` for the initial spec revision. */
|
|
25
|
+
version: string;
|
|
26
|
+
strategy: PartitionStrategy;
|
|
27
|
+
/** Number of partition servers. Used only by `hash`. */
|
|
28
|
+
servers?: number;
|
|
29
|
+
/** Hash algorithm for `hash`. Defaults to `"sha256"` if empty. */
|
|
30
|
+
algorithm?: string;
|
|
31
|
+
/** Domain this config applies to. */
|
|
32
|
+
domain: string;
|
|
33
|
+
/**
|
|
34
|
+
* If non-empty, overrides the default 26-letter mapping for
|
|
35
|
+
* `alpha`. Each entry maps a contiguous range of first-characters
|
|
36
|
+
* to a server hostname. The default mapping splits `a-z` into
|
|
37
|
+
* roughly equal groups of `servers` size and resolves via
|
|
38
|
+
* `_semp-partition-<range>.<domain>` SRV records.
|
|
39
|
+
*/
|
|
40
|
+
alpha_ranges?: AlphaRange[];
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Construct the even-split default ranges used by the §2.4 example:
|
|
44
|
+
* 4 ranges covering `a-f`, `g-m`, `n-s`, `t-z` when `servers === 4`.
|
|
45
|
+
* Generalized to any server count `>= 1`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function defaultAlphaRanges(servers: number): AlphaRange[];
|
|
48
|
+
/**
|
|
49
|
+
* Callback used by `strategy === "lookup"`. Queries the partition
|
|
50
|
+
* lookup server (published at `_semp-partition-lookup.<domain>` SRV)
|
|
51
|
+
* and returns the hostname of the delivery server that handles
|
|
52
|
+
* `address`. The discovery package does not prescribe the wire
|
|
53
|
+
* format of the lookup query — DISCOVERY.md §2.4 says "the
|
|
54
|
+
* partition server address is published as a separate SRV record"
|
|
55
|
+
* and leaves the query protocol to the implementation.
|
|
56
|
+
*/
|
|
57
|
+
export type PartitionLookupFunc = (address: string) => Promise<string>;
|
|
58
|
+
/** Inputs to {@link resolvePartition}. */
|
|
59
|
+
export interface PartitionResolverConfig {
|
|
60
|
+
/**
|
|
61
|
+
* DNS lookup backend. Required for `alpha` and `hash` (to resolve
|
|
62
|
+
* `_semp-partition-<X>.<domain>` SRV records). Unused by
|
|
63
|
+
* `lookup`.
|
|
64
|
+
*/
|
|
65
|
+
dns?: DNSLookup;
|
|
66
|
+
/** Required for `strategy === "lookup"`. Ignored otherwise. */
|
|
67
|
+
lookupFunc?: PartitionLookupFunc;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Return the SEMP server hostname that handles `address` according
|
|
71
|
+
* to `config`.
|
|
72
|
+
*
|
|
73
|
+
* - `alpha`: extract the first character of the local part, map
|
|
74
|
+
* it to the range containing it, and return the server for that
|
|
75
|
+
* range. If `config.alpha_ranges` is empty, resolve via
|
|
76
|
+
* `_semp-partition-<start>-<end>.<domain>` SRV.
|
|
77
|
+
* - `hash`: compute `SHA-256(address) mod config.servers` to get
|
|
78
|
+
* an index, then resolve via `_semp-partition-<index>.<domain>`
|
|
79
|
+
* SRV.
|
|
80
|
+
* - `lookup`: delegate to `resolverConfig.lookupFunc`.
|
|
81
|
+
*/
|
|
82
|
+
export declare function resolvePartition(config: PartitionConfig, resolverConfig: PartitionResolverConfig, address: string): Promise<string>;
|
|
83
|
+
/**
|
|
84
|
+
* Parse a `_semp-partition.<domain>` TXT record value into a
|
|
85
|
+
* {@link PartitionConfig}. The format follows the same
|
|
86
|
+
* semicolon-separated `key=value` convention as the discovery TXT
|
|
87
|
+
* record:
|
|
88
|
+
*
|
|
89
|
+
* ```
|
|
90
|
+
* "v=semp1;strategy=hash;servers=8;algorithm=sha256"
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* Unknown keys are silently ignored for forward compatibility.
|
|
94
|
+
*/
|
|
95
|
+
export declare function parsePartitionTXT(domain: string, txt: string): PartitionConfig;
|
|
96
|
+
//# sourceMappingURL=partition.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partition.d.ts","sourceRoot":"","sources":["../../src/discovery/partition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,wCAAwC;AACxC,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5D,mEAAmE;AACnE,MAAM,WAAW,UAAU;IACzB,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,oDAAoD;AACpD,MAAM,WAAW,eAAe;IAC9B,uFAAuF;IACvF,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CA2BhE;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEvE,0CAA0C;AAC1C,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,GAAG,CAAC,EAAE,SAAS,CAAC;IAChB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,mBAAmB,CAAC;CAClC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,eAAe,EACvB,cAAc,EAAE,uBAAuB,EACvC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,MAAM,CAAC,CAmBjB;AA+ID;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,GACV,eAAe,CAyDjB"}
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User-partitioning strategy per DISCOVERY.md §2.4.
|
|
3
|
+
*
|
|
4
|
+
* Large domains advertise a partition strategy via a
|
|
5
|
+
* `_semp-partition.<domain>` TXT record. Three strategies are
|
|
6
|
+
* defined: `alpha` (split alphabetically), `hash` (SHA-256 mod N),
|
|
7
|
+
* and `lookup` (delegate to a designated partition server).
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
12
|
+
import {} from "./dns.js";
|
|
13
|
+
/**
|
|
14
|
+
* Construct the even-split default ranges used by the §2.4 example:
|
|
15
|
+
* 4 ranges covering `a-f`, `g-m`, `n-s`, `t-z` when `servers === 4`.
|
|
16
|
+
* Generalized to any server count `>= 1`.
|
|
17
|
+
*/
|
|
18
|
+
export function defaultAlphaRanges(servers) {
|
|
19
|
+
if (servers <= 0) {
|
|
20
|
+
return [];
|
|
21
|
+
}
|
|
22
|
+
if (servers > 26) {
|
|
23
|
+
servers = 26;
|
|
24
|
+
}
|
|
25
|
+
const out = [];
|
|
26
|
+
const charsPerServer = Math.floor(26 / servers);
|
|
27
|
+
const remainder = 26 % servers;
|
|
28
|
+
let start = 0x61; // 'a'
|
|
29
|
+
for (let i = 0; i < servers; i++) {
|
|
30
|
+
let width = charsPerServer;
|
|
31
|
+
if (i < remainder) {
|
|
32
|
+
width += 1;
|
|
33
|
+
}
|
|
34
|
+
let end = start + width - 1;
|
|
35
|
+
if (end > 0x7a) {
|
|
36
|
+
end = 0x7a;
|
|
37
|
+
}
|
|
38
|
+
out.push({
|
|
39
|
+
start_char: String.fromCharCode(start),
|
|
40
|
+
end_char: String.fromCharCode(end),
|
|
41
|
+
});
|
|
42
|
+
start = end + 1;
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Return the SEMP server hostname that handles `address` according
|
|
48
|
+
* to `config`.
|
|
49
|
+
*
|
|
50
|
+
* - `alpha`: extract the first character of the local part, map
|
|
51
|
+
* it to the range containing it, and return the server for that
|
|
52
|
+
* range. If `config.alpha_ranges` is empty, resolve via
|
|
53
|
+
* `_semp-partition-<start>-<end>.<domain>` SRV.
|
|
54
|
+
* - `hash`: compute `SHA-256(address) mod config.servers` to get
|
|
55
|
+
* an index, then resolve via `_semp-partition-<index>.<domain>`
|
|
56
|
+
* SRV.
|
|
57
|
+
* - `lookup`: delegate to `resolverConfig.lookupFunc`.
|
|
58
|
+
*/
|
|
59
|
+
export async function resolvePartition(config, resolverConfig, address) {
|
|
60
|
+
if (address === "") {
|
|
61
|
+
throw new Error("discovery: empty address");
|
|
62
|
+
}
|
|
63
|
+
switch (config.strategy) {
|
|
64
|
+
case "alpha":
|
|
65
|
+
return resolveAlpha(config, resolverConfig, address);
|
|
66
|
+
case "hash":
|
|
67
|
+
return resolveHash(config, resolverConfig, address);
|
|
68
|
+
case "lookup":
|
|
69
|
+
if (resolverConfig.lookupFunc === undefined) {
|
|
70
|
+
throw new Error("discovery: strategy=lookup requires a lookupFunc");
|
|
71
|
+
}
|
|
72
|
+
return resolverConfig.lookupFunc(address);
|
|
73
|
+
default:
|
|
74
|
+
throw new Error(`discovery: unknown partition strategy ${JSON.stringify(config.strategy)}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async function resolveAlpha(config, resolverConfig, address) {
|
|
78
|
+
const local = localPart(address);
|
|
79
|
+
if (local === "") {
|
|
80
|
+
throw new Error("discovery: address has no local part");
|
|
81
|
+
}
|
|
82
|
+
const firstChar = firstLowerChar(local);
|
|
83
|
+
// Fast path: pre-resolved alpha_ranges with non-empty server.
|
|
84
|
+
if (config.alpha_ranges !== undefined && config.alpha_ranges.length > 0) {
|
|
85
|
+
for (const r of config.alpha_ranges) {
|
|
86
|
+
if (firstChar >= r.start_char.charCodeAt(0) &&
|
|
87
|
+
firstChar <= r.end_char.charCodeAt(0)) {
|
|
88
|
+
if (r.server !== undefined && r.server !== "") {
|
|
89
|
+
return r.server;
|
|
90
|
+
}
|
|
91
|
+
// Fall through to SRV path with this range's bounds.
|
|
92
|
+
return resolveSRV(resolverConfig, config.domain, `semp-partition-${r.start_char}-${r.end_char}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Fallback: non-alphabetic first character → last range.
|
|
96
|
+
const last = config.alpha_ranges[config.alpha_ranges.length - 1];
|
|
97
|
+
if (last.server !== undefined && last.server !== "") {
|
|
98
|
+
return last.server;
|
|
99
|
+
}
|
|
100
|
+
return resolveSRV(resolverConfig, config.domain, `semp-partition-${last.start_char}-${last.end_char}`);
|
|
101
|
+
}
|
|
102
|
+
// DNS path: construct ranges from defaultAlphaRanges and resolve
|
|
103
|
+
// each range's SRV record.
|
|
104
|
+
const ranges = defaultAlphaRanges(config.servers ?? 0);
|
|
105
|
+
if (ranges.length === 0) {
|
|
106
|
+
throw new Error("discovery: alpha partition requires at least one server");
|
|
107
|
+
}
|
|
108
|
+
let matched = ranges[ranges.length - 1]; // default to last
|
|
109
|
+
for (const r of ranges) {
|
|
110
|
+
if (firstChar >= r.start_char.charCodeAt(0) &&
|
|
111
|
+
firstChar <= r.end_char.charCodeAt(0)) {
|
|
112
|
+
matched = r;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return resolveSRV(resolverConfig, config.domain, `semp-partition-${matched.start_char}-${matched.end_char}`);
|
|
117
|
+
}
|
|
118
|
+
async function resolveHash(config, resolverConfig, address) {
|
|
119
|
+
const servers = config.servers ?? 0;
|
|
120
|
+
if (servers <= 0) {
|
|
121
|
+
throw new Error("discovery: hash partition requires servers > 0");
|
|
122
|
+
}
|
|
123
|
+
const sum = sha256(new TextEncoder().encode(address.toLowerCase()));
|
|
124
|
+
// Use the first 8 bytes as a big-endian uint64 for the mod
|
|
125
|
+
// operation. Fits in a safe-integer when `servers` is small.
|
|
126
|
+
let big = 0n;
|
|
127
|
+
for (let i = 0; i < 8; i++) {
|
|
128
|
+
big = (big << 8n) | BigInt(sum[i] ?? 0);
|
|
129
|
+
}
|
|
130
|
+
const idx = big % BigInt(servers);
|
|
131
|
+
return resolveSRV(resolverConfig, config.domain, `semp-partition-${idx.toString()}`);
|
|
132
|
+
}
|
|
133
|
+
async function resolveSRV(resolverConfig, domain, service) {
|
|
134
|
+
if (resolverConfig.dns === undefined) {
|
|
135
|
+
throw new Error("discovery: DNS lookup not configured");
|
|
136
|
+
}
|
|
137
|
+
const name = `_${service}._tcp.${domain}`;
|
|
138
|
+
const records = await resolverConfig.dns.lookupSRV(name);
|
|
139
|
+
if (records.length === 0) {
|
|
140
|
+
throw new Error(`discovery: no SRV records for ${name}`);
|
|
141
|
+
}
|
|
142
|
+
let best = records[0];
|
|
143
|
+
for (let i = 1; i < records.length; i++) {
|
|
144
|
+
if (records[i].priority < best.priority) {
|
|
145
|
+
best = records[i];
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return best.target.replace(/\.$/, "");
|
|
149
|
+
}
|
|
150
|
+
/** Extract the part before the last `@` in `address`. */
|
|
151
|
+
function localPart(address) {
|
|
152
|
+
const i = address.lastIndexOf("@");
|
|
153
|
+
if (i < 0) {
|
|
154
|
+
return address;
|
|
155
|
+
}
|
|
156
|
+
return address.slice(0, i);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* First character of `s` lowercased if it is a lowercase ASCII
|
|
160
|
+
* letter, or `~` (the highest printable ASCII, which sorts after
|
|
161
|
+
* `z`) as a fallback for non-alphabetic first characters. Forces
|
|
162
|
+
* non-alpha users into the last range.
|
|
163
|
+
*/
|
|
164
|
+
function firstLowerChar(s) {
|
|
165
|
+
if (s.length === 0) {
|
|
166
|
+
return 0x7e; // '~'
|
|
167
|
+
}
|
|
168
|
+
let c = s.charCodeAt(0);
|
|
169
|
+
// We can't see surrogate pairs as anything other than non-alpha;
|
|
170
|
+
// a non-BMP first char hits the fallback below.
|
|
171
|
+
if (c >= 0x41 /* A */ && c <= 0x5a /* Z */) {
|
|
172
|
+
c += 0x61 - 0x41;
|
|
173
|
+
}
|
|
174
|
+
if (c >= 0x61 /* a */ && c <= 0x7a /* z */) {
|
|
175
|
+
return c;
|
|
176
|
+
}
|
|
177
|
+
return 0x7e; // '~'
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Parse a `_semp-partition.<domain>` TXT record value into a
|
|
181
|
+
* {@link PartitionConfig}. The format follows the same
|
|
182
|
+
* semicolon-separated `key=value` convention as the discovery TXT
|
|
183
|
+
* record:
|
|
184
|
+
*
|
|
185
|
+
* ```
|
|
186
|
+
* "v=semp1;strategy=hash;servers=8;algorithm=sha256"
|
|
187
|
+
* ```
|
|
188
|
+
*
|
|
189
|
+
* Unknown keys are silently ignored for forward compatibility.
|
|
190
|
+
*/
|
|
191
|
+
export function parsePartitionTXT(domain, txt) {
|
|
192
|
+
if (txt.trim() === "") {
|
|
193
|
+
throw new Error("discovery: empty partition TXT record");
|
|
194
|
+
}
|
|
195
|
+
const cfg = {
|
|
196
|
+
version: "",
|
|
197
|
+
strategy: "alpha",
|
|
198
|
+
domain,
|
|
199
|
+
};
|
|
200
|
+
for (const kv of txt.split(";")) {
|
|
201
|
+
const trimmed = kv.trim();
|
|
202
|
+
const eq = trimmed.indexOf("=");
|
|
203
|
+
if (eq < 0) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
const key = trimmed.slice(0, eq).trim();
|
|
207
|
+
const val = trimmed.slice(eq + 1).trim();
|
|
208
|
+
switch (key) {
|
|
209
|
+
case "v":
|
|
210
|
+
cfg.version = val;
|
|
211
|
+
break;
|
|
212
|
+
case "strategy":
|
|
213
|
+
if (val !== "alpha" && val !== "hash" && val !== "lookup") {
|
|
214
|
+
throw new Error(`discovery: invalid partition strategy ${JSON.stringify(val)}`);
|
|
215
|
+
}
|
|
216
|
+
cfg.strategy = val;
|
|
217
|
+
break;
|
|
218
|
+
case "servers": {
|
|
219
|
+
let n = 0;
|
|
220
|
+
for (let i = 0; i < val.length; i++) {
|
|
221
|
+
const c = val.charCodeAt(i);
|
|
222
|
+
if (c < 0x30 || c > 0x39) {
|
|
223
|
+
throw new Error(`discovery: invalid servers count ${JSON.stringify(val)}`);
|
|
224
|
+
}
|
|
225
|
+
n = n * 10 + (c - 0x30);
|
|
226
|
+
}
|
|
227
|
+
cfg.servers = n;
|
|
228
|
+
break;
|
|
229
|
+
}
|
|
230
|
+
case "algorithm":
|
|
231
|
+
cfg.algorithm = val;
|
|
232
|
+
break;
|
|
233
|
+
default:
|
|
234
|
+
// unknown key — skip (forward compat).
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (cfg.version === "") {
|
|
239
|
+
throw new Error("discovery: partition TXT missing version (v=)");
|
|
240
|
+
}
|
|
241
|
+
// Strategy was defaulted to "alpha"; it must be set explicitly.
|
|
242
|
+
if (!txt.includes("strategy=")) {
|
|
243
|
+
throw new Error("discovery: partition TXT missing strategy");
|
|
244
|
+
}
|
|
245
|
+
return cfg;
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=partition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"partition.js","sourceRoot":"","sources":["../../src/discovery/partition.ts"],"names":[],"mappings":"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"}
|