okengine 0.11.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/manifest.v1.schema.json +1 -1
- package/package.json +57 -3
- package/site/content/docs/ai/index.mdx +2 -2
- package/site/content/docs/ai/llms-txt.mdx +21 -16
- package/site/content/docs/ai/mcp.mdx +1 -1
- package/site/content/docs/ai/skills.mdx +16 -14
- package/site/content/docs/deployment/docker-swarm.mdx +7 -8
- package/site/content/docs/deployment/docker.mdx +20 -12
- package/site/content/docs/deployment/index.mdx +2 -2
- package/site/content/docs/deployment/kubernetes.mdx +2 -2
- package/site/content/docs/deployment/reverse-proxy.mdx +39 -21
- package/site/content/docs/elements/ai.mdx +25 -15
- package/site/content/docs/elements/channel.mdx +2 -2
- package/site/content/docs/elements/clock.mdx +11 -1
- package/site/content/docs/elements/flow.mdx +66 -16
- package/site/content/docs/elements/gate.mdx +47 -39
- package/site/content/docs/elements/signal.mdx +2 -2
- package/site/content/docs/elements/store.mdx +211 -48
- package/site/content/docs/elements/vault.mdx +126 -41
- package/site/content/docs/get-started/basic-usage.mdx +14 -6
- package/site/content/docs/get-started/installation.mdx +24 -16
- package/site/content/docs/plugins/cors.mdx +9 -9
- package/site/content/docs/plugins/csrf.mdx +1 -1
- package/site/content/docs/providers/cockroachdb.mdx +13 -0
- package/site/content/docs/providers/index.mdx +1 -0
- package/site/content/docs/providers/neon.mdx +22 -0
- package/site/content/docs/providers/supabase.mdx +17 -0
- package/site/content/docs/providers/yugabytedb.mdx +15 -0
- package/site/content/docs/recipes/caddy.mdx +3 -3
- package/site/content/docs/recipes/cockroachdb.mdx +8 -2
- package/site/content/docs/recipes/dragonfly.mdx +4 -3
- package/site/content/docs/recipes/index.mdx +6 -1
- package/site/content/docs/recipes/llama-cpp.mdx +5 -6
- package/site/content/docs/recipes/mailpit.mdx +3 -3
- package/site/content/docs/recipes/meilisearch.mdx +4 -4
- package/site/content/docs/recipes/meta.json +1 -0
- package/site/content/docs/recipes/nginx.mdx +117 -0
- package/site/content/docs/recipes/ollama.mdx +3 -3
- package/site/content/docs/recipes/pgdog.mdx +1 -1
- package/site/content/docs/recipes/postgres.mdx +44 -8
- package/site/content/docs/recipes/redis.mdx +11 -7
- package/site/content/docs/recipes/rustfs.mdx +4 -4
- package/site/content/docs/recipes/sglang.mdx +2 -2
- package/site/content/docs/recipes/supabase-docker.mdx +24 -0
- package/site/content/docs/recipes/timescale.mdx +30 -6
- package/site/content/docs/recipes/traefik.mdx +10 -7
- package/site/content/docs/recipes/valkey.mdx +5 -3
- package/site/content/docs/recipes/vllm.mdx +2 -2
- package/site/content/docs/recipes/yugabytedb.mdx +7 -1
- package/site/content/docs/reference/cli.md +67 -34
- package/site/content/docs/reference/client.mdx +39 -20
- package/site/content/docs/reference/configuration.mdx +34 -25
- package/site/content/docs/reference/environment-variables.mdx +28 -25
- package/site/content/docs/reference/errors.mdx +25 -20
- package/site/content/docs/reference/fx.mdx +19 -12
- package/site/content/docs/reference/plugins.mdx +2 -2
- package/site/content/docs/reference/security.md +16 -7
- package/src/auth/auth.test.ts +2 -2
- package/src/auth/bindings.ts +5 -5
- package/src/auth/config.ts +8 -0
- package/src/auth/gate-auth.test.ts +5 -5
- package/src/auth/index.ts +3 -0
- package/src/auth/operator.ts +1 -1
- package/src/auth/password-policy.test.ts +142 -5
- package/src/auth/password-policy.ts +128 -12
- package/src/auth/plugin.ts +2 -2
- package/src/cli/ai-setup/ai-setup.test.ts +1 -1
- package/src/cli/ai-setup/apply.ts +3 -18
- package/src/cli/ai-setup/index.ts +4 -4
- package/src/cli/ai-setup/prompts.ts +1 -1
- package/src/cli/ask-seed.test.ts +27 -0
- package/src/cli/ask-seed.ts +11 -7
- package/src/cli/attach-host-console.test.ts +134 -0
- package/src/cli/attach-host-console.ts +100 -0
- package/src/cli/console-cmd.test.ts +81 -0
- package/src/cli/console-cmd.ts +107 -0
- package/src/cli/db-seed.ts +14 -3
- package/src/cli/db.test.ts +37 -2
- package/src/cli/db.ts +26 -0
- package/src/cli/dev-app-runner.ts +6 -40
- package/src/cli/dev-console-vite.test.ts +86 -0
- package/src/cli/dev-console-vite.ts +164 -0
- package/src/cli/dev-schema-sync.ts +2 -2
- package/src/cli/dev.test.ts +78 -2
- package/src/cli/dev.ts +170 -56
- package/src/cli/docker-cli.test.ts +2 -2
- package/src/cli/docker.ts +1 -1
- package/src/cli/doctor.ts +2 -1
- package/src/cli/drizzle-env.test.ts +4 -9
- package/src/cli/drizzle-env.ts +2 -2
- package/src/cli/hero-meta.test.ts +37 -0
- package/src/cli/hero-meta.ts +30 -9
- package/src/cli/index.ts +5 -0
- package/src/cli/load-config.images.test.ts +13 -12
- package/src/cli/load-config.ts +1 -1
- package/src/cli/project-state.test.ts +6 -2
- package/src/cli/project-state.ts +27 -11
- package/src/cli/registry.ts +11 -0
- package/src/cli/replay.ts +7 -2
- package/src/cli/vault-cmd.test.ts +2 -0
- package/src/cli/vault-cmd.ts +7 -2
- package/src/client/create.test.ts +38 -2
- package/src/client/create.ts +16 -11
- package/src/client/index.ts +6 -0
- package/src/client/pager.test.ts +66 -0
- package/src/client/pager.ts +138 -0
- package/src/client/transport.ts +9 -6
- package/src/client/types.ts +58 -10
- package/src/compiler/aot.test.ts +12 -2
- package/src/compiler/effects-infer.ts +13 -4
- package/src/compiler/extract.test.ts +257 -5
- package/src/compiler/extract.ts +324 -58
- package/src/compiler/fixtures/skyport/src/flows/bookings/index.ts +2 -2
- package/src/compiler/fixtures/skyport/src/gates.ts +2 -0
- package/src/compiler/fixtures/skyport.expected.json +4 -0
- package/src/config/driver-defaults.test.ts +3 -0
- package/src/config/driver-defaults.ts +14 -0
- package/src/config/index.ts +5 -0
- package/src/console/budget.test.ts +27 -37
- package/src/console/index.ts +3 -0
- package/src/console/password-policy.ts +89 -0
- package/src/console/server/app.ts +138 -12
- package/src/console/server/auth-rate.test.ts +3 -3
- package/src/console/server/auth-store.test.ts +222 -0
- package/src/console/server/auth-store.ts +499 -0
- package/src/console/server/bind.ts +2 -3
- package/src/console/server/channels.test.ts +1 -1
- package/src/console/server/claim.test.ts +60 -1
- package/src/console/server/claim.ts +137 -2
- package/src/console/server/console.test.ts +102 -6
- package/src/console/server/dry-run.audit.test.ts +5 -2
- package/src/console/server/files-catalog.test.ts +51 -0
- package/src/console/server/files-catalog.ts +122 -0
- package/src/console/server/flows-invoke.test.ts +655 -38
- package/src/console/server/flows.ts +907 -90
- package/src/console/server/gates.test.ts +59 -0
- package/src/console/server/gates.ts +17 -14
- package/src/console/server/i18n.ts +7 -4
- package/src/console/server/index-search.test.ts +57 -0
- package/src/console/server/index-search.ts +102 -0
- package/src/console/server/index.ts +32 -1
- package/src/console/server/instances.test.ts +68 -0
- package/src/console/server/instances.ts +58 -0
- package/src/console/server/invoke-user-flow.test.ts +206 -0
- package/src/console/server/invoke-user-flow.ts +367 -0
- package/src/console/server/live.test.ts +44 -1
- package/src/console/server/live.ts +16 -0
- package/src/console/server/operator-db.test.ts +5 -5
- package/src/console/server/operator-db.ts +2 -2
- package/src/console/server/panel-load.ts +1 -0
- package/src/console/server/plugin.ts +12 -2
- package/src/console/server/runs-history.test.ts +143 -0
- package/src/console/server/runs-ingest.test.ts +379 -0
- package/src/console/server/runs-ingest.ts +127 -0
- package/src/console/server/runs-list-nesting.test.ts +97 -0
- package/src/console/server/runs-pii.test.ts +69 -0
- package/src/console/server/runs-pii.ts +50 -4
- package/src/console/server/runs-query-guard.test.ts +75 -0
- package/src/console/server/runs-query-guard.ts +224 -0
- package/src/console/server/runs-query-mask.test.ts +37 -0
- package/src/console/server/runs-query-mask.ts +82 -0
- package/src/console/server/runs-query.test.ts +287 -0
- package/src/console/server/runs-query.ts +107 -0
- package/src/console/server/security-headers.ts +21 -2
- package/src/console/server/security.gate.test.ts +306 -3
- package/src/console/server/serve.ts +138 -9
- package/src/console/server/spa-paths.test.ts +36 -0
- package/src/console/server/spa-proxy.test.ts +86 -0
- package/src/console/server/sql-catalog.ts +572 -0
- package/src/console/server/sql-extension.test.ts +19 -0
- package/src/console/server/sql-rls.test.ts +44 -0
- package/src/console/server/state.ts +445 -7
- package/src/console/server/store-kv-stats.test.ts +178 -0
- package/src/console/server/store-kv-stats.ts +339 -0
- package/src/console/server/store-stats.test.ts +165 -0
- package/src/console/server/store-stats.ts +526 -0
- package/src/console/server/store.test.ts +930 -0
- package/src/console/server/store.ts +859 -76
- package/src/console/server/traces-replay.test.ts +212 -0
- package/src/console/server/vault-http.test.ts +458 -0
- package/src/console/server/vault-overlay.test.ts +49 -0
- package/src/console/server/vault-overlay.ts +99 -0
- package/src/console/server/vault.test.ts +75 -0
- package/src/console/server/vault.ts +443 -27
- package/src/console/ui-next/components.json +26 -0
- package/src/console/ui-next/dist/assets/bash-CLZ0U2zV.js +1 -0
- package/src/console/ui-next/dist/assets/cache-glyph-CLPBqZeb.js +1 -0
- package/src/console/ui-next/dist/assets/call-pii-button-bqkxMrJH.js +1 -0
- package/src/console/ui-next/dist/assets/collapsible-DYb0xU8C.js +1 -0
- package/src/console/ui-next/dist/assets/confirm-sheet-DDCRmG62.js +1 -0
- package/src/console/ui-next/dist/assets/dagre.esm-ZwcdTuZZ.js +1 -0
- package/src/console/ui-next/dist/assets/duration-tone-oiRxPVsZ.js +9 -0
- package/src/console/ui-next/dist/assets/explorer-empty-HjTnVQoR.js +1 -0
- package/src/console/ui-next/dist/assets/flows-page-Dg8CTE29.js +1 -0
- package/src/console/ui-next/dist/assets/github-dark-C-LZuMrd.js +1 -0
- package/src/console/ui-next/dist/assets/github-light-EUqPIrTm.js +1 -0
- package/src/console/ui-next/dist/assets/highlighted-json-CvDPvveV.js +154 -0
- package/src/console/ui-next/dist/assets/http-method-BJ92Z_ke.js +1 -0
- package/src/console/ui-next/dist/assets/index-Bp-R7jtM.js +66 -0
- package/src/console/ui-next/dist/assets/index-D4Ldtj79.css +2 -0
- package/src/console/ui-next/dist/assets/json-qhed-kSA.js +1 -0
- package/src/console/ui-next/dist/assets/link-DF7SZ9Ek.js +1 -0
- package/src/console/ui-next/dist/assets/observability-page-DAnpEaq1.js +4 -0
- package/src/console/ui-next/dist/assets/preload-helper-oH4irX4C.js +1 -0
- package/src/console/ui-next/dist/assets/query-gate-parts-1m8m1iNp.js +2 -0
- package/src/console/ui-next/dist/assets/react-B1ML8gxg.js +1 -0
- package/src/console/ui-next/dist/assets/react-dom-Bph1y7z7.js +9 -0
- package/src/console/ui-next/dist/assets/replica-lag-C8_BRt2x.js +18 -0
- package/src/console/ui-next/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/src/console/ui-next/dist/assets/sheet-form-D-ata7jy.js +1 -0
- package/src/console/ui-next/dist/assets/shortcut-Cgzuv4k1.js +1 -0
- package/src/console/ui-next/dist/assets/shortcut-keys-DO4IsVqv.js +1 -0
- package/src/console/ui-next/dist/assets/skeleton-CL_X0GCj.js +1 -0
- package/src/console/ui-next/dist/assets/sql-BskegiFM.js +1 -0
- package/src/console/ui-next/dist/assets/store-page-v3LXdYpr.js +45 -0
- package/src/console/ui-next/dist/assets/trace-detail-sheet-D16lWQMt.js +2 -0
- package/src/console/ui-next/dist/assets/tsx-udAQXfEw.js +1 -0
- package/src/console/ui-next/dist/assets/typescript-bsJCZSQ-.js +1 -0
- package/src/console/ui-next/dist/assets/units-page-BtQ0bqMe.js +1 -0
- package/src/console/ui-next/dist/assets/use-vault-list-Cl79j_ku.js +1 -0
- package/src/console/ui-next/dist/assets/vault-page-Ca-MvcmJ.js +2 -0
- package/src/console/ui-next/dist/assets/xyflow-D7n4g6go.js +7 -0
- package/src/console/ui-next/dist/assets/xyflow-DZ0Ws1xk.css +1 -0
- package/src/console/ui-next/dist/favicon.svg +6 -0
- package/src/console/ui-next/dist/index.html +56 -0
- package/src/console/ui-next/index.html +45 -0
- package/src/console/ui-next/public/favicon.svg +6 -0
- package/src/console/ui-next/seed-invoke-host.test.ts +47 -0
- package/src/console/ui-next/seed-invoke-host.ts +199 -0
- package/src/console/ui-next/seed-invoke-ops.test.ts +280 -0
- package/src/console/ui-next/seed-invoke-ops.ts +587 -0
- package/src/console/ui-next/src/client-session.test.ts +22 -0
- package/src/console/ui-next/src/client.ts +1379 -0
- package/src/console/ui-next/src/components/agents/agent-code.tsx +207 -0
- package/src/console/ui-next/src/components/agents/agent-disclosure.tsx +63 -0
- package/src/console/ui-next/src/components/agents/file-diff.tsx +271 -0
- package/src/console/ui-next/src/components/auth-card.tsx +298 -0
- package/src/console/ui-next/src/components/charts/animation.ts +36 -0
- package/src/console/ui-next/src/components/charts/area-chart-loading.tsx +115 -0
- package/src/console/ui-next/src/components/charts/area-chart.tsx +261 -0
- package/src/console/ui-next/src/components/charts/area-gradient-defs.tsx +98 -0
- package/src/console/ui-next/src/components/charts/area.tsx +349 -0
- package/src/console/ui-next/src/components/charts/chart-child-passthrough.ts +110 -0
- package/src/console/ui-next/src/components/charts/chart-config-context.tsx +81 -0
- package/src/console/ui-next/src/components/charts/chart-context.tsx +414 -0
- package/src/console/ui-next/src/components/charts/chart-defs.ts +61 -0
- package/src/console/ui-next/src/components/charts/chart-formatters.ts +26 -0
- package/src/console/ui-next/src/components/charts/chart-legend-hover.tsx +41 -0
- package/src/console/ui-next/src/components/charts/chart-loading-label.tsx +56 -0
- package/src/console/ui-next/src/components/charts/chart-phase.ts +52 -0
- package/src/console/ui-next/src/components/charts/chart-reveal-clip.tsx +87 -0
- package/src/console/ui-next/src/components/charts/composed-chart.tsx +333 -0
- package/src/console/ui-next/src/components/charts/dash-tail-stroke.tsx +75 -0
- package/src/console/ui-next/src/components/charts/decimate-time-series.ts +134 -0
- package/src/console/ui-next/src/components/charts/fade-edges.ts +52 -0
- package/src/console/ui-next/src/components/charts/filter-data-by-x-domain.ts +59 -0
- package/src/console/ui-next/src/components/charts/generate-chart-skeleton-data.ts +42 -0
- package/src/console/ui-next/src/components/charts/grid.tsx +299 -0
- package/src/console/ui-next/src/components/charts/highlight-segment-bounds.ts +68 -0
- package/src/console/ui-next/src/components/charts/highlight-segment.tsx +65 -0
- package/src/console/ui-next/src/components/charts/indicator-fade.ts +62 -0
- package/src/console/ui-next/src/components/charts/line-chart-loading.tsx +111 -0
- package/src/console/ui-next/src/components/charts/line-chart.tsx +293 -0
- package/src/console/ui-next/src/components/charts/line-loading-pulse.tsx +201 -0
- package/src/console/ui-next/src/components/charts/line-loading-timing.ts +12 -0
- package/src/console/ui-next/src/components/charts/line-series-terminal-marker.tsx +91 -0
- package/src/console/ui-next/src/components/charts/line.tsx +384 -0
- package/src/console/ui-next/src/components/charts/loading-sweep.tsx +452 -0
- package/src/console/ui-next/src/components/charts/motion-utils.ts +47 -0
- package/src/console/ui-next/src/components/charts/path-stroke-utils.ts +82 -0
- package/src/console/ui-next/src/components/charts/pattern-area.tsx +45 -0
- package/src/console/ui-next/src/components/charts/projection-config.ts +112 -0
- package/src/console/ui-next/src/components/charts/projection-line-end-marker.tsx +51 -0
- package/src/console/ui-next/src/components/charts/projection-line.tsx +208 -0
- package/src/console/ui-next/src/components/charts/projection-utils.ts +378 -0
- package/src/console/ui-next/src/components/charts/reference-area-config.ts +59 -0
- package/src/console/ui-next/src/components/charts/reference-area-geometry.ts +136 -0
- package/src/console/ui-next/src/components/charts/reference-area-registration-context.tsx +16 -0
- package/src/console/ui-next/src/components/charts/series-bar-layout.ts +60 -0
- package/src/console/ui-next/src/components/charts/series-bar.tsx +304 -0
- package/src/console/ui-next/src/components/charts/series-dash-tail-overlay.tsx +82 -0
- package/src/console/ui-next/src/components/charts/series-highlight-layer.tsx +49 -0
- package/src/console/ui-next/src/components/charts/series-hover-dim.tsx +57 -0
- package/src/console/ui-next/src/components/charts/series-markers.tsx +267 -0
- package/src/console/ui-next/src/components/charts/series-path-utils.ts +103 -0
- package/src/console/ui-next/src/components/charts/series-point-marker.tsx +205 -0
- package/src/console/ui-next/src/components/charts/static-chart-preview-context.tsx +16 -0
- package/src/console/ui-next/src/components/charts/time-series-chart-shell.tsx +644 -0
- package/src/console/ui-next/src/components/charts/tooltip/chart-tooltip.tsx +400 -0
- package/src/console/ui-next/src/components/charts/tooltip/date-ticker.tsx +140 -0
- package/src/console/ui-next/src/components/charts/tooltip/index.ts +10 -0
- package/src/console/ui-next/src/components/charts/tooltip/tooltip-box.tsx +227 -0
- package/src/console/ui-next/src/components/charts/tooltip/tooltip-content.tsx +58 -0
- package/src/console/ui-next/src/components/charts/tooltip/tooltip-dot.tsx +173 -0
- package/src/console/ui-next/src/components/charts/tooltip/tooltip-indicator.tsx +191 -0
- package/src/console/ui-next/src/components/charts/use-animated-series-path.ts +155 -0
- package/src/console/ui-next/src/components/charts/use-animated-y-domains.ts +227 -0
- package/src/console/ui-next/src/components/charts/use-chart-interaction.ts +343 -0
- package/src/console/ui-next/src/components/charts/use-chart-phase-orchestrator.ts +173 -0
- package/src/console/ui-next/src/components/charts/use-enter-complete.ts +28 -0
- package/src/console/ui-next/src/components/charts/use-grid-shimmer.ts +101 -0
- package/src/console/ui-next/src/components/charts/use-highlight-segment.ts +58 -0
- package/src/console/ui-next/src/components/charts/use-mount-progress.ts +29 -0
- package/src/console/ui-next/src/components/charts/use-scheduled-tooltip.ts +97 -0
- package/src/console/ui-next/src/components/charts/x-axis.tsx +635 -0
- package/src/console/ui-next/src/components/charts/y-axis-scales.ts +108 -0
- package/src/console/ui-next/src/components/charts/y-axis-ticks.ts +25 -0
- package/src/console/ui-next/src/components/charts/y-axis.tsx +151 -0
- package/src/console/ui-next/src/components/charts/y-domain-utils.ts +120 -0
- package/src/console/ui-next/src/components/console-chrome.tsx +50 -0
- package/src/console/ui-next/src/components/document-title.tsx +18 -0
- package/src/console/ui-next/src/components/explorer/copy-inline-button.tsx +57 -0
- package/src/console/ui-next/src/components/explorer/detail-header.tsx +82 -0
- package/src/console/ui-next/src/components/explorer/explorer-chrome.ts +123 -0
- package/src/console/ui-next/src/components/explorer/explorer-empty.tsx +67 -0
- package/src/console/ui-next/src/components/explorer/explorer-search.tsx +20 -0
- package/src/console/ui-next/src/components/explorer/explorer-start-toggle.tsx +52 -0
- package/src/console/ui-next/src/components/explorer/section-head.tsx +33 -0
- package/src/console/ui-next/src/components/explorer/tree-expand-toggle.tsx +69 -0
- package/src/console/ui-next/src/components/explorer/use-explorer-start-panel.ts +34 -0
- package/src/console/ui-next/src/components/gate-list.tsx +70 -0
- package/src/console/ui-next/src/components/generate-password-button.tsx +76 -0
- package/src/console/ui-next/src/components/highlighted-json.tsx +73 -0
- package/src/console/ui-next/src/components/http-method-badge.tsx +35 -0
- package/src/console/ui-next/src/components/mode-toggle.tsx +84 -0
- package/src/console/ui-next/src/components/motion/button/base.tsx +145 -0
- package/src/console/ui-next/src/components/motion/button/expanding-arrow.tsx +167 -0
- package/src/console/ui-next/src/components/motion/button/index.ts +12 -0
- package/src/console/ui-next/src/components/motion/button/stateful.tsx +243 -0
- package/src/console/ui-next/src/components/motion/checkbox.tsx +120 -0
- package/src/console/ui-next/src/components/motion/select.tsx +436 -0
- package/src/console/ui-next/src/components/motion/switch.tsx +108 -0
- package/src/console/ui-next/src/components/motion/table/editable-cell.tsx +98 -0
- package/src/console/ui-next/src/components/motion/table/index.tsx +404 -0
- package/src/console/ui-next/src/components/motion/table/row-handle.tsx +95 -0
- package/src/console/ui-next/src/components/motion/table/skeleton-rows.tsx +52 -0
- package/src/console/ui-next/src/components/motion/table/table-header.tsx +337 -0
- package/src/console/ui-next/src/components/motion/table/table-menu.tsx +130 -0
- package/src/console/ui-next/src/components/motion/table/types.ts +109 -0
- package/src/console/ui-next/src/components/motion/table/use-cell-range.ts +145 -0
- package/src/console/ui-next/src/components/motion/table/use-column-reorder.ts +112 -0
- package/src/console/ui-next/src/components/motion/table/use-column-resize.ts +83 -0
- package/src/console/ui-next/src/components/motion/table/use-column-sort.ts +73 -0
- package/src/console/ui-next/src/components/motion/table/use-row-selection.ts +70 -0
- package/src/console/ui-next/src/components/motion/table/utils.ts +138 -0
- package/src/console/ui-next/src/components/oke-logo.tsx +65 -0
- package/src/console/ui-next/src/components/password-input.tsx +67 -0
- package/src/console/ui-next/src/components/password-strength.tsx +160 -0
- package/src/console/ui-next/src/components/shell/app-sidebar.tsx +117 -0
- package/src/console/ui-next/src/components/shell/command-items.test.ts +30 -0
- package/src/console/ui-next/src/components/shell/command-items.ts +144 -0
- package/src/console/ui-next/src/components/shell/command-match.test.ts +37 -0
- package/src/console/ui-next/src/components/shell/command-match.ts +45 -0
- package/src/console/ui-next/src/components/shell/command-palette.tsx +334 -0
- package/src/console/ui-next/src/components/shell/nav-footer.tsx +109 -0
- package/src/console/ui-next/src/components/shell/section-empty.tsx +42 -0
- package/src/console/ui-next/src/components/shell/settings-dialog.tsx +65 -0
- package/src/console/ui-next/src/components/shell/shell-layout.tsx +100 -0
- package/src/console/ui-next/src/components/shimmering-text.tsx +87 -0
- package/src/console/ui-next/src/components/signal-delivery-badge.tsx +38 -0
- package/src/console/ui-next/src/components/theme-provider.tsx +86 -0
- package/src/console/ui-next/src/components/ui/alert-dialog.tsx +147 -0
- package/src/console/ui-next/src/components/ui/avatar.tsx +91 -0
- package/src/console/ui-next/src/components/ui/badge.tsx +54 -0
- package/src/console/ui-next/src/components/ui/breadcrumb.tsx +104 -0
- package/src/console/ui-next/src/components/ui/button.tsx +58 -0
- package/src/console/ui-next/src/components/ui/card.tsx +88 -0
- package/src/console/ui-next/src/components/ui/collapsible.tsx +15 -0
- package/src/console/ui-next/src/components/ui/confirm-sheet.tsx +149 -0
- package/src/console/ui-next/src/components/ui/dialog.tsx +144 -0
- package/src/console/ui-next/src/components/ui/dropdown-menu.tsx +265 -0
- package/src/console/ui-next/src/components/ui/empty.tsx +95 -0
- package/src/console/ui-next/src/components/ui/field.tsx +224 -0
- package/src/console/ui-next/src/components/ui/input.tsx +30 -0
- package/src/console/ui-next/src/components/ui/kbd.tsx +41 -0
- package/src/console/ui-next/src/components/ui/label.tsx +20 -0
- package/src/console/ui-next/src/components/ui/progress.tsx +66 -0
- package/src/console/ui-next/src/components/ui/resizable.tsx +74 -0
- package/src/console/ui-next/src/components/ui/select.tsx +230 -0
- package/src/console/ui-next/src/components/ui/separator.tsx +21 -0
- package/src/console/ui-next/src/components/ui/sheet-form.tsx +337 -0
- package/src/console/ui-next/src/components/ui/sheet.tsx +130 -0
- package/src/console/ui-next/src/components/ui/sidebar.tsx +691 -0
- package/src/console/ui-next/src/components/ui/skeleton.tsx +20 -0
- package/src/console/ui-next/src/components/ui/toggle-group.tsx +87 -0
- package/src/console/ui-next/src/components/ui/toggle.tsx +46 -0
- package/src/console/ui-next/src/components/ui/toolbar-tip.tsx +41 -0
- package/src/console/ui-next/src/components/ui/tooltip.tsx +74 -0
- package/src/console/ui-next/src/features/auth/auth-redirect.test.ts +119 -0
- package/src/console/ui-next/src/features/auth/auth-redirect.ts +153 -0
- package/src/console/ui-next/src/features/auth/login-form.tsx +234 -0
- package/src/console/ui-next/src/features/auth/logout.ts +17 -0
- package/src/console/ui-next/src/features/flows/data/console-live-session.test.ts +329 -0
- package/src/console/ui-next/src/features/flows/data/console-live-session.ts +210 -0
- package/src/console/ui-next/src/features/flows/data/use-console-live.ts +79 -0
- package/src/console/ui-next/src/features/flows/data/use-manifest.ts +23 -0
- package/src/console/ui-next/src/features/flows/data/use-runs.ts +24 -0
- package/src/console/ui-next/src/features/flows/fixture.ts +81 -0
- package/src/console/ui-next/src/features/flows/flows-page.tsx +227 -0
- package/src/console/ui-next/src/features/flows/graph/build-flow-graph.test.ts +236 -0
- package/src/console/ui-next/src/features/flows/graph/build-flow-graph.ts +530 -0
- package/src/console/ui-next/src/features/flows/graph/element-map.test.ts +443 -0
- package/src/console/ui-next/src/features/flows/graph/element-map.ts +1077 -0
- package/src/console/ui-next/src/features/flows/graph/flow-graph-nodes.tsx +486 -0
- package/src/console/ui-next/src/features/flows/graph/flow-graph-theme.ts +143 -0
- package/src/console/ui-next/src/features/flows/graph/flow-graph.tsx +268 -0
- package/src/console/ui-next/src/features/flows/graph/neighborhood.test.ts +64 -0
- package/src/console/ui-next/src/features/flows/graph/neighborhood.ts +82 -0
- package/src/console/ui-next/src/features/flows/graph/orchestra.test.ts +97 -0
- package/src/console/ui-next/src/features/flows/graph/orchestra.ts +86 -0
- package/src/console/ui-next/src/features/flows/graph/use-overview-orchestra.ts +95 -0
- package/src/console/ui-next/src/features/flows/state/flows-selection.test.ts +24 -0
- package/src/console/ui-next/src/features/flows/state/flows-selection.ts +92 -0
- package/src/console/ui-next/src/features/flows/traces/advanced-filters.tsx +222 -0
- package/src/console/ui-next/src/features/flows/traces/cache-glyph.tsx +42 -0
- package/src/console/ui-next/src/features/flows/traces/cache-icon.test.ts +27 -0
- package/src/console/ui-next/src/features/flows/traces/cache-icon.ts +48 -0
- package/src/console/ui-next/src/features/flows/traces/dimension-query.test.ts +100 -0
- package/src/console/ui-next/src/features/flows/traces/dimension-query.ts +325 -0
- package/src/console/ui-next/src/features/flows/traces/duration-tone.test.ts +71 -0
- package/src/console/ui-next/src/features/flows/traces/duration-tone.ts +128 -0
- package/src/console/ui-next/src/features/flows/traces/effect-kind.ts +106 -0
- package/src/console/ui-next/src/features/flows/traces/effect-summary.ts +193 -0
- package/src/console/ui-next/src/features/flows/traces/filter-runs.test.ts +98 -0
- package/src/console/ui-next/src/features/flows/traces/filter-runs.ts +68 -0
- package/src/console/ui-next/src/features/flows/traces/format-duration.test.ts +47 -0
- package/src/console/ui-next/src/features/flows/traces/format-duration.ts +25 -0
- package/src/console/ui-next/src/features/flows/traces/graph-filter.test.ts +192 -0
- package/src/console/ui-next/src/features/flows/traces/graph-filter.ts +175 -0
- package/src/console/ui-next/src/features/flows/traces/http-method.ts +134 -0
- package/src/console/ui-next/src/features/flows/traces/replay-playback.test.ts +101 -0
- package/src/console/ui-next/src/features/flows/traces/replay-playback.ts +107 -0
- package/src/console/ui-next/src/features/flows/traces/request-input-view.test.ts +60 -0
- package/src/console/ui-next/src/features/flows/traces/request-input-view.ts +108 -0
- package/src/console/ui-next/src/features/flows/traces/request-meta.ts +62 -0
- package/src/console/ui-next/src/features/flows/traces/scope-runs.test.ts +51 -0
- package/src/console/ui-next/src/features/flows/traces/scope-runs.ts +23 -0
- package/src/console/ui-next/src/features/flows/traces/trace-actions.test.ts +80 -0
- package/src/console/ui-next/src/features/flows/traces/trace-actions.ts +57 -0
- package/src/console/ui-next/src/features/flows/traces/trace-chain.test.ts +68 -0
- package/src/console/ui-next/src/features/flows/traces/trace-chain.ts +59 -0
- package/src/console/ui-next/src/features/flows/traces/trace-detail-sheet.tsx +1003 -0
- package/src/console/ui-next/src/features/flows/traces/trace-detail.test.ts +357 -0
- package/src/console/ui-next/src/features/flows/traces/trace-gates.ts +90 -0
- package/src/console/ui-next/src/features/flows/traces/trace-request-section.tsx +574 -0
- package/src/console/ui-next/src/features/flows/traces/trace-row-meta.test.ts +42 -0
- package/src/console/ui-next/src/features/flows/traces/trace-row-meta.ts +47 -0
- package/src/console/ui-next/src/features/flows/traces/trace-row.tsx +149 -0
- package/src/console/ui-next/src/features/flows/traces/traces-pane.tsx +289 -0
- package/src/console/ui-next/src/features/flows/traces/trigger-icon.test.ts +42 -0
- package/src/console/ui-next/src/features/flows/traces/trigger-icon.ts +53 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-bars.test.ts +93 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-bars.ts +80 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-timeline.test.ts +121 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-timeline.ts +230 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-tooltip.test.ts +51 -0
- package/src/console/ui-next/src/features/flows/traces/waterfall-tooltip.ts +20 -0
- package/src/console/ui-next/src/features/not-found/not-found-page.tsx +23 -0
- package/src/console/ui-next/src/features/observability/data/use-ai-list.ts +26 -0
- package/src/console/ui-next/src/features/observability/data/use-clock-list.ts +27 -0
- package/src/console/ui-next/src/features/observability/data/use-instances-list.ts +27 -0
- package/src/console/ui-next/src/features/observability/data/use-runs-query.ts +39 -0
- package/src/console/ui-next/src/features/observability/data/use-signals-list.ts +25 -0
- package/src/console/ui-next/src/features/observability/detail/ai-rail.tsx +77 -0
- package/src/console/ui-next/src/features/observability/detail/instance-fleet-sheet.tsx +111 -0
- package/src/console/ui-next/src/features/observability/detail/metrics-chart.tsx +111 -0
- package/src/console/ui-next/src/features/observability/detail/metrics-panel.tsx +154 -0
- package/src/console/ui-next/src/features/observability/explorer/error-list.tsx +139 -0
- package/src/console/ui-next/src/features/observability/explorer/error-row.tsx +84 -0
- package/src/console/ui-next/src/features/observability/explorer/health-strip.tsx +146 -0
- package/src/console/ui-next/src/features/observability/lib/ask-count.test.ts +47 -0
- package/src/console/ui-next/src/features/observability/lib/ask-count.ts +44 -0
- package/src/console/ui-next/src/features/observability/lib/health-cells.test.ts +243 -0
- package/src/console/ui-next/src/features/observability/lib/health-cells.ts +207 -0
- package/src/console/ui-next/src/features/observability/lib/run-fixture.ts +43 -0
- package/src/console/ui-next/src/features/observability/lib/time-buckets.test.ts +61 -0
- package/src/console/ui-next/src/features/observability/lib/time-buckets.ts +126 -0
- package/src/console/ui-next/src/features/observability/lib/token-count.test.ts +75 -0
- package/src/console/ui-next/src/features/observability/lib/token-count.ts +70 -0
- package/src/console/ui-next/src/features/observability/lib/top-errors.test.ts +89 -0
- package/src/console/ui-next/src/features/observability/lib/top-errors.ts +135 -0
- package/src/console/ui-next/src/features/observability/lib/window-stats.test.ts +62 -0
- package/src/console/ui-next/src/features/observability/lib/window-stats.ts +124 -0
- package/src/console/ui-next/src/features/observability/observability-page.tsx +217 -0
- package/src/console/ui-next/src/features/observability/query/runs-query-panel.tsx +91 -0
- package/src/console/ui-next/src/features/observability/state/observability-selection.test.ts +27 -0
- package/src/console/ui-next/src/features/observability/state/observability-selection.ts +121 -0
- package/src/console/ui-next/src/features/setup/auth-gate.test.ts +17 -0
- package/src/console/ui-next/src/features/setup/auth-gate.ts +21 -0
- package/src/console/ui-next/src/features/setup/claim-page.tsx +418 -0
- package/src/console/ui-next/src/features/store/data/use-gates.ts +26 -0
- package/src/console/ui-next/src/features/store/data/use-store-edit.ts +92 -0
- package/src/console/ui-next/src/features/store/data/use-store-files.ts +96 -0
- package/src/console/ui-next/src/features/store/data/use-store-kv-stats.ts +47 -0
- package/src/console/ui-next/src/features/store/data/use-store-query.test.ts +42 -0
- package/src/console/ui-next/src/features/store/data/use-store-query.ts +68 -0
- package/src/console/ui-next/src/features/store/data/use-store-reveal.ts +28 -0
- package/src/console/ui-next/src/features/store/data/use-store-sql-advise.ts +39 -0
- package/src/console/ui-next/src/features/store/data/use-store-sql-locks.ts +51 -0
- package/src/console/ui-next/src/features/store/data/use-store-sql-stats.ts +47 -0
- package/src/console/ui-next/src/features/store/data/use-store-sql.ts +39 -0
- package/src/console/ui-next/src/features/store/data/use-stores-list.ts +24 -0
- package/src/console/ui-next/src/features/store/detail/browse-section.tsx +692 -0
- package/src/console/ui-next/src/features/store/detail/json-value-sheet.tsx +470 -0
- package/src/console/ui-next/src/features/store/detail/resource-panel.tsx +325 -0
- package/src/console/ui-next/src/features/store/detail/reveal-cell.tsx +137 -0
- package/src/console/ui-next/src/features/store/detail/store-row-detail-sheet.tsx +225 -0
- package/src/console/ui-next/src/features/store/detail/touched-by-section.tsx +101 -0
- package/src/console/ui-next/src/features/store/explorer/store-tree.tsx +1044 -0
- package/src/console/ui-next/src/features/store/files/file-explorer.tsx +563 -0
- package/src/console/ui-next/src/features/store/files/file-kind-icon.tsx +70 -0
- package/src/console/ui-next/src/features/store/files/file-preview.tsx +338 -0
- package/src/console/ui-next/src/features/store/files/file-upload-sheet.tsx +190 -0
- package/src/console/ui-next/src/features/store/grid/catalog-advanced.tsx +80 -0
- package/src/console/ui-next/src/features/store/grid/extension-library-sheet.tsx +761 -0
- package/src/console/ui-next/src/features/store/grid/kv-add-sheet.tsx +165 -0
- package/src/console/ui-next/src/features/store/grid/pending-changes-sheet.tsx +219 -0
- package/src/console/ui-next/src/features/store/grid/rls-policy-sheet.tsx +875 -0
- package/src/console/ui-next/src/features/store/grid/sql-function-sheet.tsx +473 -0
- package/src/console/ui-next/src/features/store/grid/sql-index-sheet.tsx +355 -0
- package/src/console/ui-next/src/features/store/grid/sql-insert-sheet.tsx +177 -0
- package/src/console/ui-next/src/features/store/grid/sql-trigger-sheet.tsx +445 -0
- package/src/console/ui-next/src/features/store/grid/store-confirm-sheet.tsx +73 -0
- package/src/console/ui-next/src/features/store/grid/store-data-grid.tsx +1844 -0
- package/src/console/ui-next/src/features/store/grid/store-edit-sheet.tsx +329 -0
- package/src/console/ui-next/src/features/store/grid/store-grid-context-menu.tsx +111 -0
- package/src/console/ui-next/src/features/store/grid/store-grid-shortcuts.tsx +124 -0
- package/src/console/ui-next/src/features/store/lib/cell-selection.test.ts +125 -0
- package/src/console/ui-next/src/features/store/lib/cell-selection.ts +115 -0
- package/src/console/ui-next/src/features/store/lib/confirmation.test.ts +48 -0
- package/src/console/ui-next/src/features/store/lib/confirmation.ts +63 -0
- package/src/console/ui-next/src/features/store/lib/edit-history.test.ts +60 -0
- package/src/console/ui-next/src/features/store/lib/edit-history.ts +64 -0
- package/src/console/ui-next/src/features/store/lib/fields-from-table.ts +94 -0
- package/src/console/ui-next/src/features/store/lib/files-body.test.ts +16 -0
- package/src/console/ui-next/src/features/store/lib/files-body.ts +79 -0
- package/src/console/ui-next/src/features/store/lib/files-meta.test.ts +75 -0
- package/src/console/ui-next/src/features/store/lib/files-meta.ts +259 -0
- package/src/console/ui-next/src/features/store/lib/files-origin.test.ts +69 -0
- package/src/console/ui-next/src/features/store/lib/files-origin.ts +53 -0
- package/src/console/ui-next/src/features/store/lib/files-tree.test.ts +123 -0
- package/src/console/ui-next/src/features/store/lib/files-tree.ts +233 -0
- package/src/console/ui-next/src/features/store/lib/grid-model.test.ts +127 -0
- package/src/console/ui-next/src/features/store/lib/grid-model.ts +219 -0
- package/src/console/ui-next/src/features/store/lib/grid-transfer.test.ts +123 -0
- package/src/console/ui-next/src/features/store/lib/grid-transfer.ts +217 -0
- package/src/console/ui-next/src/features/store/lib/index-query.test.ts +30 -0
- package/src/console/ui-next/src/features/store/lib/index-query.ts +57 -0
- package/src/console/ui-next/src/features/store/lib/json-value.test.ts +141 -0
- package/src/console/ui-next/src/features/store/lib/json-value.ts +266 -0
- package/src/console/ui-next/src/features/store/lib/kv-format.test.ts +44 -0
- package/src/console/ui-next/src/features/store/lib/kv-format.ts +103 -0
- package/src/console/ui-next/src/features/store/lib/kv-meta.test.ts +43 -0
- package/src/console/ui-next/src/features/store/lib/kv-meta.ts +63 -0
- package/src/console/ui-next/src/features/store/lib/kv-query.test.ts +128 -0
- package/src/console/ui-next/src/features/store/lib/kv-query.ts +303 -0
- package/src/console/ui-next/src/features/store/lib/parse-resource-ref.ts +38 -0
- package/src/console/ui-next/src/features/store/lib/patch.test.ts +99 -0
- package/src/console/ui-next/src/features/store/lib/patch.ts +129 -0
- package/src/console/ui-next/src/features/store/lib/pending-edits.test.ts +125 -0
- package/src/console/ui-next/src/features/store/lib/pending-edits.ts +150 -0
- package/src/console/ui-next/src/features/store/lib/pending-sql.test.ts +108 -0
- package/src/console/ui-next/src/features/store/lib/pending-sql.ts +136 -0
- package/src/console/ui-next/src/features/store/lib/pg-extension-library.test.ts +117 -0
- package/src/console/ui-next/src/features/store/lib/pg-extension-library.ts +277 -0
- package/src/console/ui-next/src/features/store/lib/query-defaults.test.ts +78 -0
- package/src/console/ui-next/src/features/store/lib/query-defaults.ts +77 -0
- package/src/console/ui-next/src/features/store/lib/query-gate.test.ts +132 -0
- package/src/console/ui-next/src/features/store/lib/query-gate.ts +187 -0
- package/src/console/ui-next/src/features/store/lib/query-highlight.test.ts +103 -0
- package/src/console/ui-next/src/features/store/lib/query-highlight.ts +382 -0
- package/src/console/ui-next/src/features/store/lib/query-schema.test.ts +139 -0
- package/src/console/ui-next/src/features/store/lib/query-schema.ts +128 -0
- package/src/console/ui-next/src/features/store/lib/query-session.test.ts +91 -0
- package/src/console/ui-next/src/features/store/lib/query-session.ts +330 -0
- package/src/console/ui-next/src/features/store/lib/replica-lag.test.ts +101 -0
- package/src/console/ui-next/src/features/store/lib/replica-lag.ts +31 -0
- package/src/console/ui-next/src/features/store/lib/resource-effects.ts +12 -0
- package/src/console/ui-next/src/features/store/lib/rls-gate-catalog.test.ts +131 -0
- package/src/console/ui-next/src/features/store/lib/rls-gate-catalog.ts +274 -0
- package/src/console/ui-next/src/features/store/lib/rls-policy.test.ts +95 -0
- package/src/console/ui-next/src/features/store/lib/rls-policy.ts +290 -0
- package/src/console/ui-next/src/features/store/lib/rtl.test.ts +17 -0
- package/src/console/ui-next/src/features/store/lib/rtl.ts +15 -0
- package/src/console/ui-next/src/features/store/lib/schema-color.test.ts +91 -0
- package/src/console/ui-next/src/features/store/lib/schema-color.ts +216 -0
- package/src/console/ui-next/src/features/store/lib/schema-graph.test.ts +435 -0
- package/src/console/ui-next/src/features/store/lib/schema-graph.ts +566 -0
- package/src/console/ui-next/src/features/store/lib/sql-catalog.test.ts +60 -0
- package/src/console/ui-next/src/features/store/lib/sql-catalog.ts +98 -0
- package/src/console/ui-next/src/features/store/lib/sql-complete.test.ts +109 -0
- package/src/console/ui-next/src/features/store/lib/sql-complete.ts +385 -0
- package/src/console/ui-next/src/features/store/lib/sql-format.test.ts +35 -0
- package/src/console/ui-next/src/features/store/lib/sql-format.ts +85 -0
- package/src/console/ui-next/src/features/store/lib/sql-function.test.ts +141 -0
- package/src/console/ui-next/src/features/store/lib/sql-function.ts +195 -0
- package/src/console/ui-next/src/features/store/lib/sql-index.test.ts +101 -0
- package/src/console/ui-next/src/features/store/lib/sql-index.ts +151 -0
- package/src/console/ui-next/src/features/store/lib/sql-statements.test.ts +114 -0
- package/src/console/ui-next/src/features/store/lib/sql-statements.ts +205 -0
- package/src/console/ui-next/src/features/store/lib/sql-trigger.test.ts +125 -0
- package/src/console/ui-next/src/features/store/lib/sql-trigger.ts +210 -0
- package/src/console/ui-next/src/features/store/lib/store-tree.test.ts +220 -0
- package/src/console/ui-next/src/features/store/lib/store-tree.ts +314 -0
- package/src/console/ui-next/src/features/store/performance/advisor-enable.test.ts +16 -0
- package/src/console/ui-next/src/features/store/performance/advisor-enable.ts +26 -0
- package/src/console/ui-next/src/features/store/performance/kv-performance-panel.tsx +223 -0
- package/src/console/ui-next/src/features/store/performance/performance-panel.tsx +442 -0
- package/src/console/ui-next/src/features/store/query/query-complete.tsx +131 -0
- package/src/console/ui-next/src/features/store/query/query-console.tsx +1159 -0
- package/src/console/ui-next/src/features/store/query/query-editor.tsx +300 -0
- package/src/console/ui-next/src/features/store/query/query-gate-menu.tsx +178 -0
- package/src/console/ui-next/src/features/store/query/query-gate-parts.tsx +344 -0
- package/src/console/ui-next/src/features/store/query/query-gate-viz.tsx +166 -0
- package/src/console/ui-next/src/features/store/query/query-highlight-view.tsx +61 -0
- package/src/console/ui-next/src/features/store/query/query-results.tsx +369 -0
- package/src/console/ui-next/src/features/store/query/query-schema-panel.tsx +300 -0
- package/src/console/ui-next/src/features/store/query/sql-style-editor.tsx +73 -0
- package/src/console/ui-next/src/features/store/schema/schema-constraint-icon.tsx +108 -0
- package/src/console/ui-next/src/features/store/schema/schema-relation-edge.tsx +76 -0
- package/src/console/ui-next/src/features/store/schema/schema-relation-icon.tsx +84 -0
- package/src/console/ui-next/src/features/store/schema/schema-table-node.tsx +199 -0
- package/src/console/ui-next/src/features/store/schema/schema-visualizer.tsx +273 -0
- package/src/console/ui-next/src/features/store/state/store-selection.test.ts +38 -0
- package/src/console/ui-next/src/features/store/state/store-selection.ts +154 -0
- package/src/console/ui-next/src/features/store/store-page.tsx +180 -0
- package/src/console/ui-next/src/features/units/call/call-api-panel.tsx +1247 -0
- package/src/console/ui-next/src/features/units/call/call-identity-menu.tsx +226 -0
- package/src/console/ui-next/src/features/units/call/call-pii-button.tsx +60 -0
- package/src/console/ui-next/src/features/units/data/use-flows-invoke.ts +75 -0
- package/src/console/ui-next/src/features/units/detail/effects-summary.tsx +80 -0
- package/src/console/ui-next/src/features/units/detail/errors-section.tsx +64 -0
- package/src/console/ui-next/src/features/units/detail/flow-activity-strip.tsx +119 -0
- package/src/console/ui-next/src/features/units/detail/flow-contract-panel.tsx +335 -0
- package/src/console/ui-next/src/features/units/detail/schema-fields.tsx +149 -0
- package/src/console/ui-next/src/features/units/detail/validation-section.tsx +66 -0
- package/src/console/ui-next/src/features/units/explorer/units-tree.tsx +644 -0
- package/src/console/ui-next/src/features/units/lib/call-invoke-as.test.ts +40 -0
- package/src/console/ui-next/src/features/units/lib/call-read-safe.test.ts +38 -0
- package/src/console/ui-next/src/features/units/lib/call-read-safe.ts +32 -0
- package/src/console/ui-next/src/features/units/lib/call-timing.test.ts +28 -0
- package/src/console/ui-next/src/features/units/lib/call-timing.ts +34 -0
- package/src/console/ui-next/src/features/units/lib/contract-input.test.ts +47 -0
- package/src/console/ui-next/src/features/units/lib/contract-input.ts +68 -0
- package/src/console/ui-next/src/features/units/lib/fields-from-schema.test.ts +119 -0
- package/src/console/ui-next/src/features/units/lib/fields-from-schema.ts +329 -0
- package/src/console/ui-next/src/features/units/lib/fk-lookup.test.ts +103 -0
- package/src/console/ui-next/src/features/units/lib/fk-lookup.ts +175 -0
- package/src/console/ui-next/src/features/units/lib/flow-activity.test.ts +76 -0
- package/src/console/ui-next/src/features/units/lib/flow-activity.ts +68 -0
- package/src/console/ui-next/src/features/units/lib/flow-trigger.test.ts +63 -0
- package/src/console/ui-next/src/features/units/lib/flow-trigger.ts +120 -0
- package/src/console/ui-next/src/features/units/lib/invoke-cache.test.ts +31 -0
- package/src/console/ui-next/src/features/units/lib/invoke-cache.ts +22 -0
- package/src/console/ui-next/src/features/units/lib/invoke-response.test.ts +76 -0
- package/src/console/ui-next/src/features/units/lib/invoke-response.ts +70 -0
- package/src/console/ui-next/src/features/units/lib/path-params.test.ts +43 -0
- package/src/console/ui-next/src/features/units/lib/path-params.ts +75 -0
- package/src/console/ui-next/src/features/units/lib/resolve-clock.test.ts +106 -0
- package/src/console/ui-next/src/features/units/lib/resolve-clock.ts +79 -0
- package/src/console/ui-next/src/features/units/lib/schema-type-visual.ts +28 -0
- package/src/console/ui-next/src/features/units/lib/signal-delivery.test.ts +29 -0
- package/src/console/ui-next/src/features/units/lib/signal-delivery.ts +67 -0
- package/src/console/ui-next/src/features/units/lib/unit-tree.test.ts +289 -0
- package/src/console/ui-next/src/features/units/lib/unit-tree.ts +307 -0
- package/src/console/ui-next/src/features/units/lib/validate-contract.ts +103 -0
- package/src/console/ui-next/src/features/units/state/units-selection.ts +49 -0
- package/src/console/ui-next/src/features/units/units-page.tsx +120 -0
- package/src/console/ui-next/src/features/vault/data/use-vault-list.ts +27 -0
- package/src/console/ui-next/src/features/vault/detail/vault-detail.tsx +831 -0
- package/src/console/ui-next/src/features/vault/detail/vault-overview.tsx +71 -0
- package/src/console/ui-next/src/features/vault/explorer/vault-list.tsx +291 -0
- package/src/console/ui-next/src/features/vault/explorer/vault-posture-strip.tsx +131 -0
- package/src/console/ui-next/src/features/vault/explorer/vault-search.tsx +126 -0
- package/src/console/ui-next/src/features/vault/lib/backend.test.ts +147 -0
- package/src/console/ui-next/src/features/vault/lib/backend.ts +216 -0
- package/src/console/ui-next/src/features/vault/lib/blast-radius.ts +53 -0
- package/src/console/ui-next/src/features/vault/lib/confirmation.test.ts +41 -0
- package/src/console/ui-next/src/features/vault/lib/confirmation.ts +50 -0
- package/src/console/ui-next/src/features/vault/lib/contract-ops.test.ts +35 -0
- package/src/console/ui-next/src/features/vault/lib/contract-ops.ts +94 -0
- package/src/console/ui-next/src/features/vault/lib/dormant.ts +28 -0
- package/src/console/ui-next/src/features/vault/lib/export-safe.test.ts +25 -0
- package/src/console/ui-next/src/features/vault/lib/export-safe.ts +62 -0
- package/src/console/ui-next/src/features/vault/lib/fixture.ts +92 -0
- package/src/console/ui-next/src/features/vault/lib/group.test.ts +31 -0
- package/src/console/ui-next/src/features/vault/lib/group.ts +43 -0
- package/src/console/ui-next/src/features/vault/lib/posture.test.ts +137 -0
- package/src/console/ui-next/src/features/vault/lib/posture.ts +275 -0
- package/src/console/ui-next/src/features/vault/lib/progress.test.ts +36 -0
- package/src/console/ui-next/src/features/vault/lib/progress.ts +51 -0
- package/src/console/ui-next/src/features/vault/lib/search.test.ts +139 -0
- package/src/console/ui-next/src/features/vault/lib/search.ts +403 -0
- package/src/console/ui-next/src/features/vault/lib/theme.ts +14 -0
- package/src/console/ui-next/src/features/vault/lib/types.ts +114 -0
- package/src/console/ui-next/src/features/vault/lib/write-review.test.ts +139 -0
- package/src/console/ui-next/src/features/vault/lib/write-review.ts +115 -0
- package/src/console/ui-next/src/features/vault/sheets/vault-create-sheet.tsx +209 -0
- package/src/console/ui-next/src/features/vault/sheets/vault-master-key-sheet.tsx +87 -0
- package/src/console/ui-next/src/features/vault/sheets/vault-rotate-master-sheet.tsx +43 -0
- package/src/console/ui-next/src/features/vault/sheets/vault-security-sheet.tsx +205 -0
- package/src/console/ui-next/src/features/vault/sheets/vault-verify-sheet.tsx +103 -0
- package/src/console/ui-next/src/features/vault/sheets/vault-write-review-dialog.test.tsx +175 -0
- package/src/console/ui-next/src/features/vault/sheets/vault-write-review-dialog.tsx +135 -0
- package/src/console/ui-next/src/features/vault/sheets/vault-write-sheet.tsx +224 -0
- package/src/console/ui-next/src/features/vault/state/vault-selection.test.ts +20 -0
- package/src/console/ui-next/src/features/vault/state/vault-selection.ts +87 -0
- package/src/console/ui-next/src/features/vault/vault-page.tsx +439 -0
- package/src/console/ui-next/src/hooks/use-mobile.ts +22 -0
- package/src/console/ui-next/src/lib/document-meta.test.ts +43 -0
- package/src/console/ui-next/src/lib/document-meta.ts +34 -0
- package/src/console/ui-next/src/lib/ease.ts +59 -0
- package/src/console/ui-next/src/lib/element-icons.test.ts +38 -0
- package/src/console/ui-next/src/lib/element-icons.ts +75 -0
- package/src/console/ui-next/src/lib/highlight.test.ts +30 -0
- package/src/console/ui-next/src/lib/highlight.ts +39 -0
- package/src/console/ui-next/src/lib/hooks/use-hover-capable.ts +30 -0
- package/src/console/ui-next/src/lib/last-module-search.test.ts +47 -0
- package/src/console/ui-next/src/lib/last-module-search.ts +164 -0
- package/src/console/ui-next/src/lib/motion.ts +16 -0
- package/src/console/ui-next/src/lib/shiki.ts +42 -0
- package/src/console/ui-next/src/lib/shortcut-keys.tsx +47 -0
- package/src/console/ui-next/src/lib/shortcut.test.ts +70 -0
- package/src/console/ui-next/src/lib/shortcut.ts +111 -0
- package/src/console/ui-next/src/lib/use-console-shortcuts.ts +56 -0
- package/src/console/ui-next/src/lib/use-last-module-search.ts +37 -0
- package/src/console/ui-next/src/lib/utils.ts +15 -0
- package/src/console/ui-next/src/main.tsx +44 -0
- package/src/console/ui-next/src/router.tsx +175 -0
- package/src/console/ui-next/src/styles.css +384 -0
- package/src/console/ui-next/src/vite-env.d.ts +17 -0
- package/src/console/ui-next/tsconfig.json +25 -0
- package/src/console/ui-next/ui-next-dev-operator.test.ts +76 -0
- package/src/console/ui-next/ui-next-dev-operator.ts +81 -0
- package/src/console/ui-next/ui-next-seed-app-schema.ts +526 -0
- package/src/console/ui-next/ui-next-seed-manifest-surface.ts +882 -0
- package/src/console/ui-next/ui-next-seed-manifest.ts +635 -0
- package/src/console/ui-next/ui-next-seed-runs.ts +1429 -0
- package/src/console/ui-next/ui-next-seed-store.ts +1125 -0
- package/src/console/ui-next/ui-next-seed.test.ts +511 -0
- package/src/console/ui-next/ui-next-seed.ts +122 -0
- package/src/console/ui-next/vite-console-kernel-plugin.ts +195 -0
- package/src/console/ui-next/vite.config.ts +88 -0
- package/src/console/xss.gate.test.ts +21 -26
- package/src/docker/compose.ts +26 -7
- package/src/docker/derive.ts +67 -13
- package/src/docker/docker.test.ts +219 -27
- package/src/docker/helpers.ts +48 -0
- package/src/docker/images-config.test.ts +29 -22
- package/src/docker/index.ts +8 -0
- package/src/docker/postgres-advisor.integration.test.ts +163 -0
- package/src/docker/query-passthrough.integration.test.ts +212 -0
- package/src/docker/recipes/dragonfly.ts +3 -6
- package/src/docker/recipes/index.ts +13 -0
- package/src/docker/recipes/llama-cpp.ts +3 -3
- package/src/docker/recipes/nginx.ts +61 -0
- package/src/docker/recipes/ollama.ts +1 -1
- package/src/docker/recipes/postgres-advisor.ts +58 -0
- package/src/docker/recipes/postgres.ts +6 -2
- package/src/docker/recipes/redis.ts +2 -6
- package/src/docker/recipes/sglang.ts +1 -1
- package/src/docker/recipes/timescale.ts +6 -2
- package/src/docker/recipes/traefik.ts +1 -0
- package/src/docker/recipes/valkey.ts +2 -6
- package/src/docker/recipes/vllm.ts +1 -1
- package/src/docker/stack-id.test.ts +5 -14
- package/src/docker/stack-id.ts +15 -35
- package/src/docker/stack.integration.test.ts +2 -2
- package/src/docker/types.ts +16 -7
- package/src/drivers/ai-mock.ts +41 -1
- package/src/drivers/ai-openai-compatible.ts +19 -1
- package/src/drivers/index.ts +32 -0
- package/src/drivers/instances-postgres.ts +154 -0
- package/src/drivers/meilisearch.integration.test.ts +9 -0
- package/src/drivers/meilisearch.test.ts +134 -6
- package/src/drivers/meilisearch.ts +77 -8
- package/src/drivers/memory.ts +384 -24
- package/src/drivers/pg-extensions.test.ts +50 -0
- package/src/drivers/pg-extensions.ts +1054 -0
- package/src/drivers/pg-rls.test.ts +71 -0
- package/src/drivers/pg-rls.ts +234 -0
- package/src/drivers/pgvector.ts +24 -0
- package/src/drivers/redis.ts +12 -0
- package/src/drivers/s3-ensure-bucket.test.ts +88 -0
- package/src/drivers/s3-ensure-bucket.ts +152 -0
- package/src/drivers/s3.ts +34 -2
- package/src/drivers/types.ts +29 -1
- package/src/drivers/vault-1password.test.ts +164 -0
- package/src/drivers/vault-1password.ts +351 -0
- package/src/drivers/vault-aws-secrets-manager.ts +15 -94
- package/src/drivers/vault-azure-key-vault.test.ts +137 -0
- package/src/drivers/vault-azure-key-vault.ts +243 -0
- package/src/drivers/vault-doppler.test.ts +133 -0
- package/src/drivers/vault-doppler.ts +202 -0
- package/src/drivers/vault-dotenv-parse.ts +32 -0
- package/src/drivers/vault-env.ts +1 -1
- package/src/drivers/vault-gcp-secret-manager.test.ts +127 -0
- package/src/drivers/vault-gcp-secret-manager.ts +291 -0
- package/src/drivers/vault-managed.test.ts +23 -26
- package/src/drivers/vault-managed.ts +58 -20
- package/src/drivers/vault-remote-bag.ts +242 -0
- package/src/drivers/vault-types.ts +9 -7
- package/src/elements/ai/runtime.ts +100 -8
- package/src/elements/ai/schema.test.ts +133 -0
- package/src/elements/ai/schema.ts +156 -11
- package/src/elements/ai.test.ts +53 -0
- package/src/elements/ai.ts +1 -0
- package/src/elements/clock/runtime.ts +31 -13
- package/src/elements/clock.test.ts +49 -0
- package/src/elements/gate/config.ts +18 -3
- package/src/elements/gate/declare.ts +25 -5
- package/src/elements/gate/flatten.ts +74 -0
- package/src/elements/gate/permissions.ts +1 -0
- package/src/elements/gate/runtime.ts +19 -7
- package/src/elements/gate.test.ts +32 -0
- package/src/elements/gate.ts +9 -1
- package/src/elements/store/cache.test.ts +79 -0
- package/src/elements/store/cache.ts +176 -0
- package/src/elements/store/classify.ts +79 -4
- package/src/elements/store/declare.ts +7 -0
- package/src/elements/store/emit-drizzle.ts +3 -1
- package/src/elements/store/files-policy.test.ts +36 -1
- package/src/elements/store/files-policy.ts +151 -0
- package/src/elements/store/kv-sql.test.ts +86 -0
- package/src/elements/store/kv-sql.ts +178 -0
- package/src/elements/store/resource-list-docs.fixture.ts +0 -2
- package/src/elements/store/resource-list-docs.test.ts +3 -0
- package/src/elements/store/resource.test.ts +62 -2
- package/src/elements/store/resource.ts +279 -62
- package/src/elements/store/runtime.ts +88 -11
- package/src/elements/store/schema-decl.test.ts +49 -0
- package/src/elements/store/schema-decl.ts +29 -9
- package/src/elements/store/seed.test.ts +22 -1
- package/src/elements/store/seed.ts +46 -1
- package/src/elements/store/sql-session.ts +32 -7
- package/src/elements/store/table.ts +17 -1
- package/src/elements/store/upsert-app.test.ts +1 -1
- package/src/elements/store.test.ts +23 -0
- package/src/elements/store.ts +26 -3
- package/src/elements/vault/boot-chain.test.ts +108 -10
- package/src/elements/vault/boot-chain.ts +15 -15
- package/src/elements/vault/builtin-adapter.test.ts +1 -0
- package/src/elements/vault/builtin-adapter.ts +12 -0
- package/src/elements/vault/chain.ts +6 -20
- package/src/elements/vault/declare.ts +5 -2
- package/src/elements/vault/runtime.ts +47 -13
- package/src/elements/vault/storage.ts +35 -4
- package/src/elements/vault.test.ts +1 -0
- package/src/elements/vault.ts +2 -0
- package/src/full.ts +10 -0
- package/src/http.ts +1 -1
- package/src/index.ts +8 -0
- package/src/kernel/adopt-barrel-fresh.test.ts +1 -2
- package/src/kernel/app-auth.ts +8 -1
- package/src/kernel/app.ts +245 -25
- package/src/kernel/auth-resolve.ts +51 -0
- package/src/kernel/auto-cache.test.ts +270 -0
- package/src/kernel/boot-bind/ai.test.ts +34 -1
- package/src/kernel/boot-bind/ai.ts +15 -2
- package/src/kernel/boot-bind/channel.test.ts +1 -1
- package/src/kernel/boot-bind/channel.ts +1 -1
- package/src/kernel/boot-bind/clock.ts +9 -7
- package/src/kernel/boot-bind/gate.ts +1 -1
- package/src/kernel/boot-bind/honor-config.test.ts +70 -3
- package/src/kernel/boot-bind/instances.ts +58 -0
- package/src/kernel/boot-bind/journal.ts +3 -2
- package/src/kernel/boot-bind/runs.ts +63 -5
- package/src/kernel/boot-bind/signal.ts +1 -1
- package/src/kernel/boot-bind/store.test.ts +150 -1
- package/src/kernel/boot-bind/store.ts +70 -5
- package/src/kernel/boot.test.ts +9 -9
- package/src/kernel/boot.ts +115 -16
- package/src/kernel/capability.test.ts +42 -0
- package/src/kernel/capability.ts +44 -2
- package/src/kernel/compensate.test.ts +34 -1
- package/src/kernel/compensate.ts +19 -0
- package/src/kernel/effect-timing.test.ts +16 -0
- package/src/kernel/effects-stamping.test.ts +3 -3
- package/src/kernel/effects.test.ts +15 -0
- package/src/kernel/effects.ts +39 -5
- package/src/kernel/elapsed.test.ts +26 -0
- package/src/kernel/elapsed.ts +23 -0
- package/src/kernel/errors.ts +26 -3
- package/src/kernel/flow.ts +5 -1
- package/src/kernel/fx-ask-telemetry.test.ts +114 -0
- package/src/kernel/fx.test.ts +143 -2
- package/src/kernel/fx.ts +136 -19
- package/src/kernel/graceful-shutdown.test.ts +20 -0
- package/src/kernel/graceful-shutdown.ts +9 -3
- package/src/kernel/horizontal-child.ts +4 -4
- package/src/kernel/http-query.test.ts +184 -0
- package/src/kernel/http-resource.ts +55 -0
- package/src/kernel/index.ts +43 -0
- package/src/kernel/instance-id.ts +23 -0
- package/src/kernel/instances-chaos-child.ts +73 -0
- package/src/kernel/instances.chaos.test.ts +238 -0
- package/src/kernel/instances.test.ts +85 -0
- package/src/kernel/instances.ts +372 -0
- package/src/kernel/lazy-require.ts +20 -0
- package/src/kernel/list-page.test.ts +194 -0
- package/src/kernel/list-page.ts +515 -0
- package/src/kernel/list-query.ts +469 -0
- package/src/kernel/pipeline-api-key.test.ts +266 -0
- package/src/kernel/pipeline.test.ts +164 -2
- package/src/kernel/pipeline.ts +13 -1
- package/src/kernel/plugin-elements.test.ts +1 -1
- package/src/kernel/plugin-needs.test.ts +1 -1
- package/src/kernel/plugin.ts +5 -5
- package/src/kernel/ready.test.ts +22 -2
- package/src/kernel/registry.ts +8 -4
- package/src/kernel/resource-mount.test.ts +75 -0
- package/src/kernel/router/index.ts +2 -0
- package/src/kernel/router/linear.ts +7 -0
- package/src/kernel/router/regexp.ts +8 -0
- package/src/kernel/router/smart.ts +7 -3
- package/src/kernel/router/trie.ts +7 -0
- package/src/kernel/router/types.ts +41 -1
- package/src/kernel/router.test.ts +27 -0
- package/src/kernel/router.ts +2 -0
- package/src/kernel/run-duration.test.ts +92 -0
- package/src/kernel/run-telemetry.ts +8 -2
- package/src/kernel/triggers.ts +95 -74
- package/src/manifest/diff.test.ts +13 -0
- package/src/manifest/diff.ts +15 -0
- package/src/manifest/sql-resource.test.ts +29 -0
- package/src/manifest/sql-resource.ts +20 -4
- package/src/manifest/types.ts +13 -3
- package/src/plugins/auth-delivery.mailpit.integration.test.ts +1 -1
- package/src/plugins/auth-methods.security.test.ts +3 -3
- package/src/plugins/auth-methods.test.ts +2 -2
- package/src/plugins/cors.test.ts +4 -2
- package/src/plugins/cors.ts +11 -2
- package/src/plugins/csrf.test.ts +17 -0
- package/src/plugins/csrf.ts +1 -1
- package/src/plugins/username-policy.test.ts +8 -8
- package/src/plugins/username.ts +1 -1
- package/src/release/build-lib.ts +7 -1
- package/src/release/limits.ts +2 -2
- package/src/release/measure.ts +7 -10
- package/src/runs/bridge-to-console.ts +99 -0
- package/src/runs/collect.test.ts +68 -0
- package/src/runs/collect.ts +29 -2
- package/src/runs/drivers/clickhouse.ts +4 -1
- package/src/runs/drivers/files.ts +138 -33
- package/src/runs/drivers/memory.ts +46 -7
- package/src/runs/drivers/postgres.ts +4 -1
- package/src/runs/duckdb.test.ts +33 -0
- package/src/runs/duckdb.ts +41 -0
- package/src/runs/history.ts +61 -0
- package/src/runs/index.ts +29 -1
- package/src/runs/parquet.test.ts +110 -0
- package/src/runs/parquet.ts +129 -8
- package/src/runs/retention.test.ts +24 -0
- package/src/runs/retention.ts +42 -0
- package/src/runs/runs.test.ts +101 -0
- package/src/runs/runtime.ts +5 -3
- package/src/runs/types.ts +33 -4
- package/src/runtime/bun.ts +61 -4
- package/src/runtime/dev-request-log.test.ts +4 -0
- package/src/runtime/dev-request-log.ts +19 -2
- package/src/runtime/index.ts +8 -1
- package/src/runtime/json-code-block.test.ts +355 -0
- package/src/runtime/json-code-block.ts +961 -0
- package/src/runtime/serve.test.ts +49 -4
- package/src/term.test.ts +89 -1
- package/src/term.ts +103 -29
- package/src/test/create-test-app.ts +3 -1
- package/src/console/ui/access/AccessA11yView.tsx +0 -222
- package/src/console/ui/access/a11y.test.tsx +0 -113
- package/src/console/ui/access/acknowledgement.test.ts +0 -10
- package/src/console/ui/access/acknowledgement.ts +0 -33
- package/src/console/ui/access/blast-radius.test.ts +0 -26
- package/src/console/ui/access/blast-radius.ts +0 -38
- package/src/console/ui/access/confirmation.test.ts +0 -34
- package/src/console/ui/access/confirmation.ts +0 -33
- package/src/console/ui/access/fixture.ts +0 -199
- package/src/console/ui/access/grantable.test.ts +0 -15
- package/src/console/ui/access/grantable.ts +0 -31
- package/src/console/ui/access/hygiene.test.ts +0 -12
- package/src/console/ui/access/hygiene.ts +0 -39
- package/src/console/ui/access/index.ts +0 -47
- package/src/console/ui/access/provenance.test.ts +0 -10
- package/src/console/ui/access/provenance.ts +0 -25
- package/src/console/ui/access/search.test.ts +0 -13
- package/src/console/ui/access/search.ts +0 -68
- package/src/console/ui/access/types.ts +0 -111
- package/src/console/ui/ai/AiA11yView.tsx +0 -254
- package/src/console/ui/ai/a11y.test.tsx +0 -96
- package/src/console/ui/ai/findings.ts +0 -41
- package/src/console/ui/ai/fixture.ts +0 -177
- package/src/console/ui/ai/format.ts +0 -88
- package/src/console/ui/ai/group.test.ts +0 -35
- package/src/console/ui/ai/group.ts +0 -80
- package/src/console/ui/ai/index.ts +0 -59
- package/src/console/ui/ai/promotion.test.ts +0 -72
- package/src/console/ui/ai/promotion.ts +0 -141
- package/src/console/ui/ai/search.test.ts +0 -31
- package/src/console/ui/ai/search.ts +0 -79
- package/src/console/ui/ai/types.ts +0 -132
- package/src/console/ui/architecture/ArchitectureA11yView.tsx +0 -142
- package/src/console/ui/architecture/a11y.test.tsx +0 -96
- package/src/console/ui/architecture/boundary.ts +0 -42
- package/src/console/ui/architecture/declared.ts +0 -161
- package/src/console/ui/architecture/fixture.ts +0 -74
- package/src/console/ui/architecture/index.ts +0 -56
- package/src/console/ui/architecture/layers.ts +0 -64
- package/src/console/ui/architecture/layout.ts +0 -66
- package/src/console/ui/architecture/pathologies.ts +0 -251
- package/src/console/ui/architecture/search.ts +0 -136
- package/src/console/ui/architecture/traffic.ts +0 -92
- package/src/console/ui/architecture/types.ts +0 -136
- package/src/console/ui/architecture/view.test.ts +0 -153
- package/src/console/ui/architecture/view.ts +0 -489
- package/src/console/ui/channels/ChannelsA11yView.tsx +0 -171
- package/src/console/ui/channels/a11y.test.tsx +0 -95
- package/src/console/ui/channels/confirmation.test.ts +0 -34
- package/src/console/ui/channels/confirmation.ts +0 -24
- package/src/console/ui/channels/fallback.test.ts +0 -15
- package/src/console/ui/channels/fallback.ts +0 -20
- package/src/console/ui/channels/findings.ts +0 -34
- package/src/console/ui/channels/fixture.ts +0 -134
- package/src/console/ui/channels/group.ts +0 -25
- package/src/console/ui/channels/index.ts +0 -51
- package/src/console/ui/channels/locale.test.ts +0 -15
- package/src/console/ui/channels/locale.ts +0 -25
- package/src/console/ui/channels/mask.test.ts +0 -14
- package/src/console/ui/channels/mask.ts +0 -12
- package/src/console/ui/channels/search.ts +0 -49
- package/src/console/ui/channels/taxonomy.test.ts +0 -17
- package/src/console/ui/channels/taxonomy.ts +0 -47
- package/src/console/ui/channels/types.ts +0 -118
- package/src/console/ui/clock/ClockA11yView.tsx +0 -165
- package/src/console/ui/clock/a11y.test.tsx +0 -96
- package/src/console/ui/clock/confirmation.test.ts +0 -30
- package/src/console/ui/clock/confirmation.ts +0 -31
- package/src/console/ui/clock/findings.ts +0 -37
- package/src/console/ui/clock/fixture.ts +0 -111
- package/src/console/ui/clock/health.test.ts +0 -25
- package/src/console/ui/clock/health.ts +0 -56
- package/src/console/ui/clock/index.ts +0 -41
- package/src/console/ui/clock/search.test.ts +0 -37
- package/src/console/ui/clock/search.ts +0 -72
- package/src/console/ui/clock/timeline.test.ts +0 -42
- package/src/console/ui/clock/timeline.ts +0 -41
- package/src/console/ui/clock/types.ts +0 -79
- package/src/console/ui/clock/waiting-on.test.ts +0 -30
- package/src/console/ui/clock/waiting-on.ts +0 -78
- package/src/console/ui/confirmation.unify.test.ts +0 -92
- package/src/console/ui/diff/DiffA11yView.tsx +0 -76
- package/src/console/ui/diff/a11y.test.tsx +0 -96
- package/src/console/ui/diff/fixture.ts +0 -85
- package/src/console/ui/diff/group.test.ts +0 -48
- package/src/console/ui/diff/group.ts +0 -91
- package/src/console/ui/diff/index.ts +0 -32
- package/src/console/ui/diff/search.test.ts +0 -28
- package/src/console/ui/diff/search.ts +0 -63
- package/src/console/ui/diff/summary.ts +0 -73
- package/src/console/ui/diff/types.ts +0 -48
- package/src/console/ui/display.test.ts +0 -14
- package/src/console/ui/display.ts +0 -9
- package/src/console/ui/dist/assets/index--Y0Uaz-m.js +0 -10
- package/src/console/ui/dist/assets/panel-access-ri1X9Otj.js +0 -64
- package/src/console/ui/dist/assets/panel-ai-DLHjRoJk.js +0 -1
- package/src/console/ui/dist/assets/panel-architecture-DI3bQF3J.js +0 -1
- package/src/console/ui/dist/assets/panel-channels-BDYWX29p.js +0 -1
- package/src/console/ui/dist/assets/panel-clock-i-JpTjVB.js +0 -1
- package/src/console/ui/dist/assets/panel-diff-CFuWxiXy.js +0 -1
- package/src/console/ui/dist/assets/panel-flows-B8TRhcoe.js +0 -48
- package/src/console/ui/dist/assets/panel-gates-CfkBgco7.js +0 -1
- package/src/console/ui/dist/assets/panel-overview-CW0CQEc2.js +0 -1
- package/src/console/ui/dist/assets/panel-plugins-DDJwTehL.js +0 -1
- package/src/console/ui/dist/assets/panel-runs-BxuyDI3x.js +0 -1
- package/src/console/ui/dist/assets/panel-signals-BXofbj7v.js +0 -1
- package/src/console/ui/dist/assets/panel-store-B8mH-arU.js +0 -1
- package/src/console/ui/dist/assets/panel-traces-DSA-ZWnf.js +0 -1
- package/src/console/ui/dist/assets/panel-vault-BkZdJPX8.js +0 -1
- package/src/console/ui/dist/assets/rolldown-runtime-B0Z9INg1.js +0 -1
- package/src/console/ui/dist/assets/style-C3L349iZ.css +0 -3
- package/src/console/ui/dist/favicon.svg +0 -7
- package/src/console/ui/dist/index.html +0 -15
- package/src/console/ui/flows/FlowsA11yView.tsx +0 -140
- package/src/console/ui/flows/a11y.test.tsx +0 -99
- package/src/console/ui/flows/buffer.test.ts +0 -83
- package/src/console/ui/flows/buffer.ts +0 -111
- package/src/console/ui/flows/confirmation.ts +0 -129
- package/src/console/ui/flows/contract.test.ts +0 -85
- package/src/console/ui/flows/contract.ts +0 -329
- package/src/console/ui/flows/fixture.ts +0 -81
- package/src/console/ui/flows/graph.test.ts +0 -93
- package/src/console/ui/flows/graph.ts +0 -539
- package/src/console/ui/flows/index.ts +0 -82
- package/src/console/ui/flows/save-as-test.test.ts +0 -47
- package/src/console/ui/flows/save-as-test.ts +0 -97
- package/src/console/ui/flows/search.ts +0 -238
- package/src/console/ui/flows/tiers.ts +0 -133
- package/src/console/ui/gates/GatesA11yView.tsx +0 -183
- package/src/console/ui/gates/a11y.test.tsx +0 -113
- package/src/console/ui/gates/audit.test.ts +0 -40
- package/src/console/ui/gates/audit.ts +0 -61
- package/src/console/ui/gates/denial.test.ts +0 -34
- package/src/console/ui/gates/denial.ts +0 -43
- package/src/console/ui/gates/findings.ts +0 -17
- package/src/console/ui/gates/fixture.ts +0 -193
- package/src/console/ui/gates/group.test.ts +0 -30
- package/src/console/ui/gates/group.ts +0 -94
- package/src/console/ui/gates/index.ts +0 -39
- package/src/console/ui/gates/search.test.ts +0 -49
- package/src/console/ui/gates/search.ts +0 -108
- package/src/console/ui/gates/types.ts +0 -124
- package/src/console/ui/overview/OverviewA11yView.tsx +0 -134
- package/src/console/ui/overview/a11y.test.tsx +0 -112
- package/src/console/ui/overview/busiest.ts +0 -24
- package/src/console/ui/overview/compose.ts +0 -121
- package/src/console/ui/overview/cost.test.ts +0 -39
- package/src/console/ui/overview/cost.ts +0 -134
- package/src/console/ui/overview/fixture.ts +0 -156
- package/src/console/ui/overview/golden.ts +0 -47
- package/src/console/ui/overview/index.ts +0 -52
- package/src/console/ui/overview/rank.test.ts +0 -129
- package/src/console/ui/overview/rank.ts +0 -205
- package/src/console/ui/overview/slo.test.ts +0 -69
- package/src/console/ui/overview/slo.ts +0 -240
- package/src/console/ui/overview/types.ts +0 -127
- package/src/console/ui/overview/verdict.ts +0 -124
- package/src/console/ui/plugins/PluginsA11yView.tsx +0 -217
- package/src/console/ui/plugins/a11y.test.tsx +0 -96
- package/src/console/ui/plugins/command.test.ts +0 -22
- package/src/console/ui/plugins/command.ts +0 -27
- package/src/console/ui/plugins/findings.ts +0 -39
- package/src/console/ui/plugins/fixture.ts +0 -238
- package/src/console/ui/plugins/group.test.ts +0 -36
- package/src/console/ui/plugins/group.ts +0 -62
- package/src/console/ui/plugins/index.ts +0 -30
- package/src/console/ui/plugins/search.ts +0 -55
- package/src/console/ui/plugins/types.ts +0 -118
- package/src/console/ui/runs/RunsA11yView.tsx +0 -252
- package/src/console/ui/runs/a11y.test.tsx +0 -96
- package/src/console/ui/runs/errors.test.ts +0 -53
- package/src/console/ui/runs/errors.ts +0 -88
- package/src/console/ui/runs/explain.test.ts +0 -23
- package/src/console/ui/runs/explain.ts +0 -28
- package/src/console/ui/runs/fixture.ts +0 -189
- package/src/console/ui/runs/group.test.ts +0 -24
- package/src/console/ui/runs/group.ts +0 -76
- package/src/console/ui/runs/histogram.test.ts +0 -22
- package/src/console/ui/runs/histogram.ts +0 -82
- package/src/console/ui/runs/index.ts +0 -69
- package/src/console/ui/runs/project.ts +0 -118
- package/src/console/ui/runs/query.test.ts +0 -48
- package/src/console/ui/runs/query.ts +0 -260
- package/src/console/ui/runs/search.test.ts +0 -45
- package/src/console/ui/runs/search.ts +0 -143
- package/src/console/ui/runs/trace-link.test.ts +0 -26
- package/src/console/ui/runs/trace-link.ts +0 -87
- package/src/console/ui/runs/types.ts +0 -135
- package/src/console/ui/shell/App.tsx +0 -88
- package/src/console/ui/shell/client.ts +0 -1642
- package/src/console/ui/shell/components/oke-logo.tsx +0 -40
- package/src/console/ui/shell/components/ui.tsx +0 -111
- package/src/console/ui/shell/index.html +0 -13
- package/src/console/ui/shell/layout/Shell.tsx +0 -92
- package/src/console/ui/shell/main.tsx +0 -216
- package/src/console/ui/shell/panels/Access.tsx +0 -5
- package/src/console/ui/shell/panels/Ai.tsx +0 -5
- package/src/console/ui/shell/panels/Architecture.tsx +0 -5
- package/src/console/ui/shell/panels/Channels.tsx +0 -5
- package/src/console/ui/shell/panels/Clock.tsx +0 -5
- package/src/console/ui/shell/panels/Diff.tsx +0 -5
- package/src/console/ui/shell/panels/Flows.tsx +0 -5
- package/src/console/ui/shell/panels/Gates.tsx +0 -5
- package/src/console/ui/shell/panels/Overview.tsx +0 -6
- package/src/console/ui/shell/panels/Plugins.tsx +0 -5
- package/src/console/ui/shell/panels/Runs.tsx +0 -5
- package/src/console/ui/shell/panels/Signals.tsx +0 -5
- package/src/console/ui/shell/panels/Store.tsx +0 -5
- package/src/console/ui/shell/panels/Traces.tsx +0 -5
- package/src/console/ui/shell/panels/Vault.tsx +0 -5
- package/src/console/ui/shell/panels/access/AccessPanel.tsx +0 -749
- package/src/console/ui/shell/panels/ai/AiPanel.tsx +0 -492
- package/src/console/ui/shell/panels/architecture/ArchitecturePanel.tsx +0 -329
- package/src/console/ui/shell/panels/channels/ChannelsPanel.tsx +0 -422
- package/src/console/ui/shell/panels/clock/ClockPanel.tsx +0 -454
- package/src/console/ui/shell/panels/diff/DiffPanel.tsx +0 -234
- package/src/console/ui/shell/panels/flows/ContractEditor.tsx +0 -284
- package/src/console/ui/shell/panels/flows/FlowDrawer.tsx +0 -335
- package/src/console/ui/shell/panels/flows/FlowsPanel.tsx +0 -482
- package/src/console/ui/shell/panels/gates/GatesPanel.tsx +0 -433
- package/src/console/ui/shell/panels/overview/OverviewPanel.tsx +0 -398
- package/src/console/ui/shell/panels/plugins/PluginsPanel.tsx +0 -402
- package/src/console/ui/shell/panels/runs/RunsPanel.tsx +0 -652
- package/src/console/ui/shell/panels/signals/SignalsPanel.tsx +0 -788
- package/src/console/ui/shell/panels/store/StorePanel.tsx +0 -755
- package/src/console/ui/shell/panels/traces/TracesPanel.tsx +0 -478
- package/src/console/ui/shell/panels/vault/VaultPanel.tsx +0 -477
- package/src/console/ui/shell/plugin/Sandbox.tsx +0 -29
- package/src/console/ui/shell/public/favicon.svg +0 -7
- package/src/console/ui/shell/setup/Wizard.tsx +0 -211
- package/src/console/ui/shell/styles.css +0 -74
- package/src/console/ui/signals/SignalsA11yView.tsx +0 -252
- package/src/console/ui/signals/a11y.test.tsx +0 -96
- package/src/console/ui/signals/confirmation.test.ts +0 -35
- package/src/console/ui/signals/confirmation.ts +0 -59
- package/src/console/ui/signals/dry-run.test.ts +0 -18
- package/src/console/ui/signals/dry-run.ts +0 -34
- package/src/console/ui/signals/durable.test.ts +0 -22
- package/src/console/ui/signals/durable.ts +0 -39
- package/src/console/ui/signals/findings.ts +0 -31
- package/src/console/ui/signals/fixture.ts +0 -242
- package/src/console/ui/signals/group.test.ts +0 -26
- package/src/console/ui/signals/group.ts +0 -41
- package/src/console/ui/signals/index.ts +0 -49
- package/src/console/ui/signals/monitor.test.ts +0 -30
- package/src/console/ui/signals/monitor.ts +0 -74
- package/src/console/ui/signals/schema-form.test.ts +0 -23
- package/src/console/ui/signals/schema-form.ts +0 -109
- package/src/console/ui/signals/search.ts +0 -93
- package/src/console/ui/signals/types.ts +0 -72
- package/src/console/ui/store/StoreA11yView.tsx +0 -193
- package/src/console/ui/store/a11y.test.tsx +0 -96
- package/src/console/ui/store/cache-view.test.ts +0 -13
- package/src/console/ui/store/cache-view.ts +0 -36
- package/src/console/ui/store/confirmation.test.ts +0 -36
- package/src/console/ui/store/confirmation.ts +0 -52
- package/src/console/ui/store/dry-run.test.ts +0 -15
- package/src/console/ui/store/dry-run.ts +0 -26
- package/src/console/ui/store/fixture.ts +0 -167
- package/src/console/ui/store/group.test.ts +0 -16
- package/src/console/ui/store/group.ts +0 -38
- package/src/console/ui/store/index.ts +0 -36
- package/src/console/ui/store/search.ts +0 -74
- package/src/console/ui/store/types.ts +0 -67
- package/src/console/ui/store/will-not-fire.test.ts +0 -19
- package/src/console/ui/store/will-not-fire.ts +0 -39
- package/src/console/ui/traces/TracesA11yView.tsx +0 -181
- package/src/console/ui/traces/a11y.test.tsx +0 -96
- package/src/console/ui/traces/chain.test.ts +0 -47
- package/src/console/ui/traces/chain.ts +0 -142
- package/src/console/ui/traces/critical-path.test.ts +0 -22
- package/src/console/ui/traces/critical-path.ts +0 -55
- package/src/console/ui/traces/filter.test.ts +0 -74
- package/src/console/ui/traces/filter.ts +0 -104
- package/src/console/ui/traces/fixture.ts +0 -126
- package/src/console/ui/traces/fold.test.ts +0 -59
- package/src/console/ui/traces/fold.ts +0 -168
- package/src/console/ui/traces/index.ts +0 -64
- package/src/console/ui/traces/mini.ts +0 -63
- package/src/console/ui/traces/replay.test.ts +0 -22
- package/src/console/ui/traces/replay.ts +0 -33
- package/src/console/ui/traces/sampling.test.ts +0 -26
- package/src/console/ui/traces/sampling.ts +0 -63
- package/src/console/ui/traces/search.ts +0 -135
- package/src/console/ui/traces/tier.ts +0 -70
- package/src/console/ui/traces/types.ts +0 -125
- package/src/console/ui/tsconfig.json +0 -20
- package/src/console/ui/vault/VaultA11yView.tsx +0 -197
- package/src/console/ui/vault/a11y.test.tsx +0 -96
- package/src/console/ui/vault/backend.test.ts +0 -75
- package/src/console/ui/vault/backend.ts +0 -117
- package/src/console/ui/vault/blast-radius.ts +0 -53
- package/src/console/ui/vault/confirmation.test.ts +0 -37
- package/src/console/ui/vault/confirmation.ts +0 -36
- package/src/console/ui/vault/dormant.ts +0 -28
- package/src/console/ui/vault/export-safe.test.ts +0 -26
- package/src/console/ui/vault/export-safe.ts +0 -62
- package/src/console/ui/vault/fixture.ts +0 -94
- package/src/console/ui/vault/group.test.ts +0 -25
- package/src/console/ui/vault/group.ts +0 -49
- package/src/console/ui/vault/index.ts +0 -47
- package/src/console/ui/vault/search.ts +0 -58
- package/src/console/ui/vault/types.ts +0 -83
- package/src/console/ui/vite.config.ts +0 -84
- /package/src/console/{ui/vault → ui-next/src/features/vault/lib}/blast-radius.test.ts +0 -0
- /package/src/console/{ui/vault → ui-next/src/features/vault/lib}/dormant.test.ts +0 -0
|
@@ -15,7 +15,10 @@ import {
|
|
|
15
15
|
computedCacheKey,
|
|
16
16
|
createStoreRuntime,
|
|
17
17
|
files as declareFiles,
|
|
18
|
+
fileKeyWarnings,
|
|
18
19
|
index as declareIndex,
|
|
20
|
+
coerceSafeFileObjectKey,
|
|
21
|
+
inferFileContentType,
|
|
19
22
|
isInvalidatedByWrite,
|
|
20
23
|
kv as declareKv,
|
|
21
24
|
projectFileKeys,
|
|
@@ -27,8 +30,37 @@ import {
|
|
|
27
30
|
type StoreRuntime,
|
|
28
31
|
} from "../../elements/store.ts";
|
|
29
32
|
import { DryRunWriteIsolationError, withDryRun } from "../../kernel/dry-run.ts";
|
|
30
|
-
import
|
|
33
|
+
import { addPiiFieldName, piiNameAliases, PII_MASK } from "../../elements/store/classify.ts";
|
|
34
|
+
import { rankIndexHits } from "./index-search.ts";
|
|
35
|
+
import type {
|
|
36
|
+
ColumnClassification,
|
|
37
|
+
Effects,
|
|
38
|
+
Manifest,
|
|
39
|
+
ResourceRef,
|
|
40
|
+
StoreFacet,
|
|
41
|
+
} from "../../manifest/types.ts";
|
|
31
42
|
import type { WideEvent } from "../../runs/types.ts";
|
|
43
|
+
import { consoleAuthStoreEnabled, projectConsoleAuthStore } from "./auth-store.ts";
|
|
44
|
+
import {
|
|
45
|
+
fileObjectRecord,
|
|
46
|
+
isFilesCatalogKey,
|
|
47
|
+
readFilesCatalog,
|
|
48
|
+
removeFilesCatalogRecords,
|
|
49
|
+
upsertFilesCatalogRecord,
|
|
50
|
+
} from "./files-catalog.ts";
|
|
51
|
+
import {
|
|
52
|
+
alterSqlPolicy,
|
|
53
|
+
createSqlPolicy,
|
|
54
|
+
dropSqlPolicy,
|
|
55
|
+
applySqlTableRls,
|
|
56
|
+
listSqlCatalog,
|
|
57
|
+
listSqlTableRls,
|
|
58
|
+
setSqlExtension,
|
|
59
|
+
setSqlRowSecurity,
|
|
60
|
+
sqlCatalogKind,
|
|
61
|
+
sqlCatalogStoreChildren,
|
|
62
|
+
upgradeSqlExtension,
|
|
63
|
+
} from "./sql-catalog.ts";
|
|
32
64
|
|
|
33
65
|
/** Whether multi-tenancy is declared on the Manifest (off by default). */
|
|
34
66
|
export function tenancyDeclared(manifest: Manifest | null): boolean {
|
|
@@ -64,6 +96,8 @@ export interface ConsoleStoreChild {
|
|
|
64
96
|
readonly name: string;
|
|
65
97
|
/** Effect ref used in Manifest (`sql:bookings`). */
|
|
66
98
|
readonly effectRef: ResourceRef;
|
|
99
|
+
/** SQL catalog folder when not a table. */
|
|
100
|
+
readonly kind?: "table" | "index" | "function" | "trigger" | "extension" | "policy";
|
|
67
101
|
readonly writers: readonly string[];
|
|
68
102
|
readonly readers: readonly string[];
|
|
69
103
|
readonly cache: ConsoleStoreCacheView;
|
|
@@ -71,6 +105,8 @@ export interface ConsoleStoreChild {
|
|
|
71
105
|
readonly piiColumns: readonly string[];
|
|
72
106
|
/** Column key → optional human description (SQL tables). */
|
|
73
107
|
readonly columnDescriptions: Readonly<Record<string, string>>;
|
|
108
|
+
/** Live RLS (`pg_class.relrowsecurity`) when the engine can report it. */
|
|
109
|
+
readonly rls?: boolean;
|
|
74
110
|
}
|
|
75
111
|
|
|
76
112
|
/** One row in `console.store.list`. */
|
|
@@ -83,6 +119,8 @@ export interface ConsoleStoreRow {
|
|
|
83
119
|
readonly replicaLagMs: number | null;
|
|
84
120
|
readonly migrationDrift: ConsoleMigrationDrift | null;
|
|
85
121
|
readonly contentAddressed: boolean;
|
|
122
|
+
/** Files driver when the runtime could open the handle (`memory` / `fs` / `s3`). */
|
|
123
|
+
readonly driverId?: "memory" | "fs" | "s3";
|
|
86
124
|
readonly warnings: ReadonlyArray<{
|
|
87
125
|
readonly code: string;
|
|
88
126
|
readonly message: string;
|
|
@@ -99,6 +137,11 @@ export interface ProjectStoresOptions {
|
|
|
99
137
|
/** Injected fingerprints for tests. */
|
|
100
138
|
readonly declaredFingerprint?: string;
|
|
101
139
|
readonly appliedFingerprint?: string | null;
|
|
140
|
+
/**
|
|
141
|
+
* Surface `sql:oke_console` (operator-plane auth). Default: env
|
|
142
|
+
* `OKE_CONSOLE_AUTH_STORE=1`.
|
|
143
|
+
*/
|
|
144
|
+
readonly includeAuthStore?: boolean;
|
|
102
145
|
}
|
|
103
146
|
|
|
104
147
|
/**
|
|
@@ -135,17 +178,26 @@ export async function projectStoresList(options: ProjectStoresOptions): Promise<
|
|
|
135
178
|
for (const [name, store] of Object.entries(manifest?.stores ?? {})) {
|
|
136
179
|
const facet = store.facet;
|
|
137
180
|
const ref = `${facet}:${name}` as ResourceRef;
|
|
138
|
-
const children =
|
|
181
|
+
const children = await withSqlTableRls(
|
|
182
|
+
options.runtime,
|
|
183
|
+
ref,
|
|
184
|
+
facet,
|
|
185
|
+
childrenOf(manifest!, name, facet, store),
|
|
186
|
+
);
|
|
139
187
|
const replicaLagMs = facet === "sql" ? latestReplicaLag(options.runs ?? [], children) : null;
|
|
140
188
|
|
|
141
189
|
let warnings: ConsoleStoreRow["warnings"] = [];
|
|
190
|
+
let filesDriverId: FilesStoreFxHandle["driverId"] | undefined;
|
|
142
191
|
if (facet === "files" && options.runtime) {
|
|
143
192
|
try {
|
|
144
193
|
const handle = (await options.runtime.openRef(ref, {
|
|
145
194
|
effects: { reads: [ref] },
|
|
146
195
|
})) as FilesStoreFxHandle;
|
|
196
|
+
filesDriverId = handle.driverId;
|
|
147
197
|
const keys = await handle.list();
|
|
148
|
-
warnings = projectFileKeys(keys
|
|
198
|
+
warnings = projectFileKeys(keys.filter((k) => !isFilesCatalogKey(k))).flatMap(
|
|
199
|
+
(k) => k.warnings,
|
|
200
|
+
);
|
|
149
201
|
} catch {
|
|
150
202
|
warnings = [];
|
|
151
203
|
}
|
|
@@ -160,10 +212,15 @@ export async function projectStoresList(options: ProjectStoresOptions): Promise<
|
|
|
160
212
|
replicaLagMs,
|
|
161
213
|
migrationDrift: facet === "sql" ? drift : null,
|
|
162
214
|
contentAddressed: facet === "files",
|
|
215
|
+
...(filesDriverId ? { driverId: filesDriverId } : {}),
|
|
163
216
|
warnings,
|
|
164
217
|
});
|
|
165
218
|
}
|
|
166
219
|
|
|
220
|
+
if (options.includeAuthStore ?? consoleAuthStoreEnabled()) {
|
|
221
|
+
stores.push(projectConsoleAuthStore());
|
|
222
|
+
}
|
|
223
|
+
|
|
167
224
|
stores.sort((a, b) => {
|
|
168
225
|
const order: StoreFacet[] = ["sql", "kv", "files", "index"];
|
|
169
226
|
const d = order.indexOf(a.facet) - order.indexOf(b.facet);
|
|
@@ -200,10 +257,8 @@ function childrenOf(
|
|
|
200
257
|
}
|
|
201
258
|
|
|
202
259
|
const unique = [...new Set(names)].sort();
|
|
203
|
-
|
|
204
|
-
const effectRef =
|
|
205
|
-
facet === "sql" ? `sql:${childName}` : `${facet}:${storeName}`
|
|
206
|
-
) as ResourceRef;
|
|
260
|
+
const tables = unique.map((childName) => {
|
|
261
|
+
const effectRef = `${facet}:${childName}` as ResourceRef;
|
|
207
262
|
const writers = flowsTouching(manifest, effectRef, "writes");
|
|
208
263
|
const readers = flowsTouching(manifest, effectRef, "reads");
|
|
209
264
|
const willNotFire = willNotFireFor(manifest, writers);
|
|
@@ -224,8 +279,26 @@ function childrenOf(
|
|
|
224
279
|
willNotFire,
|
|
225
280
|
piiColumns,
|
|
226
281
|
columnDescriptions: columnDescriptionsFor(store, childName),
|
|
282
|
+
...(facet === "sql" ? { kind: "table" as const, rls: false } : {}),
|
|
227
283
|
};
|
|
228
284
|
});
|
|
285
|
+
if (facet !== "sql") return tables;
|
|
286
|
+
return [...tables, ...sqlCatalogStoreChildren(`${facet}:${storeName}` as ResourceRef)];
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async function withSqlTableRls(
|
|
290
|
+
runtime: StoreRuntime | null,
|
|
291
|
+
ref: ResourceRef,
|
|
292
|
+
facet: StoreFacet,
|
|
293
|
+
children: readonly ConsoleStoreChild[],
|
|
294
|
+
): Promise<readonly ConsoleStoreChild[]> {
|
|
295
|
+
if (facet !== "sql" || runtime === null) return children;
|
|
296
|
+
try {
|
|
297
|
+
const sql = (await runtime.openRef(ref, { effects: { reads: [ref] } })) as SqlStoreHandle;
|
|
298
|
+
return applySqlTableRls(children, await listSqlTableRls(sql));
|
|
299
|
+
} catch {
|
|
300
|
+
return children;
|
|
301
|
+
}
|
|
229
302
|
}
|
|
230
303
|
|
|
231
304
|
function columnDescriptionsFor(
|
|
@@ -278,10 +351,16 @@ export function willNotFireFor(
|
|
|
278
351
|
}
|
|
279
352
|
|
|
280
353
|
function piiColumnsFor(store: NonNullable<Manifest["stores"]>[string], table: string): string[] {
|
|
281
|
-
const cols
|
|
354
|
+
const cols = new Set<string>();
|
|
282
355
|
const tableMeta = store.tables?.[table];
|
|
283
356
|
for (const [col, tags] of Object.entries(tableMeta?.columns ?? {})) {
|
|
284
|
-
if (tags?.pii)
|
|
357
|
+
if (!tags?.pii) continue;
|
|
358
|
+
addPiiFieldName(cols, col);
|
|
359
|
+
const sqlName =
|
|
360
|
+
"sqlName" in tags && typeof (tags as { sqlName?: unknown }).sqlName === "string"
|
|
361
|
+
? (tags as { sqlName: string }).sqlName
|
|
362
|
+
: undefined;
|
|
363
|
+
if (sqlName) addPiiFieldName(cols, sqlName);
|
|
285
364
|
}
|
|
286
365
|
for (const [key, tags] of Object.entries(store.classifications ?? {})) {
|
|
287
366
|
if (
|
|
@@ -292,10 +371,10 @@ function piiColumnsFor(store: NonNullable<Manifest["stores"]>[string], table: st
|
|
|
292
371
|
"pii" in tags &&
|
|
293
372
|
(tags as { pii?: boolean }).pii
|
|
294
373
|
) {
|
|
295
|
-
cols
|
|
374
|
+
addPiiFieldName(cols, key.slice(table.length + 1));
|
|
296
375
|
}
|
|
297
376
|
}
|
|
298
|
-
return [...
|
|
377
|
+
return [...cols].sort();
|
|
299
378
|
}
|
|
300
379
|
|
|
301
380
|
function latestReplicaLag(
|
|
@@ -341,6 +420,9 @@ export interface StoreQueryResult {
|
|
|
341
420
|
readonly keys?: ReadonlyArray<{
|
|
342
421
|
readonly key: string;
|
|
343
422
|
readonly value?: unknown;
|
|
423
|
+
readonly ttlMs?: number | null;
|
|
424
|
+
readonly sizeBytes?: number;
|
|
425
|
+
readonly originalName?: string;
|
|
344
426
|
readonly warnings?: ReadonlyArray<{
|
|
345
427
|
readonly code: string;
|
|
346
428
|
readonly message: string;
|
|
@@ -356,6 +438,62 @@ export interface StoreQueryResult {
|
|
|
356
438
|
readonly routedRole?: "primary" | "replica";
|
|
357
439
|
}
|
|
358
440
|
|
|
441
|
+
const KV_TTL_RE = /^(\d+)(ms|s|m|h|d)$/;
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Prefix for `kv.list` when Console browse does not pass an explicit one.
|
|
445
|
+
*
|
|
446
|
+
* A dedicated `store.kv("drafts")` keeps keys at the namespace root
|
|
447
|
+
* (`ENG-184`). `${child}:` is only for a shared KV store whose children
|
|
448
|
+
* are key prefixes (`kv:cache` / `drafts:…`).
|
|
449
|
+
*
|
|
450
|
+
* @param ref - Store ref (`kv:drafts`)
|
|
451
|
+
* @param child - Selected child / namespace
|
|
452
|
+
* @param explicit - Operator-supplied list prefix
|
|
453
|
+
*/
|
|
454
|
+
function kvBrowsePrefix(
|
|
455
|
+
ref: string,
|
|
456
|
+
child: string | undefined,
|
|
457
|
+
explicit: string | undefined,
|
|
458
|
+
): string {
|
|
459
|
+
if (explicit !== undefined) return explicit;
|
|
460
|
+
if (!child) return "";
|
|
461
|
+
const storeName = ref.split(":")[1] ?? "";
|
|
462
|
+
if (child === storeName) return "";
|
|
463
|
+
return `${child}:`;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Resolve the TTL argument for `kv.set` from a Console patch.
|
|
468
|
+
* Omitted `ttl` keeps the remaining expiry; `null` / empty clears it.
|
|
469
|
+
*
|
|
470
|
+
* @param patch - Edit patch
|
|
471
|
+
* @param remainingMs - Current remaining TTL, or null
|
|
472
|
+
*/
|
|
473
|
+
function kvTtlFromPatch(
|
|
474
|
+
patch: Readonly<Record<string, unknown>>,
|
|
475
|
+
remainingMs: number | null,
|
|
476
|
+
): string | undefined {
|
|
477
|
+
if (!("ttl" in patch)) {
|
|
478
|
+
return remainingMs !== null && remainingMs > 0 ? `${Math.ceil(remainingMs)}ms` : undefined;
|
|
479
|
+
}
|
|
480
|
+
const raw = patch.ttl;
|
|
481
|
+
if (raw === null || raw === "") return undefined;
|
|
482
|
+
if (typeof raw !== "string" || !KV_TTL_RE.test(raw.trim())) {
|
|
483
|
+
throw new Error("TTL must be a duration like 30m, 1h, or empty to clear");
|
|
484
|
+
}
|
|
485
|
+
return raw.trim();
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/** UTF-8 byte length of a JSON-serialized KV value. */
|
|
489
|
+
function kvValueSizeBytes(value: unknown): number {
|
|
490
|
+
try {
|
|
491
|
+
return new TextEncoder().encode(JSON.stringify(value ?? null)).length;
|
|
492
|
+
} catch {
|
|
493
|
+
return 0;
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
359
497
|
/**
|
|
360
498
|
* Browse a store facet through the runtime (PII masked unless reveal).
|
|
361
499
|
*
|
|
@@ -381,6 +519,12 @@ export async function queryStore(
|
|
|
381
519
|
if (!table) {
|
|
382
520
|
return { facet, rows: [], masked: !input.revealPii, routedRole: sql.routedRole };
|
|
383
521
|
}
|
|
522
|
+
const catalog = sqlCatalogKind(table);
|
|
523
|
+
if (catalog) {
|
|
524
|
+
const storeName = input.ref.split(":")[1] ?? "";
|
|
525
|
+
const rows = await listSqlCatalog(sql, catalog, manifest, storeName, input.limit ?? 200);
|
|
526
|
+
return { facet, rows, masked: false, routedRole: sql.routedRole };
|
|
527
|
+
}
|
|
384
528
|
const limit = input.limit ?? 50;
|
|
385
529
|
let sqlText = `SELECT * FROM "${table}"`;
|
|
386
530
|
const params: unknown[] = [];
|
|
@@ -410,51 +554,203 @@ export async function queryStore(
|
|
|
410
554
|
|
|
411
555
|
if (facet === "kv") {
|
|
412
556
|
const kv = handle as KvStoreFxHandle;
|
|
413
|
-
const keys = await kv.list(input.
|
|
557
|
+
const keys = await kv.list(kvBrowsePrefix(input.ref, input.child, input.prefix));
|
|
414
558
|
const limited = keys.slice(0, input.limit ?? 100);
|
|
415
559
|
const entries = await Promise.all(
|
|
416
|
-
limited.map(async (key) =>
|
|
417
|
-
key
|
|
418
|
-
|
|
419
|
-
|
|
560
|
+
limited.map(async (key) => {
|
|
561
|
+
const value = await kv.get(key);
|
|
562
|
+
return {
|
|
563
|
+
key,
|
|
564
|
+
value,
|
|
565
|
+
ttlMs: await kv.ttlMs(key),
|
|
566
|
+
sizeBytes: kvValueSizeBytes(value),
|
|
567
|
+
};
|
|
568
|
+
}),
|
|
420
569
|
);
|
|
421
570
|
return { facet, keys: entries, masked: false };
|
|
422
571
|
}
|
|
423
572
|
|
|
424
573
|
if (facet === "files") {
|
|
425
574
|
const filesHandle = handle as FilesStoreFxHandle;
|
|
426
|
-
const keys = await filesHandle.list(input.prefix ?? "");
|
|
575
|
+
const keys = (await filesHandle.list(input.prefix ?? "")).filter((k) => !isFilesCatalogKey(k));
|
|
576
|
+
const catalog = await readFilesCatalog(filesHandle);
|
|
427
577
|
const projected = projectFileKeys(keys.slice(0, input.limit ?? 100));
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
578
|
+
const entries = await Promise.all(
|
|
579
|
+
projected.map(async (k) => {
|
|
580
|
+
const data = await filesHandle.get(k.key);
|
|
581
|
+
const meta = catalog.objects[k.key];
|
|
582
|
+
return {
|
|
583
|
+
key: k.key,
|
|
584
|
+
sizeBytes: data?.byteLength ?? 0,
|
|
585
|
+
...(meta ? { originalName: meta.originalName } : {}),
|
|
586
|
+
warnings: k.warnings.map((w) => ({
|
|
587
|
+
code: w.code,
|
|
588
|
+
message: w.message,
|
|
589
|
+
})),
|
|
590
|
+
};
|
|
591
|
+
}),
|
|
592
|
+
);
|
|
593
|
+
return { facet, keys: entries, masked: false };
|
|
439
594
|
}
|
|
440
595
|
|
|
441
|
-
// index
|
|
596
|
+
// index — text query ranks stored meta; a vector still probes ANN.
|
|
442
597
|
const idx = handle as IndexStoreFxHandle;
|
|
443
598
|
void manifest;
|
|
599
|
+
const topK = input.topK ?? 5;
|
|
600
|
+
const listLimit = input.limit ?? 100;
|
|
601
|
+
const q = input.q?.trim() ?? "";
|
|
602
|
+
const vector = input.vector ?? [];
|
|
603
|
+
|
|
444
604
|
if (idx.driverId === "meilisearch") {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
return {
|
|
605
|
+
if (q.length > 0) {
|
|
606
|
+
const result = await idx.search(q, { topK });
|
|
607
|
+
return {
|
|
608
|
+
facet,
|
|
609
|
+
hits: result.hits,
|
|
610
|
+
facetDistribution: result.facetDistribution,
|
|
611
|
+
masked: false,
|
|
612
|
+
};
|
|
448
613
|
}
|
|
449
|
-
|
|
450
|
-
return { facet, hits: result.hits, facetDistribution: result.facetDistribution, masked: false };
|
|
614
|
+
return { facet, hits: await idx.list(listLimit), masked: false };
|
|
451
615
|
}
|
|
452
|
-
|
|
453
|
-
if (vector.length
|
|
454
|
-
return { facet, hits:
|
|
616
|
+
|
|
617
|
+
if (vector.length > 0) {
|
|
618
|
+
return { facet, hits: await idx.search(vector, topK), masked: false };
|
|
619
|
+
}
|
|
620
|
+
if (q.length > 0) {
|
|
621
|
+
return {
|
|
622
|
+
facet,
|
|
623
|
+
hits: rankIndexHits(await idx.list(INDEX_TEXT_SCAN), q, topK),
|
|
624
|
+
masked: false,
|
|
625
|
+
};
|
|
455
626
|
}
|
|
456
|
-
|
|
457
|
-
|
|
627
|
+
return { facet, hits: await idx.list(listLimit), masked: false };
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/** How many documents a text query scans before ranking. */
|
|
631
|
+
const INDEX_TEXT_SCAN = 2_000;
|
|
632
|
+
|
|
633
|
+
/** Max object body returned by {@link getStoreFile} (2 MiB). */
|
|
634
|
+
export const STORE_FILE_BODY_MAX = 2_000_000;
|
|
635
|
+
|
|
636
|
+
/** Request for {@link getStoreFile}. */
|
|
637
|
+
export interface StoreFileGetInput {
|
|
638
|
+
readonly ref: ResourceRef;
|
|
639
|
+
readonly key: string;
|
|
640
|
+
readonly tenant?: string;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/** Object payload for Console preview / download. */
|
|
644
|
+
export interface StoreFileObject {
|
|
645
|
+
readonly key: string;
|
|
646
|
+
readonly sizeBytes: number;
|
|
647
|
+
readonly contentType: string;
|
|
648
|
+
readonly encoding: "utf8" | "base64";
|
|
649
|
+
readonly body: string;
|
|
650
|
+
readonly truncated: boolean;
|
|
651
|
+
readonly originalName?: string;
|
|
652
|
+
readonly warnings: ReadonlyArray<{
|
|
653
|
+
readonly code: string;
|
|
654
|
+
readonly message: string;
|
|
655
|
+
}>;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Read one files object for Console preview / download.
|
|
660
|
+
*
|
|
661
|
+
* @param runtime - Store runtime
|
|
662
|
+
* @param input - Store ref + object key
|
|
663
|
+
*/
|
|
664
|
+
export async function getStoreFile(
|
|
665
|
+
runtime: StoreRuntime,
|
|
666
|
+
input: StoreFileGetInput,
|
|
667
|
+
): Promise<StoreFileObject> {
|
|
668
|
+
const [facet] = input.ref.split(":") as [StoreFacet, string];
|
|
669
|
+
if (facet !== "files") {
|
|
670
|
+
throw new Error(`store object get requires a files ref, got ${input.ref}`);
|
|
671
|
+
}
|
|
672
|
+
const handle = (await runtime.openRef(input.ref, {
|
|
673
|
+
effects: { reads: [input.ref] },
|
|
674
|
+
})) as FilesStoreFxHandle;
|
|
675
|
+
const data = await handle.get(input.key);
|
|
676
|
+
if (!data) {
|
|
677
|
+
throw new StoreFileNotFoundError(input.ref, input.key);
|
|
678
|
+
}
|
|
679
|
+
const truncated = data.byteLength > STORE_FILE_BODY_MAX;
|
|
680
|
+
const slice = truncated ? data.subarray(0, STORE_FILE_BODY_MAX) : data;
|
|
681
|
+
const catalog = await readFilesCatalog(handle);
|
|
682
|
+
const meta = catalog.objects[input.key];
|
|
683
|
+
const contentType = meta?.contentType ?? inferFileContentType(meta?.originalName ?? input.key);
|
|
684
|
+
const asText = fileBytesAsUtf8(slice, contentType);
|
|
685
|
+
return {
|
|
686
|
+
key: input.key,
|
|
687
|
+
sizeBytes: data.byteLength,
|
|
688
|
+
contentType,
|
|
689
|
+
encoding: asText !== null ? "utf8" : "base64",
|
|
690
|
+
body: asText ?? bytesToBase64(slice),
|
|
691
|
+
truncated,
|
|
692
|
+
...(meta ? { originalName: meta.originalName } : {}),
|
|
693
|
+
warnings: fileKeyWarnings(input.key).map((w) => ({
|
|
694
|
+
code: w.code,
|
|
695
|
+
message: w.message,
|
|
696
|
+
})),
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
/** Missing object on {@link getStoreFile}. */
|
|
701
|
+
export class StoreFileNotFoundError extends Error {
|
|
702
|
+
readonly ref: string;
|
|
703
|
+
readonly key: string;
|
|
704
|
+
|
|
705
|
+
constructor(ref: string, key: string) {
|
|
706
|
+
super(`object not found: ${key}`);
|
|
707
|
+
this.name = "StoreFileNotFoundError";
|
|
708
|
+
this.ref = ref;
|
|
709
|
+
this.key = key;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
function fileBytesAsUtf8(bytes: Uint8Array, contentType: string): string | null {
|
|
714
|
+
if (bytes.includes(0)) return null;
|
|
715
|
+
const textual =
|
|
716
|
+
contentType.startsWith("text/") ||
|
|
717
|
+
contentType === "application/json" ||
|
|
718
|
+
contentType === "application/xml" ||
|
|
719
|
+
contentType === "application/javascript";
|
|
720
|
+
if (!textual) return null;
|
|
721
|
+
try {
|
|
722
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
723
|
+
} catch {
|
|
724
|
+
return null;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
function bytesToBase64(bytes: Uint8Array): string {
|
|
729
|
+
let binary = "";
|
|
730
|
+
const chunk = 0x8000;
|
|
731
|
+
for (let i = 0; i < bytes.length; i += chunk) {
|
|
732
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + chunk));
|
|
733
|
+
}
|
|
734
|
+
return btoa(binary);
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
function decodeFilePatchBody(patch: Readonly<Record<string, unknown>>): Uint8Array {
|
|
738
|
+
const body = patch.body;
|
|
739
|
+
if (typeof body !== "string") {
|
|
740
|
+
throw new Error("files put requires string patch.body");
|
|
741
|
+
}
|
|
742
|
+
if (patch.encoding === "utf8") {
|
|
743
|
+
return new TextEncoder().encode(body);
|
|
744
|
+
}
|
|
745
|
+
if (patch.encoding !== undefined && patch.encoding !== "base64") {
|
|
746
|
+
throw new Error("files put encoding must be utf8 or base64");
|
|
747
|
+
}
|
|
748
|
+
const binary = atob(body);
|
|
749
|
+
const bytes = new Uint8Array(binary.length);
|
|
750
|
+
for (let i = 0; i < binary.length; i++) {
|
|
751
|
+
bytes[i] = binary.charCodeAt(i);
|
|
752
|
+
}
|
|
753
|
+
return bytes;
|
|
458
754
|
}
|
|
459
755
|
|
|
460
756
|
/** Options for a direct edit (not a flow execution). */
|
|
@@ -464,6 +760,7 @@ export interface StoreEditInput {
|
|
|
464
760
|
readonly tenant?: string;
|
|
465
761
|
readonly id?: string;
|
|
466
762
|
readonly key?: string;
|
|
763
|
+
/** Column values. Omit {@link StoreEditInput.id} to INSERT (requires `patch.id`). */
|
|
467
764
|
readonly patch: Record<string, unknown>;
|
|
468
765
|
readonly confirmation?: string;
|
|
469
766
|
readonly reason?: string;
|
|
@@ -512,7 +809,7 @@ export async function editStore(
|
|
|
512
809
|
const snapshot = await snapshotEditTarget(runtime, input);
|
|
513
810
|
try {
|
|
514
811
|
const { wouldHaveFired } = await withDryRun(async () => {
|
|
515
|
-
await applyEdit(runtime, input, { revealPii: false });
|
|
812
|
+
await applyEdit(runtime, input, { revealPii: false, persistMeta: false });
|
|
516
813
|
});
|
|
517
814
|
await restoreEditTarget(runtime, snapshot);
|
|
518
815
|
return {
|
|
@@ -531,7 +828,7 @@ export async function editStore(
|
|
|
531
828
|
}
|
|
532
829
|
}
|
|
533
830
|
|
|
534
|
-
await applyEdit(runtime, input, { revealPii: false });
|
|
831
|
+
await applyEdit(runtime, input, { revealPii: false, persistMeta: true }, manifest);
|
|
535
832
|
// Direct edit: invalidate cache for written resource (effects-derived).
|
|
536
833
|
runtime.onWriteEffects({ writes: [effectRef] });
|
|
537
834
|
void options.production;
|
|
@@ -551,6 +848,7 @@ type EditSnapshot =
|
|
|
551
848
|
readonly ref: ResourceRef;
|
|
552
849
|
readonly key: string;
|
|
553
850
|
readonly value: unknown;
|
|
851
|
+
readonly ttlMs: number | null;
|
|
554
852
|
}
|
|
555
853
|
| {
|
|
556
854
|
readonly kind: "sql";
|
|
@@ -559,6 +857,27 @@ type EditSnapshot =
|
|
|
559
857
|
readonly id: string;
|
|
560
858
|
readonly row: Record<string, unknown> | null;
|
|
561
859
|
}
|
|
860
|
+
| {
|
|
861
|
+
readonly kind: "extension";
|
|
862
|
+
readonly ref: ResourceRef;
|
|
863
|
+
readonly name: string;
|
|
864
|
+
readonly enabled: boolean;
|
|
865
|
+
readonly version: string | null;
|
|
866
|
+
}
|
|
867
|
+
| {
|
|
868
|
+
readonly kind: "policy";
|
|
869
|
+
readonly ref: ResourceRef;
|
|
870
|
+
readonly id: string;
|
|
871
|
+
readonly existed: boolean;
|
|
872
|
+
}
|
|
873
|
+
| {
|
|
874
|
+
readonly kind: "files";
|
|
875
|
+
readonly ref: ResourceRef;
|
|
876
|
+
readonly key: string;
|
|
877
|
+
readonly data: Uint8Array | null;
|
|
878
|
+
readonly writtenKey: string;
|
|
879
|
+
readonly writtenData: Uint8Array | null;
|
|
880
|
+
}
|
|
562
881
|
| { readonly kind: "none" };
|
|
563
882
|
|
|
564
883
|
async function snapshotEditTarget(
|
|
@@ -566,6 +885,21 @@ async function snapshotEditTarget(
|
|
|
566
885
|
input: StoreEditInput,
|
|
567
886
|
): Promise<EditSnapshot> {
|
|
568
887
|
const [facet] = input.ref.split(":") as [StoreFacet, string];
|
|
888
|
+
if (facet === "files" && input.key) {
|
|
889
|
+
const filesHandle = (await runtime.openRef(input.ref, {
|
|
890
|
+
effects: { reads: [input.ref] },
|
|
891
|
+
})) as FilesStoreFxHandle;
|
|
892
|
+
const writtenKey = coerceSafeFileObjectKey(input.key);
|
|
893
|
+
const data = await filesHandle.get(input.key);
|
|
894
|
+
return {
|
|
895
|
+
kind: "files",
|
|
896
|
+
ref: input.ref,
|
|
897
|
+
key: input.key,
|
|
898
|
+
data,
|
|
899
|
+
writtenKey,
|
|
900
|
+
writtenData: writtenKey === input.key ? data : await filesHandle.get(writtenKey),
|
|
901
|
+
};
|
|
902
|
+
}
|
|
569
903
|
if (facet === "kv" && input.key) {
|
|
570
904
|
const kv = (await runtime.openRef(input.ref, {
|
|
571
905
|
effects: { reads: [input.ref] },
|
|
@@ -575,37 +909,83 @@ async function snapshotEditTarget(
|
|
|
575
909
|
ref: input.ref,
|
|
576
910
|
key: input.key,
|
|
577
911
|
value: await kv.get(input.key),
|
|
912
|
+
ttlMs: await kv.ttlMs(input.key),
|
|
578
913
|
};
|
|
579
914
|
}
|
|
580
|
-
if (facet === "sql" && input.child && input.id) {
|
|
915
|
+
if (facet === "sql" && input.child && input.id && sqlCatalogKind(input.child) === "policy") {
|
|
581
916
|
const sql = (await runtime.openRef(input.ref, {
|
|
582
917
|
effects: { reads: [input.ref] },
|
|
583
918
|
})) as SqlStoreHandle;
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
919
|
+
const rows = await listSqlCatalog(sql, "policy", null, "", 500);
|
|
920
|
+
return {
|
|
921
|
+
kind: "policy",
|
|
922
|
+
ref: input.ref,
|
|
923
|
+
id: input.id,
|
|
924
|
+
existed: rows.some((r) => String(r.id) === input.id),
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
if (facet === "sql" && input.child && input.id && sqlCatalogKind(input.child) === "extension") {
|
|
928
|
+
const sql = (await runtime.openRef(input.ref, {
|
|
929
|
+
effects: { reads: [input.ref] },
|
|
930
|
+
})) as SqlStoreHandle;
|
|
931
|
+
const rows = await listSqlCatalog(sql, "extension", null, "", 500);
|
|
932
|
+
const row = rows.find((r) => String(r.name) === input.id);
|
|
933
|
+
return {
|
|
934
|
+
kind: "extension",
|
|
935
|
+
ref: input.ref,
|
|
936
|
+
name: input.id,
|
|
937
|
+
enabled: row?.enabled === true,
|
|
938
|
+
version: typeof row?.version === "string" ? row.version : null,
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
if (facet === "sql" && input.child) {
|
|
942
|
+
const id = input.id ?? sqlInsertRowId(input.patch);
|
|
943
|
+
if (id) {
|
|
944
|
+
const sql = (await runtime.openRef(input.ref, {
|
|
945
|
+
effects: { reads: [input.ref] },
|
|
946
|
+
})) as SqlStoreHandle;
|
|
947
|
+
try {
|
|
948
|
+
const rows = await sql.raw(`SELECT * FROM "${input.child}" WHERE "id" = ? LIMIT 1`, [id]);
|
|
949
|
+
return {
|
|
950
|
+
kind: "sql",
|
|
951
|
+
ref: input.ref,
|
|
952
|
+
child: input.child,
|
|
953
|
+
id,
|
|
954
|
+
row: rows[0] ?? null,
|
|
955
|
+
};
|
|
956
|
+
} catch {
|
|
957
|
+
return {
|
|
958
|
+
kind: "sql",
|
|
959
|
+
ref: input.ref,
|
|
960
|
+
child: input.child,
|
|
961
|
+
id,
|
|
962
|
+
row: null,
|
|
963
|
+
};
|
|
964
|
+
}
|
|
603
965
|
}
|
|
604
966
|
}
|
|
605
967
|
return { kind: "none" };
|
|
606
968
|
}
|
|
607
969
|
|
|
608
970
|
async function restoreEditTarget(runtime: StoreRuntime, snapshot: EditSnapshot): Promise<void> {
|
|
971
|
+
if (snapshot.kind === "files") {
|
|
972
|
+
const filesHandle = (await runtime.openRef(snapshot.ref, {
|
|
973
|
+
effects: { writes: [snapshot.ref] },
|
|
974
|
+
})) as FilesStoreFxHandle;
|
|
975
|
+
if (snapshot.writtenKey !== snapshot.key) {
|
|
976
|
+
if (snapshot.writtenData === null) {
|
|
977
|
+
await filesHandle.delete(snapshot.writtenKey);
|
|
978
|
+
} else {
|
|
979
|
+
await filesHandle.put(snapshot.writtenKey, snapshot.writtenData);
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
if (snapshot.data === null) {
|
|
983
|
+
await filesHandle.delete(snapshot.key);
|
|
984
|
+
} else {
|
|
985
|
+
await filesHandle.put(snapshot.key, snapshot.data);
|
|
986
|
+
}
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
609
989
|
if (snapshot.kind === "kv") {
|
|
610
990
|
const kv = (await runtime.openRef(snapshot.ref, {
|
|
611
991
|
effects: { writes: [snapshot.ref] },
|
|
@@ -613,7 +993,33 @@ async function restoreEditTarget(runtime: StoreRuntime, snapshot: EditSnapshot):
|
|
|
613
993
|
if (snapshot.value === undefined) {
|
|
614
994
|
await kv.delete(snapshot.key);
|
|
615
995
|
} else {
|
|
616
|
-
|
|
996
|
+
const ttl =
|
|
997
|
+
snapshot.ttlMs !== null && snapshot.ttlMs > 0
|
|
998
|
+
? `${Math.ceil(snapshot.ttlMs)}ms`
|
|
999
|
+
: undefined;
|
|
1000
|
+
await kv.set(snapshot.key, snapshot.value, ttl);
|
|
1001
|
+
}
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
if (snapshot.kind === "policy") {
|
|
1005
|
+
if (snapshot.existed) return;
|
|
1006
|
+
const sql = (await runtime.openRef(snapshot.ref, {
|
|
1007
|
+
effects: { writes: [snapshot.ref] },
|
|
1008
|
+
})) as SqlStoreHandle;
|
|
1009
|
+
try {
|
|
1010
|
+
await dropSqlPolicy(sql, snapshot.id);
|
|
1011
|
+
} catch {
|
|
1012
|
+
/* best-effort restore */
|
|
1013
|
+
}
|
|
1014
|
+
return;
|
|
1015
|
+
}
|
|
1016
|
+
if (snapshot.kind === "extension") {
|
|
1017
|
+
const sql = (await runtime.openRef(snapshot.ref, {
|
|
1018
|
+
effects: { writes: [snapshot.ref] },
|
|
1019
|
+
})) as SqlStoreHandle;
|
|
1020
|
+
await setSqlExtension(sql, snapshot.name, snapshot.enabled);
|
|
1021
|
+
if (snapshot.enabled && snapshot.version) {
|
|
1022
|
+
await upgradeSqlExtension(sql, snapshot.name, snapshot.version);
|
|
617
1023
|
}
|
|
618
1024
|
return;
|
|
619
1025
|
}
|
|
@@ -642,10 +1048,83 @@ async function restoreEditTarget(runtime: StoreRuntime, snapshot: EditSnapshot):
|
|
|
642
1048
|
}
|
|
643
1049
|
}
|
|
644
1050
|
|
|
1051
|
+
function findFileObjectsTable(
|
|
1052
|
+
manifest: Manifest | null,
|
|
1053
|
+
): { readonly ref: ResourceRef; readonly table: string } | null {
|
|
1054
|
+
if (!manifest?.stores) return null;
|
|
1055
|
+
for (const [name, store] of Object.entries(manifest.stores)) {
|
|
1056
|
+
if (store.facet === "sql" && store.tables && "file_objects" in store.tables) {
|
|
1057
|
+
return { ref: `sql:${name}` as ResourceRef, table: "file_objects" };
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
return null;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
async function upsertFileObjectsSql(
|
|
1064
|
+
runtime: StoreRuntime,
|
|
1065
|
+
manifest: Manifest | null,
|
|
1066
|
+
storeRef: string,
|
|
1067
|
+
row: {
|
|
1068
|
+
readonly objectKey: string;
|
|
1069
|
+
readonly originalName: string;
|
|
1070
|
+
readonly contentType: string;
|
|
1071
|
+
readonly sizeBytes: number;
|
|
1072
|
+
},
|
|
1073
|
+
): Promise<void> {
|
|
1074
|
+
const found = findFileObjectsTable(manifest);
|
|
1075
|
+
if (!found) return;
|
|
1076
|
+
try {
|
|
1077
|
+
const sql = (await runtime.openRef(found.ref, {
|
|
1078
|
+
effects: { writes: [found.ref] },
|
|
1079
|
+
})) as SqlStoreHandle;
|
|
1080
|
+
const existing = await sql.raw(
|
|
1081
|
+
`SELECT "id" FROM "${found.table}" WHERE "object_key" = ? LIMIT 1`,
|
|
1082
|
+
[row.objectKey],
|
|
1083
|
+
);
|
|
1084
|
+
if (existing.length > 0) {
|
|
1085
|
+
await sql.raw(
|
|
1086
|
+
`UPDATE "${found.table}" SET "original_name" = ?, "content_type" = ?, "size_bytes" = ?, "store_ref" = ? WHERE "object_key" = ?`,
|
|
1087
|
+
[row.originalName, row.contentType, row.sizeBytes, storeRef, row.objectKey],
|
|
1088
|
+
);
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
1091
|
+
await sql.raw(
|
|
1092
|
+
`INSERT INTO "${found.table}" ("id", "object_key", "original_name", "content_type", "size_bytes", "store_ref") VALUES (?, ?, ?, ?, ?, ?)`,
|
|
1093
|
+
[row.objectKey, row.objectKey, row.originalName, row.contentType, row.sizeBytes, storeRef],
|
|
1094
|
+
);
|
|
1095
|
+
} catch {
|
|
1096
|
+
/* table missing or driver refused — catalog still holds the row */
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
async function deleteFileObjectsSql(
|
|
1101
|
+
runtime: StoreRuntime,
|
|
1102
|
+
manifest: Manifest | null,
|
|
1103
|
+
storeRef: string,
|
|
1104
|
+
keys: readonly string[],
|
|
1105
|
+
): Promise<void> {
|
|
1106
|
+
const found = findFileObjectsTable(manifest);
|
|
1107
|
+
if (!found || keys.length === 0) return;
|
|
1108
|
+
try {
|
|
1109
|
+
const sql = (await runtime.openRef(found.ref, {
|
|
1110
|
+
effects: { writes: [found.ref] },
|
|
1111
|
+
})) as SqlStoreHandle;
|
|
1112
|
+
for (const key of keys) {
|
|
1113
|
+
await sql.raw(`DELETE FROM "${found.table}" WHERE "object_key" = ? AND "store_ref" = ?`, [
|
|
1114
|
+
key,
|
|
1115
|
+
storeRef,
|
|
1116
|
+
]);
|
|
1117
|
+
}
|
|
1118
|
+
} catch {
|
|
1119
|
+
/* best-effort */
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
|
|
645
1123
|
async function applyEdit(
|
|
646
1124
|
runtime: StoreRuntime,
|
|
647
1125
|
input: StoreEditInput,
|
|
648
|
-
ctx: { readonly revealPii: boolean },
|
|
1126
|
+
ctx: { readonly revealPii: boolean; readonly persistMeta?: boolean },
|
|
1127
|
+
manifest?: Manifest | null,
|
|
649
1128
|
): Promise<void> {
|
|
650
1129
|
const [facet] = input.ref.split(":") as [StoreFacet, string];
|
|
651
1130
|
const handle = await runtime.openRef(input.ref, {
|
|
@@ -653,11 +1132,51 @@ async function applyEdit(
|
|
|
653
1132
|
revealPii: ctx.revealPii,
|
|
654
1133
|
});
|
|
655
1134
|
|
|
1135
|
+
if (facet === "files") {
|
|
1136
|
+
const filesHandle = handle as FilesStoreFxHandle;
|
|
1137
|
+
const requested = input.key;
|
|
1138
|
+
if (!requested) throw new Error("files edit requires key");
|
|
1139
|
+
const bytes = decodeFilePatchBody(input.patch);
|
|
1140
|
+
const key = coerceSafeFileObjectKey(requested);
|
|
1141
|
+
const originalName =
|
|
1142
|
+
typeof input.patch.originalName === "string" && input.patch.originalName.trim().length > 0
|
|
1143
|
+
? input.patch.originalName.trim()
|
|
1144
|
+
: requested.slice(requested.lastIndexOf("/") + 1);
|
|
1145
|
+
await filesHandle.put(key, bytes);
|
|
1146
|
+
if (key !== requested) {
|
|
1147
|
+
await filesHandle.delete(requested);
|
|
1148
|
+
}
|
|
1149
|
+
if (ctx.persistMeta !== false) {
|
|
1150
|
+
if (key !== requested) {
|
|
1151
|
+
await removeFilesCatalogRecords(filesHandle, [requested]);
|
|
1152
|
+
await deleteFileObjectsSql(runtime, manifest ?? null, input.ref, [requested]);
|
|
1153
|
+
}
|
|
1154
|
+
await upsertFilesCatalogRecord(
|
|
1155
|
+
filesHandle,
|
|
1156
|
+
key,
|
|
1157
|
+
fileObjectRecord(originalName, bytes.byteLength, key),
|
|
1158
|
+
);
|
|
1159
|
+
await upsertFileObjectsSql(runtime, manifest ?? null, input.ref, {
|
|
1160
|
+
objectKey: key,
|
|
1161
|
+
originalName,
|
|
1162
|
+
contentType: inferFileContentType(originalName),
|
|
1163
|
+
sizeBytes: bytes.byteLength,
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
656
1169
|
if (facet === "kv") {
|
|
657
1170
|
const kv = handle as KvStoreFxHandle;
|
|
658
1171
|
const key = input.key;
|
|
659
1172
|
if (!key) throw new Error("kv edit requires key");
|
|
660
|
-
await kv.
|
|
1173
|
+
const current = await kv.get(key);
|
|
1174
|
+
const nextValue = "value" in input.patch ? input.patch.value : current;
|
|
1175
|
+
if (nextValue === undefined) {
|
|
1176
|
+
throw new Error("kv edit requires a value for a new key");
|
|
1177
|
+
}
|
|
1178
|
+
const ttl = kvTtlFromPatch(input.patch, await kv.ttlMs(key));
|
|
1179
|
+
await kv.set(key, nextValue, ttl);
|
|
661
1180
|
return;
|
|
662
1181
|
}
|
|
663
1182
|
|
|
@@ -665,9 +1184,66 @@ async function applyEdit(
|
|
|
665
1184
|
const sql = handle as SqlStoreHandle;
|
|
666
1185
|
const table = input.child;
|
|
667
1186
|
const id = input.id;
|
|
668
|
-
if (!table
|
|
1187
|
+
if (!table) throw new Error("sql edit requires child");
|
|
1188
|
+
if (!id && sqlCatalogKind(table) !== null) {
|
|
1189
|
+
throw new Error("sql edit requires child + id");
|
|
1190
|
+
}
|
|
1191
|
+
if (id && sqlCatalogKind(table) === "policy") {
|
|
1192
|
+
if (input.patch.create === true) {
|
|
1193
|
+
await createSqlPolicy(sql, input.patch);
|
|
1194
|
+
return;
|
|
1195
|
+
}
|
|
1196
|
+
if (input.patch.drop === true) {
|
|
1197
|
+
await dropSqlPolicy(sql, id);
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
if (typeof input.patch.rls === "boolean") {
|
|
1201
|
+
const tableName = typeof input.patch.table === "string" ? input.patch.table : id;
|
|
1202
|
+
await setSqlRowSecurity(sql, tableName, input.patch.rls);
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
await alterSqlPolicy(sql, id, input.patch);
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
if (id && sqlCatalogKind(table) === "extension") {
|
|
1209
|
+
if (input.patch.upgrade === true) {
|
|
1210
|
+
const to = typeof input.patch.version === "string" ? input.patch.version : undefined;
|
|
1211
|
+
await setSqlExtension(sql, id, true);
|
|
1212
|
+
await upgradeSqlExtension(sql, id, to);
|
|
1213
|
+
return;
|
|
1214
|
+
}
|
|
1215
|
+
const enabled = input.patch.enabled;
|
|
1216
|
+
if (typeof enabled !== "boolean") {
|
|
1217
|
+
throw new Error("extension edit requires boolean enabled or upgrade");
|
|
1218
|
+
}
|
|
1219
|
+
await setSqlExtension(sql, id, enabled, {
|
|
1220
|
+
...(typeof input.patch.schema === "string" ? { schema: input.patch.schema } : {}),
|
|
1221
|
+
...(typeof input.patch.version === "string" ? { version: input.patch.version } : {}),
|
|
1222
|
+
...(input.patch.cascade === true ? { cascade: true } : {}),
|
|
1223
|
+
});
|
|
1224
|
+
return;
|
|
1225
|
+
}
|
|
669
1226
|
const sets = Object.keys(input.patch);
|
|
670
1227
|
if (sets.length === 0) return;
|
|
1228
|
+
const pii = piiColumnsForRef(runtime, input.ref, table);
|
|
1229
|
+
for (const column of sets) {
|
|
1230
|
+
if (pii.has(column) && input.patch[column] === PII_MASK) {
|
|
1231
|
+
throw new Error(
|
|
1232
|
+
`refusing to persist PII mask placeholder over column "${column}" — reveal or set a new value`,
|
|
1233
|
+
);
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
if (!id) {
|
|
1237
|
+
const insertId = sqlInsertRowId(input.patch);
|
|
1238
|
+
if (!insertId) throw new Error("sql insert requires an id in the patch");
|
|
1239
|
+
const columns = sets.map((c) => `"${c}"`).join(", ");
|
|
1240
|
+
const placeholders = sets.map(() => "?").join(", ");
|
|
1241
|
+
await sql.raw(
|
|
1242
|
+
`INSERT INTO "${table}" (${columns}) VALUES (${placeholders})`,
|
|
1243
|
+
sets.map((c) => input.patch[c]),
|
|
1244
|
+
);
|
|
1245
|
+
return;
|
|
1246
|
+
}
|
|
671
1247
|
const assignments = sets.map((c) => `"${c}" = ?`).join(", ");
|
|
672
1248
|
const params = [...sets.map((c) => input.patch[c]), id];
|
|
673
1249
|
await sql.raw(`UPDATE "${table}" SET ${assignments} WHERE "id" = ?`, params);
|
|
@@ -677,6 +1253,35 @@ async function applyEdit(
|
|
|
677
1253
|
throw new Error(`direct edit not supported for facet ${facet}`);
|
|
678
1254
|
}
|
|
679
1255
|
|
|
1256
|
+
/**
|
|
1257
|
+
* Row id for a SQL insert (`patch.id`). Used when `input.id` is omitted.
|
|
1258
|
+
*
|
|
1259
|
+
* @param patch - Insert column values
|
|
1260
|
+
*/
|
|
1261
|
+
function sqlInsertRowId(patch: Readonly<Record<string, unknown>>): string | undefined {
|
|
1262
|
+
const raw = patch.id;
|
|
1263
|
+
if (typeof raw === "string" && raw.length > 0) return raw;
|
|
1264
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return String(raw);
|
|
1265
|
+
return undefined;
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
/** PII columns for a SQL child from the Manifest bound to this runtime. */
|
|
1269
|
+
function piiColumnsForRef(
|
|
1270
|
+
runtime: StoreRuntime,
|
|
1271
|
+
ref: ResourceRef,
|
|
1272
|
+
table: string,
|
|
1273
|
+
): ReadonlySet<string> {
|
|
1274
|
+
const manifest = runtimeManifest.get(runtime);
|
|
1275
|
+
const storeName = ref.split(":")[1];
|
|
1276
|
+
if (!storeName) return new Set();
|
|
1277
|
+
const store = manifest?.stores?.[storeName];
|
|
1278
|
+
if (!store) return new Set();
|
|
1279
|
+
return new Set(piiColumnsFor(store, table));
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
/** Manifest captured when the Console runtime is created (for PII guard). */
|
|
1283
|
+
const runtimeManifest = new WeakMap<StoreRuntime, Manifest | null>();
|
|
1284
|
+
|
|
680
1285
|
/** Delete rows/keys. */
|
|
681
1286
|
export interface StoreDeleteInput {
|
|
682
1287
|
readonly ref: ResourceRef;
|
|
@@ -695,6 +1300,7 @@ export interface StoreDeleteInput {
|
|
|
695
1300
|
export async function deleteStore(
|
|
696
1301
|
runtime: StoreRuntime,
|
|
697
1302
|
input: StoreDeleteInput,
|
|
1303
|
+
manifest?: Manifest | null,
|
|
698
1304
|
): Promise<{ readonly deleted: number }> {
|
|
699
1305
|
const [facet] = input.ref.split(":") as [StoreFacet, string];
|
|
700
1306
|
const handle = await runtime.openRef(input.ref, {
|
|
@@ -708,9 +1314,16 @@ export async function deleteStore(
|
|
|
708
1314
|
}
|
|
709
1315
|
} else if (facet === "files") {
|
|
710
1316
|
const filesHandle = handle as FilesStoreFxHandle;
|
|
1317
|
+
const removed: string[] = [];
|
|
711
1318
|
for (const key of input.keys ?? []) {
|
|
712
|
-
if (
|
|
1319
|
+
if (isFilesCatalogKey(key)) continue;
|
|
1320
|
+
if (await filesHandle.delete(key)) {
|
|
1321
|
+
deleted++;
|
|
1322
|
+
removed.push(key);
|
|
1323
|
+
}
|
|
713
1324
|
}
|
|
1325
|
+
await removeFilesCatalogRecords(filesHandle, removed);
|
|
1326
|
+
await deleteFileObjectsSql(runtime, manifest ?? null, input.ref, removed);
|
|
714
1327
|
} else if (facet === "sql") {
|
|
715
1328
|
const sql = handle as SqlStoreHandle;
|
|
716
1329
|
const table = input.child;
|
|
@@ -757,13 +1370,61 @@ export function purgeStoreCache(
|
|
|
757
1370
|
return { keys: [...new Set([...event.keys, ...extra])] };
|
|
758
1371
|
}
|
|
759
1372
|
|
|
1373
|
+
/**
|
|
1374
|
+
* True when `name` is `public` or a declared policy Gate (rate gates excluded).
|
|
1375
|
+
*
|
|
1376
|
+
* @param manifest - Current Manifest
|
|
1377
|
+
* @param name - Gate name from the query console
|
|
1378
|
+
*/
|
|
1379
|
+
export function isKnownConsoleSqlGate(manifest: Manifest | null, name: string): boolean {
|
|
1380
|
+
if (name === "public") return true;
|
|
1381
|
+
const gate = manifest?.gates?.[name];
|
|
1382
|
+
if (!gate) return false;
|
|
1383
|
+
return gate.kind !== "rate" && !name.startsWith("rate:");
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
const GATE_CONTEXT_DRIVERS = new Set<SqlStoreHandle["driverId"]>(["postgres", "pglite"]);
|
|
1387
|
+
|
|
1388
|
+
/** DML / DDL heads — keep in sync with `isSqlWrite` in the query console. */
|
|
1389
|
+
const STORE_SQL_WRITE_HEADS = new Set([
|
|
1390
|
+
"INSERT",
|
|
1391
|
+
"UPDATE",
|
|
1392
|
+
"DELETE",
|
|
1393
|
+
"DROP",
|
|
1394
|
+
"ALTER",
|
|
1395
|
+
"CREATE",
|
|
1396
|
+
"TRUNCATE",
|
|
1397
|
+
"REPLACE",
|
|
1398
|
+
"GRANT",
|
|
1399
|
+
"REVOKE",
|
|
1400
|
+
"VACUUM",
|
|
1401
|
+
"COMMENT",
|
|
1402
|
+
"COPY",
|
|
1403
|
+
"CALL",
|
|
1404
|
+
"REFRESH",
|
|
1405
|
+
"MERGE",
|
|
1406
|
+
]);
|
|
1407
|
+
|
|
1408
|
+
/**
|
|
1409
|
+
* True when console SQL mutates the store (DML / DDL / `EXPLAIN ANALYZE`).
|
|
1410
|
+
*
|
|
1411
|
+
* @param sql - One statement (already trimmed)
|
|
1412
|
+
*/
|
|
1413
|
+
export function isStoreSqlWrite(sql: string): boolean {
|
|
1414
|
+
const trimmed = sql.trim().replace(/;+\s*$/, "");
|
|
1415
|
+
const head = /^([A-Za-z]+)/.exec(trimmed)?.[1]?.toUpperCase() ?? "";
|
|
1416
|
+
if (head === "EXPLAIN") return /\bANALYZE\b/i.test(trimmed);
|
|
1417
|
+
if (head === "ANALYZE") return true;
|
|
1418
|
+
return STORE_SQL_WRITE_HEADS.has(head);
|
|
1419
|
+
}
|
|
1420
|
+
|
|
760
1421
|
/**
|
|
761
1422
|
* Raw SQL console — read-only by default.
|
|
762
1423
|
*
|
|
763
1424
|
* @param runtime - Store runtime
|
|
764
1425
|
* @param ref - SQL store ref
|
|
765
1426
|
* @param sqlText - SQL
|
|
766
|
-
* @param options - Write allow + reveal
|
|
1427
|
+
* @param options - Write allow + reveal + optional Gate
|
|
767
1428
|
*/
|
|
768
1429
|
export async function runStoreSql(
|
|
769
1430
|
runtime: StoreRuntime,
|
|
@@ -773,14 +1434,18 @@ export async function runStoreSql(
|
|
|
773
1434
|
readonly allowWrite: boolean;
|
|
774
1435
|
readonly revealPii?: boolean;
|
|
775
1436
|
readonly tenant?: string;
|
|
1437
|
+
/** View rows as this Gate (`oke.gate` GUC on postgres / pglite). */
|
|
1438
|
+
readonly asGate?: string;
|
|
776
1439
|
},
|
|
777
1440
|
): Promise<{
|
|
778
1441
|
readonly rows: readonly Record<string, unknown>[];
|
|
779
1442
|
readonly masked: boolean;
|
|
780
1443
|
readonly routedRole: "primary" | "replica";
|
|
1444
|
+
readonly asGate: string | null;
|
|
1445
|
+
readonly gateApplied: boolean;
|
|
781
1446
|
}> {
|
|
782
|
-
const trimmed = sqlText.trim();
|
|
783
|
-
const isWrite =
|
|
1447
|
+
const trimmed = sqlText.trim().replace(/;+\s*$/, "");
|
|
1448
|
+
const isWrite = isStoreSqlWrite(trimmed);
|
|
784
1449
|
if (isWrite && !options.allowWrite) {
|
|
785
1450
|
throw new Error("SQL console is read-only by default — write requires console:store.sql:write");
|
|
786
1451
|
}
|
|
@@ -788,12 +1453,53 @@ export async function runStoreSql(
|
|
|
788
1453
|
effects: isWrite ? { writes: [ref] } : { reads: [ref] },
|
|
789
1454
|
revealPii: options.revealPii === true,
|
|
790
1455
|
})) as SqlStoreHandle;
|
|
791
|
-
const
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
1456
|
+
const asGate = options.asGate?.trim() || null;
|
|
1457
|
+
let gateApplied = false;
|
|
1458
|
+
try {
|
|
1459
|
+
if (asGate) gateApplied = await applySqlGateContext(handle, asGate);
|
|
1460
|
+
const rows = await handle.raw(trimmed);
|
|
1461
|
+
if (gateApplied) await handle.raw("COMMIT");
|
|
1462
|
+
return {
|
|
1463
|
+
rows,
|
|
1464
|
+
masked: !options.revealPii,
|
|
1465
|
+
routedRole: handle.routedRole,
|
|
1466
|
+
asGate,
|
|
1467
|
+
gateApplied,
|
|
1468
|
+
};
|
|
1469
|
+
} catch (err) {
|
|
1470
|
+
if (gateApplied) {
|
|
1471
|
+
try {
|
|
1472
|
+
await handle.raw("ROLLBACK");
|
|
1473
|
+
} catch {
|
|
1474
|
+
// Connection may already be idle after a failed SET.
|
|
1475
|
+
}
|
|
1476
|
+
}
|
|
1477
|
+
throw err;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1481
|
+
/**
|
|
1482
|
+
* Open a transaction and set `oke.gate` + `row_security` for RLS simulation.
|
|
1483
|
+
* No-op on memory SQL.
|
|
1484
|
+
*
|
|
1485
|
+
* @param handle - Open SQL handle
|
|
1486
|
+
* @param gate - Validated Gate name
|
|
1487
|
+
*/
|
|
1488
|
+
async function applySqlGateContext(handle: SqlStoreHandle, gate: string): Promise<boolean> {
|
|
1489
|
+
if (!GATE_CONTEXT_DRIVERS.has(handle.driverId)) return false;
|
|
1490
|
+
try {
|
|
1491
|
+
await handle.raw("BEGIN");
|
|
1492
|
+
await handle.raw("SET LOCAL row_security = on");
|
|
1493
|
+
await handle.raw("SELECT set_config('oke.gate', ?, true)", [gate]);
|
|
1494
|
+
return true;
|
|
1495
|
+
} catch {
|
|
1496
|
+
try {
|
|
1497
|
+
await handle.raw("ROLLBACK");
|
|
1498
|
+
} catch {
|
|
1499
|
+
// ignore
|
|
1500
|
+
}
|
|
1501
|
+
return false;
|
|
1502
|
+
}
|
|
797
1503
|
}
|
|
798
1504
|
|
|
799
1505
|
/**
|
|
@@ -834,7 +1540,7 @@ export async function createManifestStoreRuntime(
|
|
|
834
1540
|
case "sql":
|
|
835
1541
|
runtime.register(
|
|
836
1542
|
declareSql(name, {
|
|
837
|
-
classify: store
|
|
1543
|
+
classify: sqlClassifyFromManifest(store),
|
|
838
1544
|
}),
|
|
839
1545
|
);
|
|
840
1546
|
break;
|
|
@@ -849,5 +1555,82 @@ export async function createManifestStoreRuntime(
|
|
|
849
1555
|
break;
|
|
850
1556
|
}
|
|
851
1557
|
}
|
|
1558
|
+
runtimeManifest.set(runtime, manifest);
|
|
852
1559
|
return runtime;
|
|
853
1560
|
}
|
|
1561
|
+
|
|
1562
|
+
/**
|
|
1563
|
+
* Merge flat `store.classifications` with table-column tags from Manifest
|
|
1564
|
+
* `stores.*.tables.*.columns` into the nested `table → column → tags` shape
|
|
1565
|
+
* {@link declareSql} expects (driver-boundary masking).
|
|
1566
|
+
*
|
|
1567
|
+
* @param store - Manifest store row
|
|
1568
|
+
*/
|
|
1569
|
+
function sqlClassifyFromManifest(
|
|
1570
|
+
store: NonNullable<Manifest["stores"]>[string],
|
|
1571
|
+
): Readonly<Record<string, Readonly<Record<string, ColumnClassification>>>> {
|
|
1572
|
+
const nested: Record<string, Record<string, ColumnClassification>> = {};
|
|
1573
|
+
|
|
1574
|
+
for (const [key, value] of Object.entries(store.classifications ?? {})) {
|
|
1575
|
+
const dot = key.indexOf(".");
|
|
1576
|
+
if (dot <= 0) continue;
|
|
1577
|
+
const table = key.slice(0, dot);
|
|
1578
|
+
const column = key.slice(dot + 1);
|
|
1579
|
+
if (column.length === 0) continue;
|
|
1580
|
+
const tags = classificationFromValue(value);
|
|
1581
|
+
if (!tags) continue;
|
|
1582
|
+
putClassifyAliases(nested, table, column, tags);
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
for (const [table, meta] of Object.entries(store.tables ?? {})) {
|
|
1586
|
+
for (const [column, tags] of Object.entries(meta.columns ?? {})) {
|
|
1587
|
+
const normalized = classificationFromValue(tags);
|
|
1588
|
+
if (!normalized) continue;
|
|
1589
|
+
putClassifyAliases(nested, table, column, normalized);
|
|
1590
|
+
const sqlName =
|
|
1591
|
+
"sqlName" in tags && typeof (tags as { sqlName?: unknown }).sqlName === "string"
|
|
1592
|
+
? (tags as { sqlName: string }).sqlName
|
|
1593
|
+
: undefined;
|
|
1594
|
+
if (sqlName) putClassifyAliases(nested, table, sqlName, normalized);
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
|
|
1598
|
+
return nested;
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
/**
|
|
1602
|
+
* Register classify tags under JS and SQL spellings of a column.
|
|
1603
|
+
*
|
|
1604
|
+
* @param nested - table → column → tags
|
|
1605
|
+
* @param table - Table name
|
|
1606
|
+
* @param column - Manifest or SQL column name
|
|
1607
|
+
* @param tags - Classification tags
|
|
1608
|
+
*/
|
|
1609
|
+
function putClassifyAliases(
|
|
1610
|
+
nested: Record<string, Record<string, ColumnClassification>>,
|
|
1611
|
+
table: string,
|
|
1612
|
+
column: string,
|
|
1613
|
+
tags: ColumnClassification,
|
|
1614
|
+
): void {
|
|
1615
|
+
const row = { ...(nested[table] ?? {}) };
|
|
1616
|
+
for (const name of piiNameAliases(column)) {
|
|
1617
|
+
row[name] = tags;
|
|
1618
|
+
}
|
|
1619
|
+
nested[table] = row;
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
/**
|
|
1623
|
+
* Normalize a Manifest classification value into tags, or null when not a
|
|
1624
|
+
* tag object (e.g. string / string[] classification forms).
|
|
1625
|
+
*
|
|
1626
|
+
* @param value - Manifest classification value
|
|
1627
|
+
*/
|
|
1628
|
+
function classificationFromValue(value: unknown): ColumnClassification | null {
|
|
1629
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
1630
|
+
const v = value as Record<string, unknown>;
|
|
1631
|
+
const tags: ColumnClassification = {};
|
|
1632
|
+
if (v.pii === true) tags.pii = true;
|
|
1633
|
+
if (v.sensitive === true) tags.sensitive = true;
|
|
1634
|
+
if (typeof v.retain === "string") tags.retain = v.retain;
|
|
1635
|
+
return Object.keys(tags).length > 0 ? tags : null;
|
|
1636
|
+
}
|