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,10 +5,7 @@
|
|
|
5
5
|
import { describe, expect, test } from "bun:test";
|
|
6
6
|
import { defineTable } from "../../elements/store.ts";
|
|
7
7
|
import { classify } from "../../elements/store/classify.ts";
|
|
8
|
-
import {
|
|
9
|
-
DryRunWriteIsolationError,
|
|
10
|
-
withDryRun,
|
|
11
|
-
} from "../../kernel/dry-run.ts";
|
|
8
|
+
import { DryRunWriteIsolationError, withDryRun } from "../../kernel/dry-run.ts";
|
|
12
9
|
import type { Manifest } from "../../manifest/types.ts";
|
|
13
10
|
import {
|
|
14
11
|
createManifestStoreRuntime,
|
|
@@ -79,21 +76,24 @@ describe("tenancyDeclared", () => {
|
|
|
79
76
|
describe("projectStoresList", () => {
|
|
80
77
|
test("groups facets and surfaces will-not-fire from effects", async () => {
|
|
81
78
|
const runtime = await createManifestStoreRuntime(MANIFEST);
|
|
82
|
-
const {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
79
|
+
const {
|
|
80
|
+
stores,
|
|
81
|
+
tenancyDeclared: tenancy,
|
|
82
|
+
tenants,
|
|
83
|
+
} = await projectStoresList({
|
|
84
|
+
manifest: MANIFEST,
|
|
85
|
+
runtime,
|
|
86
|
+
declaredFingerprint: "decl",
|
|
87
|
+
appliedFingerprint: "decl",
|
|
88
|
+
runs: [
|
|
89
|
+
{
|
|
90
|
+
flow: "bookings.mine",
|
|
91
|
+
replicaLagMs: 120,
|
|
92
|
+
tenant: "t1",
|
|
93
|
+
effects: [{ kind: "read", resource: "sql:bookings" } as never],
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
97
|
|
|
98
98
|
expect(tenancy).toBe(true);
|
|
99
99
|
expect(tenants).toContain("t1");
|
|
@@ -226,8 +226,6 @@ describe("preview dual test (withDryRun)", () => {
|
|
|
226
226
|
const { recordWouldHaveFired } = await import("../../kernel/dry-run.ts");
|
|
227
227
|
recordWouldHaveFired("send", "booking-confirmed");
|
|
228
228
|
});
|
|
229
|
-
expect(wouldHaveFired).toEqual([
|
|
230
|
-
{ kind: "send", resource: "booking-confirmed" },
|
|
231
|
-
]);
|
|
229
|
+
expect(wouldHaveFired).toEqual([{ kind: "send", resource: "booking-confirmed" }]);
|
|
232
230
|
});
|
|
233
231
|
});
|
|
@@ -4,10 +4,7 @@
|
|
|
4
4
|
* The UI must not reimplement cache invalidation, PII masking, or effects graph.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
readSchemaFingerprint,
|
|
9
|
-
schemaFingerprint,
|
|
10
|
-
} from "../../cli/schema.ts";
|
|
7
|
+
import { readSchemaFingerprint, schemaFingerprint } from "../../cli/schema.ts";
|
|
11
8
|
import {
|
|
12
9
|
memoryFilesDriver,
|
|
13
10
|
memoryIndexDriver,
|
|
@@ -29,16 +26,8 @@ import {
|
|
|
29
26
|
type SqlStoreHandle,
|
|
30
27
|
type StoreRuntime,
|
|
31
28
|
} from "../../elements/store.ts";
|
|
32
|
-
import {
|
|
33
|
-
|
|
34
|
-
withDryRun,
|
|
35
|
-
} from "../../kernel/dry-run.ts";
|
|
36
|
-
import type {
|
|
37
|
-
Effects,
|
|
38
|
-
Manifest,
|
|
39
|
-
ResourceRef,
|
|
40
|
-
StoreFacet,
|
|
41
|
-
} from "../../manifest/types.ts";
|
|
29
|
+
import { DryRunWriteIsolationError, withDryRun } from "../../kernel/dry-run.ts";
|
|
30
|
+
import type { Effects, Manifest, ResourceRef, StoreFacet } from "../../manifest/types.ts";
|
|
42
31
|
import type { WideEvent } from "../../runs/types.ts";
|
|
43
32
|
|
|
44
33
|
/** Whether multi-tenancy is declared on the Manifest (off by default). */
|
|
@@ -114,9 +103,7 @@ export interface ProjectStoresOptions {
|
|
|
114
103
|
*
|
|
115
104
|
* @param options - Manifest, runtime, runs
|
|
116
105
|
*/
|
|
117
|
-
export async function projectStoresList(
|
|
118
|
-
options: ProjectStoresOptions,
|
|
119
|
-
): Promise<{
|
|
106
|
+
export async function projectStoresList(options: ProjectStoresOptions): Promise<{
|
|
120
107
|
readonly stores: readonly ConsoleStoreRow[];
|
|
121
108
|
readonly tenancyDeclared: boolean;
|
|
122
109
|
readonly tenants: readonly string[];
|
|
@@ -146,8 +133,7 @@ export async function projectStoresList(
|
|
|
146
133
|
const facet = store.facet;
|
|
147
134
|
const ref = `${facet}:${name}` as ResourceRef;
|
|
148
135
|
const children = childrenOf(manifest!, name, facet, store);
|
|
149
|
-
const replicaLagMs =
|
|
150
|
-
facet === "sql" ? latestReplicaLag(options.runs ?? [], children) : null;
|
|
136
|
+
const replicaLagMs = facet === "sql" ? latestReplicaLag(options.runs ?? [], children) : null;
|
|
151
137
|
|
|
152
138
|
let warnings: ConsoleStoreRow["warnings"] = [];
|
|
153
139
|
if (facet === "files" && options.runtime) {
|
|
@@ -194,10 +180,7 @@ function childrenOf(
|
|
|
194
180
|
names.push(...Object.keys(store.tables ?? {}));
|
|
195
181
|
// Also surface table suffixes from effects when Manifest tables are sparse.
|
|
196
182
|
for (const flow of Object.values(manifest.flows ?? {})) {
|
|
197
|
-
for (const ref of [
|
|
198
|
-
...(flow.effects?.reads ?? []),
|
|
199
|
-
...(flow.effects?.writes ?? []),
|
|
200
|
-
]) {
|
|
183
|
+
for (const ref of [...(flow.effects?.reads ?? []), ...(flow.effects?.writes ?? [])]) {
|
|
201
184
|
if (ref.startsWith("sql:")) {
|
|
202
185
|
const table = ref.slice(4);
|
|
203
186
|
if (!names.includes(table)) names.push(table);
|
|
@@ -240,11 +223,7 @@ function childrenOf(
|
|
|
240
223
|
});
|
|
241
224
|
}
|
|
242
225
|
|
|
243
|
-
function flowsTouching(
|
|
244
|
-
manifest: Manifest,
|
|
245
|
-
ref: ResourceRef,
|
|
246
|
-
kind: "reads" | "writes",
|
|
247
|
-
): string[] {
|
|
226
|
+
function flowsTouching(manifest: Manifest, ref: ResourceRef, kind: "reads" | "writes"): string[] {
|
|
248
227
|
const out: string[] = [];
|
|
249
228
|
for (const [flowId, flow] of Object.entries(manifest.flows ?? {})) {
|
|
250
229
|
if ((flow.effects?.[kind] ?? []).includes(ref)) out.push(flowId);
|
|
@@ -277,10 +256,7 @@ export function willNotFireFor(
|
|
|
277
256
|
};
|
|
278
257
|
}
|
|
279
258
|
|
|
280
|
-
function piiColumnsFor(
|
|
281
|
-
store: NonNullable<Manifest["stores"]>[string],
|
|
282
|
-
table: string,
|
|
283
|
-
): string[] {
|
|
259
|
+
function piiColumnsFor(store: NonNullable<Manifest["stores"]>[string], table: string): string[] {
|
|
284
260
|
const cols: string[] = [];
|
|
285
261
|
const tableMeta = store.tables?.[table];
|
|
286
262
|
for (const [col, tags] of Object.entries(tableMeta?.columns ?? {})) {
|
|
@@ -309,18 +285,14 @@ function latestReplicaLag(
|
|
|
309
285
|
let lag: number | null = null;
|
|
310
286
|
for (const run of runs) {
|
|
311
287
|
if (run.replicaLagMs == null) continue;
|
|
312
|
-
const touches = (run.effects ?? []).some(
|
|
313
|
-
(e) => refs.has(e.resource as ResourceRef),
|
|
314
|
-
);
|
|
288
|
+
const touches = (run.effects ?? []).some((e) => refs.has(e.resource as ResourceRef));
|
|
315
289
|
if (!touches) continue;
|
|
316
290
|
if (lag === null || run.replicaLagMs > lag) lag = run.replicaLagMs;
|
|
317
291
|
}
|
|
318
292
|
return lag;
|
|
319
293
|
}
|
|
320
294
|
|
|
321
|
-
function collectTenants(
|
|
322
|
-
runs: ReadonlyArray<{ readonly tenant?: string | null }>,
|
|
323
|
-
): string[] {
|
|
295
|
+
function collectTenants(runs: ReadonlyArray<{ readonly tenant?: string | null }>): string[] {
|
|
324
296
|
const set = new Set<string>();
|
|
325
297
|
for (const r of runs) {
|
|
326
298
|
if (r.tenant) set.add(r.tenant);
|
|
@@ -497,13 +469,9 @@ export async function editStore(
|
|
|
497
469
|
},
|
|
498
470
|
): Promise<StoreEditResult> {
|
|
499
471
|
const effectRef = (
|
|
500
|
-
input.child && input.ref.startsWith("sql:")
|
|
501
|
-
? `sql:${input.child}`
|
|
502
|
-
: input.ref
|
|
472
|
+
input.child && input.ref.startsWith("sql:") ? `sql:${input.child}` : input.ref
|
|
503
473
|
) as ResourceRef;
|
|
504
|
-
const writers = manifest
|
|
505
|
-
? flowsTouching(manifest, effectRef, "writes")
|
|
506
|
-
: [];
|
|
474
|
+
const writers = manifest ? flowsTouching(manifest, effectRef, "writes") : [];
|
|
507
475
|
const willNotFire = willNotFireFor(manifest ?? { oke: "1.0", app: "" }, writers);
|
|
508
476
|
|
|
509
477
|
if (options.dryRun) {
|
|
@@ -547,7 +515,12 @@ export async function editStore(
|
|
|
547
515
|
|
|
548
516
|
/** Snapshot of a direct-edit target for dry-run rollback. */
|
|
549
517
|
type EditSnapshot =
|
|
550
|
-
| {
|
|
518
|
+
| {
|
|
519
|
+
readonly kind: "kv";
|
|
520
|
+
readonly ref: ResourceRef;
|
|
521
|
+
readonly key: string;
|
|
522
|
+
readonly value: unknown;
|
|
523
|
+
}
|
|
551
524
|
| {
|
|
552
525
|
readonly kind: "sql";
|
|
553
526
|
readonly ref: ResourceRef;
|
|
@@ -578,10 +551,9 @@ async function snapshotEditTarget(
|
|
|
578
551
|
effects: { reads: [input.ref] },
|
|
579
552
|
})) as SqlStoreHandle;
|
|
580
553
|
try {
|
|
581
|
-
const rows = await sql.raw(
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
);
|
|
554
|
+
const rows = await sql.raw(`SELECT * FROM "${input.child}" WHERE "id" = ? LIMIT 1`, [
|
|
555
|
+
input.id,
|
|
556
|
+
]);
|
|
585
557
|
return {
|
|
586
558
|
kind: "sql",
|
|
587
559
|
ref: input.ref,
|
|
@@ -602,10 +574,7 @@ async function snapshotEditTarget(
|
|
|
602
574
|
return { kind: "none" };
|
|
603
575
|
}
|
|
604
576
|
|
|
605
|
-
async function restoreEditTarget(
|
|
606
|
-
runtime: StoreRuntime,
|
|
607
|
-
snapshot: EditSnapshot,
|
|
608
|
-
): Promise<void> {
|
|
577
|
+
async function restoreEditTarget(runtime: StoreRuntime, snapshot: EditSnapshot): Promise<void> {
|
|
609
578
|
if (snapshot.kind === "kv") {
|
|
610
579
|
const kv = (await runtime.openRef(snapshot.ref, {
|
|
611
580
|
effects: { writes: [snapshot.ref] },
|
|
@@ -623,10 +592,7 @@ async function restoreEditTarget(
|
|
|
623
592
|
})) as SqlStoreHandle;
|
|
624
593
|
if (snapshot.row === null) {
|
|
625
594
|
try {
|
|
626
|
-
await sql.raw(
|
|
627
|
-
`DELETE FROM "${snapshot.child}" WHERE "id" = ?`,
|
|
628
|
-
[snapshot.id],
|
|
629
|
-
);
|
|
595
|
+
await sql.raw(`DELETE FROM "${snapshot.child}" WHERE "id" = ?`, [snapshot.id]);
|
|
630
596
|
} catch {
|
|
631
597
|
/* table may not exist */
|
|
632
598
|
}
|
|
@@ -635,10 +601,10 @@ async function restoreEditTarget(
|
|
|
635
601
|
const cols = Object.keys(snapshot.row);
|
|
636
602
|
const assignments = cols.map((c) => `"${c}" = ?`).join(", ");
|
|
637
603
|
try {
|
|
638
|
-
await sql.raw(
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
);
|
|
604
|
+
await sql.raw(`UPDATE "${snapshot.child}" SET ${assignments} WHERE "id" = ?`, [
|
|
605
|
+
...cols.map((c) => snapshot.row![c]),
|
|
606
|
+
snapshot.id,
|
|
607
|
+
]);
|
|
642
608
|
} catch {
|
|
643
609
|
/* best-effort restore */
|
|
644
610
|
}
|
|
@@ -673,10 +639,7 @@ async function applyEdit(
|
|
|
673
639
|
if (sets.length === 0) return;
|
|
674
640
|
const assignments = sets.map((c) => `"${c}" = ?`).join(", ");
|
|
675
641
|
const params = [...sets.map((c) => input.patch[c]), id];
|
|
676
|
-
await sql.raw(
|
|
677
|
-
`UPDATE "${table}" SET ${assignments} WHERE "id" = ?`,
|
|
678
|
-
params,
|
|
679
|
-
);
|
|
642
|
+
await sql.raw(`UPDATE "${table}" SET ${assignments} WHERE "id" = ?`, params);
|
|
680
643
|
return;
|
|
681
644
|
}
|
|
682
645
|
|
|
@@ -786,14 +749,9 @@ export async function runStoreSql(
|
|
|
786
749
|
readonly routedRole: "primary" | "replica";
|
|
787
750
|
}> {
|
|
788
751
|
const trimmed = sqlText.trim();
|
|
789
|
-
const isWrite =
|
|
790
|
-
/^(INSERT|UPDATE|DELETE|DROP|ALTER|CREATE|TRUNCATE|REPLACE)\b/i.test(
|
|
791
|
-
trimmed,
|
|
792
|
-
);
|
|
752
|
+
const isWrite = /^(INSERT|UPDATE|DELETE|DROP|ALTER|CREATE|TRUNCATE|REPLACE)\b/i.test(trimmed);
|
|
793
753
|
if (isWrite && !options.allowWrite) {
|
|
794
|
-
throw new Error(
|
|
795
|
-
"SQL console is read-only by default — write requires console:store.sql:write",
|
|
796
|
-
);
|
|
754
|
+
throw new Error("SQL console is read-only by default — write requires console:store.sql:write");
|
|
797
755
|
}
|
|
798
756
|
const handle = (await runtime.openRef(ref, {
|
|
799
757
|
effects: isWrite ? { writes: [ref] } : { reads: [ref] },
|
|
@@ -814,10 +772,7 @@ export async function runStoreSql(
|
|
|
814
772
|
* @param key - Cache key
|
|
815
773
|
* @param writeRef - Written resource
|
|
816
774
|
*/
|
|
817
|
-
export function cacheKeyInvalidatedBy(
|
|
818
|
-
key: string,
|
|
819
|
-
writeRef: ResourceRef,
|
|
820
|
-
): boolean {
|
|
775
|
+
export function cacheKeyInvalidatedBy(key: string, writeRef: ResourceRef): boolean {
|
|
821
776
|
return isInvalidatedByWrite(key, { writes: [writeRef] });
|
|
822
777
|
}
|
|
823
778
|
|
|
@@ -4,15 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
import { describe, expect, test } from "bun:test";
|
|
6
6
|
import { memoryVaultDriver } from "../../drivers/index.ts";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
fingerprintSecretSync,
|
|
10
|
-
vault,
|
|
11
|
-
} from "../../elements/vault.ts";
|
|
12
|
-
import {
|
|
13
|
-
createMemoryJournalStore,
|
|
14
|
-
type JournalRun,
|
|
15
|
-
} from "../../kernel/journal.ts";
|
|
7
|
+
import { createVaultRuntime, fingerprintSecretSync, vault } from "../../elements/vault.ts";
|
|
8
|
+
import { createMemoryJournalStore, type JournalRun } from "../../kernel/journal.ts";
|
|
16
9
|
import type { Manifest } from "../../manifest/types.ts";
|
|
17
10
|
import {
|
|
18
11
|
assertNoSecretLeak,
|
|
@@ -82,13 +75,13 @@ describe("projectVaultList", () => {
|
|
|
82
75
|
const { secrets, env } = await projectVaultList({
|
|
83
76
|
manifest: manifest(),
|
|
84
77
|
runtime: rt,
|
|
85
|
-
env: "
|
|
78
|
+
env: "local",
|
|
86
79
|
peerFingerprints: {
|
|
87
80
|
STRIPE_KEY: { staging: fingerprintSecretSync(SECRET) },
|
|
88
81
|
},
|
|
89
82
|
});
|
|
90
83
|
|
|
91
|
-
expect(env).toBe("
|
|
84
|
+
expect(env).toBe("local");
|
|
92
85
|
const stripe = secrets.find((s) => s.name === "STRIPE_KEY");
|
|
93
86
|
const pub = secrets.find((s) => s.name === "PUBLIC_APP_URL");
|
|
94
87
|
expect(stripe?.sensitive).toBe(true);
|
|
@@ -131,16 +124,12 @@ describe("projectVaultList", () => {
|
|
|
131
124
|
const { secrets } = await projectVaultList({
|
|
132
125
|
manifest: null,
|
|
133
126
|
runtime: rt,
|
|
134
|
-
env: "
|
|
127
|
+
env: "local",
|
|
135
128
|
});
|
|
136
129
|
const row = secrets.find((s) => s.name === "KEY");
|
|
137
130
|
expect(row?.winner).toBe(".env.local");
|
|
138
|
-
expect(row?.resolution.find((s) => s.source === ".env.local")?.won).toBe(
|
|
139
|
-
|
|
140
|
-
);
|
|
141
|
-
expect(row?.resolution.find((s) => s.source === "driver")?.present).toBe(
|
|
142
|
-
true,
|
|
143
|
-
);
|
|
131
|
+
expect(row?.resolution.find((s) => s.source === ".env.local")?.won).toBe(true);
|
|
132
|
+
expect(row?.resolution.find((s) => s.source === "driver")?.present).toBe(true);
|
|
144
133
|
expect(row?.resolution.find((s) => s.source === "driver")?.won).toBe(false);
|
|
145
134
|
});
|
|
146
135
|
|
|
@@ -152,11 +141,9 @@ describe("projectVaultList", () => {
|
|
|
152
141
|
const { secrets } = await projectVaultList({
|
|
153
142
|
manifest: manifest(),
|
|
154
143
|
runtime: rt,
|
|
155
|
-
env: "
|
|
144
|
+
env: "local",
|
|
156
145
|
});
|
|
157
|
-
expect(secrets.find((s) => s.name === "STRIPE_KEY")?.lastReadAt).toBe(
|
|
158
|
-
1_700_000_000_000,
|
|
159
|
-
);
|
|
146
|
+
expect(secrets.find((s) => s.name === "STRIPE_KEY")?.lastReadAt).toBe(1_700_000_000_000);
|
|
160
147
|
});
|
|
161
148
|
|
|
162
149
|
test("blast radius queries journal — count + longest wake", async () => {
|
|
@@ -215,12 +202,10 @@ describe("projectVaultList", () => {
|
|
|
215
202
|
manifest: manifest(),
|
|
216
203
|
runtime: rt,
|
|
217
204
|
journal,
|
|
218
|
-
env: "
|
|
205
|
+
env: "local",
|
|
219
206
|
now: () => now,
|
|
220
207
|
});
|
|
221
|
-
expect(secrets.find((s) => s.name === "STRIPE_KEY")?.blastRadius.count).toBe(
|
|
222
|
-
2,
|
|
223
|
-
);
|
|
208
|
+
expect(secrets.find((s) => s.name === "STRIPE_KEY")?.blastRadius.count).toBe(2);
|
|
224
209
|
});
|
|
225
210
|
});
|
|
226
211
|
|
|
@@ -234,9 +219,7 @@ describe("set / rotate", () => {
|
|
|
234
219
|
});
|
|
235
220
|
expect(result.name).toBe("STRIPE_KEY");
|
|
236
221
|
expect(result.fingerprint).not.toBe(before);
|
|
237
|
-
expect(result.fingerprint).toBe(
|
|
238
|
-
fingerprintSecretSync("sk_rotated_value_xyz"),
|
|
239
|
-
);
|
|
222
|
+
expect(result.fingerprint).toBe(fingerprintSecretSync("sk_rotated_value_xyz"));
|
|
240
223
|
expect(JSON.stringify(result)).not.toContain("sk_rotated_value_xyz");
|
|
241
224
|
});
|
|
242
225
|
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
type VaultRuntime,
|
|
18
18
|
type VaultSecretDecl,
|
|
19
19
|
} from "../../elements/vault.ts";
|
|
20
|
+
import { resolveComposeEnvPath } from "../../elements/vault/chain.ts";
|
|
20
21
|
import type { JournalRun, JournalStore } from "../../kernel/journal.ts";
|
|
21
22
|
import type { Manifest } from "../../manifest/types.ts";
|
|
22
23
|
|
|
@@ -24,9 +25,7 @@ import type { Manifest } from "../../manifest/types.ts";
|
|
|
24
25
|
export type VaultEnvLabel = ConfigEnv | "staging" | (string & {});
|
|
25
26
|
|
|
26
27
|
/** Fingerprints keyed by environment — never values. */
|
|
27
|
-
export type VaultFingerprintsByEnv = Readonly<
|
|
28
|
-
Partial<Record<VaultEnvLabel, string>>
|
|
29
|
-
>;
|
|
28
|
+
export type VaultFingerprintsByEnv = Readonly<Partial<Record<VaultEnvLabel, string>>>;
|
|
30
29
|
|
|
31
30
|
/** Rotation blast radius from the durable journal (queried, not estimated). */
|
|
32
31
|
export interface ConsoleVaultBlastRadius {
|
|
@@ -84,9 +83,7 @@ export interface ProjectVaultOptions {
|
|
|
84
83
|
* Optional peer-environment fingerprints (e.g. staging from a remote
|
|
85
84
|
* probe). Never values — fingerprints only.
|
|
86
85
|
*/
|
|
87
|
-
readonly peerFingerprints?: Readonly<
|
|
88
|
-
Record<string, VaultFingerprintsByEnv>
|
|
89
|
-
>;
|
|
86
|
+
readonly peerFingerprints?: Readonly<Record<string, VaultFingerprintsByEnv>>;
|
|
90
87
|
/** Durable journal — blast radius is queried, not estimated. */
|
|
91
88
|
readonly journal?: JournalStore | null;
|
|
92
89
|
readonly now?: () => number;
|
|
@@ -97,13 +94,11 @@ export interface ProjectVaultOptions {
|
|
|
97
94
|
*
|
|
98
95
|
* @param options - Manifest, runtime, journal
|
|
99
96
|
*/
|
|
100
|
-
export async function projectVaultList(
|
|
101
|
-
options: ProjectVaultOptions,
|
|
102
|
-
): Promise<{
|
|
97
|
+
export async function projectVaultList(options: ProjectVaultOptions): Promise<{
|
|
103
98
|
readonly secrets: readonly ConsoleVaultRow[];
|
|
104
99
|
readonly env: VaultEnvLabel;
|
|
105
100
|
}> {
|
|
106
|
-
const env = options.env ?? "
|
|
101
|
+
const env = options.env ?? "local";
|
|
107
102
|
const now = options.now ?? (() => Date.now());
|
|
108
103
|
const names = collectNames(options.manifest, options.runtime);
|
|
109
104
|
const journalRuns = options.journal
|
|
@@ -115,11 +110,7 @@ export async function projectVaultList(
|
|
|
115
110
|
const contract = contractOf(name, options.manifest, options.runtime);
|
|
116
111
|
const sensitive = contract.sensitive;
|
|
117
112
|
const readers = readersOf(options.manifest, name);
|
|
118
|
-
const blastRadius = blastRadiusOf(
|
|
119
|
-
journalRuns,
|
|
120
|
-
readers,
|
|
121
|
-
now(),
|
|
122
|
-
);
|
|
113
|
+
const blastRadius = blastRadiusOf(journalRuns, readers, now());
|
|
123
114
|
const winner = options.runtime?.resolution(name) ?? null;
|
|
124
115
|
const resolution = options.runtime?.resolutionChain(name) ?? [];
|
|
125
116
|
const lastReadAt = options.runtime?.lastReadAt(name) ?? null;
|
|
@@ -141,17 +132,13 @@ export async function projectVaultList(
|
|
|
141
132
|
cleartext = options.runtime?.cleartext(name) ?? null;
|
|
142
133
|
}
|
|
143
134
|
|
|
144
|
-
const sharedFingerprintEnvs = sensitive
|
|
145
|
-
? sharedEnvs(fingerprints, env, fingerprint)
|
|
146
|
-
: [];
|
|
135
|
+
const sharedFingerprintEnvs = sensitive ? sharedEnvs(fingerprints, env, fingerprint) : [];
|
|
147
136
|
|
|
148
137
|
secrets.push({
|
|
149
138
|
name,
|
|
150
139
|
kind: contract.kind,
|
|
151
140
|
sensitive,
|
|
152
|
-
...(contract.description !== undefined
|
|
153
|
-
? { description: contract.description }
|
|
154
|
-
: {}),
|
|
141
|
+
...(contract.description !== undefined ? { description: contract.description } : {}),
|
|
155
142
|
...(contract.rotate !== undefined ? { rotate: contract.rotate } : {}),
|
|
156
143
|
fingerprints,
|
|
157
144
|
fingerprint,
|
|
@@ -187,9 +174,7 @@ export function setVaultValue(
|
|
|
187
174
|
runtime.put(input.name, input.value);
|
|
188
175
|
return {
|
|
189
176
|
name: input.name,
|
|
190
|
-
fingerprint: runtime.isSensitive(input.name)
|
|
191
|
-
? (runtime.fingerprint(input.name) ?? null)
|
|
192
|
-
: null,
|
|
177
|
+
fingerprint: runtime.isSensitive(input.name) ? (runtime.fingerprint(input.name) ?? null) : null,
|
|
193
178
|
};
|
|
194
179
|
}
|
|
195
180
|
|
|
@@ -209,7 +194,7 @@ export function rotateVaultValue(
|
|
|
209
194
|
/**
|
|
210
195
|
* Build a VaultRuntime from Manifest contracts when no host runtime is attached.
|
|
211
196
|
*
|
|
212
|
-
* Uses the standard resolution chain: process.env → .env.local → .env.
|
|
197
|
+
* Uses the standard resolution chain: process.env → .env.local → .env.docker
|
|
213
198
|
* → memory driver → (optional) dev fallback. Does not parse dotenv in the UI.
|
|
214
199
|
*
|
|
215
200
|
* @param manifest - Manifest snapshot
|
|
@@ -248,10 +233,10 @@ export async function createManifestVaultRuntime(
|
|
|
248
233
|
});
|
|
249
234
|
|
|
250
235
|
const seed = options.seed ?? {};
|
|
236
|
+
const composeEnv = resolveComposeEnvPath(cwd);
|
|
251
237
|
const runtime = createVaultRuntime({
|
|
252
238
|
secrets,
|
|
253
|
-
allowDevFallbacks:
|
|
254
|
-
options.allowDevFallbacks ?? (options.env ?? "dev") !== "prod",
|
|
239
|
+
allowDevFallbacks: options.allowDevFallbacks ?? (options.env ?? "local") !== "prod",
|
|
255
240
|
now: options.now,
|
|
256
241
|
chain: [
|
|
257
242
|
{ driver: envVaultDriver, source: "process.env" },
|
|
@@ -262,8 +247,8 @@ export async function createManifestVaultRuntime(
|
|
|
262
247
|
},
|
|
263
248
|
{
|
|
264
249
|
driver: envVaultDriver,
|
|
265
|
-
source:
|
|
266
|
-
options: { path:
|
|
250
|
+
source: composeEnv.source,
|
|
251
|
+
options: { path: composeEnv.path },
|
|
267
252
|
},
|
|
268
253
|
{
|
|
269
254
|
driver: memoryVaultDriver,
|
|
@@ -290,10 +275,7 @@ export function blastRadiusOf(
|
|
|
290
275
|
): ConsoleVaultBlastRadius {
|
|
291
276
|
const readers = new Set(readerFlowIds);
|
|
292
277
|
const affected = runs.filter(
|
|
293
|
-
(r) =>
|
|
294
|
-
r.status === "sleeping" &&
|
|
295
|
-
r.wakeAt != null &&
|
|
296
|
-
readers.has(r.flow),
|
|
278
|
+
(r) => r.status === "sleeping" && r.wakeAt != null && readers.has(r.flow),
|
|
297
279
|
);
|
|
298
280
|
if (affected.length === 0) {
|
|
299
281
|
return {
|
|
@@ -323,10 +305,7 @@ export function blastRadiusOf(
|
|
|
323
305
|
* @param manifest - Manifest
|
|
324
306
|
* @param name - Secret name
|
|
325
307
|
*/
|
|
326
|
-
export function readersOf(
|
|
327
|
-
manifest: Manifest | null,
|
|
328
|
-
name: string,
|
|
329
|
-
): readonly string[] {
|
|
308
|
+
export function readersOf(manifest: Manifest | null, name: string): readonly string[] {
|
|
330
309
|
if (!manifest?.flows) return [];
|
|
331
310
|
const out: string[] = [];
|
|
332
311
|
for (const [flowId, flow] of Object.entries(manifest.flows)) {
|
|
@@ -339,10 +318,7 @@ export function readersOf(
|
|
|
339
318
|
* @param manifest - Manifest
|
|
340
319
|
* @param runtime - Runtime
|
|
341
320
|
*/
|
|
342
|
-
function collectNames(
|
|
343
|
-
manifest: Manifest | null,
|
|
344
|
-
runtime: VaultRuntime | null,
|
|
345
|
-
): readonly string[] {
|
|
321
|
+
function collectNames(manifest: Manifest | null, runtime: VaultRuntime | null): readonly string[] {
|
|
346
322
|
const set = new Set<string>();
|
|
347
323
|
for (const name of Object.keys(manifest?.vault ?? {})) set.add(name);
|
|
348
324
|
if (runtime) {
|
|
@@ -372,12 +348,8 @@ function contractOf(
|
|
|
372
348
|
return {
|
|
373
349
|
kind: fromRuntime.kind,
|
|
374
350
|
sensitive: fromRuntime.sensitive,
|
|
375
|
-
...(fromRuntime.description !== undefined
|
|
376
|
-
|
|
377
|
-
: {}),
|
|
378
|
-
...(fromRuntime.rotate !== undefined
|
|
379
|
-
? { rotate: fromRuntime.rotate }
|
|
380
|
-
: {}),
|
|
351
|
+
...(fromRuntime.description !== undefined ? { description: fromRuntime.description } : {}),
|
|
352
|
+
...(fromRuntime.rotate !== undefined ? { rotate: fromRuntime.rotate } : {}),
|
|
381
353
|
};
|
|
382
354
|
}
|
|
383
355
|
const fromManifest = manifest?.vault?.[name];
|
|
@@ -385,12 +357,8 @@ function contractOf(
|
|
|
385
357
|
return {
|
|
386
358
|
kind: sensitive ? "secret" : "config",
|
|
387
359
|
sensitive,
|
|
388
|
-
...(fromManifest?.description !== undefined
|
|
389
|
-
|
|
390
|
-
: {}),
|
|
391
|
-
...(fromManifest?.rotate !== undefined
|
|
392
|
-
? { rotate: fromManifest.rotate }
|
|
393
|
-
: {}),
|
|
360
|
+
...(fromManifest?.description !== undefined ? { description: fromManifest.description } : {}),
|
|
361
|
+
...(fromManifest?.rotate !== undefined ? { rotate: fromManifest.rotate } : {}),
|
|
394
362
|
};
|
|
395
363
|
}
|
|
396
364
|
|
|
@@ -414,17 +382,12 @@ function sharedEnvs(
|
|
|
414
382
|
}
|
|
415
383
|
|
|
416
384
|
/** Assert a Console row never embeds a secret value (tests / export safety). */
|
|
417
|
-
export function assertNoSecretLeak(
|
|
418
|
-
row: ConsoleVaultRow,
|
|
419
|
-
knownSecrets: readonly string[],
|
|
420
|
-
): void {
|
|
385
|
+
export function assertNoSecretLeak(row: ConsoleVaultRow, knownSecrets: readonly string[]): void {
|
|
421
386
|
const blob = JSON.stringify(row);
|
|
422
387
|
for (const secret of knownSecrets) {
|
|
423
388
|
if (secret.length === 0) continue;
|
|
424
389
|
if (blob.includes(secret)) {
|
|
425
|
-
throw new Error(
|
|
426
|
-
`vault console leak: secret value appears in row for ${row.name}`,
|
|
427
|
-
);
|
|
390
|
+
throw new Error(`vault console leak: secret value appears in row for ${row.name}`);
|
|
428
391
|
}
|
|
429
392
|
}
|
|
430
393
|
}
|
|
@@ -3,16 +3,9 @@
|
|
|
3
3
|
* (console §9.14).
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
ONCE_SECRET_ACK_LABEL,
|
|
8
|
-
ONCE_SECRET_WARNING,
|
|
9
|
-
} from "./acknowledgement.ts";
|
|
6
|
+
import { ONCE_SECRET_ACK_LABEL, ONCE_SECRET_WARNING } from "./acknowledgement.ts";
|
|
10
7
|
import { formatAccessBlastRadius } from "./blast-radius.ts";
|
|
11
|
-
import {
|
|
12
|
-
ACCESS_BLAST_FIXTURE,
|
|
13
|
-
ACCESS_EFFECTIVE_FIXTURE,
|
|
14
|
-
ACCESS_LIST_FIXTURE,
|
|
15
|
-
} from "./fixture.ts";
|
|
8
|
+
import { ACCESS_BLAST_FIXTURE, ACCESS_EFFECTIVE_FIXTURE, ACCESS_LIST_FIXTURE } from "./fixture.ts";
|
|
16
9
|
import { hygieneLines } from "./hygiene.ts";
|
|
17
10
|
import { formatProvenance } from "./provenance.ts";
|
|
18
11
|
|
|
@@ -34,9 +27,7 @@ export interface AccessA11yViewProps {
|
|
|
34
27
|
export function AccessA11yView(props: AccessA11yViewProps) {
|
|
35
28
|
const plane = props.plane ?? "user";
|
|
36
29
|
const section =
|
|
37
|
-
plane === "operator"
|
|
38
|
-
? ACCESS_LIST_FIXTURE.operatorPlane
|
|
39
|
-
: ACCESS_LIST_FIXTURE.userPlane;
|
|
30
|
+
plane === "operator" ? ACCESS_LIST_FIXTURE.operatorPlane : ACCESS_LIST_FIXTURE.userPlane;
|
|
40
31
|
const openKeyId = props.openKeyId ?? "key_demo";
|
|
41
32
|
const openKey = section.keys.find((k) => k.id === openKeyId);
|
|
42
33
|
const blast = formatAccessBlastRadius(ACCESS_BLAST_FIXTURE);
|
|
@@ -86,9 +77,7 @@ export function AccessA11yView(props: AccessA11yViewProps) {
|
|
|
86
77
|
<li key={op.id}>
|
|
87
78
|
<button type="button" style={{ minHeight: 32, width: "100%" }}>
|
|
88
79
|
{op.name} ({op.email})
|
|
89
|
-
{op.neverSignedIn ?
|
|
90
|
-
<span role="status"> never signed in</span>
|
|
91
|
-
) : null}
|
|
80
|
+
{op.neverSignedIn ? <span role="status"> never signed in</span> : null}
|
|
92
81
|
</button>
|
|
93
82
|
</li>
|
|
94
83
|
))}
|
|
@@ -135,9 +124,7 @@ export function AccessA11yView(props: AccessA11yViewProps) {
|
|
|
135
124
|
style={{ minHeight: 32, width: "100%" }}
|
|
136
125
|
>
|
|
137
126
|
{k.name}
|
|
138
|
-
{k.unused90d ?
|
|
139
|
-
<span role="status"> unused 90d+</span>
|
|
140
|
-
) : null}
|
|
127
|
+
{k.unused90d ? <span role="status"> unused 90d+</span> : null}
|
|
141
128
|
</button>
|
|
142
129
|
</li>
|
|
143
130
|
))}
|
|
@@ -146,9 +133,7 @@ export function AccessA11yView(props: AccessA11yViewProps) {
|
|
|
146
133
|
|
|
147
134
|
<section aria-label="Grantable scopes">
|
|
148
135
|
<h3>Grantable scopes</h3>
|
|
149
|
-
<p>
|
|
150
|
-
Only scopes you hold appear — impossibility taught by absence
|
|
151
|
-
</p>
|
|
136
|
+
<p>Only scopes you hold appear — impossibility taught by absence</p>
|
|
152
137
|
<ul>
|
|
153
138
|
{section.grantableScopes.map((s) => (
|
|
154
139
|
<li key={s}>
|
|
@@ -16,8 +16,7 @@ describe("Access panel accessibility", () => {
|
|
|
16
16
|
let container: HTMLElement;
|
|
17
17
|
|
|
18
18
|
beforeEach(() => {
|
|
19
|
-
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT =
|
|
20
|
-
true;
|
|
19
|
+
(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true;
|
|
21
20
|
window = new Window({ url: "http://console.test/access" });
|
|
22
21
|
Object.defineProperty(globalThis, "window", {
|
|
23
22
|
value: window,
|
|
@@ -70,13 +69,7 @@ describe("Access panel accessibility", () => {
|
|
|
70
69
|
|
|
71
70
|
test("axe reports zero violations at WCAG 2.2 AA (user plane + once secret)", async () => {
|
|
72
71
|
await act(async () => {
|
|
73
|
-
root.render(
|
|
74
|
-
<AccessA11yView
|
|
75
|
-
plane="user"
|
|
76
|
-
openKeyId="key_demo"
|
|
77
|
-
showOnceSecret
|
|
78
|
-
/>,
|
|
79
|
-
);
|
|
72
|
+
root.render(<AccessA11yView plane="user" openKeyId="key_demo" showOnceSecret />);
|
|
80
73
|
});
|
|
81
74
|
|
|
82
75
|
await new Promise((r) => setTimeout(r, 10));
|
|
@@ -103,9 +96,7 @@ describe("Access panel accessibility", () => {
|
|
|
103
96
|
|
|
104
97
|
test("axe reports zero violations at WCAG 2.2 AA (operator plane)", async () => {
|
|
105
98
|
await act(async () => {
|
|
106
|
-
root.render(
|
|
107
|
-
<AccessA11yView plane="operator" openKeyId="key_ops" />,
|
|
108
|
-
);
|
|
99
|
+
root.render(<AccessA11yView plane="operator" openKeyId="key_ops" />);
|
|
109
100
|
});
|
|
110
101
|
|
|
111
102
|
await new Promise((r) => setTimeout(r, 10));
|