okengine 0.2.6 → 0.3.2
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/AGENTS.md +33 -30
- package/README.md +74 -340
- package/{spec/manifest.v1.schema.json → manifest.v1.schema.json} +40 -9
- package/package.json +47 -44
- package/site/content/docs/ai/llms-txt.mdx +54 -0
- package/site/content/docs/ai/mcp.mdx +123 -0
- package/site/content/docs/ai/meta.json +5 -0
- package/site/content/docs/ai/skills.mdx +53 -0
- package/site/content/docs/console/access.mdx +29 -0
- package/site/content/docs/console/ai.mdx +35 -0
- package/site/content/docs/console/architecture.mdx +35 -0
- package/site/content/docs/console/channels.mdx +37 -0
- package/site/content/docs/console/clock.mdx +31 -0
- package/site/content/docs/console/flows.mdx +31 -0
- package/site/content/docs/console/gates.mdx +35 -0
- package/site/content/docs/console/manifest-diff.mdx +34 -0
- package/site/content/docs/console/meta.json +23 -0
- package/site/content/docs/console/overview.mdx +40 -0
- package/site/content/docs/console/plugins.mdx +41 -0
- package/site/content/docs/console/privacy.mdx +32 -0
- package/site/content/docs/console/runs.mdx +40 -0
- package/site/content/docs/console/signals.mdx +31 -0
- package/site/content/docs/console/store.mdx +32 -0
- package/site/content/docs/console/tenancy.mdx +32 -0
- package/site/content/docs/console/traces.mdx +34 -0
- package/site/content/docs/console/vault.mdx +37 -0
- package/site/content/docs/elements/ai.mdx +180 -0
- package/site/content/docs/elements/channel.mdx +167 -0
- package/site/content/docs/elements/clock.mdx +182 -0
- package/site/content/docs/elements/flow.mdx +288 -0
- package/site/content/docs/elements/gate.mdx +171 -0
- package/site/content/docs/elements/meta.json +5 -0
- package/site/content/docs/elements/signal.mdx +171 -0
- package/site/content/docs/elements/store.mdx +320 -0
- package/site/content/docs/elements/vault.mdx +263 -0
- package/site/content/docs/get-started/basic-usage.mdx +124 -0
- package/site/content/docs/get-started/comparison.mdx +65 -0
- package/site/content/docs/get-started/installation.mdx +113 -0
- package/site/content/docs/get-started/introduction.mdx +123 -0
- package/site/content/docs/get-started/meta.json +5 -0
- package/site/content/docs/index.mdx +63 -0
- package/site/content/docs/meta.json +5 -0
- package/site/content/docs/plugins/compression.mdx +60 -0
- package/site/content/docs/plugins/cors.mdx +92 -0
- package/site/content/docs/plugins/csrf.mdx +96 -0
- package/site/content/docs/plugins/ip-allowlist.mdx +92 -0
- package/site/content/docs/plugins/maintenance-mode.mdx +101 -0
- package/site/content/docs/plugins/meta.json +15 -0
- package/site/content/docs/plugins/security-headers.mdx +136 -0
- package/site/content/docs/reference/cli.md +101 -0
- package/site/content/docs/reference/configuration.mdx +159 -0
- package/site/content/docs/reference/environment-variables.mdx +87 -0
- package/site/content/docs/reference/errors.mdx +80 -0
- package/site/content/docs/reference/fx.mdx +117 -0
- package/site/content/docs/reference/meta.json +5 -0
- package/site/content/docs/reference/plugins.mdx +249 -0
- package/site/content/docs/reference/security.md +63 -0
- package/src/auth/api-keys.ts +2 -5
- package/src/auth/attenuation.ts +2 -6
- package/src/auth/auth.test.ts +56 -31
- package/src/auth/invoke-as.ts +1 -3
- package/src/auth/operator.ts +8 -26
- package/src/auth/planes.ts +2 -7
- package/src/auth/plugin.ts +4 -7
- package/src/auth/roles.ts +1 -5
- package/src/auth/sessions.ts +10 -39
- package/src/cli/args.ts +1 -5
- package/src/cli/ask-dev-mode.ts +40 -0
- package/src/cli/build.ts +1 -2
- package/src/cli/client-add.test.ts +8 -15
- package/src/cli/client-add.ts +5 -14
- package/src/cli/completion.test.ts +1 -5
- package/src/cli/completion.ts +4 -17
- package/src/cli/db-auto-push.test.ts +64 -0
- package/src/cli/db-auto-push.ts +72 -0
- package/src/cli/db.test.ts +189 -0
- package/src/cli/db.ts +456 -0
- package/src/cli/dev-app-runner.ts +2 -8
- package/src/cli/dev-db-push.test.ts +193 -0
- package/src/cli/dev-mode.test.ts +45 -0
- package/src/cli/dev-mode.ts +78 -0
- package/src/cli/dev-schema-sync.test.ts +66 -0
- package/src/cli/dev-schema-sync.ts +139 -0
- package/src/cli/dev.test.ts +264 -15
- package/src/cli/dev.ts +355 -139
- package/src/cli/doc-staleness.test.ts +69 -0
- package/src/cli/docker-cli.test.ts +27 -8
- package/src/cli/docker.ts +11 -3
- package/src/cli/doctor-diff.test.ts +1 -5
- package/src/cli/doctor-diff.ts +17 -46
- package/src/cli/doctor-pii.ts +2 -7
- package/src/cli/doctor.test.ts +26 -4
- package/src/cli/doctor.ts +35 -11
- package/src/cli/drizzle-env.test.ts +67 -0
- package/src/cli/drizzle-env.ts +78 -0
- package/src/cli/ensure-drizzle-config.ts +50 -0
- package/src/cli/eval.ts +4 -14
- package/src/cli/gates-list.ts +1 -4
- package/src/cli/hero-meta.test.ts +17 -19
- package/src/cli/hero-meta.ts +20 -30
- package/src/cli/images.ts +3 -8
- package/src/cli/index.ts +11 -2
- package/src/cli/load-config.images.test.ts +14 -14
- package/src/cli/load-config.ts +47 -47
- package/src/cli/mcp-from-console.ts +1 -4
- package/src/cli/mode.ts +65 -0
- package/src/cli/openbao-bootstrap.test.ts +147 -0
- package/src/cli/openbao-bootstrap.ts +280 -0
- package/src/cli/openbao-restart.integration.test.ts +136 -0
- package/src/cli/ports.test.ts +7 -14
- package/src/cli/ports.ts +7 -5
- package/src/cli/privacy-erase.ts +1 -3
- package/src/cli/registry.ts +75 -25
- package/src/cli/resolve-dev-sql-env.test.ts +48 -0
- package/src/cli/resolve-dev-sql-env.ts +42 -0
- package/src/cli/schema.ts +3 -10
- package/src/cli/stack.ts +8 -10
- package/src/cli/start.ts +4 -15
- package/src/cli/upgrade.ts +1 -4
- package/src/cli/vault-cmd.ts +63 -0
- package/src/client/budget-entry.ts +1 -6
- package/src/client/create.test.ts +6 -12
- package/src/client/create.ts +2 -8
- package/src/client/errors.ts +1 -4
- package/src/client/index.ts +1 -6
- package/src/client/notes-contract.test.ts +4 -13
- package/src/client/transport.ts +9 -30
- package/src/client/types.ts +15 -30
- package/src/compiler/aot.test.ts +2 -9
- package/src/compiler/aot.ts +1 -4
- package/src/compiler/differential.test.ts +3 -11
- package/src/compiler/dynamic.ts +1 -4
- package/src/compiler/effects-infer.ts +8 -34
- package/src/compiler/emit.ts +1 -3
- package/src/compiler/extract.test.ts +136 -30
- package/src/compiler/extract.ts +485 -157
- package/src/compiler/fixtures/skyport/oke.config.ts +3 -3
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +7 -3
- package/src/compiler/fixtures/skyport/src/flows/payments/index.ts +1 -3
- package/src/compiler/fixtures/skyport/src/flows/support/index.ts +4 -1
- package/src/compiler/fixtures/skyport.expected.json +24 -83
- package/src/compiler/fixtures/triggers/five-triggers.ts +1 -2
- package/src/compiler/http-parse.ts +2 -9
- package/src/compiler/index.ts +1 -5
- package/src/compiler/response.ts +16 -7
- package/src/compiler/sucrose.ts +11 -31
- package/src/config/define-config.test.ts +55 -34
- package/src/config/index.ts +177 -46
- package/src/config/resolve-driver.test.ts +28 -17
- package/src/console/budget.test.ts +1 -4
- package/src/console/index.ts +1 -4
- package/src/console/server/access.test.ts +15 -43
- package/src/console/server/access.ts +19 -49
- package/src/console/server/ai.test.ts +3 -11
- package/src/console/server/ai.ts +23 -46
- package/src/console/server/app.ts +16 -45
- package/src/console/server/auth-rate.test.ts +4 -12
- package/src/console/server/bind.ts +1 -5
- package/src/console/server/channels.test.ts +2 -6
- package/src/console/server/channels.ts +10 -35
- package/src/console/server/claim.ts +2 -8
- package/src/console/server/clock.test.ts +2 -6
- package/src/console/server/clock.ts +8 -26
- package/src/console/server/console.test.ts +1 -3
- package/src/console/server/diff.test.ts +5 -17
- package/src/console/server/diff.ts +10 -31
- package/src/console/server/dry-run.audit.test.ts +2 -8
- package/src/console/server/flows.ts +64 -233
- package/src/console/server/gates.test.ts +14 -50
- package/src/console/server/gates.ts +13 -48
- package/src/console/server/index.ts +2 -9
- package/src/console/server/live.ts +3 -12
- package/src/console/server/operator-db.test.ts +4 -15
- package/src/console/server/operator-db.ts +13 -32
- package/src/console/server/plugin.ts +50 -53
- package/src/console/server/plugins.test.ts +2 -6
- package/src/console/server/plugins.ts +17 -56
- package/src/console/server/runs-pii.ts +2 -7
- package/src/console/server/security.gate.test.ts +18 -40
- package/src/console/server/serve.ts +10 -25
- package/src/console/server/signals.test.ts +1 -3
- package/src/console/server/signals.ts +17 -40
- package/src/console/server/state.ts +21 -59
- package/src/console/server/store.test.ts +20 -22
- package/src/console/server/store.ts +31 -76
- package/src/console/server/vault.test.ts +12 -29
- package/src/console/server/vault.ts +44 -66
- package/src/console/ui/access/AccessA11yView.tsx +6 -21
- package/src/console/ui/access/a11y.test.tsx +3 -12
- package/src/console/ui/access/acknowledgement.test.ts +1 -4
- package/src/console/ui/access/acknowledgement.ts +1 -3
- package/src/console/ui/access/blast-radius.ts +1 -3
- package/src/console/ui/access/confirmation.test.ts +1 -5
- package/src/console/ui/access/confirmation.ts +1 -4
- package/src/console/ui/access/fixture.ts +1 -5
- package/src/console/ui/access/grantable.test.ts +1 -3
- package/src/console/ui/access/grantable.ts +2 -7
- package/src/console/ui/access/index.ts +2 -9
- package/src/console/ui/access/provenance.test.ts +1 -3
- package/src/console/ui/access/provenance.ts +2 -6
- package/src/console/ui/access/search.test.ts +1 -5
- package/src/console/ui/access/search.ts +2 -6
- package/src/console/ui/ai/AiA11yView.tsx +6 -17
- package/src/console/ui/ai/a11y.test.tsx +2 -5
- package/src/console/ui/ai/fixture.ts +2 -7
- package/src/console/ui/ai/format.ts +1 -3
- package/src/console/ui/ai/group.test.ts +1 -3
- package/src/console/ui/ai/group.ts +4 -12
- package/src/console/ui/ai/index.ts +2 -9
- package/src/console/ui/ai/promotion.test.ts +2 -7
- package/src/console/ui/ai/promotion.ts +4 -13
- package/src/console/ui/ai/search.test.ts +2 -11
- package/src/console/ui/ai/search.ts +3 -13
- package/src/console/ui/ai/types.ts +1 -8
- package/src/console/ui/architecture/ArchitectureA11yView.tsx +8 -29
- package/src/console/ui/architecture/a11y.test.tsx +1 -2
- package/src/console/ui/architecture/declared.ts +1 -5
- package/src/console/ui/architecture/index.ts +7 -35
- package/src/console/ui/architecture/layout.ts +1 -3
- package/src/console/ui/architecture/pathologies.ts +10 -19
- package/src/console/ui/architecture/search.ts +6 -15
- package/src/console/ui/architecture/traffic.ts +4 -14
- package/src/console/ui/architecture/types.ts +2 -10
- package/src/console/ui/architecture/view.test.ts +7 -19
- package/src/console/ui/architecture/view.ts +9 -36
- package/src/console/ui/channels/ChannelsA11yView.tsx +4 -13
- package/src/console/ui/channels/a11y.test.tsx +1 -2
- package/src/console/ui/channels/confirmation.test.ts +1 -4
- package/src/console/ui/channels/confirmation.ts +1 -4
- package/src/console/ui/channels/findings.ts +1 -5
- package/src/console/ui/channels/index.ts +2 -8
- package/src/console/ui/channels/locale.test.ts +1 -3
- package/src/console/ui/channels/locale.ts +2 -8
- package/src/console/ui/channels/search.ts +4 -13
- package/src/console/ui/channels/taxonomy.ts +1 -3
- package/src/console/ui/clock/ClockA11yView.tsx +9 -26
- package/src/console/ui/clock/a11y.test.tsx +2 -5
- package/src/console/ui/clock/confirmation.test.ts +1 -3
- package/src/console/ui/clock/confirmation.ts +1 -4
- package/src/console/ui/clock/findings.ts +1 -4
- package/src/console/ui/clock/health.ts +2 -7
- package/src/console/ui/clock/index.ts +2 -10
- package/src/console/ui/clock/search.test.ts +1 -3
- package/src/console/ui/clock/search.ts +2 -6
- package/src/console/ui/clock/timeline.test.ts +1 -3
- package/src/console/ui/clock/waiting-on.test.ts +1 -5
- package/src/console/ui/clock/waiting-on.ts +2 -7
- package/src/console/ui/diff/DiffA11yView.tsx +8 -17
- package/src/console/ui/diff/a11y.test.tsx +2 -5
- package/src/console/ui/diff/group.test.ts +3 -13
- package/src/console/ui/diff/group.ts +2 -8
- package/src/console/ui/diff/index.ts +2 -8
- package/src/console/ui/diff/search.test.ts +1 -5
- package/src/console/ui/diff/search.ts +4 -16
- package/src/console/ui/diff/summary.ts +1 -2
- package/src/console/ui/dist/assets/{index-Dy4jht9P.js → index-BWo8R7NR.js} +2 -2
- package/src/console/ui/dist/assets/{panel-access-Dd37LU2c.js → panel-access-C0J2D-a2.js} +1 -1
- package/src/console/ui/dist/assets/{panel-ai-CC7LR6-J.js → panel-ai-D_m6WQI8.js} +1 -1
- package/src/console/ui/dist/assets/{panel-architecture-B5b3iKCz.js → panel-architecture-CKnXFyUx.js} +1 -1
- package/src/console/ui/dist/assets/{panel-channels-CeNjTKXp.js → panel-channels-BOmQ-onL.js} +1 -1
- package/src/console/ui/dist/assets/{panel-clock-DgFTLoHV.js → panel-clock-giAq0Ccv.js} +1 -1
- package/src/console/ui/dist/assets/{panel-diff-DxehccqB.js → panel-diff-cdonmH8c.js} +1 -1
- package/src/console/ui/dist/assets/{panel-flows-BtrVn-Eg.js → panel-flows-DlCU5zjA.js} +2 -2
- package/src/console/ui/dist/assets/{panel-gates-Z9MKRGdH.js → panel-gates-XclZxWD5.js} +1 -1
- package/src/console/ui/dist/assets/{panel-overview-Dt_AeXgd.js → panel-overview-BznEOTnb.js} +1 -1
- package/src/console/ui/dist/assets/{panel-plugins-DWd0TowH.js → panel-plugins-CcGM1g64.js} +1 -1
- package/src/console/ui/dist/assets/{panel-runs-DGstFHeq.js → panel-runs-CGWNHLR4.js} +1 -1
- package/src/console/ui/dist/assets/{panel-signals-DzEa2Fnt.js → panel-signals-CNywkdak.js} +1 -1
- package/src/console/ui/dist/assets/{panel-store-BJkbNgxx.js → panel-store-KmTbFHMH.js} +1 -1
- package/src/console/ui/dist/assets/{panel-traces-BaRVO3gM.js → panel-traces-DBLx2ilD.js} +1 -1
- package/src/console/ui/dist/assets/panel-vault-CEnFc0dk.js +1 -0
- package/src/console/ui/dist/index.html +1 -1
- package/src/console/ui/flows/FlowsA11yView.tsx +7 -22
- package/src/console/ui/flows/a11y.test.tsx +2 -8
- package/src/console/ui/flows/buffer.test.ts +3 -11
- package/src/console/ui/flows/buffer.ts +4 -11
- package/src/console/ui/flows/confirmation.ts +1 -3
- package/src/console/ui/flows/contract.test.ts +3 -7
- package/src/console/ui/flows/contract.ts +12 -36
- package/src/console/ui/flows/graph.test.ts +3 -11
- package/src/console/ui/flows/graph.ts +5 -15
- package/src/console/ui/flows/index.ts +1 -6
- package/src/console/ui/flows/save-as-test.ts +1 -3
- package/src/console/ui/flows/search.ts +8 -25
- package/src/console/ui/flows/tiers.ts +2 -9
- package/src/console/ui/gates/GatesA11yView.tsx +4 -13
- package/src/console/ui/gates/a11y.test.tsx +2 -5
- package/src/console/ui/gates/audit.ts +1 -3
- package/src/console/ui/gates/denial.test.ts +1 -3
- package/src/console/ui/gates/denial.ts +4 -12
- package/src/console/ui/gates/findings.ts +1 -3
- package/src/console/ui/gates/group.test.ts +3 -3
- package/src/console/ui/gates/group.ts +3 -11
- package/src/console/ui/gates/index.ts +2 -10
- package/src/console/ui/gates/search.ts +3 -10
- package/src/console/ui/overview/OverviewA11yView.tsx +9 -27
- package/src/console/ui/overview/a11y.test.tsx +1 -2
- package/src/console/ui/overview/busiest.ts +1 -3
- package/src/console/ui/overview/compose.ts +1 -13
- package/src/console/ui/overview/cost.ts +34 -38
- package/src/console/ui/overview/fixture.ts +21 -26
- package/src/console/ui/overview/golden.ts +4 -14
- package/src/console/ui/overview/index.ts +2 -9
- package/src/console/ui/overview/rank.test.ts +3 -10
- package/src/console/ui/overview/rank.ts +2 -7
- package/src/console/ui/overview/slo.test.ts +5 -9
- package/src/console/ui/overview/slo.ts +6 -23
- package/src/console/ui/overview/verdict.ts +3 -10
- package/src/console/ui/plugins/PluginsA11yView.tsx +8 -18
- package/src/console/ui/plugins/a11y.test.tsx +1 -2
- package/src/console/ui/plugins/fixture.ts +2 -4
- package/src/console/ui/plugins/group.test.ts +1 -3
- package/src/console/ui/plugins/group.ts +1 -6
- package/src/console/ui/plugins/index.ts +3 -13
- package/src/console/ui/plugins/search.ts +7 -19
- package/src/console/ui/runs/RunsA11yView.tsx +5 -20
- package/src/console/ui/runs/a11y.test.tsx +2 -5
- package/src/console/ui/runs/explain.ts +2 -6
- package/src/console/ui/runs/group.ts +3 -12
- package/src/console/ui/runs/histogram.test.ts +2 -11
- package/src/console/ui/runs/histogram.ts +1 -4
- package/src/console/ui/runs/index.ts +4 -18
- package/src/console/ui/runs/project.ts +2 -6
- package/src/console/ui/runs/query.test.ts +1 -3
- package/src/console/ui/runs/query.ts +12 -35
- package/src/console/ui/runs/search.ts +5 -19
- package/src/console/ui/runs/trace-link.test.ts +2 -6
- package/src/console/ui/runs/trace-link.ts +4 -16
- package/src/console/ui/runs/types.ts +1 -3
- package/src/console/ui/shell/App.tsx +2 -10
- package/src/console/ui/shell/client.ts +22 -115
- package/src/console/ui/shell/components/ui.tsx +1 -4
- package/src/console/ui/shell/layout/Shell.tsx +2 -4
- package/src/console/ui/shell/main.tsx +31 -96
- package/src/console/ui/shell/panels/access/AccessPanel.tsx +34 -98
- package/src/console/ui/shell/panels/ai/AiPanel.tsx +35 -106
- package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +18 -66
- package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +20 -57
- package/src/console/ui/shell/panels/clock/ClockPanel.tsx +22 -54
- package/src/console/ui/shell/panels/diff/DiffPanel.tsx +20 -61
- package/src/console/ui/shell/panels/flows/ContractEditor.tsx +6 -23
- package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +13 -28
- package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +9 -29
- package/src/console/ui/shell/panels/gates/GatesPanel.tsx +24 -80
- package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +20 -58
- package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +16 -41
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +31 -99
- package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +38 -101
- package/src/console/ui/shell/panels/store/StorePanel.tsx +27 -66
- package/src/console/ui/shell/panels/traces/TracesPanel.tsx +28 -89
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +22 -53
- package/src/console/ui/shell/setup/Wizard.tsx +3 -5
- package/src/console/ui/shell/styles.css +1 -2
- package/src/console/ui/signals/SignalsA11yView.tsx +9 -33
- package/src/console/ui/signals/a11y.test.tsx +2 -5
- package/src/console/ui/signals/confirmation.test.ts +1 -5
- package/src/console/ui/signals/confirmation.ts +2 -6
- package/src/console/ui/signals/dry-run.ts +1 -3
- package/src/console/ui/signals/durable.ts +1 -3
- package/src/console/ui/signals/findings.ts +1 -3
- package/src/console/ui/signals/group.test.ts +2 -8
- package/src/console/ui/signals/group.ts +2 -10
- package/src/console/ui/signals/index.ts +1 -4
- package/src/console/ui/signals/monitor.ts +2 -7
- package/src/console/ui/signals/schema-form.test.ts +3 -14
- package/src/console/ui/signals/schema-form.ts +1 -4
- package/src/console/ui/signals/search.ts +4 -13
- package/src/console/ui/store/StoreA11yView.tsx +3 -9
- package/src/console/ui/store/a11y.test.tsx +2 -5
- package/src/console/ui/store/confirmation.test.ts +1 -3
- package/src/console/ui/store/confirmation.ts +1 -4
- package/src/console/ui/store/dry-run.ts +2 -5
- package/src/console/ui/store/fixture.ts +1 -2
- package/src/console/ui/store/group.test.ts +1 -6
- package/src/console/ui/store/group.ts +1 -4
- package/src/console/ui/store/index.ts +1 -5
- package/src/console/ui/store/search.ts +2 -6
- package/src/console/ui/store/will-not-fire.ts +1 -2
- package/src/console/ui/traces/TracesA11yView.tsx +10 -29
- package/src/console/ui/traces/a11y.test.tsx +1 -2
- package/src/console/ui/traces/chain.test.ts +5 -19
- package/src/console/ui/traces/chain.ts +1 -3
- package/src/console/ui/traces/critical-path.test.ts +1 -3
- package/src/console/ui/traces/critical-path.ts +2 -6
- package/src/console/ui/traces/filter.test.ts +2 -6
- package/src/console/ui/traces/filter.ts +5 -13
- package/src/console/ui/traces/fold.test.ts +4 -12
- package/src/console/ui/traces/fold.ts +1 -3
- package/src/console/ui/traces/mini.ts +1 -3
- package/src/console/ui/traces/replay.test.ts +1 -3
- package/src/console/ui/traces/replay.ts +1 -3
- package/src/console/ui/traces/sampling.ts +1 -4
- package/src/console/ui/traces/search.ts +4 -17
- package/src/console/ui/traces/tier.ts +1 -3
- package/src/console/ui/vault/VaultA11yView.tsx +5 -17
- package/src/console/ui/vault/a11y.test.tsx +1 -2
- package/src/console/ui/vault/blast-radius.ts +1 -3
- package/src/console/ui/vault/confirmation.test.ts +1 -5
- package/src/console/ui/vault/confirmation.ts +1 -4
- package/src/console/ui/vault/dormant.test.ts +1 -4
- package/src/console/ui/vault/export-safe.test.ts +1 -5
- package/src/console/ui/vault/export-safe.ts +1 -4
- package/src/console/ui/vault/fixture.ts +3 -3
- package/src/console/ui/vault/group.ts +1 -2
- package/src/console/ui/vault/index.ts +2 -10
- package/src/console/ui/vault/search.ts +2 -6
- package/src/console/ui/vault/types.ts +1 -1
- package/src/console/xss.gate.test.ts +1 -3
- package/src/docker/compose.ts +215 -27
- package/src/docker/derive.ts +6 -14
- package/src/docker/docker.test.ts +118 -15
- package/src/docker/dockerfile.integration.test.ts +12 -21
- package/src/docker/helpers.ts +5 -4
- package/src/docker/index.ts +9 -6
- package/src/docker/pin.ts +1 -9
- package/src/docker/recipes/index.ts +6 -6
- package/src/docker/recipes/mailpit.ts +22 -0
- package/src/docker/recipes/openbao.ts +47 -0
- package/src/docker/recipes/postgres.ts +17 -6
- package/src/docker/recipes/redis.ts +11 -2
- package/src/docker/recipes/rustfs.ts +32 -0
- package/src/docker/stack-id.test.ts +73 -5
- package/src/docker/stack-id.ts +124 -33
- package/src/docker/stack.integration.test.ts +6 -21
- package/src/docker/stack.ts +36 -4
- package/src/docker/types.ts +16 -4
- package/src/docs-origin.ts +4 -4
- package/src/drivers/ai-anthropic.ts +5 -14
- package/src/drivers/ai-mock.ts +2 -5
- package/src/drivers/ai-openai-compatible.ts +4 -10
- package/src/drivers/ai-providers.test.ts +6 -13
- package/src/drivers/bun-native-completeness.test.ts +6 -15
- package/src/drivers/channel-console.ts +6 -7
- package/src/drivers/channel-fcm.ts +20 -30
- package/src/drivers/channel-resend.ts +1 -3
- package/src/drivers/channel-smtp.ts +2 -6
- package/src/drivers/channel-types.ts +2 -12
- package/src/drivers/channel-unifonic.ts +2 -6
- package/src/drivers/channel-wa-cloud.ts +2 -6
- package/src/drivers/channel-webpush.ts +21 -60
- package/src/drivers/conformance.test.ts +2 -10
- package/src/drivers/conformance.ts +8 -21
- package/src/drivers/drizzle-dialect.test.ts +20 -0
- package/src/drivers/drizzle-dialect.ts +37 -0
- package/src/drivers/fs.ts +2 -8
- package/src/drivers/index.ts +12 -57
- package/src/drivers/memory.ts +287 -75
- package/src/drivers/pgvector.ts +7 -11
- package/src/drivers/postgres.ts +7 -13
- package/src/drivers/redis.ts +13 -37
- package/src/drivers/s3.ts +15 -18
- package/src/drivers/signal-engine.ts +12 -49
- package/src/drivers/signal-memory.ts +2 -8
- package/src/drivers/signal-nats.ts +4 -9
- package/src/drivers/signal-postgres.ts +62 -129
- package/src/drivers/signal-redis.ts +7 -21
- package/src/drivers/signal-types.ts +1 -4
- package/src/drivers/sqlite.ts +3 -12
- package/src/drivers/types.ts +4 -23
- package/src/drivers/vault-driver-removal.test.ts +55 -0
- package/src/drivers/vault-env.ts +2 -6
- package/src/drivers/vault-infisical.ts +1 -5
- package/src/drivers/vault-managed.ts +1 -5
- package/src/drivers/vault-memory.ts +1 -5
- package/src/drivers/vault-openbao.test.ts +97 -0
- package/src/drivers/vault-openbao.ts +103 -40
- package/src/drivers/vault-types.ts +3 -16
- package/src/elements/ai/declare.ts +4 -14
- package/src/elements/ai/eval.ts +2 -6
- package/src/elements/ai/pii.ts +1 -3
- package/src/elements/ai/runtime.ts +12 -50
- package/src/elements/ai/schema.ts +4 -15
- package/src/elements/ai.test.ts +13 -24
- package/src/elements/ai.ts +1 -5
- package/src/elements/channel/consent.ts +3 -12
- package/src/elements/channel/costs.ts +4 -15
- package/src/elements/channel/declare.ts +1 -4
- package/src/elements/channel/email-auth.ts +1 -4
- package/src/elements/channel/locale.ts +2 -10
- package/src/elements/channel/mask.ts +1 -3
- package/src/elements/channel/mime.ts +2 -12
- package/src/elements/channel/outcomes.test.ts +1 -5
- package/src/elements/channel/outcomes.ts +5 -15
- package/src/elements/channel/receipts.ts +2 -7
- package/src/elements/channel/runtime.ts +28 -74
- package/src/elements/channel/suppression.ts +8 -14
- package/src/elements/channel.test.ts +8 -31
- package/src/elements/channel.ts +3 -14
- package/src/elements/clock/actions.ts +6 -18
- package/src/elements/clock/declare.ts +1 -3
- package/src/elements/clock/dst.ts +1 -5
- package/src/elements/clock/durable.ts +4 -16
- package/src/elements/clock/health.ts +2 -7
- package/src/elements/clock/leader.ts +2 -9
- package/src/elements/clock/reconcile.ts +4 -15
- package/src/elements/clock/runtime.ts +2 -5
- package/src/elements/clock/schedule.ts +4 -20
- package/src/elements/clock.test.ts +2 -7
- package/src/elements/clock.ts +5 -23
- package/src/elements/gate/permissions.ts +1 -4
- package/src/elements/gate/runtime.ts +7 -28
- package/src/elements/gate.ts +1 -5
- package/src/elements/index.ts +9 -7
- package/src/elements/signal/declare.ts +2 -7
- package/src/elements/signal/reconcile.test.ts +1 -4
- package/src/elements/signal/runtime.ts +1 -3
- package/src/elements/signal.test.ts +3 -15
- package/src/elements/signal.ts +2 -8
- package/src/elements/store/cache.test.ts +46 -0
- package/src/elements/store/cache.ts +3 -11
- package/src/elements/store/classify.ts +5 -22
- package/src/elements/store/declare.ts +11 -17
- package/src/elements/store/domain-ddl.test.ts +86 -0
- package/src/elements/store/emit-drizzle.ts +363 -0
- package/src/elements/store/files-policy.test.ts +1 -5
- package/src/elements/store/files-policy.ts +4 -12
- package/src/elements/store/load-plugin-tables.ts +103 -0
- package/src/elements/store/missing-relation.test.ts +83 -0
- package/src/elements/store/missing-relation.ts +38 -0
- package/src/elements/store/replica.ts +1 -4
- package/src/elements/store/resource-list-docs.fixture.ts +56 -0
- package/src/elements/store/resource-list-docs.test.ts +79 -0
- package/src/elements/store/resource.test.ts +253 -0
- package/src/elements/store/resource.ts +786 -0
- package/src/elements/store/runtime.ts +25 -28
- package/src/elements/store/schema-decl.test.ts +227 -0
- package/src/elements/store/schema-decl.ts +516 -0
- package/src/elements/store/sql-condition.test.ts +132 -0
- package/src/elements/store/sql-condition.ts +293 -65
- package/src/elements/store/sql-session.test.ts +135 -0
- package/src/elements/store/sql-session.ts +241 -84
- package/src/elements/store/table.ts +69 -23
- package/src/elements/store.test.ts +17 -39
- package/src/elements/store.ts +53 -31
- package/src/elements/vault/chain.ts +34 -0
- package/src/elements/vault/declare.ts +22 -32
- package/src/elements/vault/fingerprint.ts +2 -7
- package/src/elements/vault/redact.ts +2 -6
- package/src/elements/vault/runtime.ts +19 -33
- package/src/elements/vault.test.ts +12 -55
- package/src/elements/vault.ts +9 -13
- package/src/index.ts +5 -2
- package/src/kernel/adopt-routes.ts +15 -29
- package/src/kernel/app.ts +92 -118
- package/src/kernel/auth-resolve.ts +2 -9
- package/src/kernel/boot-bind/ai.ts +1 -4
- package/src/kernel/boot-bind/channel.test.ts +60 -0
- package/src/kernel/boot-bind/channel.ts +61 -5
- package/src/kernel/boot-bind/clock.ts +2 -6
- package/src/kernel/boot-bind/gate.ts +2 -8
- package/src/kernel/boot-bind/runs.ts +1 -3
- package/src/kernel/boot-bind/signal.ts +3 -10
- package/src/kernel/boot-bind/store.test.ts +27 -18
- package/src/kernel/boot-bind/store.ts +93 -52
- package/src/kernel/boot-bind/vault.ts +2 -8
- package/src/kernel/boot.test.ts +4 -10
- package/src/kernel/boot.ts +30 -77
- package/src/kernel/budget.test.ts +1 -3
- package/src/kernel/capability.ts +3 -10
- package/src/kernel/dry-run.test.ts +1 -4
- package/src/kernel/dry-run.ts +3 -11
- package/src/kernel/edge.test.ts +68 -0
- package/src/kernel/effects.test.ts +1 -5
- package/src/kernel/effects.ts +4 -11
- package/src/kernel/errors.registry.test.ts +2 -8
- package/src/kernel/errors.ts +23 -32
- package/src/kernel/flow.test.ts +12 -25
- package/src/kernel/flow.ts +13 -25
- package/src/kernel/fx.test.ts +31 -40
- package/src/kernel/fx.ts +135 -90
- package/src/kernel/hook-timing.test.ts +3 -6
- package/src/kernel/hook-timing.ts +5 -14
- package/src/kernel/hooks.test.ts +43 -10
- package/src/kernel/hooks.ts +25 -12
- package/src/kernel/index.ts +11 -17
- package/src/kernel/journal.ts +7 -31
- package/src/kernel/on.ts +45 -9
- package/src/kernel/pipeline.test.ts +10 -19
- package/src/kernel/pipeline.ts +5 -17
- package/src/kernel/plug.ts +4 -11
- package/src/kernel/plugin/conflicts.test.ts +13 -25
- package/src/kernel/plugin/decorate.test.ts +8 -13
- package/src/kernel/plugin/scoping.test.ts +4 -11
- package/src/kernel/plugin.ts +81 -27
- package/src/kernel/registry-isolation.test.ts +74 -0
- package/src/kernel/registry.ts +102 -30
- package/src/kernel/router.test.ts +15 -13
- package/src/kernel/router.ts +9 -29
- package/src/kernel/routing-budget.test.ts +1 -3
- package/src/kernel/run-telemetry.ts +1 -3
- package/src/kernel/triggers.ts +63 -21
- package/src/manifest/diff.test.ts +26 -91
- package/src/manifest/diff.ts +95 -225
- package/src/manifest/fixtures/skyport.excerpt.json +1 -1
- package/src/manifest/fixtures/skyport.manifest.json +1 -1
- package/src/manifest/index.ts +3 -10
- package/src/manifest/types.ts +30 -6
- package/src/manifest/undeclared.test.ts +4 -12
- package/src/manifest/undeclared.ts +1 -2
- package/src/manifest/validate.test.ts +2 -6
- package/src/manifest/validate.ts +5 -15
- package/src/mcp/authorization.ts +8 -27
- package/src/mcp/confirmation.ts +3 -10
- package/src/mcp/data.ts +2 -6
- package/src/mcp/docs-index.ts +4 -7
- package/src/mcp/docs-mcp.test.ts +3 -12
- package/src/mcp/docs-server.ts +7 -27
- package/src/mcp/docs-tools.ts +2 -6
- package/src/mcp/index.ts +1 -6
- package/src/mcp/injection.gate.test.ts +4 -18
- package/src/mcp/mcp.test.ts +18 -49
- package/src/mcp/protocol.ts +3 -10
- package/src/mcp/server.ts +11 -52
- package/src/mcp/session.ts +4 -14
- package/src/mcp/tools.ts +14 -50
- package/src/plugins/catalogue.test.ts +3 -7
- package/src/plugins/catalogue.ts +1 -3
- package/src/plugins/compression.test.ts +127 -0
- package/src/plugins/compression.ts +94 -0
- package/src/plugins/config-source.test.ts +204 -0
- package/src/plugins/config-source.ts +209 -0
- package/src/plugins/cors.test.ts +138 -0
- package/src/plugins/cors.ts +129 -0
- package/src/plugins/csrf.test.ts +102 -0
- package/src/plugins/csrf.ts +86 -0
- package/src/plugins/headers.ts +54 -0
- package/src/plugins/index.ts +26 -0
- package/src/plugins/ip-allowlist.test.ts +105 -0
- package/src/plugins/ip-allowlist.ts +76 -0
- package/src/plugins/maintenance-mode.test.ts +91 -0
- package/src/plugins/maintenance-mode.ts +85 -0
- package/src/plugins/node-import-scan.ts +2 -5
- package/src/plugins/security-headers.test.ts +243 -0
- package/src/plugins/security-headers.ts +255 -0
- package/src/plugins/supply-chain.ts +5 -17
- package/src/release/exports.ts +3 -8
- package/src/release/measure.exports.test.ts +1 -3
- package/src/release/measure.ts +16 -45
- package/src/runs/bench.test.ts +1 -3
- package/src/runs/collect.ts +8 -25
- package/src/runs/drivers/clickhouse.ts +2 -9
- package/src/runs/drivers/files.ts +9 -31
- package/src/runs/drivers/memory.ts +5 -22
- package/src/runs/drivers/postgres.ts +8 -20
- package/src/runs/duckdb.ts +2 -8
- package/src/runs/index.ts +3 -14
- package/src/runs/outlier.ts +3 -10
- package/src/runs/parquet.ts +8 -26
- package/src/runs/privacy.ts +2 -8
- package/src/runs/runs.test.ts +3 -9
- package/src/runs/runtime.ts +7 -32
- package/src/runs/shred.ts +10 -29
- package/src/runs/types.ts +1 -4
- package/src/runtime/bun.ts +4 -15
- package/src/runtime/cold-start.bench.ts +1 -3
- package/src/runtime/dev-request-log.test.ts +1 -4
- package/src/runtime/dev-request-log.ts +1 -4
- package/src/runtime/index.ts +1 -6
- package/src/runtime/primitives.ts +5 -4
- package/src/runtime/security.ts +3 -13
- package/src/runtime/serve.test.ts +4 -7
- package/src/runtime/types.ts +1 -4
- package/src/runtime/web-standard.ts +3 -15
- package/src/term.test.ts +4 -6
- package/src/term.ts +49 -98
- package/src/test/create-test-app.test.ts +4 -14
- package/src/test/create-test-app.ts +27 -33
- package/src/test/provisions.integration.test.ts +3 -11
- package/src/upgrade/codemods.test.ts +25 -6
- package/src/upgrade/codemods.ts +116 -3
- package/src/validation/standard-schema.test.ts +2 -5
- package/src/validation/standard-schema.ts +13 -33
- package/docs/spec/console.md +0 -739
- package/docs/spec/example.md +0 -1196
- package/docs/spec/four-applications.md +0 -1195
- package/docs/spec/unified-theory.md +0 -489
- package/src/cli/doc-drift.test.ts +0 -146
- package/src/cli/doc-drift.ts +0 -430
- package/src/cli/doctor-diff-examples.ts +0 -92
- package/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
- package/src/drivers/vault-sops.ts +0 -271
|
@@ -15,11 +15,7 @@ import { effectiveSchedule, type CronRow } from "./reconcile.ts";
|
|
|
15
15
|
* @param from - Inclusive start epoch-ms
|
|
16
16
|
* @param until - Exclusive end epoch-ms
|
|
17
17
|
*/
|
|
18
|
-
export function nextOccurrences(
|
|
19
|
-
row: CronRow,
|
|
20
|
-
from: number,
|
|
21
|
-
until: number,
|
|
22
|
-
): readonly number[] {
|
|
18
|
+
export function nextOccurrences(row: CronRow, from: number, until: number): readonly number[] {
|
|
23
19
|
if (row.status !== "active" && row.status !== "paused") return [];
|
|
24
20
|
if (until <= from) return [];
|
|
25
21
|
|
|
@@ -75,11 +71,7 @@ export function previousOccurrence(row: CronRow, at: number): number | null {
|
|
|
75
71
|
* @param from - Exclusive lower bound (usually lastRunAt)
|
|
76
72
|
* @param until - Inclusive upper bound (usually now)
|
|
77
73
|
*/
|
|
78
|
-
export function countMissedOccurrences(
|
|
79
|
-
row: CronRow,
|
|
80
|
-
from: number,
|
|
81
|
-
until: number,
|
|
82
|
-
): number {
|
|
74
|
+
export function countMissedOccurrences(row: CronRow, from: number, until: number): number {
|
|
83
75
|
if (until <= from) return 0;
|
|
84
76
|
const sched = effectiveSchedule(row);
|
|
85
77
|
if (sched.every) {
|
|
@@ -129,11 +121,7 @@ function nextCronOccurrences(
|
|
|
129
121
|
): readonly number[] {
|
|
130
122
|
const parsed = parseSimpleDaily(cron);
|
|
131
123
|
if (!parsed) {
|
|
132
|
-
if (
|
|
133
|
-
row.nextRunAt !== undefined &&
|
|
134
|
-
row.nextRunAt >= from &&
|
|
135
|
-
row.nextRunAt < until
|
|
136
|
-
) {
|
|
124
|
+
if (row.nextRunAt !== undefined && row.nextRunAt >= from && row.nextRunAt < until) {
|
|
137
125
|
return [row.nextRunAt];
|
|
138
126
|
}
|
|
139
127
|
return [];
|
|
@@ -202,11 +190,7 @@ function civilFiresOnDay(
|
|
|
202
190
|
for (let offsetMin = -14 * 60; offsetMin <= 14 * 60; offsetMin += 15) {
|
|
203
191
|
const utc = base + parsed.hour * 3_600_000 + parsed.minute * 60_000 - offsetMin * 60_000;
|
|
204
192
|
const local = zonedParts(utc, timezone);
|
|
205
|
-
if (
|
|
206
|
-
local.date === dateStr &&
|
|
207
|
-
local.hour === parsed.hour &&
|
|
208
|
-
local.minute === parsed.minute
|
|
209
|
-
) {
|
|
193
|
+
if (local.date === dateStr && local.hour === parsed.hour && local.minute === parsed.minute) {
|
|
210
194
|
if (parsed.dow !== undefined) {
|
|
211
195
|
const localDow = zonedDow(utc, timezone);
|
|
212
196
|
if (localDow !== parsed.dow) continue;
|
|
@@ -13,10 +13,7 @@ import { tmpdir } from "node:os";
|
|
|
13
13
|
import { join } from "node:path";
|
|
14
14
|
|
|
15
15
|
import { flow } from "../kernel/flow.ts";
|
|
16
|
-
import {
|
|
17
|
-
createFileJournalStore,
|
|
18
|
-
createMemoryJournalStore,
|
|
19
|
-
} from "../kernel/journal.ts";
|
|
16
|
+
import { createFileJournalStore, createMemoryJournalStore } from "../kernel/journal.ts";
|
|
20
17
|
import {
|
|
21
18
|
clock,
|
|
22
19
|
createClockRuntime,
|
|
@@ -340,9 +337,7 @@ describe("DST ambiguity", () => {
|
|
|
340
337
|
expect(detectDstAmbiguity("0 2 * * *", "UTC")).toBeNull();
|
|
341
338
|
|
|
342
339
|
// Noon is outside the transition window for US zones.
|
|
343
|
-
expect(
|
|
344
|
-
detectDstAmbiguity("0 12 * * *", "America/New_York", Date.UTC(2026, 0, 1)),
|
|
345
|
-
).toBeNull();
|
|
340
|
+
expect(detectDstAmbiguity("0 12 * * *", "America/New_York", Date.UTC(2026, 0, 1))).toBeNull();
|
|
346
341
|
});
|
|
347
342
|
|
|
348
343
|
test("reconcile attaches dstAmbiguity on the store row", async () => {
|
package/src/elements/clock.ts
CHANGED
|
@@ -15,10 +15,7 @@ export type { ClockDecl, ClockOptions } from "./clock/declare.ts";
|
|
|
15
15
|
|
|
16
16
|
export { parseDurationMs } from "./clock/duration.ts";
|
|
17
17
|
|
|
18
|
-
export {
|
|
19
|
-
detectDstAmbiguity,
|
|
20
|
-
type DstAmbiguity,
|
|
21
|
-
} from "./clock/dst.ts";
|
|
18
|
+
export { detectDstAmbiguity, type DstAmbiguity } from "./clock/dst.ts";
|
|
22
19
|
|
|
23
20
|
export {
|
|
24
21
|
tryAcquireLease,
|
|
@@ -38,10 +35,7 @@ export {
|
|
|
38
35
|
type ReconcileResult,
|
|
39
36
|
} from "./clock/reconcile.ts";
|
|
40
37
|
|
|
41
|
-
export {
|
|
42
|
-
createTimeTravel,
|
|
43
|
-
type TimeTravel,
|
|
44
|
-
} from "./clock/time-travel.ts";
|
|
38
|
+
export { createTimeTravel, type TimeTravel } from "./clock/time-travel.ts";
|
|
45
39
|
|
|
46
40
|
export {
|
|
47
41
|
createClockRuntime,
|
|
@@ -51,23 +45,11 @@ export {
|
|
|
51
45
|
type CronHandler,
|
|
52
46
|
} from "./clock/runtime.ts";
|
|
53
47
|
|
|
54
|
-
export {
|
|
55
|
-
runDurable,
|
|
56
|
-
type DurableResult,
|
|
57
|
-
type RunDurableOptions,
|
|
58
|
-
} from "./clock/durable.ts";
|
|
48
|
+
export { runDurable, type DurableResult, type RunDurableOptions } from "./clock/durable.ts";
|
|
59
49
|
|
|
60
|
-
export {
|
|
61
|
-
cronHealth,
|
|
62
|
-
type CatchUpPolicy,
|
|
63
|
-
type CronHealth,
|
|
64
|
-
} from "./clock/health.ts";
|
|
50
|
+
export { cronHealth, type CatchUpPolicy, type CronHealth } from "./clock/health.ts";
|
|
65
51
|
|
|
66
|
-
export {
|
|
67
|
-
nextOccurrences,
|
|
68
|
-
previousOccurrence,
|
|
69
|
-
countMissedOccurrences,
|
|
70
|
-
} from "./clock/schedule.ts";
|
|
52
|
+
export { nextOccurrences, previousOccurrence, countMissedOccurrences } from "./clock/schedule.ts";
|
|
71
53
|
|
|
72
54
|
export {
|
|
73
55
|
pauseCron,
|
|
@@ -81,10 +81,7 @@ function effectToAction(ref: string, op: "read" | "write"): string {
|
|
|
81
81
|
return `store.${facet}:${op}`;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
function collectEffects(
|
|
85
|
-
manifest: Manifest,
|
|
86
|
-
kind: "reads" | "writes",
|
|
87
|
-
): string[] {
|
|
84
|
+
function collectEffects(manifest: Manifest, kind: "reads" | "writes"): string[] {
|
|
88
85
|
const out: string[] = [];
|
|
89
86
|
for (const flow of Object.values(manifest.flows ?? {})) {
|
|
90
87
|
const list = flow.effects?.[kind];
|
|
@@ -8,11 +8,7 @@ import { takeRate } from "./strategies.ts";
|
|
|
8
8
|
|
|
9
9
|
/** KV surface required for rate gates. */
|
|
10
10
|
export interface GateKv {
|
|
11
|
-
eval<T = unknown>(
|
|
12
|
-
script: string,
|
|
13
|
-
keys: readonly string[],
|
|
14
|
-
args?: readonly string[],
|
|
15
|
-
): Promise<T>;
|
|
11
|
+
eval<T = unknown>(script: string, keys: readonly string[], args?: readonly string[]): Promise<T>;
|
|
16
12
|
}
|
|
17
13
|
|
|
18
14
|
/** Options for {@link createGateRuntime}. */
|
|
@@ -45,20 +41,14 @@ export interface GateRuntime {
|
|
|
45
41
|
* @param names - Gate names / rate ids
|
|
46
42
|
* @param ctx - Policy context
|
|
47
43
|
*/
|
|
48
|
-
check(
|
|
49
|
-
names: readonly string[],
|
|
50
|
-
ctx: GatePolicyContext,
|
|
51
|
-
): Promise<GateEvaluation[]>;
|
|
44
|
+
check(names: readonly string[], ctx: GatePolicyContext): Promise<GateEvaluation[]>;
|
|
52
45
|
/**
|
|
53
46
|
* Whether every gate in the chain allows.
|
|
54
47
|
*
|
|
55
48
|
* @param names - Gate names
|
|
56
49
|
* @param ctx - Policy context
|
|
57
50
|
*/
|
|
58
|
-
allow(
|
|
59
|
-
names: readonly string[],
|
|
60
|
-
ctx: GatePolicyContext,
|
|
61
|
-
): Promise<boolean>;
|
|
51
|
+
allow(names: readonly string[], ctx: GatePolicyContext): Promise<boolean>;
|
|
62
52
|
}
|
|
63
53
|
|
|
64
54
|
/**
|
|
@@ -66,19 +56,14 @@ export interface GateRuntime {
|
|
|
66
56
|
*
|
|
67
57
|
* @param options - Declarations + kv
|
|
68
58
|
*/
|
|
69
|
-
export function createGateRuntime(
|
|
70
|
-
options: CreateGateRuntimeOptions = {},
|
|
71
|
-
): GateRuntime {
|
|
59
|
+
export function createGateRuntime(options: CreateGateRuntimeOptions = {}): GateRuntime {
|
|
72
60
|
const map = new Map<string, GateDecl>();
|
|
73
61
|
for (const g of options.gates ?? []) {
|
|
74
62
|
map.set(g.name, g);
|
|
75
63
|
}
|
|
76
64
|
const now = options.now ?? (() => Date.now());
|
|
77
65
|
|
|
78
|
-
async function evaluateOne(
|
|
79
|
-
name: string,
|
|
80
|
-
ctx: GatePolicyContext,
|
|
81
|
-
): Promise<GateEvaluation> {
|
|
66
|
+
async function evaluateOne(name: string, ctx: GatePolicyContext): Promise<GateEvaluation> {
|
|
82
67
|
const decl = map.get(name);
|
|
83
68
|
if (!decl) {
|
|
84
69
|
return {
|
|
@@ -100,10 +85,7 @@ export function createGateRuntime(
|
|
|
100
85
|
return evaluateRate(decl, ctx);
|
|
101
86
|
}
|
|
102
87
|
|
|
103
|
-
async function evaluateRate(
|
|
104
|
-
decl: RateGateDecl,
|
|
105
|
-
ctx: GatePolicyContext,
|
|
106
|
-
): Promise<GateEvaluation> {
|
|
88
|
+
async function evaluateRate(decl: RateGateDecl, ctx: GatePolicyContext): Promise<GateEvaluation> {
|
|
107
89
|
if (!options.kv) {
|
|
108
90
|
return {
|
|
109
91
|
name: decl.name,
|
|
@@ -157,10 +139,7 @@ export function createGateRuntime(
|
|
|
157
139
|
};
|
|
158
140
|
}
|
|
159
141
|
|
|
160
|
-
function resolveSubject(
|
|
161
|
-
keyBy: string | undefined,
|
|
162
|
-
ctx: GatePolicyContext,
|
|
163
|
-
): string {
|
|
142
|
+
function resolveSubject(keyBy: string | undefined, ctx: GatePolicyContext): string {
|
|
164
143
|
switch (keyBy) {
|
|
165
144
|
case "user":
|
|
166
145
|
return ctx.auth.userId ?? ctx.meta?.userId ?? "anon";
|
package/src/elements/gate.ts
CHANGED
|
@@ -35,8 +35,4 @@ export {
|
|
|
35
35
|
type TakeRateOptions,
|
|
36
36
|
} from "./gate/strategies.ts";
|
|
37
37
|
|
|
38
|
-
export {
|
|
39
|
-
deriveModuleActions,
|
|
40
|
-
flowIdToAction,
|
|
41
|
-
formatGatesList,
|
|
42
|
-
} from "./gate/permissions.ts";
|
|
38
|
+
export { deriveModuleActions, flowIdToAction, formatGatesList } from "./gate/permissions.ts";
|
package/src/elements/index.ts
CHANGED
|
@@ -12,6 +12,9 @@ export {
|
|
|
12
12
|
id,
|
|
13
13
|
now,
|
|
14
14
|
defineTable,
|
|
15
|
+
field,
|
|
16
|
+
schemaTable,
|
|
17
|
+
schemaRelations,
|
|
15
18
|
createStoreRuntime,
|
|
16
19
|
createStoreCache,
|
|
17
20
|
computedCacheKey,
|
|
@@ -32,6 +35,9 @@ export type {
|
|
|
32
35
|
SqlStoreHandle,
|
|
33
36
|
TableHandle,
|
|
34
37
|
ColumnDef,
|
|
38
|
+
SchemaTableDecl,
|
|
39
|
+
SchemaColumnDecl,
|
|
40
|
+
SchemaRelationsDecl,
|
|
35
41
|
} from "./store.ts";
|
|
36
42
|
|
|
37
43
|
export { signal, createSignalRuntime } from "./signal.ts";
|
|
@@ -52,13 +58,7 @@ export {
|
|
|
52
58
|
detectDstAmbiguity,
|
|
53
59
|
parseDurationMs,
|
|
54
60
|
} from "./clock.ts";
|
|
55
|
-
export type {
|
|
56
|
-
ClockDecl,
|
|
57
|
-
ClockOptions,
|
|
58
|
-
ClockRuntime,
|
|
59
|
-
TimeTravel,
|
|
60
|
-
DurableResult,
|
|
61
|
-
} from "./clock.ts";
|
|
61
|
+
export type { ClockDecl, ClockOptions, ClockRuntime, TimeTravel, DurableResult } from "./clock.ts";
|
|
62
62
|
|
|
63
63
|
export {
|
|
64
64
|
gate,
|
|
@@ -86,6 +86,8 @@ export {
|
|
|
86
86
|
fingerprintSecretSync,
|
|
87
87
|
createSecretRedactor,
|
|
88
88
|
resolveLayerSource,
|
|
89
|
+
COMPOSE_ENV_REL,
|
|
90
|
+
resolveComposeEnvPath,
|
|
89
91
|
} from "./vault.ts";
|
|
90
92
|
export type {
|
|
91
93
|
VaultSecretDecl,
|
|
@@ -53,18 +53,13 @@ export interface SignalDecl<T = unknown> {
|
|
|
53
53
|
* @param name - Signal name
|
|
54
54
|
* @param options - Delivery physics and retry / DLQ policy
|
|
55
55
|
*/
|
|
56
|
-
export function signal<T = unknown>(
|
|
57
|
-
name: string,
|
|
58
|
-
options: SignalOptions,
|
|
59
|
-
): SignalDecl<T> {
|
|
56
|
+
export function signal<T = unknown>(name: string, options: SignalOptions): SignalDecl<T> {
|
|
60
57
|
if (
|
|
61
58
|
options.delivery !== "once" &&
|
|
62
59
|
options.delivery !== "broadcast" &&
|
|
63
60
|
options.delivery !== "live"
|
|
64
61
|
) {
|
|
65
|
-
throw new TypeError(
|
|
66
|
-
`signal("${name}"): delivery is mandatory (once | broadcast | live)`,
|
|
67
|
-
);
|
|
62
|
+
throw new TypeError(`signal("${name}"): delivery is mandatory (once | broadcast | live)`);
|
|
68
63
|
}
|
|
69
64
|
return {
|
|
70
65
|
name,
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
2
|
import { signal } from "./declare.ts";
|
|
3
|
-
import {
|
|
4
|
-
createMemorySignalConfigStore,
|
|
5
|
-
reconcileSignals,
|
|
6
|
-
} from "./reconcile.ts";
|
|
3
|
+
import { createMemorySignalConfigStore, reconcileSignals } from "./reconcile.ts";
|
|
7
4
|
|
|
8
5
|
describe("reconcileSignals", () => {
|
|
9
6
|
test("marks a removed signal orphaned without deleting it", async () => {
|
|
@@ -52,9 +52,7 @@ export interface SignalRuntime {
|
|
|
52
52
|
*
|
|
53
53
|
* @param options - Driver and bindings
|
|
54
54
|
*/
|
|
55
|
-
export function createSignalRuntime(
|
|
56
|
-
options: CreateSignalRuntimeOptions,
|
|
57
|
-
): SignalRuntime {
|
|
55
|
+
export function createSignalRuntime(options: CreateSignalRuntimeOptions): SignalRuntime {
|
|
58
56
|
const declarations = new Map<string, SignalDecl>();
|
|
59
57
|
let bus: SignalBus | null = null;
|
|
60
58
|
|
|
@@ -205,9 +205,7 @@ for (const { label, driver, setup } of drivers) {
|
|
|
205
205
|
attempt: 1,
|
|
206
206
|
});
|
|
207
207
|
expect(dlq[0]!.failures[0]!.message).toContain("boom-");
|
|
208
|
-
expect(dlq[0]!.failures.map((f) => f.attempt)).toEqual(
|
|
209
|
-
dlq[0]!.failures.map((_, i) => i + 1),
|
|
210
|
-
);
|
|
208
|
+
expect(dlq[0]!.failures.map((f) => f.attempt)).toEqual(dlq[0]!.failures.map((_, i) => i + 1));
|
|
211
209
|
});
|
|
212
210
|
});
|
|
213
211
|
}
|
|
@@ -303,12 +301,7 @@ describe("chaos — kill process mid-transaction", () => {
|
|
|
303
301
|
const durablePath = join(dir, "bus.json");
|
|
304
302
|
try {
|
|
305
303
|
const child = Bun.spawn({
|
|
306
|
-
cmd: [
|
|
307
|
-
"bun",
|
|
308
|
-
join(import.meta.dir, "signal/chaos-child.ts"),
|
|
309
|
-
durablePath,
|
|
310
|
-
"mid-txn",
|
|
311
|
-
],
|
|
304
|
+
cmd: ["bun", join(import.meta.dir, "signal/chaos-child.ts"), durablePath, "mid-txn"],
|
|
312
305
|
stdout: "pipe",
|
|
313
306
|
stderr: "pipe",
|
|
314
307
|
});
|
|
@@ -406,12 +399,7 @@ describe("chaos — kill process mid-transaction", () => {
|
|
|
406
399
|
const durablePath = join(dir, "bus.json");
|
|
407
400
|
try {
|
|
408
401
|
const child = Bun.spawn({
|
|
409
|
-
cmd: [
|
|
410
|
-
"bun",
|
|
411
|
-
join(import.meta.dir, "signal/chaos-child.ts"),
|
|
412
|
-
durablePath,
|
|
413
|
-
"commit",
|
|
414
|
-
],
|
|
402
|
+
cmd: ["bun", join(import.meta.dir, "signal/chaos-child.ts"), durablePath, "commit"],
|
|
415
403
|
stdout: "pipe",
|
|
416
404
|
stderr: "pipe",
|
|
417
405
|
});
|
package/src/elements/signal.ts
CHANGED
|
@@ -10,15 +10,9 @@ export { signal } from "./signal/declare.ts";
|
|
|
10
10
|
export type { SignalDecl, SignalOptions } from "./signal/declare.ts";
|
|
11
11
|
|
|
12
12
|
export { createSignalRuntime } from "./signal/runtime.ts";
|
|
13
|
-
export type {
|
|
14
|
-
CreateSignalRuntimeOptions,
|
|
15
|
-
SignalRuntime,
|
|
16
|
-
} from "./signal/runtime.ts";
|
|
13
|
+
export type { CreateSignalRuntimeOptions, SignalRuntime } from "./signal/runtime.ts";
|
|
17
14
|
|
|
18
|
-
export {
|
|
19
|
-
reconcileSignals,
|
|
20
|
-
createMemorySignalConfigStore,
|
|
21
|
-
} from "./signal/reconcile.ts";
|
|
15
|
+
export { reconcileSignals, createMemorySignalConfigStore } from "./signal/reconcile.ts";
|
|
22
16
|
export type {
|
|
23
17
|
SignalConfigRow,
|
|
24
18
|
SignalConfigStatus,
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tier-1 cache exactness lock — invalidation keys off declared resources.
|
|
3
|
+
*
|
|
4
|
+
* A write invalidates a cached read only when the written resource appears
|
|
5
|
+
* in that read's `effects.reads`. A read that recorded only its root table
|
|
6
|
+
* is NOT invalidated by a write to a related table — which is exactly why
|
|
7
|
+
* relational `with:` is not exposed through `fx` (silent staleness hazard).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { describe, expect, test } from "bun:test";
|
|
11
|
+
import type { Effects } from "../../manifest/types.ts";
|
|
12
|
+
import {
|
|
13
|
+
computedCacheKey,
|
|
14
|
+
createStoreCache,
|
|
15
|
+
isInvalidatedByWrite,
|
|
16
|
+
tier1KeysForReads,
|
|
17
|
+
} from "./cache.ts";
|
|
18
|
+
|
|
19
|
+
describe("tier-1 cache — exact per-resource invalidation (path b)", () => {
|
|
20
|
+
test("a write invalidates only reads that declared the written resource", () => {
|
|
21
|
+
const cache = createStoreCache();
|
|
22
|
+
|
|
23
|
+
// Root-only read — what a half-shipped `with:` expansion would record.
|
|
24
|
+
const rootOnly: Effects = { reads: ["sql:links"] };
|
|
25
|
+
const keys = tier1KeysForReads(rootOnly);
|
|
26
|
+
expect(keys).toEqual([computedCacheKey("sql:links")]);
|
|
27
|
+
|
|
28
|
+
cache.set({
|
|
29
|
+
tier: 1,
|
|
30
|
+
key: keys[0]!,
|
|
31
|
+
value: [{ id: "l1" }],
|
|
32
|
+
resources: ["sql:links"],
|
|
33
|
+
expiresAt: null,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// A write to the related table does not invalidate the root-only read.
|
|
37
|
+
expect(isInvalidatedByWrite(keys[0]!, { writes: ["sql:daily"] })).toBe(false);
|
|
38
|
+
expect(cache.invalidateFromEffects({ writes: ["sql:daily"] }).keys).toEqual([]);
|
|
39
|
+
expect(cache.get(keys[0]!)).toBeDefined();
|
|
40
|
+
|
|
41
|
+
// Exact match on the declared resource still invalidates.
|
|
42
|
+
expect(isInvalidatedByWrite(keys[0]!, { writes: ["sql:links"] })).toBe(true);
|
|
43
|
+
expect(cache.invalidateFromEffects({ writes: ["sql:links"] }).keys).toEqual(keys);
|
|
44
|
+
expect(cache.get(keys[0]!)).toBeUndefined();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -38,10 +38,7 @@ export interface InvalidationEvent {
|
|
|
38
38
|
* @param resource - Store resource ref
|
|
39
39
|
* @param dims - Optional dimension suffixes (e.g. `userId`)
|
|
40
40
|
*/
|
|
41
|
-
export function computedCacheKey(
|
|
42
|
-
resource: ResourceRef,
|
|
43
|
-
dims?: readonly string[],
|
|
44
|
-
): string {
|
|
41
|
+
export function computedCacheKey(resource: ResourceRef, dims?: readonly string[]): string {
|
|
45
42
|
if (!dims || dims.length === 0) return `computed:${resource}`;
|
|
46
43
|
return `computed:${resource}/${dims.join("/")}`;
|
|
47
44
|
}
|
|
@@ -57,9 +54,7 @@ export function tier1KeysForReads(
|
|
|
57
54
|
dimsByResource?: Readonly<Record<string, readonly string[]>>,
|
|
58
55
|
): string[] {
|
|
59
56
|
const reads = effects.reads ?? [];
|
|
60
|
-
return reads.map((resource) =>
|
|
61
|
-
computedCacheKey(resource, dimsByResource?.[resource]),
|
|
62
|
-
);
|
|
57
|
+
return reads.map((resource) => computedCacheKey(resource, dimsByResource?.[resource]));
|
|
63
58
|
}
|
|
64
59
|
|
|
65
60
|
/**
|
|
@@ -79,10 +74,7 @@ export function resourcesTouchedByWrites(effects: Effects): ResourceRef[] {
|
|
|
79
74
|
* @param key - Tier-1 cache key (`computed:…`)
|
|
80
75
|
* @param writeEffects - Effects of the writing flow
|
|
81
76
|
*/
|
|
82
|
-
export function isInvalidatedByWrite(
|
|
83
|
-
key: string,
|
|
84
|
-
writeEffects: Effects,
|
|
85
|
-
): boolean {
|
|
77
|
+
export function isInvalidatedByWrite(key: string, writeEffects: Effects): boolean {
|
|
86
78
|
if (!key.startsWith("computed:")) return false;
|
|
87
79
|
const body = key.slice("computed:".length);
|
|
88
80
|
const resource = body.split("/")[0] ?? "";
|
|
@@ -4,11 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { ColumnClassification } from "../../manifest/types.ts";
|
|
7
|
-
import {
|
|
8
|
-
classificationKey,
|
|
9
|
-
type ClassificationMap,
|
|
10
|
-
type SqlRow,
|
|
11
|
-
} from "../../drivers/types.ts";
|
|
7
|
+
import { classificationKey, type ClassificationMap, type SqlRow } from "../../drivers/types.ts";
|
|
12
8
|
|
|
13
9
|
/** Default mask token for PII columns when reveal is denied. */
|
|
14
10
|
export const PII_MASK = "[redacted]";
|
|
@@ -21,9 +17,7 @@ export const PII_MASK = "[redacted]";
|
|
|
21
17
|
*
|
|
22
18
|
* @param classification - Tags to attach
|
|
23
19
|
*/
|
|
24
|
-
export function classify(
|
|
25
|
-
classification: ColumnClassification,
|
|
26
|
-
): ColumnClassification {
|
|
20
|
+
export function classify(classification: ColumnClassification): ColumnClassification {
|
|
27
21
|
return { ...classification };
|
|
28
22
|
}
|
|
29
23
|
|
|
@@ -33,9 +27,7 @@ export function classify(
|
|
|
33
27
|
* @param tables - Per-table column classifications
|
|
34
28
|
*/
|
|
35
29
|
export function buildClassificationMap(
|
|
36
|
-
tables: Readonly<
|
|
37
|
-
Record<string, Readonly<Record<string, ColumnClassification>>>
|
|
38
|
-
>,
|
|
30
|
+
tables: Readonly<Record<string, Readonly<Record<string, ColumnClassification>>>>,
|
|
39
31
|
): ClassificationMap {
|
|
40
32
|
const map = new Map<string, ColumnClassification>();
|
|
41
33
|
for (const [table, cols] of Object.entries(tables)) {
|
|
@@ -90,10 +82,7 @@ export interface MaskRowsOptions {
|
|
|
90
82
|
* @param rows - Raw driver rows
|
|
91
83
|
* @param options - Classification + reveal policy
|
|
92
84
|
*/
|
|
93
|
-
export function maskRows(
|
|
94
|
-
rows: readonly SqlRow[],
|
|
95
|
-
options: MaskRowsOptions,
|
|
96
|
-
): SqlRow[] {
|
|
85
|
+
export function maskRows(rows: readonly SqlRow[], options: MaskRowsOptions): SqlRow[] {
|
|
97
86
|
if (options.revealPii || options.classifications.size === 0) {
|
|
98
87
|
return rows.map((r) => ({ ...r }));
|
|
99
88
|
}
|
|
@@ -101,13 +90,7 @@ export function maskRows(
|
|
|
101
90
|
return rows.map((row) => {
|
|
102
91
|
const out: SqlRow = {};
|
|
103
92
|
for (const [column, value] of Object.entries(row)) {
|
|
104
|
-
out[column] = isPiiColumn(
|
|
105
|
-
options.classifications,
|
|
106
|
-
options.table,
|
|
107
|
-
column,
|
|
108
|
-
)
|
|
109
|
-
? mask
|
|
110
|
-
: value;
|
|
93
|
+
out[column] = isPiiColumn(options.classifications, options.table, column) ? mask : value;
|
|
111
94
|
}
|
|
112
95
|
return out;
|
|
113
96
|
});
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import type { ColumnClassification, ResourceRef, StoreFacet } from "../../manifest/types.ts";
|
|
8
|
+
import { resource } from "./resource.ts";
|
|
9
|
+
import { schema } from "./schema-decl.ts";
|
|
8
10
|
import { resolveTableName, type TableHandle } from "./table.ts";
|
|
9
11
|
|
|
10
12
|
/** CDC trigger shape (mirrors kernel `CdcTrigger` without importing it). */
|
|
@@ -47,9 +49,7 @@ export interface SqlStoreOptions {
|
|
|
47
49
|
* Explicit classifications: `table → column → tags`.
|
|
48
50
|
* Merged with schema-derived tags; wins on conflict for the same column.
|
|
49
51
|
*/
|
|
50
|
-
readonly classify?: Readonly<
|
|
51
|
-
Record<string, Readonly<Record<string, ColumnClassification>>>
|
|
52
|
-
>;
|
|
52
|
+
readonly classify?: Readonly<Record<string, Readonly<Record<string, ColumnClassification>>>>;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/** SQL store declaration. */
|
|
@@ -106,11 +106,7 @@ export interface IndexStoreDecl extends StoreDeclBase {
|
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
/** Any store declaration. */
|
|
109
|
-
export type StoreDecl =
|
|
110
|
-
| SqlStoreDecl
|
|
111
|
-
| KvStoreDecl
|
|
112
|
-
| FilesStoreDecl
|
|
113
|
-
| IndexStoreDecl;
|
|
109
|
+
export type StoreDecl = SqlStoreDecl | KvStoreDecl | FilesStoreDecl | IndexStoreDecl;
|
|
114
110
|
|
|
115
111
|
/**
|
|
116
112
|
* Declare a SQL store.
|
|
@@ -161,10 +157,7 @@ export function kv(name: string, options: KvStoreOptions = {}): KvStoreDecl {
|
|
|
161
157
|
* @param name - Bucket name
|
|
162
158
|
* @param options - Options
|
|
163
159
|
*/
|
|
164
|
-
export function files(
|
|
165
|
-
name: string,
|
|
166
|
-
options: FilesStoreOptions = {},
|
|
167
|
-
): FilesStoreDecl {
|
|
160
|
+
export function files(name: string, options: FilesStoreOptions = {}): FilesStoreDecl {
|
|
168
161
|
return {
|
|
169
162
|
facet: "files",
|
|
170
163
|
name,
|
|
@@ -179,10 +172,7 @@ export function files(
|
|
|
179
172
|
* @param name - Index name
|
|
180
173
|
* @param options - Dimensions
|
|
181
174
|
*/
|
|
182
|
-
export function index(
|
|
183
|
-
name: string,
|
|
184
|
-
options: IndexStoreOptions = {},
|
|
185
|
-
): IndexStoreDecl {
|
|
175
|
+
export function index(name: string, options: IndexStoreOptions = {}): IndexStoreDecl {
|
|
186
176
|
return {
|
|
187
177
|
facet: "index",
|
|
188
178
|
name,
|
|
@@ -191,10 +181,14 @@ export function index(
|
|
|
191
181
|
};
|
|
192
182
|
}
|
|
193
183
|
|
|
194
|
-
/** Public `store` element — four facets. */
|
|
184
|
+
/** Public `store` element — four facets + abstract schema declare + resource. */
|
|
195
185
|
export const store = {
|
|
196
186
|
sql,
|
|
197
187
|
kv,
|
|
198
188
|
files,
|
|
199
189
|
index,
|
|
190
|
+
/** ORM-agnostic table declarations (`store.schema.table`). */
|
|
191
|
+
schema,
|
|
192
|
+
/** CRUD + list factory (`store.resource(db, table, opts)`). */
|
|
193
|
+
resource,
|
|
200
194
|
} as const;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain DDL policy — ensure vs migrate; missing schema → OKE1101.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, expect, test } from "bun:test";
|
|
6
|
+
import { Database } from "bun:sqlite";
|
|
7
|
+
import { OkeError, OKE_ERRORS } from "../../kernel/errors.ts";
|
|
8
|
+
import { sqliteDriver } from "../../drivers/sqlite.ts";
|
|
9
|
+
import { defineTable } from "./table.ts";
|
|
10
|
+
import { createSqlStoreHandle } from "./sql-session.ts";
|
|
11
|
+
|
|
12
|
+
const notes = defineTable("notes", { id: true, title: true });
|
|
13
|
+
|
|
14
|
+
describe("domain DDL policy", () => {
|
|
15
|
+
test("ensure mode creates tables on first touch", async () => {
|
|
16
|
+
const db = new Database(":memory:");
|
|
17
|
+
const conn = await sqliteDriver.connect({ client: db, role: "primary" });
|
|
18
|
+
const handle = createSqlStoreHandle("sql:app", {
|
|
19
|
+
connection: conn,
|
|
20
|
+
classifications: new Map(),
|
|
21
|
+
routedRole: "primary",
|
|
22
|
+
domainDdl: "ensure",
|
|
23
|
+
});
|
|
24
|
+
await handle.insert(notes).values({ id: "1", title: "hi" });
|
|
25
|
+
const rows = await handle.select().from(notes);
|
|
26
|
+
expect(rows).toHaveLength(1);
|
|
27
|
+
await conn.close();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("prod/off mode never CREATE TABLE IF NOT EXISTS", async () => {
|
|
31
|
+
const db = new Database(":memory:");
|
|
32
|
+
const execSql: string[] = [];
|
|
33
|
+
const base = await sqliteDriver.connect({ client: db, role: "primary" });
|
|
34
|
+
const conn = {
|
|
35
|
+
...base,
|
|
36
|
+
driverId: "sqlite" as const,
|
|
37
|
+
role: "primary" as const,
|
|
38
|
+
async query(sql: string, params?: readonly unknown[]) {
|
|
39
|
+
execSql.push(sql);
|
|
40
|
+
return base.query(sql, params);
|
|
41
|
+
},
|
|
42
|
+
async exec(sql: string, params?: readonly unknown[]) {
|
|
43
|
+
execSql.push(sql);
|
|
44
|
+
return base.exec(sql, params);
|
|
45
|
+
},
|
|
46
|
+
close: () => base.close(),
|
|
47
|
+
};
|
|
48
|
+
const handle = createSqlStoreHandle("sql:app", {
|
|
49
|
+
connection: conn,
|
|
50
|
+
classifications: new Map(),
|
|
51
|
+
routedRole: "primary",
|
|
52
|
+
domainDdl: "off",
|
|
53
|
+
});
|
|
54
|
+
try {
|
|
55
|
+
await handle.select().from(notes);
|
|
56
|
+
} catch {
|
|
57
|
+
/* expected — table missing */
|
|
58
|
+
}
|
|
59
|
+
expect(execSql.some((s) => /CREATE TABLE IF NOT EXISTS/i.test(s))).toBe(false);
|
|
60
|
+
await conn.close();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test("off mode remaps missing table to DOMAIN_SCHEMA_MISSING", async () => {
|
|
64
|
+
const db = new Database(":memory:");
|
|
65
|
+
const conn = await sqliteDriver.connect({ client: db, role: "primary" });
|
|
66
|
+
const handle = createSqlStoreHandle("sql:app", {
|
|
67
|
+
connection: conn,
|
|
68
|
+
classifications: new Map(),
|
|
69
|
+
routedRole: "primary",
|
|
70
|
+
domainDdl: "off",
|
|
71
|
+
});
|
|
72
|
+
let err: unknown;
|
|
73
|
+
try {
|
|
74
|
+
await handle.select().from(notes);
|
|
75
|
+
} catch (e) {
|
|
76
|
+
err = e;
|
|
77
|
+
}
|
|
78
|
+
expect(err).toBeInstanceOf(OkeError);
|
|
79
|
+
const oke = err as OkeError;
|
|
80
|
+
expect(oke.code).toBe(OKE_ERRORS.DOMAIN_SCHEMA_MISSING.code);
|
|
81
|
+
expect(oke.causeText).toContain("migrations have not been applied");
|
|
82
|
+
expect(oke.fix).toContain("oke db migrate");
|
|
83
|
+
expect(oke.docsUrl).toContain(`/e/${OKE_ERRORS.DOMAIN_SCHEMA_MISSING.code}`);
|
|
84
|
+
await conn.close();
|
|
85
|
+
});
|
|
86
|
+
});
|