okengine 0.21.0 → 0.22.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/AGENTS.md +4 -4
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +15 -9
- package/manifest.v1.schema.json +10 -0
- package/package.json +22 -25
- package/site/content/docs/ai/skills.mdx +1 -1
- package/site/content/docs/client/calling.mdx +27 -19
- package/site/content/docs/client/index.mdx +1 -1
- package/site/content/docs/elements/channel/email.mdx +1 -1
- package/site/content/docs/elements/channel/index.mdx +1 -1
- package/site/content/docs/elements/flow/http.mdx +4 -4
- package/site/content/docs/elements/flow/index.mdx +3 -3
- package/site/content/docs/elements/flow/meta.json +1 -1
- package/site/content/docs/elements/gate/tenancy.mdx +1 -1
- package/site/content/docs/elements/vault/rotation.mdx +15 -0
- package/site/content/docs/plugins/otp.mdx +31 -31
- package/site/content/docs/recipes/mailpit.mdx +1 -1
- package/site/content/docs/recipes/meilisearch.mdx +1 -1
- package/site/content/docs/recipes/pgdog.mdx +1 -1
- package/site/content/docs/reference/configuration.mdx +2 -2
- package/site/content/docs/reference/errors.mdx +12 -2
- package/site/content/docs/reference/fx.mdx +28 -15
- package/site/content/docs/reference/idempotency.mdx +192 -0
- package/site/content/docs/reference/index.mdx +6 -1
- package/site/content/docs/reference/meta.json +2 -1
- package/site/content/docs/understand/meta.json +1 -1
- package/site/content/docs/{elements/flow → understand}/routing.mdx +11 -10
- package/site/content/docs/understand/the-architecture.mdx +14 -12
- package/site/content/docs/understand/try-it.mdx +3 -3
- package/src/cli/competitor-mention-removal.test.ts +3 -3
- package/src/cli/dev.test.ts +105 -2
- package/src/cli/dev.ts +37 -2
- package/src/cli/docker-cli.test.ts +1 -1
- package/src/cli/index.ts +9 -1
- package/src/cli/load-config.images.test.ts +10 -10
- package/src/cli/load-config.ts +1 -1
- package/src/cli/vault-cmd.test.ts +23 -0
- package/src/cli/vault-cmd.ts +7 -0
- package/src/client/create.ts +31 -27
- package/src/client/live.ts +44 -101
- package/src/client/sse.ts +20 -66
- package/src/client/stream.ts +25 -67
- package/src/client/transport.test.ts +225 -0
- package/src/client/transport.ts +158 -90
- package/src/client/types.ts +29 -3
- package/src/client/wire.ts +119 -0
- package/src/compiler/aot.ts +3 -32
- package/src/compiler/dynamic.ts +13 -11
- package/src/compiler/effects-infer.ts +726 -16
- package/src/compiler/extract.test.ts +37 -0
- package/src/compiler/extract.ts +113 -12
- package/src/compiler/fixtures/skyport.expected.json +24 -0
- package/src/compiler/fx-follow.test.ts +164 -0
- package/src/compiler/fx-index.ts +399 -0
- package/src/compiler/interpret.ts +45 -0
- package/src/console/server/flows-invoke.test.ts +2 -2
- package/src/console/ui-next/dist/assets/{access-page-tIbsiphz.js → access-page-Ze6ckjdd.js} +2 -2
- package/src/console/ui-next/dist/assets/agent-disclosure-Bkohc_8X.js +1 -0
- package/src/console/ui-next/dist/assets/{cache-glyph-BCC-DxKT.js → cache-glyph-rL0lHxat.js} +1 -1
- package/src/console/ui-next/dist/assets/{call-pii-button-jOmYISdc.js → call-pii-button-Deo4PP18.js} +1 -1
- package/src/console/ui-next/dist/assets/{collapsible-DC2xNaAb.js → collapsible-CoJ6amHf.js} +1 -1
- package/src/console/ui-next/dist/assets/{copy-inline-button-CAYD18cr.js → copy-inline-button-CWG5_ZOh.js} +1 -1
- package/src/console/ui-next/dist/assets/{detail-header-DVWNjWjg.js → detail-header-b_ZzIsmU.js} +1 -1
- package/src/console/ui-next/dist/assets/{dropdown-menu-4h2LOVXM.js → dropdown-menu-nwXEO1Ac.js} +1 -1
- package/src/console/ui-next/dist/assets/duration-tone-BbQ_8z50.js +9 -0
- package/src/console/ui-next/dist/assets/element-icons-CwyLpVXz.js +1 -0
- package/src/console/ui-next/dist/assets/{explorer-empty-CJs5A-wm.js → explorer-empty-C8sSCqYT.js} +1 -1
- package/src/console/ui-next/dist/assets/{flows-page-gT1lsWQK.js → flows-page-D2E7BtKK.js} +1 -1
- package/src/console/ui-next/dist/assets/{highlighted-json-C2GZEJNI.js → highlighted-json-CPYBzDh0.js} +1 -1
- package/src/console/ui-next/dist/assets/{http-method-BdYjcIrD.js → http-method-DTPevKmM.js} +1 -1
- package/src/console/ui-next/dist/assets/index-vTuwmeQz.js +58 -0
- package/src/console/ui-next/dist/assets/observability-page-SJTSzHFJ.js +4 -0
- package/src/console/ui-next/dist/assets/{replica-lag-C4QdAF7J.js → replica-lag-BM27lXld.js} +3 -3
- package/src/console/ui-next/dist/assets/{request-meta-C43DHyld.js → request-meta-BjFT7DNl.js} +1 -1
- package/src/console/ui-next/dist/assets/shortcut-keys-CUNegEV4.js +1 -0
- package/src/console/ui-next/dist/assets/store-page-Qj9ThRE-.js +41 -0
- package/src/console/ui-next/dist/assets/{trace-detail-sheet-Dcpo4Us_.js → trace-detail-sheet-Cmitq3da.js} +2 -2
- package/src/console/ui-next/dist/assets/{tree-expand-toggle-CKJTuv43.js → tree-expand-toggle-CbDIB-7x.js} +2 -2
- package/src/console/ui-next/dist/assets/units-page-_PuYqFty.js +1 -0
- package/src/console/ui-next/dist/assets/{use-vault-list-CT4-gajj.js → use-vault-list-Cs45Czkt.js} +1 -1
- package/src/console/ui-next/dist/assets/{vault-page-BwZ9YjTW.js → vault-page-BOMr0go9.js} +2 -2
- package/src/console/ui-next/dist/index.html +2 -2
- package/src/console/ui-next/src/features/units/detail/flow-contract-panel.tsx +9 -0
- package/src/docker/docker.test.ts +13 -13
- package/src/docker/images-config.test.ts +12 -12
- package/src/docker/stack-id.test.ts +1 -1
- package/src/drivers/journal-postgres.ts +168 -3
- package/src/drivers/meilisearch.ts +2 -0
- package/src/drivers/vault-builtin.test.ts +10 -0
- package/src/drivers/vault-builtin.ts +13 -1
- package/src/drivers/vault-remote-bag.ts +5 -1
- package/src/drivers/vault-types.ts +6 -1
- package/src/elements/store/emit-drizzle.ts +2 -2
- package/src/elements/store/live-default.test.ts +2 -0
- package/src/elements/store/live-http.test.ts +1 -0
- package/src/elements/store/resource-list-docs.test.ts +2 -2
- package/src/elements/store/resource.test.ts +3 -3
- package/src/elements/store/schema-decl.test.ts +1 -0
- package/src/elements/store/sql-condition.ts +24 -7
- package/src/elements/store/sql-session.ts +20 -4
- package/src/elements/store/upsert-app.test.ts +1 -1
- package/src/elements/vault/audit.test.ts +137 -0
- package/src/elements/vault/audit.ts +106 -13
- package/src/elements/vault/boot-chain.ts +9 -1
- package/src/elements/vault/builtin-adapter.ts +33 -3
- package/src/i18n/catalogs/ar.ts +4 -0
- package/src/i18n/catalogs/en.ts +4 -0
- package/src/kernel/abort-scope.ts +33 -2
- package/src/kernel/app.ts +200 -20
- package/src/kernel/auto-cache.test.ts +6 -6
- package/src/kernel/boot-bind/vault.ts +1 -0
- package/src/kernel/boot.ts +19 -1
- package/src/kernel/builtin-errors.ts +8 -0
- package/src/kernel/client-descriptor.test.ts +78 -0
- package/src/kernel/client-descriptor.ts +24 -0
- package/src/kernel/concurrency.test.ts +33 -0
- package/src/kernel/effects-stamping.test.ts +2 -2
- package/src/kernel/errors-compiler.ts +20 -0
- package/src/kernel/errors-text.ts +99 -0
- package/src/kernel/errors.ts +90 -138
- package/src/kernel/external-effects.test.ts +36 -0
- package/src/kernel/flow.ts +24 -0
- package/src/kernel/fx-fetch.ts +5 -1
- package/src/kernel/fx-sql-handle.ts +305 -0
- package/src/kernel/fx.ts +42 -330
- package/src/kernel/idempotency-store.ts +578 -0
- package/src/kernel/idempotency.test.ts +556 -0
- package/src/kernel/idempotency.ts +304 -0
- package/src/kernel/index.ts +1 -0
- package/src/kernel/journal.ts +56 -0
- package/src/kernel/json-result.ts +59 -0
- package/src/kernel/project-out.ts +6 -1
- package/src/manifest/types.ts +8 -0
- package/src/okid-extended.ts +175 -0
- package/src/okid-shared.ts +103 -0
- package/src/okid.ts +30 -213
- package/src/plugins/auth-delivery.mailpit.integration.test.ts +1 -1
- package/src/plugins/otp.test.ts +65 -1
- package/src/plugins/otp.ts +59 -7
- package/src/release/absolute-regression.test.ts +63 -0
- package/src/release/build-lib.ts +9 -0
- package/src/release/http-graph.test.ts +25 -0
- package/src/release/http-graph.ts +90 -0
- package/src/release/index.ts +3 -0
- package/src/release/limits.ts +17 -2
- package/src/release/measure.ts +105 -14
- package/src/test/create-test-app.test.ts +3 -1
- package/src/test/create-test-app.ts +40 -0
- package/src/test/live-signals.test.ts +1 -0
- package/src/test/provisions.integration.test.ts +1 -0
- package/src/test/tenant-isolation.test.ts +1 -0
- package/src/console/ui-next/dist/assets/agent-disclosure-CSKumwS2.js +0 -1
- package/src/console/ui-next/dist/assets/duration-tone-CwoV56jn.js +0 -9
- package/src/console/ui-next/dist/assets/element-icons-BI8cJgdh.js +0 -1
- package/src/console/ui-next/dist/assets/index-Cul17AcV.js +0 -63
- package/src/console/ui-next/dist/assets/observability-page-oY9vdYBk.js +0 -4
- package/src/console/ui-next/dist/assets/shortcut-keys-3ILd8oGn.js +0 -1
- package/src/console/ui-next/dist/assets/store-page-CL0D9dOq.js +0 -41
- package/src/console/ui-next/dist/assets/units-page-1PlT19ft.js +0 -1
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One index of project functions that receive `fx`, built from ASTs
|
|
3
|
+
* extract already parsed. Inference follows a call that passes `fx`
|
|
4
|
+
* through this index — it does not re-parse or walk the filesystem.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
identifierName,
|
|
9
|
+
stringArg,
|
|
10
|
+
type AstNode,
|
|
11
|
+
type FxCalleeResolution,
|
|
12
|
+
} from "./effects-infer.ts";
|
|
13
|
+
|
|
14
|
+
/** One `tsconfig` `paths` entry (`@/*` → `./src/*`). */
|
|
15
|
+
export interface TsconfigPath {
|
|
16
|
+
readonly pattern: string;
|
|
17
|
+
readonly targets: readonly string[];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Resolve a callee in one indexed file. */
|
|
21
|
+
export interface FxIndex {
|
|
22
|
+
/**
|
|
23
|
+
* Resolve `callee` as seen from `file`.
|
|
24
|
+
*
|
|
25
|
+
* @param file - File that contains the call
|
|
26
|
+
* @param callee - Call callee node
|
|
27
|
+
*/
|
|
28
|
+
resolve(file: string, callee: AstNode): FxCalleeResolution;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface NamedImport {
|
|
32
|
+
readonly kind: "named";
|
|
33
|
+
readonly from: string;
|
|
34
|
+
readonly imported: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface NamespaceImport {
|
|
38
|
+
readonly kind: "namespace";
|
|
39
|
+
readonly from: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface IntrinsicImport {
|
|
43
|
+
readonly kind: "intrinsic";
|
|
44
|
+
readonly name: "liveQuery" | "applySearchEmbedCdc";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
type ImportBinding = NamedImport | NamespaceImport | IntrinsicImport;
|
|
48
|
+
|
|
49
|
+
interface LocalExport {
|
|
50
|
+
readonly kind: "local";
|
|
51
|
+
readonly binding: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface Reexport {
|
|
55
|
+
readonly kind: "reexport";
|
|
56
|
+
readonly from: string;
|
|
57
|
+
readonly imported: string;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface FileFx {
|
|
61
|
+
readonly functions: Map<string, AstNode>;
|
|
62
|
+
readonly imports: Map<string, ImportBinding>;
|
|
63
|
+
readonly exports: Map<string, LocalExport | Reexport>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const INTRINSIC_SOURCES: Readonly<
|
|
67
|
+
Record<string, Readonly<Record<string, "liveQuery" | "applySearchEmbedCdc">>>
|
|
68
|
+
> = {
|
|
69
|
+
okengine: { liveQuery: "liveQuery" },
|
|
70
|
+
"okengine/store": { liveQuery: "liveQuery", applySearchEmbedCdc: "applySearchEmbedCdc" },
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Read `compilerOptions.paths` from `tsconfig.json` when `rootDir` is set.
|
|
75
|
+
*
|
|
76
|
+
* @param rootDir - App root
|
|
77
|
+
*/
|
|
78
|
+
export async function readTsconfigPaths(rootDir: string): Promise<readonly TsconfigPath[]> {
|
|
79
|
+
const file = Bun.file(`${rootDir}/tsconfig.json`);
|
|
80
|
+
if (!(await file.exists())) return [];
|
|
81
|
+
let parsed: unknown;
|
|
82
|
+
try {
|
|
83
|
+
parsed = JSON.parse(await file.text()) as unknown;
|
|
84
|
+
} catch {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
if (typeof parsed !== "object" || parsed === null) return [];
|
|
88
|
+
const options = (parsed as { compilerOptions?: unknown }).compilerOptions;
|
|
89
|
+
if (typeof options !== "object" || options === null) return [];
|
|
90
|
+
const paths = (options as { paths?: unknown }).paths;
|
|
91
|
+
if (typeof paths !== "object" || paths === null) return [];
|
|
92
|
+
const out: TsconfigPath[] = [];
|
|
93
|
+
for (const [pattern, target] of Object.entries(paths)) {
|
|
94
|
+
if (!Array.isArray(target)) continue;
|
|
95
|
+
const targets = target.filter((item): item is string => typeof item === "string");
|
|
96
|
+
if (targets.length > 0) out.push({ pattern, targets });
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Index top-level functions and import/export bindings for `fx` following.
|
|
103
|
+
*
|
|
104
|
+
* @param files - Parsed sources (path → program)
|
|
105
|
+
* @param paths - `tsconfig` paths, empty when there is no root
|
|
106
|
+
*/
|
|
107
|
+
export function buildFxIndex(
|
|
108
|
+
files: readonly { readonly path: string; readonly program: AstNode }[],
|
|
109
|
+
paths: readonly TsconfigPath[] = [],
|
|
110
|
+
): FxIndex {
|
|
111
|
+
const known = new Set(files.map((file) => normalizePosix(file.path)));
|
|
112
|
+
const byFile = new Map<string, FileFx>();
|
|
113
|
+
for (const file of files) {
|
|
114
|
+
byFile.set(normalizePosix(file.path), indexFile(file.program));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function resolveModule(fromFile: string, spec: string): string | undefined {
|
|
118
|
+
if (spec.startsWith(".")) {
|
|
119
|
+
const dir = posixDir(fromFile);
|
|
120
|
+
return matchFile(normalizePosix(dir.length > 0 ? `${dir}/${spec}` : spec), known);
|
|
121
|
+
}
|
|
122
|
+
for (const entry of paths) {
|
|
123
|
+
const star = entry.pattern.indexOf("*");
|
|
124
|
+
if (star < 0) {
|
|
125
|
+
if (spec !== entry.pattern) continue;
|
|
126
|
+
for (const target of entry.targets) {
|
|
127
|
+
const hit = matchFile(normalizePosix(target), known);
|
|
128
|
+
if (hit) return hit;
|
|
129
|
+
}
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const prefix = entry.pattern.slice(0, star);
|
|
133
|
+
const suffix = entry.pattern.slice(star + 1);
|
|
134
|
+
if (!spec.startsWith(prefix) || !spec.endsWith(suffix)) continue;
|
|
135
|
+
const mid = spec.slice(prefix.length, spec.length - suffix.length);
|
|
136
|
+
for (const target of entry.targets) {
|
|
137
|
+
const hit = matchFile(normalizePosix(target.replace("*", mid)), known);
|
|
138
|
+
if (hit) return hit;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function resolveExport(file: string, exportName: string, seen: Set<string>): FxCalleeResolution {
|
|
145
|
+
const key = `${file}#${exportName}`;
|
|
146
|
+
if (seen.has(key)) return { kind: "unresolved", label: exportName };
|
|
147
|
+
seen.add(key);
|
|
148
|
+
const indexed = byFile.get(file);
|
|
149
|
+
if (!indexed) return { kind: "unresolved", label: exportName };
|
|
150
|
+
const exported = indexed.exports.get(exportName);
|
|
151
|
+
if (!exported) {
|
|
152
|
+
const fn = indexed.functions.get(exportName);
|
|
153
|
+
if (fn) return { kind: "function", fn, file };
|
|
154
|
+
return { kind: "unresolved", label: exportName };
|
|
155
|
+
}
|
|
156
|
+
if (exported.kind === "local") return resolveBinding(file, exported.binding, seen);
|
|
157
|
+
const target = resolveModule(file, exported.from);
|
|
158
|
+
if (!target) return { kind: "unresolved", label: exportName };
|
|
159
|
+
return resolveExport(target, exported.imported, seen);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function resolveBinding(file: string, name: string, seen: Set<string>): FxCalleeResolution {
|
|
163
|
+
const key = `${file}#local:${name}`;
|
|
164
|
+
if (seen.has(key)) return { kind: "unresolved", label: name };
|
|
165
|
+
seen.add(key);
|
|
166
|
+
const indexed = byFile.get(file);
|
|
167
|
+
if (!indexed) return { kind: "unresolved", label: name };
|
|
168
|
+
const fn = indexed.functions.get(name);
|
|
169
|
+
if (fn) return { kind: "function", fn, file };
|
|
170
|
+
const imported = indexed.imports.get(name);
|
|
171
|
+
if (!imported) return { kind: "unresolved", label: name };
|
|
172
|
+
if (imported.kind === "intrinsic") return { kind: "intrinsic", name: imported.name };
|
|
173
|
+
if (imported.kind === "namespace") return { kind: "unresolved", label: name };
|
|
174
|
+
const target = resolveModule(file, imported.from);
|
|
175
|
+
if (!target) return { kind: "unresolved", label: name };
|
|
176
|
+
return resolveExport(target, imported.imported, seen);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return {
|
|
180
|
+
resolve(file, callee) {
|
|
181
|
+
const from = normalizePosix(file);
|
|
182
|
+
const seen = new Set<string>();
|
|
183
|
+
if (callee.type === "Identifier") {
|
|
184
|
+
const name = identifierName(callee) ?? "callee";
|
|
185
|
+
return resolveBinding(from, name, seen);
|
|
186
|
+
}
|
|
187
|
+
if (callee.type === "MemberExpression") {
|
|
188
|
+
const member = callee as AstNode & {
|
|
189
|
+
object: AstNode;
|
|
190
|
+
property: AstNode;
|
|
191
|
+
computed?: boolean;
|
|
192
|
+
};
|
|
193
|
+
if (member.computed === true) return { kind: "unresolved", label: "callee" };
|
|
194
|
+
const objectName = identifierName(member.object);
|
|
195
|
+
const prop = identifierName(member.property);
|
|
196
|
+
if (!objectName || !prop) return { kind: "unresolved", label: "callee" };
|
|
197
|
+
const indexed = byFile.get(from);
|
|
198
|
+
const imported = indexed?.imports.get(objectName);
|
|
199
|
+
if (!imported || imported.kind !== "namespace") {
|
|
200
|
+
return { kind: "unresolved", label: prop };
|
|
201
|
+
}
|
|
202
|
+
const target = resolveModule(from, imported.from);
|
|
203
|
+
if (!target) return { kind: "unresolved", label: prop };
|
|
204
|
+
return resolveExport(target, prop, seen);
|
|
205
|
+
}
|
|
206
|
+
return { kind: "unresolved", label: "callee" };
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function indexFile(program: AstNode): FileFx {
|
|
212
|
+
const functions = new Map<string, AstNode>();
|
|
213
|
+
const imports = new Map<string, ImportBinding>();
|
|
214
|
+
const exports = new Map<string, LocalExport | Reexport>();
|
|
215
|
+
const body = (program as AstNode & { body?: AstNode[] }).body ?? [];
|
|
216
|
+
for (const stmt of body) indexStmt(stmt, functions, imports, exports);
|
|
217
|
+
return { functions, imports, exports };
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function indexStmt(
|
|
221
|
+
stmt: AstNode,
|
|
222
|
+
functions: Map<string, AstNode>,
|
|
223
|
+
imports: Map<string, ImportBinding>,
|
|
224
|
+
exports: Map<string, LocalExport | Reexport>,
|
|
225
|
+
): void {
|
|
226
|
+
if (stmt.type === "ImportDeclaration") {
|
|
227
|
+
indexImport(stmt, imports);
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (stmt.type === "FunctionDeclaration") {
|
|
231
|
+
rememberFunction(stmt, functions, exports, true);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
if (stmt.type === "VariableDeclaration") {
|
|
235
|
+
rememberVars(stmt, functions, exports, false);
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (stmt.type === "ExportDefaultDeclaration") {
|
|
239
|
+
const decl = (stmt as AstNode & { declaration?: AstNode }).declaration;
|
|
240
|
+
if (decl && isFunctionNode(decl)) {
|
|
241
|
+
functions.set("default", decl);
|
|
242
|
+
exports.set("default", { kind: "local", binding: "default" });
|
|
243
|
+
}
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (stmt.type !== "ExportNamedDeclaration") return;
|
|
247
|
+
const decl = (stmt as AstNode & { declaration?: AstNode | null }).declaration;
|
|
248
|
+
const source = stringArg((stmt as AstNode & { source?: AstNode }).source);
|
|
249
|
+
if (decl?.type === "FunctionDeclaration") rememberFunction(decl, functions, exports, true);
|
|
250
|
+
if (decl?.type === "VariableDeclaration") rememberVars(decl, functions, exports, true);
|
|
251
|
+
const specifiers = (stmt as AstNode & { specifiers?: AstNode[] }).specifiers ?? [];
|
|
252
|
+
for (const spec of specifiers) {
|
|
253
|
+
const local = exportedLocalName(spec);
|
|
254
|
+
const exported = exportedPublicName(spec) ?? local;
|
|
255
|
+
if (!local || !exported) continue;
|
|
256
|
+
if (source) {
|
|
257
|
+
exports.set(exported, { kind: "reexport", from: source, imported: local });
|
|
258
|
+
} else {
|
|
259
|
+
exports.set(exported, { kind: "local", binding: local });
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function indexImport(stmt: AstNode, imports: Map<string, ImportBinding>): void {
|
|
265
|
+
const source = stringArg((stmt as AstNode & { source?: AstNode }).source);
|
|
266
|
+
if (!source) return;
|
|
267
|
+
const specifiers = (stmt as AstNode & { specifiers?: AstNode[] }).specifiers ?? [];
|
|
268
|
+
const intrinsics = INTRINSIC_SOURCES[source];
|
|
269
|
+
for (const spec of specifiers) {
|
|
270
|
+
if (spec.type === "ImportNamespaceSpecifier") {
|
|
271
|
+
const local = identifierName((spec as AstNode & { local?: AstNode }).local);
|
|
272
|
+
if (local) imports.set(local, { kind: "namespace", from: source });
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
if (spec.type === "ImportDefaultSpecifier") {
|
|
276
|
+
const local = identifierName((spec as AstNode & { local?: AstNode }).local);
|
|
277
|
+
if (local) imports.set(local, { kind: "named", from: source, imported: "default" });
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
if (spec.type !== "ImportSpecifier") continue;
|
|
281
|
+
const local = identifierName((spec as AstNode & { local?: AstNode }).local);
|
|
282
|
+
const imported =
|
|
283
|
+
identifierName((spec as AstNode & { imported?: AstNode }).imported) ??
|
|
284
|
+
stringArg((spec as AstNode & { imported?: AstNode }).imported) ??
|
|
285
|
+
local;
|
|
286
|
+
if (!local || !imported) continue;
|
|
287
|
+
const intrinsic = intrinsics?.[imported];
|
|
288
|
+
if (intrinsic) {
|
|
289
|
+
imports.set(local, { kind: "intrinsic", name: intrinsic });
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
imports.set(local, { kind: "named", from: source, imported });
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function rememberFunction(
|
|
297
|
+
fn: AstNode,
|
|
298
|
+
functions: Map<string, AstNode>,
|
|
299
|
+
exports: Map<string, LocalExport | Reexport>,
|
|
300
|
+
exportIt: boolean,
|
|
301
|
+
): void {
|
|
302
|
+
const name = identifierName((fn as AstNode & { id?: AstNode }).id);
|
|
303
|
+
if (!name) return;
|
|
304
|
+
functions.set(name, fn);
|
|
305
|
+
if (exportIt) exports.set(name, { kind: "local", binding: name });
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
function rememberVars(
|
|
309
|
+
decl: AstNode,
|
|
310
|
+
functions: Map<string, AstNode>,
|
|
311
|
+
exports: Map<string, LocalExport | Reexport>,
|
|
312
|
+
exportIt: boolean,
|
|
313
|
+
): void {
|
|
314
|
+
const declarations = (decl as AstNode & { declarations?: AstNode[] }).declarations ?? [];
|
|
315
|
+
for (const item of declarations) {
|
|
316
|
+
const name = identifierName((item as AstNode & { id?: AstNode }).id);
|
|
317
|
+
if (!name) continue;
|
|
318
|
+
const init = (item as AstNode & { init?: AstNode | null }).init;
|
|
319
|
+
if (init && isFunctionNode(unwrapValue(init))) functions.set(name, unwrapValue(init));
|
|
320
|
+
if (exportIt) exports.set(name, { kind: "local", binding: name });
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function exportedLocalName(spec: AstNode): string | undefined {
|
|
325
|
+
return (
|
|
326
|
+
identifierName((spec as AstNode & { local?: AstNode }).local) ??
|
|
327
|
+
stringArg((spec as AstNode & { local?: AstNode }).local)
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
function exportedPublicName(spec: AstNode): string | undefined {
|
|
332
|
+
return (
|
|
333
|
+
identifierName((spec as AstNode & { exported?: AstNode }).exported) ??
|
|
334
|
+
stringArg((spec as AstNode & { exported?: AstNode }).exported)
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
function isFunctionNode(node: AstNode): boolean {
|
|
339
|
+
return (
|
|
340
|
+
node.type === "ArrowFunctionExpression" ||
|
|
341
|
+
node.type === "FunctionExpression" ||
|
|
342
|
+
node.type === "FunctionDeclaration"
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
function unwrapValue(node: AstNode): AstNode {
|
|
347
|
+
let current = node;
|
|
348
|
+
for (let i = 0; i < 8; i++) {
|
|
349
|
+
if (
|
|
350
|
+
current.type === "ParenthesizedExpression" ||
|
|
351
|
+
current.type === "TSAsExpression" ||
|
|
352
|
+
current.type === "TSTypeAssertion" ||
|
|
353
|
+
current.type === "TSSatisfiesExpression" ||
|
|
354
|
+
current.type === "TSNonNullExpression" ||
|
|
355
|
+
current.type === "AwaitExpression"
|
|
356
|
+
) {
|
|
357
|
+
const inner = (current as AstNode & { expression?: AstNode; argument?: AstNode }).expression;
|
|
358
|
+
const arg = (current as AstNode & { argument?: AstNode }).argument;
|
|
359
|
+
const next = inner ?? arg;
|
|
360
|
+
if (!next) break;
|
|
361
|
+
current = next;
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
break;
|
|
365
|
+
}
|
|
366
|
+
return current;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
function matchFile(path: string, known: ReadonlySet<string>): string | undefined {
|
|
370
|
+
const stripped = path.replace(/\.(ts|tsx|mts|cts)$/, "");
|
|
371
|
+
const candidates = [
|
|
372
|
+
path,
|
|
373
|
+
stripped,
|
|
374
|
+
`${stripped}.ts`,
|
|
375
|
+
`${stripped}.tsx`,
|
|
376
|
+
`${stripped}.mts`,
|
|
377
|
+
`${stripped}/index.ts`,
|
|
378
|
+
`${stripped}/index.tsx`,
|
|
379
|
+
];
|
|
380
|
+
for (const candidate of candidates) {
|
|
381
|
+
if (known.has(candidate)) return candidate;
|
|
382
|
+
}
|
|
383
|
+
return undefined;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function normalizePosix(path: string): string {
|
|
387
|
+
const parts: string[] = [];
|
|
388
|
+
for (const part of path.replaceAll("\\", "/").split("/")) {
|
|
389
|
+
if (part.length === 0 || part === ".") continue;
|
|
390
|
+
if (part === "..") parts.pop();
|
|
391
|
+
else parts.push(part);
|
|
392
|
+
}
|
|
393
|
+
return parts.join("/");
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function posixDir(file: string): string {
|
|
397
|
+
const slash = file.lastIndexOf("/");
|
|
398
|
+
return slash < 0 ? "" : file.slice(0, slash);
|
|
399
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interpreted parse/validate — the edge path.
|
|
3
|
+
*
|
|
4
|
+
* AoT (`new Function`) lives in {@link compileAot} and is loaded only when
|
|
5
|
+
* requested, so eval-restricted runtimes do not carry the codegen.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { FlowFailure } from "../kernel/errors.ts";
|
|
9
|
+
import { validate, type SchemaInput } from "../validation/standard-schema.ts";
|
|
10
|
+
import {
|
|
11
|
+
assembleInput,
|
|
12
|
+
extractParts,
|
|
13
|
+
type ContextInference,
|
|
14
|
+
type InputParts,
|
|
15
|
+
} from "./http-parse.ts";
|
|
16
|
+
|
|
17
|
+
/** Result of parse + validate for one request. */
|
|
18
|
+
export type ParseValidateResult =
|
|
19
|
+
| { readonly ok: true; readonly input: unknown }
|
|
20
|
+
| { readonly ok: false; readonly failure: FlowFailure };
|
|
21
|
+
|
|
22
|
+
/** Compiled parse/validate function. */
|
|
23
|
+
export type CompiledParseValidate = (
|
|
24
|
+
request: Request,
|
|
25
|
+
params: Readonly<Record<string, string>>,
|
|
26
|
+
) => Promise<ParseValidateResult>;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Interpreted parse/validate using the shared HTTP helpers (AoT fallback).
|
|
30
|
+
*
|
|
31
|
+
* @param inference - Context flags
|
|
32
|
+
* @param schema - Input schema
|
|
33
|
+
*/
|
|
34
|
+
export function createInterpretedParseValidate(
|
|
35
|
+
inference: ContextInference,
|
|
36
|
+
schema: SchemaInput | undefined,
|
|
37
|
+
): CompiledParseValidate {
|
|
38
|
+
return async (request, params) => {
|
|
39
|
+
const parts: InputParts = await extractParts(request, params, inference);
|
|
40
|
+
const raw = assembleInput(parts);
|
|
41
|
+
const result = await validate(schema, raw);
|
|
42
|
+
if (!result.ok) return { ok: false, failure: result.failure };
|
|
43
|
+
return { ok: true, input: result.value };
|
|
44
|
+
};
|
|
45
|
+
}
|
|
@@ -622,7 +622,7 @@ describe("console flows invoke", () => {
|
|
|
622
622
|
config: { drivers: { store: { sql: { test: "pglite" } } } },
|
|
623
623
|
startScheduler: false,
|
|
624
624
|
});
|
|
625
|
-
const harness = await createTestApp(host);
|
|
625
|
+
const harness = await createTestApp(host, { capability: "open" });
|
|
626
626
|
const seedFlow = host.bindings.find((b) => b.flow.name === "views.seed")?.flow;
|
|
627
627
|
expect(seedFlow).toBeDefined();
|
|
628
628
|
const seeded = await host.execute(
|
|
@@ -728,7 +728,7 @@ describe("console flows invoke", () => {
|
|
|
728
728
|
config: { drivers: { store: { sql: { test: "pglite" } } } },
|
|
729
729
|
startScheduler: false,
|
|
730
730
|
});
|
|
731
|
-
const harness = await createTestApp(host);
|
|
731
|
+
const harness = await createTestApp(host, { capability: "open" });
|
|
732
732
|
const manifest = {
|
|
733
733
|
...FLOWS_TEST_MANIFEST,
|
|
734
734
|
flows: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{r as t}from"./react-dom-Ddte4I-Q.js";import{A as n}from"./xyflow-yApv7D4e.js";import{Cr as r,Dr as i,E as a,Er as o,F as s,Fr as c,I as l,Ir as u,Lr as d,Nr as f,Pr as p,R as m,Rr as h,Sr as g,Tr as _,Vr as v,
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{r as t}from"./react-dom-Ddte4I-Q.js";import{A as n}from"./xyflow-yApv7D4e.js";import{Cr as r,Dr as i,E as a,Er as o,F as s,Fr as c,I as l,Ir as u,Lr as d,Nr as f,Pr as p,R as m,Rr as h,Sr as g,Tr as _,Vr as v,Zi as y,_a as b,_r as x,ar as S,br as C,c as w,cr as T,dr as ee,i as E,kr as D,l as O,lr as k,mr as A,nr as j,o as M,pr as N,rr as P,s as F,sr as I,tr as L,u as te,ur as R,vr as z,wr as B,x as V,xr as H}from"./shortcut-keys-CUNegEV4.js";import{i as ne,t as re}from"./http-method-DTPevKmM.js";import{a as ie,c as ae,h as oe,i as se,n as ce,o as le,r as ue,s as U,t as de}from"./element-icons-CwyLpVXz.js";import{t as fe}from"./UserIcon-DaE2PB5_.js";import{t as pe}from"./PlusSignIcon-CwG3nxfu.js";import{ht as me,jt as W,yt as he}from"./index-vTuwmeQz.js";import{t as ge}from"./explorer-empty-C8sSCqYT.js";import{a as G,c as _e,l as K,n as q,o as ve,r as ye,s as be,t as xe}from"./detail-header-b_ZzIsmU.js";import{n as Se,t as J}from"./copy-inline-button-CWG5_ZOh.js";var Ce=[[`path`,{d:`M5 21H19`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`1.5`,key:`0`}],[`path`,{d:`M12.125 12.75H12M12.25 12.75C12.25 12.8881 12.1381 13 12 13C11.8619 13 11.75 12.8881 11.75 12.75C11.75 12.6119 11.8619 12.5 12 12.5C12.1381 12.5 12.25 12.6119 12.25 12.75Z`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`1.5`,key:`1`}],[`path`,{d:`M14.9152 7.61089L13.8078 5.38179C13.019 3.79393 12.6246 3 12 3C11.3754 3 10.981 3.79393 10.1922 5.38179L9.08483 7.61089C8.58107 8.62494 8.32919 9.13197 7.87976 9.24608C7.8485 9.25401 7.81689 9.26043 7.78503 9.26533C7.32682 9.3357 6.89919 8.96678 6.04393 8.22895C4.0124 6.47635 2.99663 5.60004 2.38034 5.94899C2.34045 5.97157 2.30213 5.99686 2.26565 6.02467C1.70197 6.45439 2.09541 7.74136 2.88229 10.3153L4.04783 14.1279C4.47098 15.5121 4.68255 16.2042 5.21787 16.6021C5.75318 17 6.47261 17 7.91147 17L16.0886 16.9999C17.5274 16.9999 18.2468 16.9999 18.7821 16.602C19.3175 16.2041 19.529 15.512 19.9522 14.1279L21.1177 10.3153C21.9046 7.74137 22.298 6.4544 21.7344 6.02468C21.6979 5.99687 21.6595 5.97158 21.6197 5.94899C21.0034 5.60006 19.9876 6.47636 17.9561 8.22896C17.1008 8.96679 16.6732 9.3357 16.215 9.26533C16.1831 9.26043 16.1515 9.25401 16.1202 9.24607C15.6708 9.13197 15.4189 8.62494 14.9152 7.61089Z`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`1.5`,key:`2`}]],Y=e(t(),1);function we(e,t){if(e==null)return`never`;let n=e-t;if(Math.abs(n)<6e4)return`just now`;let r=Ee(Math.abs(n));return n<0?`${r} ago`:`in ${r}`}function Te(e,t){return e==null?`never`:e<=t?`expired`:we(e,t)}function Ee(e){if(e<36e5)return`${Math.floor(e/6e4)}m`;if(e<864e5)return`${Math.floor(e/36e5)}h`;let t=Math.floor(e/864e5);return t<100?`${t}d`:`${Math.floor(t/30)}mo`}var X=864e5;function De(e){let t=/^(\d+)(ms|s|m|h|d)$/.exec(e.trim());if(!t)return 0;let n=Number(t[1]);switch(t[2]){case`ms`:return n;case`s`:return n*1e3;case`m`:return n*6e4;case`h`:return n*36e5;case`d`:return n*X;default:return 0}}function Oe(e,t,n=``){if(e===`never`)return null;if(e===`30d`)return t+30*X;if(e===`90d`)return t+90*X;let r=De(n);return r>0?t+r:null}var Z=36e5;function ke(e,t){if(e==null)return{choice:`never`,custom:``};let n=e-t;return n<=0?{choice:`never`,custom:``}:Math.abs(n-30*X)<Z?{choice:`30d`,custom:``}:Math.abs(n-90*X)<Z?{choice:`90d`,custom:``}:{choice:`custom`,custom:Me(n)}}var Ae=7*X;function je(e,t){if(e==null||e<=t)return{choice:`90d`,custom:``};let n=e-t;return Math.abs(n-30*X)<=Ae?{choice:`30d`,custom:``}:Math.abs(n-90*X)<=Ae?{choice:`90d`,custom:``}:{choice:`custom`,custom:Me(n)}}function Me(e){return e<=0?``:e>=X&&e%X===0?`${e/X}d`:e>=Z&&e%Z===0?`${e/Z}h`:e>=6e4&&e%6e4==0?`${e/6e4}m`:e>=X?`${Math.max(1,Math.round(e/X))}d`:e>=Z?`${Math.max(1,Math.round(e/Z))}h`:`${Math.max(1,Math.round(e/6e4))}m`}var Ne=[`s`,`m`,`h`,`d`,`ms`],Pe={s:`Seconds`,m:`Minutes`,h:`Hours`,d:`Days`,ms:`Milliseconds`};function Fe(e,t,n){let r=e.trim(),i=t.trim();if(r.length===0&&i.length===0)return null;if(r.length===0||i.length===0||!/^\d+$/.test(r)||!/^\d+$/.test(i))return;let a=Number(r),o=Number(i);if(a<=0||o<=0)return;let s=`${o}${n}`;if(!(De(s)<=0))return{max:a,per:s}}function Ie(e){let t=/^(\d+)(ms|s|m|h|d)$/.exec(e.trim());return t?{count:t[1],unit:t[2]}:{count:``,unit:`m`}}function Le(e){let t=ze(e);return t.length===0?null:Be(t)?`ip`:Ve(t)?`host`:null}function Re(e){let t=new Set,n=[];for(let r of e.split(/[\s,]+/)){let e=ze(r);e.length===0||t.has(e)||Le(e)!=null&&(t.add(e),n.push(e))}return n}function ze(e){let t=e.trim().toLowerCase();if(t=t.replace(/^https?:\/\//,``),t.startsWith(`[`)&&t.includes(`]`)){let e=t.indexOf(`]`),n=t.slice(1,e),r=t.slice(e+1);t=r.startsWith(`:`)||r.startsWith(`/`)?n:`${n}${r}`}let n=t.indexOf(`/`);return n>=0&&(t=t.slice(0,n)),t.endsWith(`.`)&&(t=t.slice(0,-1)),t}function Be(e){return/^\d{1,3}(?:\.\d{1,3}){3}$/.test(e)?e.split(`.`).every(e=>Number(e)<=255):!e.includes(`:`)||!/^[0-9a-f:]+$/.test(e)||e.split(`::`).length>2?!1:e.split(`:`).filter(e=>e.length>0).length>=1}function Ve(e){if(e===`localhost`)return!0;if(e.length>253||e.includes(`:`))return!1;let t=e.split(`.`);return t.length<2?!1:t.every((e,n)=>!(e.length===0||e.length>63||!/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(e)||n===t.length-1&&!/^[a-z]{2,63}$/.test(e)))}function He(e){let t=[],n=new Map;for(let r of e){let e=r.indexOf(`:`),i=e<=0?r:r.slice(0,e),a=e<=0?r:r.slice(e+1),o=n.get(i);if(o){o.push({scope:r,action:a});continue}t.push(i),n.set(i,[{scope:r,action:a}])}return t.map(e=>({group:e,items:n.get(e)??[]}))}var Q=n(),Ue=`GET /secure
|
|
2
2
|
Authorization: Bearer <secret>`,We=`{ "ok": true }`;function Ge({keyRow:e,blast:t,now:n,leading:r,onEdit:a,onRefresh:s,onRevoke:c,onRotate:l,rotatePending:u}){let d=e.revokedAt!==null,f=e.expiresAt!==null&&e.expiresAt<=n,p=t?.lastUsedAt??e.lastUsedAt,m=t?.callVolume??0,h=Te(e.expiresAt,n),g=we(p,n),_=e.rateLimit?`${e.rateLimit.max} / ${e.rateLimit.per}`:`none`,v=(0,Y.useMemo)(()=>He(e.scopes),[e.scopes]),y=e.creatorScopes.length,b=y>0&&e.scopes.length<y;return(0,Q.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col overflow-y-auto`,"data-slot":`access-detail`,"aria-label":`Access key detail`,"aria-live":`polite`,children:[(0,Q.jsx)(xe,{dataSlot:`access-detail-header`,leading:r,icon:(0,Q.jsx)(i,{icon:oe,className:`size-4`}),title:e.name,badge:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(`span`,{className:`inline-flex items-center gap-1 font-mono text-[10px] font-medium tracking-[0.08em] text-muted-foreground uppercase`,children:[(0,Q.jsx)(i,{icon:e.plane===`operator`?Ce:fe,className:`size-3`,"aria-hidden":!0}),e.plane]}),d?(0,Q.jsx)(`span`,{className:`font-mono text-[10px] text-destructive`,children:`revoked`}):null,f&&!d?(0,Q.jsx)(`span`,{className:`font-mono text-[10px] text-amber-700 dark:text-amber-400`,children:`expired`}):null,e.unused90d&&!d&&!f?(0,Q.jsx)(`span`,{className:`font-mono text-[10px] text-amber-700 dark:text-amber-400`,children:`unused`}):null]}),subtitle:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(`code`,{className:`min-w-0 truncate font-mono text-[11px] leading-none text-foreground/80`,children:e.id}),(0,Q.jsx)(J,{value:e.id,label:`Copy ${e.id}`})]}),actions:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(U,{label:`Rename or re-attenuate scopes`,className:`flex self-stretch`,children:(0,Q.jsx)(V,{type:`button`,variant:`ghost`,size:`sm`,className:`h-full rounded-none`,disabled:d,onClick:a,children:`Edit`})}),(0,Q.jsx)(U,{label:`Reset expiry from now. The secret stays the same.`,className:`flex self-stretch`,children:(0,Q.jsx)(V,{type:`button`,variant:`ghost`,size:`sm`,className:`h-full rounded-none`,"data-slot":`access-refresh`,disabled:d,onClick:s,children:`Refresh`})}),(0,Q.jsx)(U,{label:`Mint a new secret. The current secret stops working after residual TTL.`,className:`flex self-stretch`,children:(0,Q.jsx)(V,{type:`button`,variant:`ghost`,size:`sm`,className:`h-full rounded-none`,disabled:u||d,onClick:l,children:`Rotate`})}),(0,Q.jsx)(U,{label:`Irreversible. Residual sessions may continue for the access TTL.`,className:`flex self-stretch`,children:(0,Q.jsx)(V,{type:`button`,variant:`destructive`,size:`sm`,className:`h-full rounded-none`,disabled:d,onClick:c,children:`Revoke`})})]})}),(0,Q.jsx)(Ke,{revoked:d,expired:f,unused:e.unused90d,residual:t?.residualAccessNote}),(0,Q.jsxs)(`div`,{className:z,"data-slot":`access-briefing`,role:`group`,"aria-label":`Usage`,children:[(0,Q.jsx)(Xe,{label:`calls`,value:String(m)}),(0,Q.jsx)(Xe,{label:`used`,value:g,hint:p?new Date(p).toISOString():`No recorded call`,warn:p==null&&!d}),(0,Q.jsx)(Xe,{label:`expires`,value:h,hint:e.expiresAt?new Date(e.expiresAt).toISOString():`No expiry`,warn:f&&!d}),(0,Q.jsx)(Xe,{label:`rate`,value:_})]}),(0,Q.jsxs)(`section`,{className:`shrink-0 border-b border-border/60`,"aria-label":`Scopes`,children:[(0,Q.jsx)($,{title:`Scopes`,meta:b?`${e.scopes.length} of ${y}`:String(e.scopes.length),children:e.scopes.length>0?(0,Q.jsx)(J,{value:e.scopes.join(`
|
|
3
3
|
`),label:`Copy scopes`}):null}),v.length===0?(0,Q.jsx)(`p`,{className:`px-2 py-1.5 text-[11px] text-muted-foreground`,children:`No scopes granted.`}):(0,Q.jsx)(`ul`,{"data-slot":`access-scopes`,children:v.map(e=>(0,Q.jsxs)(`li`,{className:A,"aria-label":e.group,children:[(0,Q.jsx)(`span`,{className:o(B,`w-[5.5rem] shrink-0`),children:e.group}),(0,Q.jsx)(`div`,{className:`flex min-w-0 flex-1 flex-wrap items-center gap-x-2`,children:e.items.map(e=>(0,Q.jsx)(`span`,{title:e.scope,className:`font-mono text-[11px] text-foreground`,children:e.action},e.scope))}),(0,Q.jsx)(Ze,{value:e.items.map(e=>e.scope).join(`
|
|
4
|
-
`),label:`Copy ${e.group} scopes`})]},e.group))})]}),(0,Q.jsxs)(`section`,{className:`shrink-0 border-b border-border/60`,"aria-label":`Key`,children:[(0,Q.jsx)($,{title:`Key`}),(0,Q.jsxs)(`dl`,{"data-slot":`access-key-facts`,children:[(0,Q.jsx)(Qe,{label:`Issuer`,value:e.creatorId,copy:e.creatorId,copyLabel:`Copy ${e.creatorId}`}),(0,Q.jsx)(Qe,{label:`Created`,value:we(e.createdAt,n),hint:new Date(e.createdAt).toISOString()}),(0,Q.jsx)(Qe,{label:`Expires`,value:h,hint:e.expiresAt?new Date(e.expiresAt).toISOString():void 0,warn:f&&!d}),(0,Q.jsx)(Qe,{label:`Rate`,value:_})]})]}),(0,Q.jsx)(qe,{entries:e.ipAllowlist}),(0,Q.jsx)(Je,{sourceAddresses:t?.sourceAddresses??[],residual:t?.residualAccessNote,lastUsed:p,now:n}),(0,Q.jsx)(Ye,{scopes:e.scopes})]})}function Ke({revoked:e,expired:t,unused:n,residual:r}){return e?(0,Q.jsx)(`section`,{className:o(z,`border-destructive/25 bg-destructive/5`),"aria-label":`Revoked`,role:`status`,children:(0,Q.jsxs)(`p`,{className:`flex min-w-0 flex-1 items-center px-2 text-[12px] text-destructive`,children:[`Revoked`,(0,Q.jsxs)(`span`,{className:`text-muted-foreground`,children:[` `,`· `,r??`This secret no longer authenticates.`]})]})}):t?(0,Q.jsx)(`section`,{className:o(z,`border-amber-500/25 bg-amber-500/5`),"aria-label":`Expired`,role:`status`,children:(0,Q.jsxs)(`p`,{className:`flex min-w-0 flex-1 items-center px-2 text-[12px] text-amber-900 dark:text-amber-300`,children:[`Expired`,r?(0,Q.jsxs)(`span`,{className:`text-muted-foreground`,children:[` · `,r]}):null]})}):n?(0,Q.jsx)(`section`,{className:o(z,`border-amber-500/25 bg-amber-500/5`),"aria-label":`Unused`,role:`status`,children:(0,Q.jsxs)(`p`,{className:`flex min-w-0 flex-1 items-center px-2 text-[12px] text-amber-900 dark:text-amber-300`,children:[`No calls in 90 days`,(0,Q.jsx)(`span`,{className:`text-muted-foreground`,children:` · rotate or revoke`})]})}):null}function qe({entries:e}){return(0,Q.jsxs)(`section`,{className:`shrink-0 border-b border-border/60`,"aria-label":`Allow`,children:[(0,Q.jsx)($,{title:`Allow`,meta:e.length>0?String(e.length):`any`}),e.length===0?(0,Q.jsx)(`p`,{className:`px-2 py-1.5 text-[11px] text-muted-foreground`,children:`Any origin.`}):(0,Q.jsx)(`ul`,{"data-slot":`access-allow`,children:e.map(e=>{let t=Le(e);return(0,Q.jsxs)(`li`,{className:A,children:[(0,Q.jsx)(`span`,{className:o(B,`w-[5.5rem] shrink-0`),children:t===`ip`?`IP`:t===`host`?`Host`:`—`}),(0,Q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-[11px]`,children:e}),(0,Q.jsx)(Ze,{value:e,label:`Copy ${e}`})]},e)})})]})}function Je({sourceAddresses:e,residual:t,lastUsed:n,now:r}){return(0,Q.jsxs)(`section`,{className:`shrink-0 border-b border-border/60`,"aria-label":`Usage`,children:[(0,Q.jsx)($,{title:`Usage`,meta:n?we(n,r):`never`}),e.length===0?(0,Q.jsx)(`p`,{className:`px-2 py-1.5 text-[11px] text-muted-foreground`,children:`No observed source IPs.`}):(0,Q.jsx)(`ul`,{"data-slot":`access-sources`,children:e.map(e=>(0,Q.jsxs)(`li`,{className:A,children:[(0,Q.jsx)(`span`,{className:o(B,`w-[5.5rem] shrink-0`),children:`IP`}),(0,Q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-[11px]`,children:e}),(0,Q.jsx)(Ze,{value:e,label:`Copy ${e}`})]},e))}),t?(0,Q.jsx)(`p`,{className:`border-t border-border/60 px-2 py-1.5 text-[11px] text-muted-foreground`,children:t}):null]})}function Ye({scopes:e}){return(0,Q.jsxs)(`section`,{"data-slot":`access-call-example`,children:[(0,Q.jsx)($,{title:`Request`,children:(0,Q.jsx)(J,{value:Ue,label:`Copy request`})}),(0,Q.jsxs)(`div`,{className:`flex min-w-0 border-b border-border/60`,children:[(0,Q.jsx)(`div`,{className:o(`w-1 shrink-0 self-stretch`,ne(`GET`)),"aria-hidden":!0}),(0,Q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2 px-2.5 py-2`,children:[(0,Q.jsx)(`span`,{className:o(`shrink-0 font-mono text-[10px] font-semibold tracking-[0.08em] uppercase`,_(re(`GET`))),children:`GET`}),(0,Q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-xs text-foreground select-all`,children:`/secure`})]}),(0,Q.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2 border-t border-border/60 px-2.5 py-2`,children:[(0,Q.jsx)(`span`,{className:`w-[7.5rem] shrink-0 truncate font-mono text-[11px] font-medium text-sky-600 dark:text-sky-400`,children:`Authorization`}),(0,Q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-[11px] text-muted-foreground`,children:`Bearer <secret>`})]})]})]}),(0,Q.jsx)($,{title:`Response`,children:(0,Q.jsx)(J,{value:We,label:`Copy response`})}),(0,Q.jsxs)(`div`,{className:`flex min-w-0 border-b border-border/60`,children:[(0,Q.jsx)(`div`,{className:`w-1 shrink-0 self-stretch bg-emerald-500`,"aria-hidden":!0}),(0,Q.jsx)(`p`,{className:`min-w-0 flex-1 px-2.5 py-2 font-mono text-[11px] text-foreground/80 select-all`,children:We})]}),(0,Q.jsxs)(`p`,{className:`px-2 py-1.5 text-[11px] text-muted-foreground`,children:[`Seed the Bearer secret from create / rotate. The key is the issuer; gates see`,` `,e.join(`, `)||`its scopes`,`.`]})]})}function $({title:e,meta:t,children:n}){return(0,Q.jsxs)(`header`,{className:o(z,`items-center gap-2 px-2`),children:[(0,Q.jsx)(`h3`,{className:o(B,`shrink-0 leading-none`),children:e}),t?(0,Q.jsx)(`span`,{className:o(x,!n&&`ml-auto`),children:t}):null,n?(0,Q.jsx)(`div`,{className:`ml-auto flex items-center`,children:n}):null]})}function Xe({label:e,value:t,hint:n,warn:r=!1}){return(0,Q.jsxs)(`span`,{title:n,className:o(S,H,`gap-1.5`),children:[(0,Q.jsx)(`span`,{className:`tracking-[0.08em] uppercase`,children:e}),(0,Q.jsx)(`span`,{className:o(`font-mono tabular-nums text-foreground`,r&&`text-amber-800 dark:text-amber-400`),children:t})]})}function Ze({value:e,label:t}){return(0,Q.jsx)(`div`,{className:`opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100`,children:(0,Q.jsx)(J,{value:e,label:t})})}function Qe({label:e,value:t,hint:n,copy:r,copyLabel:i,warn:a=!1}){return(0,Q.jsxs)(`div`,{className:A,children:[(0,Q.jsx)(`dt`,{className:o(B,`w-[5.5rem] shrink-0`),children:e}),(0,Q.jsx)(`dd`,{className:o(`min-w-0 flex-1 truncate font-mono text-[11px]`,a&&`text-amber-800 dark:text-amber-400`),title:n,children:t}),r?(0,Q.jsx)(Ze,{value:r,label:i??`Copy ${e}`}):null]})}var $e=[`console.access.list`];function et(){return y({queryKey:$e,queryFn:async()=>{let e=await c();if(e.error||!e.data)throw Error(e.error?.message??`Empty access list`);return e.data}})}function tt({rows:e,selectedKey:t,query:n,loading:r=!1,onSelect:i}){let a=e.filter(e=>e.plane===`user`),o=e.filter(e=>e.plane===`operator`);return(0,Q.jsxs)(`div`,{id:`access-list`,"data-slot":`access-list`,className:`min-h-0 flex-1 overflow-y-auto`,children:[r&&e.length===0?(0,Q.jsx)(`p`,{className:R,children:`Loading…`}):null,!r&&e.length===0&&n.trim().length>0?(0,Q.jsx)(`p`,{className:R,children:`No keys match.`}):null,(0,Q.jsx)(nt,{label:`User`,icon:fe,rows:a,selectedKey:t,onSelect:i}),(0,Q.jsx)(nt,{label:`Operator`,icon:Ce,rows:o,selectedKey:t,onSelect:i})]})}function nt(e){return(0,Q.jsxs)(`section`,{className:L,"aria-label":e.label,children:[(0,Q.jsxs)(`div`,{className:j,children:[(0,Q.jsx)(i,{icon:e.icon,className:o(k,`text-muted-foreground`),"aria-hidden":!0}),(0,Q.jsx)(`span`,{className:o(P,`flex-1`),children:e.label}),(0,Q.jsx)(`span`,{className:x,children:e.rows.length})]}),e.rows.map(t=>{let n=t.id===e.selectedKey,r=t.revokedAt!==null;return(0,Q.jsxs)(`button`,{type:`button`,"data-slot":`access-key-row`,className:o(A,n&&`bg-muted/70 text-foreground`),onClick:()=>e.onSelect(t.id),children:[(0,Q.jsx)(`span`,{className:o(N,n&&`bg-sky-500`)}),(0,Q.jsx)(i,{icon:oe,className:o(k,`text-muted-foreground`)}),(0,Q.jsx)(`span`,{className:o(`min-w-0 truncate`,r&&`text-muted-foreground line-through`),children:t.name}),r?(0,Q.jsx)(`span`,{className:`ml-auto text-[10px] text-muted-foreground`,children:`revoked`}):t.unused90d?(0,Q.jsx)(`span`,{className:`ml-auto text-[10px] text-amber-700 dark:text-amber-400`,children:`unused`}):(0,Q.jsx)(`span`,{className:o(`ml-auto tabular-nums text-[10px] text-muted-foreground`),children:t.scopes.length})]},t.id)})]})}function rt({entries:e,rateMax:t,rateCount:n,rateUnit:r,onEntries:c,onRateMax:u,onRateCount:d,onRateUnit:f}){let[p,h]=(0,Y.useState)(``),_=Re(p),v=p.trim().length>0&&_.length===0,y=()=>{if(_.length===0)return;let t=new Set(e),n=[...e];for(let e of _)t.has(e)||(t.add(e),n.push(e));c(n),h(``)};return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(`div`,{className:`border-b border-border/50`,"data-slot":`access-allow-field`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Allow`}),(0,Q.jsx)(a,{value:p,onChange:e=>h(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),y())},placeholder:`203.0.113.4 or ci.example.com`,autoComplete:`off`,"aria-label":`Add allow entry`,"aria-invalid":v,flat:!0,className:o(q,`min-w-0 flex-1 font-mono`)}),e.length>0?(0,Q.jsx)(`span`,{className:o(x,`flex h-8 items-center pr-2`),children:e.length}):null,(0,Q.jsx)(`button`,{type:`button`,className:o(w,`h-8`),"aria-label":`Add allow entry`,disabled:_.length===0,onClick:y,children:(0,Q.jsx)(i,{icon:pe,className:`size-3.5`,"aria-hidden":!0})})]}),v?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-2 text-[11px] text-destructive`,children:`Need an IP or host — 203.0.113.4, ::1, localhost, or ci.example.com.`}):e.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-2 text-[11px] text-muted-foreground`,children:`Any client. Add an IP or host.`}):(0,Q.jsx)(`div`,{role:`list`,"aria-label":`Allow list`,children:e.map(t=>{let n=Le(t);return(0,Q.jsxs)(`div`,{role:`listitem`,"data-slot":`access-allow-entry`,"data-kind":n??`invalid`,className:o(A,`last:border-b-0`),children:[(0,Q.jsx)(`span`,{className:o(B,`w-[5.5rem] shrink-0 px-1.5`,n==null&&`text-destructive`),children:n===`ip`?`IP`:n===`host`?`Host`:`Bad`}),(0,Q.jsx)(`span`,{className:o(`min-w-0 truncate font-mono text-[11px]`,n==null&&`text-destructive`),children:t}),(0,Q.jsx)(`button`,{type:`button`,className:o(I,`ml-auto opacity-0 group-hover:opacity-100 focus-visible:opacity-100`),"aria-label":`Remove ${t}`,onClick:()=>c(e.filter(e=>e!==t)),children:(0,Q.jsx)(i,{icon:D,className:`size-3`,"aria-hidden":!0})})]},t)})})]}),(0,Q.jsxs)(`div`,{className:`flex items-stretch border-b border-border/50`,"data-slot":`access-rate-field`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Rate`}),(0,Q.jsxs)(`label`,{className:`flex min-w-0 flex-1 items-stretch border-r border-border/50`,children:[(0,Q.jsx)(`span`,{className:`flex h-8 shrink-0 items-center pl-1 text-[10px] font-semibold tracking-[0.08em] text-muted-foreground uppercase`,children:`Max`}),(0,Q.jsx)(a,{value:t,onChange:e=>u(e.target.value),placeholder:`none`,inputMode:`numeric`,autoComplete:`off`,"aria-label":`Rate max`,flat:!0,className:o(q,`min-w-0 flex-1 px-2 font-mono tabular-nums`)})]}),(0,Q.jsxs)(`label`,{className:`flex min-w-0 flex-1 items-stretch`,children:[(0,Q.jsx)(`span`,{className:`flex h-8 shrink-0 items-center pl-2 text-[10px] font-semibold tracking-[0.08em] text-muted-foreground uppercase`,children:`Every`}),(0,Q.jsx)(a,{value:n,onChange:e=>d(e.target.value),placeholder:`1`,inputMode:`numeric`,autoComplete:`off`,"aria-label":`Rate window`,flat:!0,className:o(q,`min-w-0 flex-1 px-2 font-mono tabular-nums`)})]}),(0,Q.jsx)(`div`,{className:`flex h-8 shrink-0 items-stretch`,role:`group`,"aria-label":`Rate unit`,children:Ne.map(e=>(0,Q.jsxs)(s,{children:[(0,Q.jsx)(m,{render:t=>(0,Q.jsx)(`button`,{...t,type:`button`,"aria-pressed":r===e,"aria-label":Pe[e],onClick:n=>{t.onClick?.(n),f(e)},className:o(S,`h-8 px-1.5 font-mono font-semibold`,r===e?g:H),children:e})}),(0,Q.jsx)(l,{side:`bottom`,className:`text-[11px]`,children:Pe[e]})]},e))})]})]})}function it({expires:e,customExpires:t,onExpires:n,onCustomExpires:r}){return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(ve,{label:`Expires`,children:[(0,Q.jsx)(G,{active:e===`never`,onClick:()=>n(`never`),children:`never`}),(0,Q.jsx)(G,{active:e===`30d`,onClick:()=>n(`30d`),children:`30d`}),(0,Q.jsx)(G,{active:e===`90d`,onClick:()=>n(`90d`),children:`90d`}),(0,Q.jsx)(G,{active:e===`custom`,onClick:()=>n(`custom`),children:`custom`})]}),e===`custom`?(0,Q.jsx)(_e,{label:`Duration`,hint:`7d · 12h · 30m`,children:(0,Q.jsx)(a,{value:t,onChange:e=>r(e.target.value),placeholder:`7d`,autoComplete:`off`,"aria-label":`Custom expiry duration`,flat:!0,className:o(q,`font-mono`)})}):null]})}function at({value:e,placeholder:t,label:n,onChange:r}){return(0,Q.jsxs)(`label`,{className:`relative min-w-0 flex-1`,children:[(0,Q.jsx)(i,{icon:he,className:`pointer-events-none absolute top-1/2 left-3 size-3.5 -translate-y-1/2 text-muted-foreground`,"aria-hidden":!0}),(0,Q.jsx)(a,{value:e,onChange:e=>r(e.target.value),placeholder:t,"aria-label":n,autoComplete:`off`,flat:!0,className:o(ye)})]})}function ot({scopes:e,selected:t,empty:n,onChange:r}){let[i,a]=(0,Y.useState)(``),s=new Set(t),c=(0,Y.useMemo)(()=>st(e,i),[e,i]),l=(0,Y.useMemo)(()=>He(c),[c]),u=e.join(`\0`);return(0,Y.useEffect)(()=>{a(``)},[u]),(0,Q.jsxs)(`div`,{className:`border-b border-border/50`,"data-slot":`access-scope-field`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Scopes`}),e.length>0?(0,Q.jsx)(at,{value:i,placeholder:`Search scopes`,label:`Search scopes`,onChange:a}):null]}),e.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-3 text-[11px] text-muted-foreground`,children:n}):c.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-3 text-[11px] text-muted-foreground`,children:`No scopes match.`}):(0,Q.jsx)(`div`,{className:`max-h-56 overflow-y-auto`,role:`group`,"aria-label":`Scopes`,children:l.map(e=>(0,Q.jsxs)(`div`,{className:`flex items-stretch border-t border-border/50`,role:`group`,"aria-label":e.group,children:[(0,Q.jsx)(`p`,{className:`flex w-[5.5rem] shrink-0 items-center px-4 font-mono text-[10px] font-semibold tracking-[0.08em] text-muted-foreground uppercase`,children:e.group}),(0,Q.jsx)(`div`,{className:`flex min-w-0 flex-1 flex-wrap items-stretch`,children:e.items.map(e=>{let n=s.has(e.scope);return(0,Q.jsx)(`button`,{type:`button`,"aria-pressed":n,"aria-label":e.scope,"data-slot":`access-scope-chip`,title:e.scope,onClick:()=>{r(n?t.filter(t=>t!==e.scope):[...t,e.scope])},className:o(`inline-flex h-8 min-w-0 items-center px-2 font-mono text-[10px] font-semibold outline-none select-none`,`focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-inset`,n?`bg-muted text-foreground`:`text-muted-foreground hover:text-foreground`),children:e.action},e.scope)})})]},e.group))})]})}function st(e,t){let n=t.trim().toLowerCase();return n.length===0?e:e.filter(e=>e.toLowerCase().includes(n))}function ct({open:e,users:t,userScopes:n,operatorScopes:r,pending:i,error:s,onOpenChange:c,onSubmit:l}){let[u,d]=(0,Y.useState)(`user`),[f,p]=(0,Y.useState)(``),[m,h]=(0,Y.useState)(``),[g,_]=(0,Y.useState)([]),[v,y]=(0,Y.useState)(`never`),[b,x]=(0,Y.useState)(``),[S,w]=(0,Y.useState)([]),[T,ee]=(0,Y.useState)(``),[D,k]=(0,Y.useState)(``),[j,P]=(0,Y.useState)(`m`),[I,L]=(0,Y.useState)(``),R=t.find(e=>e.id===m)??null,z=(0,Y.useMemo)(()=>{let e=I.trim().toLowerCase(),n=e.length===0?t:t.filter(t=>t.name.toLowerCase().includes(e)||t.id.toLowerCase().includes(e)||t.email.toLowerCase().includes(e));return R&&!n.some(e=>e.id===R.id)?[R,...n]:n},[t,I,R]),B=(0,Y.useMemo)(()=>u===`operator`?r:R==null?[]:R.scopes.length>0?R.scopes:n,[u,n,r,R]);(0,Y.useEffect)(()=>{e||(d(`user`),p(``),h(``),_([]),y(`never`),x(``),w([]),ee(``),k(``),P(`m`),L(``))},[e]),(0,Y.useEffect)(()=>{_(e=>{let t=e.filter(e=>B.includes(e));if(t.length>0)return t;let n=B[0];return n?[n]:[]})},[B]);let V=De(b),H=Fe(T,D,j),ne=f.trim().length>0&&g.length>0&&!i&&H!==void 0&&(u===`operator`||m.length>0)&&(v!==`custom`||V>0);return(0,Q.jsx)(E,{open:e,modal:!1,disablePointerDismissal:!0,onOpenChange:c,children:(0,Q.jsxs)(M,{side:`right`,showOverlay:!1,className:`gap-0 p-0 data-[side=right]:sm:max-w-md`,"data-slot":`access-create-sheet`,children:[(0,Q.jsxs)(O,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(te,{className:`text-sm`,children:`Create API key`}),(0,Q.jsx)(F,{className:`text-[11px]`,children:u===`user`?`User-plane keys require an issuer. The key cannot exceed that user's grants.`:`Operator keys inherit the actor ceiling. Absence is impossible — only grantable scopes appear.`})]}),(0,Q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch border-b border-border/50`,"data-slot":`access-name-field`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Name`}),(0,Q.jsx)(a,{value:f,onChange:e=>p(e.target.value),placeholder:`CI deploy`,autoComplete:`off`,"aria-label":`Key name`,flat:!0,className:o(q,`min-w-0 flex-1`)})]}),(0,Q.jsxs)(ve,{label:`Plane`,children:[(0,Q.jsx)(G,{active:u===`user`,icon:fe,onClick:()=>{d(`user`)},children:`user`}),(0,Q.jsx)(G,{active:u===`operator`,icon:Ce,onClick:()=>{d(`operator`),h(``),L(``)},children:`operator`})]}),(0,Q.jsx)(it,{expires:v,customExpires:b,onExpires:y,onCustomExpires:x}),(0,Q.jsx)(rt,{entries:S,rateMax:T,rateCount:D,rateUnit:j,onEntries:w,onRateMax:ee,onRateCount:k,onRateUnit:P}),u===`user`?(0,Q.jsxs)(`div`,{className:`border-b border-border/50`,"data-slot":`access-issuer-field`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Issuer`}),t.length>0?(0,Q.jsx)(at,{value:I,placeholder:`Search users`,label:`Search users`,onChange:L}):null]}),t.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-3 text-[11px] text-muted-foreground`,children:`No users on this plane.`}):z.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-3 text-[11px] text-muted-foreground`,children:`No users match.`}):(0,Q.jsx)(`div`,{className:`max-h-56 overflow-y-auto`,children:z.map(e=>{let t=e.id===m;return(0,Q.jsxs)(`button`,{type:`button`,"data-slot":`access-creator-user`,"aria-pressed":t,className:o(A,t&&`bg-muted/70 text-foreground`),onClick:()=>h(e.id),children:[(0,Q.jsx)(`span`,{className:o(N,t&&`bg-sky-500`)}),(0,Q.jsx)(`span`,{className:`min-w-0 truncate`,children:e.name}),(0,Q.jsx)(`span`,{className:`ml-auto shrink-0 font-mono text-[10px] text-muted-foreground`,children:e.id})]},e.id)})})]}):null,(0,Q.jsx)(ot,{scopes:B,selected:g,empty:u===`user`&&m.length===0?`Select an issuer to see grantable scopes.`:u===`user`?`This user has no grants.`:`No grantable scopes on this plane.`,onChange:_}),s?(0,Q.jsx)(be,{slot:`access-create-error`,children:s}):null]}),(0,Q.jsxs)(C,{children:[(0,Q.jsx)(K,{split:!0,onClick:()=>c(!1),disabled:i,children:`Cancel`}),(0,Q.jsx)(K,{variant:`default`,disabled:!ne,"data-slot":`access-create-submit`,onClick:()=>{if(H===void 0)return;let e=Oe(v,Date.now(),b);l({plane:u,name:f.trim(),scopes:g,...u===`user`?{creatorUserId:m}:{},...e==null?{}:{expiresAt:e},...H==null?{}:{rateLimit:H},...S.length>0?{ipAllowlist:S}:{}})},children:i?`Creating…`:`Create`})]})]})})}function lt({open:e,keyRow:t,users:n,operators:r,operatorScopes:s,pending:c,error:l,now:u=Date.now(),onOpenChange:d,onSubmit:f}){let p=ke(t.expiresAt,u),[m,h]=(0,Y.useState)(t.name),[g,_]=(0,Y.useState)(t.scopes),[v,y]=(0,Y.useState)(p.choice),[b,x]=(0,Y.useState)(p.custom),[S,w]=(0,Y.useState)(t.ipAllowlist),T=Ie(t.rateLimit?.per??``),[ee,D]=(0,Y.useState)(t.rateLimit?String(t.rateLimit.max):``),[k,A]=(0,Y.useState)(T.count),[j,N]=(0,Y.useState)(T.unit);(0,Y.useEffect)(()=>{if(!e)return;let n=ke(t.expiresAt,u);h(t.name),_(t.scopes),y(n.choice),x(n.custom),w(t.ipAllowlist);let r=Ie(t.rateLimit?.per??``);D(t.rateLimit?String(t.rateLimit.max):``),A(r.count),N(r.unit)},[e,t.id]);let P=t.creatorId??``,I=(0,Y.useMemo)(()=>P.length===0?null:n.find(e=>e.id===P)??r.find(e=>e.id===P)??null,[P,r,n]),L=I?I.name.trim()||I.email.trim()||I.id:P||`Unknown`,R=(0,Y.useMemo)(()=>{let e=t.creatorScopes??[];return e.length>0?e:t.plane===`operator`?I&&I.scopes.length>0?I.scopes:s:I?.scopes??[]},[I,t.creatorScopes,t.plane,s]),z=Array.from(new Set([...R,...t.scopes])),B=De(b),V=Fe(ee,k,j),H=m.trim().length>0&&g.length>0&&!c&&V!==void 0&&(v!==`custom`||B>0);return(0,Q.jsx)(E,{open:e,modal:!1,disablePointerDismissal:!0,onOpenChange:d,children:(0,Q.jsxs)(M,{side:`right`,showOverlay:!1,className:`gap-0 p-0 data-[side=right]:sm:max-w-md`,"data-slot":`access-edit-sheet`,children:[(0,Q.jsxs)(O,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(te,{className:`text-sm`,children:`Edit key`}),(0,Q.jsx)(F,{className:`text-[11px]`,children:`Change name, expiry, allow, rate, and scopes. Issuer stays frozen.`})]}),(0,Q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch border-b border-border/50`,"data-slot":`access-name-field`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Name`}),(0,Q.jsx)(a,{value:m,onChange:e=>h(e.target.value),placeholder:`CI deploy`,autoComplete:`off`,"aria-label":`Key name`,flat:!0,className:o(q,`min-w-0 flex-1`)})]}),(0,Q.jsxs)(`div`,{className:`flex items-stretch border-b border-border/50`,"data-slot":`access-issuer-field`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Issuer`}),(0,Q.jsxs)(`p`,{className:`flex min-w-0 flex-1 items-center gap-1.5 px-4 text-[12px] text-muted-foreground`,"aria-label":`Issuer ${L}`,children:[(0,Q.jsx)(i,{icon:t.plane===`operator`?Ce:fe,className:`size-3 shrink-0`,"aria-hidden":!0}),(0,Q.jsx)(`span`,{className:`min-w-0 truncate text-foreground`,children:L})]}),P.length>0&&P!==L?(0,Q.jsx)(`span`,{className:`flex h-8 shrink-0 items-center pr-4 font-mono text-[10px] text-muted-foreground`,children:P}):null]}),(0,Q.jsx)(it,{expires:v,customExpires:b,onExpires:y,onCustomExpires:x}),(0,Q.jsx)(rt,{entries:S,rateMax:ee,rateCount:k,rateUnit:j,onEntries:w,onRateMax:D,onRateCount:A,onRateUnit:N}),(0,Q.jsx)(ot,{scopes:z,selected:g,empty:t.plane===`user`&&I==null?`Issuer is gone. Only scopes already on this key remain.`:t.plane===`user`?`This issuer has no grants.`:`No grantable scopes on this plane.`,onChange:_}),l?(0,Q.jsx)(be,{slot:`access-edit-error`,children:l}):null]}),(0,Q.jsxs)(C,{children:[(0,Q.jsx)(K,{split:!0,onClick:()=>d(!1),disabled:c,children:`Cancel`}),(0,Q.jsx)(K,{variant:`default`,disabled:!H,"data-slot":`access-edit-submit`,onClick:()=>{V!==void 0&&f({name:m.trim(),scopes:g,expiresAt:Oe(v,Date.now(),b),rateLimit:V,ipAllowlist:S})},children:c?`Saving…`:`Save`})]})]})})}function ut({open:e,keyRow:t,pending:n,error:r,now:i=Date.now(),onOpenChange:a,onSubmit:o}){let s=je(t.expiresAt,i),[c,l]=(0,Y.useState)(s.choice),[u,d]=(0,Y.useState)(s.custom);(0,Y.useEffect)(()=>{if(!e)return;let n=je(t.expiresAt,i);l(n.choice),d(n.custom)},[e,t.id]);let f=De(u);return(0,Q.jsx)(E,{open:e,modal:!1,disablePointerDismissal:!0,onOpenChange:a,children:(0,Q.jsxs)(M,{side:`right`,showOverlay:!1,className:`gap-0 p-0 data-[side=right]:sm:max-w-md`,"data-slot":`access-refresh-sheet`,children:[(0,Q.jsxs)(O,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(te,{className:`text-sm`,children:`Refresh expiry`}),(0,Q.jsx)(F,{className:`text-[11px]`,children:`Reset the deadline from now. The secret does not change.`})]}),(0,Q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,Q.jsx)(it,{expires:c,customExpires:u,onExpires:l,onCustomExpires:d}),r?(0,Q.jsx)(be,{slot:`access-refresh-error`,children:r}):null]}),(0,Q.jsxs)(C,{children:[(0,Q.jsx)(K,{split:!0,onClick:()=>a(!1),disabled:n,children:`Cancel`}),(0,Q.jsx)(K,{variant:`default`,disabled:!(!n&&(c!==`custom`||f>0)),"data-slot":`access-refresh-submit`,onClick:()=>{o(Oe(c,Date.now(),u))},children:n?`Refreshing…`:`Refresh`})]})]})})}function dt({secret:e,title:t=`New API key`,onDismiss:n}){let[r,i]=(0,Y.useState)(!1);return(0,Q.jsx)(E,{open:e!==null,onOpenChange:e=>{e||n()},children:(0,Q.jsxs)(M,{side:`right`,showOverlay:!1,className:`gap-0 p-0 data-[side=right]:sm:max-w-md`,"data-slot":`access-secret-sheet`,children:[(0,Q.jsxs)(O,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(te,{className:`text-sm`,children:t}),(0,Q.jsx)(F,{className:`text-[11px]`,children:`Shown once. Store it offline. This Console process does not keep it for you.`})]}),(0,Q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,Q.jsx)(`p`,{className:`border-b border-border/50 px-4 py-3 font-mono text-[11px] break-all`,children:e}),(0,Q.jsx)(`p`,{className:`px-4 py-3 text-[11px] text-muted-foreground`,role:`status`,children:`Copying puts the secret on the clipboard. Anyone with this device can read it until you clear it.`})]}),(0,Q.jsxs)(C,{children:[(0,Q.jsx)(K,{split:!0,disabled:!e,onClick:()=>{e&&(navigator.clipboard?.writeText(e),i(!0))},children:r?`Copied`:`Copy (clipboard warning)`}),(0,Q.jsx)(K,{variant:`destructive`,onClick:()=>{i(!1),n()},children:`I have stored this key`})]})]})})}function ft(){let e=et(),t=ee(),{query:n,selectedKey:a,action:o,setQuery:s,setSelectedKey:c,setAction:l}=me(),m=ce(),[g]=(0,Y.useState)(()=>Date.now()),[_,x]=(0,Y.useState)(null),[S,C]=(0,Y.useState)(`New API key`),E=(0,Y.useMemo)(()=>{let t=e.data?.userPlane.keys??[],n=e.data?.operatorPlane.keys??[];return[...t,...n]},[e.data]),D=(0,Y.useMemo)(()=>{let e=n.trim().toLowerCase();return e?E.filter(t=>t.name.toLowerCase().includes(e)||t.id.toLowerCase().includes(e)||t.scopes.some(t=>t.toLowerCase().includes(e))):E},[E,n]),O=D.find(e=>e.id===a)??E.find(e=>e.id===a),k=y({queryKey:[`console.access.blast`,O?.id],queryFn:async()=>{if(!O)throw Error(`no key`);let e=await p(O.id);if(e.error||!e.data)throw Error(e.error?.message??`blast failed`);return e.data},enabled:O!==void 0});(0,Y.useEffect)(()=>{let e=e=>{if(e.key!==`/`||e.metaKey||e.ctrlKey||e.altKey)return;let t=e.target;if(t instanceof HTMLElement){let e=t.tagName;if(e===`INPUT`||e===`TEXTAREA`||t.isContentEditable)return}e.preventDefault(),document.querySelector(`[data-slot='access-search-input']`)?.focus()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[]);let A=()=>{t.invalidateQueries({queryKey:$e})},j=W({mutationFn:f,onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?v(e.error):`create failed`);C(`New API key`),x(e.data.secret),c(e.data.key.id),l(null),A()}}),M=W({mutationFn:e=>d({keyId:O.id,confirmation:e.confirmation,reason:e.reason}),onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?v(e.error):`rotate failed`);C(`Rotated API key`),x(e.data.secret),l(null),A()}}),N=W({mutationFn:e=>u({keyId:O.id,confirmation:e.confirmation,reason:e.reason}),onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?v(e.error):`revoke failed`);l(null),A()}}),P=W({mutationFn:h,onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?v(e.error):`update failed`);l(null),A()}}),F=W({mutationFn:e=>h({keyId:O.id,expiresAt:e}),onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?v(e.error):`refresh failed`);l(null),A()}}),I=(0,Q.jsx)(le,{open:m.open,onToggle:m.toggle,noun:`keys`,controlsId:`access-list`,dataSlot:`access-list-toggle`});return(0,Q.jsxs)(`div`,{className:T,"data-slot":`access-page`,children:[(0,Q.jsxs)(ie,{orientation:`horizontal`,className:`min-h-0 flex-1`,children:[(0,Q.jsx)(se,{panelRef:m.panelRef,collapsible:!0,collapsedSize:0,defaultSize:b.start.defaultSize,minSize:b.start.minSize,onResize:m.onResize,className:`min-h-0 overflow-hidden`,children:(0,Q.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col overflow-hidden`,children:[(0,Q.jsxs)(`div`,{className:r,children:[(0,Q.jsx)(ae,{"data-slot":`access-search-input`,placeholder:`Search keys`,"aria-label":`Search keys`,value:n,onChange:e=>s(e.target.value)}),(0,Q.jsx)(U,{label:`Create key`,className:`flex self-stretch`,children:(0,Q.jsx)(`button`,{type:`button`,className:w,"data-slot":`access-create`,"aria-label":`Create key`,onClick:()=>l(`create`),children:(0,Q.jsx)(i,{icon:pe,className:`size-3.5`})})})]}),(0,Q.jsx)(tt,{rows:D,selectedKey:a,query:n,loading:e.isLoading,onSelect:c})]})}),m.open?(0,Q.jsx)(ue,{withHandle:!0}):null,(0,Q.jsx)(se,{defaultSize:b.end.defaultSize,minSize:b.end.minSize,className:`min-h-0 overflow-hidden`,children:O?(0,Q.jsx)(Ge,{keyRow:O,blast:k.data,now:g,leading:I,onEdit:()=>l(`edit`),onRefresh:()=>l(`refresh`),onRevoke:()=>l(`revoke`),onRotate:()=>l(`rotate`),rotatePending:M.isPending}):(0,Q.jsx)(ge,{icon:de.gate.icon,iconClassName:`border-border/70`,title:e.isLoading?`Loading keys…`:E.length>0?`Select a key`:`No keys yet`,leading:I,description:e.isLoading?`Reading planes and grantable scopes.`:E.length>0&&n.trim().length>0?(0,Q.jsxs)(Q.Fragment,{children:[`Nothing matches `,(0,Q.jsx)(`span`,{className:`font-mono`,children:n}),`.`,` `,(0,Q.jsx)(`button`,{type:`button`,className:`underline underline-offset-2 hover:text-foreground`,onClick:()=>s(``),children:`Clear search`})]}):`Create one to mint a secret once.`})})]}),(0,Q.jsx)(ct,{open:o===`create`,users:e.data?.userPlane.users??[],userScopes:e.data?.userPlane.grantableScopes??[],operatorScopes:e.data?.operatorPlane.grantableScopes??[],pending:j.isPending,error:j.error instanceof Error?j.error.message:null,onOpenChange:e=>{e||l(null)},onSubmit:e=>j.mutate(e)}),O?(0,Q.jsx)(lt,{open:o===`edit`,keyRow:O,users:e.data?.userPlane.users??[],operators:e.data?.operatorPlane.operators??[],operatorScopes:e.data?.operatorPlane.grantableScopes??[],pending:P.isPending,error:P.error instanceof Error?P.error.message:null,onOpenChange:e=>{e||l(null)},onSubmit:e=>P.mutate({keyId:O.id,...e})}):null,O?(0,Q.jsx)(ut,{open:o===`refresh`,keyRow:O,pending:F.isPending,error:F.error instanceof Error?F.error.message:null,onOpenChange:e=>{e||l(null)},onSubmit:e=>F.mutate(e)}):null,O?(0,Q.jsx)(Se,{open:o===`revoke`,onOpenChange:e=>{e||l(null)},phrase:`REVOKE`,title:`Revoke ${O.name}`,description:`Irreversible. Residual sessions may continue for the access TTL.`,pending:N.isPending,error:N.error instanceof Error?N.error.message:null,confirmLabel:`Revoke key`,slot:`access-revoke-sheet`,onConfirm:e=>N.mutate({confirmation:`REVOKE`,reason:e.reason})}):null,O?(0,Q.jsx)(Se,{open:o===`rotate`,onOpenChange:e=>{e||l(null)},phrase:`ROTATE`,title:`Rotate ${O.name}`,description:`Mints a new secret once. The current secret stops after residual TTL.`,pending:M.isPending,error:M.error instanceof Error?M.error.message:null,confirmLabel:`Rotate key`,confirmVariant:`ghost`,slot:`access-rotate-sheet`,onConfirm:e=>M.mutate({confirmation:`ROTATE`,reason:e.reason})}):null,(0,Q.jsx)(dt,{secret:_,title:S,onDismiss:()=>x(null)})]})}export{ft as AccessPage};
|
|
4
|
+
`),label:`Copy ${e.group} scopes`})]},e.group))})]}),(0,Q.jsxs)(`section`,{className:`shrink-0 border-b border-border/60`,"aria-label":`Key`,children:[(0,Q.jsx)($,{title:`Key`}),(0,Q.jsxs)(`dl`,{"data-slot":`access-key-facts`,children:[(0,Q.jsx)(Qe,{label:`Issuer`,value:e.creatorId,copy:e.creatorId,copyLabel:`Copy ${e.creatorId}`}),(0,Q.jsx)(Qe,{label:`Created`,value:we(e.createdAt,n),hint:new Date(e.createdAt).toISOString()}),(0,Q.jsx)(Qe,{label:`Expires`,value:h,hint:e.expiresAt?new Date(e.expiresAt).toISOString():void 0,warn:f&&!d}),(0,Q.jsx)(Qe,{label:`Rate`,value:_})]})]}),(0,Q.jsx)(qe,{entries:e.ipAllowlist}),(0,Q.jsx)(Je,{sourceAddresses:t?.sourceAddresses??[],residual:t?.residualAccessNote,lastUsed:p,now:n}),(0,Q.jsx)(Ye,{scopes:e.scopes})]})}function Ke({revoked:e,expired:t,unused:n,residual:r}){return e?(0,Q.jsx)(`section`,{className:o(z,`border-destructive/25 bg-destructive/5`),"aria-label":`Revoked`,role:`status`,children:(0,Q.jsxs)(`p`,{className:`flex min-w-0 flex-1 items-center px-2 text-[12px] text-destructive`,children:[`Revoked`,(0,Q.jsxs)(`span`,{className:`text-muted-foreground`,children:[` `,`· `,r??`This secret no longer authenticates.`]})]})}):t?(0,Q.jsx)(`section`,{className:o(z,`border-amber-500/25 bg-amber-500/5`),"aria-label":`Expired`,role:`status`,children:(0,Q.jsxs)(`p`,{className:`flex min-w-0 flex-1 items-center px-2 text-[12px] text-amber-900 dark:text-amber-300`,children:[`Expired`,r?(0,Q.jsxs)(`span`,{className:`text-muted-foreground`,children:[` · `,r]}):null]})}):n?(0,Q.jsx)(`section`,{className:o(z,`border-amber-500/25 bg-amber-500/5`),"aria-label":`Unused`,role:`status`,children:(0,Q.jsxs)(`p`,{className:`flex min-w-0 flex-1 items-center px-2 text-[12px] text-amber-900 dark:text-amber-300`,children:[`No calls in 90 days`,(0,Q.jsx)(`span`,{className:`text-muted-foreground`,children:` · rotate or revoke`})]})}):null}function qe({entries:e}){return(0,Q.jsxs)(`section`,{className:`shrink-0 border-b border-border/60`,"aria-label":`Allow`,children:[(0,Q.jsx)($,{title:`Allow`,meta:e.length>0?String(e.length):`any`}),e.length===0?(0,Q.jsx)(`p`,{className:`px-2 py-1.5 text-[11px] text-muted-foreground`,children:`Any origin.`}):(0,Q.jsx)(`ul`,{"data-slot":`access-allow`,children:e.map(e=>{let t=Le(e);return(0,Q.jsxs)(`li`,{className:A,children:[(0,Q.jsx)(`span`,{className:o(B,`w-[5.5rem] shrink-0`),children:t===`ip`?`IP`:t===`host`?`Host`:`—`}),(0,Q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-[11px]`,children:e}),(0,Q.jsx)(Ze,{value:e,label:`Copy ${e}`})]},e)})})]})}function Je({sourceAddresses:e,residual:t,lastUsed:n,now:r}){return(0,Q.jsxs)(`section`,{className:`shrink-0 border-b border-border/60`,"aria-label":`Usage`,children:[(0,Q.jsx)($,{title:`Usage`,meta:n?we(n,r):`never`}),e.length===0?(0,Q.jsx)(`p`,{className:`px-2 py-1.5 text-[11px] text-muted-foreground`,children:`No observed source IPs.`}):(0,Q.jsx)(`ul`,{"data-slot":`access-sources`,children:e.map(e=>(0,Q.jsxs)(`li`,{className:A,children:[(0,Q.jsx)(`span`,{className:o(B,`w-[5.5rem] shrink-0`),children:`IP`}),(0,Q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-[11px]`,children:e}),(0,Q.jsx)(Ze,{value:e,label:`Copy ${e}`})]},e))}),t?(0,Q.jsx)(`p`,{className:`border-t border-border/60 px-2 py-1.5 text-[11px] text-muted-foreground`,children:t}):null]})}function Ye({scopes:e}){return(0,Q.jsxs)(`section`,{"data-slot":`access-call-example`,children:[(0,Q.jsx)($,{title:`Request`,children:(0,Q.jsx)(J,{value:Ue,label:`Copy request`})}),(0,Q.jsxs)(`div`,{className:`flex min-w-0 border-b border-border/60`,children:[(0,Q.jsx)(`div`,{className:o(`w-1 shrink-0 self-stretch`,ne(`GET`)),"aria-hidden":!0}),(0,Q.jsxs)(`div`,{className:`min-w-0 flex-1`,children:[(0,Q.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2 px-2.5 py-2`,children:[(0,Q.jsx)(`span`,{className:o(`shrink-0 font-mono text-[10px] font-semibold tracking-[0.08em] uppercase`,_(re(`GET`))),children:`GET`}),(0,Q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-xs text-foreground select-all`,children:`/secure`})]}),(0,Q.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2 border-t border-border/60 px-2.5 py-2`,children:[(0,Q.jsx)(`span`,{className:`w-[7.5rem] shrink-0 truncate font-mono text-[11px] font-medium text-sky-600 dark:text-sky-400`,children:`Authorization`}),(0,Q.jsx)(`span`,{className:`min-w-0 flex-1 truncate font-mono text-[11px] text-muted-foreground`,children:`Bearer <secret>`})]})]})]}),(0,Q.jsx)($,{title:`Response`,children:(0,Q.jsx)(J,{value:We,label:`Copy response`})}),(0,Q.jsxs)(`div`,{className:`flex min-w-0 border-b border-border/60`,children:[(0,Q.jsx)(`div`,{className:`w-1 shrink-0 self-stretch bg-emerald-500`,"aria-hidden":!0}),(0,Q.jsx)(`p`,{className:`min-w-0 flex-1 px-2.5 py-2 font-mono text-[11px] text-foreground/80 select-all`,children:We})]}),(0,Q.jsxs)(`p`,{className:`px-2 py-1.5 text-[11px] text-muted-foreground`,children:[`Seed the Bearer secret from create / rotate. The key is the issuer; gates see`,` `,e.join(`, `)||`its scopes`,`.`]})]})}function $({title:e,meta:t,children:n}){return(0,Q.jsxs)(`header`,{className:o(z,`items-center gap-2 px-2`),children:[(0,Q.jsx)(`h3`,{className:o(B,`shrink-0 leading-none`),children:e}),t?(0,Q.jsx)(`span`,{className:o(S,!n&&`ml-auto`),children:t}):null,n?(0,Q.jsx)(`div`,{className:`ml-auto flex items-center`,children:n}):null]})}function Xe({label:e,value:t,hint:n,warn:r=!1}){return(0,Q.jsxs)(`span`,{title:n,className:o(C,H,`gap-1.5`),children:[(0,Q.jsx)(`span`,{className:`tracking-[0.08em] uppercase`,children:e}),(0,Q.jsx)(`span`,{className:o(`font-mono tabular-nums text-foreground`,r&&`text-amber-800 dark:text-amber-400`),children:t})]})}function Ze({value:e,label:t}){return(0,Q.jsx)(`div`,{className:`opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100`,children:(0,Q.jsx)(J,{value:e,label:t})})}function Qe({label:e,value:t,hint:n,copy:r,copyLabel:i,warn:a=!1}){return(0,Q.jsxs)(`div`,{className:A,children:[(0,Q.jsx)(`dt`,{className:o(B,`w-[5.5rem] shrink-0`),children:e}),(0,Q.jsx)(`dd`,{className:o(`min-w-0 flex-1 truncate font-mono text-[11px]`,a&&`text-amber-800 dark:text-amber-400`),title:n,children:t}),r?(0,Q.jsx)(Ze,{value:r,label:i??`Copy ${e}`}):null]})}var $e=[`console.access.list`];function et(){return y({queryKey:$e,queryFn:async()=>{let e=await c();if(e.error||!e.data)throw Error(e.error?.message??`Empty access list`);return e.data}})}function tt({rows:e,selectedKey:t,query:n,loading:r=!1,onSelect:i}){let a=e.filter(e=>e.plane===`user`),o=e.filter(e=>e.plane===`operator`);return(0,Q.jsxs)(`div`,{id:`access-list`,"data-slot":`access-list`,className:`min-h-0 flex-1 overflow-y-auto`,children:[r&&e.length===0?(0,Q.jsx)(`p`,{className:R,children:`Loading…`}):null,!r&&e.length===0&&n.trim().length>0?(0,Q.jsx)(`p`,{className:R,children:`No keys match.`}):null,(0,Q.jsx)(nt,{label:`User`,icon:fe,rows:a,selectedKey:t,onSelect:i}),(0,Q.jsx)(nt,{label:`Operator`,icon:Ce,rows:o,selectedKey:t,onSelect:i})]})}function nt(e){return(0,Q.jsxs)(`section`,{className:L,"aria-label":e.label,children:[(0,Q.jsxs)(`div`,{className:j,children:[(0,Q.jsx)(i,{icon:e.icon,className:o(k,`text-muted-foreground`),"aria-hidden":!0}),(0,Q.jsx)(`span`,{className:o(P,`flex-1`),children:e.label}),(0,Q.jsx)(`span`,{className:S,children:e.rows.length})]}),e.rows.map(t=>{let n=t.id===e.selectedKey,r=t.revokedAt!==null;return(0,Q.jsxs)(`button`,{type:`button`,"data-slot":`access-key-row`,className:o(A,n&&`bg-muted/70 text-foreground`),onClick:()=>e.onSelect(t.id),children:[(0,Q.jsx)(`span`,{className:o(N,n&&`bg-sky-500`)}),(0,Q.jsx)(i,{icon:oe,className:o(k,`text-muted-foreground`)}),(0,Q.jsx)(`span`,{className:o(`min-w-0 truncate`,r&&`text-muted-foreground line-through`),children:t.name}),r?(0,Q.jsx)(`span`,{className:`ml-auto text-[10px] text-muted-foreground`,children:`revoked`}):t.unused90d?(0,Q.jsx)(`span`,{className:`ml-auto text-[10px] text-amber-700 dark:text-amber-400`,children:`unused`}):(0,Q.jsx)(`span`,{className:o(`ml-auto tabular-nums text-[10px] text-muted-foreground`),children:t.scopes.length})]},t.id)})]})}function rt({entries:e,rateMax:t,rateCount:n,rateUnit:r,onEntries:c,onRateMax:u,onRateCount:d,onRateUnit:f}){let[p,h]=(0,Y.useState)(``),_=Re(p),v=p.trim().length>0&&_.length===0,y=()=>{if(_.length===0)return;let t=new Set(e),n=[...e];for(let e of _)t.has(e)||(t.add(e),n.push(e));c(n),h(``)};return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(`div`,{className:`border-b border-border/50`,"data-slot":`access-allow-field`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Allow`}),(0,Q.jsx)(a,{value:p,onChange:e=>h(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),y())},placeholder:`203.0.113.4 or ci.example.com`,autoComplete:`off`,"aria-label":`Add allow entry`,"aria-invalid":v,flat:!0,className:o(q,`min-w-0 flex-1 font-mono`)}),e.length>0?(0,Q.jsx)(`span`,{className:o(S,`flex h-8 items-center pr-2`),children:e.length}):null,(0,Q.jsx)(`button`,{type:`button`,className:o(T,`h-8`),"aria-label":`Add allow entry`,disabled:_.length===0,onClick:y,children:(0,Q.jsx)(i,{icon:pe,className:`size-3.5`,"aria-hidden":!0})})]}),v?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-2 text-[11px] text-destructive`,children:`Need an IP or host — 203.0.113.4, ::1, localhost, or ci.example.com.`}):e.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-2 text-[11px] text-muted-foreground`,children:`Any client. Add an IP or host.`}):(0,Q.jsx)(`div`,{role:`list`,"aria-label":`Allow list`,children:e.map(t=>{let n=Le(t);return(0,Q.jsxs)(`div`,{role:`listitem`,"data-slot":`access-allow-entry`,"data-kind":n??`invalid`,className:o(A,`last:border-b-0`),children:[(0,Q.jsx)(`span`,{className:o(B,`w-[5.5rem] shrink-0 px-1.5`,n==null&&`text-destructive`),children:n===`ip`?`IP`:n===`host`?`Host`:`Bad`}),(0,Q.jsx)(`span`,{className:o(`min-w-0 truncate font-mono text-[11px]`,n==null&&`text-destructive`),children:t}),(0,Q.jsx)(`button`,{type:`button`,className:o(I,`ml-auto opacity-0 group-hover:opacity-100 focus-visible:opacity-100`),"aria-label":`Remove ${t}`,onClick:()=>c(e.filter(e=>e!==t)),children:(0,Q.jsx)(i,{icon:D,className:`size-3`,"aria-hidden":!0})})]},t)})})]}),(0,Q.jsxs)(`div`,{className:`flex items-stretch border-b border-border/50`,"data-slot":`access-rate-field`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Rate`}),(0,Q.jsxs)(`label`,{className:`flex min-w-0 flex-1 items-stretch border-r border-border/50`,children:[(0,Q.jsx)(`span`,{className:`flex h-8 shrink-0 items-center pl-1 text-[10px] font-semibold tracking-[0.08em] text-muted-foreground uppercase`,children:`Max`}),(0,Q.jsx)(a,{value:t,onChange:e=>u(e.target.value),placeholder:`none`,inputMode:`numeric`,autoComplete:`off`,"aria-label":`Rate max`,flat:!0,className:o(q,`min-w-0 flex-1 px-2 font-mono tabular-nums`)})]}),(0,Q.jsxs)(`label`,{className:`flex min-w-0 flex-1 items-stretch`,children:[(0,Q.jsx)(`span`,{className:`flex h-8 shrink-0 items-center pl-2 text-[10px] font-semibold tracking-[0.08em] text-muted-foreground uppercase`,children:`Every`}),(0,Q.jsx)(a,{value:n,onChange:e=>d(e.target.value),placeholder:`1`,inputMode:`numeric`,autoComplete:`off`,"aria-label":`Rate window`,flat:!0,className:o(q,`min-w-0 flex-1 px-2 font-mono tabular-nums`)})]}),(0,Q.jsx)(`div`,{className:`flex h-8 shrink-0 items-stretch`,role:`group`,"aria-label":`Rate unit`,children:Ne.map(e=>(0,Q.jsxs)(s,{children:[(0,Q.jsx)(m,{render:t=>(0,Q.jsx)(`button`,{...t,type:`button`,"aria-pressed":r===e,"aria-label":Pe[e],onClick:n=>{t.onClick?.(n),f(e)},className:o(C,`h-8 px-1.5 font-mono font-semibold`,r===e?g:H),children:e})}),(0,Q.jsx)(l,{side:`bottom`,className:`text-[11px]`,children:Pe[e]})]},e))})]})]})}function it({expires:e,customExpires:t,onExpires:n,onCustomExpires:r}){return(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsxs)(ve,{label:`Expires`,children:[(0,Q.jsx)(G,{active:e===`never`,onClick:()=>n(`never`),children:`never`}),(0,Q.jsx)(G,{active:e===`30d`,onClick:()=>n(`30d`),children:`30d`}),(0,Q.jsx)(G,{active:e===`90d`,onClick:()=>n(`90d`),children:`90d`}),(0,Q.jsx)(G,{active:e===`custom`,onClick:()=>n(`custom`),children:`custom`})]}),e===`custom`?(0,Q.jsx)(_e,{label:`Duration`,hint:`7d · 12h · 30m`,children:(0,Q.jsx)(a,{value:t,onChange:e=>r(e.target.value),placeholder:`7d`,autoComplete:`off`,"aria-label":`Custom expiry duration`,flat:!0,className:o(q,`font-mono`)})}):null]})}function at({value:e,placeholder:t,label:n,onChange:r}){return(0,Q.jsxs)(`label`,{className:`relative min-w-0 flex-1`,children:[(0,Q.jsx)(i,{icon:me,className:`pointer-events-none absolute top-1/2 left-3 size-3.5 -translate-y-1/2 text-muted-foreground`,"aria-hidden":!0}),(0,Q.jsx)(a,{value:e,onChange:e=>r(e.target.value),placeholder:t,"aria-label":n,autoComplete:`off`,flat:!0,className:o(ye)})]})}function ot({scopes:e,selected:t,empty:n,onChange:r}){let[i,a]=(0,Y.useState)(``),s=new Set(t),c=(0,Y.useMemo)(()=>st(e,i),[e,i]),l=(0,Y.useMemo)(()=>He(c),[c]),u=e.join(`\0`);return(0,Y.useEffect)(()=>{a(``)},[u]),(0,Q.jsxs)(`div`,{className:`border-b border-border/50`,"data-slot":`access-scope-field`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Scopes`}),e.length>0?(0,Q.jsx)(at,{value:i,placeholder:`Search scopes`,label:`Search scopes`,onChange:a}):null]}),e.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-3 text-[11px] text-muted-foreground`,children:n}):c.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-3 text-[11px] text-muted-foreground`,children:`No scopes match.`}):(0,Q.jsx)(`div`,{className:`max-h-56 overflow-y-auto`,role:`group`,"aria-label":`Scopes`,children:l.map(e=>(0,Q.jsxs)(`div`,{className:`flex items-stretch border-t border-border/50`,role:`group`,"aria-label":e.group,children:[(0,Q.jsx)(`p`,{className:`flex w-[5.5rem] shrink-0 items-center px-4 font-mono text-[10px] font-semibold tracking-[0.08em] text-muted-foreground uppercase`,children:e.group}),(0,Q.jsx)(`div`,{className:`flex min-w-0 flex-1 flex-wrap items-stretch`,children:e.items.map(e=>{let n=s.has(e.scope);return(0,Q.jsx)(`button`,{type:`button`,"aria-pressed":n,"aria-label":e.scope,"data-slot":`access-scope-chip`,title:e.scope,onClick:()=>{r(n?t.filter(t=>t!==e.scope):[...t,e.scope])},className:o(`inline-flex h-8 min-w-0 items-center px-2 font-mono text-[10px] font-semibold outline-none select-none`,`focus-visible:ring-2 focus-visible:ring-ring/50 focus-visible:ring-inset`,n?`bg-muted text-foreground`:`text-muted-foreground hover:text-foreground`),children:e.action},e.scope)})})]},e.group))})]})}function st(e,t){let n=t.trim().toLowerCase();return n.length===0?e:e.filter(e=>e.toLowerCase().includes(n))}function ct({open:e,users:t,userScopes:n,operatorScopes:r,pending:i,error:s,onOpenChange:c,onSubmit:l}){let[u,d]=(0,Y.useState)(`user`),[f,p]=(0,Y.useState)(``),[m,h]=(0,Y.useState)(``),[g,_]=(0,Y.useState)([]),[v,y]=(0,Y.useState)(`never`),[b,x]=(0,Y.useState)(``),[S,C]=(0,Y.useState)([]),[T,ee]=(0,Y.useState)(``),[D,k]=(0,Y.useState)(``),[j,P]=(0,Y.useState)(`m`),[I,L]=(0,Y.useState)(``),R=t.find(e=>e.id===m)??null,z=(0,Y.useMemo)(()=>{let e=I.trim().toLowerCase(),n=e.length===0?t:t.filter(t=>t.name.toLowerCase().includes(e)||t.id.toLowerCase().includes(e)||t.email.toLowerCase().includes(e));return R&&!n.some(e=>e.id===R.id)?[R,...n]:n},[t,I,R]),B=(0,Y.useMemo)(()=>u===`operator`?r:R==null?[]:R.scopes.length>0?R.scopes:n,[u,n,r,R]);(0,Y.useEffect)(()=>{e||(d(`user`),p(``),h(``),_([]),y(`never`),x(``),C([]),ee(``),k(``),P(`m`),L(``))},[e]),(0,Y.useEffect)(()=>{_(e=>{let t=e.filter(e=>B.includes(e));if(t.length>0)return t;let n=B[0];return n?[n]:[]})},[B]);let V=De(b),H=Fe(T,D,j),ne=f.trim().length>0&&g.length>0&&!i&&H!==void 0&&(u===`operator`||m.length>0)&&(v!==`custom`||V>0);return(0,Q.jsx)(E,{open:e,modal:!1,disablePointerDismissal:!0,onOpenChange:c,children:(0,Q.jsxs)(M,{side:`right`,showOverlay:!1,className:`gap-0 p-0 data-[side=right]:sm:max-w-md`,"data-slot":`access-create-sheet`,children:[(0,Q.jsxs)(O,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(te,{className:`text-sm`,children:`Create API key`}),(0,Q.jsx)(F,{className:`text-[11px]`,children:u===`user`?`User-plane keys require an issuer. The key cannot exceed that user's grants.`:`Operator keys inherit the actor ceiling. Absence is impossible — only grantable scopes appear.`})]}),(0,Q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch border-b border-border/50`,"data-slot":`access-name-field`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Name`}),(0,Q.jsx)(a,{value:f,onChange:e=>p(e.target.value),placeholder:`CI deploy`,autoComplete:`off`,"aria-label":`Key name`,flat:!0,className:o(q,`min-w-0 flex-1`)})]}),(0,Q.jsxs)(ve,{label:`Plane`,children:[(0,Q.jsx)(G,{active:u===`user`,icon:fe,onClick:()=>{d(`user`)},children:`user`}),(0,Q.jsx)(G,{active:u===`operator`,icon:Ce,onClick:()=>{d(`operator`),h(``),L(``)},children:`operator`})]}),(0,Q.jsx)(it,{expires:v,customExpires:b,onExpires:y,onCustomExpires:x}),(0,Q.jsx)(rt,{entries:S,rateMax:T,rateCount:D,rateUnit:j,onEntries:C,onRateMax:ee,onRateCount:k,onRateUnit:P}),u===`user`?(0,Q.jsxs)(`div`,{className:`border-b border-border/50`,"data-slot":`access-issuer-field`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Issuer`}),t.length>0?(0,Q.jsx)(at,{value:I,placeholder:`Search users`,label:`Search users`,onChange:L}):null]}),t.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-3 text-[11px] text-muted-foreground`,children:`No users on this plane.`}):z.length===0?(0,Q.jsx)(`p`,{className:`border-t border-border/50 px-4 py-3 text-[11px] text-muted-foreground`,children:`No users match.`}):(0,Q.jsx)(`div`,{className:`max-h-56 overflow-y-auto`,children:z.map(e=>{let t=e.id===m;return(0,Q.jsxs)(`button`,{type:`button`,"data-slot":`access-creator-user`,"aria-pressed":t,className:o(A,t&&`bg-muted/70 text-foreground`),onClick:()=>h(e.id),children:[(0,Q.jsx)(`span`,{className:o(N,t&&`bg-sky-500`)}),(0,Q.jsx)(`span`,{className:`min-w-0 truncate`,children:e.name}),(0,Q.jsx)(`span`,{className:`ml-auto shrink-0 font-mono text-[10px] text-muted-foreground`,children:e.id})]},e.id)})})]}):null,(0,Q.jsx)(ot,{scopes:B,selected:g,empty:u===`user`&&m.length===0?`Select an issuer to see grantable scopes.`:u===`user`?`This user has no grants.`:`No grantable scopes on this plane.`,onChange:_}),s?(0,Q.jsx)(be,{slot:`access-create-error`,children:s}):null]}),(0,Q.jsxs)(w,{children:[(0,Q.jsx)(K,{split:!0,onClick:()=>c(!1),disabled:i,children:`Cancel`}),(0,Q.jsx)(K,{variant:`default`,disabled:!ne,"data-slot":`access-create-submit`,onClick:()=>{if(H===void 0)return;let e=Oe(v,Date.now(),b);l({plane:u,name:f.trim(),scopes:g,...u===`user`?{creatorUserId:m}:{},...e==null?{}:{expiresAt:e},...H==null?{}:{rateLimit:H},...S.length>0?{ipAllowlist:S}:{}})},children:i?`Creating…`:`Create`})]})]})})}function lt({open:e,keyRow:t,users:n,operators:r,operatorScopes:s,pending:c,error:l,now:u=Date.now(),onOpenChange:d,onSubmit:f}){let p=ke(t.expiresAt,u),[m,h]=(0,Y.useState)(t.name),[g,_]=(0,Y.useState)(t.scopes),[v,y]=(0,Y.useState)(p.choice),[b,x]=(0,Y.useState)(p.custom),[S,C]=(0,Y.useState)(t.ipAllowlist),T=Ie(t.rateLimit?.per??``),[ee,D]=(0,Y.useState)(t.rateLimit?String(t.rateLimit.max):``),[k,A]=(0,Y.useState)(T.count),[j,N]=(0,Y.useState)(T.unit);(0,Y.useEffect)(()=>{if(!e)return;let n=ke(t.expiresAt,u);h(t.name),_(t.scopes),y(n.choice),x(n.custom),C(t.ipAllowlist);let r=Ie(t.rateLimit?.per??``);D(t.rateLimit?String(t.rateLimit.max):``),A(r.count),N(r.unit)},[e,t.id]);let P=t.creatorId??``,I=(0,Y.useMemo)(()=>P.length===0?null:n.find(e=>e.id===P)??r.find(e=>e.id===P)??null,[P,r,n]),L=I?I.name.trim()||I.email.trim()||I.id:P||`Unknown`,R=(0,Y.useMemo)(()=>{let e=t.creatorScopes??[];return e.length>0?e:t.plane===`operator`?I&&I.scopes.length>0?I.scopes:s:I?.scopes??[]},[I,t.creatorScopes,t.plane,s]),z=Array.from(new Set([...R,...t.scopes])),B=De(b),V=Fe(ee,k,j),H=m.trim().length>0&&g.length>0&&!c&&V!==void 0&&(v!==`custom`||B>0);return(0,Q.jsx)(E,{open:e,modal:!1,disablePointerDismissal:!0,onOpenChange:d,children:(0,Q.jsxs)(M,{side:`right`,showOverlay:!1,className:`gap-0 p-0 data-[side=right]:sm:max-w-md`,"data-slot":`access-edit-sheet`,children:[(0,Q.jsxs)(O,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(te,{className:`text-sm`,children:`Edit key`}),(0,Q.jsx)(F,{className:`text-[11px]`,children:`Change name, expiry, allow, rate, and scopes. Issuer stays frozen.`})]}),(0,Q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,Q.jsxs)(`div`,{className:`flex items-stretch border-b border-border/50`,"data-slot":`access-name-field`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Name`}),(0,Q.jsx)(a,{value:m,onChange:e=>h(e.target.value),placeholder:`CI deploy`,autoComplete:`off`,"aria-label":`Key name`,flat:!0,className:o(q,`min-w-0 flex-1`)})]}),(0,Q.jsxs)(`div`,{className:`flex items-stretch border-b border-border/50`,"data-slot":`access-issuer-field`,children:[(0,Q.jsx)(`p`,{className:`flex h-8 w-[5.5rem] shrink-0 items-center px-4 text-[10px] font-semibold tracking-[0.12em] text-muted-foreground uppercase`,children:`Issuer`}),(0,Q.jsxs)(`p`,{className:`flex min-w-0 flex-1 items-center gap-1.5 px-4 text-[12px] text-muted-foreground`,"aria-label":`Issuer ${L}`,children:[(0,Q.jsx)(i,{icon:t.plane===`operator`?Ce:fe,className:`size-3 shrink-0`,"aria-hidden":!0}),(0,Q.jsx)(`span`,{className:`min-w-0 truncate text-foreground`,children:L})]}),P.length>0&&P!==L?(0,Q.jsx)(`span`,{className:`flex h-8 shrink-0 items-center pr-4 font-mono text-[10px] text-muted-foreground`,children:P}):null]}),(0,Q.jsx)(it,{expires:v,customExpires:b,onExpires:y,onCustomExpires:x}),(0,Q.jsx)(rt,{entries:S,rateMax:ee,rateCount:k,rateUnit:j,onEntries:C,onRateMax:D,onRateCount:A,onRateUnit:N}),(0,Q.jsx)(ot,{scopes:z,selected:g,empty:t.plane===`user`&&I==null?`Issuer is gone. Only scopes already on this key remain.`:t.plane===`user`?`This issuer has no grants.`:`No grantable scopes on this plane.`,onChange:_}),l?(0,Q.jsx)(be,{slot:`access-edit-error`,children:l}):null]}),(0,Q.jsxs)(w,{children:[(0,Q.jsx)(K,{split:!0,onClick:()=>d(!1),disabled:c,children:`Cancel`}),(0,Q.jsx)(K,{variant:`default`,disabled:!H,"data-slot":`access-edit-submit`,onClick:()=>{V!==void 0&&f({name:m.trim(),scopes:g,expiresAt:Oe(v,Date.now(),b),rateLimit:V,ipAllowlist:S})},children:c?`Saving…`:`Save`})]})]})})}function ut({open:e,keyRow:t,pending:n,error:r,now:i=Date.now(),onOpenChange:a,onSubmit:o}){let s=je(t.expiresAt,i),[c,l]=(0,Y.useState)(s.choice),[u,d]=(0,Y.useState)(s.custom);(0,Y.useEffect)(()=>{if(!e)return;let n=je(t.expiresAt,i);l(n.choice),d(n.custom)},[e,t.id]);let f=De(u);return(0,Q.jsx)(E,{open:e,modal:!1,disablePointerDismissal:!0,onOpenChange:a,children:(0,Q.jsxs)(M,{side:`right`,showOverlay:!1,className:`gap-0 p-0 data-[side=right]:sm:max-w-md`,"data-slot":`access-refresh-sheet`,children:[(0,Q.jsxs)(O,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(te,{className:`text-sm`,children:`Refresh expiry`}),(0,Q.jsx)(F,{className:`text-[11px]`,children:`Reset the deadline from now. The secret does not change.`})]}),(0,Q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,Q.jsx)(it,{expires:c,customExpires:u,onExpires:l,onCustomExpires:d}),r?(0,Q.jsx)(be,{slot:`access-refresh-error`,children:r}):null]}),(0,Q.jsxs)(w,{children:[(0,Q.jsx)(K,{split:!0,onClick:()=>a(!1),disabled:n,children:`Cancel`}),(0,Q.jsx)(K,{variant:`default`,disabled:!(!n&&(c!==`custom`||f>0)),"data-slot":`access-refresh-submit`,onClick:()=>{o(Oe(c,Date.now(),u))},children:n?`Refreshing…`:`Refresh`})]})]})})}function dt({secret:e,title:t=`New API key`,onDismiss:n}){let[r,i]=(0,Y.useState)(!1);return(0,Q.jsx)(E,{open:e!==null,onOpenChange:e=>{e||n()},children:(0,Q.jsxs)(M,{side:`right`,showOverlay:!1,className:`gap-0 p-0 data-[side=right]:sm:max-w-md`,"data-slot":`access-secret-sheet`,children:[(0,Q.jsxs)(O,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(te,{className:`text-sm`,children:t}),(0,Q.jsx)(F,{className:`text-[11px]`,children:`Shown once. Store it offline. This Console process does not keep it for you.`})]}),(0,Q.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col overflow-y-auto`,children:[(0,Q.jsx)(`p`,{className:`border-b border-border/50 px-4 py-3 font-mono text-[11px] break-all`,children:e}),(0,Q.jsx)(`p`,{className:`px-4 py-3 text-[11px] text-muted-foreground`,role:`status`,children:`Copying puts the secret on the clipboard. Anyone with this device can read it until you clear it.`})]}),(0,Q.jsxs)(w,{children:[(0,Q.jsx)(K,{split:!0,disabled:!e,onClick:()=>{e&&(navigator.clipboard?.writeText(e),i(!0))},children:r?`Copied`:`Copy (clipboard warning)`}),(0,Q.jsx)(K,{variant:`destructive`,onClick:()=>{i(!1),n()},children:`I have stored this key`})]})]})})}function ft(){let e=et(),t=b(),{query:n,selectedKey:a,action:o,setQuery:s,setSelectedKey:c,setAction:l}=he(),m=ce(),[g]=(0,Y.useState)(()=>Date.now()),[_,S]=(0,Y.useState)(null),[C,w]=(0,Y.useState)(`New API key`),E=(0,Y.useMemo)(()=>{let t=e.data?.userPlane.keys??[],n=e.data?.operatorPlane.keys??[];return[...t,...n]},[e.data]),D=(0,Y.useMemo)(()=>{let e=n.trim().toLowerCase();return e?E.filter(t=>t.name.toLowerCase().includes(e)||t.id.toLowerCase().includes(e)||t.scopes.some(t=>t.toLowerCase().includes(e))):E},[E,n]),O=D.find(e=>e.id===a)??E.find(e=>e.id===a),k=y({queryKey:[`console.access.blast`,O?.id],queryFn:async()=>{if(!O)throw Error(`no key`);let e=await p(O.id);if(e.error||!e.data)throw Error(e.error?.message??`blast failed`);return e.data},enabled:O!==void 0});(0,Y.useEffect)(()=>{let e=e=>{if(e.key!==`/`||e.metaKey||e.ctrlKey||e.altKey)return;let t=e.target;if(t instanceof HTMLElement){let e=t.tagName;if(e===`INPUT`||e===`TEXTAREA`||t.isContentEditable)return}e.preventDefault(),document.querySelector(`[data-slot='access-search-input']`)?.focus()};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[]);let A=()=>{t.invalidateQueries({queryKey:$e})},j=W({mutationFn:f,onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?v(e.error):`create failed`);w(`New API key`),S(e.data.secret),c(e.data.key.id),l(null),A()}}),M=W({mutationFn:e=>d({keyId:O.id,confirmation:e.confirmation,reason:e.reason}),onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?v(e.error):`rotate failed`);w(`Rotated API key`),S(e.data.secret),l(null),A()}}),N=W({mutationFn:e=>u({keyId:O.id,confirmation:e.confirmation,reason:e.reason}),onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?v(e.error):`revoke failed`);l(null),A()}}),P=W({mutationFn:h,onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?v(e.error):`update failed`);l(null),A()}}),F=W({mutationFn:e=>h({keyId:O.id,expiresAt:e}),onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?v(e.error):`refresh failed`);l(null),A()}}),I=(0,Q.jsx)(le,{open:m.open,onToggle:m.toggle,noun:`keys`,controlsId:`access-list`,dataSlot:`access-list-toggle`});return(0,Q.jsxs)(`div`,{className:ee,"data-slot":`access-page`,children:[(0,Q.jsxs)(ie,{orientation:`horizontal`,className:`min-h-0 flex-1`,children:[(0,Q.jsx)(se,{panelRef:m.panelRef,collapsible:!0,collapsedSize:0,defaultSize:x.start.defaultSize,minSize:x.start.minSize,onResize:m.onResize,className:`min-h-0 overflow-hidden`,children:(0,Q.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col overflow-hidden`,children:[(0,Q.jsxs)(`div`,{className:r,children:[(0,Q.jsx)(ae,{"data-slot":`access-search-input`,placeholder:`Search keys`,"aria-label":`Search keys`,value:n,onChange:e=>s(e.target.value)}),(0,Q.jsx)(U,{label:`Create key`,className:`flex self-stretch`,children:(0,Q.jsx)(`button`,{type:`button`,className:T,"data-slot":`access-create`,"aria-label":`Create key`,onClick:()=>l(`create`),children:(0,Q.jsx)(i,{icon:pe,className:`size-3.5`})})})]}),(0,Q.jsx)(tt,{rows:D,selectedKey:a,query:n,loading:e.isLoading,onSelect:c})]})}),m.open?(0,Q.jsx)(ue,{withHandle:!0}):null,(0,Q.jsx)(se,{defaultSize:x.end.defaultSize,minSize:x.end.minSize,className:`min-h-0 overflow-hidden`,children:O?(0,Q.jsx)(Ge,{keyRow:O,blast:k.data,now:g,leading:I,onEdit:()=>l(`edit`),onRefresh:()=>l(`refresh`),onRevoke:()=>l(`revoke`),onRotate:()=>l(`rotate`),rotatePending:M.isPending}):(0,Q.jsx)(ge,{icon:de.gate.icon,iconClassName:`border-border/70`,title:e.isLoading?`Loading keys…`:E.length>0?`Select a key`:`No keys yet`,leading:I,description:e.isLoading?`Reading planes and grantable scopes.`:E.length>0&&n.trim().length>0?(0,Q.jsxs)(Q.Fragment,{children:[`Nothing matches `,(0,Q.jsx)(`span`,{className:`font-mono`,children:n}),`.`,` `,(0,Q.jsx)(`button`,{type:`button`,className:`underline underline-offset-2 hover:text-foreground`,onClick:()=>s(``),children:`Clear search`})]}):`Create one to mint a secret once.`})})]}),(0,Q.jsx)(ct,{open:o===`create`,users:e.data?.userPlane.users??[],userScopes:e.data?.userPlane.grantableScopes??[],operatorScopes:e.data?.operatorPlane.grantableScopes??[],pending:j.isPending,error:j.error instanceof Error?j.error.message:null,onOpenChange:e=>{e||l(null)},onSubmit:e=>j.mutate(e)}),O?(0,Q.jsx)(lt,{open:o===`edit`,keyRow:O,users:e.data?.userPlane.users??[],operators:e.data?.operatorPlane.operators??[],operatorScopes:e.data?.operatorPlane.grantableScopes??[],pending:P.isPending,error:P.error instanceof Error?P.error.message:null,onOpenChange:e=>{e||l(null)},onSubmit:e=>P.mutate({keyId:O.id,...e})}):null,O?(0,Q.jsx)(ut,{open:o===`refresh`,keyRow:O,pending:F.isPending,error:F.error instanceof Error?F.error.message:null,onOpenChange:e=>{e||l(null)},onSubmit:e=>F.mutate(e)}):null,O?(0,Q.jsx)(Se,{open:o===`revoke`,onOpenChange:e=>{e||l(null)},phrase:`REVOKE`,title:`Revoke ${O.name}`,description:`Irreversible. Residual sessions may continue for the access TTL.`,pending:N.isPending,error:N.error instanceof Error?N.error.message:null,confirmLabel:`Revoke key`,slot:`access-revoke-sheet`,onConfirm:e=>N.mutate({confirmation:`REVOKE`,reason:e.reason})}):null,O?(0,Q.jsx)(Se,{open:o===`rotate`,onOpenChange:e=>{e||l(null)},phrase:`ROTATE`,title:`Rotate ${O.name}`,description:`Mints a new secret once. The current secret stops after residual TTL.`,pending:M.isPending,error:M.error instanceof Error?M.error.message:null,confirmLabel:`Rotate key`,confirmVariant:`ghost`,slot:`access-rotate-sheet`,onConfirm:e=>M.mutate({confirmation:`ROTATE`,reason:e.reason})}):null,(0,Q.jsx)(dt,{secret:_,title:C,onDismiss:()=>S(null)})]})}export{ft as AccessPage};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{A as e}from"./xyflow-yApv7D4e.js";import{Er as t}from"./shortcut-keys-CUNegEV4.js";import{c as n,l as r,st as i}from"./index-vTuwmeQz.js";var a=e();function o({open:e,openHeight:o=`auto`,className:s,style:c,transition:l,...u}){let d=r()??!1;return(0,a.jsx)(n.div,{...u,"aria-hidden":!e,inert:!e||void 0,initial:!1,animate:d?{opacity:+!!e}:{opacity:+!!e,clipPath:e?`inset(0 0 0% 0)`:`inset(0 0 100% 0)`,y:e?0:-4},transition:l??{duration:d?0:e?.22:.14,ease:i},className:t(`overflow-hidden`,s),style:{...c,height:e?o:0,pointerEvents:e?void 0:`none`,transformOrigin:`top`}})}export{o as t};
|