@noy-db/hub 0.6.0-pre.9 → 0.7.0-pre.0
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/CHANGELOG.md +7127 -0
- package/README.md +1 -1
- package/codemods/0.4.0-pre.json +24 -0
- package/codemods/0.6.0-pre.json +229 -0
- package/codemods/0.7.0-pre.json +258 -0
- package/dist/api-EQYRTZO2.js +20 -0
- package/dist/as/index.js +146 -0
- package/dist/as/index.js.map +1 -0
- package/dist/at/index.js +23 -0
- package/dist/attestation/index.js +19 -19
- package/dist/{backup-KULFZ2T4.js → backup-Z7ZBTAQ6.js} +36 -18
- package/dist/backup-Z7ZBTAQ6.js.map +1 -0
- package/dist/blobs/index.js +22 -20
- package/dist/blobs/index.js.map +1 -1
- package/dist/broker/index.js +12 -12
- package/dist/by/index.js +11 -0
- package/dist/cargo/index.js +40 -36
- package/dist/{chunk-YAWK6AWF.js → chunk-225O5CXQ.js} +2 -2
- package/dist/{chunk-MSWYQLMQ.js → chunk-2GXEQUEX.js} +2 -2
- package/dist/chunk-2GXEQUEX.js.map +1 -0
- package/dist/{chunk-3URQC7EH.js → chunk-2LPVI4PX.js} +355 -132
- package/dist/chunk-2LPVI4PX.js.map +1 -0
- package/dist/{chunk-JJNOLSG5.js → chunk-3L2MVE36.js} +15 -16
- package/dist/chunk-3L2MVE36.js.map +1 -0
- package/dist/{chunk-OF3L2SD6.js → chunk-3QARDAYW.js} +2 -2
- package/dist/{chunk-WLZ47GSL.js → chunk-467SKJ65.js} +12 -10
- package/dist/{chunk-WLZ47GSL.js.map → chunk-467SKJ65.js.map} +1 -1
- package/dist/{chunk-W3TVWF6N.js → chunk-4A4TYISP.js} +2 -2
- package/dist/{chunk-ZJADGNYF.js → chunk-4AOERLTV.js} +1 -1
- package/dist/chunk-4AOERLTV.js.map +1 -0
- package/dist/{chunk-CCZJJ4I2.js → chunk-4G25SDQL.js} +6 -6
- package/dist/{chunk-4I72F5DF.js → chunk-4LPF226H.js} +11 -14
- package/dist/chunk-4LPF226H.js.map +1 -0
- package/dist/{chunk-7F4DBNSP.js → chunk-4ZPE6SKS.js} +135 -18
- package/dist/chunk-4ZPE6SKS.js.map +1 -0
- package/dist/{chunk-7TSYBD3E.js → chunk-5263OEM3.js} +2 -2
- package/dist/{chunk-WFUIE565.js → chunk-57JTHWLQ.js} +17 -14
- package/dist/chunk-57JTHWLQ.js.map +1 -0
- package/dist/{chunk-FNSMZQS4.js → chunk-5ACAVJUI.js} +2 -2
- package/dist/{chunk-PDLLCOGD.js → chunk-5AFMP532.js} +20 -17
- package/dist/chunk-5AFMP532.js.map +1 -0
- package/dist/{chunk-JRKZTEZZ.js → chunk-5W7YXFV5.js} +444 -73
- package/dist/chunk-5W7YXFV5.js.map +1 -0
- package/dist/chunk-6EW2UCVF.js +190 -0
- package/dist/chunk-6EW2UCVF.js.map +1 -0
- package/dist/{chunk-4VUPLMZ6.js → chunk-6FOGTKBY.js} +68 -73
- package/dist/chunk-6FOGTKBY.js.map +1 -0
- package/dist/{chunk-VMCCGUQB.js → chunk-7LYUJNU3.js} +2 -2
- package/dist/{chunk-52JPHN5N.js → chunk-A2YW5EMU.js} +27 -149
- package/dist/chunk-A2YW5EMU.js.map +1 -0
- package/dist/{chunk-WLYIROCJ.js → chunk-AB5P32RE.js} +2 -2
- package/dist/{chunk-PL2GHSCM.js → chunk-ALB64CZM.js} +157 -90
- package/dist/chunk-ALB64CZM.js.map +1 -0
- package/dist/{chunk-SUFG5E73.js → chunk-ALUNQEBY.js} +2 -2
- package/dist/{chunk-CADUYBQD.js → chunk-ATL3ZVXT.js} +2 -2
- package/dist/{chunk-BWVKEOPE.js → chunk-ATV637J7.js} +7 -11
- package/dist/chunk-ATV637J7.js.map +1 -0
- package/dist/{chunk-DG27IUVI.js → chunk-CBRS2NEK.js} +2 -11
- package/dist/chunk-CBRS2NEK.js.map +1 -0
- package/dist/{chunk-7MNBICB5.js → chunk-CN6B5PEN.js} +16 -14
- package/dist/chunk-CN6B5PEN.js.map +1 -0
- package/dist/{chunk-6FJWSWFT.js → chunk-DBNYPLWY.js} +3 -3
- package/dist/{chunk-5JY5TSVY.js → chunk-DFAUMLD7.js} +25 -31
- package/dist/chunk-DFAUMLD7.js.map +1 -0
- package/dist/{chunk-FFDNKRCY.js → chunk-DKWPJOYH.js} +2 -2
- package/dist/chunk-DKWPJOYH.js.map +1 -0
- package/dist/{chunk-VJFMXYKP.js → chunk-E6YA6UAP.js} +2 -2
- package/dist/{chunk-WASHZV34.js → chunk-F23WQK3G.js} +65 -27
- package/dist/chunk-F23WQK3G.js.map +1 -0
- package/dist/{chunk-JIUVJ4M7.js → chunk-F7ZFRPGQ.js} +3 -3
- package/dist/{chunk-HXGUIPQB.js → chunk-FOG7YEJP.js} +3 -3
- package/dist/{chunk-QULVCV3M.js → chunk-GK4DRVUD.js} +6 -6
- package/dist/chunk-GK4DRVUD.js.map +1 -0
- package/dist/{chunk-BRVW2GS5.js → chunk-H36KSN6X.js} +87 -34
- package/dist/chunk-H36KSN6X.js.map +1 -0
- package/dist/{chunk-O2ERS4UJ.js → chunk-H4M7ADXY.js} +81 -52
- package/dist/chunk-H4M7ADXY.js.map +1 -0
- package/dist/{chunk-FZ6NYJ7L.js → chunk-H7HP56F6.js} +11 -8
- package/dist/chunk-H7HP56F6.js.map +1 -0
- package/dist/chunk-HK67PX4J.js +27 -0
- package/dist/chunk-HK67PX4J.js.map +1 -0
- package/dist/{chunk-X56RTUK3.js → chunk-HM4JSXX2.js} +3 -3
- package/dist/{chunk-AHLJSVRL.js → chunk-HTGRQZFB.js} +5 -7
- package/dist/chunk-HTGRQZFB.js.map +1 -0
- package/dist/{chunk-GQ3BX5EA.js → chunk-I3ISCYT7.js} +2 -2
- package/dist/{chunk-Q6TEJXBX.js → chunk-IESNYJXZ.js} +31 -49
- package/dist/chunk-IESNYJXZ.js.map +1 -0
- package/dist/{chunk-FUHKW252.js → chunk-J4MN6XIU.js} +2 -2
- package/dist/{chunk-ADW22QSB.js → chunk-J4UJ5FRV.js} +4 -4
- package/dist/{chunk-HNGSV2YC.js → chunk-JBIV4FLR.js} +67 -10
- package/dist/chunk-JBIV4FLR.js.map +1 -0
- package/dist/{chunk-HVQGCKY4.js → chunk-JVLSU7S2.js} +2 -2
- package/dist/{chunk-AR2JDFAE.js → chunk-KDJGJR7F.js} +2 -2
- package/dist/{chunk-NPP5R7FF.js → chunk-KN4W2OQ4.js} +22 -18
- package/dist/chunk-KN4W2OQ4.js.map +1 -0
- package/dist/{chunk-G6S5VVHP.js → chunk-L6GTLZRK.js} +10 -10
- package/dist/chunk-L6GTLZRK.js.map +1 -0
- package/dist/{chunk-2BMRJ6LQ.js → chunk-LF6DMX4C.js} +8 -11
- package/dist/{chunk-2BMRJ6LQ.js.map → chunk-LF6DMX4C.js.map} +1 -1
- package/dist/chunk-LFUID7OW.js +163 -0
- package/dist/chunk-LFUID7OW.js.map +1 -0
- package/dist/{chunk-747LRSOO.js → chunk-LKFKXS5K.js} +2 -2
- package/dist/{chunk-U5O6GIWZ.js → chunk-LR4Z47QD.js} +3 -3
- package/dist/{chunk-VZ3XFUQ7.js → chunk-MTBXJAS4.js} +16 -22
- package/dist/chunk-MTBXJAS4.js.map +1 -0
- package/dist/chunk-N4CNVSUF.js +66 -0
- package/dist/chunk-N4CNVSUF.js.map +1 -0
- package/dist/{chunk-RTAMLDWP.js → chunk-NLKLXXTO.js} +2 -2
- package/dist/{chunk-IGJCYUT5.js → chunk-NSITFOCJ.js} +1 -1
- package/dist/chunk-NSITFOCJ.js.map +1 -0
- package/dist/{chunk-FDX7OWWI.js → chunk-OPXR4PB2.js} +2 -2
- package/dist/{chunk-4GZ6XOVW.js → chunk-OWLVBOWO.js} +44 -42
- package/dist/chunk-OWLVBOWO.js.map +1 -0
- package/dist/{chunk-Z45YRGFO.js → chunk-P6ASQOZR.js} +2 -2
- package/dist/{chunk-5O5HRRTV.js → chunk-PCQDY6QN.js} +7 -7
- package/dist/{chunk-5O5HRRTV.js.map → chunk-PCQDY6QN.js.map} +1 -1
- package/dist/{chunk-BEFVYAR5.js → chunk-PGFKIOR3.js} +4 -4
- package/dist/chunk-PGFKIOR3.js.map +1 -0
- package/dist/{chunk-3FSX6LDG.js → chunk-POS53FG6.js} +18 -3
- package/dist/{chunk-3FSX6LDG.js.map → chunk-POS53FG6.js.map} +1 -1
- package/dist/{chunk-3IXIU6FP.js → chunk-PQ6Z2TAP.js} +7 -10
- package/dist/chunk-PQ6Z2TAP.js.map +1 -0
- package/dist/{chunk-CEJWMBXO.js → chunk-PUJTKLPL.js} +6 -2
- package/dist/chunk-PUJTKLPL.js.map +1 -0
- package/dist/{chunk-GAG7QOVO.js → chunk-QGJ4XIA7.js} +53 -18
- package/dist/chunk-QGJ4XIA7.js.map +1 -0
- package/dist/{chunk-2DHSSLOD.js → chunk-QHJKK77B.js} +13 -15
- package/dist/chunk-QHJKK77B.js.map +1 -0
- package/dist/{chunk-2Z3NCLNX.js → chunk-QI5NWLVW.js} +7 -7
- package/dist/{chunk-6SAFL5YE.js → chunk-RC4BROYR.js} +3 -3
- package/dist/{chunk-NJDQ4YSV.js → chunk-RDHUZ674.js} +4 -4
- package/dist/{chunk-YPYHVOXP.js → chunk-RK7N4OQ5.js} +2 -2
- package/dist/chunk-RK7N4OQ5.js.map +1 -0
- package/dist/{chunk-3737A6EA.js → chunk-S2VG3ABP.js} +127 -31
- package/dist/chunk-S2VG3ABP.js.map +1 -0
- package/dist/{chunk-3JVXVJ7L.js → chunk-S35S77YU.js} +10 -10
- package/dist/{chunk-KUDZVJKQ.js → chunk-SHILAQH5.js} +2 -2
- package/dist/{chunk-4UVDI4XE.js → chunk-T3PHCEN4.js} +4 -4
- package/dist/{chunk-55LKVALY.js → chunk-T7IR4N2S.js} +1 -3
- package/dist/chunk-T7IR4N2S.js.map +1 -0
- package/dist/{chunk-RXYYFSBB.js → chunk-TOV6VMHF.js} +6 -6
- package/dist/chunk-TOV6VMHF.js.map +1 -0
- package/dist/{chunk-W77KZHCW.js → chunk-TVIFAHZR.js} +16 -17
- package/dist/chunk-TVIFAHZR.js.map +1 -0
- package/dist/chunk-UBSFPGVJ.js +1 -0
- package/dist/{chunk-FAXZQ5UF.js → chunk-UCUALOSM.js} +2 -2
- package/dist/{chunk-4HDYQL3J.js → chunk-VAG47QHV.js} +2 -2
- package/dist/{chunk-35EBKWQU.js → chunk-VFIWDPXZ.js} +4 -4
- package/dist/{chunk-5ZKS6ZE2.js → chunk-VTG7327U.js} +4 -4
- package/dist/chunk-VTG7327U.js.map +1 -0
- package/dist/{chunk-VCETL77O.js → chunk-W5LHQXZU.js} +36 -7
- package/dist/chunk-W5LHQXZU.js.map +1 -0
- package/dist/{chunk-6NVPFKN3.js → chunk-WK5FSW7T.js} +92 -35
- package/dist/chunk-WK5FSW7T.js.map +1 -0
- package/dist/{chunk-HNHCQ556.js → chunk-WLLUM35R.js} +2 -2
- package/dist/{chunk-YJ6IONGA.js → chunk-X62MEF2O.js} +13 -5
- package/dist/chunk-X62MEF2O.js.map +1 -0
- package/dist/{chunk-7G6VDWXB.js → chunk-X67FCULK.js} +5 -5
- package/dist/chunk-X67FCULK.js.map +1 -0
- package/dist/{chunk-UHXCLPGC.js → chunk-XDVVBETV.js} +2 -2
- package/dist/chunk-XDVVBETV.js.map +1 -0
- package/dist/chunk-XJ3FEKEY.js +15 -0
- package/dist/chunk-XJ3FEKEY.js.map +1 -0
- package/dist/{chunk-E6427JU2.js → chunk-XSN63FUS.js} +19 -3
- package/dist/chunk-XSN63FUS.js.map +1 -0
- package/dist/{chunk-JRCYZEHU.js → chunk-XVU7J43V.js} +2 -2
- package/dist/{chunk-2GAJGUNM.js → chunk-Y3YLJORD.js} +408 -260
- package/dist/chunk-Y3YLJORD.js.map +1 -0
- package/dist/{chunk-6BU3L4UE.js → chunk-Y6GZ2P4M.js} +7 -10
- package/dist/chunk-Y6GZ2P4M.js.map +1 -0
- package/dist/{chunk-DMQCLZ4Z.js → chunk-YCSM3GZU.js} +2 -2
- package/dist/{chunk-RV3ARMPN.js → chunk-YKPGQJFU.js} +30 -180
- package/dist/chunk-YKPGQJFU.js.map +1 -0
- package/dist/{chunk-FMQJZH4R.js → chunk-YMLQBZFJ.js} +6 -6
- package/dist/{chunk-6HFM7EIT.js → chunk-YPSOHDNC.js} +2 -2
- package/dist/{chunk-CDB2HVQW.js → chunk-YXA2TCTZ.js} +14 -15
- package/dist/chunk-YXA2TCTZ.js.map +1 -0
- package/dist/{chunk-N35NC4JH.js → chunk-Z2PWOSCJ.js} +2 -2
- package/dist/{chunk-XWX7GL56.js → chunk-Z2WK53N6.js} +47 -23
- package/dist/chunk-Z2WK53N6.js.map +1 -0
- package/dist/{chunk-HPLWFNG4.js → chunk-Z7ZXZL6Y.js} +2 -2
- package/dist/{chunk-PNKHAKQ7.js → chunk-ZO252Q5S.js} +17 -10
- package/dist/chunk-ZO252Q5S.js.map +1 -0
- package/dist/classified/index.js +5 -5
- package/dist/{classified-marker-2KJAXRRO.js → classified-marker-BSQHU4JT.js} +3 -3
- package/dist/collection-facade-LG3NYZVB.js +45 -0
- package/dist/{computed-6G5M3UPH.js → computed-ASBNTLOK.js} +3 -3
- package/dist/consent/index.js +10 -10
- package/dist/cover/index.js +10 -3
- package/dist/custody/index.js +12 -11
- package/dist/{dead-filter-DCB62VWW.js → dead-filter-QKU56XTQ.js} +2 -2
- package/dist/debug/index.js +1 -1
- package/dist/{delegation-MO7YZYJS.js → delegation-XWRPYODW.js} +24 -23
- package/dist/delegation-XWRPYODW.js.map +1 -0
- package/dist/derivations/index.js +12 -12
- package/dist/derive-CXHCY46K.js +22 -0
- package/dist/directory/index.js +10 -10
- package/dist/{dispatch-MJ6SHB3Y.js → dispatch-4AP4PUZU.js} +18 -18
- package/dist/{dispatch-FZEAWKVM.js → dispatch-VR4LRXZ7.js} +9 -6
- package/dist/dispatch-VR4LRXZ7.js.map +1 -0
- package/dist/{enclave-JU4YIEPB.js → enclave-NYPT7WA7.js} +31 -9
- package/dist/executor-3KFRQETS.js +29 -0
- package/dist/executor-AFHQYRAU.js +9 -0
- package/dist/executor-YYDW6XQI.js +9 -0
- package/dist/export-accessible-BX2ILB4C.js +23 -0
- package/dist/extract-partition-UPOVITFI.js +38 -0
- package/dist/{fanout-sidecar-NNAJQXMX.js → fanout-sidecar-IWP3R4RC.js} +18 -27
- package/dist/fanout-sidecar-IWP3R4RC.js.map +1 -0
- package/dist/{fence-watcher-DHQ775JB.js → fence-watcher-ZVSMLKQD.js} +1 -1
- package/dist/fence-watcher-ZVSMLKQD.js.map +1 -0
- package/dist/find-SZBL2HPB.js +11 -0
- package/dist/forget/index.js +9 -9
- package/dist/guards/index.js +4 -4
- package/dist/history/index.js +23 -20
- package/dist/history/index.js.map +1 -1
- package/dist/i18n/index.js +14 -14
- package/dist/index.d.ts +35 -18
- package/dist/index.js +199 -204
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.js +4 -4
- package/dist/introspection/index.js +12 -11
- package/dist/issue-G53NB6EW.js +19 -0
- package/dist/kernel/collection-config.d.ts +9 -9
- package/dist/kernel/collection.d.ts +9 -3
- package/dist/kernel/constants.d.ts +36 -0
- package/dist/kernel/enclave/crypto.d.ts +52 -4
- package/dist/kernel/enclave/index.d.ts +10 -3
- package/dist/kernel/enclave/record-aad.d.ts +131 -0
- package/dist/kernel/enclave/record-envelope.d.ts +76 -0
- package/dist/kernel/enclave/record-keys/envelope-body.d.ts +34 -2
- package/dist/kernel/enclave/record-keys/lifecycle.d.ts +22 -5
- package/dist/kernel/enclave/record-keys/record-codec.d.ts +47 -14
- package/dist/kernel/enclave/record-keys/rekey-blob.d.ts +88 -0
- package/dist/kernel/enclave/record-keys/rekey.d.ts +91 -0
- package/dist/kernel/enclave/record-keys/tombstone.d.ts +3 -2
- package/dist/kernel/errors.d.ts +134 -14
- package/dist/kernel/merge-authority.d.ts +25 -0
- package/dist/kernel/noydb.d.ts +33 -10
- package/dist/kernel/query/builder.d.ts +51 -4
- package/dist/kernel/query/join.d.ts +27 -0
- package/dist/kernel/query/live.d.ts +31 -9
- package/dist/kernel/query/predicate.d.ts +9 -0
- package/dist/kernel/refs.d.ts +3 -1
- package/dist/kernel/secret-mode.d.ts +1 -1
- package/dist/kernel/sync-policy.d.ts +0 -2
- package/dist/kernel/tier-visibility.d.ts +34 -0
- package/dist/kernel/types.d.ts +145 -28
- package/dist/kernel/vault.d.ts +16 -7
- package/dist/kernel/via/compose.d.ts +3 -3
- package/dist/kernel/via/index.d.ts +15 -6
- package/dist/kernel/via/pipeline.d.ts +6 -6
- package/dist/kernel/via/reconcile.d.ts +14 -2
- package/dist/kernel/via/taint-binding.d.ts +3 -3
- package/dist/{ledger-AETNF4OM.js → ledger-T5K4P2D7.js} +11 -11
- package/dist/liberate-VEOZRESE.js +25 -0
- package/dist/{link-set-E5HNY67I.js → link-set-76JZ6YB4.js} +11 -11
- package/dist/{managed-secret-CWQ6PND5.js → managed-secret-6YC32VXG.js} +13 -5
- package/dist/materialized-views/index.js +27 -27
- package/dist/migrate-cek-LBRKYUZZ.js +19 -0
- package/dist/migrate-cek-LBRKYUZZ.js.map +1 -0
- package/dist/money/index.js +5 -5
- package/dist/noydb-EDJA4JNJ.js +86 -0
- package/dist/on/index.js +1 -0
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.js +12 -12
- package/dist/pod/index.js +79 -88
- package/dist/pod-handle-P6DPBM5U.js +41 -0
- package/dist/pod-handle-P6DPBM5U.js.map +1 -0
- package/dist/policy/index.js +11 -4
- package/dist/port/as/active.d.ts +10 -0
- package/dist/port/as/index.d.ts +32 -0
- package/dist/port/as/types.d.ts +113 -0
- package/dist/port/at/index.d.ts +37 -0
- package/dist/port/by/default-provider.d.ts +3 -3
- package/dist/port/by/index.d.ts +32 -10
- package/dist/port/by/types.d.ts +29 -11
- package/dist/port/on/index.d.ts +50 -0
- package/dist/port/to/index.d.ts +4 -4
- package/dist/port/to/locator.d.ts +54 -8
- package/dist/port/with/computed-strategy.d.ts +1 -1
- package/dist/port/with/device-seal-strategy.d.ts +2 -2
- package/dist/port/with/formats-strategy.d.ts +76 -0
- package/dist/port/with/i18n-strategy.d.ts +4 -1
- package/dist/port/with/lookup-strategy.d.ts +4 -1
- package/dist/port/with/merge-authority.d.ts +52 -0
- package/dist/port/with/service-bus.d.ts +0 -4
- package/dist/port/with/strategies.d.ts +13 -5
- package/dist/port/with/team-strategy.d.ts +5 -1
- package/dist/portability/index.js +8 -8
- package/dist/{post-register-2XSSMGEQ.js → post-register-53O7AJRZ.js} +6 -6
- package/dist/query/index.js +6 -6
- package/dist/reduce/index.js +6 -6
- package/dist/register-6TCBR6XD.js +32 -0
- package/dist/registry-DH2L4O2V.js +18 -0
- package/dist/registry-IWFMXCHX.js +9 -0
- package/dist/registry-Q3FG3OAX.js +9 -0
- package/dist/registry-YC3IFG3A.js +19 -0
- package/dist/request-withdrawal-NM5VYR6F.js +31 -0
- package/dist/{reveal-BW36KCOQ.js → reveal-XBIMHAXR.js} +6 -6
- package/dist/revoke-MJNYWO72.js +24 -0
- package/dist/satellites/index.js +1 -1
- package/dist/schema-update/index.js +2 -2
- package/dist/sealed-record/index.js +20 -13
- package/dist/sealed-record/index.js.map +1 -1
- package/dist/search/index.js +4 -4
- package/dist/{seed-GDV5PT4R.js → seed-NSNIGYXE.js} +20 -22
- package/dist/seed-NSNIGYXE.js.map +1 -0
- package/dist/sequence/index.js +9 -9
- package/dist/session/index.js +10 -10
- package/dist/shadow/index.js +2 -2
- package/dist/share-link/index.js +1 -1
- package/dist/signer-6XVS2AU3.js +25 -0
- package/dist/snapshots/index.js +10 -10
- package/dist/snapshots/index.js.map +1 -1
- package/dist/{stale-ARHFVL5U.js → stale-MCS46TFO.js} +10 -10
- package/dist/storage-ZXUT476I.js +23 -0
- package/dist/storage-ZXUT476I.js.map +1 -0
- package/dist/{store-coordination-provider-GFCUOBR6.js → store-coordination-provider-6FM26VQM.js} +22 -15
- package/dist/store-coordination-provider-6FM26VQM.js.map +1 -0
- package/dist/sync/index.js +11 -11
- package/dist/team/index.js +17 -16
- package/dist/tiers/index.js +11 -10
- package/dist/to/index.js +17 -9
- package/dist/to/index.js.map +1 -1
- package/dist/transactions/index.js +4 -4
- package/dist/{ulid-PTAIMDG4.js → ulid-VQW6ERQN.js} +2 -2
- package/dist/ulid-VQW6ERQN.js.map +1 -0
- package/dist/util/index.js +1 -1
- package/dist/vault-diff-FE5J35NJ.js +9 -0
- package/dist/vault-diff-FE5J35NJ.js.map +1 -0
- package/dist/vault-head/index.js +115 -0
- package/dist/vault-head/index.js.map +1 -0
- package/dist/{verify-RO5RTZOJ.js → verify-WYOFLSNA.js} +5 -5
- package/dist/via/blob/binding.d.ts +6 -6
- package/dist/via/blob/index.d.ts +3 -0
- package/dist/via/classified/binding.d.ts +9 -9
- package/dist/via/computed/binding.d.ts +2 -2
- package/dist/via/i18n/binding.d.ts +4 -4
- package/dist/via/lookup/binding.d.ts +5 -5
- package/dist/via/lookup/handle.d.ts +4 -1
- package/dist/via/lookup/index.d.ts +1 -1
- package/dist/via/lookup/snapshot.d.ts +1 -1
- package/dist/via/money/binding.d.ts +3 -3
- package/dist/via/money/normalize.d.ts +1 -1
- package/dist/via/money/where.d.ts +3 -3
- package/dist/walk-JNEOYCAU.js +21 -0
- package/dist/walk-JNEOYCAU.js.map +1 -0
- package/dist/with-audit/periods/periods.d.ts +1 -1
- package/dist/with-audit/periods/strategy.d.ts +1 -1
- package/dist/with-audit/sealed-record/index.d.ts +13 -0
- package/dist/with-audit/tiers/index.d.ts +17 -2
- package/dist/with-cargo/adopt-partition.d.ts +7 -7
- package/dist/with-cargo/extract-partition.d.ts +1 -1
- package/dist/with-cargo/floor.d.ts +1 -1
- package/dist/with-cargo/index.d.ts +2 -2
- package/dist/with-commit/history/history.d.ts +26 -0
- package/dist/with-commit/history/index.d.ts +2 -1
- package/dist/with-commit/history/ledger/store.d.ts +7 -1
- package/dist/with-commit/history/strategy.d.ts +11 -1
- package/dist/with-commit/numbering/index.d.ts +0 -5
- package/dist/with-commit/vault-head/active.d.ts +2 -0
- package/dist/with-commit/vault-head/head.d.ts +28 -0
- package/dist/with-commit/vault-head/index.d.ts +10 -0
- package/dist/with-commit/vault-head/strategy.d.ts +127 -0
- package/dist/with-commit/vault-head/verify.d.ts +90 -0
- package/dist/with-formula/materialized-views/dependency-analyzer.d.ts +4 -0
- package/dist/with-formula/materialized-views/projection-legs.d.ts +59 -0
- package/dist/with-formula/materialized-views/registry.d.ts +50 -0
- package/dist/with-formula/materialized-views/types.d.ts +68 -10
- package/dist/with-party/directory/cover/storage.d.ts +0 -8
- package/dist/with-party/directory/storage.d.ts +0 -11
- package/dist/with-party/directory/visibility.d.ts +0 -21
- package/dist/with-party/policy/storage.d.ts +0 -10
- package/dist/with-party/team/deed.d.ts +4 -4
- package/dist/with-party/team/device-seal.d.ts +5 -5
- package/dist/with-party/team/echo-ceremony.d.ts +2 -2
- package/dist/with-party/team/echo-secret.d.ts +4 -4
- package/dist/with-party/team/index.d.ts +3 -3
- package/dist/with-party/team/keyring.d.ts +141 -4
- package/dist/with-party/team/managed-secret.d.ts +21 -11
- package/dist/with-party/team/noydb-facade.d.ts +7 -3
- package/dist/with-party/team/{shamir-recovery-provider.d.ts → noydb-shamir.d.ts} +1 -1
- package/dist/with-party/team/recovery.d.ts +3 -3
- package/dist/with-party/team/roster-tag.d.ts +101 -0
- package/dist/with-party/team/rotate-recover.d.ts +5 -5
- package/dist/with-party/team/tiers.d.ts +2 -1
- package/dist/with-pod/format.d.ts +11 -13
- package/dist/with-pod/index.d.ts +10 -10
- package/dist/with-pod/open.d.ts +2 -2
- package/dist/with-pod/pod-handle.d.ts +19 -0
- package/dist/with-pod/pod-store.d.ts +0 -8
- package/dist/with-pod/{bundle.d.ts → pod.d.ts} +17 -25
- package/dist/with-pod/ulid.d.ts +1 -1
- package/dist/with-shape/blobs/blob-compaction.d.ts +13 -0
- package/dist/with-shape/blobs/blob-set.d.ts +83 -11
- package/dist/with-shape/blobs/orphan-report.d.ts +62 -0
- package/dist/with-shape/introspection/describe.d.ts +2 -2
- package/dist/with-shape/schema-update/fence-controller.d.ts +4 -4
- package/dist/with-shape/schema-update/fence-watcher.d.ts +4 -4
- package/dist/with-shape/schema-update/store-coordination-provider.d.ts +7 -6
- package/dist/with-sync/engine.d.ts +54 -5
- package/dist/with-sync/strategy.d.ts +3 -0
- package/dist/withdraw-accessible-ILTSXTIE.js +28 -0
- package/dist/withdraw-accessible-ILTSXTIE.js.map +1 -0
- package/package.json +29 -5
- package/dist/api-RXUMEKT3.js +0 -20
- package/dist/backup-KULFZ2T4.js.map +0 -1
- package/dist/bundle-handle-GFNHT52M.js +0 -36
- package/dist/bundle-handle-GFNHT52M.js.map +0 -1
- package/dist/chunk-2DHSSLOD.js.map +0 -1
- package/dist/chunk-2GAJGUNM.js.map +0 -1
- package/dist/chunk-3737A6EA.js.map +0 -1
- package/dist/chunk-3IXIU6FP.js.map +0 -1
- package/dist/chunk-3URQC7EH.js.map +0 -1
- package/dist/chunk-4GZ6XOVW.js.map +0 -1
- package/dist/chunk-4I72F5DF.js.map +0 -1
- package/dist/chunk-4VUPLMZ6.js.map +0 -1
- package/dist/chunk-52JPHN5N.js.map +0 -1
- package/dist/chunk-55LKVALY.js.map +0 -1
- package/dist/chunk-5JY5TSVY.js.map +0 -1
- package/dist/chunk-5ZKS6ZE2.js.map +0 -1
- package/dist/chunk-6BU3L4UE.js.map +0 -1
- package/dist/chunk-6NVPFKN3.js.map +0 -1
- package/dist/chunk-7F4DBNSP.js.map +0 -1
- package/dist/chunk-7G6VDWXB.js.map +0 -1
- package/dist/chunk-7H73RIE3.js +0 -45
- package/dist/chunk-7H73RIE3.js.map +0 -1
- package/dist/chunk-7MNBICB5.js.map +0 -1
- package/dist/chunk-AFHQATY4.js +0 -47
- package/dist/chunk-AFHQATY4.js.map +0 -1
- package/dist/chunk-AHLJSVRL.js.map +0 -1
- package/dist/chunk-BEFVYAR5.js.map +0 -1
- package/dist/chunk-BRVW2GS5.js.map +0 -1
- package/dist/chunk-BWVKEOPE.js.map +0 -1
- package/dist/chunk-CDB2HVQW.js.map +0 -1
- package/dist/chunk-CEJWMBXO.js.map +0 -1
- package/dist/chunk-DG27IUVI.js.map +0 -1
- package/dist/chunk-E6427JU2.js.map +0 -1
- package/dist/chunk-FFDNKRCY.js.map +0 -1
- package/dist/chunk-FZ6NYJ7L.js.map +0 -1
- package/dist/chunk-G6S5VVHP.js.map +0 -1
- package/dist/chunk-GAG7QOVO.js.map +0 -1
- package/dist/chunk-HNGSV2YC.js.map +0 -1
- package/dist/chunk-IGJCYUT5.js.map +0 -1
- package/dist/chunk-JJNOLSG5.js.map +0 -1
- package/dist/chunk-JRKZTEZZ.js.map +0 -1
- package/dist/chunk-MSWYQLMQ.js.map +0 -1
- package/dist/chunk-NPP5R7FF.js.map +0 -1
- package/dist/chunk-O2ERS4UJ.js.map +0 -1
- package/dist/chunk-PDLLCOGD.js.map +0 -1
- package/dist/chunk-PL2GHSCM.js.map +0 -1
- package/dist/chunk-PNKHAKQ7.js.map +0 -1
- package/dist/chunk-Q6TEJXBX.js.map +0 -1
- package/dist/chunk-QULVCV3M.js.map +0 -1
- package/dist/chunk-RV3ARMPN.js.map +0 -1
- package/dist/chunk-RXYYFSBB.js.map +0 -1
- package/dist/chunk-UHXCLPGC.js.map +0 -1
- package/dist/chunk-VCETL77O.js.map +0 -1
- package/dist/chunk-VZ3XFUQ7.js.map +0 -1
- package/dist/chunk-W77KZHCW.js.map +0 -1
- package/dist/chunk-WASHZV34.js.map +0 -1
- package/dist/chunk-WFUIE565.js.map +0 -1
- package/dist/chunk-XWX7GL56.js.map +0 -1
- package/dist/chunk-YJ6IONGA.js.map +0 -1
- package/dist/chunk-YPYHVOXP.js.map +0 -1
- package/dist/chunk-ZJADGNYF.js.map +0 -1
- package/dist/collection-facade-QEJIM6BC.js +0 -45
- package/dist/delegation-MO7YZYJS.js.map +0 -1
- package/dist/derive-IUA6JFLB.js +0 -22
- package/dist/dispatch-FZEAWKVM.js.map +0 -1
- package/dist/executor-CYJQLKKI.js +0 -9
- package/dist/executor-S4QIKEHW.js +0 -9
- package/dist/executor-YIQB2S6N.js +0 -29
- package/dist/export-accessible-4S36PQNR.js +0 -23
- package/dist/extract-partition-IO7FDZ2P.js +0 -38
- package/dist/fanout-sidecar-NNAJQXMX.js.map +0 -1
- package/dist/fence-watcher-DHQ775JB.js.map +0 -1
- package/dist/find-RBBYKXI7.js +0 -11
- package/dist/issue-RIVHSY2S.js +0 -19
- package/dist/liberate-GFN4C7RR.js +0 -24
- package/dist/noydb-ASEXNJS6.js +0 -83
- package/dist/register-4EFJCVYD.js +0 -32
- package/dist/registry-4SDHHOJ7.js +0 -18
- package/dist/registry-CZVINVQH.js +0 -9
- package/dist/registry-IKUR2MXD.js +0 -9
- package/dist/registry-OYTFGWVK.js +0 -19
- package/dist/request-withdrawal-KGXGDPVQ.js +0 -31
- package/dist/revoke-JFN773KF.js +0 -24
- package/dist/seed-GDV5PT4R.js.map +0 -1
- package/dist/signer-TA55QB6R.js +0 -25
- package/dist/storage-V7MTFAQJ.js +0 -23
- package/dist/store-coordination-provider-GFCUOBR6.js.map +0 -1
- package/dist/walk-3ZECBFDA.js +0 -21
- package/dist/with-pod/bundle-handle.d.ts +0 -9
- package/dist/withdraw-accessible-7PG4DYQK.js +0 -28
- /package/dist/{api-RXUMEKT3.js.map → api-EQYRTZO2.js.map} +0 -0
- /package/dist/{collection-facade-QEJIM6BC.js.map → at/index.js.map} +0 -0
- /package/dist/{computed-6G5M3UPH.js.map → by/index.js.map} +0 -0
- /package/dist/{chunk-YAWK6AWF.js.map → chunk-225O5CXQ.js.map} +0 -0
- /package/dist/{chunk-OF3L2SD6.js.map → chunk-3QARDAYW.js.map} +0 -0
- /package/dist/{chunk-W3TVWF6N.js.map → chunk-4A4TYISP.js.map} +0 -0
- /package/dist/{chunk-CCZJJ4I2.js.map → chunk-4G25SDQL.js.map} +0 -0
- /package/dist/{chunk-7TSYBD3E.js.map → chunk-5263OEM3.js.map} +0 -0
- /package/dist/{chunk-FNSMZQS4.js.map → chunk-5ACAVJUI.js.map} +0 -0
- /package/dist/{chunk-VMCCGUQB.js.map → chunk-7LYUJNU3.js.map} +0 -0
- /package/dist/{chunk-WLYIROCJ.js.map → chunk-AB5P32RE.js.map} +0 -0
- /package/dist/{chunk-SUFG5E73.js.map → chunk-ALUNQEBY.js.map} +0 -0
- /package/dist/{chunk-CADUYBQD.js.map → chunk-ATL3ZVXT.js.map} +0 -0
- /package/dist/{chunk-6FJWSWFT.js.map → chunk-DBNYPLWY.js.map} +0 -0
- /package/dist/{chunk-VJFMXYKP.js.map → chunk-E6YA6UAP.js.map} +0 -0
- /package/dist/{chunk-JIUVJ4M7.js.map → chunk-F7ZFRPGQ.js.map} +0 -0
- /package/dist/{chunk-HXGUIPQB.js.map → chunk-FOG7YEJP.js.map} +0 -0
- /package/dist/{chunk-X56RTUK3.js.map → chunk-HM4JSXX2.js.map} +0 -0
- /package/dist/{chunk-GQ3BX5EA.js.map → chunk-I3ISCYT7.js.map} +0 -0
- /package/dist/{chunk-FUHKW252.js.map → chunk-J4MN6XIU.js.map} +0 -0
- /package/dist/{chunk-ADW22QSB.js.map → chunk-J4UJ5FRV.js.map} +0 -0
- /package/dist/{chunk-HVQGCKY4.js.map → chunk-JVLSU7S2.js.map} +0 -0
- /package/dist/{chunk-AR2JDFAE.js.map → chunk-KDJGJR7F.js.map} +0 -0
- /package/dist/{chunk-747LRSOO.js.map → chunk-LKFKXS5K.js.map} +0 -0
- /package/dist/{chunk-U5O6GIWZ.js.map → chunk-LR4Z47QD.js.map} +0 -0
- /package/dist/{chunk-RTAMLDWP.js.map → chunk-NLKLXXTO.js.map} +0 -0
- /package/dist/{chunk-FDX7OWWI.js.map → chunk-OPXR4PB2.js.map} +0 -0
- /package/dist/{chunk-Z45YRGFO.js.map → chunk-P6ASQOZR.js.map} +0 -0
- /package/dist/{chunk-2Z3NCLNX.js.map → chunk-QI5NWLVW.js.map} +0 -0
- /package/dist/{chunk-6SAFL5YE.js.map → chunk-RC4BROYR.js.map} +0 -0
- /package/dist/{chunk-NJDQ4YSV.js.map → chunk-RDHUZ674.js.map} +0 -0
- /package/dist/{chunk-3JVXVJ7L.js.map → chunk-S35S77YU.js.map} +0 -0
- /package/dist/{chunk-KUDZVJKQ.js.map → chunk-SHILAQH5.js.map} +0 -0
- /package/dist/{chunk-4UVDI4XE.js.map → chunk-T3PHCEN4.js.map} +0 -0
- /package/dist/{derive-IUA6JFLB.js.map → chunk-UBSFPGVJ.js.map} +0 -0
- /package/dist/{chunk-FAXZQ5UF.js.map → chunk-UCUALOSM.js.map} +0 -0
- /package/dist/{chunk-4HDYQL3J.js.map → chunk-VAG47QHV.js.map} +0 -0
- /package/dist/{chunk-35EBKWQU.js.map → chunk-VFIWDPXZ.js.map} +0 -0
- /package/dist/{chunk-HNHCQ556.js.map → chunk-WLLUM35R.js.map} +0 -0
- /package/dist/{chunk-JRCYZEHU.js.map → chunk-XVU7J43V.js.map} +0 -0
- /package/dist/{chunk-DMQCLZ4Z.js.map → chunk-YCSM3GZU.js.map} +0 -0
- /package/dist/{chunk-FMQJZH4R.js.map → chunk-YMLQBZFJ.js.map} +0 -0
- /package/dist/{chunk-6HFM7EIT.js.map → chunk-YPSOHDNC.js.map} +0 -0
- /package/dist/{chunk-N35NC4JH.js.map → chunk-Z2PWOSCJ.js.map} +0 -0
- /package/dist/{chunk-HPLWFNG4.js.map → chunk-Z7ZXZL6Y.js.map} +0 -0
- /package/dist/{classified-marker-2KJAXRRO.js.map → classified-marker-BSQHU4JT.js.map} +0 -0
- /package/dist/{enclave-JU4YIEPB.js.map → collection-facade-LG3NYZVB.js.map} +0 -0
- /package/dist/{executor-CYJQLKKI.js.map → computed-ASBNTLOK.js.map} +0 -0
- /package/dist/{dead-filter-DCB62VWW.js.map → dead-filter-QKU56XTQ.js.map} +0 -0
- /package/dist/{executor-S4QIKEHW.js.map → derive-CXHCY46K.js.map} +0 -0
- /package/dist/{dispatch-MJ6SHB3Y.js.map → dispatch-4AP4PUZU.js.map} +0 -0
- /package/dist/{executor-YIQB2S6N.js.map → enclave-NYPT7WA7.js.map} +0 -0
- /package/dist/{export-accessible-4S36PQNR.js.map → executor-3KFRQETS.js.map} +0 -0
- /package/dist/{extract-partition-IO7FDZ2P.js.map → executor-AFHQYRAU.js.map} +0 -0
- /package/dist/{find-RBBYKXI7.js.map → executor-YYDW6XQI.js.map} +0 -0
- /package/dist/{issue-RIVHSY2S.js.map → export-accessible-BX2ILB4C.js.map} +0 -0
- /package/dist/{ledger-AETNF4OM.js.map → extract-partition-UPOVITFI.js.map} +0 -0
- /package/dist/{liberate-GFN4C7RR.js.map → find-SZBL2HPB.js.map} +0 -0
- /package/dist/{link-set-E5HNY67I.js.map → issue-G53NB6EW.js.map} +0 -0
- /package/dist/{managed-secret-CWQ6PND5.js.map → ledger-T5K4P2D7.js.map} +0 -0
- /package/dist/{noydb-ASEXNJS6.js.map → liberate-VEOZRESE.js.map} +0 -0
- /package/dist/{register-4EFJCVYD.js.map → link-set-76JZ6YB4.js.map} +0 -0
- /package/dist/{registry-4SDHHOJ7.js.map → managed-secret-6YC32VXG.js.map} +0 -0
- /package/dist/{registry-CZVINVQH.js.map → noydb-EDJA4JNJ.js.map} +0 -0
- /package/dist/{registry-IKUR2MXD.js.map → on/index.js.map} +0 -0
- /package/dist/{post-register-2XSSMGEQ.js.map → post-register-53O7AJRZ.js.map} +0 -0
- /package/dist/{registry-OYTFGWVK.js.map → register-6TCBR6XD.js.map} +0 -0
- /package/dist/{request-withdrawal-KGXGDPVQ.js.map → registry-DH2L4O2V.js.map} +0 -0
- /package/dist/{revoke-JFN773KF.js.map → registry-IWFMXCHX.js.map} +0 -0
- /package/dist/{signer-TA55QB6R.js.map → registry-Q3FG3OAX.js.map} +0 -0
- /package/dist/{stale-ARHFVL5U.js.map → registry-YC3IFG3A.js.map} +0 -0
- /package/dist/{storage-V7MTFAQJ.js.map → request-withdrawal-NM5VYR6F.js.map} +0 -0
- /package/dist/{reveal-BW36KCOQ.js.map → reveal-XBIMHAXR.js.map} +0 -0
- /package/dist/{ulid-PTAIMDG4.js.map → revoke-MJNYWO72.js.map} +0 -0
- /package/dist/{walk-3ZECBFDA.js.map → signer-6XVS2AU3.js.map} +0 -0
- /package/dist/{withdraw-accessible-7PG4DYQK.js.map → stale-MCS46TFO.js.map} +0 -0
- /package/dist/{verify-RO5RTZOJ.js.map → verify-WYOFLSNA.js.map} +0 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-key one envelope from an old collection DEK to a new one (#1074).
|
|
3
|
+
*
|
|
4
|
+
* Lives in the enclave because it is envelope surgery: it reads and writes the
|
|
5
|
+
* protected body slots (`_iv`/`_data`/`_cek`), which `enclave-body-only`
|
|
6
|
+
* reserves to `kernel/enclave/**`. `rotateKeys` previously did this inline in
|
|
7
|
+
* `with-party/team/keyring.ts` and got it wrong in two ways that the guard
|
|
8
|
+
* would have caught had the code lived here.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
import { type EnclaveKey } from '../crypto.js';
|
|
13
|
+
import type { EncryptedEnvelope } from '../../types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Produce the envelope `envelope` becomes once its collection's DEK rotates
|
|
16
|
+
* from `oldDek` to `newDek`.
|
|
17
|
+
*
|
|
18
|
+
* **Every slot is carried forward except `_bidx`.** The previous inline version
|
|
19
|
+
* built a fresh literal holding only `_noydb/_v/_ts/_iv/_data`, silently
|
|
20
|
+
* discarding `_by`, `_tier`, `_cek`, `_sealed`, `_vdig` and `_source`. Losing
|
|
21
|
+
* `_tier` was the worst of those: tier-0 reads treat elevated as missing, so an
|
|
22
|
+
* elevated record did not error after a rotation — it simply disappeared.
|
|
23
|
+
*
|
|
24
|
+
* `_bidx` is dropped deliberately. It is a DEK-rooted equality tag, so a tag
|
|
25
|
+
* carried across a DEK rotation can never be re-derived to match a query again
|
|
26
|
+
* while still leaking the old equality partition. Index coverage regrows
|
|
27
|
+
* per-record on the next `put()` under the new DEK.
|
|
28
|
+
*
|
|
29
|
+
* Two shapes, and picking the wrong one is why this needed a helper:
|
|
30
|
+
*
|
|
31
|
+
* - **per-record CEK** (`_cek` present) — the body is sealed under the CEK and
|
|
32
|
+
* the CEK is wrapped under the collection DEK, so rotation re-wraps the CEK
|
|
33
|
+
* and leaves the body **untouched**. The old inline code instead ran
|
|
34
|
+
* `decrypt(body, oldDek)` on these, which throws: rotation could not complete
|
|
35
|
+
* on a collection containing any CEK record.
|
|
36
|
+
* - **bare** — body sealed directly under the DEK, so decrypt and re-encrypt.
|
|
37
|
+
*
|
|
38
|
+
* Idempotence is the caller's problem, not this function's: it assumes
|
|
39
|
+
* `envelope` is still under `oldDek`. A resumable rotation must know which side
|
|
40
|
+
* of the migration each record is on before calling.
|
|
41
|
+
*/
|
|
42
|
+
export declare function rekeyEnvelopeToDek(ref: {
|
|
43
|
+
readonly collection: string;
|
|
44
|
+
readonly id: string;
|
|
45
|
+
}, envelope: EncryptedEnvelope, oldDek: EnclaveKey, newDek: EnclaveKey): Promise<EncryptedEnvelope>;
|
|
46
|
+
/**
|
|
47
|
+
* Resumable variant: returns the re-keyed envelope, or `null` when `envelope`
|
|
48
|
+
* is **already** under `newDek` and needs no work (#1074 part 2).
|
|
49
|
+
*
|
|
50
|
+
* A rotation interrupted mid-collection leaves records on both sides of the
|
|
51
|
+
* migration. Resuming means re-running the rotation with the *same* new DEK,
|
|
52
|
+
* which requires distinguishing "not yet moved" from "already moved" without
|
|
53
|
+
* the caller touching protected slots.
|
|
54
|
+
*
|
|
55
|
+
* Detection is by trial decryption under `oldDek`. There is no metadata that
|
|
56
|
+
* says which DEK sealed a record — deliberately, since such a marker would be
|
|
57
|
+
* store-writable and therefore a downgrade lever (the same reasoning that
|
|
58
|
+
* keeps the reader from branching on `_noydb`).
|
|
59
|
+
*
|
|
60
|
+
* A record that opens under *neither* key is genuinely damaged and rethrows,
|
|
61
|
+
* rather than being silently skipped: a rotation that quietly walked past
|
|
62
|
+
* unreadable records would convert a loud failure into permanent silent loss,
|
|
63
|
+
* which is the defect this whole issue is about.
|
|
64
|
+
*/
|
|
65
|
+
export declare function rekeyEnvelopeIfNeeded(ref: {
|
|
66
|
+
readonly collection: string;
|
|
67
|
+
readonly id: string;
|
|
68
|
+
}, envelope: EncryptedEnvelope, oldDek: EnclaveKey, newDek: EnclaveKey): Promise<EncryptedEnvelope | null>;
|
|
69
|
+
/**
|
|
70
|
+
* Does this envelope open under ANY of `keys`? A read-only probe — decrypts
|
|
71
|
+
* nothing into a caller-visible value and writes nothing.
|
|
72
|
+
*
|
|
73
|
+
* Exists so a rotation can tell *"this envelope belongs to a DIFFERENT DEK slot
|
|
74
|
+
* the caller also holds"* from *"this envelope is damaged"* (#1125). Those two
|
|
75
|
+
* look identical from a failed `rekeyEnvelopeIfNeeded`, and collapsing them
|
|
76
|
+
* either aborts a legitimate rotation or walks past unreadable data.
|
|
77
|
+
*
|
|
78
|
+
* **The question is deliberately asked of the KEY, not of the envelope's claimed
|
|
79
|
+
* `_tier`.** `_tier` is unencrypted — the store writes it — so routing a
|
|
80
|
+
* rotation on it would let a store mark a tier-0 record `_tier: 5` and have the
|
|
81
|
+
* rotation skip it, leaving a revoked member's DEK live on real data. That is
|
|
82
|
+
* #1115's defect wearing a different hat. A key either opens the body or it does
|
|
83
|
+
* not, and a store cannot forge that.
|
|
84
|
+
*
|
|
85
|
+
* Mirrors `rekeyBlobSet`'s `otherDeks` treatment, which asks the same question
|
|
86
|
+
* about the same kind of ambiguity.
|
|
87
|
+
*/
|
|
88
|
+
export declare function envelopeOpensUnderAny(ref: {
|
|
89
|
+
readonly collection: string;
|
|
90
|
+
readonly id: string;
|
|
91
|
+
}, envelope: EncryptedEnvelope, keys: readonly EnclaveKey[]): Promise<boolean>;
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* vault; it calls into these.
|
|
17
17
|
*/
|
|
18
18
|
import { type EncryptedEnvelope } from '../../types.js';
|
|
19
|
+
import type { RecordRef } from '../record-aad.js';
|
|
19
20
|
/**
|
|
20
21
|
* Shape-only tombstone recognition for layers that have no per-collection
|
|
21
22
|
* context (the sync engine, #590): a tombstone carries an empty `_data` and
|
|
@@ -45,7 +46,7 @@ export declare function isTombstone(envelope: EncryptedEnvelope, encrypted: bool
|
|
|
45
46
|
* Deliberately omits `_iv`/`_data`/`_cek`/`_det` — that omission *is* the
|
|
46
47
|
* erasure.
|
|
47
48
|
*/
|
|
48
|
-
export declare function buildTombstone(version: number, actor: string): EncryptedEnvelope;
|
|
49
|
+
export declare function buildTombstone(ref: RecordRef, version: number, actor: string): EncryptedEnvelope;
|
|
49
50
|
/** #589: is this envelope an ordinary-delete marker (version-ordered, reads as absent)? */
|
|
50
51
|
export declare function isDeleteMarker(envelope: EncryptedEnvelope): boolean;
|
|
51
52
|
/**
|
|
@@ -54,4 +55,4 @@ export declare function isDeleteMarker(envelope: EncryptedEnvelope): boolean;
|
|
|
54
55
|
* keeps the displaced `_v` — so it wins convergence over the pre-delete copy and a
|
|
55
56
|
* re-create can still win over it at a higher version.
|
|
56
57
|
*/
|
|
57
|
-
export declare function buildDeleteMarker(version: number, actor: string): EncryptedEnvelope;
|
|
58
|
+
export declare function buildDeleteMarker(ref: RecordRef, version: number, actor: string): EncryptedEnvelope;
|
package/dist/kernel/errors.d.ts
CHANGED
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
* ├─ Crypto errors
|
|
11
11
|
* │ ├─ DecryptionError — AES-GCM tag failure
|
|
12
12
|
* │ ├─ TamperedError — ciphertext modified after write
|
|
13
|
-
* │
|
|
13
|
+
* │ ├─ InvalidKeyError — wrong secret / corrupt keyring
|
|
14
|
+
* │ ├─ KeyringCorruptError — partial DEK corruption, KEK correct
|
|
15
|
+
* │ └─ KeyringTamperedError — keyring roster failed authentication (#1096)
|
|
14
16
|
* ├─ Access errors
|
|
15
17
|
* │ ├─ NoAccessError — no DEK for this collection
|
|
16
18
|
* │ ├─ ReadOnlyError — ro permission, write attempted
|
|
@@ -52,7 +54,7 @@
|
|
|
52
54
|
* │ ├─ BackupLedgerError — hash-chain verification failed
|
|
53
55
|
* │ └─ BackupCorruptedError — envelope hash mismatch in dump
|
|
54
56
|
* ├─ Bundle errors
|
|
55
|
-
* │ └─
|
|
57
|
+
* │ └─ PodIntegrityError — .noydb body sha256 mismatch
|
|
56
58
|
* ├─ Session errors
|
|
57
59
|
* │ ├─ SessionExpiredError
|
|
58
60
|
* │ ├─ SessionNotFoundError
|
|
@@ -143,7 +145,23 @@ export declare class DecryptionError extends NoydbError {
|
|
|
143
145
|
* Treat it as a security alert: the stored bytes are not what NOYDB wrote.
|
|
144
146
|
*/
|
|
145
147
|
export declare class TamperedError extends NoydbError {
|
|
146
|
-
|
|
148
|
+
/**
|
|
149
|
+
* Why the tag check failed, when the enclave could tell (#1103).
|
|
150
|
+
*
|
|
151
|
+
* `'unbound-legacy-format'` — the body opens under an EMPTY AAD, so it was
|
|
152
|
+
* sealed before identity binding (#1041) and this is a format transition, not
|
|
153
|
+
* an attack. Positive evidence, not a guess: producing a body that decrypts
|
|
154
|
+
* under this DEK requires the DEK, which an untrusted store does not hold.
|
|
155
|
+
*
|
|
156
|
+
* Absent — no benign explanation was found. Treat as the security alert this
|
|
157
|
+
* error has always been.
|
|
158
|
+
*
|
|
159
|
+
* The field is additive and the throw is unchanged, so
|
|
160
|
+
* `catch (e) { if (e instanceof TamperedError) … }` keeps working; callers
|
|
161
|
+
* that want to tell a migration from a breach can now read this.
|
|
162
|
+
*/
|
|
163
|
+
readonly reason?: 'unbound-legacy-format';
|
|
164
|
+
constructor(message?: string, reason?: 'unbound-legacy-format');
|
|
147
165
|
}
|
|
148
166
|
/**
|
|
149
167
|
* Thrown when key unwrapping fails, typically because the secret is wrong
|
|
@@ -177,6 +195,86 @@ export declare class KeyringCorruptError extends NoydbError {
|
|
|
177
195
|
message?: string;
|
|
178
196
|
});
|
|
179
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* #1096 — the keyring's plaintext AUTHORITY half failed authentication.
|
|
200
|
+
*
|
|
201
|
+
* Thrown by `loadKeyring` when the canary is absent, when the reserved
|
|
202
|
+
* roster-key DEK entry is absent, or when the keys check out (KEK proven
|
|
203
|
+
* correct) but `roster_tag` is missing or does not match the file.
|
|
204
|
+
*
|
|
205
|
+
* Distinct from {@link KeyringCorruptError}: the KEYS are fine; the ROSTER —
|
|
206
|
+
* `role`, `permissions`, `granted_by`, the capability grants — is what cannot
|
|
207
|
+
* be trusted. A `_keyring` file is stored plaintext so admins can edit a
|
|
208
|
+
* member's authority without holding that member's credential, which left
|
|
209
|
+
* those fields authenticated by nothing; this error is what a hostile store
|
|
210
|
+
* editing them now produces.
|
|
211
|
+
*
|
|
212
|
+
* Deliberately raised only AFTER the key-unwrap epilogue, so a plain
|
|
213
|
+
* wrong-secret keeps reporting as `InvalidKeyError` and is never
|
|
214
|
+
* misannounced to the user as an attack.
|
|
215
|
+
*/
|
|
216
|
+
/**
|
|
217
|
+
* Why a `_keyring` file failed roster authentication (#1096).
|
|
218
|
+
*
|
|
219
|
+
* Named rather than inlined because a third consumer now reports it without
|
|
220
|
+
* throwing: `RotateResult.unverified` (#1114) lists the members a rotation
|
|
221
|
+
* skipped, and a union duplicated per call site drifts.
|
|
222
|
+
*/
|
|
223
|
+
export type KeyringTamperedReason = 'canary-missing' | 'roster-key-missing' | 'roster-tag-missing' | 'roster-tag-mismatch'
|
|
224
|
+
/**
|
|
225
|
+
* The tag does not verify AND the file declares an older `_noydb_keyring`
|
|
226
|
+
* than this build writes (#1115) — a format transition, not an attack.
|
|
227
|
+
*
|
|
228
|
+
* Split out of `roster-tag-mismatch` deliberately. That label carries the one
|
|
229
|
+
* UNQUALIFIED accusation in this union, on the grounds that no released
|
|
230
|
+
* version ever wrote a mismatched tag. Widening what the tag covers makes
|
|
231
|
+
* that false for every vault written before the change, so without this the
|
|
232
|
+
* most common cause of a mismatch — you upgraded — would be reported as
|
|
233
|
+
* "the store has changed a member's role".
|
|
234
|
+
*
|
|
235
|
+
* CLASSIFICATION ONLY: the outcome is refusal either way, so a store that
|
|
236
|
+
* rewrites the plaintext version field changes the wording and nothing else.
|
|
237
|
+
*/
|
|
238
|
+
| 'format-superseded'
|
|
239
|
+
/**
|
|
240
|
+
* The file did not parse at all (#1121). Never thrown by
|
|
241
|
+
* `assertRosterAuthenticated` — which cannot reach a file it could not read —
|
|
242
|
+
* but reported by `verifyRoster` and accepted by `quarantineKeyring`, because
|
|
243
|
+
* truncation and bitrot produce the most literally unauthenticatable file
|
|
244
|
+
* there is and the tools for unauthenticatable files must not be the ones
|
|
245
|
+
* that choke on it.
|
|
246
|
+
*/
|
|
247
|
+
| 'unparseable';
|
|
248
|
+
export declare class KeyringTamperedError extends NoydbError {
|
|
249
|
+
readonly details: {
|
|
250
|
+
readonly userId: string;
|
|
251
|
+
readonly reason: KeyringTamperedReason;
|
|
252
|
+
/**
|
|
253
|
+
* The keyring format transition, when one is known: `from` is the version
|
|
254
|
+
* the FILE declares, `to` the version this build writes.
|
|
255
|
+
*
|
|
256
|
+
* Present so a reader can tell which version they hold and which one this
|
|
257
|
+
* build wants, without reverse-engineering it from the prose. The message
|
|
258
|
+
* said "an OLDER FORMAT" and never named either number, which is not
|
|
259
|
+
* enough to work out whether you are one release behind or five.
|
|
260
|
+
*
|
|
261
|
+
* Structured, not parsed out of the message: a consumer that translates
|
|
262
|
+
* the error never sees the English at all.
|
|
263
|
+
*/
|
|
264
|
+
readonly format?: {
|
|
265
|
+
readonly from: number;
|
|
266
|
+
readonly to: number;
|
|
267
|
+
};
|
|
268
|
+
};
|
|
269
|
+
constructor(details: {
|
|
270
|
+
readonly userId: string;
|
|
271
|
+
readonly reason: KeyringTamperedReason;
|
|
272
|
+
readonly format?: {
|
|
273
|
+
readonly from: number;
|
|
274
|
+
readonly to: number;
|
|
275
|
+
};
|
|
276
|
+
});
|
|
277
|
+
}
|
|
180
278
|
/**
|
|
181
279
|
* Thrown when the authenticated user does not have a DEK for the requested
|
|
182
280
|
* collection — i.e. the collection is not in their keyring at all.
|
|
@@ -277,7 +375,7 @@ export declare class ExportCapabilityError extends NoydbError {
|
|
|
277
375
|
* can show a precise "this bundle slot has expired" message instead
|
|
278
376
|
* of the generic decryption-failure UX.
|
|
279
377
|
*
|
|
280
|
-
* Used predominantly on `
|
|
378
|
+
* Used predominantly on `PodRecipient` slots produced by
|
|
281
379
|
* `writePod({ recipients: [...] })` to time-box audit access.
|
|
282
380
|
*/
|
|
283
381
|
export declare class KeyringExpiredError extends NoydbError {
|
|
@@ -759,10 +857,6 @@ export declare class PodVersionConflictError extends NoydbError {
|
|
|
759
857
|
readonly remoteVersion: string;
|
|
760
858
|
constructor(remoteVersion: string, message?: string);
|
|
761
859
|
}
|
|
762
|
-
/** @deprecated Use `PodVersionConflictError`. */
|
|
763
|
-
export declare const BundleVersionConflictError: typeof PodVersionConflictError;
|
|
764
|
-
/** @deprecated Use `PodVersionConflictError`. */
|
|
765
|
-
export type BundleVersionConflictError = PodVersionConflictError;
|
|
766
860
|
/**
|
|
767
861
|
* Thrown when a sync operation (push or pull) fails due to a network error.
|
|
768
862
|
*
|
|
@@ -1012,7 +1106,7 @@ export declare class FieldNotQueryableError extends NoydbError {
|
|
|
1012
1106
|
* format violations like a missing magic prefix or malformed
|
|
1013
1107
|
* header JSON) so consumers can pattern-match the corruption case
|
|
1014
1108
|
* and handle it differently from a producer bug. A
|
|
1015
|
-
* `
|
|
1109
|
+
* `PodIntegrityError` indicates "the bytes you got are not
|
|
1016
1110
|
* what was written"; a plain `Error` from `parsePrefixAndHeader`
|
|
1017
1111
|
* indicates "what was written wasn't a valid bundle in the first
|
|
1018
1112
|
* place."
|
|
@@ -1022,7 +1116,7 @@ export declare class FieldNotQueryableError extends NoydbError {
|
|
|
1022
1116
|
* written) but it surfaces with the same error class because the
|
|
1023
1117
|
* end result is "the body cannot be turned back into a dump."
|
|
1024
1118
|
*/
|
|
1025
|
-
export declare class
|
|
1119
|
+
export declare class PodIntegrityError extends NoydbError {
|
|
1026
1120
|
constructor(message: string);
|
|
1027
1121
|
}
|
|
1028
1122
|
/**
|
|
@@ -1039,14 +1133,14 @@ export declare class PodHeaderVerificationError extends NoydbError {
|
|
|
1039
1133
|
}
|
|
1040
1134
|
/**
|
|
1041
1135
|
* Thrown by `readPod` when the bundle carries
|
|
1042
|
-
* sealed per-user secrets but no supplied `
|
|
1136
|
+
* sealed per-user secrets but no supplied `NoydbSealer`
|
|
1043
1137
|
* has a `.id` (= `pid`) matching the sealed entry's `pid`.
|
|
1044
1138
|
*
|
|
1045
1139
|
* Carries the failing pid + the user id so the recipient can
|
|
1046
1140
|
* surface an actionable prompt:
|
|
1047
1141
|
*
|
|
1048
1142
|
* ```
|
|
1049
|
-
*
|
|
1143
|
+
* PodSealMismatchError: bundle carries sealed secret for user "alice"
|
|
1050
1144
|
* under provider "macos-keychain:com.acme.app/alice@acme.example",
|
|
1051
1145
|
* but no registered provider matches that pid.
|
|
1052
1146
|
* ```
|
|
@@ -1059,7 +1153,7 @@ export declare class PodHeaderVerificationError extends NoydbError {
|
|
|
1059
1153
|
* 3. Inspect without unsealing — pass no `sealingProviders` to
|
|
1060
1154
|
* receive the sealed entries unmodified for offline analysis.
|
|
1061
1155
|
*/
|
|
1062
|
-
export declare class
|
|
1156
|
+
export declare class PodSealMismatchError extends NoydbError {
|
|
1063
1157
|
readonly userId: string;
|
|
1064
1158
|
readonly pid: string;
|
|
1065
1159
|
constructor(userId: string, pid: string);
|
|
@@ -1565,6 +1659,32 @@ export declare class CrossJoinTooLargeError extends NoydbError {
|
|
|
1565
1659
|
limit: number;
|
|
1566
1660
|
});
|
|
1567
1661
|
}
|
|
1662
|
+
/**
|
|
1663
|
+
* Thrown by `.join()` when the field it is asked to follow carries no `ref()`
|
|
1664
|
+
* declaration on the left collection (and is not a `dictKey` join field).
|
|
1665
|
+
*
|
|
1666
|
+
* A distinct class rather than a bare `Error` because the condition is
|
|
1667
|
+
* legitimately TRANSIENT for one caller: a materialized view's `query()`
|
|
1668
|
+
* callback is invoked during `openVault()`, before user code has had any
|
|
1669
|
+
* opportunity to declare a collection's refs, so the MV registry defers that
|
|
1670
|
+
* strategy's planning and retries instead of failing the vault open (#1139).
|
|
1671
|
+
* Matching that condition on the message text would be the kind of proxy this
|
|
1672
|
+
* codebase keeps getting bitten by; the class is the fact.
|
|
1673
|
+
*
|
|
1674
|
+
* For every other caller the meaning is unchanged and terminal: declare the
|
|
1675
|
+
* ref, then retry. The message is identical to the one this replaced.
|
|
1676
|
+
*/
|
|
1677
|
+
export declare class RefNotDeclaredError extends NoydbError {
|
|
1678
|
+
/** Collection the join was issued from. */
|
|
1679
|
+
readonly collection: string;
|
|
1680
|
+
/** Field the join tried to follow. */
|
|
1681
|
+
readonly field: string;
|
|
1682
|
+
constructor(opts: {
|
|
1683
|
+
collection: string;
|
|
1684
|
+
field: string;
|
|
1685
|
+
message: string;
|
|
1686
|
+
});
|
|
1687
|
+
}
|
|
1568
1688
|
/**
|
|
1569
1689
|
* Thrown at cross-join execution time when the target collection is not
|
|
1570
1690
|
* reachable from the current vault. The left collection is included in the
|
|
@@ -1977,7 +2097,7 @@ export declare class RecoveryNotEnrolledError extends NoydbError {
|
|
|
1977
2097
|
* STRONG recovery profile enrolled.
|
|
1978
2098
|
*
|
|
1979
2099
|
* Managed mode means the user never types a secret — the unlock
|
|
1980
|
-
* material lives in a `
|
|
2100
|
+
* material lives in a `NoydbSealer` (`at-*` package). If that
|
|
1981
2101
|
* provider's key is lost AND no strong recovery is enrolled, the
|
|
1982
2102
|
* vault is irrecoverable. To prevent that footgun, managed-mode vaults
|
|
1983
2103
|
* require at least one strong recovery profile (Shamir today;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { MergeAuthority } from '../port/with/merge-authority.js';
|
|
2
|
+
import type { EnclaveKey } from './enclave/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* ⚠️ **A client cannot verify what it cannot decrypt** — and that boundary is
|
|
5
|
+
* stated here rather than hidden.
|
|
6
|
+
*
|
|
7
|
+
* A record at a tier this caller holds no key for is accepted **unverified**.
|
|
8
|
+
* Rejecting it would break replication of data the peer legitimately holds but
|
|
9
|
+
* this client is not cleared to read, converting a confidentiality boundary
|
|
10
|
+
* into a replication failure. The residue is narrow: envelopes whose key the
|
|
11
|
+
* client lacks are pass-through, exactly as every envelope was before #1042.
|
|
12
|
+
*
|
|
13
|
+
* Closing that residue needs the vault head (#1044), which can detect absence
|
|
14
|
+
* and substitution without holding the key.
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildMergeAuthority(
|
|
17
|
+
/**
|
|
18
|
+
* Just the DEK map, not the whole keyring. `port-layering` refused a type
|
|
19
|
+
* import of `UnlockedKeyring` from `with-party` — correctly, and the narrower
|
|
20
|
+
* shape is better anyway: this needs to look up keys, not to know what a
|
|
21
|
+
* keyring is.
|
|
22
|
+
*/
|
|
23
|
+
keyring: {
|
|
24
|
+
readonly deks: ReadonlyMap<string, EnclaveKey>;
|
|
25
|
+
}): MergeAuthority;
|
package/dist/kernel/noydb.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type { RotateResult } from '../with-party/team/keyring.js';
|
|
2
|
-
import type { NoydbOptions, NoydbEventMap, GrantOptions, RevokeOptions, UpdateUserOptions, UserInfo, PushResult, PullResult, PushOptions, PullOptions, SyncStatus, SyncTargetInfo, NoydbStore, AccessibleVault, ListAccessibleVaultsOptions, QueryAcrossOptions, QueryAcrossResult, TranslatorAuditEntry, WriteConflict, UserApiFactory, ActiveTier, FactorProofBundle, GateName, VaultPolicy } from './types.js';
|
|
1
|
+
import type { RotateResult, RosterVerifyResult, QuarantineResult } from '../with-party/team/keyring.js';
|
|
2
|
+
import type { NoydbOptions, NoydbEventMap, GrantOptions, RevokeOptions, UpdateUserOptions, UserInfo, PushResult, PullResult, PushOptions, PullOptions, SyncStatus, SyncTargetInfo, SyncTargetStatus, NoydbStore, AccessibleVault, ListAccessibleVaultsOptions, QueryAcrossOptions, QueryAcrossResult, TranslatorAuditEntry, WriteConflict, UserApiFactory, ActiveTier, FactorProofBundle, GateName, VaultPolicy } from './types.js';
|
|
3
3
|
import type { SecretPolicy } from './validation.js';
|
|
4
|
-
import { type
|
|
4
|
+
import { type NoydbMesh } from '../port/by/default-provider.js';
|
|
5
5
|
import type { Cover } from '../with-party/directory/cover/types.js';
|
|
6
6
|
import type { SetCoverInput } from '../with-party/directory/cover/schema.js';
|
|
7
7
|
import { Vault } from './vault.js';
|
|
@@ -36,8 +36,8 @@ export declare class Noydb {
|
|
|
36
36
|
/** Session that owns this instance's writers (one user's writers across vaults). */
|
|
37
37
|
private readonly sessionId;
|
|
38
38
|
/** Drain-barrier coordination transport for the schema fence. */
|
|
39
|
-
private readonly
|
|
40
|
-
/** Pre-resolved `vault.user` API factory (mirrors `
|
|
39
|
+
private readonly meshPort;
|
|
40
|
+
/** Pre-resolved `vault.user` API factory (mirrors `meshPort` above). Public so `Vault` can call it. */
|
|
41
41
|
readonly userApiFactory: UserApiFactory;
|
|
42
42
|
private readonly vaultCache;
|
|
43
43
|
/**
|
|
@@ -96,7 +96,7 @@ export declare class Noydb {
|
|
|
96
96
|
get custodyStrategy(): CustodyStrategy;
|
|
97
97
|
private readonly snapshots;
|
|
98
98
|
private readonly policyManager;
|
|
99
|
-
/** Pre-resolved policy-gate engine function (mirrors `
|
|
99
|
+
/** Pre-resolved policy-gate engine function (mirrors `meshPort`/`userApiFactory` above). */
|
|
100
100
|
private readonly policyCheckGate;
|
|
101
101
|
/**
|
|
102
102
|
* Credential and multi-user operations — enrolment, secret rotation,
|
|
@@ -282,8 +282,8 @@ export declare class Noydb {
|
|
|
282
282
|
* collection) pair that was dropped. Re-run `grant()` for those pairs, or
|
|
283
283
|
* they stay locked out.
|
|
284
284
|
*
|
|
285
|
-
* Unlike `revoke(
|
|
286
|
-
*
|
|
285
|
+
* Unlike `revoke()`, this call does not REMOVE any user from the vault —
|
|
286
|
+
* they keep membership and their other collections.
|
|
287
287
|
* This is the "just rotate" path; "revoke and rotate" lives in `revoke()`.
|
|
288
288
|
*
|
|
289
289
|
* Exposed on Noydb (rather than only on the lower-level keyring
|
|
@@ -292,6 +292,23 @@ export declare class Noydb {
|
|
|
292
292
|
* Opt-in (#267): throws {@link TeamNotEnabledError} without `withTeam()`.
|
|
293
293
|
*/
|
|
294
294
|
rotate(vault: string, collections: string[]): Promise<RotateResult>;
|
|
295
|
+
/**
|
|
296
|
+
* Verify every `_keyring` file in the vault. Read-only (#1121).
|
|
297
|
+
*
|
|
298
|
+
* Names each failing file and why, so the bad one need not be found by trial.
|
|
299
|
+
* Reports `checked` too: "nothing unverified" is equally true of a sweep that
|
|
300
|
+
* examined nothing.
|
|
301
|
+
*/
|
|
302
|
+
verifyRoster(vault: string): Promise<RosterVerifyResult>;
|
|
303
|
+
/**
|
|
304
|
+
* Remove a `_keyring` file that cannot be authenticated, and re-key behind it
|
|
305
|
+
* (#1121). Owner-only; refuses a file that verifies (use {@link revoke}).
|
|
306
|
+
*
|
|
307
|
+
* `revoke` consults the target's own `role`, so it cannot act on a file it
|
|
308
|
+
* will not trust. This ignores every claim the file makes — which is exactly
|
|
309
|
+
* why it is restricted to files that already fail authentication.
|
|
310
|
+
*/
|
|
311
|
+
quarantineKeyring(vault: string, userId: string, factors?: FactorProofBundle): Promise<QuarantineResult>;
|
|
295
312
|
/** List all users with access to a vault. */
|
|
296
313
|
listUsers(vault: string): Promise<UserInfo[]>;
|
|
297
314
|
/**
|
|
@@ -549,6 +566,12 @@ export declare class Noydb {
|
|
|
549
566
|
_clearActiveTxContext(ctx: TxContext): void;
|
|
550
567
|
/** Get sync status for a vault. */
|
|
551
568
|
syncStatus(vault: string): SyncStatus;
|
|
569
|
+
/**
|
|
570
|
+
* Per-target sync state for `vault` (#1034) — `syncStatus()` reads only the
|
|
571
|
+
* primary engine, so it cannot express "the LAN store is behind, the cloud
|
|
572
|
+
* is current". Registration order, primary first. See {@link SyncTargetStatus}.
|
|
573
|
+
*/
|
|
574
|
+
syncTargetStatus(vault: string): SyncTargetStatus[];
|
|
552
575
|
/**
|
|
553
576
|
* Enumerate the sync targets wired for `vault` (#948) — the primary engine
|
|
554
577
|
* (keyed by vault name) plus any additional targets (keyed `vault::label`
|
|
@@ -613,9 +636,9 @@ export declare class Noydb {
|
|
|
613
636
|
/**
|
|
614
637
|
* @internal Drain-barrier coordination transport for the schema fence.
|
|
615
638
|
* The default store-backed provider reproduces today's fence behavior; a
|
|
616
|
-
* `by-*` real-time transport is injected via `
|
|
639
|
+
* `by-*` real-time transport is injected via `mesh`.
|
|
617
640
|
*/
|
|
618
|
-
get
|
|
641
|
+
get mesh(): NoydbMesh;
|
|
619
642
|
/**
|
|
620
643
|
* #693: true when multi-tab coordination is active at all — presence/election
|
|
621
644
|
* alone (`propagateWrites: false`) or full write-propagation — a peer tab can
|
|
@@ -270,6 +270,32 @@ export declare class Query<T, S extends keyof T = never, Q extends keyof T & str
|
|
|
270
270
|
* carries the original `T` fields plus `result[as]` populated from every
|
|
271
271
|
* right-side row (or the filtered subset when `on:` is supplied).
|
|
272
272
|
*
|
|
273
|
+
* **⚠️ INNER-join semantics — an empty right subset DROPS the left row.**
|
|
274
|
+
* Each left row is emitted once per matching right row, so when `on:`
|
|
275
|
+
* yields nothing the row vanishes with no error, no warning and no count
|
|
276
|
+
* mismatch. This bites hardest on a reverse FK, where `.join()` (which is
|
|
277
|
+
* forward-only, and already a genuine LEFT outer join) does not apply and
|
|
278
|
+
* `.crossJoin()` is the only tool. To keep the row, return a one-element
|
|
279
|
+
* array holding `null`:
|
|
280
|
+
*
|
|
281
|
+
* ```ts
|
|
282
|
+
* .crossJoin('clients', { as: 'client', on: (b) => byEntity.get(b.entityId) ?? [null] })
|
|
283
|
+
* // ^^^^^^^^
|
|
284
|
+
* // the ONLY thing preserving the row
|
|
285
|
+
* ```
|
|
286
|
+
*
|
|
287
|
+
* **Prefer `outer: true`**, which does exactly this and types the alias as
|
|
288
|
+
* `TTarget | null`:
|
|
289
|
+
*
|
|
290
|
+
* ```ts
|
|
291
|
+
* .crossJoin('clients', { as: 'client', outer: true, on: (b) => byEntity.get(b.entityId) ?? [] })
|
|
292
|
+
* ```
|
|
293
|
+
*
|
|
294
|
+
* The `?? [null]` form remains valid and is what `outer` does internally, but
|
|
295
|
+
* it is invisible intent: it types the alias as non-null while the row can
|
|
296
|
+
* hold null, and a later "simplification" that drops it silently
|
|
297
|
+
* reintroduces the row loss.
|
|
298
|
+
*
|
|
273
299
|
* **Order matters:** `.where().crossJoin()` filters BEFORE expanding (cheaper);
|
|
274
300
|
* `.crossJoin().where('alias.field', ...)` filters AFTER (required when the
|
|
275
301
|
* where clause references the aliased fields).
|
|
@@ -286,14 +312,22 @@ export declare class Query<T, S extends keyof T = never, Q extends keyof T & str
|
|
|
286
312
|
*
|
|
287
313
|
* Requires a JoinContext (constructed via `collection.query()`).
|
|
288
314
|
*/
|
|
289
|
-
crossJoin<TTarget = unknown, As extends string = string>(target: string, opts: {
|
|
315
|
+
crossJoin<TTarget = unknown, As extends string = string, TOuter extends boolean = false>(target: string, opts: {
|
|
290
316
|
as: As;
|
|
291
317
|
on?: ((left: T) => unknown[] | ((right: TTarget) => boolean)) | {
|
|
292
318
|
readonly predicate: string;
|
|
293
319
|
};
|
|
294
320
|
maxRows?: number;
|
|
321
|
+
/**
|
|
322
|
+
* Keep the left row when its right side is empty, with `null` under
|
|
323
|
+
* `as`, instead of dropping it (#1130). Widens the alias to
|
|
324
|
+
* `TTarget | null` — which is why it is a type parameter rather than a
|
|
325
|
+
* plain boolean: `outer: false` must not pay for a null the row can
|
|
326
|
+
* never hold.
|
|
327
|
+
*/
|
|
328
|
+
outer?: TOuter;
|
|
295
329
|
}): Query<T & {
|
|
296
|
-
[K in As]: TTarget;
|
|
330
|
+
[K in As]: TOuter extends true ? TTarget | null : TTarget;
|
|
297
331
|
}, S, Q, M>;
|
|
298
332
|
/**
|
|
299
333
|
* Execute the plan and return the matching records. When the plan
|
|
@@ -309,6 +343,12 @@ export declare class Query<T, S extends keyof T = never, Q extends keyof T & str
|
|
|
309
343
|
toArray(opts?: {
|
|
310
344
|
locale?: string;
|
|
311
345
|
}): T[];
|
|
346
|
+
/**
|
|
347
|
+
* Joins need a `JoinContext`. Unreachable in practice — `.join()` throws
|
|
348
|
+
* when one is missing — but belt-and-braces for a plan built through the
|
|
349
|
+
* raw `Query` constructor with joins pre-populated.
|
|
350
|
+
*/
|
|
351
|
+
private requireJoinContext;
|
|
312
352
|
/**
|
|
313
353
|
* Decode this source's Via-covered fields on read (e.g. money: stored
|
|
314
354
|
* scaled-int → canonical decimal), so `query().toArray()` agrees with
|
|
@@ -330,12 +370,19 @@ export declare class Query<T, S extends keyof T = never, Q extends keyof T & str
|
|
|
330
370
|
}): T | null;
|
|
331
371
|
/**
|
|
332
372
|
* Return the number of matching records (after where/filter,
|
|
333
|
-
* before limit). **Joins are NOT applied** — count() reports the
|
|
334
|
-
* left-side cardinality, because joins
|
|
373
|
+
* before limit). **Joins are normally NOT applied** — count() reports the
|
|
374
|
+
* left-side cardinality, because joins are projection-only
|
|
335
375
|
* (they attach an aliased field; they never filter). Running joins
|
|
336
376
|
* here just to discard the aliases would be wasteful, and in strict
|
|
337
377
|
* mode it could throw `DanglingReferenceError` for a call whose
|
|
338
378
|
* intent is purely to count.
|
|
379
|
+
*
|
|
380
|
+
* The exception (#1030) is a `where` clause addressing a join alias. Then
|
|
381
|
+
* the legs must run, because the predicate is part of what is being
|
|
382
|
+
* counted — skipping them would report the unfiltered left cardinality.
|
|
383
|
+
* A strict-mode `DanglingReferenceError` becomes reachable from `count()`
|
|
384
|
+
* in exactly that case, which is acceptable: the caller asked to filter on
|
|
385
|
+
* the joined side, so they asked for the join.
|
|
339
386
|
*/
|
|
340
387
|
count(): number;
|
|
341
388
|
/**
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
* including joined reads.
|
|
46
46
|
*/
|
|
47
47
|
import type { RefDescriptor, RefMode } from '../refs.js';
|
|
48
|
+
import type { Clause } from './predicate.js';
|
|
48
49
|
/** Planner strategy for a single join leg. Auto-selected unless overridden. */
|
|
49
50
|
export type JoinStrategy = 'hash' | 'nested';
|
|
50
51
|
/** Default per-side row ceiling before `.join()` throws `JoinTooLargeError`. */
|
|
@@ -168,6 +169,32 @@ export interface JoinContext {
|
|
|
168
169
|
*/
|
|
169
170
|
resolveDictSource?(field: string): JoinableSource | null;
|
|
170
171
|
}
|
|
172
|
+
/**
|
|
173
|
+
* Split a plan's clauses into those evaluable before the join legs run and
|
|
174
|
+
* those that need the joined shape (#1030).
|
|
175
|
+
*
|
|
176
|
+
* Join legs attach after `where` so the left set can be narrowed (and
|
|
177
|
+
* index-driven) first. That is the right default, but it silently broke any
|
|
178
|
+
* predicate addressing a joined alias: the field did not exist yet, so
|
|
179
|
+
* `readPath` returned `undefined`, nothing matched, and the query returned an
|
|
180
|
+
* empty result with no error.
|
|
181
|
+
*
|
|
182
|
+
* The split is deliberately narrow. When no clause addresses an alias — every
|
|
183
|
+
* query written against the previous behaviour — `postJoin` is empty and the
|
|
184
|
+
* caller takes its original path unchanged. The reordered pipeline therefore
|
|
185
|
+
* only ever runs for queries that match nothing today.
|
|
186
|
+
*
|
|
187
|
+
* KNOWN RESIDUAL: `.filter(r => r.client?.name === 'Ann')` cannot be
|
|
188
|
+
* classified (the predicate is a closure), so it still runs pre-join and still
|
|
189
|
+
* sees no alias. Prefer `.where()` for anything addressing a joined field.
|
|
190
|
+
*
|
|
191
|
+
* Shared by the eager `Query` and the streaming `ScanBuilder` so the two
|
|
192
|
+
* cannot drift on which side a clause belongs to.
|
|
193
|
+
*/
|
|
194
|
+
export declare function splitAroundJoins(clauses: readonly Clause[], joins: readonly JoinLeg[]): {
|
|
195
|
+
readonly preJoin: readonly Clause[];
|
|
196
|
+
readonly postJoin: readonly Clause[];
|
|
197
|
+
};
|
|
171
198
|
/**
|
|
172
199
|
* Apply every join leg in the plan against a base set of left-side
|
|
173
200
|
* rows. Called by the query executor after `where` / `orderBy` /
|
|
@@ -6,11 +6,18 @@
|
|
|
6
6
|
* collection AND every right-side collection a join leg points at)
|
|
7
7
|
* mutates.
|
|
8
8
|
*
|
|
9
|
-
* Framework-agnostic by design
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
9
|
+
* Framework-agnostic by design — core never depends on a UI
|
|
10
|
+
* framework. The binding that wraps a `LiveQuery` is
|
|
11
|
+
* `@noy-db/in-vue`'s `useLiveQuery(live)`: it subscribes once,
|
|
12
|
+
* mirrors `value` into a `ShallowRef`, re-reads `error` on every
|
|
13
|
+
* notification, and disposes via `onScopeDispose`.
|
|
14
|
+
* `@noy-db/in-pinia`'s `store.liveQuery(build)` delegates to it, so
|
|
15
|
+
* there is one implementation rather than two that drift (#1131).
|
|
16
|
+
*
|
|
17
|
+
* There is NO wrapper for `in-react`, `in-solid` or `in-svelte` — a
|
|
18
|
+
* consumer on those subscribes directly (see **Error semantics**
|
|
19
|
+
* below, which is the part a hand-rolled wrapper usually gets
|
|
20
|
+
* wrong). Do not describe those adapters as existing until one does.
|
|
14
21
|
*
|
|
15
22
|
* **Error semantics.** A `.live()` query may throw at re-run time —
|
|
16
23
|
* a strict-mode `DanglingReferenceError` is the most common case
|
|
@@ -57,10 +64,25 @@
|
|
|
57
64
|
*/
|
|
58
65
|
export interface LiveQuery<T> {
|
|
59
66
|
/**
|
|
60
|
-
* Current snapshot of the query result.
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
67
|
+
* Current snapshot of the query result.
|
|
68
|
+
*
|
|
69
|
+
* **A FRESH ARRAY on every successful re-run** — `refresh()` assigns
|
|
70
|
+
* `this._value = this.recompute()`, and `recompute` is the query's own
|
|
71
|
+
* `toArray()`. So the reference CHANGES on each change, and reference
|
|
72
|
+
* identity is a valid change signal: a Vue `shallowRef`, a React
|
|
73
|
+
* `useState`, or any `Object.is` comparison detects an update without
|
|
74
|
+
* copying.
|
|
75
|
+
*
|
|
76
|
+
* The corollary is the part that bites: a consumer who reads `value`
|
|
77
|
+
* ONCE and holds the array gets a snapshot that never updates. Read it
|
|
78
|
+
* again after each notification — do not cache it.
|
|
79
|
+
*
|
|
80
|
+
* (An earlier version of this comment said the opposite — "updated in
|
|
81
|
+
* place… the reference returned is the same array" — and told callers to
|
|
82
|
+
* copy for change detection. Both halves were wrong, and the advice was
|
|
83
|
+
* backwards. Verified against `buildLiveQuery`: two reads across a
|
|
84
|
+
* notification are not `===`, and the first array still holds the old
|
|
85
|
+
* contents.)
|
|
64
86
|
*/
|
|
65
87
|
readonly value: readonly T[];
|
|
66
88
|
/**
|