trellis 3.1.35 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -5
- package/README.md +19 -2
- package/bin/trellis.mjs +2 -75
- package/dist/better-sqlite-backend-2P4F6AOJ.js +209 -0
- package/dist/{better-sqlite-backend-ahx5p0br.js → better-sqlite-backend-PII64VE6.js} +37 -25
- package/dist/better-sqlite-backend-VUBVQ7SN.js +209 -0
- package/dist/better-sqlite-backend-Y3AQN65E.js +159 -0
- package/dist/better-sqlite-backend-Y3M7DXOX.js +159 -0
- package/dist/boot-middleware-FJDGVUM4.js +9 -0
- package/dist/boot-middleware-MHLHFCUC.js +9 -0
- package/dist/boot-middleware-MLJUTLUM.js +9 -0
- package/dist/boot-middleware-ZZPDZNYR.js +9 -0
- package/dist/{index-wncptktd.js → chunk-276LKLZR.js} +126 -59
- package/dist/chunk-2BRTCEHB.js +143 -0
- package/dist/chunk-2CX5UCRV.js +111 -0
- package/dist/chunk-2ESYSVXG.js +48 -0
- package/dist/{index-yp88he8n.js → chunk-2I5JU73Y.js} +88 -64
- package/dist/{index-w5wccer3.js → chunk-2UNSRRNB.js} +10 -5
- package/dist/{index-4wxa8xz4.js → chunk-335UEHQR.js} +158 -22
- package/dist/chunk-36VSSTL7.js +357 -0
- package/dist/chunk-3ETIIPPB.js +1077 -0
- package/dist/chunk-3GDRZTAW.js +45 -0
- package/dist/chunk-44FFQKQX.js +142 -0
- package/dist/chunk-4CF2L46N.js +29 -0
- package/dist/chunk-4HYPLFJD.js +150 -0
- package/dist/chunk-4XIVMVHC.js +361 -0
- package/dist/chunk-5CINODKT.js +41 -0
- package/dist/chunk-5ESGWJ5L.js +45 -0
- package/dist/chunk-5FGLQGMF.js +1676 -0
- package/dist/chunk-5IQZFITY.js +357 -0
- package/dist/{index-wt8rz4gn.js → chunk-5JWFAQDW.js} +41 -23
- package/dist/{index-7pjz3tsy.js → chunk-62UHTVU3.js} +50 -16
- package/dist/{index-h32txmxe.js → chunk-66UJQT2I.js} +6 -13
- package/dist/chunk-6CTA6MCE.js +340 -0
- package/dist/{index-4cdr7x2x.js → chunk-6RNNVOAS.js} +178 -109
- package/dist/chunk-6X23PZ6H.js +969 -0
- package/dist/chunk-7C7LL6MB.js +315 -0
- package/dist/chunk-7F4HM3JG.js +394 -0
- package/dist/chunk-7KJ7T4D3.js +910 -0
- package/dist/chunk-7QQQNUB5.js +92 -0
- package/dist/{index-53f3b8p8.js → chunk-7QWJBS72.js} +210 -165
- package/dist/chunk-7R36OZK3.js +957 -0
- package/dist/chunk-7UPKCOHE.js +946 -0
- package/dist/chunk-7WQGTFVJ.js +7434 -0
- package/dist/chunk-A3BONW34.js +35 -0
- package/dist/chunk-AHMDVHBL.js +141 -0
- package/dist/chunk-AW6A4OZY.js +171 -0
- package/dist/chunk-B3ZIFA2O.js +2240 -0
- package/dist/chunk-BJ5EKCJ5.js +458 -0
- package/dist/chunk-BJ7EZ7FP.js +145 -0
- package/dist/chunk-BQBUVMRN.js +171 -0
- package/dist/chunk-BRGYDO7D.js +223 -0
- package/dist/chunk-BXSTJVE3.js +67 -0
- package/dist/chunk-C5KPSEDN.js +359 -0
- package/dist/chunk-CCTNYTUC.js +940 -0
- package/dist/chunk-CYQ2OVD2.js +35 -0
- package/dist/chunk-DDAK7YOE.js +299 -0
- package/dist/chunk-DRILKBY6.js +965 -0
- package/dist/chunk-DXE24HNN.js +45 -0
- package/dist/chunk-E7ICUNW7.js +945 -0
- package/dist/chunk-EAL2PUOE.js +10022 -0
- package/dist/chunk-ELT7MLZB.js +109 -0
- package/dist/chunk-EO3J7GRP.js +0 -0
- package/dist/chunk-EWEIRF6G.js +171 -0
- package/dist/chunk-F5VDGQJC.js +120 -0
- package/dist/chunk-FCPL3IEQ.js +98 -0
- package/dist/{index-nq520y6k.js → chunk-FDPKYSV7.js} +43 -31
- package/dist/chunk-FES3TC24.js +171 -0
- package/dist/chunk-FF36CQHZ.js +61 -0
- package/dist/chunk-FKQO5A3H.js +35 -0
- package/dist/chunk-FOWKR5TW.js +129 -0
- package/dist/chunk-FZVCXDYW.js +150 -0
- package/dist/chunk-G3XIHPSQ.js +361 -0
- package/dist/chunk-GD5QJXSS.js +98 -0
- package/dist/chunk-GFZCJ4EH.js +108 -0
- package/dist/chunk-GKJLYLVU.js +359 -0
- package/dist/chunk-GLM4HGN4.js +55 -0
- package/dist/chunk-GNXHXNVQ.js +113 -0
- package/dist/chunk-GSR6ILTM.js +277 -0
- package/dist/chunk-GWRIMRSX.js +45 -0
- package/dist/chunk-H72UW2HJ.js +45 -0
- package/dist/chunk-HGI74PXB.js +7417 -0
- package/dist/chunk-HGRA37LO.js +145 -0
- package/dist/chunk-HO4TURXW.js +1078 -0
- package/dist/chunk-HXSRQO3L.js +145 -0
- package/dist/chunk-IG2X2BVO.js +373 -0
- package/dist/chunk-IIJVDD54.js +373 -0
- package/dist/chunk-IUWVEEOX.js +145 -0
- package/dist/chunk-IX4BBOIT.js +394 -0
- package/dist/{index-yhwjgfvj.js → chunk-IXU4RMQM.js} +67 -60
- package/dist/chunk-J3WYZO3Q.js +211 -0
- package/dist/{index-vkpkfwhq.js → chunk-J6OUIION.js} +234 -194
- package/dist/{index-xzym9w0m.js → chunk-JA7AIHRK.js} +12 -7
- package/dist/chunk-JUEMDWLU.js +233 -0
- package/dist/chunk-K46RNFDE.js +171 -0
- package/dist/chunk-KAGU2XMY.js +359 -0
- package/dist/chunk-KCVYJNVX.js +394 -0
- package/dist/chunk-KFQGP6VL.js +33 -0
- package/dist/chunk-KKDRMIV6.js +419 -0
- package/dist/chunk-KQ4A2D2P.js +910 -0
- package/dist/chunk-KSU2GW22.js +958 -0
- package/dist/chunk-KYLIQ3YI.js +399 -0
- package/dist/chunk-KZYJJIRN.js +946 -0
- package/dist/chunk-LFOX744K.js +96 -0
- package/dist/{index-rv1p47gp.js → chunk-LHOVJEWR.js} +2756 -2307
- package/dist/{index-h9e2efx4.js → chunk-LNUIGRDZ.js} +71 -55
- package/dist/chunk-LOPXTPF3.js +120 -0
- package/dist/chunk-LZR3VIFU.js +907 -0
- package/dist/chunk-MBNBTJCR.js +394 -0
- package/dist/chunk-MCKGQKYU.js +15 -0
- package/dist/{index-skhn0agf.js → chunk-MLC5BUYO.js} +19 -20
- package/dist/chunk-MPXUVGT3.js +104 -0
- package/dist/chunk-MU6EOS6F.js +0 -0
- package/dist/chunk-MWRQ2TXT.js +357 -0
- package/dist/{index-nzb3am4f.js → chunk-NO73OK2I.js} +43 -21
- package/dist/chunk-NPE2YJHK.js +394 -0
- package/dist/{index-xhcp6xrn.js → chunk-NSDXU6QX.js} +654 -500
- package/dist/chunk-NXIRDSZ6.js +145 -0
- package/dist/chunk-NZWFNHCS.js +407 -0
- package/dist/chunk-O2AV5WMN.js +48 -0
- package/dist/{index-h7zxhhhh.js → chunk-OB4CMMX6.js} +46 -38
- package/dist/chunk-OBKU74FU.js +7411 -0
- package/dist/chunk-OQNDWRDE.js +145 -0
- package/dist/chunk-OVWAJMB6.js +394 -0
- package/dist/chunk-PDHLBTTD.js +45 -0
- package/dist/chunk-PEQNRKLG.js +210 -0
- package/dist/chunk-QERIS7QY.js +7403 -0
- package/dist/chunk-QHA2DM3C.js +373 -0
- package/dist/chunk-QLM4HSYC.js +45 -0
- package/dist/chunk-RSWUFTO2.js +857 -0
- package/dist/chunk-S2OT3TQJ.js +283 -0
- package/dist/chunk-S5PHSN5K.js +907 -0
- package/dist/chunk-SIAA4J6H.js +21 -0
- package/dist/chunk-SPSPV5BC.js +390 -0
- package/dist/chunk-SQBNLUIA.js +171 -0
- package/dist/chunk-STLN6A6B.js +355 -0
- package/dist/chunk-TCKXSOBP.js +123 -0
- package/dist/chunk-U7HV7GU2.js +17 -0
- package/dist/chunk-UBGUDMUV.js +59 -0
- package/dist/chunk-UGZHOGRA.js +39 -0
- package/dist/chunk-UICF66FS.js +359 -0
- package/dist/chunk-UK3EQREE.js +1078 -0
- package/dist/chunk-UPKPURVY.js +394 -0
- package/dist/chunk-URC74VCN.js +959 -0
- package/dist/chunk-USEINYUL.js +12 -0
- package/dist/{index-bmyt7k8n.js → chunk-UZRUP7QW.js} +12 -4
- package/dist/chunk-V3G7Q3QQ.js +102 -0
- package/dist/chunk-VDAKEOML.js +857 -0
- package/dist/chunk-VUJ6SA55.js +303 -0
- package/dist/chunk-VUJQLIML.js +141 -0
- package/dist/chunk-VWKLKLYB.js +267 -0
- package/dist/chunk-VYC3RZMK.js +277 -0
- package/dist/chunk-WMERMSWI.js +154 -0
- package/dist/chunk-WMR777PO.js +2213 -0
- package/dist/{index-n9f2qyh5.js → chunk-X46IECAC.js} +55 -33
- package/dist/chunk-X5FLTRUB.js +517 -0
- package/dist/chunk-X762XWVC.js +419 -0
- package/dist/chunk-XEN3OEYY.js +2234 -0
- package/dist/chunk-XMQ7G77X.js +260 -0
- package/dist/chunk-XZQ66K7A.js +124 -0
- package/dist/{index-w7ng765c.js → chunk-YCM7ZYEZ.js} +102 -49
- package/dist/chunk-YY3GF7DH.js +7411 -0
- package/dist/chunk-ZE5R3H4C.js +907 -0
- package/dist/chunk-ZHVI7BQN.js +1077 -0
- package/dist/chunk-ZMN5LUB7.js +7411 -0
- package/dist/chunk-ZUV4MD5U.js +94 -0
- package/dist/cli/errors.d.ts +6 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/examples.d.ts +23 -0
- package/dist/cli/examples.d.ts.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2338 -6190
- package/dist/client/index.d.ts +6 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +41 -21
- package/dist/client/live.d.ts +67 -0
- package/dist/client/live.d.ts.map +1 -0
- package/dist/client/reactive.d.ts +31 -0
- package/dist/client/reactive.d.ts.map +1 -0
- package/dist/client/sdk.d.ts +26 -2
- package/dist/client/sdk.d.ts.map +1 -1
- package/dist/client/sdk.js +9 -0
- package/dist/client/vcs-client.d.ts +129 -0
- package/dist/client/vcs-client.d.ts.map +1 -0
- package/dist/cms/index.js +171 -163
- package/dist/{config-8hczw0rs.js → config-KMY6RRK3.js} +8 -9
- package/dist/config-PFTP67TR.js +19 -0
- package/dist/config-VDMK2DUJ.js +19 -0
- package/dist/core/computation/index.d.ts +5 -0
- package/dist/core/computation/index.d.ts.map +1 -0
- package/dist/core/computation/rollup.d.ts +18 -0
- package/dist/core/computation/rollup.d.ts.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +168 -101
- package/dist/core/kernel/boot-middleware.d.ts +10 -0
- package/dist/core/kernel/boot-middleware.d.ts.map +1 -0
- package/dist/core/kernel/logic-middleware.d.ts +7 -1
- package/dist/core/kernel/logic-middleware.d.ts.map +1 -1
- package/dist/core/kernel/trellis-kernel.d.ts.map +1 -1
- package/dist/core/ontology/types.d.ts +5 -0
- package/dist/core/ontology/types.d.ts.map +1 -1
- package/dist/core/persist/better-sqlite-backend.d.ts +9 -2
- package/dist/core/persist/better-sqlite-backend.d.ts.map +1 -1
- package/dist/core/persist/factory.d.ts +6 -7
- package/dist/core/persist/factory.d.ts.map +1 -1
- package/dist/core/persist/factory.js +2 -3
- package/dist/core/persist/sqljs-backend.js +2 -3
- package/dist/db/index.d.ts +4 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +69 -56
- package/dist/db/inspector.js +11 -19
- package/dist/decisions/index.js +9 -10
- package/dist/deploy-66EC752W.js +9 -0
- package/dist/deploy-SO7AFK6L.js +9 -0
- package/dist/embeddings/auto-embed.d.ts +2 -2
- package/dist/embeddings/auto-embed.d.ts.map +1 -1
- package/dist/embeddings/index.js +20 -22
- package/dist/embeddings/search.d.ts +2 -1
- package/dist/embeddings/search.d.ts.map +1 -1
- package/dist/embeddings/store.d.ts +25 -4
- package/dist/embeddings/store.d.ts.map +1 -1
- package/dist/engine-7GXBM4IT.js +7 -0
- package/dist/engine-NSR6BIF7.js +7 -0
- package/dist/engine.d.ts +32 -12
- package/dist/engine.d.ts.map +1 -1
- package/dist/factory-2P64OC7M.js +34 -0
- package/dist/factory-YP4ZZK5K.js +34 -0
- package/dist/import-AJLYHFIA.js +10 -0
- package/dist/import-UZEKXU3B.js +10 -0
- package/dist/index.js +102 -93
- package/dist/launch-explorer-AI6L2AWJ.js +91 -0
- package/dist/launch-explorer-HZ4ZJA4X.js +95 -0
- package/dist/links/index.js +24 -26
- package/dist/plugins/agent-memory/index.js +316 -0
- package/dist/plugins/idea-garden/index.js +165 -0
- package/dist/plugins/plan-approval/index.js +579 -0
- package/dist/plugins/proactive-watcher/index.js +194 -0
- package/dist/{index-2r4jxwnb.js → query-GJL3CVGN.js} +14 -15
- package/dist/query-MBJSK3EB.js +31 -0
- package/dist/query-TJHEVSKL.js +31 -0
- package/dist/query-WUIKOHPE.js +524 -0
- package/dist/query-XYLTJYSA.js +31 -0
- package/dist/react/index.js +39 -70
- package/dist/react/realtime.js +11 -0
- package/dist/react/schema-hooks.js +87 -0
- package/dist/realtime/broadcast-channel-transport.d.ts +43 -0
- package/dist/realtime/broadcast-channel-transport.d.ts.map +1 -0
- package/dist/realtime/durable-object-relay-transport.d.ts +96 -0
- package/dist/realtime/durable-object-relay-transport.d.ts.map +1 -0
- package/dist/realtime/index.d.ts +44 -0
- package/dist/realtime/index.d.ts.map +1 -0
- package/dist/realtime/index.js +40 -0
- package/dist/realtime/memory-hub.d.ts +32 -0
- package/dist/realtime/memory-hub.d.ts.map +1 -0
- package/dist/realtime/persistent-channel.d.ts +105 -0
- package/dist/realtime/persistent-channel.d.ts.map +1 -0
- package/dist/realtime/presence.d.ts +73 -0
- package/dist/realtime/presence.d.ts.map +1 -0
- package/dist/realtime/relay-persistence.d.ts +37 -0
- package/dist/realtime/relay-persistence.d.ts.map +1 -0
- package/dist/realtime/relay-persistence.js +107 -0
- package/dist/realtime/relay-server.d.ts +103 -0
- package/dist/realtime/relay-server.d.ts.map +1 -0
- package/dist/realtime/room.d.ts +98 -0
- package/dist/realtime/room.d.ts.map +1 -0
- package/dist/realtime/text.d.ts +73 -0
- package/dist/realtime/text.d.ts.map +1 -0
- package/dist/realtime/types.d.ts +89 -0
- package/dist/realtime/types.d.ts.map +1 -0
- package/dist/realtime/websocket-relay-transport.d.ts +28 -0
- package/dist/realtime/websocket-relay-transport.d.ts.map +1 -0
- package/dist/realtime.bundle.js +1100 -0
- package/dist/remote-manager-BLJZ6KF6.js +224 -0
- package/dist/{remote-manager-xvbg4230.js → remote-manager-BPYE46SI.js} +24 -15
- package/dist/remote-manager-FMESEAFA.js +224 -0
- package/dist/remote-manager-K2WZ5RHY.js +223 -0
- package/dist/remote-manager-SG545WNY.js +224 -0
- package/dist/remote-manager-SG5PQKCH.js +224 -0
- package/dist/remote-manager-WGP6MIQZ.js +224 -0
- package/dist/scaffold/write.d.ts.map +1 -1
- package/dist/schema/define.d.ts +137 -0
- package/dist/schema/define.d.ts.map +1 -0
- package/dist/schema/entity-projection.d.ts +34 -0
- package/dist/schema/entity-projection.d.ts.map +1 -0
- package/dist/schema/eql.d.ts +46 -0
- package/dist/schema/eql.d.ts.map +1 -0
- package/dist/schema/index.d.ts +21 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +45 -0
- package/dist/schema/kernel-resolve.d.ts +21 -0
- package/dist/schema/kernel-resolve.d.ts.map +1 -0
- package/dist/schema/mutations.d.ts +20 -0
- package/dist/schema/mutations.d.ts.map +1 -0
- package/dist/schema/resolve.d.ts +21 -0
- package/dist/schema/resolve.d.ts.map +1 -0
- package/dist/sdk-3KBB3E6V.js +16 -0
- package/dist/sdk-4ZQO6UTU.js +16 -0
- package/dist/sdk-6JA6GV3G.js +16 -0
- package/dist/sdk-6VTP5UTZ.js +16 -0
- package/dist/sdk-7VS6TYCD.js +16 -0
- package/dist/sdk-HQ3FTLRT.js +16 -0
- package/dist/sdk-HZ7NU3XE.js +15 -0
- package/dist/sdk-KBQE2OXT.js +16 -0
- package/dist/sdk-LZ7W3EEY.js +9 -0
- package/dist/sdk-MSCDZ7JU.js +15 -0
- package/dist/sdk-WNZOGO3S.js +15 -0
- package/dist/sdk-YLV33ZCW.js +9 -0
- package/dist/sdk-ZSUD2LLJ.js +16 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +69 -61
- package/dist/server/node-adapter.js +5 -104
- package/dist/server/realtime.d.ts +10 -2
- package/dist/server/realtime.d.ts.map +1 -1
- package/dist/server/server.d.ts +7 -16
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/sprites.d.ts.map +1 -1
- package/dist/server/tenancy.d.ts.map +1 -1
- package/dist/server-AFXFFBWA.js +11 -0
- package/dist/server-AGHC4VUL.js +11 -0
- package/dist/server-BOH7M4TT.js +13 -0
- package/dist/server-DBUY2KY5.js +11 -0
- package/dist/server-GWBQJPRG.js +11 -0
- package/dist/server-IGBIIJSF.js +13 -0
- package/dist/server-JZZFULVU.js +11 -0
- package/dist/server-L5XAF4M5.js +11 -0
- package/dist/server-NYFUHANA.js +12 -0
- package/dist/server-OABUB2LO.js +12 -0
- package/dist/server-P2CKZWWV.js +12 -0
- package/dist/{sprites-vc4qbrp1.js → sprites-RU3E4XQN.js} +6 -7
- package/dist/sprites-XVSMQLSI.js +15 -0
- package/dist/sql-wasm-FORCZFHZ.js +2148 -0
- package/dist/sql-wasm-JZH76RLO.js +2148 -0
- package/dist/sqljs-backend-CJQOIQYE.js +266 -0
- package/dist/sqljs-backend-KWXBUDUO.js +266 -0
- package/dist/state-demo.bundle.js +1033 -0
- package/dist/svelte/index.d.ts +17 -0
- package/dist/svelte/index.d.ts.map +1 -0
- package/dist/svelte/index.js +51 -0
- package/dist/svelte/schema-hooks.d.ts +45 -0
- package/dist/svelte/schema-hooks.d.ts.map +1 -0
- package/dist/svelte/schema-hooks.js +71 -0
- package/dist/svelte/stores.d.ts +78 -0
- package/dist/svelte/stores.d.ts.map +1 -0
- package/dist/sync/http-transport.d.ts +3 -3
- package/dist/sync/http-transport.d.ts.map +1 -1
- package/dist/sync/index.d.ts +15 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/index.js +617 -0
- package/dist/sync/memory-room.d.ts +37 -0
- package/dist/sync/memory-room.d.ts.map +1 -0
- package/dist/sync/memory-transport.d.ts +3 -3
- package/dist/sync/memory-transport.d.ts.map +1 -1
- package/dist/sync/partykit-room.d.ts +40 -0
- package/dist/sync/partykit-room.d.ts.map +1 -0
- package/dist/sync/partykit-transport.d.ts +84 -0
- package/dist/sync/partykit-transport.d.ts.map +1 -0
- package/dist/sync/room-core.d.ts +53 -0
- package/dist/sync/room-core.d.ts.map +1 -0
- package/dist/sync/sync-engine.d.ts +40 -2
- package/dist/sync/sync-engine.d.ts.map +1 -1
- package/dist/sync/sync-room-server.d.ts +39 -0
- package/dist/sync/sync-room-server.d.ts.map +1 -0
- package/dist/sync/types.d.ts +70 -3
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/sync/vcs-sync-peer.d.ts +63 -0
- package/dist/sync/vcs-sync-peer.d.ts.map +1 -0
- package/dist/sync/ws-transport.d.ts +2 -2
- package/dist/sync/ws-transport.d.ts.map +1 -1
- package/dist/tenancy-CBWYEVUB.js +11 -0
- package/dist/tenancy-FO6WVYFN.js +13 -0
- package/dist/tenancy-FWDBESMX.js +14 -0
- package/dist/tenancy-HGPIS5QA.js +13 -0
- package/dist/tenancy-HXFALA37.js +14 -0
- package/dist/tenancy-OP34NFFS.js +14 -0
- package/dist/tenancy-S676GLID.js +14 -0
- package/dist/tenancy-V7ARWNNV.js +14 -0
- package/dist/tenancy-ZDN4GXK5.js +13 -0
- package/dist/tenancy-ZT5VMY7B.js +14 -0
- package/dist/ui/client.html +355 -67
- package/dist/ui/launch-explorer.d.ts +22 -0
- package/dist/ui/launch-explorer.d.ts.map +1 -0
- package/dist/ui/server.d.ts +1 -1
- package/dist/ui/server.d.ts.map +1 -1
- package/dist/vcs/blob-store.d.ts.map +1 -1
- package/dist/vcs/idb-op-log.d.ts +67 -0
- package/dist/vcs/idb-op-log.d.ts.map +1 -0
- package/dist/vcs/index.d.ts +1 -0
- package/dist/vcs/index.d.ts.map +1 -1
- package/dist/vcs/index.js +81 -72
- package/dist/vcs/issue.d.ts +22 -5
- package/dist/vcs/issue.d.ts.map +1 -1
- package/dist/vcs/lane-materialize.d.ts +5 -0
- package/dist/vcs/lane-materialize.d.ts.map +1 -1
- package/dist/vcs/op-log.d.ts +28 -2
- package/dist/vcs/op-log.d.ts.map +1 -1
- package/dist/vcs/ops.d.ts +10 -0
- package/dist/vcs/ops.d.ts.map +1 -1
- package/dist/{vm-config-6xhsj6b3.js → vm-config-JI4OXKDQ.js} +9 -10
- package/dist/vm-config-YZRJ3KUB.js +21 -0
- package/dist/vue/hooks.d.ts +64 -0
- package/dist/vue/hooks.d.ts.map +1 -0
- package/dist/vue/index.d.ts +19 -0
- package/dist/vue/index.d.ts.map +1 -0
- package/dist/vue/index.js +59 -0
- package/dist/vue/schema-hooks.d.ts +41 -0
- package/dist/vue/schema-hooks.d.ts.map +1 -0
- package/dist/vue/schema-hooks.js +64 -0
- package/package.json +118 -16
- package/dist/deploy-999q207z.js +0 -10
- package/dist/engine-y0724kjq.js +0 -8
- package/dist/import-s2b8e0ft.js +0 -11
- package/dist/index-a76rekgs.js +0 -67
- package/dist/index-c9h37r6h.js +0 -1
- package/dist/index-hr9qvv77.js +0 -860
- package/dist/index-k5b0xskw.js +0 -1
- package/dist/index-y6a4kj0p.js +0 -43
- package/dist/sdk-bepky0xs.js +0 -16
- package/dist/server-szdjx0nt.js +0 -13
- package/dist/sqlite-backend-0vsmc6qj.js +0 -8
- package/dist/tenancy-pjm32b4v.js +0 -14
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
// @bun
|
|
2
1
|
import {
|
|
3
2
|
parseSimple
|
|
4
|
-
} from "./
|
|
3
|
+
} from "./chunk-X46IECAC.js";
|
|
5
4
|
import {
|
|
6
5
|
QueryEngine
|
|
7
|
-
} from "./
|
|
8
|
-
import {
|
|
9
|
-
__require
|
|
10
|
-
} from "./index-a76rekgs.js";
|
|
6
|
+
} from "./chunk-2I5JU73Y.js";
|
|
11
7
|
|
|
12
8
|
// src/server/server.ts
|
|
13
9
|
import { existsSync, readFileSync } from "fs";
|
|
@@ -33,13 +29,19 @@ function base64UrlDecode(input) {
|
|
|
33
29
|
return Uint8Array.from(binary, (c) => c.charCodeAt(0));
|
|
34
30
|
}
|
|
35
31
|
async function hmacKey(secret) {
|
|
36
|
-
return crypto.subtle.importKey(
|
|
32
|
+
return crypto.subtle.importKey(
|
|
33
|
+
"raw",
|
|
34
|
+
new TextEncoder().encode(secret),
|
|
35
|
+
{ name: "HMAC", hash: "SHA-256" },
|
|
36
|
+
false,
|
|
37
|
+
["sign", "verify"]
|
|
38
|
+
);
|
|
37
39
|
}
|
|
38
40
|
async function signJwt(payload, secret, expiresInSeconds = 86400) {
|
|
39
41
|
const header = { alg: "HS256", typ: "JWT" };
|
|
40
|
-
const now = Math.floor(Date.now() /
|
|
42
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
41
43
|
const claims = { iat: now, exp: now + expiresInSeconds, ...payload };
|
|
42
|
-
const enc = new TextEncoder;
|
|
44
|
+
const enc = new TextEncoder();
|
|
43
45
|
const headerB64 = base64UrlEncode(enc.encode(JSON.stringify(header)));
|
|
44
46
|
const payloadB64 = base64UrlEncode(enc.encode(JSON.stringify(claims)));
|
|
45
47
|
const signing = `${headerB64}.${payloadB64}`;
|
|
@@ -50,22 +52,29 @@ async function signJwt(payload, secret, expiresInSeconds = 86400) {
|
|
|
50
52
|
}
|
|
51
53
|
async function verifyJwt(token, secret) {
|
|
52
54
|
const parts = token.split(".");
|
|
53
|
-
if (parts.length !== 3)
|
|
54
|
-
return null;
|
|
55
|
+
if (parts.length !== 3) return null;
|
|
55
56
|
const [headerB64, payloadB64, sigB64] = parts;
|
|
56
|
-
const enc = new TextEncoder;
|
|
57
|
+
const enc = new TextEncoder();
|
|
57
58
|
const signing = `${headerB64}.${payloadB64}`;
|
|
58
59
|
try {
|
|
59
60
|
const key = await hmacKey(secret);
|
|
60
61
|
const sigRaw = base64UrlDecode(sigB64);
|
|
61
|
-
const sigBuf = sigRaw.buffer.slice(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
const sigBuf = sigRaw.buffer.slice(
|
|
63
|
+
sigRaw.byteOffset,
|
|
64
|
+
sigRaw.byteOffset + sigRaw.byteLength
|
|
65
|
+
);
|
|
66
|
+
const valid = await crypto.subtle.verify(
|
|
67
|
+
"HMAC",
|
|
68
|
+
key,
|
|
69
|
+
sigBuf,
|
|
70
|
+
enc.encode(signing)
|
|
71
|
+
);
|
|
72
|
+
if (!valid) return null;
|
|
73
|
+
const claims = JSON.parse(
|
|
74
|
+
new TextDecoder().decode(base64UrlDecode(payloadB64))
|
|
75
|
+
);
|
|
76
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
77
|
+
if (typeof claims.exp === "number" && claims.exp < now) return null;
|
|
69
78
|
return claims;
|
|
70
79
|
} catch {
|
|
71
80
|
return null;
|
|
@@ -157,34 +166,50 @@ async function exchangeOAuthCode(provider, code, redirectUri) {
|
|
|
157
166
|
id: String(user.id ?? user.sub ?? ""),
|
|
158
167
|
email: String(user.email ?? ""),
|
|
159
168
|
name: String(user.name ?? user.login ?? ""),
|
|
160
|
-
avatarUrl: user.picture ?? user.avatar_url ??
|
|
169
|
+
avatarUrl: user.picture ?? user.avatar_url ?? void 0
|
|
161
170
|
};
|
|
162
171
|
}
|
|
163
172
|
|
|
164
173
|
// src/server/permissions.ts
|
|
165
|
-
|
|
166
|
-
rules = new Map;
|
|
174
|
+
var PermissionRegistry = class {
|
|
175
|
+
rules = /* @__PURE__ */ new Map();
|
|
167
176
|
defaultRule = "authenticated";
|
|
177
|
+
/**
|
|
178
|
+
* Register permissions for an entity type.
|
|
179
|
+
*/
|
|
168
180
|
register(entityType, permissions) {
|
|
169
181
|
this.rules.set(entityType, permissions);
|
|
170
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* Set the fallback rule used when an entity type has no declared permissions.
|
|
185
|
+
*/
|
|
171
186
|
setDefault(rule) {
|
|
172
187
|
this.defaultRule = rule;
|
|
173
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* Get the permission rule for a specific operation on an entity type.
|
|
191
|
+
* Falls back to the default rule if not declared.
|
|
192
|
+
*/
|
|
174
193
|
getRule(entityType, op) {
|
|
175
194
|
const def = this.rules.get(entityType);
|
|
176
195
|
return def?.[op] ?? this.defaultRule;
|
|
177
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Check whether an auth context is allowed to perform an operation.
|
|
199
|
+
*/
|
|
178
200
|
check(auth, entityType, op, entity = null) {
|
|
179
201
|
const rule = this.getRule(entityType, op);
|
|
180
202
|
return evaluateRule(rule, auth, entity);
|
|
181
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Assert access — throws a PermissionError if denied.
|
|
206
|
+
*/
|
|
182
207
|
assert(auth, entityType, op, entity = null) {
|
|
183
208
|
if (!this.check(auth, entityType, op, entity)) {
|
|
184
209
|
throw new PermissionError(auth, entityType, op);
|
|
185
210
|
}
|
|
186
211
|
}
|
|
187
|
-
}
|
|
212
|
+
};
|
|
188
213
|
function evaluateRule(rule, auth, entity) {
|
|
189
214
|
if (rule === "public") {
|
|
190
215
|
return true;
|
|
@@ -193,9 +218,10 @@ function evaluateRule(rule, auth, entity) {
|
|
|
193
218
|
return auth.authenticated;
|
|
194
219
|
}
|
|
195
220
|
if (rule === "own") {
|
|
196
|
-
if (!auth.authenticated || !auth.userId)
|
|
197
|
-
|
|
198
|
-
|
|
221
|
+
if (!auth.authenticated || !auth.userId) return false;
|
|
222
|
+
const ownerFact = entity?.facts.find(
|
|
223
|
+
(f) => f.a === "ownerId" || f.a === "createdBy"
|
|
224
|
+
);
|
|
199
225
|
return ownerFact?.v === auth.userId;
|
|
200
226
|
}
|
|
201
227
|
if (typeof rule === "object") {
|
|
@@ -215,11 +241,7 @@ function evaluateRule(rule, auth, entity) {
|
|
|
215
241
|
}
|
|
216
242
|
return false;
|
|
217
243
|
}
|
|
218
|
-
|
|
219
|
-
class PermissionError extends Error {
|
|
220
|
-
auth;
|
|
221
|
-
entityType;
|
|
222
|
-
op;
|
|
244
|
+
var PermissionError = class extends Error {
|
|
223
245
|
constructor(auth, entityType, op) {
|
|
224
246
|
const who = auth.authenticated ? `user:${auth.userId}` : "anonymous";
|
|
225
247
|
super(`Permission denied: ${who} cannot ${op} ${entityType}`);
|
|
@@ -235,7 +257,7 @@ class PermissionError extends Error {
|
|
|
235
257
|
code: 403
|
|
236
258
|
};
|
|
237
259
|
}
|
|
238
|
-
}
|
|
260
|
+
};
|
|
239
261
|
var PUBLIC_READ = {
|
|
240
262
|
read: "public",
|
|
241
263
|
create: "authenticated",
|
|
@@ -262,19 +284,22 @@ var ADMIN_ONLY = {
|
|
|
262
284
|
};
|
|
263
285
|
|
|
264
286
|
// src/server/realtime.ts
|
|
265
|
-
|
|
266
|
-
clients = new Map;
|
|
287
|
+
var SubscriptionManager = class {
|
|
288
|
+
clients = /* @__PURE__ */ new Map();
|
|
267
289
|
pool;
|
|
268
290
|
permissions;
|
|
269
291
|
constructor(pool, permissions = null) {
|
|
270
292
|
this.pool = pool;
|
|
271
293
|
this.permissions = permissions;
|
|
272
294
|
}
|
|
295
|
+
// -------------------------------------------------------------------------
|
|
296
|
+
// Client lifecycle
|
|
297
|
+
// -------------------------------------------------------------------------
|
|
273
298
|
addClient(clientId, ws, auth, tenantId) {
|
|
274
299
|
this.clients.set(clientId, {
|
|
275
300
|
id: clientId,
|
|
276
301
|
ws,
|
|
277
|
-
subscriptions: new Map,
|
|
302
|
+
subscriptions: /* @__PURE__ */ new Map(),
|
|
278
303
|
auth,
|
|
279
304
|
tenantId
|
|
280
305
|
});
|
|
@@ -282,10 +307,12 @@ class SubscriptionManager {
|
|
|
282
307
|
removeClient(clientId) {
|
|
283
308
|
this.clients.delete(clientId);
|
|
284
309
|
}
|
|
310
|
+
// -------------------------------------------------------------------------
|
|
311
|
+
// Message handling
|
|
312
|
+
// -------------------------------------------------------------------------
|
|
285
313
|
async handleMessage(clientId, raw) {
|
|
286
314
|
const client = this.clients.get(clientId);
|
|
287
|
-
if (!client)
|
|
288
|
-
return;
|
|
315
|
+
if (!client) return;
|
|
289
316
|
let msg;
|
|
290
317
|
try {
|
|
291
318
|
msg = JSON.parse(raw);
|
|
@@ -306,6 +333,13 @@ class SubscriptionManager {
|
|
|
306
333
|
return;
|
|
307
334
|
}
|
|
308
335
|
}
|
|
336
|
+
// -------------------------------------------------------------------------
|
|
337
|
+
// Notify — called after every mutation
|
|
338
|
+
// -------------------------------------------------------------------------
|
|
339
|
+
/**
|
|
340
|
+
* Re-evaluate all subscriptions for a given tenant and push diffs.
|
|
341
|
+
* Called after every write op lands.
|
|
342
|
+
*/
|
|
309
343
|
async notify(tenantId) {
|
|
310
344
|
const tid = tenantId ?? null;
|
|
311
345
|
const dead = [];
|
|
@@ -314,20 +348,20 @@ class SubscriptionManager {
|
|
|
314
348
|
dead.push(clientId);
|
|
315
349
|
continue;
|
|
316
350
|
}
|
|
317
|
-
if (client.tenantId !== tid)
|
|
318
|
-
continue;
|
|
351
|
+
if (client.tenantId !== tid) continue;
|
|
319
352
|
for (const [subId, sub] of client.subscriptions) {
|
|
320
|
-
if (sub.tenantId !== tid)
|
|
321
|
-
continue;
|
|
353
|
+
if (sub.tenantId !== tid) continue;
|
|
322
354
|
await this._pushUpdate(client, sub);
|
|
323
355
|
}
|
|
324
356
|
}
|
|
325
|
-
for (const id of dead)
|
|
326
|
-
this.clients.delete(id);
|
|
357
|
+
for (const id of dead) this.clients.delete(id);
|
|
327
358
|
}
|
|
328
359
|
get clientCount() {
|
|
329
360
|
return this.clients.size;
|
|
330
361
|
}
|
|
362
|
+
// -------------------------------------------------------------------------
|
|
363
|
+
// Private
|
|
364
|
+
// -------------------------------------------------------------------------
|
|
331
365
|
async _handleSubscribe(client, subId, queryStr, tenantId) {
|
|
332
366
|
const tid = tenantId ?? client.tenantId ?? null;
|
|
333
367
|
let parsedQuery;
|
|
@@ -392,9 +426,10 @@ class SubscriptionManager {
|
|
|
392
426
|
_send(client, payload) {
|
|
393
427
|
try {
|
|
394
428
|
client.ws.send(JSON.stringify(payload));
|
|
395
|
-
} catch {
|
|
429
|
+
} catch {
|
|
430
|
+
}
|
|
396
431
|
}
|
|
397
|
-
}
|
|
432
|
+
};
|
|
398
433
|
function entityId(row) {
|
|
399
434
|
return String(row["?e"] ?? row.id ?? row.e ?? JSON.stringify(row));
|
|
400
435
|
}
|
|
@@ -412,31 +447,20 @@ function computeDiff(prev, next) {
|
|
|
412
447
|
}
|
|
413
448
|
}
|
|
414
449
|
for (const [id, row] of prevMap) {
|
|
415
|
-
if (!nextMap.has(id))
|
|
416
|
-
removed.push(row);
|
|
450
|
+
if (!nextMap.has(id)) removed.push(row);
|
|
417
451
|
}
|
|
418
452
|
return { added, updated, removed };
|
|
419
453
|
}
|
|
420
454
|
|
|
421
455
|
// src/server/server.ts
|
|
422
456
|
var __moduleDir = import.meta.dir ?? dirname(fileURLToPath(import.meta.url));
|
|
423
|
-
function startServer(opts) {
|
|
424
|
-
return startServerBun(opts);
|
|
425
|
-
}
|
|
426
|
-
async function startServerCrossRuntime(opts) {
|
|
427
|
-
if (typeof globalThis.Bun !== "undefined") {
|
|
428
|
-
const bunServer = startServerBun(opts);
|
|
429
|
-
return {
|
|
430
|
-
port: bunServer.port ?? opts.port ?? opts.config.port ?? 3000,
|
|
431
|
-
hostname: bunServer.hostname,
|
|
432
|
-
stop: (closeActive) => bunServer.stop(closeActive)
|
|
433
|
-
};
|
|
434
|
-
}
|
|
457
|
+
async function startServer(opts) {
|
|
435
458
|
return startServerNode(opts);
|
|
436
459
|
}
|
|
460
|
+
var startServerCrossRuntime = startServer;
|
|
437
461
|
function buildServerContext(opts) {
|
|
438
462
|
const { pool, permissions, config } = opts;
|
|
439
|
-
const port = opts.port ?? config.port ??
|
|
463
|
+
const port = opts.port ?? config.port ?? 3e3;
|
|
440
464
|
const authConfig = {
|
|
441
465
|
jwtSecret: config.jwtSecret,
|
|
442
466
|
apiKey: config.apiKey,
|
|
@@ -446,7 +470,10 @@ function buildServerContext(opts) {
|
|
|
446
470
|
const handleHttp = async (req) => {
|
|
447
471
|
const url = new URL(req.url);
|
|
448
472
|
const path = url.pathname;
|
|
449
|
-
const auth = await resolveAuth(
|
|
473
|
+
const auth = await resolveAuth(
|
|
474
|
+
req.headers.get("authorization"),
|
|
475
|
+
authConfig
|
|
476
|
+
);
|
|
450
477
|
const tenantId = auth.tenantId ?? url.searchParams.get("tenantId") ?? null;
|
|
451
478
|
try {
|
|
452
479
|
return await route(req, url, path, auth, tenantId, {
|
|
@@ -467,42 +494,6 @@ function buildServerContext(opts) {
|
|
|
467
494
|
};
|
|
468
495
|
return { port, authConfig, subs, handleHttp };
|
|
469
496
|
}
|
|
470
|
-
function startServerBun(opts) {
|
|
471
|
-
const { port, subs, handleHttp } = buildServerContext(opts);
|
|
472
|
-
return Bun.serve({
|
|
473
|
-
port,
|
|
474
|
-
async fetch(req, server) {
|
|
475
|
-
if (req.headers.get("upgrade") === "websocket") {
|
|
476
|
-
const upgraded = server.upgrade(req, { data: undefined });
|
|
477
|
-
if (upgraded)
|
|
478
|
-
return;
|
|
479
|
-
return new Response("WebSocket upgrade failed", { status: 400 });
|
|
480
|
-
}
|
|
481
|
-
return handleHttp(req);
|
|
482
|
-
},
|
|
483
|
-
websocket: {
|
|
484
|
-
async open(ws) {
|
|
485
|
-
const id = crypto.randomUUID();
|
|
486
|
-
ws.__clientId = id;
|
|
487
|
-
subs.addClient(id, ws, {
|
|
488
|
-
userId: null,
|
|
489
|
-
tenantId: null,
|
|
490
|
-
roles: [],
|
|
491
|
-
claims: {},
|
|
492
|
-
authenticated: false
|
|
493
|
-
}, null);
|
|
494
|
-
},
|
|
495
|
-
async message(ws, raw) {
|
|
496
|
-
const id = ws.__clientId;
|
|
497
|
-
await subs.handleMessage(id, typeof raw === "string" ? raw : new TextDecoder().decode(raw));
|
|
498
|
-
},
|
|
499
|
-
close(ws) {
|
|
500
|
-
const id = ws.__clientId;
|
|
501
|
-
subs.removeClient(id);
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
497
|
async function startServerNode(opts) {
|
|
507
498
|
const { port, subs, handleHttp } = buildServerContext(opts);
|
|
508
499
|
const { startNodeServer } = await import("./server/node-adapter.js");
|
|
@@ -513,17 +504,25 @@ async function startServerNode(opts) {
|
|
|
513
504
|
open(ws) {
|
|
514
505
|
const id = crypto.randomUUID();
|
|
515
506
|
ws.__clientId = id;
|
|
516
|
-
subs.addClient(
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
507
|
+
subs.addClient(
|
|
508
|
+
id,
|
|
509
|
+
ws,
|
|
510
|
+
{
|
|
511
|
+
userId: null,
|
|
512
|
+
tenantId: null,
|
|
513
|
+
roles: [],
|
|
514
|
+
claims: {},
|
|
515
|
+
authenticated: false
|
|
516
|
+
},
|
|
517
|
+
null
|
|
518
|
+
);
|
|
523
519
|
},
|
|
524
520
|
async message(ws, raw) {
|
|
525
521
|
const id = ws.__clientId;
|
|
526
|
-
await subs.handleMessage(
|
|
522
|
+
await subs.handleMessage(
|
|
523
|
+
id,
|
|
524
|
+
typeof raw === "string" ? raw : raw.toString()
|
|
525
|
+
);
|
|
527
526
|
},
|
|
528
527
|
close(ws) {
|
|
529
528
|
const id = ws.__clientId;
|
|
@@ -537,7 +536,9 @@ async function route(req, url, path, auth, tenantId, ctx) {
|
|
|
537
536
|
if (method === "GET" && path === "/__trellis/inspector.js") {
|
|
538
537
|
const candidates = [
|
|
539
538
|
join(__moduleDir, "db", "inspector.js"),
|
|
539
|
+
// chunk lives in dist/, inspector in dist/db/
|
|
540
540
|
join(__moduleDir, "inspector.js")
|
|
541
|
+
// chunk lives in dist/db/, inspector alongside
|
|
541
542
|
];
|
|
542
543
|
for (const p of candidates) {
|
|
543
544
|
if (existsSync(p)) {
|
|
@@ -546,9 +547,12 @@ async function route(req, url, path, auth, tenantId, ctx) {
|
|
|
546
547
|
});
|
|
547
548
|
}
|
|
548
549
|
}
|
|
549
|
-
return new Response(
|
|
550
|
-
|
|
551
|
-
|
|
550
|
+
return new Response(
|
|
551
|
+
"/* Trellis DB Inspector: run `bun run build:inspector` first */",
|
|
552
|
+
{
|
|
553
|
+
headers: { "Content-Type": "application/javascript" }
|
|
554
|
+
}
|
|
555
|
+
);
|
|
552
556
|
}
|
|
553
557
|
if (method === "GET" && path === "/__trellis/trellis.css") {
|
|
554
558
|
const candidates = [
|
|
@@ -593,20 +597,16 @@ async function route(req, url, path, auth, tenantId, ctx) {
|
|
|
593
597
|
});
|
|
594
598
|
}
|
|
595
599
|
if (path === "/entities" || path === "/entities/") {
|
|
596
|
-
if (method === "POST")
|
|
597
|
-
|
|
598
|
-
if (method === "GET")
|
|
599
|
-
return handleList(url, auth, tenantId, ctx);
|
|
600
|
+
if (method === "POST") return handleCreate(req, auth, tenantId, ctx);
|
|
601
|
+
if (method === "GET") return handleList(url, auth, tenantId, ctx);
|
|
600
602
|
}
|
|
601
603
|
const entityMatch = path.match(/^\/entities\/([^/]+)$/);
|
|
602
604
|
if (entityMatch) {
|
|
603
605
|
const id = decodeURIComponent(entityMatch[1]);
|
|
604
|
-
if (method === "GET")
|
|
605
|
-
return handleRead(id, auth, tenantId, ctx);
|
|
606
|
+
if (method === "GET") return handleRead(id, auth, tenantId, ctx);
|
|
606
607
|
if (method === "PUT" || method === "PATCH")
|
|
607
608
|
return handleUpdate(req, id, auth, tenantId, ctx);
|
|
608
|
-
if (method === "DELETE")
|
|
609
|
-
return handleDelete(id, auth, tenantId, ctx);
|
|
609
|
+
if (method === "DELETE") return handleDelete(id, auth, tenantId, ctx);
|
|
610
610
|
}
|
|
611
611
|
if (method === "POST" && path === "/query") {
|
|
612
612
|
return handleQuery(req, auth, tenantId, ctx);
|
|
@@ -636,35 +636,35 @@ async function route(req, url, path, auth, tenantId, ctx) {
|
|
|
636
636
|
}
|
|
637
637
|
async function handleCreate(req, auth, tenantId, ctx) {
|
|
638
638
|
const body = await req.json();
|
|
639
|
-
if (!body.type)
|
|
640
|
-
return json({ error: "type is required" }, 400);
|
|
639
|
+
if (!body.type) return json({ error: "type is required" }, 400);
|
|
641
640
|
ctx.permissions?.assert(auth, body.type, "create");
|
|
642
641
|
const kernel = ctx.pool.get(tenantId);
|
|
643
642
|
const entityId2 = `${body.type.toLowerCase()}:${crypto.randomUUID()}`;
|
|
644
643
|
const attrs = {
|
|
645
644
|
...body.attributes
|
|
646
645
|
};
|
|
647
|
-
if (auth.userId)
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
646
|
+
if (auth.userId) attrs.createdBy = auth.userId;
|
|
647
|
+
if (auth.tenantId) attrs.tenantId = auth.tenantId;
|
|
648
|
+
const result = await kernel.createEntity(
|
|
649
|
+
entityId2,
|
|
650
|
+
body.type,
|
|
651
|
+
attrs,
|
|
652
|
+
body.links
|
|
653
|
+
);
|
|
652
654
|
await ctx.subs.notify(tenantId);
|
|
653
655
|
return json({ id: entityId2, op: result.op.hash }, 201);
|
|
654
656
|
}
|
|
655
657
|
async function handleRead(id, auth, tenantId, ctx) {
|
|
656
658
|
const kernel = ctx.pool.get(tenantId);
|
|
657
659
|
const entity = kernel.getEntity(id);
|
|
658
|
-
if (!entity)
|
|
659
|
-
return json({ error: "Not Found" }, 404);
|
|
660
|
+
if (!entity) return json({ error: "Not Found" }, 404);
|
|
660
661
|
ctx.permissions?.assert(auth, entity.type, "read", entity);
|
|
661
662
|
return json(entityToJson(entity));
|
|
662
663
|
}
|
|
663
664
|
async function handleUpdate(req, id, auth, tenantId, ctx) {
|
|
664
665
|
const kernel = ctx.pool.get(tenantId);
|
|
665
666
|
const entity = kernel.getEntity(id);
|
|
666
|
-
if (!entity)
|
|
667
|
-
return json({ error: "Not Found" }, 404);
|
|
667
|
+
if (!entity) return json({ error: "Not Found" }, 404);
|
|
668
668
|
ctx.permissions?.assert(auth, entity.type, "update", entity);
|
|
669
669
|
const updates = await req.json();
|
|
670
670
|
await kernel.updateEntity(id, updates);
|
|
@@ -674,21 +674,22 @@ async function handleUpdate(req, id, auth, tenantId, ctx) {
|
|
|
674
674
|
async function handleDelete(id, auth, tenantId, ctx) {
|
|
675
675
|
const kernel = ctx.pool.get(tenantId);
|
|
676
676
|
const entity = kernel.getEntity(id);
|
|
677
|
-
if (!entity)
|
|
678
|
-
return json({ error: "Not Found" }, 404);
|
|
677
|
+
if (!entity) return json({ error: "Not Found" }, 404);
|
|
679
678
|
ctx.permissions?.assert(auth, entity.type, "delete", entity);
|
|
680
679
|
await kernel.deleteEntity(id);
|
|
681
680
|
await ctx.subs.notify(tenantId);
|
|
682
681
|
return json({ id, deleted: true });
|
|
683
682
|
}
|
|
684
683
|
async function handleList(url, auth, tenantId, ctx) {
|
|
685
|
-
const type = url.searchParams.get("type") ??
|
|
684
|
+
const type = url.searchParams.get("type") ?? void 0;
|
|
686
685
|
const limit = parseInt(url.searchParams.get("limit") ?? "100");
|
|
687
686
|
const offset = parseInt(url.searchParams.get("offset") ?? "0");
|
|
688
687
|
const kernel = ctx.pool.get(tenantId);
|
|
689
688
|
let entities = kernel.listEntities(type);
|
|
690
689
|
if (ctx.permissions && type) {
|
|
691
|
-
entities = entities.filter(
|
|
690
|
+
entities = entities.filter(
|
|
691
|
+
(e) => ctx.permissions.check(auth, e.type, "read", e)
|
|
692
|
+
);
|
|
692
693
|
}
|
|
693
694
|
const page = entities.slice(offset, offset + limit);
|
|
694
695
|
return json({
|
|
@@ -700,8 +701,7 @@ async function handleList(url, auth, tenantId, ctx) {
|
|
|
700
701
|
}
|
|
701
702
|
async function handleQuery(req, auth, tenantId, ctx) {
|
|
702
703
|
const body = await req.json();
|
|
703
|
-
if (!body.query)
|
|
704
|
-
return json({ error: "query is required" }, 400);
|
|
704
|
+
if (!body.query) return json({ error: "query is required" }, 400);
|
|
705
705
|
let parsed;
|
|
706
706
|
try {
|
|
707
707
|
parsed = parseSimple(body.query);
|
|
@@ -735,9 +735,11 @@ async function handleFileDownload(hash, ctx, tenantId) {
|
|
|
735
735
|
const kernel = ctx.pool.get(tenantId);
|
|
736
736
|
const backend = kernel.getBackend();
|
|
737
737
|
const blob = backend.getBlob(hash);
|
|
738
|
-
if (!blob)
|
|
739
|
-
|
|
740
|
-
|
|
738
|
+
if (!blob) return json({ error: "Not Found" }, 404);
|
|
739
|
+
const cleanBuf = blob.buffer.slice(
|
|
740
|
+
blob.byteOffset,
|
|
741
|
+
blob.byteOffset + blob.byteLength
|
|
742
|
+
);
|
|
741
743
|
return new Response(cleanBuf, {
|
|
742
744
|
headers: { "Content-Type": "application/octet-stream" }
|
|
743
745
|
});
|
|
@@ -764,7 +766,10 @@ async function handleRegister(req, tenantId, ctx) {
|
|
|
764
766
|
role: "user",
|
|
765
767
|
...tenantId ? { tenantId } : {}
|
|
766
768
|
});
|
|
767
|
-
const token = await signJwt(
|
|
769
|
+
const token = await signJwt(
|
|
770
|
+
{ sub: userId, email: body.email, roles: ["user"], tenantId },
|
|
771
|
+
ctx.config.jwtSecret
|
|
772
|
+
);
|
|
768
773
|
return json({ token, userId }, 201);
|
|
769
774
|
}
|
|
770
775
|
async function handleLogin(req, tenantId, ctx) {
|
|
@@ -787,7 +792,10 @@ async function handleLogin(req, tenantId, ctx) {
|
|
|
787
792
|
return json({ error: "Invalid credentials" }, 401);
|
|
788
793
|
}
|
|
789
794
|
const role = String(roleFact?.v ?? "user");
|
|
790
|
-
const token = await signJwt(
|
|
795
|
+
const token = await signJwt(
|
|
796
|
+
{ sub: user.id, email: body.email, roles: [role], tenantId },
|
|
797
|
+
ctx.config.jwtSecret
|
|
798
|
+
);
|
|
791
799
|
return json({ token, userId: user.id });
|
|
792
800
|
}
|
|
793
801
|
function handleOAuthRedirect(providerName, url, ctx) {
|
|
@@ -804,8 +812,7 @@ async function handleOAuthCallback(url, providerName, tenantId, ctx) {
|
|
|
804
812
|
return json({ error: "Auth not configured (no jwtSecret)" }, 501);
|
|
805
813
|
}
|
|
806
814
|
const code = url.searchParams.get("code");
|
|
807
|
-
if (!code)
|
|
808
|
-
return json({ error: "Missing code" }, 400);
|
|
815
|
+
if (!code) return json({ error: "Missing code" }, 400);
|
|
809
816
|
const provider = ctx.oauthProviders[providerName] ?? getBuiltinProvider(providerName, ctx);
|
|
810
817
|
if (!provider)
|
|
811
818
|
return json({ error: `Unknown provider: ${providerName}` }, 400);
|
|
@@ -834,51 +841,71 @@ async function handleOAuthCallback(url, providerName, tenantId, ctx) {
|
|
|
834
841
|
} else {
|
|
835
842
|
userId = users[0].id;
|
|
836
843
|
}
|
|
837
|
-
const token = await signJwt(
|
|
844
|
+
const token = await signJwt(
|
|
845
|
+
{ sub: userId, email: profile.email, roles: ["user"], tenantId },
|
|
846
|
+
ctx.config.jwtSecret
|
|
847
|
+
);
|
|
838
848
|
return json({ token, userId });
|
|
839
849
|
}
|
|
840
850
|
function getBuiltinProvider(name, ctx) {
|
|
841
851
|
if (name === "google") {
|
|
842
852
|
const cid = process.env.GOOGLE_CLIENT_ID;
|
|
843
853
|
const csec = process.env.GOOGLE_CLIENT_SECRET;
|
|
844
|
-
if (!cid || !csec)
|
|
845
|
-
return null;
|
|
854
|
+
if (!cid || !csec) return null;
|
|
846
855
|
return { ...GOOGLE_PROVIDER, clientId: cid, clientSecret: csec };
|
|
847
856
|
}
|
|
848
857
|
if (name === "github") {
|
|
849
858
|
const cid = process.env.GITHUB_CLIENT_ID;
|
|
850
859
|
const csec = process.env.GITHUB_CLIENT_SECRET;
|
|
851
|
-
if (!cid || !csec)
|
|
852
|
-
return null;
|
|
860
|
+
if (!cid || !csec) return null;
|
|
853
861
|
return { ...GITHUB_PROVIDER, clientId: cid, clientSecret: csec };
|
|
854
862
|
}
|
|
855
863
|
return null;
|
|
856
864
|
}
|
|
857
865
|
async function hashPassword(password) {
|
|
858
866
|
const salt = crypto.randomUUID().replace(/-/g, "");
|
|
859
|
-
const enc = new TextEncoder;
|
|
860
|
-
const keyMat = await crypto.subtle.importKey(
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
+
const enc = new TextEncoder();
|
|
868
|
+
const keyMat = await crypto.subtle.importKey(
|
|
869
|
+
"raw",
|
|
870
|
+
enc.encode(password),
|
|
871
|
+
"PBKDF2",
|
|
872
|
+
false,
|
|
873
|
+
["deriveBits"]
|
|
874
|
+
);
|
|
875
|
+
const bits = await crypto.subtle.deriveBits(
|
|
876
|
+
{
|
|
877
|
+
name: "PBKDF2",
|
|
878
|
+
salt: enc.encode(salt),
|
|
879
|
+
iterations: 1e5,
|
|
880
|
+
hash: "SHA-256"
|
|
881
|
+
},
|
|
882
|
+
keyMat,
|
|
883
|
+
256
|
|
884
|
+
);
|
|
867
885
|
const hash = Array.from(new Uint8Array(bits)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
868
886
|
return `${salt}:${hash}`;
|
|
869
887
|
}
|
|
870
888
|
async function verifyPassword(password, stored) {
|
|
871
889
|
const [salt, expectedHash] = stored.split(":");
|
|
872
|
-
if (!salt || !expectedHash)
|
|
873
|
-
|
|
874
|
-
const
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
890
|
+
if (!salt || !expectedHash) return false;
|
|
891
|
+
const enc = new TextEncoder();
|
|
892
|
+
const keyMat = await crypto.subtle.importKey(
|
|
893
|
+
"raw",
|
|
894
|
+
enc.encode(password),
|
|
895
|
+
"PBKDF2",
|
|
896
|
+
false,
|
|
897
|
+
["deriveBits"]
|
|
898
|
+
);
|
|
899
|
+
const bits = await crypto.subtle.deriveBits(
|
|
900
|
+
{
|
|
901
|
+
name: "PBKDF2",
|
|
902
|
+
salt: enc.encode(salt),
|
|
903
|
+
iterations: 1e5,
|
|
904
|
+
hash: "SHA-256"
|
|
905
|
+
},
|
|
906
|
+
keyMat,
|
|
907
|
+
256
|
|
908
|
+
);
|
|
882
909
|
const hash = Array.from(new Uint8Array(bits)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
883
910
|
return hash === expectedHash;
|
|
884
911
|
}
|
|
@@ -898,4 +925,22 @@ function json(data, status = 200) {
|
|
|
898
925
|
});
|
|
899
926
|
}
|
|
900
927
|
|
|
901
|
-
export {
|
|
928
|
+
export {
|
|
929
|
+
ANONYMOUS,
|
|
930
|
+
signJwt,
|
|
931
|
+
verifyJwt,
|
|
932
|
+
resolveAuth,
|
|
933
|
+
GOOGLE_PROVIDER,
|
|
934
|
+
GITHUB_PROVIDER,
|
|
935
|
+
buildOAuthUrl,
|
|
936
|
+
exchangeOAuthCode,
|
|
937
|
+
PermissionRegistry,
|
|
938
|
+
PermissionError,
|
|
939
|
+
PUBLIC_READ,
|
|
940
|
+
FULLY_PUBLIC,
|
|
941
|
+
OWNER_ONLY,
|
|
942
|
+
ADMIN_ONLY,
|
|
943
|
+
SubscriptionManager,
|
|
944
|
+
startServer,
|
|
945
|
+
startServerCrossRuntime
|
|
946
|
+
};
|