okengine 0.2.5 → 0.2.8
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 +24 -23
- package/README.md +52 -346
- package/docs/spec/console.md +165 -142
- package/docs/spec/example.md +490 -312
- package/docs/spec/four-applications.md +495 -314
- package/docs/spec/unified-theory.md +184 -175
- package/package.json +46 -38
- package/spec/manifest.v1.schema.json +40 -9
- package/src/auth/api-keys.ts +2 -5
- package/src/auth/attenuation.ts +2 -6
- package/src/auth/auth.test.ts +53 -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 +386 -0
- package/src/cli/dev-app-runner.ts +2 -8
- package/src/cli/dev-db-push.test.ts +163 -0
- package/src/cli/dev-mode.test.ts +45 -0
- package/src/cli/dev-mode.ts +78 -0
- package/src/cli/dev.test.ts +148 -21
- package/src/cli/dev.ts +208 -134
- package/src/cli/doc-drift.test.ts +3 -2
- package/src/cli/doc-drift.ts +21 -50
- package/src/cli/doc-staleness.test.ts +69 -0
- package/src/cli/docker-cli.test.ts +7 -8
- package/src/cli/docker.ts +1 -3
- package/src/cli/doctor-diff-examples.ts +1 -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/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 +41 -47
- package/src/cli/mcp-from-console.ts +1 -4
- package/src/cli/mode.ts +45 -0
- package/src/cli/ports.test.ts +4 -13
- package/src/cli/ports.ts +1 -3
- package/src/cli/privacy-erase.ts +1 -3
- package/src/cli/registry.ts +75 -25
- package/src/cli/schema.ts +3 -10
- package/src/cli/stack.ts +2 -7
- package/src/cli/start.ts +4 -15
- package/src/cli/upgrade.ts +1 -4
- 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 +8 -29
- 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 +96 -30
- package/src/compiler/extract.ts +362 -156
- package/src/compiler/fixtures/skyport/oke.config.ts +1 -1
- 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 +4 -7
- package/src/compiler/sucrose.ts +11 -31
- package/src/config/define-config.test.ts +57 -34
- package/src/config/index.ts +181 -37
- 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 +14 -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 +23 -60
- 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 +112 -20
- package/src/docker/derive.ts +5 -19
- package/src/docker/docker.test.ts +15 -15
- package/src/docker/dockerfile.integration.test.ts +12 -21
- package/src/docker/helpers.ts +5 -4
- package/src/docker/index.ts +4 -11
- package/src/docker/pin.ts +1 -9
- package/src/docker/recipes/index.ts +5 -6
- package/src/docker/recipes/mailpit.ts +22 -0
- package/src/docker/recipes/postgres.ts +17 -6
- package/src/docker/recipes/redis.ts +6 -1
- package/src/docker/recipes/rustfs.ts +33 -0
- package/src/docker/stack-id.test.ts +33 -0
- package/src/docker/stack-id.ts +25 -13
- package/src/docker/stack.integration.test.ts +6 -21
- package/src/docker/types.ts +13 -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/fs.ts +2 -8
- package/src/drivers/index.ts +12 -56
- package/src/drivers/memory.ts +14 -41
- 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 +5 -17
- 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-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.ts +1 -5
- package/src/drivers/vault-sops.ts +10 -35
- package/src/drivers/vault-types.ts +1 -7
- 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 +8 -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/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.ts +11 -21
- package/src/elements/store/sql-session.test.ts +50 -0
- package/src/elements/store/sql-session.ts +60 -63
- package/src/elements/store/table.ts +35 -19
- package/src/elements/store.test.ts +17 -39
- package/src/elements/store.ts +37 -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 +18 -32
- package/src/elements/vault.test.ts +12 -28
- package/src/elements/vault.ts +8 -12
- package/src/index.ts +5 -2
- package/src/kernel/adopt-routes.ts +15 -29
- package/src/kernel/app.ts +34 -94
- package/src/kernel/auth-resolve.ts +2 -9
- package/src/kernel/boot-bind/ai.ts +1 -4
- package/src/kernel/boot-bind/channel.ts +2 -8
- 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 +17 -17
- package/src/kernel/boot-bind/store.ts +44 -50
- package/src/kernel/boot-bind/vault.ts +2 -8
- package/src/kernel/boot.test.ts +4 -9
- package/src/kernel/boot.ts +29 -76
- 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/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 +5 -25
- package/src/kernel/fx.test.ts +15 -44
- package/src/kernel/fx.ts +27 -79
- package/src/kernel/hook-timing.test.ts +3 -6
- package/src/kernel/hook-timing.ts +5 -14
- package/src/kernel/hooks.test.ts +10 -10
- package/src/kernel/hooks.ts +3 -12
- package/src/kernel/index.ts +4 -17
- package/src/kernel/journal.ts +7 -31
- package/src/kernel/on.ts +1 -6
- 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 +48 -24
- package/src/kernel/registry.ts +80 -29
- 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 +4 -21
- package/src/manifest/diff.test.ts +26 -91
- package/src/manifest/diff.ts +95 -225
- package/src/manifest/index.ts +2 -9
- package/src/manifest/types.ts +29 -5
- 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 +4 -14
- 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/node-import-scan.ts +2 -5
- 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 +15 -43
- 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 +13 -31
- 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/src/console/ui/dist/assets/panel-vault-BbfWdox0.js +0 -1
|
@@ -5,13 +5,12 @@
|
|
|
5
5
|
* Same flow code runs against sqlite, postgres, and memory.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
import type { DomainDdlMode } from "../../config/index.ts";
|
|
8
9
|
import type { ClassificationMap, SqlConnection, SqlRow } from "../../drivers/types.ts";
|
|
10
|
+
import { throwOke } from "../../kernel/errors.ts";
|
|
9
11
|
import { maskRows, tableFromSql } from "./classify.ts";
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
resolveSelectColumns,
|
|
13
|
-
type WhereMap,
|
|
14
|
-
} from "./sql-condition.ts";
|
|
12
|
+
import { isMissingDomainRelationError } from "./missing-relation.ts";
|
|
13
|
+
import { compileWhere, resolveSelectColumns, type WhereMap } from "./sql-condition.ts";
|
|
15
14
|
import {
|
|
16
15
|
mapRowToJs,
|
|
17
16
|
prepareInsertRow,
|
|
@@ -32,6 +31,12 @@ export interface SqlSessionOptions {
|
|
|
32
31
|
readonly revealPii?: boolean;
|
|
33
32
|
/** Which connection was chosen — exposed for replica proofs. */
|
|
34
33
|
readonly routedRole: "primary" | "replica";
|
|
34
|
+
/**
|
|
35
|
+
* Domain DDL policy. `ensure` runs `CREATE TABLE IF NOT EXISTS` on first
|
|
36
|
+
* touch; `off` means migrations / `oke db push` own the schema (docker/prod
|
|
37
|
+
* and local+autoPush). Default `ensure` for backward-compatible tests.
|
|
38
|
+
*/
|
|
39
|
+
readonly domainDdl?: DomainDdlMode;
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
/**
|
|
@@ -172,10 +177,7 @@ export interface SqlStoreHandle {
|
|
|
172
177
|
* @param table - Table
|
|
173
178
|
* @param idOrWhere - Primary key string, or column equality map
|
|
174
179
|
*/
|
|
175
|
-
exists(
|
|
176
|
-
table: TableHandle | unknown,
|
|
177
|
-
idOrWhere: string | WhereMap,
|
|
178
|
-
): Promise<boolean>;
|
|
180
|
+
exists(table: TableHandle | unknown, idOrWhere: string | WhereMap): Promise<boolean>;
|
|
179
181
|
/**
|
|
180
182
|
* Atomically add `by` to `column` on the PK row.
|
|
181
183
|
*
|
|
@@ -184,12 +186,7 @@ export interface SqlStoreHandle {
|
|
|
184
186
|
* @param column - Numeric column to bump
|
|
185
187
|
* @param by - Delta (default `1`)
|
|
186
188
|
*/
|
|
187
|
-
increment(
|
|
188
|
-
table: TableHandle | unknown,
|
|
189
|
-
id: string,
|
|
190
|
-
column: string,
|
|
191
|
-
by?: number,
|
|
192
|
-
): Promise<number>;
|
|
189
|
+
increment(table: TableHandle | unknown, id: string, column: string, by?: number): Promise<number>;
|
|
193
190
|
/**
|
|
194
191
|
* Raw SQL — PII masking still applied at the boundary.
|
|
195
192
|
*
|
|
@@ -216,38 +213,55 @@ export function createSqlStoreHandle(
|
|
|
216
213
|
options: SqlSessionOptions,
|
|
217
214
|
): SqlStoreHandle {
|
|
218
215
|
const { connection, classifications, revealPii } = options;
|
|
216
|
+
const domainDdl: DomainDdlMode = options.domainDdl ?? "ensure";
|
|
219
217
|
|
|
220
218
|
function mask(rows: SqlRow[], table?: string): SqlRow[] {
|
|
221
219
|
return maskRows(rows, { classifications, table, revealPii });
|
|
222
220
|
}
|
|
223
221
|
|
|
222
|
+
/**
|
|
223
|
+
* Run a connection op; remap missing-relation driver errors to OKE1101
|
|
224
|
+
* when domain auto-DDL is off.
|
|
225
|
+
*/
|
|
226
|
+
async function withSchemaGuard<T>(fn: () => Promise<T>): Promise<T> {
|
|
227
|
+
try {
|
|
228
|
+
return await fn();
|
|
229
|
+
} catch (err) {
|
|
230
|
+
if (domainDdl === "off" && isMissingDomainRelationError(err)) {
|
|
231
|
+
throwOke("DOMAIN_SCHEMA_MISSING");
|
|
232
|
+
}
|
|
233
|
+
throw err;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
function query(sql: string, params: readonly unknown[] = []): Promise<SqlRow[]> {
|
|
238
|
+
return withSchemaGuard(() => connection.query(sql, params));
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function exec(sql: string, params: readonly unknown[] = []): Promise<{ changes: number }> {
|
|
242
|
+
return withSchemaGuard(() => connection.exec(sql, params));
|
|
243
|
+
}
|
|
244
|
+
|
|
224
245
|
async function ensureFromMeta(table: TableHandle | unknown): Promise<void> {
|
|
246
|
+
if (domainDdl !== "ensure") return;
|
|
225
247
|
const cols = resolveColumns(table);
|
|
226
248
|
if (cols.length === 0) return;
|
|
227
249
|
const name = resolveTableName(table);
|
|
228
250
|
const pk = cols.find((c) => c.primary)?.sqlName;
|
|
229
251
|
const colSql = cols
|
|
230
252
|
.map((c) => {
|
|
231
|
-
const typ =
|
|
232
|
-
pk && c.sqlName === pk
|
|
233
|
-
? `${c.sqlType} PRIMARY KEY`
|
|
234
|
-
: c.sqlType;
|
|
253
|
+
const typ = pk && c.sqlName === pk ? `${c.sqlType} PRIMARY KEY` : c.sqlType;
|
|
235
254
|
return `${quoteIdent(c.sqlName)} ${typ}`;
|
|
236
255
|
})
|
|
237
256
|
.join(", ");
|
|
238
|
-
await
|
|
239
|
-
`CREATE TABLE IF NOT EXISTS ${quoteIdent(name)} (${colSql})`,
|
|
240
|
-
);
|
|
257
|
+
await exec(`CREATE TABLE IF NOT EXISTS ${quoteIdent(name)} (${colSql})`);
|
|
241
258
|
}
|
|
242
259
|
|
|
243
260
|
function toJs(table: TableHandle | unknown, rows: SqlRow[]): SqlRow[] {
|
|
244
261
|
return rows.map((r) => mapRowToJs(table, r) as SqlRow);
|
|
245
262
|
}
|
|
246
263
|
|
|
247
|
-
function normalizeWhereMap(
|
|
248
|
-
table: TableHandle | unknown,
|
|
249
|
-
where: WhereMap,
|
|
250
|
-
): WhereMap {
|
|
264
|
+
function normalizeWhereMap(table: TableHandle | unknown, where: WhereMap): WhereMap {
|
|
251
265
|
const cols = resolveColumns(table);
|
|
252
266
|
if (cols.length === 0) return where;
|
|
253
267
|
const out: Record<string, unknown> = {};
|
|
@@ -305,7 +319,7 @@ export function createSqlStoreHandle(
|
|
|
305
319
|
sql += ` LIMIT ${Math.max(0, Math.floor(limit))}`;
|
|
306
320
|
}
|
|
307
321
|
|
|
308
|
-
const rows = await
|
|
322
|
+
const rows = await query(sql, params);
|
|
309
323
|
if (projection === null) {
|
|
310
324
|
return toJs(table, mask(rows, name));
|
|
311
325
|
}
|
|
@@ -322,10 +336,7 @@ export function createSqlStoreHandle(
|
|
|
322
336
|
);
|
|
323
337
|
}
|
|
324
338
|
|
|
325
|
-
function selectFrom(
|
|
326
|
-
table: TableHandle | unknown,
|
|
327
|
-
columns?: unknown,
|
|
328
|
-
): SelectFromBuilder {
|
|
339
|
+
function selectFrom(table: TableHandle | unknown, columns?: unknown): SelectFromBuilder {
|
|
329
340
|
const projection = resolveSelectColumns(columns);
|
|
330
341
|
const all = runSelect(table, projection, undefined);
|
|
331
342
|
return {
|
|
@@ -371,7 +382,7 @@ export function createSqlStoreHandle(
|
|
|
371
382
|
const colList = cols.map(quoteIdent).join(", ");
|
|
372
383
|
const params = cols.map((c) => prepared[c]);
|
|
373
384
|
const sql = `INSERT INTO ${quoteIdent(name)} (${colList}) VALUES (${placeholders})`;
|
|
374
|
-
await
|
|
385
|
+
await exec(sql, params);
|
|
375
386
|
};
|
|
376
387
|
return {
|
|
377
388
|
async returning() {
|
|
@@ -382,7 +393,7 @@ export function createSqlStoreHandle(
|
|
|
382
393
|
const colList = cols.map(quoteIdent).join(", ");
|
|
383
394
|
const params = cols.map((c) => prepared[c]);
|
|
384
395
|
const sql = `INSERT INTO ${quoteIdent(name)} (${colList}) VALUES (${placeholders}) RETURNING *`;
|
|
385
|
-
const rows = await
|
|
396
|
+
const rows = await query(sql, params);
|
|
386
397
|
return toJs(table, mask(rows, name));
|
|
387
398
|
},
|
|
388
399
|
execute: runExecute,
|
|
@@ -404,18 +415,13 @@ export function createSqlStoreHandle(
|
|
|
404
415
|
const prepared = prepareInsertRow(table, row);
|
|
405
416
|
const setEntries = Object.entries(prepared);
|
|
406
417
|
if (setEntries.length === 0) return 0;
|
|
407
|
-
const setSql = setEntries
|
|
408
|
-
.map(([col]) => `${quoteIdent(col)} = ?`)
|
|
409
|
-
.join(", ");
|
|
418
|
+
const setSql = setEntries.map(([col]) => `${quoteIdent(col)} = ?`).join(", ");
|
|
410
419
|
const compiled = compileTableWhere(table, where);
|
|
411
420
|
if (!compiled.clause) {
|
|
412
421
|
throw new Error("update().set().where(): condition required");
|
|
413
422
|
}
|
|
414
|
-
const params = [
|
|
415
|
-
|
|
416
|
-
...compiled.params,
|
|
417
|
-
];
|
|
418
|
-
const result = await connection.exec(
|
|
423
|
+
const params = [...setEntries.map(([, v]) => v), ...compiled.params];
|
|
424
|
+
const result = await exec(
|
|
419
425
|
`UPDATE ${quoteIdent(name)} SET ${setSql} WHERE ${compiled.clause}`,
|
|
420
426
|
params,
|
|
421
427
|
);
|
|
@@ -430,27 +436,22 @@ export function createSqlStoreHandle(
|
|
|
430
436
|
await ensureFromMeta(table);
|
|
431
437
|
const name = resolveTableName(table);
|
|
432
438
|
const pk = resolvePkColumn(table);
|
|
433
|
-
const rows = await
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
);
|
|
439
|
+
const rows = await query(`SELECT * FROM ${quoteIdent(name)} WHERE ${quoteIdent(pk)} = ?`, [
|
|
440
|
+
idValue,
|
|
441
|
+
]);
|
|
437
442
|
const masked = toJs(table, mask(rows, name));
|
|
438
443
|
return masked[0] ?? null;
|
|
439
444
|
},
|
|
440
445
|
|
|
441
|
-
delete: ((
|
|
442
|
-
table: TableHandle | unknown,
|
|
443
|
-
idValue?: string,
|
|
444
|
-
): DeleteBuilder | Promise<boolean> => {
|
|
446
|
+
delete: ((table: TableHandle | unknown, idValue?: string): DeleteBuilder | Promise<boolean> => {
|
|
445
447
|
if (idValue !== undefined) {
|
|
446
448
|
return (async () => {
|
|
447
449
|
await ensureFromMeta(table);
|
|
448
450
|
const name = resolveTableName(table);
|
|
449
451
|
const pk = resolvePkColumn(table);
|
|
450
|
-
const result = await
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
);
|
|
452
|
+
const result = await exec(`DELETE FROM ${quoteIdent(name)} WHERE ${quoteIdent(pk)} = ?`, [
|
|
453
|
+
idValue,
|
|
454
|
+
]);
|
|
454
455
|
return result.changes > 0;
|
|
455
456
|
})();
|
|
456
457
|
}
|
|
@@ -462,7 +463,7 @@ export function createSqlStoreHandle(
|
|
|
462
463
|
if (!compiled.clause) {
|
|
463
464
|
throw new Error("delete().where(): condition required");
|
|
464
465
|
}
|
|
465
|
-
const result = await
|
|
466
|
+
const result = await exec(
|
|
466
467
|
`DELETE FROM ${quoteIdent(name)} WHERE ${compiled.clause}`,
|
|
467
468
|
compiled.params,
|
|
468
469
|
);
|
|
@@ -483,7 +484,7 @@ export function createSqlStoreHandle(
|
|
|
483
484
|
if (!compiled.clause) {
|
|
484
485
|
throw new Error("exists() requires at least one where predicate");
|
|
485
486
|
}
|
|
486
|
-
const rows = await
|
|
487
|
+
const rows = await query(
|
|
487
488
|
`SELECT 1 AS "ok" FROM ${quoteIdent(name)} WHERE ${compiled.clause} LIMIT 1`,
|
|
488
489
|
compiled.params,
|
|
489
490
|
);
|
|
@@ -498,22 +499,20 @@ export function createSqlStoreHandle(
|
|
|
498
499
|
const colMeta = cols.find((c) => c.key === column || c.sqlName === column);
|
|
499
500
|
const sqlCol = colMeta?.sqlName ?? column;
|
|
500
501
|
const col = quoteIdent(sqlCol);
|
|
501
|
-
const rows = await
|
|
502
|
+
const rows = await query(
|
|
502
503
|
`UPDATE ${quoteIdent(name)} SET ${col} = ${col} + ? WHERE ${quoteIdent(pk)} = ? RETURNING ${col}`,
|
|
503
504
|
[by, idValue],
|
|
504
505
|
);
|
|
505
506
|
const row = rows[0];
|
|
506
507
|
if (!row) {
|
|
507
|
-
throw new Error(
|
|
508
|
-
`increment(): no row with ${pk} ${JSON.stringify(idValue)} in ${name}`,
|
|
509
|
-
);
|
|
508
|
+
throw new Error(`increment(): no row with ${pk} ${JSON.stringify(idValue)} in ${name}`);
|
|
510
509
|
}
|
|
511
510
|
return asNumber(row[sqlCol], sqlCol);
|
|
512
511
|
},
|
|
513
512
|
|
|
514
513
|
async raw(sql, params = []) {
|
|
515
514
|
const table = tableFromSql(sql);
|
|
516
|
-
const rows = await
|
|
515
|
+
const rows = await query(sql, params);
|
|
517
516
|
return mask(rows, table);
|
|
518
517
|
},
|
|
519
518
|
|
|
@@ -534,9 +533,7 @@ export function createSqlStoreHandle(
|
|
|
534
533
|
return `${quoteIdent(c.name)} ${typ}`;
|
|
535
534
|
})
|
|
536
535
|
.join(", ");
|
|
537
|
-
await
|
|
538
|
-
`CREATE TABLE IF NOT EXISTS ${quoteIdent(table.name)} (${colSql})`,
|
|
539
|
-
);
|
|
536
|
+
await exec(`CREATE TABLE IF NOT EXISTS ${quoteIdent(table.name)} (${colSql})`);
|
|
540
537
|
},
|
|
541
538
|
};
|
|
542
539
|
|
|
@@ -31,9 +31,7 @@ export interface TableHandle {
|
|
|
31
31
|
*/
|
|
32
32
|
export function defineTable(
|
|
33
33
|
name: string,
|
|
34
|
-
columns: Readonly<
|
|
35
|
-
Record<string, ColumnDef | ColumnClassification | true | undefined>
|
|
36
|
-
>,
|
|
34
|
+
columns: Readonly<Record<string, ColumnDef | ColumnClassification | true | undefined>>,
|
|
37
35
|
): TableHandle {
|
|
38
36
|
const resolved: Record<string, ColumnDef> = {};
|
|
39
37
|
for (const [key, value] of Object.entries(columns)) {
|
|
@@ -120,14 +118,38 @@ export function resolveColumns(table: unknown): ResolvedColumn[] {
|
|
|
120
118
|
if (table && typeof table === "object") {
|
|
121
119
|
const t = table as Record<string, unknown>;
|
|
122
120
|
if ("columns" in t && t.columns && typeof t.columns === "object") {
|
|
123
|
-
return Object.entries(
|
|
124
|
-
|
|
121
|
+
return Object.entries(
|
|
122
|
+
t.columns as Record<
|
|
123
|
+
string,
|
|
124
|
+
ColumnDef & {
|
|
125
|
+
sqlName?: string;
|
|
126
|
+
sqlType?: string;
|
|
127
|
+
primaryKey?: boolean;
|
|
128
|
+
defaultFn?: () => unknown;
|
|
129
|
+
}
|
|
130
|
+
>,
|
|
131
|
+
).map(([key, col]) => {
|
|
132
|
+
const sqlName = col.sqlName ?? col.name;
|
|
133
|
+
const primary =
|
|
134
|
+
typeof col.primaryKey === "boolean"
|
|
135
|
+
? col.primaryKey
|
|
136
|
+
: col.name === "id" || key === "id" || sqlName === "id";
|
|
137
|
+
const sqlType =
|
|
138
|
+
col.sqlType === "integer" || col.sqlType === "INTEGER"
|
|
139
|
+
? ("INTEGER" as const)
|
|
140
|
+
: col.sqlType === "real" || col.sqlType === "REAL"
|
|
141
|
+
? ("REAL" as const)
|
|
142
|
+
: col.sqlType === "blob" || col.sqlType === "BLOB"
|
|
143
|
+
? ("BLOB" as const)
|
|
144
|
+
: ("TEXT" as const);
|
|
145
|
+
return {
|
|
125
146
|
key,
|
|
126
|
-
sqlName
|
|
127
|
-
primary
|
|
128
|
-
sqlType
|
|
129
|
-
|
|
130
|
-
|
|
147
|
+
sqlName,
|
|
148
|
+
primary,
|
|
149
|
+
sqlType,
|
|
150
|
+
...(typeof col.defaultFn === "function" ? { defaultFn: col.defaultFn } : {}),
|
|
151
|
+
};
|
|
152
|
+
});
|
|
131
153
|
}
|
|
132
154
|
if (isDrizzleTable(t)) {
|
|
133
155
|
return drizzleColumns(t);
|
|
@@ -168,18 +190,14 @@ function drizzleColumns(t: Record<string, unknown>): ResolvedColumn[] {
|
|
|
168
190
|
config?: { primaryKey?: boolean };
|
|
169
191
|
};
|
|
170
192
|
const sqlName = typeof col.name === "string" ? col.name : key;
|
|
171
|
-
const primary = Boolean(
|
|
172
|
-
col.primary || col.config?.primaryKey || sqlName === "id",
|
|
173
|
-
);
|
|
193
|
+
const primary = Boolean(col.primary || col.config?.primaryKey || sqlName === "id");
|
|
174
194
|
const sqlType = drizzleSqlType(col.columnType, col.dataType);
|
|
175
195
|
out.push({
|
|
176
196
|
key,
|
|
177
197
|
sqlName,
|
|
178
198
|
primary,
|
|
179
199
|
sqlType,
|
|
180
|
-
...(typeof col.defaultFn === "function"
|
|
181
|
-
? { defaultFn: col.defaultFn.bind(col) }
|
|
182
|
-
: {}),
|
|
200
|
+
...(typeof col.defaultFn === "function" ? { defaultFn: col.defaultFn.bind(col) } : {}),
|
|
183
201
|
});
|
|
184
202
|
}
|
|
185
203
|
return out;
|
|
@@ -257,9 +275,7 @@ export function mapRowToJs(
|
|
|
257
275
|
*
|
|
258
276
|
* @param table - Table handle
|
|
259
277
|
*/
|
|
260
|
-
export function classificationsFromTable(
|
|
261
|
-
table: TableHandle,
|
|
262
|
-
): Record<string, ColumnClassification> {
|
|
278
|
+
export function classificationsFromTable(table: TableHandle): Record<string, ColumnClassification> {
|
|
263
279
|
const out: Record<string, ColumnClassification> = {};
|
|
264
280
|
for (const [key, col] of Object.entries(table.columns)) {
|
|
265
281
|
if (col.classification) out[key] = col.classification;
|
|
@@ -7,11 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { describe, expect, test } from "bun:test";
|
|
10
|
-
import {
|
|
11
|
-
createPostgresFakeClient,
|
|
12
|
-
postgresDriver,
|
|
13
|
-
sqliteDriver,
|
|
14
|
-
} from "../drivers/index.ts";
|
|
10
|
+
import { createPostgresFakeClient, postgresDriver, sqliteDriver } from "../drivers/index.ts";
|
|
15
11
|
import type { Effects } from "../manifest/types.ts";
|
|
16
12
|
import {
|
|
17
13
|
classify,
|
|
@@ -72,9 +68,7 @@ describe("store facets", () => {
|
|
|
72
68
|
});
|
|
73
69
|
|
|
74
70
|
test("id and now helpers", () => {
|
|
75
|
-
expect(id()).toMatch(
|
|
76
|
-
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,
|
|
77
|
-
);
|
|
71
|
+
expect(id()).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i);
|
|
78
72
|
expect(now()).toBeGreaterThan(0);
|
|
79
73
|
});
|
|
80
74
|
});
|
|
@@ -119,13 +113,11 @@ describe("same flow against sqlite and postgres", () => {
|
|
|
119
113
|
describe("replica routing from effects", () => {
|
|
120
114
|
test("read-only flows are detected from the effect set", () => {
|
|
121
115
|
expect(isReadOnlyStoreFlow({ reads: ["sql:notes"] })).toBe(true);
|
|
122
|
-
expect(
|
|
123
|
-
isReadOnlyStoreFlow({ reads: ["sql:notes"], writes: ["sql:notes"] }),
|
|
124
|
-
).toBe(false);
|
|
116
|
+
expect(isReadOnlyStoreFlow({ reads: ["sql:notes"], writes: ["sql:notes"] })).toBe(false);
|
|
125
117
|
expect(sqlRoleForEffects({ reads: ["sql:notes"] }, true)).toBe("replica");
|
|
126
|
-
expect(
|
|
127
|
-
|
|
128
|
-
)
|
|
118
|
+
expect(sqlRoleForEffects({ reads: ["sql:notes"], writes: ["sql:notes"] }, true)).toBe(
|
|
119
|
+
"primary",
|
|
120
|
+
);
|
|
129
121
|
});
|
|
130
122
|
|
|
131
123
|
test("read-only flow provably hits a replica", async () => {
|
|
@@ -135,10 +127,11 @@ describe("replica routing from effects", () => {
|
|
|
135
127
|
await replicaClient.unsafe(
|
|
136
128
|
`CREATE TABLE IF NOT EXISTS "notes" ("id" TEXT PRIMARY KEY, "title" TEXT, "email" TEXT)`,
|
|
137
129
|
);
|
|
138
|
-
await replicaClient.unsafe(
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
130
|
+
await replicaClient.unsafe(`INSERT INTO "notes" ("id", "title", "email") VALUES ($1, $2, $3)`, [
|
|
131
|
+
"n1",
|
|
132
|
+
"from-replica",
|
|
133
|
+
"x@y.z",
|
|
134
|
+
]);
|
|
142
135
|
|
|
143
136
|
const decl = store.sql("notes", {
|
|
144
137
|
classify: { notes: { email: classify({ pii: true }) } },
|
|
@@ -213,12 +206,8 @@ describe("tier-1 cache invalidation from effects", () => {
|
|
|
213
206
|
expiresAt: null,
|
|
214
207
|
});
|
|
215
208
|
|
|
216
|
-
expect(isInvalidatedByWrite(keys[0]!, { writes: ["sql:notes"] })).toBe(
|
|
217
|
-
|
|
218
|
-
);
|
|
219
|
-
expect(isInvalidatedByWrite(keys[0]!, { writes: ["sql:orders"] })).toBe(
|
|
220
|
-
false,
|
|
221
|
-
);
|
|
209
|
+
expect(isInvalidatedByWrite(keys[0]!, { writes: ["sql:notes"] })).toBe(true);
|
|
210
|
+
expect(isInvalidatedByWrite(keys[0]!, { writes: ["sql:orders"] })).toBe(false);
|
|
222
211
|
|
|
223
212
|
const event = cache.invalidateFromEffects({ writes: ["sql:notes"] });
|
|
224
213
|
expect(event.keys).toEqual([computedCacheKey("sql:notes")]);
|
|
@@ -268,10 +257,7 @@ describe("exists and increment helpers", () => {
|
|
|
268
257
|
}),
|
|
269
258
|
);
|
|
270
259
|
await handle.ensureTable(counters);
|
|
271
|
-
await handle
|
|
272
|
-
.insert(counters)
|
|
273
|
-
.values({ id: "c1", clicks: 0 })
|
|
274
|
-
.execute();
|
|
260
|
+
await handle.insert(counters).values({ id: "c1", clicks: 0 }).execute();
|
|
275
261
|
|
|
276
262
|
expect(await handle.exists(counters, { id: "c1" }), label).toBe(true);
|
|
277
263
|
expect(await handle.exists(counters, { id: "gone" }), label).toBe(false);
|
|
@@ -301,16 +287,11 @@ describe("exists and increment helpers", () => {
|
|
|
301
287
|
}),
|
|
302
288
|
);
|
|
303
289
|
await handle.ensureTable(counters);
|
|
304
|
-
await handle
|
|
305
|
-
.insert(counters)
|
|
306
|
-
.values({ id: "c1", clicks: 0 })
|
|
307
|
-
.execute();
|
|
290
|
+
await handle.insert(counters).values({ id: "c1", clicks: 0 }).execute();
|
|
308
291
|
|
|
309
292
|
const n = 100;
|
|
310
293
|
const results = await Promise.all(
|
|
311
|
-
Array.from({ length: n }, () =>
|
|
312
|
-
handle.increment(counters, "c1", "clicks"),
|
|
313
|
-
),
|
|
294
|
+
Array.from({ length: n }, () => handle.increment(counters, "c1", "clicks")),
|
|
314
295
|
);
|
|
315
296
|
expect(new Set(results).size, label).toBe(n);
|
|
316
297
|
expect(Math.max(...results), label).toBe(n);
|
|
@@ -337,10 +318,7 @@ describe("PII masking at the driver boundary", () => {
|
|
|
337
318
|
}),
|
|
338
319
|
);
|
|
339
320
|
await handle.ensureTable(notes);
|
|
340
|
-
await handle
|
|
341
|
-
.insert(notes)
|
|
342
|
-
.values({ id: "1", title: "t", email: "pii@x.com" })
|
|
343
|
-
.execute();
|
|
321
|
+
await handle.insert(notes).values({ id: "1", title: "t", email: "pii@x.com" }).execute();
|
|
344
322
|
|
|
345
323
|
const rows = await handle.raw(`SELECT * FROM notes`);
|
|
346
324
|
expect(rows[0]?.title).toBe("t");
|
package/src/elements/store.ts
CHANGED
|
@@ -21,6 +21,37 @@ export type {
|
|
|
21
21
|
IndexStoreOptions,
|
|
22
22
|
} from "./store/declare.ts";
|
|
23
23
|
|
|
24
|
+
export {
|
|
25
|
+
field,
|
|
26
|
+
schema,
|
|
27
|
+
schemaTable,
|
|
28
|
+
schemaRelations,
|
|
29
|
+
isSchemaTableDecl,
|
|
30
|
+
isSchemaColumnDecl,
|
|
31
|
+
isSchemaRelationsDecl,
|
|
32
|
+
isFieldBuilder,
|
|
33
|
+
finalizeColumnMap,
|
|
34
|
+
tablesFromExports,
|
|
35
|
+
relationsFromExports,
|
|
36
|
+
} from "./store/schema-decl.ts";
|
|
37
|
+
export type {
|
|
38
|
+
FieldBuilder,
|
|
39
|
+
FieldSqlType,
|
|
40
|
+
DefaultFnKind,
|
|
41
|
+
SchemaColumnDecl,
|
|
42
|
+
SchemaColumnInput,
|
|
43
|
+
SchemaTableDecl,
|
|
44
|
+
SchemaTableWithColumns,
|
|
45
|
+
SchemaRelationsDecl,
|
|
46
|
+
SchemaRelationEntry,
|
|
47
|
+
SchemaRelationOne,
|
|
48
|
+
SchemaRelationMany,
|
|
49
|
+
RelationColumnRef,
|
|
50
|
+
ReferenceAction,
|
|
51
|
+
ReferenceActions,
|
|
52
|
+
ColumnReference,
|
|
53
|
+
} from "./store/schema-decl.ts";
|
|
54
|
+
|
|
24
55
|
export {
|
|
25
56
|
classify,
|
|
26
57
|
buildClassificationMap,
|
|
@@ -39,33 +70,15 @@ export {
|
|
|
39
70
|
isInvalidatedByWrite,
|
|
40
71
|
parseTtlMs,
|
|
41
72
|
} from "./store/cache.ts";
|
|
42
|
-
export type {
|
|
43
|
-
CacheTier,
|
|
44
|
-
CacheEntry,
|
|
45
|
-
InvalidationEvent,
|
|
46
|
-
StoreCache,
|
|
47
|
-
} from "./store/cache.ts";
|
|
73
|
+
export type { CacheTier, CacheEntry, InvalidationEvent, StoreCache } from "./store/cache.ts";
|
|
48
74
|
|
|
49
|
-
export {
|
|
50
|
-
isReadOnlyStoreFlow,
|
|
51
|
-
sqlRoleForEffects,
|
|
52
|
-
resolveSqlTarget,
|
|
53
|
-
} from "./store/replica.ts";
|
|
75
|
+
export { isReadOnlyStoreFlow, sqlRoleForEffects, resolveSqlTarget } from "./store/replica.ts";
|
|
54
76
|
export type { SqlBindingConfig } from "./store/replica.ts";
|
|
55
77
|
|
|
56
|
-
export {
|
|
57
|
-
defineTable,
|
|
58
|
-
resolveTableName,
|
|
59
|
-
classificationsFromTable,
|
|
60
|
-
id,
|
|
61
|
-
now,
|
|
62
|
-
} from "./store/table.ts";
|
|
78
|
+
export { defineTable, resolveTableName, classificationsFromTable, id, now } from "./store/table.ts";
|
|
63
79
|
export type { ColumnDef, TableHandle } from "./store/table.ts";
|
|
64
80
|
|
|
65
|
-
export {
|
|
66
|
-
createSqlStoreHandle,
|
|
67
|
-
resolvePkColumn,
|
|
68
|
-
} from "./store/sql-session.ts";
|
|
81
|
+
export { createSqlStoreHandle, resolvePkColumn } from "./store/sql-session.ts";
|
|
69
82
|
export type {
|
|
70
83
|
SqlStoreHandle,
|
|
71
84
|
SelectBuilder,
|
|
@@ -76,10 +89,7 @@ export type {
|
|
|
76
89
|
WhereMap,
|
|
77
90
|
} from "./store/sql-session.ts";
|
|
78
91
|
|
|
79
|
-
export {
|
|
80
|
-
createStoreRuntime,
|
|
81
|
-
putTier2,
|
|
82
|
-
} from "./store/runtime.ts";
|
|
92
|
+
export { createStoreRuntime, putTier2 } from "./store/runtime.ts";
|
|
83
93
|
export type {
|
|
84
94
|
StoreRuntime,
|
|
85
95
|
StoreDriverBundle,
|
|
@@ -92,9 +102,5 @@ export type {
|
|
|
92
102
|
IndexStoreFxHandle,
|
|
93
103
|
} from "./store/runtime.ts";
|
|
94
104
|
|
|
95
|
-
export {
|
|
96
|
-
fileKeyWarnings,
|
|
97
|
-
contentAddressedKey,
|
|
98
|
-
projectFileKeys,
|
|
99
|
-
} from "./store/files-policy.ts";
|
|
105
|
+
export { fileKeyWarnings, contentAddressedKey, projectFileKeys } from "./store/files-policy.ts";
|
|
100
106
|
export type { FileKeyWarning } from "./store/files-policy.ts";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical vault compose-env path resolution — shared by app boot and Console.
|
|
3
|
+
*
|
|
4
|
+
* Compose credentials live at `docker/.env.docker`. Legacy project-root
|
|
5
|
+
* `.env.docker` is consulted when absent (soft-compat).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { existsSync } from "node:fs";
|
|
9
|
+
import { resolve } from "node:path";
|
|
10
|
+
import type { VaultResolutionSource } from "./runtime.ts";
|
|
11
|
+
|
|
12
|
+
/** Canonical relative path for compose stack credentials. */
|
|
13
|
+
export const COMPOSE_ENV_REL = "docker/.env.docker";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Resolve the compose-env path: prefer `docker/.env.docker`, then legacy
|
|
17
|
+
* project-root `.env.docker`.
|
|
18
|
+
*
|
|
19
|
+
* @param root - Project root
|
|
20
|
+
*/
|
|
21
|
+
export function resolveComposeEnvPath(root: string): {
|
|
22
|
+
readonly path: string;
|
|
23
|
+
readonly source: Extract<VaultResolutionSource, ".env.docker">;
|
|
24
|
+
} {
|
|
25
|
+
const dockerPath = resolve(root, COMPOSE_ENV_REL);
|
|
26
|
+
if (existsSync(dockerPath)) {
|
|
27
|
+
return { path: dockerPath, source: ".env.docker" };
|
|
28
|
+
}
|
|
29
|
+
const legacyDocker = resolve(root, ".env.docker");
|
|
30
|
+
if (existsSync(legacyDocker)) {
|
|
31
|
+
return { path: legacyDocker, source: ".env.docker" };
|
|
32
|
+
}
|
|
33
|
+
return { path: dockerPath, source: ".env.docker" };
|
|
34
|
+
}
|