@noy-db/hub 0.2.0-pre.18 → 0.2.0-pre.19
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/aggregate/index.cjs +227 -3
- package/dist/aggregate/index.cjs.map +1 -1
- package/dist/aggregate/index.d.cts +3 -3
- package/dist/aggregate/index.d.ts +3 -3
- package/dist/aggregate/index.js +5 -4
- package/dist/aggregate/index.js.map +1 -1
- package/dist/attestation/index.cjs.map +1 -1
- package/dist/attestation/index.d.cts +5 -5
- package/dist/attestation/index.d.ts +5 -5
- package/dist/attestation/index.js +6 -6
- package/dist/blobs/index.cjs +4 -10
- package/dist/blobs/index.cjs.map +1 -1
- package/dist/blobs/index.d.cts +6 -6
- package/dist/blobs/index.d.ts +6 -6
- package/dist/blobs/index.js +6 -6
- package/dist/bundle/index.cjs +520 -46
- package/dist/bundle/index.cjs.map +1 -1
- package/dist/bundle/index.d.cts +7 -7
- package/dist/bundle/index.d.ts +7 -7
- package/dist/bundle/index.js +10 -10
- package/dist/{chunk-6Q5XRLKG.js → chunk-3FSMVWBN.js} +4 -4
- package/dist/{chunk-647TFNYL.js → chunk-3Q2AOPLT.js} +76 -28
- package/dist/chunk-3Q2AOPLT.js.map +1 -0
- package/dist/{chunk-2U226RDC.js → chunk-4ULLGYPA.js} +3 -3
- package/dist/{chunk-6FHCU3QO.js → chunk-5IGWRMEC.js} +5 -5
- package/dist/{chunk-Y5XVB75E.js → chunk-6KESZO5D.js} +35 -7
- package/dist/chunk-6KESZO5D.js.map +1 -0
- package/dist/{chunk-KQ523X3A.js → chunk-6OSOE6BY.js} +2 -2
- package/dist/{chunk-HWK75CYX.js → chunk-7C6VFNIY.js} +2 -2
- package/dist/{chunk-33DAO2XG.js → chunk-7HD67R6U.js} +2 -2
- package/dist/{chunk-RQFG2YSV.js → chunk-B6E5IRPJ.js} +3 -3
- package/dist/{chunk-YWYW2YNO.js → chunk-CYNTFU2D.js} +2 -2
- package/dist/{chunk-HMFC6M2G.js → chunk-DJF3FXW5.js} +17 -1
- package/dist/{chunk-HMFC6M2G.js.map → chunk-DJF3FXW5.js.map} +1 -1
- package/dist/{chunk-KTZ2MHQK.js → chunk-DY3EOJEN.js} +2 -2
- package/dist/{chunk-PGVEL5IZ.js → chunk-E66DSTJP.js} +3 -3
- package/dist/{chunk-6YEC7LLO.js → chunk-FBLAWK6A.js} +2 -2
- package/dist/{chunk-LQ3GD5LL.js → chunk-FPHRTW2Z.js} +5 -5
- package/dist/{chunk-ZJ67TB4S.js → chunk-G4PYA575.js} +2 -2
- package/dist/{chunk-45643PAU.js → chunk-GKQAU52M.js} +4 -4
- package/dist/{chunk-5KKNBDCT.js → chunk-GYAWXHFO.js} +2 -2
- package/dist/{chunk-KOURQXIU.js → chunk-H42KZXNV.js} +5 -210
- package/dist/chunk-H42KZXNV.js.map +1 -0
- package/dist/{chunk-6XEGHIBA.js → chunk-IBVTH4JR.js} +4 -4
- package/dist/{chunk-AB7JF2KF.js → chunk-IVP5IVON.js} +2 -2
- package/dist/{chunk-T4T5I5L6.js → chunk-KEDJDWWQ.js} +3 -3
- package/dist/{chunk-C2OYWD5S.js → chunk-KNKNOJFS.js} +3 -3
- package/dist/chunk-KNKNOJFS.js.map +1 -0
- package/dist/{chunk-F2IJ2HGD.js → chunk-KYGGXXT6.js} +228 -69
- package/dist/chunk-KYGGXXT6.js.map +1 -0
- package/dist/{chunk-RZWQNMMP.js → chunk-LSIIPKYT.js} +2 -2
- package/dist/{chunk-FQRAYDS4.js → chunk-M3FPNTO2.js} +4 -4
- package/dist/{chunk-DR5I7Q6N.js → chunk-MI36HL5G.js} +4 -4
- package/dist/{chunk-Z3I2WNGF.js → chunk-NN6IISZO.js} +2 -2
- package/dist/{chunk-32XVU2LT.js → chunk-OBMYMKGO.js} +29 -6
- package/dist/{chunk-32XVU2LT.js.map → chunk-OBMYMKGO.js.map} +1 -1
- package/dist/{chunk-QJKZ5WUP.js → chunk-OKOKPYWH.js} +2 -2
- package/dist/{chunk-CMISAJAE.js → chunk-OY7RX2VL.js} +9 -15
- package/dist/chunk-OY7RX2VL.js.map +1 -0
- package/dist/{chunk-Z3BE5BRK.js → chunk-PTGQPWMV.js} +2 -2
- package/dist/{chunk-QPJ7Z4L3.js → chunk-PWFTQHYX.js} +2 -2
- package/dist/{chunk-K3NYRK7U.js → chunk-Q5MCHUXZ.js} +2 -2
- package/dist/{chunk-IQ4GMEYZ.js → chunk-S22UOMHM.js} +6 -6
- package/dist/{chunk-WZCG3EZ6.js → chunk-S3XA7G35.js} +2 -2
- package/dist/{chunk-LGPSCKWZ.js → chunk-SHIUFIPW.js} +1 -1
- package/dist/chunk-SHIUFIPW.js.map +1 -0
- package/dist/{chunk-BUBJYIZ7.js → chunk-U7JNBSS3.js} +3 -3
- package/dist/{chunk-TFAN3NFD.js → chunk-V3VIRTTE.js} +3 -3
- package/dist/{chunk-VVDSDOVV.js → chunk-V5FZWQNN.js} +4 -4
- package/dist/chunk-VEIVAYJ7.js +361 -0
- package/dist/chunk-VEIVAYJ7.js.map +1 -0
- package/dist/{chunk-P57D4KBG.js → chunk-VNUE6FHP.js} +3 -3
- package/dist/{chunk-TPOHMOGX.js → chunk-WFK2EVYU.js} +10 -2
- package/dist/chunk-WFK2EVYU.js.map +1 -0
- package/dist/{chunk-TTS3RWL5.js → chunk-X7FJMKT3.js} +2 -2
- package/dist/{chunk-HZOEBM67.js → chunk-XPH3FWME.js} +7 -2
- package/dist/{chunk-HZOEBM67.js.map → chunk-XPH3FWME.js.map} +1 -1
- package/dist/{chunk-DKMPR76W.js → chunk-Y5J63SMF.js} +5 -5
- package/dist/{chunk-HOO5I3VG.js → chunk-YLRRU72W.js} +2 -2
- package/dist/{chunk-MGB67HKX.js → chunk-YX333DPS.js} +4 -4
- package/dist/{chunk-4UI5T3K7.js → chunk-YZE6C3TQ.js} +3 -3
- package/dist/consent/index.cjs.map +1 -1
- package/dist/consent/index.d.cts +6 -6
- package/dist/consent/index.d.ts +6 -6
- package/dist/consent/index.js +3 -3
- package/dist/{crypto-FNK3XPCS.js → crypto-B46VNH6X.js} +3 -3
- package/dist/{delegation-FMXNUWE6.js → delegation-5HON72PV.js} +5 -5
- package/dist/derivations/index.cjs.map +1 -1
- package/dist/derivations/index.d.cts +7 -7
- package/dist/derivations/index.d.ts +7 -7
- package/dist/derivations/index.js +4 -4
- package/dist/{dev-unlock-3_2b_vo6.d.cts → dev-unlock-BR1rMOS-.d.cts} +1 -1
- package/dist/{dev-unlock-BMvwPr_E.d.ts → dev-unlock-whL49sxV.d.ts} +1 -1
- package/dist/{errors-DUTlAt3Y.d.ts → errors-DL-zTrrF.d.cts} +14 -1
- package/dist/{errors-DUTlAt3Y.d.cts → errors-DL-zTrrF.d.ts} +14 -1
- package/dist/executor-44R5CUS2.js +12 -0
- package/dist/executor-AOACUK7Z.js +8 -0
- package/dist/executor-OKFLQCDW.js +8 -0
- package/dist/{fanout-sidecar-JGHXAJO5.js → fanout-sidecar-DCQWJQ6S.js} +2 -2
- package/dist/forget/index.cjs.map +1 -1
- package/dist/forget/index.d.cts +1 -1
- package/dist/forget/index.d.ts +1 -1
- package/dist/forget/index.js +4 -4
- package/dist/guards/index.cjs.map +1 -1
- package/dist/guards/index.d.cts +7 -7
- package/dist/guards/index.d.ts +7 -7
- package/dist/guards/index.js +3 -3
- package/dist/{hash-BnWnL9bQ.d.cts → hash-BEUBmmI4.d.cts} +1 -1
- package/dist/{hash-BThBJFO1.d.ts → hash-Dtb7FwWd.d.ts} +1 -1
- package/dist/history/index.cjs.map +1 -1
- package/dist/history/index.d.cts +7 -7
- package/dist/history/index.d.ts +7 -7
- package/dist/history/index.js +5 -5
- package/dist/i18n/index.cjs +149 -132
- package/dist/i18n/index.cjs.map +1 -1
- package/dist/i18n/index.d.cts +6 -6
- package/dist/i18n/index.d.ts +6 -6
- package/dist/i18n/index.js +14 -14
- package/dist/{index-C6lgoUhK.d.cts → index-BM7O48Ur.d.cts} +47 -8
- package/dist/{index-C-SSRIxP.d.ts → index-BMmajblo.d.cts} +14 -0
- package/dist/{index-C-SSRIxP.d.cts → index-BMmajblo.d.ts} +14 -0
- package/dist/{index-DP1JTWHZ.d.ts → index-BelbyUwz.d.ts} +47 -8
- package/dist/index.cjs +799 -465
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -16
- package/dist/index.d.ts +29 -16
- package/dist/index.js +56 -52
- package/dist/index.js.map +1 -1
- package/dist/indexing/index.cjs.map +1 -1
- package/dist/indexing/index.js +4 -4
- package/dist/issue-EPA2PSWP.js +12 -0
- package/dist/{ledger-GXC2YA3A.js → ledger-LS6GXCBP.js} +5 -5
- package/dist/materialized-views/index.cjs +257 -4
- package/dist/materialized-views/index.cjs.map +1 -1
- package/dist/materialized-views/index.d.cts +7 -7
- package/dist/materialized-views/index.d.ts +7 -7
- package/dist/materialized-views/index.js +8 -7
- package/dist/noydb-BVKFP74P.js +38 -0
- package/dist/overlay-views/index.cjs.map +1 -1
- package/dist/overlay-views/index.d.cts +7 -7
- package/dist/overlay-views/index.d.ts +7 -7
- package/dist/overlay-views/index.js +4 -4
- package/dist/periods/index.cjs.map +1 -1
- package/dist/periods/index.d.cts +6 -6
- package/dist/periods/index.d.ts +6 -6
- package/dist/periods/index.js +5 -5
- package/dist/{public-envelope-HXOFHY4N.js → public-envelope-AGU6SS4Z.js} +4 -4
- package/dist/query/index.cjs +296 -27
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +3 -3
- package/dist/query/index.d.ts +3 -3
- package/dist/query/index.js +7 -6
- package/dist/registry-ERNAMRDE.js +8 -0
- package/dist/registry-EXTHSXQW.js +8 -0
- package/dist/{registry-WVXO6NH5.js → registry-RDPTFXQ7.js} +3 -3
- package/dist/{revoke-7LCWE2AH.js → revoke-IFLXEZA5.js} +6 -6
- package/dist/sealed-record/index.cjs.map +1 -1
- package/dist/sealed-record/index.d.cts +1 -1
- package/dist/sealed-record/index.d.ts +1 -1
- package/dist/sealed-record/index.js +2 -2
- package/dist/session/index.cjs.map +1 -1
- package/dist/session/index.d.cts +7 -7
- package/dist/session/index.d.ts +7 -7
- package/dist/session/index.js +3 -3
- package/dist/shadow/index.cjs.map +1 -1
- package/dist/shadow/index.d.cts +6 -6
- package/dist/shadow/index.d.ts +6 -6
- package/dist/shadow/index.js +2 -2
- package/dist/{signer-HAVDLGOK.js → signer-UNWOUJAK.js} +5 -5
- package/dist/snapshots/index.cjs.map +1 -1
- package/dist/snapshots/index.d.cts +6 -6
- package/dist/snapshots/index.d.ts +6 -6
- package/dist/snapshots/index.js +4 -4
- package/dist/{stale-PGTEGJDI.js → stale-NTEV5SLX.js} +2 -2
- package/dist/{state-vault-QKQKN3H3.js → state-vault-TUTFRTOA.js} +4 -4
- package/dist/store/index.cjs +8 -0
- package/dist/store/index.cjs.map +1 -1
- package/dist/store/index.d.cts +13 -6
- package/dist/store/index.d.ts +13 -6
- package/dist/store/index.js +2 -2
- package/dist/{strategy-Diwh5lzS.d.ts → strategy-BDxQnnTX.d.ts} +315 -4
- package/dist/{strategy-nuyN8K5N.d.cts → strategy-C5ol6NdV.d.cts} +315 -4
- package/dist/sync/index.cjs.map +1 -1
- package/dist/sync/index.d.cts +5 -5
- package/dist/sync/index.d.ts +5 -5
- package/dist/sync/index.js +4 -4
- package/dist/team/index.cjs.map +1 -1
- package/dist/team/index.d.cts +6 -6
- package/dist/team/index.d.ts +6 -6
- package/dist/team/index.js +8 -8
- package/dist/{transition-guard--t3exQHF.d.cts → transition-guard-B1N82hMf.d.cts} +1 -1
- package/dist/{transition-guard-BlI9Oy5K.d.ts → transition-guard-C__YeF3_.d.ts} +1 -1
- package/dist/tx/index.cjs.map +1 -1
- package/dist/tx/index.d.cts +6 -6
- package/dist/tx/index.d.ts +6 -6
- package/dist/tx/index.js +3 -3
- package/dist/{types-Diqc2caK.d.ts → types-CraiZOyO.d.ts} +134 -292
- package/dist/{types-BpLPqyaO.d.cts → types-D-gr5t0G.d.cts} +134 -292
- package/dist/{ulid-DNiRB4Mx.d.cts → ulid-DQnSAP5W.d.cts} +1 -1
- package/dist/{ulid-B1zNV8r9.d.ts → ulid-FFRRHkVf.d.ts} +1 -1
- package/dist/util/index.cjs.map +1 -1
- package/dist/util/index.js +1 -1
- package/dist/{vault-group-DPZVFRI5.js → vault-group-27EV7KB4.js} +29 -8
- package/dist/vault-group-27EV7KB4.js.map +1 -0
- package/dist/{with-materialized-view-BdH_A_r6.d.cts → with-materialized-view-BboqxyV3.d.cts} +1 -1
- package/dist/{with-materialized-view-CzAgp_HJ.d.ts → with-materialized-view-CguCeVcT.d.ts} +1 -1
- package/dist/{with-overlayed-view-BJbqQnsR.d.ts → with-overlayed-view-DO08u_tx.d.ts} +1 -1
- package/dist/{with-overlayed-view-C40rDPlu.d.cts → with-overlayed-view-mmsg5Of3.d.cts} +1 -1
- package/dist/{with-rollup-DrlGkxiE.d.ts → with-rollup-_TyBzz3T.d.ts} +1 -1
- package/dist/{with-rollup-Bopu5UDZ.d.cts → with-rollup-aaxOZcIb.d.cts} +1 -1
- package/package.json +3 -3
- package/dist/chunk-647TFNYL.js.map +0 -1
- package/dist/chunk-C2OYWD5S.js.map +0 -1
- package/dist/chunk-CMISAJAE.js.map +0 -1
- package/dist/chunk-F2IJ2HGD.js.map +0 -1
- package/dist/chunk-KOURQXIU.js.map +0 -1
- package/dist/chunk-LGPSCKWZ.js.map +0 -1
- package/dist/chunk-M3H7VSRV.js +0 -139
- package/dist/chunk-M3H7VSRV.js.map +0 -1
- package/dist/chunk-TPOHMOGX.js.map +0 -1
- package/dist/chunk-Y5XVB75E.js.map +0 -1
- package/dist/executor-IZ2NVXCY.js +0 -11
- package/dist/executor-THSEYEJG.js +0 -8
- package/dist/executor-WLFDUTOM.js +0 -8
- package/dist/issue-R2MWQO6K.js +0 -12
- package/dist/noydb-RJL6FQ4B.js +0 -37
- package/dist/registry-3T2RZC5A.js +0 -8
- package/dist/registry-DMS7OKBM.js +0 -8
- package/dist/vault-group-DPZVFRI5.js.map +0 -1
- /package/dist/{chunk-6Q5XRLKG.js.map → chunk-3FSMVWBN.js.map} +0 -0
- /package/dist/{chunk-2U226RDC.js.map → chunk-4ULLGYPA.js.map} +0 -0
- /package/dist/{chunk-6FHCU3QO.js.map → chunk-5IGWRMEC.js.map} +0 -0
- /package/dist/{chunk-KQ523X3A.js.map → chunk-6OSOE6BY.js.map} +0 -0
- /package/dist/{chunk-HWK75CYX.js.map → chunk-7C6VFNIY.js.map} +0 -0
- /package/dist/{chunk-33DAO2XG.js.map → chunk-7HD67R6U.js.map} +0 -0
- /package/dist/{chunk-RQFG2YSV.js.map → chunk-B6E5IRPJ.js.map} +0 -0
- /package/dist/{chunk-YWYW2YNO.js.map → chunk-CYNTFU2D.js.map} +0 -0
- /package/dist/{chunk-KTZ2MHQK.js.map → chunk-DY3EOJEN.js.map} +0 -0
- /package/dist/{chunk-PGVEL5IZ.js.map → chunk-E66DSTJP.js.map} +0 -0
- /package/dist/{chunk-6YEC7LLO.js.map → chunk-FBLAWK6A.js.map} +0 -0
- /package/dist/{chunk-LQ3GD5LL.js.map → chunk-FPHRTW2Z.js.map} +0 -0
- /package/dist/{chunk-ZJ67TB4S.js.map → chunk-G4PYA575.js.map} +0 -0
- /package/dist/{chunk-45643PAU.js.map → chunk-GKQAU52M.js.map} +0 -0
- /package/dist/{chunk-5KKNBDCT.js.map → chunk-GYAWXHFO.js.map} +0 -0
- /package/dist/{chunk-6XEGHIBA.js.map → chunk-IBVTH4JR.js.map} +0 -0
- /package/dist/{chunk-AB7JF2KF.js.map → chunk-IVP5IVON.js.map} +0 -0
- /package/dist/{chunk-T4T5I5L6.js.map → chunk-KEDJDWWQ.js.map} +0 -0
- /package/dist/{chunk-RZWQNMMP.js.map → chunk-LSIIPKYT.js.map} +0 -0
- /package/dist/{chunk-FQRAYDS4.js.map → chunk-M3FPNTO2.js.map} +0 -0
- /package/dist/{chunk-DR5I7Q6N.js.map → chunk-MI36HL5G.js.map} +0 -0
- /package/dist/{chunk-Z3I2WNGF.js.map → chunk-NN6IISZO.js.map} +0 -0
- /package/dist/{chunk-QJKZ5WUP.js.map → chunk-OKOKPYWH.js.map} +0 -0
- /package/dist/{chunk-Z3BE5BRK.js.map → chunk-PTGQPWMV.js.map} +0 -0
- /package/dist/{chunk-QPJ7Z4L3.js.map → chunk-PWFTQHYX.js.map} +0 -0
- /package/dist/{chunk-K3NYRK7U.js.map → chunk-Q5MCHUXZ.js.map} +0 -0
- /package/dist/{chunk-IQ4GMEYZ.js.map → chunk-S22UOMHM.js.map} +0 -0
- /package/dist/{chunk-WZCG3EZ6.js.map → chunk-S3XA7G35.js.map} +0 -0
- /package/dist/{chunk-BUBJYIZ7.js.map → chunk-U7JNBSS3.js.map} +0 -0
- /package/dist/{chunk-TFAN3NFD.js.map → chunk-V3VIRTTE.js.map} +0 -0
- /package/dist/{chunk-VVDSDOVV.js.map → chunk-V5FZWQNN.js.map} +0 -0
- /package/dist/{chunk-P57D4KBG.js.map → chunk-VNUE6FHP.js.map} +0 -0
- /package/dist/{chunk-TTS3RWL5.js.map → chunk-X7FJMKT3.js.map} +0 -0
- /package/dist/{chunk-DKMPR76W.js.map → chunk-Y5J63SMF.js.map} +0 -0
- /package/dist/{chunk-HOO5I3VG.js.map → chunk-YLRRU72W.js.map} +0 -0
- /package/dist/{chunk-MGB67HKX.js.map → chunk-YX333DPS.js.map} +0 -0
- /package/dist/{chunk-4UI5T3K7.js.map → chunk-YZE6C3TQ.js.map} +0 -0
- /package/dist/{crypto-FNK3XPCS.js.map → crypto-B46VNH6X.js.map} +0 -0
- /package/dist/{delegation-FMXNUWE6.js.map → delegation-5HON72PV.js.map} +0 -0
- /package/dist/{executor-IZ2NVXCY.js.map → executor-44R5CUS2.js.map} +0 -0
- /package/dist/{executor-THSEYEJG.js.map → executor-AOACUK7Z.js.map} +0 -0
- /package/dist/{executor-WLFDUTOM.js.map → executor-OKFLQCDW.js.map} +0 -0
- /package/dist/{fanout-sidecar-JGHXAJO5.js.map → fanout-sidecar-DCQWJQ6S.js.map} +0 -0
- /package/dist/{issue-R2MWQO6K.js.map → issue-EPA2PSWP.js.map} +0 -0
- /package/dist/{ledger-GXC2YA3A.js.map → ledger-LS6GXCBP.js.map} +0 -0
- /package/dist/{noydb-RJL6FQ4B.js.map → noydb-BVKFP74P.js.map} +0 -0
- /package/dist/{public-envelope-HXOFHY4N.js.map → public-envelope-AGU6SS4Z.js.map} +0 -0
- /package/dist/{registry-3T2RZC5A.js.map → registry-ERNAMRDE.js.map} +0 -0
- /package/dist/{registry-DMS7OKBM.js.map → registry-EXTHSXQW.js.map} +0 -0
- /package/dist/{registry-WVXO6NH5.js.map → registry-RDPTFXQ7.js.map} +0 -0
- /package/dist/{revoke-7LCWE2AH.js.map → revoke-IFLXEZA5.js.map} +0 -0
- /package/dist/{signer-HAVDLGOK.js.map → signer-UNWOUJAK.js.map} +0 -0
- /package/dist/{stale-PGTEGJDI.js.map → stale-NTEV5SLX.js.map} +0 -0
- /package/dist/{state-vault-QKQKN3H3.js.map → state-vault-TUTFRTOA.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -46,7 +46,7 @@ var init_types = __esm({
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
// src/errors.ts
|
|
49
|
-
var NoydbError, DecryptionError, TamperedError, InvalidKeyError, KeyringCorruptError, NoAccessError, ReadOnlyError, ReadOnlyAtInstantError, ReadOnlyFrameError, PermissionDeniedError, ExportCapabilityError, KeyringExpiredError, ImportCapabilityError, StoreCapabilityError, PrivilegeEscalationError, ReservedVaultNameError, PeriodClosedError, RecordLockedError, FieldFrozenError, IllegalTransitionError, InvariantError, AmendmentForbiddenError, DirectoryDisabledError, TierNotGrantedError, ElevationExpiredError, AlreadyElevatedError, TierDemoteDeniedError, DelegationTargetMissingError, ConflictError, LedgerContentionError, SequenceContentionError, SequenceOfflineError, NumberingUncertaintyError, BundleVersionConflictError, NetworkError, NotFoundError, ValidationError, SchemaValidationError, SchemaUpdateError, NonAdditiveSchemaChangeError, SchemaLockedError, SchemaFenceError, MigrationRequiredError, QuiesceTimeoutError, GroupCardinalityError, IndexRequiredError, UniqueConstraintError, UnsupportedIndexOptionError, IndexWriteFailureError, BundleIntegrityError, BundleSealMismatchError, ReservedCollectionNameError, DictKeyMissingError, DictKeyInUseError, MissingTranslationError, LocaleNotSpecifiedError, ScriptViolationError, StaticDictReadonlyError, UnknownDictCodeError, TranslatorNotConfiguredError, BackupLedgerError, BackupCorruptedError, AttestationError, SessionExpiredError, SessionNotFoundError, SessionPolicyError, JoinTooLargeError, CrossJoinTooLargeError, CrossJoinSourceUnknownError, DanglingReferenceError, FilenameSanitizationError, PathEscapeError, DerivationCycleError, DerivationDepthError, DerivationOutputUnknownError, DerivationOutputShapeError, DerivationCapExceededError, MaterializedViewCycleError, MaterializedViewSourceUnknownError, MaterializedViewTooLargeError, MaterializedViewConfigError, OverlayBaseIsVirtualError, OverlayCollectionUnavailableError, OverlayNameCollisionError, OverlayIdMismatchError, SnapshotNotFoundError, UnknownShardError, ShardProvisioningError, CrossShardJoinError, VaultTemplateNotFoundError, ForgetStrategyNotConfiguredError, SealedRecordExpiredError, SealedRecordMismatchError, RecordCekNotFoundError;
|
|
49
|
+
var NoydbError, DecryptionError, TamperedError, InvalidKeyError, KeyringCorruptError, NoAccessError, ReadOnlyError, ReadOnlyAtInstantError, ReadOnlyFrameError, PermissionDeniedError, ExportCapabilityError, KeyringExpiredError, ImportCapabilityError, StoreCapabilityError, PrivilegeEscalationError, ReservedVaultNameError, PeriodClosedError, RecordLockedError, FieldFrozenError, IllegalTransitionError, InvariantError, AmendmentForbiddenError, DirectoryDisabledError, TierNotGrantedError, ElevationExpiredError, AlreadyElevatedError, TierDemoteDeniedError, DelegationTargetMissingError, ConflictError, LedgerContentionError, SequenceContentionError, SequenceOfflineError, NumberingUncertaintyError, BundleVersionConflictError, NetworkError, NotFoundError, ValidationError, SchemaValidationError, SchemaUpdateError, NonAdditiveSchemaChangeError, SchemaLockedError, SchemaFenceError, MigrationRequiredError, QuiesceTimeoutError, GroupCardinalityError, IndexRequiredError, UniqueConstraintError, UnsupportedIndexOptionError, IndexWriteFailureError, BundleIntegrityError, BundleSealMismatchError, ReservedCollectionNameError, DictKeyMissingError, DictKeyInUseError, MissingTranslationError, LocaleNotSpecifiedError, ScriptViolationError, StaticDictReadonlyError, UnknownDictCodeError, TranslatorNotConfiguredError, BackupLedgerError, BackupCorruptedError, AttestationError, SessionExpiredError, SessionNotFoundError, SessionPolicyError, JoinTooLargeError, CrossJoinTooLargeError, CrossJoinSourceUnknownError, DanglingReferenceError, FilenameSanitizationError, PathEscapeError, DerivationCycleError, DerivationDepthError, DerivationOutputUnknownError, DerivationOutputShapeError, DerivationCapExceededError, MaterializedViewCycleError, MaterializedViewSourceUnknownError, MaterializedViewTooLargeError, MaterializedViewConfigError, OverlayBaseIsVirtualError, OverlayCollectionUnavailableError, OverlayNameCollisionError, OverlayIdMismatchError, SnapshotNotFoundError, UnknownShardError, ShardProvisioningError, DataResidencyError, CrossShardJoinError, VaultTemplateNotFoundError, ForgetStrategyNotConfiguredError, SealedRecordExpiredError, SealedRecordMismatchError, RecordCekNotFoundError;
|
|
50
50
|
var init_errors = __esm({
|
|
51
51
|
"src/errors.ts"() {
|
|
52
52
|
"use strict";
|
|
@@ -1035,6 +1035,21 @@ Resolutions:
|
|
|
1035
1035
|
this.vaultId = vaultId;
|
|
1036
1036
|
}
|
|
1037
1037
|
};
|
|
1038
|
+
DataResidencyError = class extends NoydbError {
|
|
1039
|
+
vaultId;
|
|
1040
|
+
requiredRegion;
|
|
1041
|
+
backendRegion;
|
|
1042
|
+
constructor(vaultId, requiredRegion, backendRegion) {
|
|
1043
|
+
super(
|
|
1044
|
+
"DATA_RESIDENCY",
|
|
1045
|
+
`Shard "${vaultId}" requires region "${requiredRegion}" but its placement backend declares region ${backendRegion === void 0 ? "(none)" : `"${backendRegion}"`}. Refusing to provision \u2014 route this shard to a region-correct backend via routeStore({ vaultRoutes }) (e.g. a region-encoded partition key) before retrying.`
|
|
1046
|
+
);
|
|
1047
|
+
this.name = "DataResidencyError";
|
|
1048
|
+
this.vaultId = vaultId;
|
|
1049
|
+
this.requiredRegion = requiredRegion;
|
|
1050
|
+
this.backendRegion = backendRegion;
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
1038
1053
|
CrossShardJoinError = class extends NoydbError {
|
|
1039
1054
|
constructor(message) {
|
|
1040
1055
|
super("CROSS_SHARD_JOIN", message);
|
|
@@ -2433,9 +2448,371 @@ __export(public_envelope_exports, {
|
|
|
2433
2448
|
var init_public_envelope = __esm({
|
|
2434
2449
|
"src/meta/public-envelope/index.ts"() {
|
|
2435
2450
|
"use strict";
|
|
2436
|
-
init_types2();
|
|
2437
|
-
init_schema();
|
|
2438
|
-
init_storage();
|
|
2451
|
+
init_types2();
|
|
2452
|
+
init_schema();
|
|
2453
|
+
init_storage();
|
|
2454
|
+
}
|
|
2455
|
+
});
|
|
2456
|
+
|
|
2457
|
+
// src/i18n/policy.ts
|
|
2458
|
+
function resolvePolicy(onMissing, layer) {
|
|
2459
|
+
const explicit = onMissing && typeof onMissing === "object" ? onMissing[layer] : void 0;
|
|
2460
|
+
const scalar = typeof onMissing === "string" ? onMissing : void 0;
|
|
2461
|
+
const layerDefault = layer === "guard" ? "substitute" : void 0;
|
|
2462
|
+
return explicit ?? layerDefault ?? scalar ?? "throw";
|
|
2463
|
+
}
|
|
2464
|
+
var init_policy = __esm({
|
|
2465
|
+
"src/i18n/policy.ts"() {
|
|
2466
|
+
"use strict";
|
|
2467
|
+
}
|
|
2468
|
+
});
|
|
2469
|
+
|
|
2470
|
+
// src/i18n/script.ts
|
|
2471
|
+
function inferScripts(locale) {
|
|
2472
|
+
const parts = locale.split("-");
|
|
2473
|
+
const subtag = parts.find((t) => /^[A-Z][a-z]{3}$/.test(t));
|
|
2474
|
+
if (subtag && SUBTAG_SCRIPTS[subtag]) return SUBTAG_SCRIPTS[subtag];
|
|
2475
|
+
const base = (parts[0] ?? "").toLowerCase();
|
|
2476
|
+
if (LATIN_BASE.has(base)) return ["Latin"];
|
|
2477
|
+
const primary = SCRIPT_TABLE[base];
|
|
2478
|
+
if (primary) return [...primary, "Latin"];
|
|
2479
|
+
return ["Latin"];
|
|
2480
|
+
}
|
|
2481
|
+
function allowedFor(descriptor, locale) {
|
|
2482
|
+
const script = descriptor.options.script;
|
|
2483
|
+
if (script && script !== "auto") {
|
|
2484
|
+
const explicit = script[locale];
|
|
2485
|
+
if (explicit) return explicit;
|
|
2486
|
+
}
|
|
2487
|
+
return inferScripts(locale);
|
|
2488
|
+
}
|
|
2489
|
+
function fullMatcher(scripts) {
|
|
2490
|
+
const cls = scripts.map((s) => `\\p{Script=${s}}`).join("");
|
|
2491
|
+
return new RegExp(`^[${BASELINE}${cls}]*$`, "u");
|
|
2492
|
+
}
|
|
2493
|
+
function charMatcher(scripts) {
|
|
2494
|
+
const cls = scripts.map((s) => `\\p{Script=${s}}`).join("");
|
|
2495
|
+
return new RegExp(`[${BASELINE}${cls}]`, "u");
|
|
2496
|
+
}
|
|
2497
|
+
function offendingSample(str, scripts) {
|
|
2498
|
+
const ok = charMatcher(scripts);
|
|
2499
|
+
const bad = [];
|
|
2500
|
+
for (const ch of str) {
|
|
2501
|
+
if (!ok.test(ch)) bad.push(ch);
|
|
2502
|
+
if (bad.length >= 8) break;
|
|
2503
|
+
}
|
|
2504
|
+
return bad.join("");
|
|
2505
|
+
}
|
|
2506
|
+
function stripDisallowed(str, scripts) {
|
|
2507
|
+
const ok = charMatcher(scripts);
|
|
2508
|
+
let out = "";
|
|
2509
|
+
for (const ch of str) if (ok.test(ch)) out += ch;
|
|
2510
|
+
return out;
|
|
2511
|
+
}
|
|
2512
|
+
function enforceScript(value, field, descriptor) {
|
|
2513
|
+
const opt = descriptor.options;
|
|
2514
|
+
if (!opt.script) return { value, warnings: [] };
|
|
2515
|
+
const mode = opt.onScriptViolation ?? "reject";
|
|
2516
|
+
const warnings = [];
|
|
2517
|
+
let out = value;
|
|
2518
|
+
for (const [locale, raw] of Object.entries(value)) {
|
|
2519
|
+
if (typeof raw !== "string") continue;
|
|
2520
|
+
const allowed = allowedFor(descriptor, locale);
|
|
2521
|
+
if (fullMatcher(allowed).test(raw)) continue;
|
|
2522
|
+
const sample = offendingSample(raw, allowed);
|
|
2523
|
+
if (mode === "reject") {
|
|
2524
|
+
throw new ScriptViolationError(field, locale, allowed, sample);
|
|
2525
|
+
}
|
|
2526
|
+
warnings.push({ field, locale, expected: allowed, sample });
|
|
2527
|
+
if (mode === "filter") {
|
|
2528
|
+
if (out === value) out = { ...value };
|
|
2529
|
+
out[locale] = stripDisallowed(raw, allowed);
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
return { value: out, warnings };
|
|
2533
|
+
}
|
|
2534
|
+
var LATIN_BASE, SCRIPT_TABLE, SUBTAG_SCRIPTS, BASELINE;
|
|
2535
|
+
var init_script = __esm({
|
|
2536
|
+
"src/i18n/script.ts"() {
|
|
2537
|
+
"use strict";
|
|
2538
|
+
init_errors();
|
|
2539
|
+
LATIN_BASE = /* @__PURE__ */ new Set([
|
|
2540
|
+
"en",
|
|
2541
|
+
"fr",
|
|
2542
|
+
"de",
|
|
2543
|
+
"es",
|
|
2544
|
+
"it",
|
|
2545
|
+
"pt",
|
|
2546
|
+
"nl",
|
|
2547
|
+
"sv",
|
|
2548
|
+
"no",
|
|
2549
|
+
"da",
|
|
2550
|
+
"fi",
|
|
2551
|
+
"is",
|
|
2552
|
+
"pl",
|
|
2553
|
+
"cs",
|
|
2554
|
+
"sk",
|
|
2555
|
+
"hu",
|
|
2556
|
+
"ro",
|
|
2557
|
+
"hr",
|
|
2558
|
+
"sl",
|
|
2559
|
+
"et",
|
|
2560
|
+
"lv",
|
|
2561
|
+
"lt",
|
|
2562
|
+
"tr",
|
|
2563
|
+
"vi",
|
|
2564
|
+
"id",
|
|
2565
|
+
"ms",
|
|
2566
|
+
"tl",
|
|
2567
|
+
"sw",
|
|
2568
|
+
"af",
|
|
2569
|
+
"ca",
|
|
2570
|
+
"gl",
|
|
2571
|
+
"eu",
|
|
2572
|
+
"cy",
|
|
2573
|
+
"ga"
|
|
2574
|
+
]);
|
|
2575
|
+
SCRIPT_TABLE = {
|
|
2576
|
+
th: ["Thai"],
|
|
2577
|
+
ko: ["Hangul", "Han"],
|
|
2578
|
+
ja: ["Han", "Hiragana", "Katakana"],
|
|
2579
|
+
zh: ["Han"],
|
|
2580
|
+
ar: ["Arabic"],
|
|
2581
|
+
fa: ["Arabic"],
|
|
2582
|
+
ur: ["Arabic"],
|
|
2583
|
+
ru: ["Cyrillic"],
|
|
2584
|
+
uk: ["Cyrillic"],
|
|
2585
|
+
bg: ["Cyrillic"],
|
|
2586
|
+
sr: ["Cyrillic"],
|
|
2587
|
+
he: ["Hebrew"],
|
|
2588
|
+
el: ["Greek"],
|
|
2589
|
+
hi: ["Devanagari"],
|
|
2590
|
+
ta: ["Tamil"],
|
|
2591
|
+
km: ["Khmer"],
|
|
2592
|
+
lo: ["Lao"],
|
|
2593
|
+
my: ["Myanmar"]
|
|
2594
|
+
};
|
|
2595
|
+
SUBTAG_SCRIPTS = {
|
|
2596
|
+
Latn: ["Latin"],
|
|
2597
|
+
Cyrl: ["Cyrillic", "Latin"],
|
|
2598
|
+
Hans: ["Han", "Latin"],
|
|
2599
|
+
Hant: ["Han", "Latin"],
|
|
2600
|
+
Thai: ["Thai", "Latin"],
|
|
2601
|
+
Arab: ["Arabic", "Latin"]
|
|
2602
|
+
};
|
|
2603
|
+
BASELINE = String.raw`\p{White_Space}\p{Script=Common}\p{Script=Inherited}\p{Mark}`;
|
|
2604
|
+
}
|
|
2605
|
+
});
|
|
2606
|
+
|
|
2607
|
+
// src/i18n/core.ts
|
|
2608
|
+
function i18nText(options) {
|
|
2609
|
+
return { _noydbI18nText: true, options };
|
|
2610
|
+
}
|
|
2611
|
+
function isI18nTextDescriptor(x) {
|
|
2612
|
+
return typeof x === "object" && x !== null && x._noydbI18nText === true;
|
|
2613
|
+
}
|
|
2614
|
+
function validateI18nTextValue(value, field, descriptor) {
|
|
2615
|
+
const { options } = descriptor;
|
|
2616
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2617
|
+
throw new MissingTranslationError(
|
|
2618
|
+
field,
|
|
2619
|
+
options.languages,
|
|
2620
|
+
`Field "${field}" must be a { [locale]: string } map, got ${typeof value}.`
|
|
2621
|
+
);
|
|
2622
|
+
}
|
|
2623
|
+
const map = value;
|
|
2624
|
+
for (const [locale, v] of Object.entries(map)) {
|
|
2625
|
+
if (typeof v !== "string") {
|
|
2626
|
+
throw new MissingTranslationError(
|
|
2627
|
+
field,
|
|
2628
|
+
[locale],
|
|
2629
|
+
`Field "${field}": locale "${locale}" must be a string, got ${typeof v}.`
|
|
2630
|
+
);
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
const { required } = options;
|
|
2634
|
+
if (required === "all") {
|
|
2635
|
+
const missing = options.languages.filter(
|
|
2636
|
+
(lang) => !(lang in map) || map[lang] === ""
|
|
2637
|
+
);
|
|
2638
|
+
if (missing.length > 0) {
|
|
2639
|
+
throw new MissingTranslationError(
|
|
2640
|
+
field,
|
|
2641
|
+
missing,
|
|
2642
|
+
`Field "${field}" requires all declared languages. Missing: ${missing.join(", ")}.`
|
|
2643
|
+
);
|
|
2644
|
+
}
|
|
2645
|
+
} else if (required === "any") {
|
|
2646
|
+
const present = options.languages.some(
|
|
2647
|
+
(lang) => lang in map && map[lang] !== ""
|
|
2648
|
+
);
|
|
2649
|
+
if (!present) {
|
|
2650
|
+
throw new MissingTranslationError(
|
|
2651
|
+
field,
|
|
2652
|
+
options.languages,
|
|
2653
|
+
`Field "${field}" requires at least one declared language. None present.`
|
|
2654
|
+
);
|
|
2655
|
+
}
|
|
2656
|
+
} else {
|
|
2657
|
+
const requiredList = required;
|
|
2658
|
+
const missing = requiredList.filter(
|
|
2659
|
+
(lang) => !(lang in map) || map[lang] === ""
|
|
2660
|
+
);
|
|
2661
|
+
if (missing.length > 0) {
|
|
2662
|
+
throw new MissingTranslationError(
|
|
2663
|
+
field,
|
|
2664
|
+
missing,
|
|
2665
|
+
`Field "${field}" requires: ${requiredList.join(", ")}. Missing: ${missing.join(", ")}.`
|
|
2666
|
+
);
|
|
2667
|
+
}
|
|
2668
|
+
}
|
|
2669
|
+
}
|
|
2670
|
+
function toChain(fallback) {
|
|
2671
|
+
return Array.isArray(fallback) ? fallback : fallback ? [fallback] : [];
|
|
2672
|
+
}
|
|
2673
|
+
function pickFromChain(value, chain) {
|
|
2674
|
+
for (const fb of chain) {
|
|
2675
|
+
if (fb === "any") {
|
|
2676
|
+
const any = Object.values(value).find((v) => v !== "");
|
|
2677
|
+
if (any !== void 0) return any;
|
|
2678
|
+
} else if (value[fb] !== void 0 && value[fb] !== "") {
|
|
2679
|
+
return value[fb];
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
return void 0;
|
|
2683
|
+
}
|
|
2684
|
+
function resolveI18nText(value, locale, fallback, field, opts) {
|
|
2685
|
+
if (locale === "raw") {
|
|
2686
|
+
return value;
|
|
2687
|
+
}
|
|
2688
|
+
if (!locale) {
|
|
2689
|
+
throw new LocaleNotSpecifiedError(field ?? "<unknown>");
|
|
2690
|
+
}
|
|
2691
|
+
if (value[locale] !== void 0 && value[locale] !== "") {
|
|
2692
|
+
return value[locale];
|
|
2693
|
+
}
|
|
2694
|
+
const policy = opts?.policy ?? "throw";
|
|
2695
|
+
const callerChain = toChain(fallback);
|
|
2696
|
+
const callerHit = pickFromChain(value, callerChain);
|
|
2697
|
+
if (callerHit !== void 0) return callerHit;
|
|
2698
|
+
if (policy === "substitute") {
|
|
2699
|
+
const subHit = pickFromChain(value, toChain(opts?.substitute));
|
|
2700
|
+
if (subHit !== void 0) return subHit;
|
|
2701
|
+
if (opts?.smartSubstitute) {
|
|
2702
|
+
const smartHit = pickNearestScript(value, locale);
|
|
2703
|
+
if (smartHit !== void 0) return smartHit;
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
if (policy === "throw") {
|
|
2707
|
+
throw new LocaleNotSpecifiedError(
|
|
2708
|
+
field ?? "<unknown>",
|
|
2709
|
+
`No translation available for locale "${locale}"` + (callerChain.length > 0 ? ` or fallback chain [${callerChain.join(", ")}]` : "") + "."
|
|
2710
|
+
);
|
|
2711
|
+
}
|
|
2712
|
+
return null;
|
|
2713
|
+
}
|
|
2714
|
+
function pickNearestScript(value, target) {
|
|
2715
|
+
const targetScript = inferScripts(target)[0] ?? "Latin";
|
|
2716
|
+
let best;
|
|
2717
|
+
for (const [loc, v] of Object.entries(value)) {
|
|
2718
|
+
if (typeof v !== "string" || v === "") continue;
|
|
2719
|
+
const s = inferScripts(loc)[0] ?? "Latin";
|
|
2720
|
+
const score = s === targetScript ? 0 : s === "Latin" ? 1 : 2;
|
|
2721
|
+
if (best === void 0 || score < best.score) best = { score, v };
|
|
2722
|
+
if (score === 0) break;
|
|
2723
|
+
}
|
|
2724
|
+
return best?.v;
|
|
2725
|
+
}
|
|
2726
|
+
function getAtPath(obj, path) {
|
|
2727
|
+
const arrayIdx = path.indexOf("[].");
|
|
2728
|
+
if (arrayIdx !== -1) {
|
|
2729
|
+
const arrayKey = path.slice(0, arrayIdx);
|
|
2730
|
+
const restPath = path.slice(arrayIdx + 3);
|
|
2731
|
+
const arr = obj[arrayKey];
|
|
2732
|
+
if (!Array.isArray(arr)) return [];
|
|
2733
|
+
return arr.flatMap((item) => {
|
|
2734
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return [];
|
|
2735
|
+
return getAtPath(item, restPath);
|
|
2736
|
+
});
|
|
2737
|
+
}
|
|
2738
|
+
const dotIdx = path.indexOf(".");
|
|
2739
|
+
if (dotIdx !== -1) {
|
|
2740
|
+
const head = path.slice(0, dotIdx);
|
|
2741
|
+
const rest = path.slice(dotIdx + 1);
|
|
2742
|
+
const nested = obj[head];
|
|
2743
|
+
if (!nested || typeof nested !== "object" || Array.isArray(nested)) return [];
|
|
2744
|
+
return getAtPath(nested, rest);
|
|
2745
|
+
}
|
|
2746
|
+
const val = obj[path];
|
|
2747
|
+
return val !== void 0 ? [val] : [];
|
|
2748
|
+
}
|
|
2749
|
+
function setAtPathInPlace(obj, path, value) {
|
|
2750
|
+
const dotIdx = path.indexOf(".");
|
|
2751
|
+
if (dotIdx !== -1) {
|
|
2752
|
+
const head = path.slice(0, dotIdx);
|
|
2753
|
+
const rest = path.slice(dotIdx + 1);
|
|
2754
|
+
const nested = obj[head];
|
|
2755
|
+
if (!nested || typeof nested !== "object" || Array.isArray(nested)) return;
|
|
2756
|
+
setAtPathInPlace(nested, rest, value);
|
|
2757
|
+
return;
|
|
2758
|
+
}
|
|
2759
|
+
obj[path] = value;
|
|
2760
|
+
}
|
|
2761
|
+
function applyAtPath(obj, path, locale, fallback, opts) {
|
|
2762
|
+
const arrayIdx = path.indexOf("[].");
|
|
2763
|
+
if (arrayIdx !== -1) {
|
|
2764
|
+
const arrayKey = path.slice(0, arrayIdx);
|
|
2765
|
+
const restPath = path.slice(arrayIdx + 3);
|
|
2766
|
+
const arr = obj[arrayKey];
|
|
2767
|
+
if (!Array.isArray(arr)) return obj;
|
|
2768
|
+
return {
|
|
2769
|
+
...obj,
|
|
2770
|
+
[arrayKey]: arr.map((item) => {
|
|
2771
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) return item;
|
|
2772
|
+
return applyAtPath(item, restPath, locale, fallback, opts);
|
|
2773
|
+
})
|
|
2774
|
+
};
|
|
2775
|
+
}
|
|
2776
|
+
const dotIdx = path.indexOf(".");
|
|
2777
|
+
if (dotIdx !== -1) {
|
|
2778
|
+
const head = path.slice(0, dotIdx);
|
|
2779
|
+
const rest = path.slice(dotIdx + 1);
|
|
2780
|
+
const nested = obj[head];
|
|
2781
|
+
if (!nested || typeof nested !== "object" || Array.isArray(nested)) return obj;
|
|
2782
|
+
return {
|
|
2783
|
+
...obj,
|
|
2784
|
+
[head]: applyAtPath(nested, rest, locale, fallback, opts)
|
|
2785
|
+
};
|
|
2786
|
+
}
|
|
2787
|
+
const raw = obj[path];
|
|
2788
|
+
if (raw === void 0 || raw === null) return obj;
|
|
2789
|
+
if (typeof raw !== "object" || Array.isArray(raw)) return obj;
|
|
2790
|
+
return {
|
|
2791
|
+
...obj,
|
|
2792
|
+
[path]: resolveI18nText(raw, locale, fallback, path, opts)
|
|
2793
|
+
};
|
|
2794
|
+
}
|
|
2795
|
+
function applyI18nLocale(record, i18nFields, locale, fallback, layer = "read") {
|
|
2796
|
+
const fieldNames = Object.keys(i18nFields);
|
|
2797
|
+
if (fieldNames.length === 0) return record;
|
|
2798
|
+
let result = record;
|
|
2799
|
+
for (const [field, descriptor] of Object.entries(i18nFields)) {
|
|
2800
|
+
const { onMissing, substitute, smartSubstitute } = descriptor.options;
|
|
2801
|
+
const opts = {
|
|
2802
|
+
policy: resolvePolicy(onMissing, layer),
|
|
2803
|
+
...substitute !== void 0 ? { substitute } : {},
|
|
2804
|
+
...smartSubstitute ? { smartSubstitute } : {}
|
|
2805
|
+
};
|
|
2806
|
+
result = applyAtPath(result, field, locale, fallback, opts);
|
|
2807
|
+
}
|
|
2808
|
+
return result;
|
|
2809
|
+
}
|
|
2810
|
+
var init_core = __esm({
|
|
2811
|
+
"src/i18n/core.ts"() {
|
|
2812
|
+
"use strict";
|
|
2813
|
+
init_errors();
|
|
2814
|
+
init_policy();
|
|
2815
|
+
init_script();
|
|
2439
2816
|
}
|
|
2440
2817
|
});
|
|
2441
2818
|
|
|
@@ -3418,6 +3795,7 @@ var init_groupby = __esm({
|
|
|
3418
3795
|
init_canonical_key();
|
|
3419
3796
|
init_errors();
|
|
3420
3797
|
init_money_reducer();
|
|
3798
|
+
init_core();
|
|
3421
3799
|
GROUPBY_WARN_CARDINALITY = 1e4;
|
|
3422
3800
|
GROUPBY_MAX_CARDINALITY = 1e5;
|
|
3423
3801
|
warnedCardinalityFields = /* @__PURE__ */ new Set();
|
|
@@ -3486,9 +3864,29 @@ var init_groupby = __esm({
|
|
|
3486
3864
|
upstreams;
|
|
3487
3865
|
dictLabelResolver;
|
|
3488
3866
|
fields;
|
|
3489
|
-
/**
|
|
3490
|
-
|
|
3491
|
-
|
|
3867
|
+
/**
|
|
3868
|
+
* Execute the query, group, reduce, and return an array of rows.
|
|
3869
|
+
*
|
|
3870
|
+
* `opts` (#285 query-form MV grouping): when a `locale` + `i18nFields` are
|
|
3871
|
+
* given, the declared group-key `i18nText` fields are resolved to that locale
|
|
3872
|
+
* at the `mv` layer BEFORE bucketing — so an i18n group key is a stable string
|
|
3873
|
+
* instead of a raw `{locale}` map. The MV executor passes the MV's
|
|
3874
|
+
* `i18nLocale`/`i18nFields`; ordinary `.run()` callers pass nothing and are
|
|
3875
|
+
* unaffected.
|
|
3876
|
+
*/
|
|
3877
|
+
run(opts) {
|
|
3878
|
+
let records = this.executeRecords();
|
|
3879
|
+
if (opts?.locale !== void 0 && opts.i18nFields !== void 0) {
|
|
3880
|
+
const groupI18n = {};
|
|
3881
|
+
for (const f of this.fields) {
|
|
3882
|
+
const d = opts.i18nFields[f];
|
|
3883
|
+
if (d !== void 0) groupI18n[f] = d;
|
|
3884
|
+
}
|
|
3885
|
+
if (Object.keys(groupI18n).length > 0) {
|
|
3886
|
+
records = records.map((r) => applyI18nLocale(r, groupI18n, opts.locale, void 0, "mv"));
|
|
3887
|
+
}
|
|
3888
|
+
}
|
|
3889
|
+
return groupAndReduce(records, this.fields, this.spec);
|
|
3492
3890
|
}
|
|
3493
3891
|
/**
|
|
3494
3892
|
* Execute the query, group, reduce, and resolve `<field>Label` for
|
|
@@ -4073,12 +4471,13 @@ var executor_exports3 = {};
|
|
|
4073
4471
|
__export(executor_exports3, {
|
|
4074
4472
|
MaterializedViewExecutor: () => MaterializedViewExecutor
|
|
4075
4473
|
});
|
|
4076
|
-
async function materializeQueryResult(q, mvName) {
|
|
4474
|
+
async function materializeQueryResult(q, mvName, i18nLocale, i18nFields) {
|
|
4077
4475
|
if (typeof q?.toArray === "function") {
|
|
4078
4476
|
return await q.toArray();
|
|
4079
4477
|
}
|
|
4080
4478
|
if (typeof q?.run === "function") {
|
|
4081
|
-
const
|
|
4479
|
+
const runOpts = i18nLocale !== void 0 ? { locale: i18nLocale, i18nFields } : void 0;
|
|
4480
|
+
const result = await Promise.resolve(q.run(runOpts));
|
|
4082
4481
|
if (Array.isArray(result)) {
|
|
4083
4482
|
return result;
|
|
4084
4483
|
}
|
|
@@ -4107,6 +4506,29 @@ async function materializeUnionResult(spec, db) {
|
|
|
4107
4506
|
}
|
|
4108
4507
|
if (!spec.groupBy) return unified;
|
|
4109
4508
|
const groupFields = typeof spec.groupBy === "string" ? [spec.groupBy] : spec.groupBy;
|
|
4509
|
+
if (spec.i18nLocale !== void 0 && spec.i18nFields !== void 0) {
|
|
4510
|
+
const groupI18n = {};
|
|
4511
|
+
for (const f of groupFields) {
|
|
4512
|
+
const d = spec.i18nFields[f];
|
|
4513
|
+
if (d !== void 0) groupI18n[f] = d;
|
|
4514
|
+
}
|
|
4515
|
+
if (Object.keys(groupI18n).length > 0) {
|
|
4516
|
+
for (let i = 0; i < unified.length; i++) {
|
|
4517
|
+
unified[i] = applyI18nLocale(unified[i], groupI18n, spec.i18nLocale, void 0, "mv");
|
|
4518
|
+
}
|
|
4519
|
+
}
|
|
4520
|
+
}
|
|
4521
|
+
for (const f of groupFields) {
|
|
4522
|
+
for (const row of unified) {
|
|
4523
|
+
const v = row[f];
|
|
4524
|
+
if (v !== null && typeof v === "object") {
|
|
4525
|
+
throw new LocaleNotSpecifiedError(
|
|
4526
|
+
f,
|
|
4527
|
+
`Materialized view "${spec.name}" groups by "${f}", whose value is a raw i18n locale map \u2014 an unstable object group key. Declare { i18nLocale, i18nFields } on the MV to resolve it at the 'mv' layer, or group by a dictKey/staticDict code (the stable key) and resolve the label at read time.`
|
|
4528
|
+
);
|
|
4529
|
+
}
|
|
4530
|
+
}
|
|
4531
|
+
}
|
|
4110
4532
|
if (!spec.aggregate) {
|
|
4111
4533
|
const seen = /* @__PURE__ */ new Map();
|
|
4112
4534
|
for (const row of unified) {
|
|
@@ -4138,6 +4560,7 @@ var init_executor3 = __esm({
|
|
|
4138
4560
|
init_registry();
|
|
4139
4561
|
init_groupby();
|
|
4140
4562
|
init_canonical_key();
|
|
4563
|
+
init_core();
|
|
4141
4564
|
DEFAULT_MAX_ROWS = 1e5;
|
|
4142
4565
|
MaterializedViewExecutor = {
|
|
4143
4566
|
async refresh(reg, accessor) {
|
|
@@ -4153,7 +4576,7 @@ var init_executor3 = __esm({
|
|
|
4153
4576
|
rows = await materializeUnionResult(spec, ctxForQuery);
|
|
4154
4577
|
} else {
|
|
4155
4578
|
const q = spec.query(ctxForQuery);
|
|
4156
|
-
rows = await materializeQueryResult(q, spec.name);
|
|
4579
|
+
rows = await materializeQueryResult(q, spec.name, spec.i18nLocale, spec.i18nFields);
|
|
4157
4580
|
}
|
|
4158
4581
|
if (rows.length > maxRows) {
|
|
4159
4582
|
throw new MaterializedViewTooLargeError(spec.name, rows.length, maxRows);
|
|
@@ -5506,13 +5929,21 @@ var init_vault_group = __esm({
|
|
|
5506
5929
|
* - row + vault present → no-op, return handle
|
|
5507
5930
|
* - row present, vault gone → ShardProvisioningError
|
|
5508
5931
|
* - row absent (vault present or not) → open-or-create, configure, write row
|
|
5932
|
+
*
|
|
5933
|
+
* When `region` is given (the routing `put` passes `sharding.regionOf(record)`),
|
|
5934
|
+
* the candidate backend's `capabilities.region` must match or this throws
|
|
5935
|
+
* `DataResidencyError` BEFORE provisioning (#271 data-residency guard).
|
|
5509
5936
|
*/
|
|
5510
|
-
async createShard(partitionKey) {
|
|
5937
|
+
async createShard(partitionKey, region) {
|
|
5511
5938
|
const vaultId = this.shardVaultId(partitionKey);
|
|
5512
5939
|
const row = await this.registry.get(this.registryId(partitionKey));
|
|
5513
5940
|
const provisioned = await this.db._shardVaultProvisioned(vaultId);
|
|
5514
5941
|
if (row && !provisioned) throw new ShardProvisioningError(vaultId, partitionKey);
|
|
5515
5942
|
if (row && provisioned) return this.openShard(partitionKey);
|
|
5943
|
+
if (region !== void 0) {
|
|
5944
|
+
const backendRegion = this.db._resolveBackend(vaultId).capabilities?.region;
|
|
5945
|
+
if (backendRegion !== region) throw new DataResidencyError(vaultId, region, backendRegion);
|
|
5946
|
+
}
|
|
5516
5947
|
const vault = await this.db.openVault(vaultId);
|
|
5517
5948
|
this.template.configure(vault);
|
|
5518
5949
|
await this.registry.put(this.registryId(partitionKey), {
|
|
@@ -5594,8 +6025,19 @@ var init_vault_group = __esm({
|
|
|
5594
6025
|
*
|
|
5595
6026
|
* v1 is explicit-refresh (no write-path push); call `refreshInsights()`
|
|
5596
6027
|
* after a batch of writes, or on a schedule.
|
|
6028
|
+
*
|
|
6029
|
+
* The `target.vault` must NOT be the group itself or one of its shards —
|
|
6030
|
+
* a summary writing back into client-shard data would breach the Insight
|
|
6031
|
+
* Vault's separate-DEK-boundary contract. Such a target throws a
|
|
6032
|
+
* `ValidationError` at registration (#271 Insight-write isolation).
|
|
5597
6033
|
*/
|
|
5598
6034
|
withCrossVaultDerivation(spec) {
|
|
6035
|
+
const target = spec.target.vault;
|
|
6036
|
+
if (target === this.name || target.startsWith(`${this.name}${SHARD_SEPARATOR}`)) {
|
|
6037
|
+
throw new ValidationError(
|
|
6038
|
+
`withCrossVaultDerivation: target.vault "${target}" is the "${this.name}" group itself or one of its shards \u2014 an Insight summary must target a SEPARATE analytics vault, never write back into client-shard data (it would breach the per-shard DEK boundary). Use a distinct vault name.`
|
|
6039
|
+
);
|
|
6040
|
+
}
|
|
5599
6041
|
this.crossVaultDerivations.push(spec);
|
|
5600
6042
|
}
|
|
5601
6043
|
/**
|
|
@@ -5744,7 +6186,7 @@ var init_vault_group = __esm({
|
|
|
5744
6186
|
if (this.group.sharding.autoCreate === false) {
|
|
5745
6187
|
throw new UnknownShardError(key, this.group.name);
|
|
5746
6188
|
}
|
|
5747
|
-
vault = await this.group.createShard(key);
|
|
6189
|
+
vault = await this.group.createShard(key, this.group.sharding.regionOf?.(record));
|
|
5748
6190
|
} else {
|
|
5749
6191
|
vault = await this.group.openShard(key);
|
|
5750
6192
|
}
|
|
@@ -5971,6 +6413,7 @@ __export(src_exports, {
|
|
|
5971
6413
|
DICT_COLLECTION_PREFIX: () => DICT_COLLECTION_PREFIX,
|
|
5972
6414
|
DIRECTORY_RECORD_ID: () => DIRECTORY_RECORD_ID,
|
|
5973
6415
|
DanglingReferenceError: () => DanglingReferenceError,
|
|
6416
|
+
DataResidencyError: () => DataResidencyError,
|
|
5974
6417
|
DecryptionError: () => DecryptionError,
|
|
5975
6418
|
DelegationTargetMissingError: () => DelegationTargetMissingError,
|
|
5976
6419
|
DerivationCapExceededError: () => DerivationCapExceededError,
|
|
@@ -6293,6 +6736,7 @@ __export(src_exports, {
|
|
|
6293
6736
|
sha256Hex: () => sha256Hex3,
|
|
6294
6737
|
staticDict: () => staticDict,
|
|
6295
6738
|
sum: () => sum,
|
|
6739
|
+
tokenize: () => tokenize,
|
|
6296
6740
|
transitionGuard: () => transitionGuard,
|
|
6297
6741
|
unwrapDeksFromBlob: () => unwrapDeksFromBlob,
|
|
6298
6742
|
unwrapDeksFromPaperEntry: () => unwrapDeksFromPaperEntry,
|
|
@@ -6691,11 +7135,8 @@ async function compressBytes(data) {
|
|
|
6691
7135
|
if (typeof CompressionStream === "undefined") {
|
|
6692
7136
|
return { bytes: data, algorithm: "none" };
|
|
6693
7137
|
}
|
|
6694
|
-
const
|
|
6695
|
-
const
|
|
6696
|
-
await writer.write(data);
|
|
6697
|
-
await writer.close();
|
|
6698
|
-
const buf = await new Response(cs.readable).arrayBuffer();
|
|
7138
|
+
const piped = new Response(data).body.pipeThrough(new CompressionStream("gzip"));
|
|
7139
|
+
const buf = await new Response(piped).arrayBuffer();
|
|
6699
7140
|
return { bytes: new Uint8Array(buf), algorithm: "gzip" };
|
|
6700
7141
|
}
|
|
6701
7142
|
async function decompressBytes(data) {
|
|
@@ -6704,11 +7145,8 @@ async function decompressBytes(data) {
|
|
|
6704
7145
|
"[noy-db] DecompressionStream not available \u2014 cannot decompress blob chunk"
|
|
6705
7146
|
);
|
|
6706
7147
|
}
|
|
6707
|
-
const
|
|
6708
|
-
const
|
|
6709
|
-
await writer.write(data);
|
|
6710
|
-
await writer.close();
|
|
6711
|
-
const buf = await new Response(ds.readable).arrayBuffer();
|
|
7148
|
+
const piped = new Response(data).body.pipeThrough(new DecompressionStream("gzip"));
|
|
7149
|
+
const buf = await new Response(piped).arrayBuffer();
|
|
6712
7150
|
return new Uint8Array(buf);
|
|
6713
7151
|
}
|
|
6714
7152
|
function concatChunks(chunks) {
|
|
@@ -8240,6 +8678,14 @@ function routeStore(opts) {
|
|
|
8240
8678
|
const q = {};
|
|
8241
8679
|
for (const [k, v] of writeQueues) q[k] = v.writes.length;
|
|
8242
8680
|
return { overrides: ov, suspended: [...suspended], queued: q };
|
|
8681
|
+
},
|
|
8682
|
+
resolveBackend(vaultId) {
|
|
8683
|
+
if (opts.vaultRoutes) {
|
|
8684
|
+
for (const [prefix, s] of Object.entries(opts.vaultRoutes)) {
|
|
8685
|
+
if (vaultId.startsWith(prefix)) return s;
|
|
8686
|
+
}
|
|
8687
|
+
}
|
|
8688
|
+
return primary;
|
|
8243
8689
|
}
|
|
8244
8690
|
};
|
|
8245
8691
|
if (anyHas("listVaults")) {
|
|
@@ -12406,286 +12852,91 @@ async function recoverUser(store, vault, callerKeyring, options) {
|
|
|
12406
12852
|
const target = JSON.parse(env._data);
|
|
12407
12853
|
const targetRole = options.role ?? target.role;
|
|
12408
12854
|
if (!canRecover(callerKeyring.role, targetRole)) {
|
|
12409
|
-
throw new PermissionDeniedError(
|
|
12410
|
-
`Role "${callerKeyring.role}" cannot recover role "${targetRole}"`
|
|
12411
|
-
);
|
|
12412
|
-
}
|
|
12413
|
-
if (!canRecover(callerKeyring.role, target.role)) {
|
|
12414
|
-
throw new PermissionDeniedError(
|
|
12415
|
-
`Role "${callerKeyring.role}" cannot recover role "${target.role}"`
|
|
12416
|
-
);
|
|
12417
|
-
}
|
|
12418
|
-
for (const coll of Object.keys(target.deks)) {
|
|
12419
|
-
if (!callerKeyring.deks.has(coll)) {
|
|
12420
|
-
throw new PrivilegeEscalationError(coll);
|
|
12421
|
-
}
|
|
12422
|
-
}
|
|
12423
|
-
if (options.validatePassphrase && !options.allowWeakPassphrase) {
|
|
12424
|
-
assertStrongPassphrase(options.passphrase, options.passphrasePolicy);
|
|
12425
|
-
}
|
|
12426
|
-
const newSalt = generateSalt();
|
|
12427
|
-
const newKek = await deriveKey(options.passphrase, newSalt);
|
|
12428
|
-
const wrappedDeks = {};
|
|
12429
|
-
for (const coll of Object.keys(target.deks)) {
|
|
12430
|
-
const callerDek = callerKeyring.deks.get(coll);
|
|
12431
|
-
if (!callerDek) {
|
|
12432
|
-
throw new PrivilegeEscalationError(coll);
|
|
12433
|
-
}
|
|
12434
|
-
wrappedDeks[coll] = await wrapKey(callerDek, newKek);
|
|
12435
|
-
}
|
|
12436
|
-
const canary = await mintKeyringCanary(newKek);
|
|
12437
|
-
const next = {
|
|
12438
|
-
...target,
|
|
12439
|
-
_noydb_keyring: NOYDB_KEYRING_VERSION,
|
|
12440
|
-
role: targetRole,
|
|
12441
|
-
display_name: options.displayName ?? target.display_name,
|
|
12442
|
-
deks: wrappedDeks,
|
|
12443
|
-
salt: bufferToBase64(newSalt),
|
|
12444
|
-
granted_by: callerKeyring.userId,
|
|
12445
|
-
authenticators: [],
|
|
12446
|
-
canary
|
|
12447
|
-
};
|
|
12448
|
-
const envelope = {
|
|
12449
|
-
_noydb: 1,
|
|
12450
|
-
_v: 1,
|
|
12451
|
-
_ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12452
|
-
_iv: "",
|
|
12453
|
-
_data: JSON.stringify(next)
|
|
12454
|
-
};
|
|
12455
|
-
await store.put(vault, "_keyring", options.userId, envelope);
|
|
12456
|
-
}
|
|
12457
|
-
|
|
12458
|
-
// src/index.ts
|
|
12459
|
-
init_errors();
|
|
12460
|
-
|
|
12461
|
-
// src/noydb.ts
|
|
12462
|
-
init_errors();
|
|
12463
|
-
init_constants();
|
|
12464
|
-
init_ulid();
|
|
12465
|
-
init_public_envelope();
|
|
12466
|
-
|
|
12467
|
-
// src/vault.ts
|
|
12468
|
-
init_types();
|
|
12469
|
-
|
|
12470
|
-
// src/collection.ts
|
|
12471
|
-
init_types();
|
|
12472
|
-
|
|
12473
|
-
// src/crdt/strategy.ts
|
|
12474
|
-
var NOT_ENABLED = new Error(
|
|
12475
|
-
'CRDT mode requires the CRDT strategy. Import `{ withCrdt }` from "@noy-db/hub/crdt" and pass it to `createNoydb({ crdtStrategy: withCrdt() })`.'
|
|
12476
|
-
);
|
|
12477
|
-
var NO_CRDT = {
|
|
12478
|
-
buildLwwMapState() {
|
|
12479
|
-
throw NOT_ENABLED;
|
|
12480
|
-
},
|
|
12481
|
-
buildRgaState() {
|
|
12482
|
-
throw NOT_ENABLED;
|
|
12483
|
-
},
|
|
12484
|
-
mergeCrdtStates() {
|
|
12485
|
-
throw NOT_ENABLED;
|
|
12486
|
-
},
|
|
12487
|
-
resolveCrdtSnapshot() {
|
|
12488
|
-
throw NOT_ENABLED;
|
|
12489
|
-
}
|
|
12490
|
-
};
|
|
12491
|
-
|
|
12492
|
-
// src/i18n/core.ts
|
|
12493
|
-
init_errors();
|
|
12494
|
-
|
|
12495
|
-
// src/i18n/policy.ts
|
|
12496
|
-
function resolvePolicy(onMissing, layer) {
|
|
12497
|
-
const explicit = onMissing && typeof onMissing === "object" ? onMissing[layer] : void 0;
|
|
12498
|
-
const scalar = typeof onMissing === "string" ? onMissing : void 0;
|
|
12499
|
-
const layerDefault = layer === "guard" ? "substitute" : void 0;
|
|
12500
|
-
return explicit ?? layerDefault ?? scalar ?? "throw";
|
|
12501
|
-
}
|
|
12502
|
-
|
|
12503
|
-
// src/i18n/core.ts
|
|
12504
|
-
function i18nText(options) {
|
|
12505
|
-
return { _noydbI18nText: true, options };
|
|
12506
|
-
}
|
|
12507
|
-
function isI18nTextDescriptor(x) {
|
|
12508
|
-
return typeof x === "object" && x !== null && x._noydbI18nText === true;
|
|
12509
|
-
}
|
|
12510
|
-
function validateI18nTextValue(value, field, descriptor) {
|
|
12511
|
-
const { options } = descriptor;
|
|
12512
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
12513
|
-
throw new MissingTranslationError(
|
|
12514
|
-
field,
|
|
12515
|
-
options.languages,
|
|
12516
|
-
`Field "${field}" must be a { [locale]: string } map, got ${typeof value}.`
|
|
12517
|
-
);
|
|
12518
|
-
}
|
|
12519
|
-
const map = value;
|
|
12520
|
-
for (const [locale, v] of Object.entries(map)) {
|
|
12521
|
-
if (typeof v !== "string") {
|
|
12522
|
-
throw new MissingTranslationError(
|
|
12523
|
-
field,
|
|
12524
|
-
[locale],
|
|
12525
|
-
`Field "${field}": locale "${locale}" must be a string, got ${typeof v}.`
|
|
12526
|
-
);
|
|
12527
|
-
}
|
|
12528
|
-
}
|
|
12529
|
-
const { required } = options;
|
|
12530
|
-
if (required === "all") {
|
|
12531
|
-
const missing = options.languages.filter(
|
|
12532
|
-
(lang) => !(lang in map) || map[lang] === ""
|
|
12533
|
-
);
|
|
12534
|
-
if (missing.length > 0) {
|
|
12535
|
-
throw new MissingTranslationError(
|
|
12536
|
-
field,
|
|
12537
|
-
missing,
|
|
12538
|
-
`Field "${field}" requires all declared languages. Missing: ${missing.join(", ")}.`
|
|
12539
|
-
);
|
|
12540
|
-
}
|
|
12541
|
-
} else if (required === "any") {
|
|
12542
|
-
const present = options.languages.some(
|
|
12543
|
-
(lang) => lang in map && map[lang] !== ""
|
|
12544
|
-
);
|
|
12545
|
-
if (!present) {
|
|
12546
|
-
throw new MissingTranslationError(
|
|
12547
|
-
field,
|
|
12548
|
-
options.languages,
|
|
12549
|
-
`Field "${field}" requires at least one declared language. None present.`
|
|
12550
|
-
);
|
|
12551
|
-
}
|
|
12552
|
-
} else {
|
|
12553
|
-
const requiredList = required;
|
|
12554
|
-
const missing = requiredList.filter(
|
|
12555
|
-
(lang) => !(lang in map) || map[lang] === ""
|
|
12556
|
-
);
|
|
12557
|
-
if (missing.length > 0) {
|
|
12558
|
-
throw new MissingTranslationError(
|
|
12559
|
-
field,
|
|
12560
|
-
missing,
|
|
12561
|
-
`Field "${field}" requires: ${requiredList.join(", ")}. Missing: ${missing.join(", ")}.`
|
|
12562
|
-
);
|
|
12563
|
-
}
|
|
12564
|
-
}
|
|
12565
|
-
}
|
|
12566
|
-
function toChain(fallback) {
|
|
12567
|
-
return Array.isArray(fallback) ? fallback : fallback ? [fallback] : [];
|
|
12568
|
-
}
|
|
12569
|
-
function pickFromChain(value, chain) {
|
|
12570
|
-
for (const fb of chain) {
|
|
12571
|
-
if (fb === "any") {
|
|
12572
|
-
const any = Object.values(value).find((v) => v !== "");
|
|
12573
|
-
if (any !== void 0) return any;
|
|
12574
|
-
} else if (value[fb] !== void 0 && value[fb] !== "") {
|
|
12575
|
-
return value[fb];
|
|
12576
|
-
}
|
|
12577
|
-
}
|
|
12578
|
-
return void 0;
|
|
12579
|
-
}
|
|
12580
|
-
function resolveI18nText(value, locale, fallback, field, opts) {
|
|
12581
|
-
if (locale === "raw") {
|
|
12582
|
-
return value;
|
|
12583
|
-
}
|
|
12584
|
-
if (!locale) {
|
|
12585
|
-
throw new LocaleNotSpecifiedError(field ?? "<unknown>");
|
|
12586
|
-
}
|
|
12587
|
-
if (value[locale] !== void 0 && value[locale] !== "") {
|
|
12588
|
-
return value[locale];
|
|
12589
|
-
}
|
|
12590
|
-
const policy = opts?.policy ?? "throw";
|
|
12591
|
-
const callerChain = toChain(fallback);
|
|
12592
|
-
const callerHit = pickFromChain(value, callerChain);
|
|
12593
|
-
if (callerHit !== void 0) return callerHit;
|
|
12594
|
-
if (policy === "substitute") {
|
|
12595
|
-
const subHit = pickFromChain(value, toChain(opts?.substitute));
|
|
12596
|
-
if (subHit !== void 0) return subHit;
|
|
12597
|
-
}
|
|
12598
|
-
if (policy === "throw") {
|
|
12599
|
-
throw new LocaleNotSpecifiedError(
|
|
12600
|
-
field ?? "<unknown>",
|
|
12601
|
-
`No translation available for locale "${locale}"` + (callerChain.length > 0 ? ` or fallback chain [${callerChain.join(", ")}]` : "") + "."
|
|
12602
|
-
);
|
|
12603
|
-
}
|
|
12604
|
-
return null;
|
|
12605
|
-
}
|
|
12606
|
-
function getAtPath(obj, path) {
|
|
12607
|
-
const arrayIdx = path.indexOf("[].");
|
|
12608
|
-
if (arrayIdx !== -1) {
|
|
12609
|
-
const arrayKey = path.slice(0, arrayIdx);
|
|
12610
|
-
const restPath = path.slice(arrayIdx + 3);
|
|
12611
|
-
const arr = obj[arrayKey];
|
|
12612
|
-
if (!Array.isArray(arr)) return [];
|
|
12613
|
-
return arr.flatMap((item) => {
|
|
12614
|
-
if (!item || typeof item !== "object" || Array.isArray(item)) return [];
|
|
12615
|
-
return getAtPath(item, restPath);
|
|
12616
|
-
});
|
|
12855
|
+
throw new PermissionDeniedError(
|
|
12856
|
+
`Role "${callerKeyring.role}" cannot recover role "${targetRole}"`
|
|
12857
|
+
);
|
|
12617
12858
|
}
|
|
12618
|
-
|
|
12619
|
-
|
|
12620
|
-
|
|
12621
|
-
|
|
12622
|
-
const nested = obj[head];
|
|
12623
|
-
if (!nested || typeof nested !== "object" || Array.isArray(nested)) return [];
|
|
12624
|
-
return getAtPath(nested, rest);
|
|
12859
|
+
if (!canRecover(callerKeyring.role, target.role)) {
|
|
12860
|
+
throw new PermissionDeniedError(
|
|
12861
|
+
`Role "${callerKeyring.role}" cannot recover role "${target.role}"`
|
|
12862
|
+
);
|
|
12625
12863
|
}
|
|
12626
|
-
const
|
|
12627
|
-
|
|
12628
|
-
|
|
12629
|
-
|
|
12630
|
-
const dotIdx = path.indexOf(".");
|
|
12631
|
-
if (dotIdx !== -1) {
|
|
12632
|
-
const head = path.slice(0, dotIdx);
|
|
12633
|
-
const rest = path.slice(dotIdx + 1);
|
|
12634
|
-
const nested = obj[head];
|
|
12635
|
-
if (!nested || typeof nested !== "object" || Array.isArray(nested)) return;
|
|
12636
|
-
setAtPathInPlace(nested, rest, value);
|
|
12637
|
-
return;
|
|
12864
|
+
for (const coll of Object.keys(target.deks)) {
|
|
12865
|
+
if (!callerKeyring.deks.has(coll)) {
|
|
12866
|
+
throw new PrivilegeEscalationError(coll);
|
|
12867
|
+
}
|
|
12638
12868
|
}
|
|
12639
|
-
|
|
12640
|
-
|
|
12641
|
-
function applyAtPath(obj, path, locale, fallback, opts) {
|
|
12642
|
-
const arrayIdx = path.indexOf("[].");
|
|
12643
|
-
if (arrayIdx !== -1) {
|
|
12644
|
-
const arrayKey = path.slice(0, arrayIdx);
|
|
12645
|
-
const restPath = path.slice(arrayIdx + 3);
|
|
12646
|
-
const arr = obj[arrayKey];
|
|
12647
|
-
if (!Array.isArray(arr)) return obj;
|
|
12648
|
-
return {
|
|
12649
|
-
...obj,
|
|
12650
|
-
[arrayKey]: arr.map((item) => {
|
|
12651
|
-
if (!item || typeof item !== "object" || Array.isArray(item)) return item;
|
|
12652
|
-
return applyAtPath(item, restPath, locale, fallback, opts);
|
|
12653
|
-
})
|
|
12654
|
-
};
|
|
12869
|
+
if (options.validatePassphrase && !options.allowWeakPassphrase) {
|
|
12870
|
+
assertStrongPassphrase(options.passphrase, options.passphrasePolicy);
|
|
12655
12871
|
}
|
|
12656
|
-
const
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
|
|
12660
|
-
const
|
|
12661
|
-
if (!
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
};
|
|
12872
|
+
const newSalt = generateSalt();
|
|
12873
|
+
const newKek = await deriveKey(options.passphrase, newSalt);
|
|
12874
|
+
const wrappedDeks = {};
|
|
12875
|
+
for (const coll of Object.keys(target.deks)) {
|
|
12876
|
+
const callerDek = callerKeyring.deks.get(coll);
|
|
12877
|
+
if (!callerDek) {
|
|
12878
|
+
throw new PrivilegeEscalationError(coll);
|
|
12879
|
+
}
|
|
12880
|
+
wrappedDeks[coll] = await wrapKey(callerDek, newKek);
|
|
12666
12881
|
}
|
|
12667
|
-
const
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
|
|
12882
|
+
const canary = await mintKeyringCanary(newKek);
|
|
12883
|
+
const next = {
|
|
12884
|
+
...target,
|
|
12885
|
+
_noydb_keyring: NOYDB_KEYRING_VERSION,
|
|
12886
|
+
role: targetRole,
|
|
12887
|
+
display_name: options.displayName ?? target.display_name,
|
|
12888
|
+
deks: wrappedDeks,
|
|
12889
|
+
salt: bufferToBase64(newSalt),
|
|
12890
|
+
granted_by: callerKeyring.userId,
|
|
12891
|
+
authenticators: [],
|
|
12892
|
+
canary
|
|
12893
|
+
};
|
|
12894
|
+
const envelope = {
|
|
12895
|
+
_noydb: 1,
|
|
12896
|
+
_v: 1,
|
|
12897
|
+
_ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
12898
|
+
_iv: "",
|
|
12899
|
+
_data: JSON.stringify(next)
|
|
12673
12900
|
};
|
|
12901
|
+
await store.put(vault, "_keyring", options.userId, envelope);
|
|
12674
12902
|
}
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
|
|
12680
|
-
|
|
12681
|
-
|
|
12682
|
-
|
|
12683
|
-
|
|
12684
|
-
|
|
12685
|
-
|
|
12903
|
+
|
|
12904
|
+
// src/index.ts
|
|
12905
|
+
init_errors();
|
|
12906
|
+
|
|
12907
|
+
// src/noydb.ts
|
|
12908
|
+
init_errors();
|
|
12909
|
+
init_constants();
|
|
12910
|
+
init_ulid();
|
|
12911
|
+
init_public_envelope();
|
|
12912
|
+
|
|
12913
|
+
// src/vault.ts
|
|
12914
|
+
init_types();
|
|
12915
|
+
|
|
12916
|
+
// src/collection.ts
|
|
12917
|
+
init_types();
|
|
12918
|
+
|
|
12919
|
+
// src/crdt/strategy.ts
|
|
12920
|
+
var NOT_ENABLED = new Error(
|
|
12921
|
+
'CRDT mode requires the CRDT strategy. Import `{ withCrdt }` from "@noy-db/hub/crdt" and pass it to `createNoydb({ crdtStrategy: withCrdt() })`.'
|
|
12922
|
+
);
|
|
12923
|
+
var NO_CRDT = {
|
|
12924
|
+
buildLwwMapState() {
|
|
12925
|
+
throw NOT_ENABLED;
|
|
12926
|
+
},
|
|
12927
|
+
buildRgaState() {
|
|
12928
|
+
throw NOT_ENABLED;
|
|
12929
|
+
},
|
|
12930
|
+
mergeCrdtStates() {
|
|
12931
|
+
throw NOT_ENABLED;
|
|
12932
|
+
},
|
|
12933
|
+
resolveCrdtSnapshot() {
|
|
12934
|
+
throw NOT_ENABLED;
|
|
12686
12935
|
}
|
|
12687
|
-
|
|
12688
|
-
|
|
12936
|
+
};
|
|
12937
|
+
|
|
12938
|
+
// src/collection.ts
|
|
12939
|
+
init_core();
|
|
12689
12940
|
|
|
12690
12941
|
// src/i18n/dictionary.ts
|
|
12691
12942
|
init_types();
|
|
@@ -13390,6 +13641,7 @@ var NO_I18N = {
|
|
|
13390
13641
|
};
|
|
13391
13642
|
|
|
13392
13643
|
// src/collection.ts
|
|
13644
|
+
init_policy();
|
|
13393
13645
|
init_crypto();
|
|
13394
13646
|
init_errors();
|
|
13395
13647
|
init_tiers();
|
|
@@ -13441,6 +13693,7 @@ init_predicate();
|
|
|
13441
13693
|
// src/query/join.ts
|
|
13442
13694
|
init_predicate();
|
|
13443
13695
|
init_errors();
|
|
13696
|
+
init_core();
|
|
13444
13697
|
var DEFAULT_JOIN_MAX_ROWS = 5e4;
|
|
13445
13698
|
var JOIN_WARN_FRACTION = 0.8;
|
|
13446
13699
|
function coerceRefKey(value) {
|
|
@@ -13468,15 +13721,15 @@ function warnCeilingApproaching(target, side, rows, maxRows) {
|
|
|
13468
13721
|
`[noy-db] .join() ${side} side is at ${pct}% of the ${maxRows}-row ceiling for target "${target}" (${rows} rows). Streaming joins over scan() are not yet supported for collections that need to exceed this.`
|
|
13469
13722
|
);
|
|
13470
13723
|
}
|
|
13471
|
-
function applyJoins(rows, joins, context) {
|
|
13724
|
+
function applyJoins(rows, joins, context, locale) {
|
|
13472
13725
|
if (joins.length === 0) return [...rows];
|
|
13473
13726
|
let result = [...rows];
|
|
13474
13727
|
for (const leg of joins) {
|
|
13475
|
-
result = applyOneJoin(result, leg, context);
|
|
13728
|
+
result = applyOneJoin(result, leg, context, locale);
|
|
13476
13729
|
}
|
|
13477
13730
|
return result;
|
|
13478
13731
|
}
|
|
13479
|
-
function applyOneJoin(leftRows, leg, context) {
|
|
13732
|
+
function applyOneJoin(leftRows, leg, context, locale) {
|
|
13480
13733
|
if (leg.isDictJoin) {
|
|
13481
13734
|
const dictSource = context.resolveDictSource?.(leg.field);
|
|
13482
13735
|
if (!dictSource) {
|
|
@@ -13531,24 +13784,27 @@ function applyOneJoin(leftRows, leg, context) {
|
|
|
13531
13784
|
if (rightSnapshot.length > maxRows * JOIN_WARN_FRACTION) {
|
|
13532
13785
|
warnCeilingApproaching(leg.target, "right", rightSnapshot.length, maxRows);
|
|
13533
13786
|
}
|
|
13787
|
+
const effLocale = locale ?? context.defaultLocale;
|
|
13788
|
+
const i18nResolve = effLocale !== void 0 && source.i18nFields !== void 0 ? (right) => right !== null && typeof right === "object" ? applyI18nLocale(right, source.i18nFields, effLocale, void 0, "join") : right : void 0;
|
|
13534
13789
|
const strategy = leg.strategy ?? (source.lookupById ? "nested" : "hash");
|
|
13535
13790
|
if (strategy === "nested" && source.lookupById) {
|
|
13536
13791
|
const lookup = (id) => source.lookupById?.(id);
|
|
13537
|
-
return nestedLoopJoin(leftRows, leg, lookup);
|
|
13792
|
+
return nestedLoopJoin(leftRows, leg, lookup, i18nResolve);
|
|
13538
13793
|
}
|
|
13539
|
-
return hashJoin(leftRows, leg, rightSnapshot);
|
|
13794
|
+
return hashJoin(leftRows, leg, rightSnapshot, i18nResolve);
|
|
13540
13795
|
}
|
|
13541
|
-
function nestedLoopJoin(leftRows, leg, lookupById) {
|
|
13796
|
+
function nestedLoopJoin(leftRows, leg, lookupById, i18nResolve) {
|
|
13542
13797
|
const out = [];
|
|
13543
13798
|
for (const left of leftRows) {
|
|
13544
13799
|
const rawId = readPath(left, leg.field);
|
|
13545
13800
|
const key = coerceRefKey(rawId);
|
|
13546
|
-
|
|
13801
|
+
let right = key === null ? void 0 : lookupById(key);
|
|
13802
|
+
if (i18nResolve && right !== void 0) right = i18nResolve(right);
|
|
13547
13803
|
out.push(attachJoin(left, leg, right, rawId));
|
|
13548
13804
|
}
|
|
13549
13805
|
return out;
|
|
13550
13806
|
}
|
|
13551
|
-
function hashJoin(leftRows, leg, rightSnapshot) {
|
|
13807
|
+
function hashJoin(leftRows, leg, rightSnapshot, i18nResolve) {
|
|
13552
13808
|
const rightMap = /* @__PURE__ */ new Map();
|
|
13553
13809
|
for (const record of rightSnapshot) {
|
|
13554
13810
|
const rawId = readPath(record, "id");
|
|
@@ -13561,7 +13817,8 @@ function hashJoin(leftRows, leg, rightSnapshot) {
|
|
|
13561
13817
|
for (const left of leftRows) {
|
|
13562
13818
|
const rawId = readPath(left, leg.field);
|
|
13563
13819
|
const key = coerceRefKey(rawId);
|
|
13564
|
-
|
|
13820
|
+
let right = key === null ? void 0 : rightMap.get(key);
|
|
13821
|
+
if (i18nResolve && right !== void 0) right = i18nResolve(right);
|
|
13565
13822
|
out.push(attachJoin(left, leg, right, rawId));
|
|
13566
13823
|
}
|
|
13567
13824
|
return out;
|
|
@@ -13859,11 +14116,16 @@ var Query = class _Query {
|
|
|
13859
14116
|
this.predicates
|
|
13860
14117
|
);
|
|
13861
14118
|
}
|
|
13862
|
-
/**
|
|
13863
|
-
|
|
14119
|
+
/**
|
|
14120
|
+
* Sort by a field. Subsequent calls are tie-breakers. Pass
|
|
14121
|
+
* `{ by: 'label' }` to sort a `dictKey`/`staticDict` field by its resolved
|
|
14122
|
+
* label at the query locale instead of the stored code (#285).
|
|
14123
|
+
*/
|
|
14124
|
+
orderBy(field, direction = "asc", opts) {
|
|
14125
|
+
const entry = opts?.by === "label" ? { field, direction, by: "label" } : { field, direction };
|
|
13864
14126
|
return new _Query(
|
|
13865
14127
|
this.source,
|
|
13866
|
-
{ ...this.plan, orderBy: [...this.plan.orderBy,
|
|
14128
|
+
{ ...this.plan, orderBy: [...this.plan.orderBy, entry] },
|
|
13867
14129
|
this.joinContext,
|
|
13868
14130
|
this.aggregateStrategy,
|
|
13869
14131
|
this.predicates
|
|
@@ -14066,16 +14328,21 @@ var Query = class _Query {
|
|
|
14066
14328
|
* carries any join legs, they are applied after `where` / `orderBy`
|
|
14067
14329
|
* / `limit` / `offset` narrow the left set. See the `.join()` doc
|
|
14068
14330
|
* for the ordering rationale.
|
|
14331
|
+
*
|
|
14332
|
+
* `opts.locale` (#285 §3) resolves JOINED right-side i18n fields at the
|
|
14333
|
+
* `join` layer to that locale; without it, the owning collection's default
|
|
14334
|
+
* locale applies, and a locale-less query leaves joined i18n fields raw.
|
|
14335
|
+
* (Left/base i18n fields are resolved by `get`/`list`, not here.)
|
|
14069
14336
|
*/
|
|
14070
|
-
toArray() {
|
|
14071
|
-
const base = this.decodeMoney(executePlanWithSource(this.source, this.plan, this.joinContext));
|
|
14337
|
+
toArray(opts) {
|
|
14338
|
+
const base = this.decodeMoney(executePlanWithSource(this.source, this.plan, this.joinContext, opts?.locale));
|
|
14072
14339
|
if (this.plan.joins.length === 0) return base;
|
|
14073
14340
|
if (!this.joinContext) {
|
|
14074
14341
|
throw new Error(
|
|
14075
14342
|
`Query.toArray(): plan carries ${this.plan.joins.length} join leg(s) but no JoinContext is attached. This usually means the Query was constructed via the raw Query constructor with a plan that had joins pre-populated. Use collection.query().join(...) instead.`
|
|
14076
14343
|
);
|
|
14077
14344
|
}
|
|
14078
|
-
return applyJoins(base, this.plan.joins, this.joinContext);
|
|
14345
|
+
return applyJoins(base, this.plan.joins, this.joinContext, opts?.locale);
|
|
14079
14346
|
}
|
|
14080
14347
|
/**
|
|
14081
14348
|
* Decode this source's money fields on read (stored scaled-int → canonical
|
|
@@ -14094,9 +14361,9 @@ var Query = class _Query {
|
|
|
14094
14361
|
if (!moneyFields || Object.keys(moneyFields).length === 0) return records;
|
|
14095
14362
|
return records.map((r) => decodeMoneyFields(r, moneyFields, "raw"));
|
|
14096
14363
|
}
|
|
14097
|
-
/** Return the first matching record, or null. Joins are applied. */
|
|
14098
|
-
first() {
|
|
14099
|
-
const arr = this.limit(1).toArray();
|
|
14364
|
+
/** Return the first matching record, or null. Joins are applied. `opts.locale` resolves joined i18n fields (#285 §3). */
|
|
14365
|
+
first(opts) {
|
|
14366
|
+
const arr = this.limit(1).toArray(opts);
|
|
14100
14367
|
return arr[0] ?? null;
|
|
14101
14368
|
}
|
|
14102
14369
|
/**
|
|
@@ -14339,7 +14606,7 @@ var Query = class _Query {
|
|
|
14339
14606
|
return serializePlan(this.plan);
|
|
14340
14607
|
}
|
|
14341
14608
|
};
|
|
14342
|
-
function executePlanWithSource(source, plan, joinContext) {
|
|
14609
|
+
function executePlanWithSource(source, plan, joinContext, locale) {
|
|
14343
14610
|
const hasCrossJoins = plan.clauses.some((c) => c.type === "crossJoin");
|
|
14344
14611
|
let result;
|
|
14345
14612
|
if (hasCrossJoins) {
|
|
@@ -14354,7 +14621,8 @@ function executePlanWithSource(source, plan, joinContext) {
|
|
|
14354
14621
|
result = remainingClauses.length === 0 ? [...candidates] : filterRecords(candidates, remainingClauses, fnViewDecoder(source));
|
|
14355
14622
|
}
|
|
14356
14623
|
if (plan.orderBy.length > 0) {
|
|
14357
|
-
|
|
14624
|
+
const labelMaps = buildOrderLabelMaps(plan.orderBy, joinContext, locale);
|
|
14625
|
+
result = sortRecords(result, plan.orderBy, source.moneyFields, labelMaps);
|
|
14358
14626
|
}
|
|
14359
14627
|
if (plan.offset > 0) {
|
|
14360
14628
|
result = result.slice(plan.offset);
|
|
@@ -14511,11 +14779,19 @@ function applyCrossJoin(leftRel, clause, rightSource) {
|
|
|
14511
14779
|
}
|
|
14512
14780
|
return expanded;
|
|
14513
14781
|
}
|
|
14514
|
-
function sortRecords(records, orderBy, moneyFields) {
|
|
14782
|
+
function sortRecords(records, orderBy, moneyFields, labelMaps) {
|
|
14515
14783
|
return [...records].sort((a, b) => {
|
|
14516
|
-
for (const { field, direction } of orderBy) {
|
|
14517
|
-
|
|
14518
|
-
|
|
14784
|
+
for (const { field, direction, by } of orderBy) {
|
|
14785
|
+
let av = readField(a, field);
|
|
14786
|
+
let bv = readField(b, field);
|
|
14787
|
+
const labelMap = by === "label" ? labelMaps?.get(field) : void 0;
|
|
14788
|
+
if (labelMap) {
|
|
14789
|
+
av = (typeof av === "string" ? labelMap.get(av) : void 0) ?? av;
|
|
14790
|
+
bv = (typeof bv === "string" ? labelMap.get(bv) : void 0) ?? bv;
|
|
14791
|
+
const cmp2 = compareValues(av, bv);
|
|
14792
|
+
if (cmp2 !== 0) return direction === "asc" ? cmp2 : -cmp2;
|
|
14793
|
+
continue;
|
|
14794
|
+
}
|
|
14519
14795
|
const desc = moneyFields?.[field];
|
|
14520
14796
|
const cmp = desc ? compareMoney(av, bv, desc) : compareValues(av, bv);
|
|
14521
14797
|
if (cmp !== 0) return direction === "asc" ? cmp : -cmp;
|
|
@@ -14523,6 +14799,28 @@ function sortRecords(records, orderBy, moneyFields) {
|
|
|
14523
14799
|
return 0;
|
|
14524
14800
|
});
|
|
14525
14801
|
}
|
|
14802
|
+
function buildOrderLabelMaps(orderBy, joinContext, locale) {
|
|
14803
|
+
if (!joinContext?.resolveDictSource) return void 0;
|
|
14804
|
+
const resolveDict = joinContext.resolveDictSource.bind(joinContext);
|
|
14805
|
+
let maps;
|
|
14806
|
+
for (const { field, by } of orderBy) {
|
|
14807
|
+
if (by !== "label") continue;
|
|
14808
|
+
const dictSource = resolveDict(field);
|
|
14809
|
+
if (!dictSource) continue;
|
|
14810
|
+
const loc = locale ?? dictSource.displayLocale;
|
|
14811
|
+
if (loc === void 0) continue;
|
|
14812
|
+
const codeToLabel = /* @__PURE__ */ new Map();
|
|
14813
|
+
for (const entry of dictSource.snapshot()) {
|
|
14814
|
+
const k = entry["key"];
|
|
14815
|
+
const labels = entry["labels"];
|
|
14816
|
+
const label = labels?.[loc];
|
|
14817
|
+
if (typeof k === "string" && typeof label === "string") codeToLabel.set(k, label);
|
|
14818
|
+
}
|
|
14819
|
+
;
|
|
14820
|
+
(maps ??= /* @__PURE__ */ new Map()).set(field, codeToLabel);
|
|
14821
|
+
}
|
|
14822
|
+
return maps;
|
|
14823
|
+
}
|
|
14526
14824
|
function compareMoney(a, b, desc) {
|
|
14527
14825
|
const av = moneyScaledValue(a, desc);
|
|
14528
14826
|
const bv = moneyScaledValue(b, desc);
|
|
@@ -15502,6 +15800,74 @@ var DISABLED_STATE = {
|
|
|
15502
15800
|
getPersistedIndexes: () => null
|
|
15503
15801
|
};
|
|
15504
15802
|
|
|
15803
|
+
// src/search/tokenize.ts
|
|
15804
|
+
var WORD = /[\p{L}\p{N}]+/gu;
|
|
15805
|
+
var tokenize = (text) => {
|
|
15806
|
+
if (!text) return [];
|
|
15807
|
+
return text.normalize("NFKC").toLowerCase().match(WORD) ?? [];
|
|
15808
|
+
};
|
|
15809
|
+
|
|
15810
|
+
// src/search/scan.ts
|
|
15811
|
+
var K1 = 1.2;
|
|
15812
|
+
var B = 0.75;
|
|
15813
|
+
function fieldText(record, field) {
|
|
15814
|
+
const v = record[field];
|
|
15815
|
+
if (typeof v === "string") return v;
|
|
15816
|
+
if (v === null || v === void 0) return "";
|
|
15817
|
+
if (typeof v === "number" || typeof v === "boolean") return String(v);
|
|
15818
|
+
return "";
|
|
15819
|
+
}
|
|
15820
|
+
function searchScan(entries, field, query, opts = {}, tokenizer = tokenize) {
|
|
15821
|
+
const queryTerms = tokenizer(query);
|
|
15822
|
+
if (queryTerms.length === 0) return [];
|
|
15823
|
+
const match = opts.match ?? "any";
|
|
15824
|
+
const usePrefix = opts.prefix ?? false;
|
|
15825
|
+
const exactTerms = usePrefix ? queryTerms.slice(0, -1) : queryTerms;
|
|
15826
|
+
const prefixTerm = usePrefix ? queryTerms[queryTerms.length - 1] : void 0;
|
|
15827
|
+
const docs = entries.map((e) => ({ id: e.id, record: e.record, terms: tokenizer(fieldText(e.record, field)) }));
|
|
15828
|
+
const N = docs.length || 1;
|
|
15829
|
+
const df = /* @__PURE__ */ new Map();
|
|
15830
|
+
let totalLen = 0;
|
|
15831
|
+
for (const d of docs) {
|
|
15832
|
+
totalLen += d.terms.length;
|
|
15833
|
+
for (const t of new Set(d.terms)) df.set(t, (df.get(t) ?? 0) + 1);
|
|
15834
|
+
}
|
|
15835
|
+
const avgdl = totalLen / N || 1;
|
|
15836
|
+
let prefixDf = 0;
|
|
15837
|
+
if (prefixTerm !== void 0) {
|
|
15838
|
+
for (const d of docs) {
|
|
15839
|
+
if (d.terms.some((t) => t.startsWith(prefixTerm))) prefixDf++;
|
|
15840
|
+
}
|
|
15841
|
+
}
|
|
15842
|
+
const requiredCount = exactTerms.length + (prefixTerm !== void 0 ? 1 : 0);
|
|
15843
|
+
const results = [];
|
|
15844
|
+
for (const d of docs) {
|
|
15845
|
+
const tf = /* @__PURE__ */ new Map();
|
|
15846
|
+
for (const t of d.terms) tf.set(t, (tf.get(t) ?? 0) + 1);
|
|
15847
|
+
const matched = [];
|
|
15848
|
+
for (const qt of exactTerms) {
|
|
15849
|
+
const c = tf.get(qt) ?? 0;
|
|
15850
|
+
if (c > 0) matched.push({ tf: c, df: df.get(qt) ?? 0 });
|
|
15851
|
+
}
|
|
15852
|
+
if (prefixTerm !== void 0) {
|
|
15853
|
+
let ptf = 0;
|
|
15854
|
+
for (const [t, c] of tf) if (t.startsWith(prefixTerm)) ptf += c;
|
|
15855
|
+
if (ptf > 0) matched.push({ tf: ptf, df: prefixDf });
|
|
15856
|
+
}
|
|
15857
|
+
if (matched.length === 0) continue;
|
|
15858
|
+
if (match === "all" && matched.length < requiredCount) continue;
|
|
15859
|
+
let score = 0;
|
|
15860
|
+
for (const m of matched) {
|
|
15861
|
+
const idf = Math.log(1 + (N - m.df + 0.5) / (m.df + 0.5));
|
|
15862
|
+
const denom = m.tf + K1 * (1 - B + B * (d.terms.length / avgdl));
|
|
15863
|
+
score += idf * (m.tf * (K1 + 1) / (denom || 1));
|
|
15864
|
+
}
|
|
15865
|
+
results.push({ id: d.id, score, record: d.record });
|
|
15866
|
+
}
|
|
15867
|
+
results.sort((a, b) => b.score - a.score);
|
|
15868
|
+
return opts.limit !== void 0 ? results.slice(0, opts.limit) : results;
|
|
15869
|
+
}
|
|
15870
|
+
|
|
15505
15871
|
// src/collection.ts
|
|
15506
15872
|
init_errors();
|
|
15507
15873
|
|
|
@@ -17789,6 +18155,29 @@ var Collection = class {
|
|
|
17789
18155
|
hasReadTransforms() {
|
|
17790
18156
|
return this.moneyFields !== void 0 && Object.keys(this.moneyFields).length > 0 || this.i18nFields !== void 0 && Object.keys(this.i18nFields).length > 0 || this.dictKeyFields !== void 0 && Object.keys(this.dictKeyFields).length > 0;
|
|
17791
18157
|
}
|
|
18158
|
+
/**
|
|
18159
|
+
* Scan-mode full-text search over a plain-text `field` (#308). Decrypts the
|
|
18160
|
+
* collection in memory and ranks records by BM25 against the tokenized query.
|
|
18161
|
+
* **Zero added store leakage** — pure client-side scan; nothing searchable is
|
|
18162
|
+
* written to the store. (A store-usable blind index for at-scale search is a
|
|
18163
|
+
* separate, gated opt-in — see the #308 design note.) Eager mode only.
|
|
18164
|
+
*
|
|
18165
|
+
* `opts.match` (`'any'` default | `'all'`), `opts.prefix` (last query term as
|
|
18166
|
+
* a prefix → typeahead), `opts.limit` (top-N). Returns `{ id, score, record }`
|
|
18167
|
+
* ranked by descending score. The default tokenizer is word-boundary based —
|
|
18168
|
+
* see `src/search/tokenize.ts` for the Thai/CJK caveat.
|
|
18169
|
+
*/
|
|
18170
|
+
async search(field, query, opts = {}) {
|
|
18171
|
+
if (this.lazy) {
|
|
18172
|
+
throw new Error(
|
|
18173
|
+
`Collection "${this.name}": search() (scan mode) requires eager mode (prefetch: true). A store-usable blind index for lazy / at-scale search is a separate gated opt-in (#308).`
|
|
18174
|
+
);
|
|
18175
|
+
}
|
|
18176
|
+
await this.ensureHydrated();
|
|
18177
|
+
const entries = [];
|
|
18178
|
+
for (const [id, e] of this.cache) entries.push({ id, record: e.record });
|
|
18179
|
+
return searchScan(entries, field, query, opts);
|
|
18180
|
+
}
|
|
17792
18181
|
// ─── Bulk operations ─────────────────────────────────────
|
|
17793
18182
|
/**
|
|
17794
18183
|
* Put many records in one call. Each item is processed sequentially
|
|
@@ -17966,6 +18355,10 @@ var Collection = class {
|
|
|
17966
18355
|
leftCollection,
|
|
17967
18356
|
resolveRef: (field) => resolver.resolveRef(leftCollection, field),
|
|
17968
18357
|
resolveSource: (collectionName) => resolver.resolveSource(collectionName),
|
|
18358
|
+
// #285 §3 — flow the vault/collection default locale to joins so a
|
|
18359
|
+
// joined i18n field resolves like get()/list() when no per-call
|
|
18360
|
+
// locale is given; toArray({ locale }) overrides it.
|
|
18361
|
+
...this.defaultLocale !== void 0 ? { defaultLocale: this.defaultLocale } : {},
|
|
17969
18362
|
...resolver.resolveDictSource ? { resolveDictSource: (field) => resolver.resolveDictSource(leftCollection, field) } : {}
|
|
17970
18363
|
} : void 0;
|
|
17971
18364
|
return new Query(source, void 0, joinContext, this.aggregateStrategy);
|
|
@@ -18054,7 +18447,10 @@ var Collection = class {
|
|
|
18054
18447
|
};
|
|
18055
18448
|
this.emitter.on("change", handler);
|
|
18056
18449
|
return () => this.emitter.off("change", handler);
|
|
18057
|
-
}
|
|
18450
|
+
},
|
|
18451
|
+
// #285 §3 — expose this (right-side) collection's i18nText descriptors so
|
|
18452
|
+
// the join executor can resolve joined i18n fields at the `join` layer.
|
|
18453
|
+
...this.i18nFields !== void 0 ? { i18nFields: this.i18nFields } : {}
|
|
18058
18454
|
};
|
|
18059
18455
|
}
|
|
18060
18456
|
/**
|
|
@@ -18287,6 +18683,10 @@ var Collection = class {
|
|
|
18287
18683
|
leftCollection,
|
|
18288
18684
|
resolveRef: (field) => resolver.resolveRef(leftCollection, field),
|
|
18289
18685
|
resolveSource: (collectionName) => resolver.resolveSource(collectionName),
|
|
18686
|
+
// #285 §3 — flow the vault/collection default locale to joins so a
|
|
18687
|
+
// joined i18n field resolves like get()/list() when no per-call
|
|
18688
|
+
// locale is given; toArray({ locale }) overrides it.
|
|
18689
|
+
...this.defaultLocale !== void 0 ? { defaultLocale: this.defaultLocale } : {},
|
|
18290
18690
|
...resolver.resolveDictSource ? { resolveDictSource: (field) => resolver.resolveDictSource(leftCollection, field) } : {}
|
|
18291
18691
|
} : void 0;
|
|
18292
18692
|
return new ScanBuilder(
|
|
@@ -18844,6 +19244,34 @@ var Collection = class {
|
|
|
18844
19244
|
}
|
|
18845
19245
|
}
|
|
18846
19246
|
}
|
|
19247
|
+
/**
|
|
19248
|
+
* @internal — hard-delete this record's persisted `_idx/<field>/<recordId>`
|
|
19249
|
+
* side-cars for the erasure path (#401). `forget()` crypto-shreds the body but
|
|
19250
|
+
* keeps the collection DEK, under which these side-cars are encrypted — so
|
|
19251
|
+
* without this they leave the indexed field VALUES readable after a "forget".
|
|
19252
|
+
*
|
|
19253
|
+
* Content-free: the side-car id is `encodeIdxId(def.key, id)`, so it needs no
|
|
19254
|
+
* body decode (the body is being shredded). Eager mode has no durable side-car
|
|
19255
|
+
* → no-op. The in-memory mirror is left as-is: it is ephemeral (rebuilt from
|
|
19256
|
+
* the now-deleted side-cars on reopen) and live reads skip the tombstone, so a
|
|
19257
|
+
* stale mirror hit cannot surface the erased record. Returns the count deleted
|
|
19258
|
+
* + the `def.key`s whose delete FAILED (residue that still leaks the value).
|
|
19259
|
+
*/
|
|
19260
|
+
async _purgePersistedIndexes(id) {
|
|
19261
|
+
const persisted = this.persistedIndexes;
|
|
19262
|
+
if (!persisted) return { purged: 0, residue: [] };
|
|
19263
|
+
let purged = 0;
|
|
19264
|
+
const residue = [];
|
|
19265
|
+
for (const def of persisted.definitions()) {
|
|
19266
|
+
try {
|
|
19267
|
+
await this.adapter.delete(this.vault, this.name, encodeIdxId(def.key, id));
|
|
19268
|
+
purged++;
|
|
19269
|
+
} catch {
|
|
19270
|
+
residue.push(def.key);
|
|
19271
|
+
}
|
|
19272
|
+
}
|
|
19273
|
+
return { purged, residue };
|
|
19274
|
+
}
|
|
18847
19275
|
/**
|
|
18848
19276
|
* Bulk-load the persisted-index mirror from `_idx/<field>/*` side-cars
|
|
18849
19277
|
* on first lazy-mode query. Idempotent — subsequent calls short-circuit
|
|
@@ -19976,6 +20404,7 @@ var NO_PERIODS = {
|
|
|
19976
20404
|
};
|
|
19977
20405
|
|
|
19978
20406
|
// src/vault.ts
|
|
20407
|
+
init_core();
|
|
19979
20408
|
init_errors();
|
|
19980
20409
|
|
|
19981
20410
|
// src/periods/periods.ts
|
|
@@ -22586,6 +23015,8 @@ var Vault = class {
|
|
|
22586
23015
|
const blobResidueCollections = /* @__PURE__ */ new Set();
|
|
22587
23016
|
let blobsShredded = 0;
|
|
22588
23017
|
let blobsRetainedShared = 0;
|
|
23018
|
+
let indexPostingsPurged = 0;
|
|
23019
|
+
const indexResidue = [];
|
|
22589
23020
|
const blobsEnabled = this.blobStrategy !== void 0;
|
|
22590
23021
|
const actor = this.keyring.userId;
|
|
22591
23022
|
for (const ref2 of refs) {
|
|
@@ -22607,6 +23038,9 @@ var Vault = class {
|
|
|
22607
23038
|
ref2.id,
|
|
22608
23039
|
actor
|
|
22609
23040
|
);
|
|
23041
|
+
const idxPurge = await coll._purgePersistedIndexes(ref2.id);
|
|
23042
|
+
indexPostingsPurged += idxPurge.purged;
|
|
23043
|
+
for (const field of idxPurge.residue) indexResidue.push(`${ref2.collection}:${ref2.id}:${field}`);
|
|
22610
23044
|
if (blobsEnabled) {
|
|
22611
23045
|
const r = await this.collection(ref2.collection).blob(ref2.id).shredAllForRecord();
|
|
22612
23046
|
blobsShredded += r.shredded.length;
|
|
@@ -22642,7 +23076,9 @@ var Vault = class {
|
|
|
22642
23076
|
unmigratedCount: unmigratedRecords.length,
|
|
22643
23077
|
blobsShredded,
|
|
22644
23078
|
blobsRetainedShared,
|
|
22645
|
-
blobResidueCollections: [...blobResidueCollections]
|
|
23079
|
+
blobResidueCollections: [...blobResidueCollections],
|
|
23080
|
+
indexPostingsPurged,
|
|
23081
|
+
indexResidueCount: indexResidue.length
|
|
22646
23082
|
})
|
|
22647
23083
|
});
|
|
22648
23084
|
return {
|
|
@@ -22654,6 +23090,8 @@ var Vault = class {
|
|
|
22654
23090
|
blobsShredded,
|
|
22655
23091
|
blobsRetainedShared,
|
|
22656
23092
|
blobResidueCollections: [...blobResidueCollections],
|
|
23093
|
+
indexPostingsPurged,
|
|
23094
|
+
indexResidue,
|
|
22657
23095
|
ledgerEntry
|
|
22658
23096
|
};
|
|
22659
23097
|
}
|
|
@@ -23916,6 +24354,8 @@ var Vault = class {
|
|
|
23916
24354
|
*/
|
|
23917
24355
|
async *exportStream(opts = {}) {
|
|
23918
24356
|
const granularity = opts.granularity ?? "collection";
|
|
24357
|
+
const exportLocale = opts.resolveLabels;
|
|
24358
|
+
const localeOpts = exportLocale !== void 0 ? { locale: exportLocale, _layer: "export" } : void 0;
|
|
23919
24359
|
const snapshot = await this.adapter.loadAll(this.name);
|
|
23920
24360
|
const collectionNames = Object.keys(snapshot).sort();
|
|
23921
24361
|
const ledgerHead = opts.withLedgerHead ? await (async () => {
|
|
@@ -23925,19 +24365,21 @@ var Vault = class {
|
|
|
23925
24365
|
return head ? { hash: head.hash, index: head.entry.index, ts: head.entry.ts } : void 0;
|
|
23926
24366
|
})() : void 0;
|
|
23927
24367
|
const dictSnapshotCache = /* @__PURE__ */ new Map();
|
|
23928
|
-
|
|
23929
|
-
const
|
|
23930
|
-
|
|
23931
|
-
|
|
23932
|
-
|
|
23933
|
-
const
|
|
23934
|
-
|
|
23935
|
-
|
|
23936
|
-
|
|
24368
|
+
if (exportLocale === void 0) {
|
|
24369
|
+
for (const collectionName of collectionNames) {
|
|
24370
|
+
const dictFields = this.dictKeyFieldRegistry.get(collectionName);
|
|
24371
|
+
if (dictFields && Object.keys(dictFields).length > 0) {
|
|
24372
|
+
const snap = {};
|
|
24373
|
+
for (const [fieldName, dictName] of Object.entries(dictFields)) {
|
|
24374
|
+
const entries = await this.dictionary(dictName).list();
|
|
24375
|
+
const keyMap = {};
|
|
24376
|
+
for (const entry of entries) {
|
|
24377
|
+
keyMap[entry.key] = entry.labels;
|
|
24378
|
+
}
|
|
24379
|
+
snap[fieldName] = keyMap;
|
|
23937
24380
|
}
|
|
23938
|
-
snap
|
|
24381
|
+
dictSnapshotCache.set(collectionName, snap);
|
|
23939
24382
|
}
|
|
23940
|
-
dictSnapshotCache.set(collectionName, snap);
|
|
23941
24383
|
}
|
|
23942
24384
|
}
|
|
23943
24385
|
for (const collectionName of collectionNames) {
|
|
@@ -23950,7 +24392,7 @@ var Vault = class {
|
|
|
23950
24392
|
if (granularity === "collection") {
|
|
23951
24393
|
const records = [];
|
|
23952
24394
|
for (const id of ids) {
|
|
23953
|
-
const record = await coll.get(id);
|
|
24395
|
+
const record = await coll.get(id, localeOpts);
|
|
23954
24396
|
if (record !== null) records.push(record);
|
|
23955
24397
|
}
|
|
23956
24398
|
const chunk = {
|
|
@@ -23964,7 +24406,7 @@ var Vault = class {
|
|
|
23964
24406
|
yield chunk;
|
|
23965
24407
|
} else {
|
|
23966
24408
|
for (const id of ids) {
|
|
23967
|
-
const record = await coll.get(id);
|
|
24409
|
+
const record = await coll.get(id, localeOpts);
|
|
23968
24410
|
if (record === null) continue;
|
|
23969
24411
|
const chunk = {
|
|
23970
24412
|
collection: collectionName,
|
|
@@ -24068,7 +24510,10 @@ var Vault = class {
|
|
|
24068
24510
|
const allDictionaries = {};
|
|
24069
24511
|
for await (const chunk of this.exportStream({
|
|
24070
24512
|
granularity: "collection",
|
|
24071
|
-
withLedgerHead: opts.withLedgerHead === true
|
|
24513
|
+
withLedgerHead: opts.withLedgerHead === true,
|
|
24514
|
+
// #285 export layer: thread the export locale so records are read at the
|
|
24515
|
+
// `export` layer (i18nText collapsed + dictKey/staticDict labels resolved).
|
|
24516
|
+
...opts.resolveLabels !== void 0 ? { resolveLabels: opts.resolveLabels } : {}
|
|
24072
24517
|
})) {
|
|
24073
24518
|
collections[chunk.collection] = {
|
|
24074
24519
|
schema: null,
|
|
@@ -25902,6 +26347,16 @@ var Noydb = class {
|
|
|
25902
26347
|
async _shardVaultProvisioned(vaultId) {
|
|
25903
26348
|
return (await this.options.store.list(vaultId, "_keyring")).length > 0;
|
|
25904
26349
|
}
|
|
26350
|
+
/**
|
|
26351
|
+
* @internal — the physical backend store a vault id maps to. A
|
|
26352
|
+
* `routeStore` resolves the vault-prefix route via its `resolveBackend`;
|
|
26353
|
+
* a plain store is its own backend. Used by the federation data-residency
|
|
26354
|
+
* guard to read the placement backend's `capabilities.region` (#271).
|
|
26355
|
+
*/
|
|
26356
|
+
_resolveBackend(vaultId) {
|
|
26357
|
+
const store = this.options.store;
|
|
26358
|
+
return store.resolveBackend ? store.resolveBackend(vaultId) : this.options.store;
|
|
26359
|
+
}
|
|
25905
26360
|
/**
|
|
25906
26361
|
* Change the current user's passphrase for a vault.
|
|
25907
26362
|
*
|
|
@@ -28461,6 +28916,11 @@ function withMaterializedView(spec) {
|
|
|
28461
28916
|
);
|
|
28462
28917
|
}
|
|
28463
28918
|
}
|
|
28919
|
+
if (spec.i18nLocale !== void 0 && spec.i18nFields === void 0) {
|
|
28920
|
+
throw new MaterializedViewConfigError(
|
|
28921
|
+
`withMaterializedView "${spec.name}": i18nLocale requires i18nFields \u2014 declare the i18nText descriptors of the group-key fields so they can be resolved at the mv layer before bucketing.`
|
|
28922
|
+
);
|
|
28923
|
+
}
|
|
28464
28924
|
if (typeof spec.rowKey !== "function") {
|
|
28465
28925
|
throw new ValidationError("withMaterializedView: rowKey is required (no default; see spec \xA7 Type surface)");
|
|
28466
28926
|
}
|
|
@@ -28510,6 +28970,7 @@ function withOverlayedView(spec) {
|
|
|
28510
28970
|
// src/index.ts
|
|
28511
28971
|
init_errors();
|
|
28512
28972
|
init_errors();
|
|
28973
|
+
init_core();
|
|
28513
28974
|
|
|
28514
28975
|
// src/money/index.ts
|
|
28515
28976
|
init_descriptor();
|
|
@@ -28626,138 +29087,9 @@ function isMoneyLike(value) {
|
|
|
28626
29087
|
return decimalScaleOf(value) !== null;
|
|
28627
29088
|
}
|
|
28628
29089
|
|
|
28629
|
-
// src/i18n/script.ts
|
|
28630
|
-
init_errors();
|
|
28631
|
-
var LATIN_BASE = /* @__PURE__ */ new Set([
|
|
28632
|
-
"en",
|
|
28633
|
-
"fr",
|
|
28634
|
-
"de",
|
|
28635
|
-
"es",
|
|
28636
|
-
"it",
|
|
28637
|
-
"pt",
|
|
28638
|
-
"nl",
|
|
28639
|
-
"sv",
|
|
28640
|
-
"no",
|
|
28641
|
-
"da",
|
|
28642
|
-
"fi",
|
|
28643
|
-
"is",
|
|
28644
|
-
"pl",
|
|
28645
|
-
"cs",
|
|
28646
|
-
"sk",
|
|
28647
|
-
"hu",
|
|
28648
|
-
"ro",
|
|
28649
|
-
"hr",
|
|
28650
|
-
"sl",
|
|
28651
|
-
"et",
|
|
28652
|
-
"lv",
|
|
28653
|
-
"lt",
|
|
28654
|
-
"tr",
|
|
28655
|
-
"vi",
|
|
28656
|
-
"id",
|
|
28657
|
-
"ms",
|
|
28658
|
-
"tl",
|
|
28659
|
-
"sw",
|
|
28660
|
-
"af",
|
|
28661
|
-
"ca",
|
|
28662
|
-
"gl",
|
|
28663
|
-
"eu",
|
|
28664
|
-
"cy",
|
|
28665
|
-
"ga"
|
|
28666
|
-
]);
|
|
28667
|
-
var SCRIPT_TABLE = {
|
|
28668
|
-
th: ["Thai"],
|
|
28669
|
-
ko: ["Hangul", "Han"],
|
|
28670
|
-
ja: ["Han", "Hiragana", "Katakana"],
|
|
28671
|
-
zh: ["Han"],
|
|
28672
|
-
ar: ["Arabic"],
|
|
28673
|
-
fa: ["Arabic"],
|
|
28674
|
-
ur: ["Arabic"],
|
|
28675
|
-
ru: ["Cyrillic"],
|
|
28676
|
-
uk: ["Cyrillic"],
|
|
28677
|
-
bg: ["Cyrillic"],
|
|
28678
|
-
sr: ["Cyrillic"],
|
|
28679
|
-
he: ["Hebrew"],
|
|
28680
|
-
el: ["Greek"],
|
|
28681
|
-
hi: ["Devanagari"],
|
|
28682
|
-
ta: ["Tamil"],
|
|
28683
|
-
km: ["Khmer"],
|
|
28684
|
-
lo: ["Lao"],
|
|
28685
|
-
my: ["Myanmar"]
|
|
28686
|
-
};
|
|
28687
|
-
var SUBTAG_SCRIPTS = {
|
|
28688
|
-
Latn: ["Latin"],
|
|
28689
|
-
Cyrl: ["Cyrillic", "Latin"],
|
|
28690
|
-
Hans: ["Han", "Latin"],
|
|
28691
|
-
Hant: ["Han", "Latin"],
|
|
28692
|
-
Thai: ["Thai", "Latin"],
|
|
28693
|
-
Arab: ["Arabic", "Latin"]
|
|
28694
|
-
};
|
|
28695
|
-
function inferScripts(locale) {
|
|
28696
|
-
const parts = locale.split("-");
|
|
28697
|
-
const subtag = parts.find((t) => /^[A-Z][a-z]{3}$/.test(t));
|
|
28698
|
-
if (subtag && SUBTAG_SCRIPTS[subtag]) return SUBTAG_SCRIPTS[subtag];
|
|
28699
|
-
const base = (parts[0] ?? "").toLowerCase();
|
|
28700
|
-
if (LATIN_BASE.has(base)) return ["Latin"];
|
|
28701
|
-
const primary = SCRIPT_TABLE[base];
|
|
28702
|
-
if (primary) return [...primary, "Latin"];
|
|
28703
|
-
return ["Latin"];
|
|
28704
|
-
}
|
|
28705
|
-
function allowedFor(descriptor, locale) {
|
|
28706
|
-
const script = descriptor.options.script;
|
|
28707
|
-
if (script && script !== "auto") {
|
|
28708
|
-
const explicit = script[locale];
|
|
28709
|
-
if (explicit) return explicit;
|
|
28710
|
-
}
|
|
28711
|
-
return inferScripts(locale);
|
|
28712
|
-
}
|
|
28713
|
-
var BASELINE = String.raw`\p{White_Space}\p{Script=Common}\p{Script=Inherited}\p{Mark}`;
|
|
28714
|
-
function fullMatcher(scripts) {
|
|
28715
|
-
const cls = scripts.map((s) => `\\p{Script=${s}}`).join("");
|
|
28716
|
-
return new RegExp(`^[${BASELINE}${cls}]*$`, "u");
|
|
28717
|
-
}
|
|
28718
|
-
function charMatcher(scripts) {
|
|
28719
|
-
const cls = scripts.map((s) => `\\p{Script=${s}}`).join("");
|
|
28720
|
-
return new RegExp(`[${BASELINE}${cls}]`, "u");
|
|
28721
|
-
}
|
|
28722
|
-
function offendingSample(str, scripts) {
|
|
28723
|
-
const ok = charMatcher(scripts);
|
|
28724
|
-
const bad = [];
|
|
28725
|
-
for (const ch of str) {
|
|
28726
|
-
if (!ok.test(ch)) bad.push(ch);
|
|
28727
|
-
if (bad.length >= 8) break;
|
|
28728
|
-
}
|
|
28729
|
-
return bad.join("");
|
|
28730
|
-
}
|
|
28731
|
-
function stripDisallowed(str, scripts) {
|
|
28732
|
-
const ok = charMatcher(scripts);
|
|
28733
|
-
let out = "";
|
|
28734
|
-
for (const ch of str) if (ok.test(ch)) out += ch;
|
|
28735
|
-
return out;
|
|
28736
|
-
}
|
|
28737
|
-
function enforceScript(value, field, descriptor) {
|
|
28738
|
-
const opt = descriptor.options;
|
|
28739
|
-
if (!opt.script) return { value, warnings: [] };
|
|
28740
|
-
const mode = opt.onScriptViolation ?? "reject";
|
|
28741
|
-
const warnings = [];
|
|
28742
|
-
let out = value;
|
|
28743
|
-
for (const [locale, raw] of Object.entries(value)) {
|
|
28744
|
-
if (typeof raw !== "string") continue;
|
|
28745
|
-
const allowed = allowedFor(descriptor, locale);
|
|
28746
|
-
if (fullMatcher(allowed).test(raw)) continue;
|
|
28747
|
-
const sample = offendingSample(raw, allowed);
|
|
28748
|
-
if (mode === "reject") {
|
|
28749
|
-
throw new ScriptViolationError(field, locale, allowed, sample);
|
|
28750
|
-
}
|
|
28751
|
-
warnings.push({ field, locale, expected: allowed, sample });
|
|
28752
|
-
if (mode === "filter") {
|
|
28753
|
-
if (out === value) out = { ...value };
|
|
28754
|
-
out[locale] = stripDisallowed(raw, allowed);
|
|
28755
|
-
}
|
|
28756
|
-
}
|
|
28757
|
-
return { value: out, warnings };
|
|
28758
|
-
}
|
|
28759
|
-
|
|
28760
29090
|
// src/index.ts
|
|
29091
|
+
init_policy();
|
|
29092
|
+
init_script();
|
|
28761
29093
|
init_errors();
|
|
28762
29094
|
|
|
28763
29095
|
// src/team/sync-credentials.ts
|
|
@@ -29424,6 +29756,7 @@ function shortJSON(value) {
|
|
|
29424
29756
|
DICT_COLLECTION_PREFIX,
|
|
29425
29757
|
DIRECTORY_RECORD_ID,
|
|
29426
29758
|
DanglingReferenceError,
|
|
29759
|
+
DataResidencyError,
|
|
29427
29760
|
DecryptionError,
|
|
29428
29761
|
DelegationTargetMissingError,
|
|
29429
29762
|
DerivationCapExceededError,
|
|
@@ -29746,6 +30079,7 @@ function shortJSON(value) {
|
|
|
29746
30079
|
sha256Hex,
|
|
29747
30080
|
staticDict,
|
|
29748
30081
|
sum,
|
|
30082
|
+
tokenize,
|
|
29749
30083
|
transitionGuard,
|
|
29750
30084
|
unwrapDeksFromBlob,
|
|
29751
30085
|
unwrapDeksFromPaperEntry,
|