okengine 0.14.1 → 0.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -4
- package/site/content/docs/elements/ai.mdx +2 -1
- package/site/content/docs/elements/channel.mdx +1 -0
- package/site/content/docs/elements/clock.mdx +3 -0
- package/site/content/docs/elements/flow.mdx +3 -0
- package/site/content/docs/elements/gate.mdx +25 -22
- package/site/content/docs/elements/signal.mdx +4 -4
- package/site/content/docs/elements/store.mdx +86 -27
- package/site/content/docs/elements/vault.mdx +1 -0
- package/site/content/docs/get-started/basic-usage.mdx +22 -13
- package/site/content/docs/get-started/index.mdx +5 -0
- package/site/content/docs/get-started/introduction.mdx +11 -3
- package/site/content/docs/get-started/meta.json +1 -1
- package/site/content/docs/get-started/project-structure.mdx +932 -0
- package/site/content/docs/reference/cli.md +13 -10
- package/site/content/docs/reference/client.mdx +25 -21
- package/site/content/docs/reference/security.md +1 -1
- package/src/auth/bindings.ts +14 -5
- package/src/auth/cross-plane.ts +10 -3
- package/src/cli/ai-setup/ai-setup.test.ts +62 -0
- package/src/cli/ai-setup/apply.ts +32 -1
- package/src/cli/attach-host-console.test.ts +3 -2
- package/src/cli/attach-host-console.ts +3 -0
- package/src/cli/build.test.ts +4 -2
- package/src/cli/db-seed.ts +48 -15
- package/src/cli/db.test.ts +104 -0
- package/src/cli/db.ts +122 -10
- package/src/cli/dev-controls.test.ts +20 -0
- package/src/cli/dev-controls.ts +13 -0
- package/src/cli/dev.test.ts +15 -4
- package/src/cli/dev.ts +102 -29
- package/src/cli/ensure-drizzle-config.ts +2 -1
- package/src/cli/tui/DevLive.tsx +12 -2
- package/src/cli/tui/keys.test.ts +2 -1
- package/src/cli/tui/keys.ts +3 -2
- package/src/compiler/aot.test.ts +1 -1
- package/src/compiler/extract.test.ts +409 -33
- package/src/compiler/extract.ts +318 -67
- package/src/compiler/flow-path.test.ts +96 -0
- package/src/compiler/flow-path.ts +173 -0
- package/src/compiler/generate-adopt.test.ts +112 -3
- package/src/compiler/generate-adopt.ts +280 -26
- package/src/compiler/schema-from-ast.ts +609 -0
- package/src/console/server/bind.ts +2 -2
- package/src/console/server/console.test.ts +3 -0
- package/src/console/server/flows.ts +120 -40
- package/src/console/server/invoke-user-flow.test.ts +3 -1
- package/src/console/server/invoke-user-flow.ts +17 -2
- package/src/console/server/iso-at.test.ts +9 -0
- package/src/console/server/iso-at.ts +11 -0
- package/src/console/server/security-headers.ts +6 -3
- package/src/console/server/spa-proxy.test.ts +1 -0
- package/src/console/server/sql-catalog.ts +147 -7
- package/src/console/server/sql-rls.test.ts +16 -0
- package/src/console/server/state.ts +8 -0
- package/src/console/server/store.test.ts +7 -4
- package/src/console/server/store.ts +142 -58
- package/src/console/ui-next/dist/assets/agent-disclosure-C0X1fbWF.js +1 -0
- package/src/console/ui-next/dist/assets/{cache-glyph-BanhLsEY.js → cache-glyph-F1FI122b.js} +1 -1
- package/src/console/ui-next/dist/assets/{call-pii-button-bqkxMrJH.js → call-pii-button-DEDCl_j3.js} +1 -1
- package/src/console/ui-next/dist/assets/collapsible-LPqGvfoz.js +1 -0
- package/src/console/ui-next/dist/assets/{confirm-sheet-DDCRmG62.js → confirm-sheet-3ptDzXbz.js} +1 -1
- package/src/console/ui-next/dist/assets/{duration-tone-oiRxPVsZ.js → duration-tone-sC3lGABz.js} +1 -1
- package/src/console/ui-next/dist/assets/{explorer-empty-HjTnVQoR.js → explorer-empty-BvYrygyO.js} +1 -1
- package/src/console/ui-next/dist/assets/flows-page-Dluo1Bd7.js +1 -0
- package/src/console/ui-next/dist/assets/{highlighted-json-CvDPvveV.js → highlighted-json-CS_O8L-r.js} +1 -1
- package/src/console/ui-next/dist/assets/http-method--sWDdXSB.js +1 -0
- package/src/console/ui-next/dist/assets/index-Ca3HZMVq.js +66 -0
- package/src/console/ui-next/dist/assets/index-UtTDRQpS.css +2 -0
- package/src/console/ui-next/dist/assets/{link-DF7SZ9Ek.js → link-COeyggt-.js} +1 -1
- package/src/console/ui-next/dist/assets/{observability-page-BEZDzyYh.js → observability-page-HK9-BO8z.js} +2 -2
- package/src/console/ui-next/dist/assets/react-D8E3mtu1.js +1 -0
- package/src/console/ui-next/dist/assets/replica-lag-DBIFFf7d.js +18 -0
- package/src/console/ui-next/dist/assets/sheet-form-Dnwa5oOR.js +1 -0
- package/src/console/ui-next/dist/assets/shortcut-keys-CoqwEIi0.js +1 -0
- package/src/console/ui-next/dist/assets/skeleton-BHcfDYcb.js +1 -0
- package/src/console/ui-next/dist/assets/store-page-BSohH3wM.js +41 -0
- package/src/console/ui-next/dist/assets/trace-detail-sheet-CFIGRnnA.js +2 -0
- package/src/console/ui-next/dist/assets/tree-expand-toggle-BgLl34w7.js +54 -0
- package/src/console/ui-next/dist/assets/units-page-B0cFE76A.js +1 -0
- package/src/console/ui-next/dist/assets/{use-vault-list-Cl79j_ku.js → use-vault-list-BLbZhzyF.js} +1 -1
- package/src/console/ui-next/dist/assets/vault-page-B1SbYe10.js +2 -0
- package/src/console/ui-next/dist/index.html +6 -6
- package/src/console/ui-next/src/client.ts +35 -7
- package/src/console/ui-next/src/components/motion/table/index.tsx +16 -0
- package/src/console/ui-next/src/components/motion/table/types.ts +4 -0
- package/src/console/ui-next/src/components/ui/kbd.tsx +2 -2
- package/src/console/ui-next/src/features/flows/traces/http-method.ts +19 -0
- package/src/console/ui-next/src/features/flows/traces/trace-detail.test.ts +19 -1
- package/src/console/ui-next/src/features/flows/traces/traces-pane.tsx +10 -3
- package/src/console/ui-next/src/features/store/detail/browse-section.tsx +45 -1
- package/src/console/ui-next/src/features/store/detail/resource-panel.tsx +78 -16
- package/src/console/ui-next/src/features/store/detail/store-row-detail-sheet.tsx +155 -14
- package/src/console/ui-next/src/features/store/explorer/store-tree.tsx +33 -133
- package/src/console/ui-next/src/features/store/files/file-preview.tsx +4 -1
- package/src/console/ui-next/src/features/store/grid/rls-policy-sheet.tsx +326 -165
- package/src/console/ui-next/src/features/store/grid/sql-insert-sheet.tsx +6 -0
- package/src/console/ui-next/src/features/store/grid/store-data-grid.tsx +50 -3
- package/src/console/ui-next/src/features/store/lib/files-meta.test.ts +3 -0
- package/src/console/ui-next/src/features/store/lib/files-meta.ts +12 -0
- package/src/console/ui-next/src/features/store/lib/query-defaults.test.ts +25 -0
- package/src/console/ui-next/src/features/store/lib/query-defaults.ts +85 -3
- package/src/console/ui-next/src/features/store/lib/query-gate.ts +30 -4
- package/src/console/ui-next/src/features/store/lib/rls-policy.test.ts +139 -0
- package/src/console/ui-next/src/features/store/lib/rls-policy.ts +223 -21
- package/src/console/ui-next/src/features/store/lib/schema-graph.ts +4 -0
- package/src/console/ui-next/src/features/store/lib/sql-catalog.test.ts +24 -0
- package/src/console/ui-next/src/features/store/lib/sql-catalog.ts +19 -0
- package/src/console/ui-next/src/features/store/lib/store-tree.test.ts +6 -0
- package/src/console/ui-next/src/features/store/lib/store-tree.ts +13 -0
- package/src/console/ui-next/src/features/store/query/query-console.tsx +48 -14
- package/src/console/ui-next/src/features/store/query/query-gate-menu.tsx +19 -20
- package/src/console/ui-next/src/features/store/query/query-gate-parts.tsx +2 -1
- package/src/console/ui-next/src/features/store/query/query-results.tsx +110 -83
- package/src/console/ui-next/src/features/store/schema/schema-table-node.tsx +17 -0
- package/src/console/ui-next/src/features/units/call/call-api-panel.tsx +112 -72
- package/src/console/ui-next/src/features/units/lib/contract-input.test.ts +206 -1
- package/src/console/ui-next/src/features/units/lib/contract-input.ts +55 -0
- package/src/console/ui-next/src/features/vault/lib/types.ts +1 -1
- package/src/docker/compose-health.test.ts +27 -0
- package/src/docker/compose-health.ts +19 -3
- package/src/docker/docker.test.ts +3 -0
- package/src/docker/recipes/pgdog.ts +2 -0
- package/src/drivers/clock-postgres.ts +13 -9
- package/src/drivers/instances-postgres.ts +4 -6
- package/src/drivers/journal-postgres.ts +13 -9
- package/src/drivers/pg-rls.test.ts +87 -0
- package/src/drivers/pg-rls.ts +233 -7
- package/src/drivers/pglite.ts +26 -3
- package/src/drivers/postgres.test.ts +23 -0
- package/src/drivers/postgres.ts +133 -9
- package/src/drivers/types.ts +10 -0
- package/src/elements/clock/declare.ts +26 -1
- package/src/elements/gate/boot.ts +5 -5
- package/src/elements/gate/declare.ts +36 -4
- package/src/elements/gate/flatten.ts +1 -1
- package/src/elements/gate/runtime.ts +1 -1
- package/src/elements/store/declare.ts +9 -6
- package/src/elements/store/emit-drizzle.ts +44 -8
- package/src/elements/store/resource.test.ts +1 -1
- package/src/elements/store/rls-identity.test.ts +95 -0
- package/src/elements/store/rls-identity.ts +116 -0
- package/src/elements/store/runtime.ts +4 -0
- package/src/elements/store/schema-decl.test.ts +37 -0
- package/src/elements/store/schema-decl.ts +161 -0
- package/src/elements/store/seed.ts +1 -1
- package/src/elements/store/sql-condition.test.ts +12 -0
- package/src/elements/store/sql-condition.ts +26 -2
- package/src/elements/store/sql-rls-isolation.test.ts +165 -0
- package/src/elements/store/sql-rls-stamp.test.ts +117 -0
- package/src/elements/store/sql-session.ts +81 -3
- package/src/elements/store/upsert-app.test.ts +1 -1
- package/src/elements/store.ts +14 -0
- package/src/http.ts +20 -3
- package/src/index.ts +10 -1
- package/src/kernel/adopt-barrel-fresh.test.ts +1 -1
- package/src/kernel/adopt-routes.ts +30 -2
- package/src/kernel/app.ts +131 -14
- package/src/kernel/auto-cache.test.ts +8 -8
- package/src/kernel/auto-registry.test.ts +49 -9
- package/src/kernel/boot.test.ts +4 -4
- package/src/kernel/boot.ts +2 -2
- package/src/kernel/effects-stamping.test.ts +3 -3
- package/src/kernel/element-registries.ts +12 -5
- package/src/kernel/errors.ts +24 -0
- package/src/kernel/flow-units.ts +64 -0
- package/src/kernel/flow.ts +29 -17
- package/src/kernel/fx.ts +23 -0
- package/src/kernel/horizontal-child.ts +4 -4
- package/src/kernel/http-path-pending.ts +20 -0
- package/src/kernel/http-resource.ts +4 -0
- package/src/kernel/http-stream.test.ts +4 -4
- package/src/kernel/pipeline.test.ts +2 -2
- package/src/kernel/plugin-elements.test.ts +1 -1
- package/src/kernel/plugin-needs.test.ts +1 -1
- package/src/kernel/ready.test.ts +2 -2
- package/src/kernel/resource-mount.test.ts +14 -0
- package/src/kernel/run-duration.test.ts +2 -2
- package/src/kernel/stamp-http.test.ts +79 -0
- package/src/kernel/stamp-http.ts +75 -0
- package/src/kernel/triggers.ts +52 -27
- package/src/manifest/types.ts +13 -0
- package/src/release/measure.ts +2 -2
- package/src/runtime/json-code-block.test.ts +2 -2
- package/src/runtime/serve.test.ts +4 -4
- package/src/term.test.ts +52 -4
- package/src/term.ts +125 -17
- package/src/test/reset-element-registries.ts +8 -3
- package/src/cli/ask-seed.test.ts +0 -96
- package/src/cli/ask-seed.ts +0 -82
- package/src/console/ui-next/dist/assets/collapsible-DYb0xU8C.js +0 -1
- package/src/console/ui-next/dist/assets/flows-page-DxDsOd4f.js +0 -1
- package/src/console/ui-next/dist/assets/http-method-CJCBYL2j.js +0 -1
- package/src/console/ui-next/dist/assets/index-Ce6WKWKM.js +0 -66
- package/src/console/ui-next/dist/assets/index-D4Ldtj79.css +0 -2
- package/src/console/ui-next/dist/assets/query-gate-parts-1m8m1iNp.js +0 -2
- package/src/console/ui-next/dist/assets/react-B1ML8gxg.js +0 -1
- package/src/console/ui-next/dist/assets/replica-lag-C8_BRt2x.js +0 -18
- package/src/console/ui-next/dist/assets/sheet-form-D-ata7jy.js +0 -1
- package/src/console/ui-next/dist/assets/shortcut-keys-DO4IsVqv.js +0 -1
- package/src/console/ui-next/dist/assets/skeleton-CL_X0GCj.js +0 -1
- package/src/console/ui-next/dist/assets/store-page-v3LXdYpr.js +0 -45
- package/src/console/ui-next/dist/assets/trace-detail-sheet-DFLFfUUX.js +0 -2
- package/src/console/ui-next/dist/assets/units-page-C0gW6Kdo.js +0 -1
- package/src/console/ui-next/dist/assets/vault-page-DuKzqwzW.js +0 -2
|
@@ -37,18 +37,18 @@
|
|
|
37
37
|
} catch (e) {}
|
|
38
38
|
})();
|
|
39
39
|
</script>
|
|
40
|
-
<script type="module" crossorigin src="/assets/index-
|
|
40
|
+
<script type="module" crossorigin src="/assets/index-Ca3HZMVq.js"></script>
|
|
41
41
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-hePW80VL.js">
|
|
42
42
|
<link rel="modulepreload" crossorigin href="/assets/react-dom-Bph1y7z7.js">
|
|
43
43
|
<link rel="modulepreload" crossorigin href="/assets/xyflow-D7n4g6go.js">
|
|
44
|
-
<link rel="modulepreload" crossorigin href="/assets/shortcut-keys-
|
|
45
|
-
<link rel="modulepreload" crossorigin href="/assets/link-
|
|
46
|
-
<link rel="modulepreload" crossorigin href="/assets/skeleton-
|
|
47
|
-
<link rel="modulepreload" crossorigin href="/assets/react-
|
|
44
|
+
<link rel="modulepreload" crossorigin href="/assets/shortcut-keys-CoqwEIi0.js">
|
|
45
|
+
<link rel="modulepreload" crossorigin href="/assets/link-COeyggt-.js">
|
|
46
|
+
<link rel="modulepreload" crossorigin href="/assets/skeleton-BHcfDYcb.js">
|
|
47
|
+
<link rel="modulepreload" crossorigin href="/assets/react-D8E3mtu1.js">
|
|
48
48
|
<link rel="modulepreload" crossorigin href="/assets/preload-helper-oH4irX4C.js">
|
|
49
49
|
<link rel="modulepreload" crossorigin href="/assets/shortcut-Cgzuv4k1.js">
|
|
50
50
|
<link rel="stylesheet" crossorigin href="/assets/xyflow-DZ0Ws1xk.css">
|
|
51
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
51
|
+
<link rel="stylesheet" crossorigin href="/assets/index-UtTDRQpS.css">
|
|
52
52
|
</head>
|
|
53
53
|
<body>
|
|
54
54
|
<div id="root"></div>
|
|
@@ -446,7 +446,7 @@ export type TracesReplayResult = {
|
|
|
446
446
|
readonly ok: true;
|
|
447
447
|
readonly rootId: string;
|
|
448
448
|
readonly dryRun: boolean;
|
|
449
|
-
readonly at:
|
|
449
|
+
readonly at: string;
|
|
450
450
|
readonly flow: string;
|
|
451
451
|
};
|
|
452
452
|
|
|
@@ -506,6 +506,11 @@ export type FlowsInvokeResult = {
|
|
|
506
506
|
readonly flowId: string;
|
|
507
507
|
readonly asUserId: string;
|
|
508
508
|
readonly asGate?: string | null;
|
|
509
|
+
readonly rls?: {
|
|
510
|
+
readonly gate: string | null;
|
|
511
|
+
readonly userId: string;
|
|
512
|
+
readonly applied: boolean;
|
|
513
|
+
};
|
|
509
514
|
readonly trigger: string;
|
|
510
515
|
readonly response: unknown;
|
|
511
516
|
/** True when classified PII keys were redacted. */
|
|
@@ -674,7 +679,7 @@ export type ClockRunNowResult = {
|
|
|
674
679
|
readonly ok: true;
|
|
675
680
|
readonly name: string;
|
|
676
681
|
readonly ran: boolean;
|
|
677
|
-
readonly at:
|
|
682
|
+
readonly at: string;
|
|
678
683
|
};
|
|
679
684
|
|
|
680
685
|
/**
|
|
@@ -721,6 +726,8 @@ export type StoreListChild = {
|
|
|
721
726
|
readonly columnDescriptions: Readonly<Record<string, string>>;
|
|
722
727
|
/** Live RLS when the engine reported `pg_class.relrowsecurity`. */
|
|
723
728
|
readonly rls?: boolean;
|
|
729
|
+
/** Live + declared RLS policy count when the child is a SQL table. */
|
|
730
|
+
readonly rlsPolicyCount?: number;
|
|
724
731
|
};
|
|
725
732
|
|
|
726
733
|
/** One store row from `GET /console/store` (matches server `StoreListOut`). */
|
|
@@ -772,6 +779,8 @@ export type StoreQueryInput = {
|
|
|
772
779
|
readonly topK?: number;
|
|
773
780
|
/** When true, SQL browse returns PII cleartext (audited). Default masks. */
|
|
774
781
|
readonly revealPii?: boolean;
|
|
782
|
+
readonly asGate?: string;
|
|
783
|
+
readonly asUserId?: string;
|
|
775
784
|
};
|
|
776
785
|
|
|
777
786
|
/** Success payload from `QUERY /console/store/query` (matches server `StoreQueryOut`). */
|
|
@@ -793,6 +802,11 @@ export type StoreQueryResult = {
|
|
|
793
802
|
}>;
|
|
794
803
|
readonly masked: boolean;
|
|
795
804
|
readonly routedRole?: "primary" | "replica";
|
|
805
|
+
readonly rls?: {
|
|
806
|
+
readonly gate: string | null;
|
|
807
|
+
readonly userId: string;
|
|
808
|
+
readonly applied: boolean;
|
|
809
|
+
};
|
|
796
810
|
};
|
|
797
811
|
|
|
798
812
|
/**
|
|
@@ -822,7 +836,7 @@ export type StoreRevealInput = {
|
|
|
822
836
|
export type StoreRevealResult = {
|
|
823
837
|
readonly ok: true;
|
|
824
838
|
readonly value: unknown;
|
|
825
|
-
readonly at:
|
|
839
|
+
readonly at: string;
|
|
826
840
|
};
|
|
827
841
|
|
|
828
842
|
/**
|
|
@@ -851,6 +865,8 @@ export type StoreEditInput = {
|
|
|
851
865
|
readonly confirmation?: string;
|
|
852
866
|
readonly reason?: string;
|
|
853
867
|
readonly commit?: boolean;
|
|
868
|
+
readonly asGate?: string;
|
|
869
|
+
readonly asUserId?: string;
|
|
854
870
|
};
|
|
855
871
|
|
|
856
872
|
/** Success payload from `POST /console/store/edit` (matches server). */
|
|
@@ -863,7 +879,12 @@ export type StoreEditResult = {
|
|
|
863
879
|
readonly kind: "send" | "ask";
|
|
864
880
|
readonly resource: string;
|
|
865
881
|
}>;
|
|
866
|
-
readonly at:
|
|
882
|
+
readonly at: string;
|
|
883
|
+
readonly rls?: {
|
|
884
|
+
readonly gate: string | null;
|
|
885
|
+
readonly userId: string;
|
|
886
|
+
readonly applied: boolean;
|
|
887
|
+
};
|
|
867
888
|
};
|
|
868
889
|
|
|
869
890
|
/**
|
|
@@ -907,7 +928,7 @@ export type StoreDeleteInput = {
|
|
|
907
928
|
export type StoreDeleteResult = {
|
|
908
929
|
readonly ok: true;
|
|
909
930
|
readonly deleted: number;
|
|
910
|
-
readonly at:
|
|
931
|
+
readonly at: string;
|
|
911
932
|
};
|
|
912
933
|
|
|
913
934
|
/**
|
|
@@ -934,6 +955,7 @@ export type StoreSqlInput = {
|
|
|
934
955
|
readonly revealPii?: boolean;
|
|
935
956
|
/** View rows as this Gate (`oke.gate` on postgres / pglite). */
|
|
936
957
|
readonly asGate?: string;
|
|
958
|
+
readonly asUserId?: string;
|
|
937
959
|
};
|
|
938
960
|
|
|
939
961
|
/** Success payload from `POST /console/store/sql` (matches server `StoreSqlOut`). */
|
|
@@ -942,7 +964,13 @@ export type StoreSqlResult = {
|
|
|
942
964
|
readonly masked: boolean;
|
|
943
965
|
readonly routedRole: "primary" | "replica";
|
|
944
966
|
readonly asGate: string | null;
|
|
967
|
+
readonly asUserId: string | null;
|
|
945
968
|
readonly gateApplied: boolean;
|
|
969
|
+
readonly rls?: {
|
|
970
|
+
readonly gate: string | null;
|
|
971
|
+
readonly userId: string;
|
|
972
|
+
readonly applied: boolean;
|
|
973
|
+
};
|
|
946
974
|
};
|
|
947
975
|
|
|
948
976
|
/**
|
|
@@ -1267,7 +1295,7 @@ export type VaultWriteResult = {
|
|
|
1267
1295
|
readonly ok: true;
|
|
1268
1296
|
readonly name: string;
|
|
1269
1297
|
readonly fingerprint: string | null;
|
|
1270
|
-
readonly at:
|
|
1298
|
+
readonly at: string;
|
|
1271
1299
|
};
|
|
1272
1300
|
|
|
1273
1301
|
/**
|
|
@@ -1331,7 +1359,7 @@ export type VaultRotateMasterResult = {
|
|
|
1331
1359
|
readonly kekVersion: number;
|
|
1332
1360
|
readonly remaining: number;
|
|
1333
1361
|
readonly masterKey: string | null;
|
|
1334
|
-
readonly at:
|
|
1362
|
+
readonly at: string;
|
|
1335
1363
|
};
|
|
1336
1364
|
|
|
1337
1365
|
/**
|
|
@@ -61,6 +61,8 @@ export function Table<T>({
|
|
|
61
61
|
onInsertColumn,
|
|
62
62
|
onDeleteColumn,
|
|
63
63
|
onRowDoubleClick,
|
|
64
|
+
onRowContextMenu,
|
|
65
|
+
onViewportContextMenu,
|
|
64
66
|
cellRange = null,
|
|
65
67
|
onCellRangeChange,
|
|
66
68
|
onCellActivate,
|
|
@@ -192,6 +194,13 @@ export function Table<T>({
|
|
|
192
194
|
onPointerMove={cellSelect.onScrollerPointerMove}
|
|
193
195
|
onPointerUp={cellSelect.onPointerUp}
|
|
194
196
|
onPointerCancel={cellSelect.onPointerUp}
|
|
197
|
+
onContextMenu={(event) => {
|
|
198
|
+
if (!onViewportContextMenu) return;
|
|
199
|
+
const target = event.target;
|
|
200
|
+
if (target instanceof Element && target.closest("[data-slot='table-row']")) return;
|
|
201
|
+
event.preventDefault();
|
|
202
|
+
onViewportContextMenu();
|
|
203
|
+
}}
|
|
195
204
|
className={cn("overflow-auto", onCellRangeChange ? "select-none" : undefined)}
|
|
196
205
|
style={{ height }}
|
|
197
206
|
>
|
|
@@ -273,12 +282,19 @@ export function Table<T>({
|
|
|
273
282
|
ref={(el) => {
|
|
274
283
|
rowRefs.current[entry.id] = el;
|
|
275
284
|
}}
|
|
285
|
+
data-slot="table-row"
|
|
276
286
|
data-selected={isSelected}
|
|
277
287
|
style={{ height: rowHeight }}
|
|
278
288
|
onPointerEnter={
|
|
279
289
|
hasRowMenu ? () => activateRow(entry.id, vItem.index) : undefined
|
|
280
290
|
}
|
|
281
291
|
onPointerLeave={hasRowMenu ? deactivateRow : undefined}
|
|
292
|
+
onContextMenu={(event) => {
|
|
293
|
+
if (!onRowContextMenu) return;
|
|
294
|
+
event.preventDefault();
|
|
295
|
+
event.stopPropagation();
|
|
296
|
+
onRowContextMenu(entry.row, entry.id);
|
|
297
|
+
}}
|
|
282
298
|
onDoubleClick={(e) => {
|
|
283
299
|
if (!onRowDoubleClick) return;
|
|
284
300
|
const target = e.target;
|
|
@@ -78,6 +78,10 @@ export interface TableProps<T> {
|
|
|
78
78
|
readonly onDeleteColumn?: (columnKey: string, index: number) => void;
|
|
79
79
|
/** Double-click a body row. */
|
|
80
80
|
readonly onRowDoubleClick?: (row: T, id: string) => void;
|
|
81
|
+
/** Two-finger / right-click a body row (caller should `preventDefault`). */
|
|
82
|
+
readonly onRowContextMenu?: (row: T, id: string) => void;
|
|
83
|
+
/** Two-finger / right-click empty viewport (not a row). */
|
|
84
|
+
readonly onViewportContextMenu?: () => void;
|
|
81
85
|
/** Controlled cell range (visible row index × column index). */
|
|
82
86
|
readonly cellRange?: CellRange | null;
|
|
83
87
|
/** Enables drag / Shift+click cell-range selection. */
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Keyboard key — shadcn Kbd.
|
|
2
|
+
* Keyboard key — shadcn Kbd. Buttons inherit ink; tooltips invert.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import type { ComponentProps, JSX } from "react";
|
|
@@ -15,7 +15,7 @@ function Kbd({ className, ...props }: ComponentProps<"kbd">): JSX.Element {
|
|
|
15
15
|
<kbd
|
|
16
16
|
data-slot="kbd"
|
|
17
17
|
className={cn(
|
|
18
|
-
"pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-none bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none in-data-[slot=tooltip-content]:bg-background/20 in-data-[slot=tooltip-content]:text-background dark:in-data-[slot=tooltip-content]:bg-background/10 [&_svg:not([class*='size-'])]:size-3",
|
|
18
|
+
"pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-none bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none in-[.bg-primary]:bg-primary-foreground/20 in-[.bg-primary]:text-primary-foreground in-data-[slot=tooltip-content]:bg-background/20 in-data-[slot=tooltip-content]:text-background dark:in-data-[slot=tooltip-content]:bg-background/10 [&_svg:not([class*='size-'])]:size-3",
|
|
19
19
|
className,
|
|
20
20
|
)}
|
|
21
21
|
{...props}
|
|
@@ -18,6 +18,25 @@ import type { ElementHugeIcon } from "@/lib/element-icons.ts";
|
|
|
18
18
|
/** Known HTTP methods from Manifest `HttpTrigger.method`. */
|
|
19
19
|
export type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS" | "QUERY";
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Whether the verb carries a JSON request body on the wire.
|
|
23
|
+
*
|
|
24
|
+
* Matches the HTTP compiler (`GET` / `HEAD` / `DELETE` are path-or-query
|
|
25
|
+
* only) and the typed client (`GET` / `HEAD` leftover fields → query).
|
|
26
|
+
*
|
|
27
|
+
* @param method - HTTP method string (case-insensitive) or null
|
|
28
|
+
*/
|
|
29
|
+
export function httpMethodHasBody(method: string | null | undefined): boolean {
|
|
30
|
+
switch ((method ?? "").toUpperCase()) {
|
|
31
|
+
case "GET":
|
|
32
|
+
case "HEAD":
|
|
33
|
+
case "DELETE":
|
|
34
|
+
return false;
|
|
35
|
+
default:
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
21
40
|
/**
|
|
22
41
|
* Units-tree display rank: GET → POST → QUERY → PATCH/PUT → DELETE.
|
|
23
42
|
*
|
|
@@ -8,6 +8,7 @@ import { ELEMENT_ICONS } from "@/lib/element-icons.ts";
|
|
|
8
8
|
import { EDGE_STROKE } from "../graph/flow-graph-theme.ts";
|
|
9
9
|
import {
|
|
10
10
|
httpMethodBadgeClass,
|
|
11
|
+
httpMethodHasBody,
|
|
11
12
|
httpMethodIcon,
|
|
12
13
|
httpMethodRailClass,
|
|
13
14
|
httpMethodSortRank,
|
|
@@ -110,6 +111,23 @@ describe("effectKindIcon", () => {
|
|
|
110
111
|
});
|
|
111
112
|
});
|
|
112
113
|
|
|
114
|
+
describe("httpMethodHasBody", () => {
|
|
115
|
+
test("GET, HEAD, and DELETE are path/query only", () => {
|
|
116
|
+
expect(httpMethodHasBody("GET")).toBe(false);
|
|
117
|
+
expect(httpMethodHasBody("HEAD")).toBe(false);
|
|
118
|
+
expect(httpMethodHasBody("DELETE")).toBe(false);
|
|
119
|
+
expect(httpMethodHasBody("get")).toBe(false);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
test("POST, PUT, PATCH, QUERY, and OPTIONS carry JSON", () => {
|
|
123
|
+
expect(httpMethodHasBody("POST")).toBe(true);
|
|
124
|
+
expect(httpMethodHasBody("PUT")).toBe(true);
|
|
125
|
+
expect(httpMethodHasBody("PATCH")).toBe(true);
|
|
126
|
+
expect(httpMethodHasBody("QUERY")).toBe(true);
|
|
127
|
+
expect(httpMethodHasBody("OPTIONS")).toBe(true);
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
113
131
|
describe("httpMethodBadgeClass", () => {
|
|
114
132
|
test("assigns distinct accents per method", () => {
|
|
115
133
|
expect(httpMethodBadgeClass("GET")).toContain("emerald");
|
|
@@ -352,7 +370,7 @@ describe("Sheet Replay path", () => {
|
|
|
352
370
|
ok: true as const,
|
|
353
371
|
rootId: run.id,
|
|
354
372
|
dryRun: false,
|
|
355
|
-
at:
|
|
373
|
+
at: "2026-08-21T09:36:51.525Z",
|
|
356
374
|
flow: run.flow,
|
|
357
375
|
},
|
|
358
376
|
error: null,
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
EXPLORER_STRIP_TOKEN_IDLE_CLASS,
|
|
16
16
|
EXPLORER_TOOLBAR_CLASS,
|
|
17
17
|
} from "@/components/explorer/explorer-chrome.ts";
|
|
18
|
+
import { AgentDisclosure } from "@/components/agents/agent-disclosure.tsx";
|
|
18
19
|
import { ExplorerSearch } from "@/components/explorer/explorer-search.tsx";
|
|
19
20
|
import {
|
|
20
21
|
Empty,
|
|
@@ -236,10 +237,16 @@ export function TracesPane({
|
|
|
236
237
|
) : null}
|
|
237
238
|
</div>
|
|
238
239
|
|
|
239
|
-
{runs.length > 0
|
|
240
|
-
<
|
|
240
|
+
{runs.length > 0 ? (
|
|
241
|
+
<AgentDisclosure
|
|
242
|
+
id="traces-advanced-panel"
|
|
243
|
+
role="region"
|
|
244
|
+
aria-label="Advanced filters"
|
|
245
|
+
open={advancedOpen}
|
|
246
|
+
className="shrink-0"
|
|
247
|
+
>
|
|
241
248
|
<AdvancedFilters query={filters.advanced} runs={runs} onChange={setAdvanced} />
|
|
242
|
-
</
|
|
249
|
+
</AgentDisclosure>
|
|
243
250
|
) : null}
|
|
244
251
|
|
|
245
252
|
<div className="flex min-h-0 flex-1 flex-col overflow-y-auto">
|
|
@@ -55,6 +55,7 @@ import { ToolbarTip } from "@/components/ui/toolbar-tip.tsx";
|
|
|
55
55
|
import { buildStoreGridModel, type StoreGridRow } from "../lib/grid-model.ts";
|
|
56
56
|
import { parseIndexQuery } from "../lib/index-query.ts";
|
|
57
57
|
import { childCatalogKind, groupSqlChildren, isSqlCatalogChild } from "../lib/sql-catalog.ts";
|
|
58
|
+
import { QueryGateMenu } from "../query/query-gate-menu.tsx";
|
|
58
59
|
import { TouchedByLists } from "./touched-by-section.tsx";
|
|
59
60
|
|
|
60
61
|
/** Browse page sizes offered in the Rows select. */
|
|
@@ -116,6 +117,10 @@ export function BrowseSection({
|
|
|
116
117
|
const [indexOpen, setIndexOpen] = useState(false);
|
|
117
118
|
const [triggerOpen, setTriggerOpen] = useState(false);
|
|
118
119
|
const [insertOpen, setInsertOpen] = useState(false);
|
|
120
|
+
const [rlsAs, setRlsAs] = useState<{ asGate: string | null; asUserId: string | null }>({
|
|
121
|
+
asGate: null,
|
|
122
|
+
asUserId: null,
|
|
123
|
+
});
|
|
119
124
|
|
|
120
125
|
const debouncedIndexText = useDebouncedValue(indexText, INDEX_SEARCH_DEBOUNCE_MS);
|
|
121
126
|
const indexQuery = useMemo(() => parseIndexQuery(debouncedIndexText), [debouncedIndexText]);
|
|
@@ -133,8 +138,25 @@ export function BrowseSection({
|
|
|
133
138
|
: {}),
|
|
134
139
|
...(store.facet === "index" && indexQuery.kind === "text" ? { q: indexQuery.q, topK } : {}),
|
|
135
140
|
...(store.facet === "sql" && !piiMasked ? { revealPii: true } : {}),
|
|
141
|
+
...(store.facet === "sql" && !isSqlCatalogChild(child) && rlsAs.asGate
|
|
142
|
+
? { asGate: rlsAs.asGate }
|
|
143
|
+
: {}),
|
|
144
|
+
...(store.facet === "sql" && !isSqlCatalogChild(child) && rlsAs.asUserId
|
|
145
|
+
? { asUserId: rlsAs.asUserId }
|
|
146
|
+
: {}),
|
|
136
147
|
};
|
|
137
|
-
}, [
|
|
148
|
+
}, [
|
|
149
|
+
store.ref,
|
|
150
|
+
store.facet,
|
|
151
|
+
child,
|
|
152
|
+
tenant,
|
|
153
|
+
tenantReady,
|
|
154
|
+
limit,
|
|
155
|
+
indexQuery,
|
|
156
|
+
topK,
|
|
157
|
+
piiMasked,
|
|
158
|
+
rlsAs,
|
|
159
|
+
]);
|
|
138
160
|
|
|
139
161
|
const browse = useStoreQuery(queryInput, tenantReady);
|
|
140
162
|
const deleteMutation = useStoreDelete();
|
|
@@ -191,6 +213,8 @@ export function BrowseSection({
|
|
|
191
213
|
c.key === "with_check" ||
|
|
192
214
|
c.key === "command" ||
|
|
193
215
|
c.key === "permissive",
|
|
216
|
+
...(c.key === "origin" ? { label: "Origin" } : {}),
|
|
217
|
+
...(c.key === "code" ? { label: "Code" } : {}),
|
|
194
218
|
})),
|
|
195
219
|
};
|
|
196
220
|
}
|
|
@@ -269,6 +293,9 @@ export function BrowseSection({
|
|
|
269
293
|
|
|
270
294
|
const toolbarExtras = (
|
|
271
295
|
<>
|
|
296
|
+
{store.facet === "sql" && !isSqlCatalogChild(child) ? (
|
|
297
|
+
<QueryGateMenu manifest={manifest} value={rlsAs} onChange={setRlsAs} />
|
|
298
|
+
) : null}
|
|
272
299
|
<Tooltip>
|
|
273
300
|
<TooltipTrigger
|
|
274
301
|
render={(props) => (
|
|
@@ -576,9 +603,26 @@ export function BrowseSection({
|
|
|
576
603
|
}
|
|
577
604
|
insertOpen={insertOpen}
|
|
578
605
|
onInsertOpenChange={setInsertOpen}
|
|
606
|
+
asGate={rlsAs.asGate}
|
|
607
|
+
asUserId={rlsAs.asUserId}
|
|
579
608
|
onDeleteRows={
|
|
580
609
|
authReadOnly || extensionCatalog ? undefined : (rows) => setDeleting(rows)
|
|
581
610
|
}
|
|
611
|
+
onViewportContextMenu={
|
|
612
|
+
store.ref === "sql:oke_console"
|
|
613
|
+
? undefined
|
|
614
|
+
: policyCatalog
|
|
615
|
+
? () => setPolicyOpen(true)
|
|
616
|
+
: functionCatalog
|
|
617
|
+
? () => setFunctionOpen(true)
|
|
618
|
+
: indexCatalog
|
|
619
|
+
? () => setIndexOpen(true)
|
|
620
|
+
: triggerCatalog
|
|
621
|
+
? () => setTriggerOpen(true)
|
|
622
|
+
: store.facet === "sql" && !isSqlCatalogChild(child)
|
|
623
|
+
? () => setInsertOpen(true)
|
|
624
|
+
: undefined
|
|
625
|
+
}
|
|
582
626
|
/>
|
|
583
627
|
</div>
|
|
584
628
|
) : null}
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
CheckmarkCircle02Icon,
|
|
10
10
|
Folder01Icon,
|
|
11
11
|
SecurityCheckIcon,
|
|
12
|
+
ShieldEnergyIcon,
|
|
13
|
+
ShieldOff,
|
|
12
14
|
Timer01Icon,
|
|
13
15
|
} from "@hugeicons/core-free-icons";
|
|
14
16
|
import { HugeiconsIcon } from "@hugeicons/react";
|
|
@@ -24,8 +26,13 @@ import { formatDuration } from "@/features/flows/traces/format-duration.ts";
|
|
|
24
26
|
import { cn } from "@/lib/utils";
|
|
25
27
|
import { filesDriverLabel, filesDriverOrigin } from "../lib/files-origin.ts";
|
|
26
28
|
import { latestReplicaLagFromRuns } from "../lib/replica-lag.ts";
|
|
27
|
-
import {
|
|
28
|
-
|
|
29
|
+
import {
|
|
30
|
+
isSqlCatalogChild,
|
|
31
|
+
storeChildLabel,
|
|
32
|
+
storeChildRlsPolicyCount,
|
|
33
|
+
storeChildShowsRls,
|
|
34
|
+
} from "../lib/sql-catalog.ts";
|
|
35
|
+
import { resourceHeaderChildRef, STORE_FACET_SPECS } from "../lib/store-tree.ts";
|
|
29
36
|
import { BrowseSection } from "./browse-section.tsx";
|
|
30
37
|
|
|
31
38
|
/** Props for {@link ResourcePanel}. */
|
|
@@ -77,7 +84,12 @@ export function ResourcePanel({
|
|
|
77
84
|
const lagTone = lagMs != null ? durationTone(lagMs) : null;
|
|
78
85
|
|
|
79
86
|
const files = store.facet === "files";
|
|
80
|
-
const
|
|
87
|
+
const showsRls = storeChildShowsRls(child);
|
|
88
|
+
const rlsOn = child.rls === true;
|
|
89
|
+
const rlsCount = storeChildRlsPolicyCount(child, manifest, store.name);
|
|
90
|
+
const showStatus = Boolean(
|
|
91
|
+
drift || lagMs !== null || store.contentAddressed || piiCount > 0 || showsRls,
|
|
92
|
+
);
|
|
81
93
|
|
|
82
94
|
return (
|
|
83
95
|
<div className="flex h-full min-h-0 flex-col overflow-hidden" data-slot="resource-panel">
|
|
@@ -124,18 +136,7 @@ export function ResourcePanel({
|
|
|
124
136
|
<CopyInlineButton value={child.effectRef} label="Copy effect ref" />
|
|
125
137
|
</>
|
|
126
138
|
) : (
|
|
127
|
-
|
|
128
|
-
<span className="shrink-0 font-mono text-[11px] leading-none text-muted-foreground">
|
|
129
|
-
{store.ref}
|
|
130
|
-
</span>
|
|
131
|
-
<span aria-hidden className="text-border">
|
|
132
|
-
·
|
|
133
|
-
</span>
|
|
134
|
-
<code className="min-w-0 truncate font-mono text-[11px] leading-none text-foreground/70">
|
|
135
|
-
{child.effectRef}
|
|
136
|
-
</code>
|
|
137
|
-
<CopyInlineButton value={child.effectRef} label="Copy effect ref" />
|
|
138
|
-
</>
|
|
139
|
+
<ResourceRefSubtitle storeRef={store.ref} effectRef={child.effectRef} />
|
|
139
140
|
)}
|
|
140
141
|
</>
|
|
141
142
|
}
|
|
@@ -154,6 +155,30 @@ export function ResourcePanel({
|
|
|
154
155
|
</StatusChip>
|
|
155
156
|
) : null}
|
|
156
157
|
{store.contentAddressed ? <StatusChip>content-addressed</StatusChip> : null}
|
|
158
|
+
{showsRls ? (
|
|
159
|
+
<StatusChip
|
|
160
|
+
tone={rlsOn ? "emerald" : "neutral"}
|
|
161
|
+
icon={
|
|
162
|
+
<HugeiconsIcon
|
|
163
|
+
icon={rlsOn ? ShieldEnergyIcon : ShieldOff}
|
|
164
|
+
className="size-3"
|
|
165
|
+
aria-hidden
|
|
166
|
+
/>
|
|
167
|
+
}
|
|
168
|
+
title={
|
|
169
|
+
rlsOn
|
|
170
|
+
? rlsCount > 0
|
|
171
|
+
? `Row-level security enabled · ${rlsCount} ${rlsCount === 1 ? "policy" : "policies"}`
|
|
172
|
+
: "Row-level security enabled"
|
|
173
|
+
: "Row-level security disabled"
|
|
174
|
+
}
|
|
175
|
+
role="status"
|
|
176
|
+
data-slot="resource-rls"
|
|
177
|
+
data-rls={rlsOn ? "on" : "off"}
|
|
178
|
+
>
|
|
179
|
+
{rlsOn && rlsCount > 0 ? `${rlsCount} RLS` : "RLS"}
|
|
180
|
+
</StatusChip>
|
|
181
|
+
) : null}
|
|
157
182
|
{piiCount > 0 ? (
|
|
158
183
|
<StatusChip
|
|
159
184
|
tone={piiMasked ? "sky" : "amber"}
|
|
@@ -233,6 +258,34 @@ export function ResourcePanel({
|
|
|
233
258
|
);
|
|
234
259
|
}
|
|
235
260
|
|
|
261
|
+
function ResourceRefSubtitle({
|
|
262
|
+
storeRef,
|
|
263
|
+
effectRef,
|
|
264
|
+
}: {
|
|
265
|
+
readonly storeRef: string;
|
|
266
|
+
readonly effectRef: string;
|
|
267
|
+
}): JSX.Element {
|
|
268
|
+
const childRef = resourceHeaderChildRef(storeRef, effectRef);
|
|
269
|
+
return (
|
|
270
|
+
<>
|
|
271
|
+
<span className="shrink-0 font-mono text-[11px] leading-none text-muted-foreground">
|
|
272
|
+
{storeRef}
|
|
273
|
+
</span>
|
|
274
|
+
{childRef ? (
|
|
275
|
+
<>
|
|
276
|
+
<span aria-hidden className="text-border">
|
|
277
|
+
·
|
|
278
|
+
</span>
|
|
279
|
+
<code className="min-w-0 truncate font-mono text-[11px] leading-none text-foreground/70">
|
|
280
|
+
{childRef}
|
|
281
|
+
</code>
|
|
282
|
+
</>
|
|
283
|
+
) : null}
|
|
284
|
+
<CopyInlineButton value={effectRef} label="Copy effect ref" />
|
|
285
|
+
</>
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
236
289
|
type ChipTone = "neutral" | "emerald" | "amber" | "sky";
|
|
237
290
|
|
|
238
291
|
const CHIP_TONES: Record<ChipTone, string> = {
|
|
@@ -251,6 +304,7 @@ interface StatusChipProps {
|
|
|
251
304
|
readonly role?: string;
|
|
252
305
|
readonly "data-slot"?: string;
|
|
253
306
|
readonly "data-drifted"?: string;
|
|
307
|
+
readonly "data-rls"?: string;
|
|
254
308
|
readonly pressed?: boolean;
|
|
255
309
|
readonly onClick?: () => void;
|
|
256
310
|
readonly ariaLabel?: string;
|
|
@@ -270,6 +324,7 @@ function StatusChip({
|
|
|
270
324
|
role,
|
|
271
325
|
"data-slot": dataSlot,
|
|
272
326
|
"data-drifted": dataDrifted,
|
|
327
|
+
"data-rls": dataRls,
|
|
273
328
|
pressed,
|
|
274
329
|
onClick,
|
|
275
330
|
ariaLabel,
|
|
@@ -290,13 +345,20 @@ function StatusChip({
|
|
|
290
345
|
aria-label={ariaLabel}
|
|
291
346
|
data-slot={dataSlot}
|
|
292
347
|
data-drifted={dataDrifted}
|
|
348
|
+
data-rls={dataRls}
|
|
293
349
|
onClick={onClick}
|
|
294
350
|
>
|
|
295
351
|
{icon}
|
|
296
352
|
{children}
|
|
297
353
|
</button>
|
|
298
354
|
) : (
|
|
299
|
-
<span
|
|
355
|
+
<span
|
|
356
|
+
className={className}
|
|
357
|
+
role={role}
|
|
358
|
+
data-slot={dataSlot}
|
|
359
|
+
data-drifted={dataDrifted}
|
|
360
|
+
data-rls={dataRls}
|
|
361
|
+
>
|
|
300
362
|
{icon}
|
|
301
363
|
{children}
|
|
302
364
|
</span>
|