@powerhousedao/shared 6.2.3-dev.6 → 6.2.3-dev.60
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analytics/index.d.ts +4 -4
- package/dist/analytics/index.d.ts.map +1 -1
- package/dist/analytics/index.js +25 -24
- package/dist/analytics/index.js.map +1 -1
- package/dist/clis/args/{access-token-To5LaIfL.mjs → access-token-3Hqv_U8I.mjs} +2 -2
- package/dist/clis/args/{access-token-To5LaIfL.mjs.map → access-token-3Hqv_U8I.mjs.map} +1 -1
- package/dist/clis/args/access-token-C5sKsH2O.d.mts +16 -0
- package/dist/clis/args/access-token-C5sKsH2O.d.mts.map +1 -0
- package/dist/clis/args/access-token.d.mts +3 -2
- package/dist/clis/args/access-token.mjs +1 -1
- package/dist/clis/args/{common-CcYbXrBx.mjs → common-BXabdhiO.mjs} +30 -7
- package/dist/clis/args/common-BXabdhiO.mjs.map +1 -0
- package/dist/clis/args/common-Bnm859xU.d.mts +186 -0
- package/dist/clis/args/common-Bnm859xU.d.mts.map +1 -0
- package/dist/clis/args/common.d.mts +3 -2
- package/dist/clis/args/common.mjs +1 -1
- package/dist/clis/args/{connect-BVVvCmL9.mjs → connect-BG3HkYBk.mjs} +8 -3
- package/dist/clis/args/connect-BG3HkYBk.mjs.map +1 -0
- package/dist/clis/args/connect-DjeiqXus.d.mts +450 -0
- package/dist/clis/args/connect-DjeiqXus.d.mts.map +1 -0
- package/dist/clis/args/connect.d.mts +3 -2
- package/dist/clis/args/connect.mjs +1 -1
- package/dist/clis/args/dist-CorQTQL-.mjs +1533 -0
- package/dist/clis/args/dist-CorQTQL-.mjs.map +1 -0
- package/dist/clis/args/{generate-CA916Fvj.mjs → generate-BOItUNvP.mjs} +40 -2
- package/dist/clis/args/generate-BOItUNvP.mjs.map +1 -0
- package/dist/clis/args/generate-BPBBLeUD.d.mts +103 -0
- package/dist/clis/args/generate-BPBBLeUD.d.mts.map +1 -0
- package/dist/clis/args/generate.d.mts +3 -2
- package/dist/clis/args/generate.mjs +1 -1
- package/dist/clis/args/{help-Bqbgbalu.mjs → help-BfAqpYvC.mjs} +43 -16
- package/dist/clis/args/help-BfAqpYvC.mjs.map +1 -0
- package/dist/clis/args/help-KuqI-EEG.d.mts +203 -0
- package/dist/clis/args/help-KuqI-EEG.d.mts.map +1 -0
- package/dist/clis/args/help.d.mts +3 -2
- package/dist/clis/args/help.mjs +1 -1
- package/dist/clis/args/index.d.mts +20 -19
- package/dist/clis/args/index.mjs +18 -18
- package/dist/clis/args/init-CTaK80wE.d.mts +55 -0
- package/dist/clis/args/init-CTaK80wE.d.mts.map +1 -0
- package/dist/clis/args/{init-rz9Ei7nq.mjs → init-xlCNZ8Oe.mjs} +7 -2
- package/dist/clis/args/{init-rz9Ei7nq.mjs.map → init-xlCNZ8Oe.mjs.map} +1 -1
- package/dist/clis/args/init.d.mts +3 -2
- package/dist/clis/args/init.mjs +1 -1
- package/dist/clis/args/inspect-BjRmtB86.d.mts +13 -0
- package/dist/clis/args/inspect-BjRmtB86.d.mts.map +1 -0
- package/dist/clis/args/{inspect-tckH8mSw.mjs → inspect-UNQgtuR0.mjs} +2 -2
- package/dist/clis/args/{inspect-tckH8mSw.mjs.map → inspect-UNQgtuR0.mjs.map} +1 -1
- package/dist/clis/args/inspect.d.mts +3 -2
- package/dist/clis/args/inspect.mjs +1 -1
- package/dist/clis/args/install-B0tMyUMw.d.mts +37 -0
- package/dist/clis/args/install-B0tMyUMw.d.mts.map +1 -0
- package/dist/clis/args/{install-Sz2DlCHh.mjs → install-F-27kF6m.mjs} +2 -2
- package/dist/clis/args/{install-Sz2DlCHh.mjs.map → install-F-27kF6m.mjs.map} +1 -1
- package/dist/clis/args/install.d.mts +3 -2
- package/dist/clis/args/install.mjs +1 -1
- package/dist/clis/args/{list-DM2d6f1m.mjs → list-Bkfn8Yuo.mjs} +2 -2
- package/dist/clis/args/{list-DM2d6f1m.mjs.map → list-Bkfn8Yuo.mjs.map} +1 -1
- package/dist/clis/args/list-DrbxA7JJ.d.mts +10 -0
- package/dist/clis/args/list-DrbxA7JJ.d.mts.map +1 -0
- package/dist/clis/args/list.d.mts +3 -2
- package/dist/clis/args/list.mjs +1 -1
- package/dist/clis/args/{login-DiKT5Jfu.mjs → login-CIFkQExi.mjs} +2 -2
- package/dist/clis/args/{login-DiKT5Jfu.mjs.map → login-CIFkQExi.mjs.map} +1 -1
- package/dist/clis/args/login-CXRJXg71.d.mts +25 -0
- package/dist/clis/args/login-CXRJXg71.d.mts.map +1 -0
- package/dist/clis/args/login.d.mts +3 -2
- package/dist/clis/args/login.mjs +1 -1
- package/dist/clis/args/migrate-DkCQRL2D.d.mts +19 -0
- package/dist/clis/args/migrate-DkCQRL2D.d.mts.map +1 -0
- package/dist/clis/args/{migrate-CG_gWc4k.mjs → migrate-DwJGhc2d.mjs} +2 -2
- package/dist/clis/args/{migrate-CG_gWc4k.mjs.map → migrate-DwJGhc2d.mjs.map} +1 -1
- package/dist/clis/args/migrate.d.mts +3 -2
- package/dist/clis/args/migrate.mjs +1 -1
- package/dist/clis/args/publish-CeW4bOrl.d.mts +16 -0
- package/dist/clis/args/publish-CeW4bOrl.d.mts.map +1 -0
- package/dist/clis/args/{publish-DDZYsUfV.mjs → publish-DHqlGWmL.mjs} +2 -2
- package/dist/clis/args/{publish-DDZYsUfV.mjs.map → publish-DHqlGWmL.mjs.map} +1 -1
- package/dist/clis/args/publish.d.mts +3 -2
- package/dist/clis/args/publish.mjs +1 -1
- package/dist/clis/args/{registry-C_OVFQmI.mjs → registry-DIwES3l2.mjs} +2 -2
- package/dist/clis/args/{registry-C_OVFQmI.mjs.map → registry-DIwES3l2.mjs.map} +1 -1
- package/dist/clis/args/registry-DNH8xuaE.d.mts +17 -0
- package/dist/clis/args/registry-DNH8xuaE.d.mts.map +1 -0
- package/dist/clis/args/registry.d.mts +3 -2
- package/dist/clis/args/registry.mjs +1 -1
- package/dist/clis/args/run-CYp5t1xU.mjs +28 -0
- package/dist/clis/args/run-CYp5t1xU.mjs.map +1 -0
- package/dist/clis/args/run.d.mts +18 -0
- package/dist/clis/args/run.d.mts.map +1 -0
- package/dist/clis/args/run.mjs +2 -0
- package/dist/clis/args/service-CHjY5epu.d.mts +27 -0
- package/dist/clis/args/service-CHjY5epu.d.mts.map +1 -0
- package/dist/clis/args/{service-CHOOr0Gg.mjs → service-Cpjlyeu5.mjs} +2 -2
- package/dist/clis/args/{service-CHOOr0Gg.mjs.map → service-Cpjlyeu5.mjs.map} +1 -1
- package/dist/clis/args/service.d.mts +3 -2
- package/dist/clis/args/service.mjs +1 -1
- package/dist/clis/args/{switchboard-Dsp7nosi.mjs → switchboard-CCaAtU56.mjs} +2 -2
- package/dist/clis/args/{switchboard-Dsp7nosi.mjs.map → switchboard-CCaAtU56.mjs.map} +1 -1
- package/dist/clis/args/switchboard-RrNb1fUH.d.mts +70 -0
- package/dist/clis/args/switchboard-RrNb1fUH.d.mts.map +1 -0
- package/dist/clis/args/switchboard.d.mts +3 -2
- package/dist/clis/args/switchboard.mjs +1 -1
- package/dist/clis/args/{uninstall-CTwTX0u_.mjs → uninstall-3U0B8g5c.mjs} +2 -2
- package/dist/clis/args/{uninstall-CTwTX0u_.mjs.map → uninstall-3U0B8g5c.mjs.map} +1 -1
- package/dist/clis/args/uninstall-CDx7lwxn.d.mts +28 -0
- package/dist/clis/args/uninstall-CDx7lwxn.d.mts.map +1 -0
- package/dist/clis/args/uninstall.d.mts +3 -2
- package/dist/clis/args/uninstall.mjs +1 -1
- package/dist/clis/args/unpublish-CEDsk6uv.d.mts +22 -0
- package/dist/clis/args/unpublish-CEDsk6uv.d.mts.map +1 -0
- package/dist/clis/args/{unpublish-BPMkGEg5.mjs → unpublish-s9zUh6Gw.mjs} +2 -2
- package/dist/clis/args/{unpublish-BPMkGEg5.mjs.map → unpublish-s9zUh6Gw.mjs.map} +1 -1
- package/dist/clis/args/unpublish.d.mts +3 -2
- package/dist/clis/args/unpublish.mjs +1 -1
- package/dist/clis/args/{vetra-b4KUu1Ax.mjs → vetra-BUNlAAPp.mjs} +2 -2
- package/dist/clis/args/{vetra-b4KUu1Ax.mjs.map → vetra-BUNlAAPp.mjs.map} +1 -1
- package/dist/clis/args/vetra-DkDaWFPi.d.mts +111 -0
- package/dist/clis/args/vetra-DkDaWFPi.d.mts.map +1 -0
- package/dist/clis/args/vetra-ports.test.d.mts +2 -1
- package/dist/clis/args/vetra-ports.test.mjs +7366 -5728
- package/dist/clis/args/vetra-ports.test.mjs.map +1 -1
- package/dist/clis/args/vetra.d.mts +3 -2
- package/dist/clis/args/vetra.mjs +1 -1
- package/dist/clis/build-config-HbYUSZS1.mjs +252 -0
- package/dist/clis/build-config-HbYUSZS1.mjs.map +1 -0
- package/dist/clis/build-config.d.mts +52 -10616
- package/dist/clis/build-config.d.mts.map +1 -1
- package/dist/clis/build-config.mjs +2 -88
- package/dist/clis/build-pieces.d.mts +160 -0
- package/dist/clis/build-pieces.d.mts.map +1 -0
- package/dist/clis/build-pieces.mjs +549 -0
- package/dist/clis/build-pieces.mjs.map +1 -0
- package/dist/clis/command-names.d.mts +2 -2
- package/dist/clis/command-names.d.mts.map +1 -1
- package/dist/clis/command-names.mjs +1 -0
- package/dist/clis/command-names.mjs.map +1 -1
- package/dist/clis/constants.d.mts +3 -462
- package/dist/clis/constants.mjs +43 -12
- package/dist/clis/constants.mjs.map +1 -1
- package/dist/clis/feature-flags.d.mts +17 -0
- package/dist/clis/feature-flags.d.mts.map +1 -0
- package/dist/clis/feature-flags.mjs +21 -0
- package/dist/clis/feature-flags.mjs.map +1 -0
- package/dist/clis/index-6CZwrmQi.d.mts +11154 -0
- package/dist/clis/index-6CZwrmQi.d.mts.map +1 -0
- package/dist/clis/index.d.mts +1448 -1225
- package/dist/clis/index.d.mts.map +1 -1
- package/dist/clis/index.mjs +665 -352
- package/dist/clis/index.mjs.map +1 -1
- package/dist/clis/project-env.d.mts +4 -4
- package/dist/clis/project-env.d.mts.map +1 -1
- package/dist/clis/project-env.mjs.map +1 -1
- package/dist/clis/project-ports.d.mts +5 -5
- package/dist/clis/project-ports.d.mts.map +1 -1
- package/dist/clis/project-ports.mjs +1 -1
- package/dist/clis/project-ports.mjs.map +1 -1
- package/dist/clis/services/telemetry.d.mts +7 -7
- package/dist/clis/services/telemetry.d.mts.map +1 -1
- package/dist/clis/services/telemetry.mjs.map +1 -1
- package/dist/clis/types-DvsXtkR2.d.mts +582 -0
- package/dist/clis/types-DvsXtkR2.d.mts.map +1 -0
- package/dist/clis/utils.d.mts +4 -4
- package/dist/clis/utils.d.mts.map +1 -1
- package/dist/clis/utils.mjs.map +1 -1
- package/dist/{config-loader-B845Hidf.js → config-loader-DBJolZd0.js} +43 -9
- package/dist/config-loader-DBJolZd0.js.map +1 -0
- package/dist/connect/config-loader.d.ts +21 -8
- package/dist/connect/config-loader.d.ts.map +1 -1
- package/dist/connect/config-loader.js +2 -2
- package/dist/connect/index.d.ts +203 -57
- package/dist/connect/index.d.ts.map +1 -1
- package/dist/connect/index.js +318 -31
- package/dist/connect/index.js.map +1 -1
- package/dist/connect/json-adapter.d.ts +3 -4
- package/dist/connect/json-adapter.d.ts.map +1 -1
- package/dist/connect/json-adapter.js.map +1 -1
- package/dist/constants-DVJon33y.d.ts +9 -0
- package/dist/constants-DVJon33y.d.ts.map +1 -0
- package/dist/constants.d.ts +3 -2
- package/dist/constants.js +14 -5
- package/dist/constants.js.map +1 -1
- package/dist/document-drive/index.d.ts +131 -105
- package/dist/document-drive/index.d.ts.map +1 -1
- package/dist/document-drive/index.js +116 -54
- package/dist/document-drive/index.js.map +1 -1
- package/dist/document-model/errors.d.ts +3 -0
- package/dist/document-model/errors.js +152 -0
- package/dist/document-model/errors.js.map +1 -0
- package/dist/document-model/index.d.ts +5 -4
- package/dist/document-model/index.js +296 -390
- package/dist/document-model/index.js.map +1 -1
- package/dist/document-model/mock.d.ts +2 -3
- package/dist/document-model/mock.d.ts.map +1 -1
- package/dist/document-model/mock.js +2 -1
- package/dist/document-model/mock.js.map +1 -1
- package/dist/document-model/utils.d.ts +3 -2
- package/dist/document-model/utils.js +1 -1
- package/dist/document-model/version.d.ts +3 -0
- package/dist/document-model/version.js +8 -0
- package/dist/document-model/version.js.map +1 -0
- package/dist/index-bx0vYtFw.d.ts +36 -0
- package/dist/index-bx0vYtFw.d.ts.map +1 -0
- package/dist/index.d.ts +7 -6
- package/dist/index.js.map +1 -1
- package/dist/processors/index.d.ts +3 -2
- package/dist/processors/index.js +63 -4
- package/dist/processors/index.js.map +1 -1
- package/dist/purge-v06m_oGz.js +381 -0
- package/dist/purge-v06m_oGz.js.map +1 -0
- package/dist/registry/index.d.ts +15 -15
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +24 -6
- package/dist/registry/index.js.map +1 -1
- package/dist/registry/manifest-slim.d.ts +4 -3
- package/dist/registry/manifest-slim.d.ts.map +1 -1
- package/dist/registry/manifest-slim.js +21 -0
- package/dist/registry/manifest-slim.js.map +1 -1
- package/dist/registry/updates.d.ts +3 -3
- package/dist/registry/updates.d.ts.map +1 -1
- package/dist/registry/updates.js.map +1 -1
- package/dist/registry/urls.d.ts +2 -2
- package/dist/registry/urls.d.ts.map +1 -1
- package/dist/registry/urls.js.map +1 -1
- package/dist/{types-C1in4fl3.d.ts → types-Bsp8VL2y.d.ts} +2 -2
- package/dist/types-Bsp8VL2y.d.ts.map +1 -0
- package/dist/{types-YqLqb0Zb.d.ts → types-CfU91XFU.d.ts} +39 -43
- package/dist/types-CfU91XFU.d.ts.map +1 -0
- package/dist/{types-CpnWmiFY.d.ts → types-DzleLgA8.d.ts} +2038 -822
- package/dist/types-DzleLgA8.d.ts.map +1 -0
- package/dist/{utils-DP122OSS.d.ts → utils-BrKxCmKx.d.ts} +2 -2
- package/dist/utils-BrKxCmKx.d.ts.map +1 -0
- package/dist/{utils-aaTmfxFW.js → utils-CSF716ux.js} +10 -3
- package/dist/utils-CSF716ux.js.map +1 -0
- package/dist/version-BxLITo9P.d.ts +6 -0
- package/dist/version-BxLITo9P.d.ts.map +1 -0
- package/package.json +15 -6
- package/dist/clis/args/access-token--9H57y8J.d.mts +0 -18
- package/dist/clis/args/access-token--9H57y8J.d.mts.map +0 -1
- package/dist/clis/args/common-CcYbXrBx.mjs.map +0 -1
- package/dist/clis/args/common-Dsf1vpHV.d.mts +0 -183
- package/dist/clis/args/common-Dsf1vpHV.d.mts.map +0 -1
- package/dist/clis/args/connect-BVVvCmL9.mjs.map +0 -1
- package/dist/clis/args/connect-DetTnI8g.d.mts +0 -443
- package/dist/clis/args/connect-DetTnI8g.d.mts.map +0 -1
- package/dist/clis/args/generate-CA916Fvj.mjs.map +0 -1
- package/dist/clis/args/generate-DnV-bfXt.d.mts +0 -87
- package/dist/clis/args/generate-DnV-bfXt.d.mts.map +0 -1
- package/dist/clis/args/help-Bqbgbalu.mjs.map +0 -1
- package/dist/clis/args/help-CjAsudUn.d.mts +0 -193
- package/dist/clis/args/help-CjAsudUn.d.mts.map +0 -1
- package/dist/clis/args/init-CUXyfquF.d.mts +0 -55
- package/dist/clis/args/init-CUXyfquF.d.mts.map +0 -1
- package/dist/clis/args/inspect-DtZeoA5c.d.mts +0 -15
- package/dist/clis/args/inspect-DtZeoA5c.d.mts.map +0 -1
- package/dist/clis/args/install-CkP8zcHb.d.mts +0 -40
- package/dist/clis/args/install-CkP8zcHb.d.mts.map +0 -1
- package/dist/clis/args/list-BGf8s_gj.d.mts +0 -12
- package/dist/clis/args/list-BGf8s_gj.d.mts.map +0 -1
- package/dist/clis/args/login-DNsHwvqk.d.mts +0 -27
- package/dist/clis/args/login-DNsHwvqk.d.mts.map +0 -1
- package/dist/clis/args/magic-string.es-h_0HDQBQ.mjs +0 -1013
- package/dist/clis/args/magic-string.es-h_0HDQBQ.mjs.map +0 -1
- package/dist/clis/args/migrate-sixkWhxm.d.mts +0 -21
- package/dist/clis/args/migrate-sixkWhxm.d.mts.map +0 -1
- package/dist/clis/args/publish-Dqe5DUst.d.mts +0 -18
- package/dist/clis/args/publish-Dqe5DUst.d.mts.map +0 -1
- package/dist/clis/args/registry-C_RfTsKB.d.mts +0 -19
- package/dist/clis/args/registry-C_RfTsKB.d.mts.map +0 -1
- package/dist/clis/args/service-DhIkf8-O.d.mts +0 -22
- package/dist/clis/args/service-DhIkf8-O.d.mts.map +0 -1
- package/dist/clis/args/switchboard-BlPaq2at.d.mts +0 -72
- package/dist/clis/args/switchboard-BlPaq2at.d.mts.map +0 -1
- package/dist/clis/args/uninstall-BpA3YYbw.d.mts +0 -31
- package/dist/clis/args/uninstall-BpA3YYbw.d.mts.map +0 -1
- package/dist/clis/args/unpublish-CvwaIimG.d.mts +0 -24
- package/dist/clis/args/unpublish-CvwaIimG.d.mts.map +0 -1
- package/dist/clis/args/vetra-DLQ6lhLl.d.mts +0 -113
- package/dist/clis/args/vetra-DLQ6lhLl.d.mts.map +0 -1
- package/dist/clis/build-config.mjs.map +0 -1
- package/dist/clis/constants.d.mts.map +0 -1
- package/dist/config-loader-B845Hidf.js.map +0 -1
- package/dist/constants-BP_gjn8g.d.ts +0 -8
- package/dist/constants-BP_gjn8g.d.ts.map +0 -1
- package/dist/index-C_iVZe7f.d.ts +0 -7
- package/dist/index-C_iVZe7f.d.ts.map +0 -1
- package/dist/index-DyYIJtVy.d.ts +0 -836
- package/dist/index-DyYIJtVy.d.ts.map +0 -1
- package/dist/types-C1in4fl3.d.ts.map +0 -1
- package/dist/types-CpnWmiFY.d.ts.map +0 -1
- package/dist/types-YqLqb0Zb.d.ts.map +0 -1
- package/dist/utils-DP122OSS.d.ts.map +0 -1
- package/dist/utils-aaTmfxFW.js.map +0 -1
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import { l as bytesToBase64Url$1, n as generateId, s as buildOperationSignatureMessage, t as deriveOperationId } from "./utils-CSF716ux.js";
|
|
2
|
+
import { stringify } from "safe-stable-stringify";
|
|
3
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
4
|
+
//#region document-model/action-signature.ts
|
|
5
|
+
const ACTION_SIGNATURE_V2_PREFIX = "v2:";
|
|
6
|
+
const V2_HASH = /^v2:[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$/;
|
|
7
|
+
const V2_TIMESTAMP = /^[0-9]+$/;
|
|
8
|
+
const V2_SIGNATURE = /^0x[0-9a-f]{128}$/;
|
|
9
|
+
const LONE_SURROGATE = /\p{Cs}/u;
|
|
10
|
+
const PREIMAGE_FIELDS = [
|
|
11
|
+
"version",
|
|
12
|
+
"documentId",
|
|
13
|
+
"branch",
|
|
14
|
+
"scope",
|
|
15
|
+
"type",
|
|
16
|
+
"id",
|
|
17
|
+
"timestampUtcMs",
|
|
18
|
+
"input",
|
|
19
|
+
"signer.user.address",
|
|
20
|
+
"signer.user.networkId",
|
|
21
|
+
"signer.user.chainId",
|
|
22
|
+
"signer.app.key"
|
|
23
|
+
];
|
|
24
|
+
/** A value that would not survive a JSON store round trip unchanged. */
|
|
25
|
+
var CanonicalJsonError = class extends Error {
|
|
26
|
+
constructor(path, detail) {
|
|
27
|
+
super(`Cannot canonicalize ${path}: ${detail}`);
|
|
28
|
+
this.name = "CanonicalJsonError";
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
/** Sorted-key JSON, as the state hash encodes; drops `undefined` properties. */
|
|
32
|
+
function canonicalJson(value, label = "value") {
|
|
33
|
+
assertCanonical(value, label, /* @__PURE__ */ new Set());
|
|
34
|
+
return stringify(value);
|
|
35
|
+
}
|
|
36
|
+
/** Actions the reactor reduces itself, onto the document scope. */
|
|
37
|
+
const DOCUMENT_SCOPE_ACTION_TYPES = /* @__PURE__ */ new Set([
|
|
38
|
+
"CREATE_DOCUMENT",
|
|
39
|
+
"DELETE_DOCUMENT",
|
|
40
|
+
"UPGRADE_DOCUMENT",
|
|
41
|
+
"ADD_RELATIONSHIP",
|
|
42
|
+
"REMOVE_RELATIONSHIP",
|
|
43
|
+
"UPDATE_RELATIONSHIP",
|
|
44
|
+
"PURGE_DOCUMENT"
|
|
45
|
+
]);
|
|
46
|
+
/** Where a document-scope action writes: `sourceId` or `documentId`. */
|
|
47
|
+
function targetDocumentId(action, fallback) {
|
|
48
|
+
const input = action.input;
|
|
49
|
+
if (action.type === "ADD_RELATIONSHIP" || action.type === "REMOVE_RELATIONSHIP" || action.type === "UPDATE_RELATIONSHIP") return typeof input?.sourceId === "string" && input.sourceId.length > 0 ? input.sourceId : fallback;
|
|
50
|
+
return typeof input?.documentId === "string" && input.documentId.length > 0 ? input.documentId : fallback;
|
|
51
|
+
}
|
|
52
|
+
/** The log an action submitted to a job on `documentId` is stored in. */
|
|
53
|
+
function actionSigningTarget(action, documentId, branch) {
|
|
54
|
+
return {
|
|
55
|
+
documentId: DOCUMENT_SCOPE_ACTION_TYPES.has(action.type) ? targetDocumentId(action, documentId) : documentId,
|
|
56
|
+
branch
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** The identity a signer writes into `context.signer`, and signs over. */
|
|
60
|
+
function actionSignerIdentity(signer) {
|
|
61
|
+
return {
|
|
62
|
+
user: {
|
|
63
|
+
address: signer.user?.address ?? "",
|
|
64
|
+
networkId: signer.user?.networkId ?? "",
|
|
65
|
+
chainId: signer.user?.chainId ?? 0
|
|
66
|
+
},
|
|
67
|
+
app: {
|
|
68
|
+
name: signer.app?.name ?? "",
|
|
69
|
+
key: signer.app?.key ?? ""
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/** The v2 preimage; throws `CanonicalJsonError` on an unsignable action. */
|
|
74
|
+
function actionPreimageV2(action, target, signer) {
|
|
75
|
+
if (!target.documentId) throw new CanonicalJsonError("documentId", "must not be empty");
|
|
76
|
+
if (!target.branch) throw new CanonicalJsonError("branch", "must not be empty");
|
|
77
|
+
if (action.input === void 0) throw new CanonicalJsonError("input", `action ${action.id} (${action.type}) has no input`);
|
|
78
|
+
const fields = [
|
|
79
|
+
"v2",
|
|
80
|
+
target.documentId,
|
|
81
|
+
target.branch,
|
|
82
|
+
action.scope,
|
|
83
|
+
action.type,
|
|
84
|
+
action.id,
|
|
85
|
+
action.timestampUtcMs,
|
|
86
|
+
action.input,
|
|
87
|
+
signer.user.address,
|
|
88
|
+
signer.user.networkId,
|
|
89
|
+
signer.user.chainId,
|
|
90
|
+
signer.app.key
|
|
91
|
+
];
|
|
92
|
+
fields.forEach((field, i) => {
|
|
93
|
+
assertCanonical(field, PREIMAGE_FIELDS[i], /* @__PURE__ */ new Set());
|
|
94
|
+
});
|
|
95
|
+
return stringify(fields);
|
|
96
|
+
}
|
|
97
|
+
/** `"v2:" + base64url(sha256(preimage))`, unpadded. */
|
|
98
|
+
async function hashActionV2(action, target, signer) {
|
|
99
|
+
const preimage = actionPreimageV2(action, target, signer);
|
|
100
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(preimage));
|
|
101
|
+
return "v2:" + bytesToBase64Url(new Uint8Array(digest));
|
|
102
|
+
}
|
|
103
|
+
/** Signs `action` as a v2 tuple; the message layout is the legacy one. */
|
|
104
|
+
async function signActionV2(params) {
|
|
105
|
+
const { action, target, signer, sign } = params;
|
|
106
|
+
const previousStateHash = params.previousStateHash ?? "";
|
|
107
|
+
if (previousStateHash.includes(", ")) throw new Error(`Cannot sign action ${action.id}: the previous state hash contains ", "`);
|
|
108
|
+
const tuple = [
|
|
109
|
+
(Date.now() / 1e3).toFixed(0),
|
|
110
|
+
signer.app.key,
|
|
111
|
+
await hashActionV2(action, target, signer),
|
|
112
|
+
previousStateHash
|
|
113
|
+
];
|
|
114
|
+
const signature = await sign(buildOperationSignatureMessage(tuple));
|
|
115
|
+
if (signature.length !== 64) throw new Error(`Cannot sign action ${action.id}: expected a 64-byte P-256 signature, got ${signature.length} bytes`);
|
|
116
|
+
return [...tuple, `0x${bytesToHex(signature)}`];
|
|
117
|
+
}
|
|
118
|
+
/** Element [2] carries the v2 prefix, whether or not it is well formed. */
|
|
119
|
+
function isV2ActionHash(hash) {
|
|
120
|
+
return hash.startsWith("v2:");
|
|
121
|
+
}
|
|
122
|
+
/** The strict shape of a v2 tuple, apart from what its hash covers. */
|
|
123
|
+
function v2TupleProblem(tuple) {
|
|
124
|
+
if (!V2_TIMESTAMP.test(tuple[0])) return "signing time is not decimal seconds";
|
|
125
|
+
if (!V2_HASH.test(tuple[2])) return "hash is not v2: and 43 base64url characters";
|
|
126
|
+
if (!V2_SIGNATURE.test(tuple[4])) return "signature is not 0x and 128 lowercase hex digits";
|
|
127
|
+
}
|
|
128
|
+
function assertCanonical(value, path, ancestors) {
|
|
129
|
+
switch (typeof value) {
|
|
130
|
+
case "string":
|
|
131
|
+
if (LONE_SURROGATE.test(value)) throw new CanonicalJsonError(path, "string holds a lone surrogate");
|
|
132
|
+
return;
|
|
133
|
+
case "boolean": return;
|
|
134
|
+
case "number":
|
|
135
|
+
if (!Number.isFinite(value)) throw new CanonicalJsonError(path, `${value} is not a JSON number`);
|
|
136
|
+
return;
|
|
137
|
+
case "undefined": throw new CanonicalJsonError(path, "undefined is not a JSON value");
|
|
138
|
+
case "bigint": throw new CanonicalJsonError(path, "BigInt is not a JSON value");
|
|
139
|
+
case "function":
|
|
140
|
+
case "symbol": throw new CanonicalJsonError(path, `${typeof value} is not a JSON value`);
|
|
141
|
+
}
|
|
142
|
+
if (value === null) return;
|
|
143
|
+
const object = value;
|
|
144
|
+
if (ancestors.has(object)) throw new CanonicalJsonError(path, "value is circular");
|
|
145
|
+
const toJSON = object.toJSON;
|
|
146
|
+
if (typeof toJSON === "function") {
|
|
147
|
+
assertCanonical(toJSON.call(object), path, new Set(ancestors).add(object));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
ancestors.add(object);
|
|
151
|
+
if (Array.isArray(object)) for (let i = 0; i < object.length; i++) {
|
|
152
|
+
if (!(i in object)) throw new CanonicalJsonError(`${path}[${i}]`, "array is sparse");
|
|
153
|
+
assertCanonical(object[i], `${path}[${i}]`, ancestors);
|
|
154
|
+
}
|
|
155
|
+
else for (const [key, child] of Object.entries(object)) {
|
|
156
|
+
if (LONE_SURROGATE.test(key)) throw new CanonicalJsonError(path, "key holds a lone surrogate");
|
|
157
|
+
if (child === void 0) continue;
|
|
158
|
+
assertCanonical(child, `${path}.${key}`, ancestors);
|
|
159
|
+
}
|
|
160
|
+
ancestors.delete(object);
|
|
161
|
+
}
|
|
162
|
+
function bytesToBase64Url(bytes) {
|
|
163
|
+
let binary = "";
|
|
164
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
165
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
166
|
+
}
|
|
167
|
+
function bytesToHex(bytes) {
|
|
168
|
+
return Array.from(bytes).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
169
|
+
}
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region document-model/peer-agreement.ts
|
|
172
|
+
/** A purged document's protocol; never preferred, so creation never selects it. */
|
|
173
|
+
const DOCUMENT_PURGE_PROTOCOL = "document-purge";
|
|
174
|
+
/** A peer that takes refusals of polled purge markers on the poll. */
|
|
175
|
+
const MARKER_REFUSAL_FEATURE = "marker-refusal";
|
|
176
|
+
const PEER_CAPABILITIES = [
|
|
177
|
+
{
|
|
178
|
+
kind: "protocol",
|
|
179
|
+
name: "base-reducer",
|
|
180
|
+
baseline: [1, 2],
|
|
181
|
+
supported: () => [1, 2],
|
|
182
|
+
preferred: () => 2,
|
|
183
|
+
optional: false
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
kind: "protocol",
|
|
187
|
+
name: "signature",
|
|
188
|
+
baseline: [2],
|
|
189
|
+
supported: () => [2],
|
|
190
|
+
optional: true
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
kind: "protocol",
|
|
194
|
+
name: DOCUMENT_PURGE_PROTOCOL,
|
|
195
|
+
baseline: [],
|
|
196
|
+
supported: () => [1],
|
|
197
|
+
optional: true
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
kind: "feature",
|
|
201
|
+
name: MARKER_REFUSAL_FEATURE,
|
|
202
|
+
baseline: [],
|
|
203
|
+
supported: () => [1]
|
|
204
|
+
}
|
|
205
|
+
];
|
|
206
|
+
/** `base` plus `extra`; an extra replaces a base entry of the same name. */
|
|
207
|
+
function mergePeerCapabilities(base, extra) {
|
|
208
|
+
const key = (capability) => `${capability.kind}:${capability.name}`;
|
|
209
|
+
const replaced = new Set(extra.map(key));
|
|
210
|
+
return [...base.filter((capability) => !replaced.has(key(capability))), ...extra];
|
|
211
|
+
}
|
|
212
|
+
const PEER_MANIFEST_FORMAT = 1;
|
|
213
|
+
function versionSet(values) {
|
|
214
|
+
return [...new Set(values)].sort((a, b) => a - b);
|
|
215
|
+
}
|
|
216
|
+
function supportsFrom(capabilities, values) {
|
|
217
|
+
const supports = {
|
|
218
|
+
protocols: {},
|
|
219
|
+
features: {}
|
|
220
|
+
};
|
|
221
|
+
for (const capability of capabilities) {
|
|
222
|
+
const target = capability.kind === "protocol" ? supports.protocols : supports.features;
|
|
223
|
+
target[capability.name] = versionSet(values(capability));
|
|
224
|
+
}
|
|
225
|
+
return supports;
|
|
226
|
+
}
|
|
227
|
+
/** What this reactor supports, for every capability it registers. */
|
|
228
|
+
function localSupports(capabilities, flags) {
|
|
229
|
+
return supportsFrom(capabilities, (capability) => capability.supported(flags));
|
|
230
|
+
}
|
|
231
|
+
/** What a peer that announces nothing supports. */
|
|
232
|
+
function legacySupports(capabilities) {
|
|
233
|
+
return supportsFrom(capabilities, (capability) => capability.baseline);
|
|
234
|
+
}
|
|
235
|
+
function manifestRevision(supports, sequence = 0) {
|
|
236
|
+
const preimage = canonicalJson({
|
|
237
|
+
protocols: supports.protocols,
|
|
238
|
+
features: supports.features,
|
|
239
|
+
sequence
|
|
240
|
+
}, "peer manifest");
|
|
241
|
+
return bytesToBase64Url$1(sha256(new TextEncoder().encode(preimage)));
|
|
242
|
+
}
|
|
243
|
+
function localPeerManifest(capabilities, flags, appKey, sequence = 0) {
|
|
244
|
+
const supports = localSupports(capabilities, flags);
|
|
245
|
+
return {
|
|
246
|
+
format: 1,
|
|
247
|
+
...appKey !== void 0 ? { appKey } : {},
|
|
248
|
+
sequence,
|
|
249
|
+
revision: manifestRevision(supports, sequence),
|
|
250
|
+
protocols: supports.protocols,
|
|
251
|
+
features: supports.features
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/** A manifest sent before the one already held; silence carries no sequence. */
|
|
255
|
+
function isOlderManifest(next, held) {
|
|
256
|
+
return next !== null && held != null && next.sequence < held.sequence;
|
|
257
|
+
}
|
|
258
|
+
/** A peer's manifest, or the baselines for a peer that announced none. */
|
|
259
|
+
function peerSupports(manifest, capabilities) {
|
|
260
|
+
return manifest ?? legacySupports(capabilities);
|
|
261
|
+
}
|
|
262
|
+
function readVersionMap(value) {
|
|
263
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return;
|
|
264
|
+
const map = {};
|
|
265
|
+
for (const [name, versions] of Object.entries(value)) {
|
|
266
|
+
if (!Array.isArray(versions) || !versions.every((v) => Number.isInteger(v))) return;
|
|
267
|
+
map[name] = versionSet(versions);
|
|
268
|
+
}
|
|
269
|
+
return map;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* A manifest as received from a peer, or null when it is not one. Formats only
|
|
273
|
+
* add fields, so one of an unknown format is read as its two maps.
|
|
274
|
+
*/
|
|
275
|
+
function readPeerManifest(value) {
|
|
276
|
+
if (typeof value !== "object" || value === null) return null;
|
|
277
|
+
const raw = value;
|
|
278
|
+
const protocols = readVersionMap(raw.protocols);
|
|
279
|
+
const features = readVersionMap(raw.features ?? {});
|
|
280
|
+
if (!protocols || !features) return null;
|
|
281
|
+
const sequence = Number.isSafeInteger(raw.sequence) ? raw.sequence : 0;
|
|
282
|
+
return {
|
|
283
|
+
format: 1,
|
|
284
|
+
...typeof raw.appKey === "string" ? { appKey: raw.appKey } : {},
|
|
285
|
+
sequence,
|
|
286
|
+
revision: typeof raw.revision === "string" ? raw.revision : manifestRevision({
|
|
287
|
+
protocols,
|
|
288
|
+
features
|
|
289
|
+
}, sequence),
|
|
290
|
+
protocols,
|
|
291
|
+
features
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
/** Only keys this reactor registers are judged; an absent key agrees. */
|
|
295
|
+
function holdReason(peer, versions, capabilities) {
|
|
296
|
+
for (const capability of capabilities) {
|
|
297
|
+
if (capability.kind !== "protocol") continue;
|
|
298
|
+
const version = versions[capability.name];
|
|
299
|
+
if (version === void 0) continue;
|
|
300
|
+
const supported = peer.protocols[capability.name] ?? [];
|
|
301
|
+
if (!supported.includes(version)) return {
|
|
302
|
+
protocol: capability.name,
|
|
303
|
+
version,
|
|
304
|
+
peerSupports: supported
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/** Whether a peer runs every version this reactor does, so nothing is held. */
|
|
309
|
+
function coversLocal(peer, local, capabilities) {
|
|
310
|
+
for (const capability of capabilities) {
|
|
311
|
+
if (capability.kind !== "protocol") continue;
|
|
312
|
+
const theirs = peer.protocols[capability.name] ?? [];
|
|
313
|
+
if (!(local.protocols[capability.name] ?? []).every((version) => theirs.includes(version))) return false;
|
|
314
|
+
}
|
|
315
|
+
return true;
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* protocolVersions for a new document: per negotiated protocol, the highest
|
|
319
|
+
* version up to the local preference that every member supports, else the
|
|
320
|
+
* lowest local one. `requested` wins over what is selected.
|
|
321
|
+
*/
|
|
322
|
+
function selectProtocolVersions(input) {
|
|
323
|
+
const members = [...input.members];
|
|
324
|
+
const selected = {};
|
|
325
|
+
for (const capability of input.capabilities) {
|
|
326
|
+
if (capability.kind !== "protocol" || !capability.preferred) continue;
|
|
327
|
+
const preferred = capability.preferred(input.flags);
|
|
328
|
+
const supported = capability.supported(input.flags);
|
|
329
|
+
let agreed = supported.filter((version) => version <= preferred);
|
|
330
|
+
for (const member of members) {
|
|
331
|
+
const theirs = member.protocols[capability.name] ?? [];
|
|
332
|
+
agreed = agreed.filter((version) => theirs.includes(version));
|
|
333
|
+
}
|
|
334
|
+
selected[capability.name] = agreed.length > 0 ? Math.max(...agreed) : Math.min(...supported);
|
|
335
|
+
}
|
|
336
|
+
return {
|
|
337
|
+
...selected,
|
|
338
|
+
...input.requested
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
//#endregion
|
|
342
|
+
//#region document-model/purge.ts
|
|
343
|
+
const PURGE_DOCUMENT = "PURGE_DOCUMENT";
|
|
344
|
+
function isPurgeMarker(value) {
|
|
345
|
+
return ("operation" in value ? value.operation.action : "action" in value ? value.action : value)?.type === PURGE_DOCUMENT;
|
|
346
|
+
}
|
|
347
|
+
/** An unsigned marker; `purgedAtUtcIso` is the action's own timestamp. */
|
|
348
|
+
function purgeDocumentAction(input, options = {}) {
|
|
349
|
+
const timestampUtcMs = options.timestampUtcMs ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
350
|
+
return {
|
|
351
|
+
id: options.id ?? generateId(),
|
|
352
|
+
type: PURGE_DOCUMENT,
|
|
353
|
+
scope: "document",
|
|
354
|
+
timestampUtcMs,
|
|
355
|
+
input: {
|
|
356
|
+
documentId: input.documentId,
|
|
357
|
+
documentType: input.documentType,
|
|
358
|
+
purgedAtUtcIso: timestampUtcMs,
|
|
359
|
+
requestId: input.requestId
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
/** The sole row of a purged stream: document/main, index 0, skip 0, hash "". */
|
|
364
|
+
function purgeMarkerOperation(action) {
|
|
365
|
+
return {
|
|
366
|
+
id: deriveOperationId(action.input.documentId, "document", "main", action.id),
|
|
367
|
+
index: 0,
|
|
368
|
+
skip: 0,
|
|
369
|
+
timestampUtcMs: action.timestampUtcMs,
|
|
370
|
+
hash: "",
|
|
371
|
+
action
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
/** Protocol versions of a purged id; derived, never stored. */
|
|
375
|
+
function purgedProtocolVersions() {
|
|
376
|
+
return { [DOCUMENT_PURGE_PROTOCOL]: 1 };
|
|
377
|
+
}
|
|
378
|
+
//#endregion
|
|
379
|
+
export { signActionV2 as A, DOCUMENT_SCOPE_ACTION_TYPES as C, canonicalJson as D, actionSigningTarget as E, v2TupleProblem as M, hashActionV2 as O, CanonicalJsonError as S, actionSignerIdentity as T, mergePeerCapabilities as _, purgedProtocolVersions as a, selectProtocolVersions as b, PEER_CAPABILITIES as c, holdReason as d, isOlderManifest as f, manifestRevision as g, localSupports as h, purgeMarkerOperation as i, targetDocumentId as j, isV2ActionHash as k, PEER_MANIFEST_FORMAT as l, localPeerManifest as m, isPurgeMarker as n, DOCUMENT_PURGE_PROTOCOL as o, legacySupports as p, purgeDocumentAction as r, MARKER_REFUSAL_FEATURE as s, PURGE_DOCUMENT as t, coversLocal as u, peerSupports as v, actionPreimageV2 as w, ACTION_SIGNATURE_V2_PREFIX as x, readPeerManifest as y };
|
|
380
|
+
|
|
381
|
+
//# sourceMappingURL=purge-v06m_oGz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purge-v06m_oGz.js","names":["stringifyJson","bytesToBase64Url"],"sources":["../document-model/action-signature.ts","../document-model/peer-agreement.ts","../document-model/purge.ts"],"sourcesContent":["import { stringify as stringifyJson } from \"safe-stable-stringify\";\nimport type { Action } from \"./actions.js\";\nimport { buildOperationSignatureMessage } from \"./crypto.js\";\nimport type {\n AppActionSigner,\n Signature,\n UserActionSigner,\n} from \"./signatures.js\";\nimport type { ActionSigningHandler } from \"./types.js\";\n\nexport const ACTION_SIGNATURE_V2_PREFIX = \"v2:\";\n\n// 32 bytes: 42 free characters, then one whose low two bits are zero.\nconst V2_HASH = /^v2:[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$/;\nconst V2_TIMESTAMP = /^[0-9]+$/;\nconst V2_SIGNATURE = /^0x[0-9a-f]{128}$/;\nconst LONE_SURROGATE = /\\p{Cs}/u;\nconst PREIMAGE_FIELDS = [\n \"version\",\n \"documentId\",\n \"branch\",\n \"scope\",\n \"type\",\n \"id\",\n \"timestampUtcMs\",\n \"input\",\n \"signer.user.address\",\n \"signer.user.networkId\",\n \"signer.user.chainId\",\n \"signer.app.key\",\n];\n\n/** The log an operation is stored in, which a v2 tuple is bound to. */\nexport type ActionSigningTarget = {\n documentId: string;\n branch: string;\n};\n\n/** Who a v2 tuple attributes the action to; both halves are in the preimage. */\nexport type ActionSignerIdentity = {\n user: UserActionSigner;\n app: AppActionSigner;\n};\n\n/** A value that would not survive a JSON store round trip unchanged. */\nexport class CanonicalJsonError extends Error {\n constructor(path: string, detail: string) {\n super(`Cannot canonicalize ${path}: ${detail}`);\n this.name = \"CanonicalJsonError\";\n }\n}\n\n/** Sorted-key JSON, as the state hash encodes; drops `undefined` properties. */\nexport function canonicalJson(value: unknown, label = \"value\"): string {\n assertCanonical(value, label, new Set());\n return stringifyJson(value) as string;\n}\n\n/** Actions the reactor reduces itself, onto the document scope. */\nexport const DOCUMENT_SCOPE_ACTION_TYPES: ReadonlySet<string> = new Set([\n \"CREATE_DOCUMENT\",\n \"DELETE_DOCUMENT\",\n \"UPGRADE_DOCUMENT\",\n \"ADD_RELATIONSHIP\",\n \"REMOVE_RELATIONSHIP\",\n \"UPDATE_RELATIONSHIP\",\n \"PURGE_DOCUMENT\",\n]);\n\n/** Where a document-scope action writes: `sourceId` or `documentId`. */\nexport function targetDocumentId(\n action: { type: string; input: unknown },\n fallback: string,\n): string {\n const input = action.input as\n | { documentId?: unknown; sourceId?: unknown }\n | undefined;\n\n if (\n action.type === \"ADD_RELATIONSHIP\" ||\n action.type === \"REMOVE_RELATIONSHIP\" ||\n action.type === \"UPDATE_RELATIONSHIP\"\n ) {\n return typeof input?.sourceId === \"string\" && input.sourceId.length > 0\n ? input.sourceId\n : fallback;\n }\n\n return typeof input?.documentId === \"string\" && input.documentId.length > 0\n ? input.documentId\n : fallback;\n}\n\n/** The log an action submitted to a job on `documentId` is stored in. */\nexport function actionSigningTarget(\n action: { type: string; input: unknown },\n documentId: string,\n branch: string,\n): ActionSigningTarget {\n return {\n documentId: DOCUMENT_SCOPE_ACTION_TYPES.has(action.type)\n ? targetDocumentId(action, documentId)\n : documentId,\n branch,\n };\n}\n\n/** The identity a signer writes into `context.signer`, and signs over. */\nexport function actionSignerIdentity(signer: {\n user?: UserActionSigner;\n app?: AppActionSigner;\n}): ActionSignerIdentity {\n return {\n user: {\n address: signer.user?.address ?? \"\",\n networkId: signer.user?.networkId ?? \"\",\n chainId: signer.user?.chainId ?? 0,\n },\n app: {\n name: signer.app?.name ?? \"\",\n key: signer.app?.key ?? \"\",\n },\n };\n}\n\n/** The v2 preimage; throws `CanonicalJsonError` on an unsignable action. */\nexport function actionPreimageV2(\n action: Action,\n target: ActionSigningTarget,\n signer: ActionSignerIdentity,\n): string {\n if (!target.documentId) {\n throw new CanonicalJsonError(\"documentId\", \"must not be empty\");\n }\n if (!target.branch) {\n throw new CanonicalJsonError(\"branch\", \"must not be empty\");\n }\n if (action.input === undefined) {\n throw new CanonicalJsonError(\n \"input\",\n `action ${action.id} (${action.type}) has no input`,\n );\n }\n const fields: unknown[] = [\n \"v2\",\n target.documentId,\n target.branch,\n action.scope,\n action.type,\n action.id,\n action.timestampUtcMs,\n action.input,\n signer.user.address,\n signer.user.networkId,\n signer.user.chainId,\n signer.app.key,\n ];\n fields.forEach((field, i) => {\n assertCanonical(field, PREIMAGE_FIELDS[i], new Set());\n });\n return stringifyJson(fields) as string;\n}\n\n/** `\"v2:\" + base64url(sha256(preimage))`, unpadded. */\nexport async function hashActionV2(\n action: Action,\n target: ActionSigningTarget,\n signer: ActionSignerIdentity,\n): Promise<string> {\n const preimage = actionPreimageV2(action, target, signer);\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(preimage),\n );\n return ACTION_SIGNATURE_V2_PREFIX + bytesToBase64Url(new Uint8Array(digest));\n}\n\n/** Signs `action` as a v2 tuple; the message layout is the legacy one. */\nexport async function signActionV2(params: {\n action: Action;\n target: ActionSigningTarget;\n signer: ActionSignerIdentity;\n sign: ActionSigningHandler;\n previousStateHash?: string;\n}): Promise<Signature> {\n const { action, target, signer, sign } = params;\n const previousStateHash = params.previousStateHash ?? \"\";\n if (previousStateHash.includes(\", \")) {\n throw new Error(\n `Cannot sign action ${action.id}: the previous state hash contains \", \"`,\n );\n }\n\n const tuple: [string, string, string, string] = [\n (Date.now() / 1000).toFixed(0),\n signer.app.key,\n await hashActionV2(action, target, signer),\n previousStateHash,\n ];\n const signature = await sign(buildOperationSignatureMessage(tuple));\n if (signature.length !== 64) {\n throw new Error(\n `Cannot sign action ${action.id}: expected a 64-byte P-256 signature, got ${signature.length} bytes`,\n );\n }\n return [...tuple, `0x${bytesToHex(signature)}`];\n}\n\n/** Element [2] carries the v2 prefix, whether or not it is well formed. */\nexport function isV2ActionHash(hash: string): boolean {\n return hash.startsWith(ACTION_SIGNATURE_V2_PREFIX);\n}\n\n/** The strict shape of a v2 tuple, apart from what its hash covers. */\nexport function v2TupleProblem(tuple: Signature): string | undefined {\n if (!V2_TIMESTAMP.test(tuple[0])) {\n return \"signing time is not decimal seconds\";\n }\n if (!V2_HASH.test(tuple[2])) {\n return \"hash is not v2: and 43 base64url characters\";\n }\n if (!V2_SIGNATURE.test(tuple[4])) {\n return \"signature is not 0x and 128 lowercase hex digits\";\n }\n return undefined;\n}\n\nfunction assertCanonical(\n value: unknown,\n path: string,\n ancestors: Set<object>,\n): void {\n switch (typeof value) {\n case \"string\":\n if (LONE_SURROGATE.test(value)) {\n throw new CanonicalJsonError(path, \"string holds a lone surrogate\");\n }\n return;\n case \"boolean\":\n return;\n case \"number\":\n if (!Number.isFinite(value)) {\n throw new CanonicalJsonError(path, `${value} is not a JSON number`);\n }\n return;\n case \"undefined\":\n throw new CanonicalJsonError(path, \"undefined is not a JSON value\");\n case \"bigint\":\n throw new CanonicalJsonError(path, \"BigInt is not a JSON value\");\n case \"function\":\n case \"symbol\":\n throw new CanonicalJsonError(path, `${typeof value} is not a JSON value`);\n }\n\n if (value === null) {\n return;\n }\n\n const object = value as object;\n if (ancestors.has(object)) {\n throw new CanonicalJsonError(path, \"value is circular\");\n }\n\n const toJSON = (object as { toJSON?: unknown }).toJSON;\n if (typeof toJSON === \"function\") {\n assertCanonical(\n (toJSON as () => unknown).call(object),\n path,\n new Set(ancestors).add(object),\n );\n return;\n }\n\n ancestors.add(object);\n if (Array.isArray(object)) {\n for (let i = 0; i < object.length; i++) {\n if (!(i in object)) {\n throw new CanonicalJsonError(`${path}[${i}]`, \"array is sparse\");\n }\n assertCanonical(object[i], `${path}[${i}]`, ancestors);\n }\n } else {\n for (const [key, child] of Object.entries(object)) {\n if (LONE_SURROGATE.test(key)) {\n throw new CanonicalJsonError(path, \"key holds a lone surrogate\");\n }\n if (child === undefined) {\n continue;\n }\n assertCanonical(child, `${path}.${key}`, ancestors);\n }\n }\n ancestors.delete(object);\n}\n\nfunction bytesToBase64Url(bytes: Uint8Array): string {\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n","import { sha256 } from \"@noble/hashes/sha2.js\";\nimport { canonicalJson } from \"./action-signature.js\";\nimport { bytesToBase64Url } from \"./crypto.js\";\n\n/** The reactor feature flags a capability's support is a function of. */\nexport type PeerCapabilityFlags = {\n readonly [flag: string]: boolean | undefined;\n};\n\n/** A document protocol, named by its `protocolVersions` key. */\nexport type ProtocolCapability = {\n kind: \"protocol\";\n name: string;\n /** What a peer that announces nothing is assumed to support. */\n baseline: readonly number[];\n supported(flags: PeerCapabilityFlags): readonly number[];\n /** The version new documents take when peers agree. Absent: not negotiated. */\n preferred?(flags: PeerCapabilityFlags): number;\n /** A header may omit the key. */\n optional: boolean;\n};\n\n/** A feature that changes what a peer sends or expects on the wire. */\nexport type FeatureCapability = {\n kind: \"feature\";\n name: string;\n baseline: readonly number[];\n supported(flags: PeerCapabilityFlags): readonly number[];\n};\n\nexport type PeerCapability = ProtocolCapability | FeatureCapability;\n\n/** A purged document's protocol; never preferred, so creation never selects it. */\nexport const DOCUMENT_PURGE_PROTOCOL = \"document-purge\";\n\n/** A peer that takes refusals of polled purge markers on the poll. */\nexport const MARKER_REFUSAL_FEATURE = \"marker-refusal\";\n\n// Baselines are frozen at what the last release without peer agreement runs.\nexport const PEER_CAPABILITIES: readonly PeerCapability[] = [\n {\n kind: \"protocol\",\n name: \"base-reducer\",\n baseline: [1, 2],\n supported: () => [1, 2],\n preferred: () => 2,\n optional: false,\n },\n {\n kind: \"protocol\",\n name: \"signature\",\n baseline: [2],\n supported: () => [2],\n optional: true,\n },\n {\n kind: \"protocol\",\n name: DOCUMENT_PURGE_PROTOCOL,\n baseline: [],\n supported: () => [1],\n optional: true,\n },\n {\n kind: \"feature\",\n name: MARKER_REFUSAL_FEATURE,\n baseline: [],\n supported: () => [1],\n },\n];\n\n/** `base` plus `extra`; an extra replaces a base entry of the same name. */\nexport function mergePeerCapabilities(\n base: readonly PeerCapability[],\n extra: readonly PeerCapability[],\n): PeerCapability[] {\n const key = (capability: PeerCapability) =>\n `${capability.kind}:${capability.name}`;\n const replaced = new Set(extra.map(key));\n return [\n ...base.filter((capability) => !replaced.has(key(capability))),\n ...extra,\n ];\n}\n\nexport const PEER_MANIFEST_FORMAT = 1;\n\nexport type Supports = {\n protocols: { [protocol: string]: readonly number[] };\n features: { [feature: string]: readonly number[] };\n};\n\nexport type PeerManifest = Supports & {\n format: 1;\n /** The signer's did:key, when configured; informational. */\n appKey?: string;\n /** Grows with every start of the reactor; a peer ignores an older one. */\n sequence: number;\n /** base64url(sha256(canonicalJson(Supports & { sequence }))) */\n revision: string;\n};\n\nfunction versionSet(values: readonly number[]): number[] {\n return [...new Set(values)].sort((a, b) => a - b);\n}\n\nfunction supportsFrom(\n capabilities: readonly PeerCapability[],\n values: (capability: PeerCapability) => readonly number[],\n): Supports {\n const supports: Supports = { protocols: {}, features: {} };\n for (const capability of capabilities) {\n const target =\n capability.kind === \"protocol\" ? supports.protocols : supports.features;\n target[capability.name] = versionSet(values(capability));\n }\n return supports;\n}\n\n/** What this reactor supports, for every capability it registers. */\nexport function localSupports(\n capabilities: readonly PeerCapability[],\n flags: PeerCapabilityFlags,\n): Supports {\n return supportsFrom(capabilities, (capability) =>\n capability.supported(flags),\n );\n}\n\n/** What a peer that announces nothing supports. */\nexport function legacySupports(\n capabilities: readonly PeerCapability[],\n): Supports {\n return supportsFrom(capabilities, (capability) => capability.baseline);\n}\n\nexport function manifestRevision(supports: Supports, sequence = 0): string {\n const preimage = canonicalJson(\n { protocols: supports.protocols, features: supports.features, sequence },\n \"peer manifest\",\n );\n return bytesToBase64Url(sha256(new TextEncoder().encode(preimage)));\n}\n\nexport function localPeerManifest(\n capabilities: readonly PeerCapability[],\n flags: PeerCapabilityFlags,\n appKey?: string,\n sequence = 0,\n): PeerManifest {\n const supports = localSupports(capabilities, flags);\n return {\n format: PEER_MANIFEST_FORMAT,\n ...(appKey !== undefined ? { appKey } : {}),\n sequence,\n revision: manifestRevision(supports, sequence),\n protocols: supports.protocols,\n features: supports.features,\n };\n}\n\n/** A manifest sent before the one already held; silence carries no sequence. */\nexport function isOlderManifest(\n next: PeerManifest | null,\n held: PeerManifest | null | undefined,\n): boolean {\n return next !== null && held != null && next.sequence < held.sequence;\n}\n\n/** A peer's manifest, or the baselines for a peer that announced none. */\nexport function peerSupports(\n manifest: PeerManifest | null,\n capabilities: readonly PeerCapability[],\n): Supports {\n return manifest ?? legacySupports(capabilities);\n}\n\nfunction readVersionMap(\n value: unknown,\n): { [name: string]: readonly number[] } | undefined {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n return undefined;\n }\n const map: { [name: string]: readonly number[] } = {};\n for (const [name, versions] of Object.entries(value)) {\n if (\n !Array.isArray(versions) ||\n !versions.every((v) => Number.isInteger(v))\n ) {\n return undefined;\n }\n map[name] = versionSet(versions as number[]);\n }\n return map;\n}\n\n/**\n * A manifest as received from a peer, or null when it is not one. Formats only\n * add fields, so one of an unknown format is read as its two maps.\n */\nexport function readPeerManifest(value: unknown): PeerManifest | null {\n if (typeof value !== \"object\" || value === null) {\n return null;\n }\n const raw = value as Record<string, unknown>;\n const protocols = readVersionMap(raw.protocols);\n const features = readVersionMap(raw.features ?? {});\n if (!protocols || !features) {\n return null;\n }\n const sequence = Number.isSafeInteger(raw.sequence)\n ? (raw.sequence as number)\n : 0;\n return {\n format: PEER_MANIFEST_FORMAT,\n ...(typeof raw.appKey === \"string\" ? { appKey: raw.appKey } : {}),\n sequence,\n revision:\n typeof raw.revision === \"string\"\n ? raw.revision\n : manifestRevision({ protocols, features }, sequence),\n protocols,\n features,\n };\n}\n\n/** Why a document may not go to a peer. */\nexport type HoldReason = {\n protocol: string;\n version: number;\n peerSupports: readonly number[];\n};\n\n/** Only keys this reactor registers are judged; an absent key agrees. */\nexport function holdReason(\n peer: Supports,\n versions: { readonly [protocol: string]: number },\n capabilities: readonly PeerCapability[],\n): HoldReason | undefined {\n for (const capability of capabilities) {\n if (capability.kind !== \"protocol\") continue;\n const version = versions[capability.name] as number | undefined;\n if (version === undefined) continue;\n const supported = peer.protocols[capability.name] ?? [];\n if (!supported.includes(version)) {\n return { protocol: capability.name, version, peerSupports: supported };\n }\n }\n return undefined;\n}\n\n/** Whether a peer runs every version this reactor does, so nothing is held. */\nexport function coversLocal(\n peer: Supports,\n local: Supports,\n capabilities: readonly PeerCapability[],\n): boolean {\n for (const capability of capabilities) {\n if (capability.kind !== \"protocol\") continue;\n const theirs = peer.protocols[capability.name] ?? [];\n const ours = local.protocols[capability.name] ?? [];\n if (!ours.every((version) => theirs.includes(version))) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * protocolVersions for a new document: per negotiated protocol, the highest\n * version up to the local preference that every member supports, else the\n * lowest local one. `requested` wins over what is selected.\n */\nexport function selectProtocolVersions(input: {\n capabilities: readonly PeerCapability[];\n flags: PeerCapabilityFlags;\n members: Iterable<Supports>;\n requested?: { readonly [protocol: string]: number };\n}): { [protocol: string]: number } {\n const members = [...input.members];\n const selected: { [protocol: string]: number } = {};\n for (const capability of input.capabilities) {\n if (capability.kind !== \"protocol\" || !capability.preferred) continue;\n const preferred = capability.preferred(input.flags);\n const supported = capability.supported(input.flags);\n let agreed = supported.filter((version) => version <= preferred);\n for (const member of members) {\n const theirs = member.protocols[capability.name] ?? [];\n agreed = agreed.filter((version) => theirs.includes(version));\n }\n selected[capability.name] =\n agreed.length > 0 ? Math.max(...agreed) : Math.min(...supported);\n }\n return { ...selected, ...input.requested };\n}\n","import type { Action } from \"./actions.js\";\nimport type { Operation, OperationWithContext } from \"./operations.js\";\nimport { DOCUMENT_PURGE_PROTOCOL } from \"./peer-agreement.js\";\nimport type { PurgeDocumentAction, PurgeDocumentActionInput } from \"./types.js\";\nimport { deriveOperationId, generateId } from \"./utils.js\";\n\nexport const PURGE_DOCUMENT = \"PURGE_DOCUMENT\";\n\nexport type PurgeMarkerOperation = Operation & { action: PurgeDocumentAction };\n\ntype ActionLike = Pick<Action, \"type\">;\n\nexport function isPurgeMarker(value: Action): value is PurgeDocumentAction;\nexport function isPurgeMarker(value: Operation): value is PurgeMarkerOperation;\nexport function isPurgeMarker(\n value: OperationWithContext,\n): value is OperationWithContext & { operation: PurgeMarkerOperation };\nexport function isPurgeMarker(\n value: ActionLike | { action?: ActionLike } | { operation: Operation },\n): boolean;\nexport function isPurgeMarker(\n value: ActionLike | { action?: ActionLike } | { operation: Operation },\n): boolean {\n const action =\n \"operation\" in value\n ? value.operation.action\n : \"action\" in value\n ? value.action\n : (value as ActionLike);\n return action?.type === PURGE_DOCUMENT;\n}\n\n/** An unsigned marker; `purgedAtUtcIso` is the action's own timestamp. */\nexport function purgeDocumentAction(\n input: Omit<PurgeDocumentActionInput, \"purgedAtUtcIso\">,\n options: { id?: string; timestampUtcMs?: string } = {},\n): PurgeDocumentAction {\n const timestampUtcMs = options.timestampUtcMs ?? new Date().toISOString();\n return {\n id: options.id ?? generateId(),\n type: PURGE_DOCUMENT,\n scope: \"document\",\n timestampUtcMs,\n input: {\n documentId: input.documentId,\n documentType: input.documentType,\n purgedAtUtcIso: timestampUtcMs,\n requestId: input.requestId,\n },\n };\n}\n\n/** The sole row of a purged stream: document/main, index 0, skip 0, hash \"\". */\nexport function purgeMarkerOperation(\n action: PurgeDocumentAction,\n): PurgeMarkerOperation {\n return {\n id: deriveOperationId(\n action.input.documentId,\n \"document\",\n \"main\",\n action.id,\n ),\n index: 0,\n skip: 0,\n timestampUtcMs: action.timestampUtcMs,\n hash: \"\",\n action,\n };\n}\n\n/** Protocol versions of a purged id; derived, never stored. */\nexport function purgedProtocolVersions(): { [protocol: string]: number } {\n return { [DOCUMENT_PURGE_PROTOCOL]: 1 };\n}\n"],"mappings":"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"}
|
package/dist/registry/index.d.ts
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { B as
|
|
1
|
+
import { U as DEFAULT_REGISTRY_URL } from "../types-DzleLgA8.js";
|
|
2
|
+
import { B as PackagePage, F as PACKAGE_MODULE_TYPES, G as RegistryPackageSource, H as RegistryPackage, I as PackageFacets, K as RegistryPackageStatus, L as PackageInfo, R as PackageListItem, U as RegistryPackageList, V as Page, W as RegistryPackageMap, z as PackageModuleType } from "../types-CfU91XFU.js";
|
|
3
3
|
import { slimManifest } from "./manifest-slim.js";
|
|
4
4
|
import { toCdnUrl } from "./urls.js";
|
|
5
5
|
import { getUpdateTarget, parseInstallSpec } from "./updates.js";
|
|
6
|
-
|
|
7
6
|
//#region registry/registry.d.ts
|
|
8
7
|
/**
|
|
9
8
|
* Extract the host portion of a registry URL — what npm uses as the key in
|
|
10
9
|
* `~/.npmrc` for per-registry tokens (e.g. `//registry.vetra.io/`).
|
|
11
10
|
*/
|
|
12
|
-
declare function registryAuthKey(registryUrl: string): string;
|
|
13
|
-
interface ResolveRegistryUrlOptions {
|
|
11
|
+
export declare function registryAuthKey(registryUrl: string): string;
|
|
12
|
+
export interface ResolveRegistryUrlOptions {
|
|
14
13
|
/** Explicit registry URL (e.g. from --registry flag). Highest priority. */
|
|
15
14
|
registry?: string;
|
|
16
15
|
/** Project path to read powerhouse.config.json from. */
|
|
@@ -21,13 +20,13 @@ interface ResolveRegistryUrlOptions {
|
|
|
21
20
|
/**
|
|
22
21
|
* Resolve the registry URL with priority: flag > env > config > default.
|
|
23
22
|
*/
|
|
24
|
-
declare function resolveRegistryUrl(options: ResolveRegistryUrlOptions): string;
|
|
23
|
+
export declare function resolveRegistryUrl(options: ResolveRegistryUrlOptions): string;
|
|
25
24
|
/**
|
|
26
25
|
* Check if the user is authenticated with the given npm registry.
|
|
27
26
|
* Returns the username on success, throws on failure.
|
|
28
27
|
*/
|
|
29
|
-
declare function checkNpmAuth(registryUrl: string): Promise<string>;
|
|
30
|
-
interface NpmPublishOptions {
|
|
28
|
+
export declare function checkNpmAuth(registryUrl: string): Promise<string>;
|
|
29
|
+
export interface NpmPublishOptions {
|
|
31
30
|
/** Registry URL to publish to. */
|
|
32
31
|
registryUrl: string;
|
|
33
32
|
/** Working directory (project root). */
|
|
@@ -38,7 +37,7 @@ interface NpmPublishOptions {
|
|
|
38
37
|
* `_authToken` config flag rather than read from the user's `.npmrc`. */
|
|
39
38
|
authToken?: string;
|
|
40
39
|
}
|
|
41
|
-
interface NpmPublishResult {
|
|
40
|
+
export interface NpmPublishResult {
|
|
42
41
|
/** stdout from npm publish. */
|
|
43
42
|
stdout: string;
|
|
44
43
|
}
|
|
@@ -50,14 +49,14 @@ interface NpmPublishResult {
|
|
|
50
49
|
* `--//host/:_authToken=<token>` flag (npm's standard form for per-registry
|
|
51
50
|
* tokens) so we never have to write to `~/.npmrc`.
|
|
52
51
|
*/
|
|
53
|
-
declare function npmPublish(options: NpmPublishOptions): Promise<NpmPublishResult>;
|
|
52
|
+
export declare function npmPublish(options: NpmPublishOptions): Promise<NpmPublishResult>;
|
|
54
53
|
/**
|
|
55
54
|
* Write `_authToken=<token>` for the given registry host into `~/.npmrc`,
|
|
56
55
|
* preserving any other lines. Replaces the existing entry for the same key
|
|
57
56
|
* if present. Returns the absolute path to the npmrc that was written.
|
|
58
57
|
*/
|
|
59
|
-
declare function writeRegistryAuthToken(registryUrl: string, token: string): Promise<string>;
|
|
60
|
-
interface NpmUnpublishOptions {
|
|
58
|
+
export declare function writeRegistryAuthToken(registryUrl: string, token: string): Promise<string>;
|
|
59
|
+
export interface NpmUnpublishOptions {
|
|
61
60
|
/** Registry URL to unpublish from. */
|
|
62
61
|
registryUrl: string;
|
|
63
62
|
/** Working directory (project root). */
|
|
@@ -69,7 +68,7 @@ interface NpmUnpublishOptions {
|
|
|
69
68
|
/** Bearer token for the registry (same semantics as `NpmPublishOptions.authToken`). */
|
|
70
69
|
authToken?: string;
|
|
71
70
|
}
|
|
72
|
-
interface NpmUnpublishResult {
|
|
71
|
+
export interface NpmUnpublishResult {
|
|
73
72
|
/** stdout from npm unpublish. */
|
|
74
73
|
stdout: string;
|
|
75
74
|
}
|
|
@@ -78,7 +77,8 @@ interface NpmUnpublishResult {
|
|
|
78
77
|
* Always passes `--force` because npm otherwise refuses to unpublish packages
|
|
79
78
|
* older than 72h (a public-npmjs safeguard that doesn't apply to private registries).
|
|
80
79
|
*/
|
|
81
|
-
declare function npmUnpublish(options: NpmUnpublishOptions): Promise<NpmUnpublishResult>;
|
|
80
|
+
export declare function npmUnpublish(options: NpmUnpublishOptions): Promise<NpmUnpublishResult>;
|
|
82
81
|
//#endregion
|
|
83
|
-
export { DEFAULT_REGISTRY_URL,
|
|
82
|
+
export { DEFAULT_REGISTRY_URL, PACKAGE_MODULE_TYPES, PackageFacets, PackageInfo, PackageListItem, PackageModuleType, PackagePage, Page, RegistryPackage, RegistryPackageList, RegistryPackageMap, RegistryPackageSource, RegistryPackageStatus, getUpdateTarget, parseInstallSpec, slimManifest, toCdnUrl };
|
|
83
|
+
export {};
|
|
84
84
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../registry/registry.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../registry/registry.ts"],"mappings":";;;;;;;;;;wBAgBgB,gBAAgB;iBAQf;;EAEf;;EAEA;;EAEA,MAAM;;;;;wBAMQ,mBAAmB,SAAS;;;;;wBAiBtB,aAAa,sBAAsB;iBAIxC;;EAEf;;EAEA;;EAEA;;;EAGA;;iBAGe;;EAEf;;;;;;;;;;wBAWoB,WACpB,SAAS,oBACR,QAAQ;;;;;;wBAeW,uBACpB,qBACA,gBACC;iBAmBc;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA;;iBAGe;;EAEf;;;;;;;wBAQoB,aACpB,SAAS,sBACR,QAAQ"}
|
package/dist/registry/index.js
CHANGED
|
@@ -5,14 +5,32 @@ import { promises, readFileSync } from "node:fs";
|
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import spawn from "cross-spawn";
|
|
8
|
+
//#region registry/types.ts
|
|
9
|
+
/** Manifest module lists accepted by the `moduleType` filter. */
|
|
10
|
+
const PACKAGE_MODULE_TYPES = [
|
|
11
|
+
"documentModels",
|
|
12
|
+
"editors",
|
|
13
|
+
"apps",
|
|
14
|
+
"subgraphs",
|
|
15
|
+
"processors"
|
|
16
|
+
];
|
|
8
17
|
const DEFAULT_REGISTRY_URL = "https://registry.vetra.io";
|
|
9
18
|
const POWERHOUSE_CONFIG_FILE = "powerhouse.config.json";
|
|
10
|
-
|
|
19
|
+
const HOME_DIR = homedir();
|
|
20
|
+
join(HOME_DIR, ".ph");
|
|
11
21
|
const VERSIONED_PEER_DEPENDENCIES = ["document-model", "@powerhousedao/reactor-browser"];
|
|
12
|
-
const FEATURE_DEPENDENCIES = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
22
|
+
const FEATURE_DEPENDENCIES = {
|
|
23
|
+
analyticsProcessor: {
|
|
24
|
+
peerVersioned: ["@powerhousedao/analytics-engine-core"],
|
|
25
|
+
peerExternal: {},
|
|
26
|
+
devVersioned: []
|
|
27
|
+
},
|
|
28
|
+
piece: {
|
|
29
|
+
peerVersioned: [],
|
|
30
|
+
peerExternal: {},
|
|
31
|
+
devVersioned: ["@powerhousedao/pieces-framework"]
|
|
32
|
+
}
|
|
33
|
+
};
|
|
16
34
|
[...VERSIONED_PEER_DEPENDENCIES, ...FEATURE_DEPENDENCIES.analyticsProcessor.peerVersioned];
|
|
17
35
|
const DEFAULT_CONFIG = {
|
|
18
36
|
documentModelsDir: "./document-models",
|
|
@@ -155,6 +173,6 @@ async function npmUnpublish(options) {
|
|
|
155
173
|
], { cwd }) };
|
|
156
174
|
}
|
|
157
175
|
//#endregion
|
|
158
|
-
export { DEFAULT_REGISTRY_URL, checkNpmAuth, getUpdateTarget, npmPublish, npmUnpublish, parseInstallSpec, registryAuthKey, resolveRegistryUrl, slimManifest, toCdnUrl, writeRegistryAuthToken };
|
|
176
|
+
export { DEFAULT_REGISTRY_URL, PACKAGE_MODULE_TYPES, checkNpmAuth, getUpdateTarget, npmPublish, npmUnpublish, parseInstallSpec, registryAuthKey, resolveRegistryUrl, slimManifest, toCdnUrl, writeRegistryAuthToken };
|
|
159
177
|
|
|
160
178
|
//# sourceMappingURL=index.js.map
|