okengine 0.18.3 → 0.18.5
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 +5 -3
- package/README.md +5 -5
- package/package.json +2 -2
- package/site/content/docs/ai/index.mdx +25 -6
- package/site/content/docs/ai/mcp.mdx +10 -1
- package/site/content/docs/ai/skills.mdx +9 -9
- package/site/content/docs/elements/ai.mdx +1 -1
- package/site/content/docs/elements/gate.mdx +3 -2
- package/site/content/docs/elements/index.mdx +42 -11
- package/site/content/docs/elements/store.mdx +2 -0
- package/site/content/docs/get-started/basic-usage.mdx +3 -10
- package/site/content/docs/get-started/index.mdx +1 -1
- package/site/content/docs/get-started/installation.mdx +1 -1
- package/site/content/docs/get-started/introduction.mdx +69 -64
- package/site/content/docs/get-started/meta.json +1 -1
- package/site/content/docs/get-started/project-structure.mdx +4 -11
- package/site/content/docs/get-started/why.mdx +64 -114
- package/site/content/docs/index.mdx +69 -15
- package/site/content/docs/meta.json +10 -5
- package/site/content/docs/providers/index.mdx +2 -0
- package/site/content/docs/recipes/index.mdx +2 -0
- package/src/cli/competitor-mention-removal.test.ts +1 -1
- package/src/compiler/extract.test.ts +1 -1
- package/src/console/ui-next/dist/assets/{access-page-DY4N6nnk.js → access-page-3-EFj-2G.js} +1 -1
- package/src/console/ui-next/dist/assets/{flows-page-CsPDMrVM.js → flows-page-cVFnA4HH.js} +1 -1
- package/src/console/ui-next/dist/assets/{index-CcTDXHuz.js → index-CMIgUbD0.js} +3 -3
- package/src/console/ui-next/dist/assets/{observability-page-CKR595wP.js → observability-page-CQ3p34ip.js} +1 -1
- package/src/console/ui-next/dist/assets/{units-page-CpPFFKyE.js → units-page-l8FeKfnP.js} +1 -1
- package/src/console/ui-next/dist/assets/{vault-page-BsMf-9_W.js → vault-page-CL-d_mLE.js} +1 -1
- package/src/console/ui-next/dist/index.html +1 -1
- package/src/index.ts +1 -1
|
@@ -1,164 +1,114 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Why OKE
|
|
3
|
-
description:
|
|
3
|
+
description: The problem of seams across independent backend tools, the insight, and the smaller model.
|
|
4
4
|
source: docs/spec/unified-theory.md
|
|
5
5
|
icon: Compass
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
##
|
|
8
|
+
## The Problem: The Seams You Own
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Modern backends accumulate many independently adopted systems: router, queue, cron, websockets, cache, secrets, mailer, AI wrappers, and observability.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Every TypeScript backend works on day one. The bill arrives later. None of these are router problems — they are **gaps** between what your code knows and what your tooling knows.
|
|
18
|
-
|
|
19
|
-
### Cache that lies
|
|
20
|
-
|
|
21
|
-
You add a column to `orders` and update three writers. The cache key in `checkout` is not one of them. A customer finds it a week later.
|
|
12
|
+
<Callout title="A note on the count">
|
|
13
|
+
'Forty' is a representative illustration of the number of backend concerns developers commonly
|
|
14
|
+
assemble across modern stacks, not a literal census.
|
|
15
|
+
</Callout>
|
|
22
16
|
|
|
23
|
-
|
|
17
|
+
```text
|
|
18
|
+
many systems → many seams → many contracts → many mental models
|
|
19
|
+
```
|
|
24
20
|
|
|
25
|
-
|
|
21
|
+
Every TypeScript backend works on day one. The bill arrives later in the seams:
|
|
26
22
|
|
|
27
|
-
|
|
23
|
+
- **Cache that lies:** You update a writer, but forget the cache key in checkout.
|
|
24
|
+
- **Secret that fails at 2am:** Deploy boots fine; the first charge fails because the env var was missed.
|
|
25
|
+
- **Permission checks in the wrong place:** Auth logic scattered across handlers instead of verified at the trigger.
|
|
26
|
+
- **The dashboard that doesn't know you:** Observability tools learn routes from traffic samples instead of the compiled model.
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
## The Insight: One Programming Model
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
These concerns do not need to become separate programming concepts. They collapse into one closed set:
|
|
32
31
|
|
|
33
|
-
|
|
32
|
+
```text
|
|
33
|
+
Many backend concerns → One programming model
|
|
34
|
+
```
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
> **One law. Eight elements. One contract.**
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
## Wrong vs. Right Mental Model
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
Understanding OKE begins by rejecting the conventional feature-pile model:
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
| ❌ Wrong Mental Model (Feature Bundle) | ✅ OKEngine Model (Unified Primitives) |
|
|
43
|
+
| -------------------------------------- | -------------------------------------- |
|
|
44
|
+
| Router + Queue + Cron + Auth + ORM | `on(Trigger) → Flow` (One species) |
|
|
45
|
+
| Separate mental model per tool | Eight closed semantic elements |
|
|
46
|
+
| Ad-hoc side effects everywhere | Single door to the world: `fx` |
|
|
47
|
+
| Hand-maintained glue & OpenAPI | Compiled Manifest contract |
|
|
48
|
+
| Unchecked runtime drift | Derived, inspectable surfaces |
|
|
42
49
|
|
|
43
|
-
|
|
50
|
+
The difference is not how many features OKE has. It is how few concepts you need to understand.
|
|
44
51
|
|
|
45
|
-
|
|
52
|
+
## The Law and the `fx` Rule
|
|
46
53
|
|
|
47
|
-
|
|
54
|
+
Every backend behavior is a Flow:
|
|
48
55
|
|
|
49
|
-
|
|
56
|
+
```typescript
|
|
57
|
+
import { on, flow, http } from "okengine/http";
|
|
50
58
|
|
|
51
|
-
|
|
59
|
+
export const health = on(http.get().public(), flow({ do: () => ({ ok: true }) }));
|
|
60
|
+
```
|
|
52
61
|
|
|
53
|
-
|
|
62
|
+
**All world access goes through `fx`.** A Flow that calls `fetch` directly, imports `node:fs`, or uses `Date.now()` is a defect.
|
|
54
63
|
|
|
55
|
-
|
|
64
|
+
```text
|
|
65
|
+
Flow → fx → observable Effects → Compiler → Manifest → Surfaces
|
|
66
|
+
```
|
|
56
67
|
|
|
57
|
-
|
|
68
|
+
Because all effects pass through `fx`, the compiler infers cache keys, capability matrices, and trace trees without manual annotations.
|
|
58
69
|
|
|
59
|
-
## One
|
|
70
|
+
## One Contract, Many Surfaces
|
|
60
71
|
|
|
61
|
-
|
|
72
|
+
The source of truth is the backend model expressed in code. The **Manifest** is the compiled, versioned contract representing that model.
|
|
62
73
|
|
|
63
|
-
| Surface | Port | You
|
|
74
|
+
| Surface | Port | You Maintain? |
|
|
64
75
|
| --------------------------------- | ------------------ | ----------------------------- |
|
|
65
|
-
| Typed client (`okengine/client`) | your app code | No — derived from
|
|
76
|
+
| Typed client (`okengine/client`) | your app code | No — derived from Manifest |
|
|
66
77
|
| Console panels, traces, explorers | `:6533` | No — reads the Manifest |
|
|
67
78
|
| MCP for agents | `:6535` | No — reads the Manifest |
|
|
68
79
|
| Architecture diagram | Console | No — it _is_ the effect graph |
|
|
69
80
|
| Capability matrix + cache keys | compiler / runtime | No — inferred from `fx` |
|
|
70
81
|
|
|
71
|
-
|
|
82
|
+
Operational surfaces are derived, not separately maintained.
|
|
72
83
|
|
|
73
|
-
##
|
|
84
|
+
## See the Model Compose
|
|
74
85
|
|
|
75
|
-
|
|
86
|
+
OKE does not add new subsystems when new architectural requirements emerge. The eight closed primitives compose naturally:
|
|
76
87
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
| Inferred from `fx` | What it gives you |
|
|
83
|
-
| ----------------------- | ------------------------------------ |
|
|
84
|
-
| Cache invalidation keys | Automatic — follows the Flow |
|
|
85
|
-
| Live queries | Built-in subscription model |
|
|
86
|
-
| Least-privilege tokens | Capability matrix from effects |
|
|
87
|
-
| Deterministic tests | Time, clock, and randomness injected |
|
|
88
|
-
| Manifest Diff | Exact change surface on every save |
|
|
89
|
-
|
|
90
|
-
## Eight elements — a closed set
|
|
91
|
-
|
|
92
|
-
Forty infrastructure concerns collapse into eight elements — each kept only because it has **irreducible physics**. New infrastructure becomes a **driver** for an existing element, never a ninth.
|
|
93
|
-
|
|
94
|
-
| Element | Essence | Replaces the zoo |
|
|
95
|
-
| ----------- | ----------------------------- | --------------------------------------------------------- |
|
|
96
|
-
| **Flow** | Behavior | endpoint · handler · consumer · job · workflow · webhook |
|
|
97
|
-
| **Signal** | Data in motion | queue · pub/sub · stream · websocket · SSE · event bus |
|
|
98
|
-
| **Store** | Data at rest | database · cache · KV · file storage · search index |
|
|
99
|
-
| **Clock** | Time | cron · delay · timeout · durable sleep · TTL |
|
|
100
|
-
| **Gate** | Permission to act | auth · session · ABAC · rate limit · quota · feature flag |
|
|
101
|
-
| **Vault** | Protected knowledge | secrets · config · environment |
|
|
102
|
-
| **Channel** | Reaching humans | email · SMS · WhatsApp · push |
|
|
103
|
-
| **AI** | Reaching machine intelligence | model calls · prompts · embeddings · agents · RAG |
|
|
104
|
-
|
|
105
|
-
Drivers are named after **protocols** (`postgres`, `redis`, `s3`) — never vendors. The vendor lives in `images`, and `oke dev` runs the real stack locally.
|
|
106
|
-
|
|
107
|
-
## The shape of a Flow
|
|
108
|
-
|
|
109
|
-
One pipeline. Only the trigger changes between an endpoint, a job, a consumer, and a row hook:
|
|
110
|
-
|
|
111
|
-
```ts
|
|
112
|
-
import { on, flow, http } from "okengine";
|
|
113
|
-
import { z } from "zod";
|
|
114
|
-
|
|
115
|
-
export const health = on(
|
|
116
|
-
http.get().public(),
|
|
117
|
-
flow({
|
|
118
|
-
out: z.object({ ok: z.literal(true) }),
|
|
119
|
-
do: () => ({ ok: true as const }),
|
|
120
|
-
}),
|
|
121
|
-
);
|
|
122
|
-
```
|
|
88
|
+
- **Realtime:** `Store + Gate + Signal + Flow → Live Query` (Global CDC + RLS re-check + SSE).
|
|
89
|
+
- **Security:** `Gate + Store/RLS + Tenant + fx → Secure execution` (Unified user, operator, and agent boundaries).
|
|
90
|
+
- **Agents:** `MCP + Gate + OAuth + Flow → Agent-accessible backend` (Exposing Flows as MCP tools).
|
|
91
|
+
- **Operations:** `Manifest + Effects + Runs → Inspectable backend` (Wide-event telemetry and live graphs).
|
|
123
92
|
|
|
124
|
-
|
|
125
|
-
| ------------- | -------------------------------------------------------------- |
|
|
126
|
-
| **Trigger** | How work starts — `http`, a signal, `every`, a row change |
|
|
127
|
-
| **Contracts** | `in`, `out`, typed `errors` — validated before and after `do` |
|
|
128
|
-
| **`do`** | The body — every read, write, emit, and call goes through `fx` |
|
|
129
|
-
| **Effects** | Inferred from those `fx` calls — not hand-annotated |
|
|
93
|
+
> **None of these required a ninth primitive.**
|
|
130
94
|
|
|
131
|
-
|
|
95
|
+
## Core Philosophy
|
|
132
96
|
|
|
133
|
-
|
|
97
|
+
> **Keep the model small. Let the backend grow without growing the mental model.**
|
|
134
98
|
|
|
135
|
-
|
|
136
|
-
> **Grounded in**: Eight elements, effect inference through `fx`, Gate and Vault, the official plugin set
|
|
137
|
-
> **Maturity**: **pre-1.0** — published and usable; not independently battle-tested at scale yet
|
|
99
|
+
Your backend is not just executable. It is inspectable.
|
|
138
100
|
|
|
139
|
-
##
|
|
140
|
-
|
|
141
|
-
- [Introduction](/docs/get-started/introduction) — the one law, eight elements, ten exports
|
|
142
|
-
- [Flow](/docs/elements/flow) — how effects are recorded and inferred
|
|
143
|
-
- [Vault](/docs/elements/vault) — fail-loud secret contracts
|
|
144
|
-
- [Plugins](/docs/reference/plugins) — the official HTTP glue set
|
|
145
|
-
|
|
146
|
-
## Next
|
|
101
|
+
## Next Steps
|
|
147
102
|
|
|
148
103
|
<Cards>
|
|
149
|
-
<Card
|
|
150
|
-
title="Installation"
|
|
151
|
-
description="Scaffold with create-oke and open the Console."
|
|
152
|
-
href="/docs/get-started/installation"
|
|
153
|
-
/>
|
|
154
|
-
<Card
|
|
155
|
-
title="Basic Usage"
|
|
156
|
-
description="Health Flow, typed client, and bun:test."
|
|
157
|
-
href="/docs/get-started/basic-usage"
|
|
158
|
-
/>
|
|
159
104
|
<Card
|
|
160
105
|
title="Introduction"
|
|
161
|
-
description="The
|
|
106
|
+
description="The Law, Flow anatomy, and the eight elements."
|
|
162
107
|
href="/docs/get-started/introduction"
|
|
163
108
|
/>
|
|
109
|
+
<Card
|
|
110
|
+
title="Installation"
|
|
111
|
+
description="Scaffold your first project with create-oke."
|
|
112
|
+
href="/docs/get-started/installation"
|
|
113
|
+
/>
|
|
164
114
|
</Cards>
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Documentation"
|
|
3
|
-
description: "One law. Eight elements.
|
|
3
|
+
description: "A new programming model for backends. One law. Eight elements. One contract."
|
|
4
4
|
icon: "BookOpen"
|
|
5
5
|
source: "docs/spec/unified-theory.md"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
Welcome to the
|
|
8
|
+
Welcome to the OKEngine handbook. Keep the model small; let the backend grow without growing the mental model.
|
|
9
9
|
|
|
10
|
-
<Callout title="The
|
|
10
|
+
<Callout title="The Law">
|
|
11
11
|
Every backend behavior is a Flow: `on(Trigger) → Effects`. One species; triggers are typed values.
|
|
12
12
|
</Callout>
|
|
13
13
|
|
|
@@ -17,29 +17,83 @@ on(every("10m"), expireStale);
|
|
|
17
17
|
on(orderPlaced, sendReceipt);
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
##
|
|
20
|
+
## 01 Understand (The Core Model)
|
|
21
|
+
|
|
22
|
+
Master the mental model before exploring features:
|
|
21
23
|
|
|
22
24
|
<Cards>
|
|
23
25
|
<Card
|
|
24
|
-
title="
|
|
25
|
-
description="
|
|
26
|
+
title="Why OKE"
|
|
27
|
+
description="The problem of seams across independent tools, the insight, and the smaller model."
|
|
28
|
+
href="/docs/get-started/why"
|
|
29
|
+
/>
|
|
30
|
+
<Card
|
|
31
|
+
title="Introduction"
|
|
32
|
+
description="The Law, Flow anatomy, the fx rule, and the compiled Manifest contract."
|
|
26
33
|
href="/docs/get-started/introduction"
|
|
27
34
|
/>
|
|
28
|
-
<Card title="Elements" description="Flow → AI reference, one page each." href="/docs/elements" />
|
|
29
35
|
<Card
|
|
30
|
-
title="
|
|
31
|
-
description="
|
|
32
|
-
href="/docs/
|
|
36
|
+
title="Eight Elements"
|
|
37
|
+
description="The closed primitive set: Flow, Signal, Store, Clock, Gate, Vault, Channel, AI."
|
|
38
|
+
href="/docs/elements"
|
|
33
39
|
/>
|
|
40
|
+
<Card
|
|
41
|
+
title="fx Surface"
|
|
42
|
+
description="The single door to the outside world — where effects become structurally observable."
|
|
43
|
+
href="/docs/reference/fx"
|
|
44
|
+
/>
|
|
45
|
+
</Cards>
|
|
46
|
+
|
|
47
|
+
## 02 Build (Development)
|
|
48
|
+
|
|
49
|
+
Build, test, and expose real applications:
|
|
50
|
+
|
|
51
|
+
<Cards>
|
|
52
|
+
<Card
|
|
53
|
+
title="Get Started"
|
|
54
|
+
description="Scaffold with create-oke, run the dev stack, and open the Console."
|
|
55
|
+
href="/docs/get-started/installation"
|
|
56
|
+
/>
|
|
57
|
+
<Card
|
|
58
|
+
title="Basic Usage"
|
|
59
|
+
description="Write your first flow, call it with the typed client, and test with bun:test."
|
|
60
|
+
href="/docs/get-started/basic-usage"
|
|
61
|
+
/>
|
|
62
|
+
<Card
|
|
63
|
+
title="Project Structure"
|
|
64
|
+
description="Folder layout, flow file routing conventions, and schema declarations."
|
|
65
|
+
href="/docs/get-started/project-structure"
|
|
66
|
+
/>
|
|
67
|
+
<Card
|
|
68
|
+
title="AI & MCP Surface"
|
|
69
|
+
description="Runtime MCP (:6535), docs MCP (:6536), agent skills, and machine-readable docs."
|
|
70
|
+
href="/docs/ai"
|
|
71
|
+
/>
|
|
72
|
+
</Cards>
|
|
73
|
+
|
|
74
|
+
## 03 Operate & 04 Extend
|
|
75
|
+
|
|
76
|
+
Deploy to production and connect to infrastructure:
|
|
77
|
+
|
|
78
|
+
<Cards>
|
|
34
79
|
<Card
|
|
35
80
|
title="Deployment"
|
|
36
|
-
description="
|
|
81
|
+
description="Production runtime operations: Docker, Swarm, Kubernetes, and reverse proxy."
|
|
37
82
|
href="/docs/deployment"
|
|
38
83
|
/>
|
|
39
84
|
<Card
|
|
40
|
-
title="
|
|
41
|
-
description="
|
|
42
|
-
href="/docs/
|
|
85
|
+
title="Plugins"
|
|
86
|
+
description="Official extensions that add capabilities without creating a ninth element."
|
|
87
|
+
href="/docs/plugins"
|
|
88
|
+
/>
|
|
89
|
+
<Card
|
|
90
|
+
title="Providers"
|
|
91
|
+
description="Managed cloud infrastructure behind protocol-named drivers."
|
|
92
|
+
href="/docs/providers"
|
|
93
|
+
/>
|
|
94
|
+
<Card
|
|
95
|
+
title="Recipes"
|
|
96
|
+
description="Self-hosted Docker compose recipes for SQL, KV, search, and local AI."
|
|
97
|
+
href="/docs/recipes"
|
|
43
98
|
/>
|
|
44
|
-
<Card title="AI Resources" description="MCP, skills, /llms.txt." href="/docs/ai" />
|
|
45
99
|
</Cards>
|
|
@@ -3,13 +3,18 @@
|
|
|
3
3
|
"icon": "BookOpen",
|
|
4
4
|
"pages": [
|
|
5
5
|
"index",
|
|
6
|
-
"
|
|
6
|
+
"---01 Understand---",
|
|
7
7
|
"elements",
|
|
8
|
-
"
|
|
8
|
+
"---02 Build---",
|
|
9
|
+
"get-started",
|
|
10
|
+
"ai",
|
|
11
|
+
"---03 Operate---",
|
|
9
12
|
"deployment",
|
|
10
|
-
"
|
|
13
|
+
"---04 Extend---",
|
|
14
|
+
"plugins",
|
|
11
15
|
"providers",
|
|
12
|
-
"
|
|
13
|
-
"
|
|
16
|
+
"recipes",
|
|
17
|
+
"---05 Reference---",
|
|
18
|
+
"reference"
|
|
14
19
|
]
|
|
15
20
|
}
|
|
@@ -8,6 +8,8 @@ source: "docs/spec/unified-theory.md"
|
|
|
8
8
|
Every provider below speaks a protocol oke already drives — Postgres wire or Redis wire.
|
|
9
9
|
Hand the connection string to that driver; no new driver id, no Flow code changes.
|
|
10
10
|
|
|
11
|
+
These managed providers are real, working infrastructure choices behind the same two templates (`standard`, `advanced`) and the same eight elements — not alternative products or separate frameworks.
|
|
12
|
+
|
|
11
13
|
<Callout title="The one rule">
|
|
12
14
|
Vendor choice lives in a connection URL (`DATABASE_URL` / `REDIS_URL`) — never in
|
|
13
15
|
`drivers.store.sql` / `drivers.store.kv`, which only ever say `postgres` or `redis`.
|
|
@@ -8,6 +8,8 @@ source: "docs/spec/unified-theory.md"
|
|
|
8
8
|
Every recipe below is already wired into `oke docker` — pin an image in `oke.config.ts`
|
|
9
9
|
and get env, healthcheck, and a connection URL for free.
|
|
10
10
|
|
|
11
|
+
These recipes are real, working infrastructure choices behind the same two templates (`standard`, `advanced`) and the same eight elements — not alternative products or separate frameworks.
|
|
12
|
+
|
|
11
13
|
<Callout title="The one rule">
|
|
12
14
|
Vendor choice lives in `images[…]` — never in `drivers.*`, which only ever say protocol ids
|
|
13
15
|
(`postgres`, `redis`, `s3`, `smtp`, `meilisearch`, `openai-compatible`, `ollama`, …).
|
|
@@ -48,7 +48,7 @@ const OKID_PROMPT_ALLOW = [
|
|
|
48
48
|
// Minified zod-core inside the vendored Console bundle registers string
|
|
49
49
|
// format validators whose names collide with peer library names — vendor
|
|
50
50
|
// identifiers, not authored comparisons. Hash changes on Console rebuilds.
|
|
51
|
-
"src/console/ui-next/dist/
|
|
51
|
+
"src/console/ui-next/dist/",
|
|
52
52
|
];
|
|
53
53
|
|
|
54
54
|
/**
|
|
@@ -145,7 +145,7 @@ export const flow_${i} = on(
|
|
|
145
145
|
expect(Object.keys(manifest.flows ?? {}).length).toBe(200);
|
|
146
146
|
// Local ~400ms after warmup. GHA shared runners measured ~2.9s cold.
|
|
147
147
|
// Warmup + extract exceeds Bun's 5s default (v0.15.0 tag timed out at 5.6s).
|
|
148
|
-
const budgetMs = process.env.CI ?
|
|
148
|
+
const budgetMs = process.env.CI ? 6_000 : 5_000;
|
|
149
149
|
expect(elapsed).toBeLessThan(budgetMs);
|
|
150
150
|
},
|
|
151
151
|
{ timeout: 15_000 },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{$n as t,Bi as n,Br as r,Cr as i,E as a,F as o,Fo as s,L as c,No as l,P as u,Qn as d,Sa as f,Sr as p,Ta as m,Ui as h,Yr as g,_a as _,_r as v,ar as y,ba as b,br as x,c as S,ca as C,cr as w,dr as T,er as E,hr as D,i as O,ir as k,l as A,mr as j,nr as M,o as N,or as P,s as F,sr as I,u as ee,ur as L,va as R,vr as z,wr as B,x as V,xa as te,xi as H,xr as U,ya as W,yr as ne}from"./shortcut-keys-DKxNTe_m.js";import{t as G}from"./useMutation-B8EO02Ej.js";import{r as re}from"./react-dom-Bph1y7z7.js";import{A as ie}from"./xyflow-D7n4g6go.js";import{n as ae}from"./index-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{$n as t,Bi as n,Br as r,Cr as i,E as a,F as o,Fo as s,L as c,No as l,P as u,Qn as d,Sa as f,Sr as p,Ta as m,Ui as h,Yr as g,_a as _,_r as v,ar as y,ba as b,br as x,c as S,ca as C,cr as w,dr as T,er as E,hr as D,i as O,ir as k,l as A,mr as j,nr as M,o as N,or as P,s as F,sr as I,u as ee,ur as L,va as R,vr as z,wr as B,x as V,xa as te,xi as H,xr as U,ya as W,yr as ne}from"./shortcut-keys-DKxNTe_m.js";import{t as G}from"./useMutation-B8EO02Ej.js";import{r as re}from"./react-dom-Bph1y7z7.js";import{A as ie}from"./xyflow-D7n4g6go.js";import{n as ae}from"./index-CMIgUbD0.js";import{a as oe,c as se,i as ce,n as le,o as ue,r as de,s as fe,t as pe}from"./element-icons-BVXtRyd3.js";import{t as me}from"./explorer-empty-2uIhBu0_.js";import{a as K,c as he,l as q,n as J,o as ge,r as _e,s as ve,t as ye}from"./detail-header-DhHM1iaZ.js";import{n as be,t as xe}from"./copy-inline-button-DBHhgHKP.js";import{i as Se,t as Ce}from"./http-method-_UHM2ODJ.js";var Y=e(re(),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=ie(),Ue=`GET /secure
|
|
2
2
|
Authorization: Bearer <secret>`,We=`{ "ok": true }`;function Ge({keyRow:e,blast:t,now:n,leading:r,onEdit:a,onRefresh:o,onRevoke:s,onRotate:c,rotatePending:l}){let u=e.revokedAt!==null,d=e.expiresAt!==null&&e.expiresAt<=n,f=t?.lastUsedAt??e.lastUsedAt,p=t?.callVolume??0,m=Te(e.expiresAt,n),h=we(f,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)(ye,{dataSlot:`access-detail-header`,leading:r,icon:(0,Q.jsx)(B,{icon:H,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)(B,{icon:e.plane===`operator`?g:C,className:`size-3`,"aria-hidden":!0}),e.plane]}),u?(0,Q.jsx)(`span`,{className:`font-mono text-[10px] text-destructive`,children:`revoked`}):null,d&&!u?(0,Q.jsx)(`span`,{className:`font-mono text-[10px] text-amber-700 dark:text-amber-400`,children:`expired`}):null,e.unused90d&&!u&&!d?(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)(xe,{value:e.id,label:`Copy ${e.id}`})]}),actions:(0,Q.jsxs)(Q.Fragment,{children:[(0,Q.jsx)(fe,{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:u,onClick:a,children:`Edit`})}),(0,Q.jsx)(fe,{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:u,onClick:o,children:`Refresh`})}),(0,Q.jsx)(fe,{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:l||u,onClick:c,children:`Rotate`})}),(0,Q.jsx)(fe,{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:u,onClick:s,children:`Revoke`})})]})}),(0,Q.jsx)(Ke,{revoked:u,expired:d,unused:e.unused90d,residual:t?.residualAccessNote}),(0,Q.jsxs)(`div`,{className:D,"data-slot":`access-briefing`,role:`group`,"aria-label":`Usage`,children:[(0,Q.jsx)(Xe,{label:`calls`,value:String(p)}),(0,Q.jsx)(Xe,{label:`used`,value:h,hint:f?new Date(f).toISOString():`No recorded call`,warn:f==null&&!u}),(0,Q.jsx)(Xe,{label:`expires`,value:m,hint:e.expiresAt?new Date(e.expiresAt).toISOString():`No expiry`,warn:d&&!u}),(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)(xe,{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:T,"aria-label":e.group,children:[(0,Q.jsx)(`span`,{className:i(U,`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
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:m,hint:e.expiresAt?new Date(e.expiresAt).toISOString():void 0,warn:d&&!u}),(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:f,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:i(D,`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:i(D,`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:i(D,`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:T,children:[(0,Q.jsx)(`span`,{className:i(U,`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:T,children:[(0,Q.jsx)(`span`,{className:i(U,`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)(xe,{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:i(`w-1 shrink-0 self-stretch`,Se(`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:i(`shrink-0 font-mono text-[10px] font-semibold tracking-[0.08em] uppercase`,p(Ce(`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)(xe,{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:i(D,`items-center gap-2 px-2`),children:[(0,Q.jsx)(`h3`,{className:i(U,`shrink-0 leading-none`),children:e}),t?(0,Q.jsx)(`span`,{className:i(M,!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:i(v,z,`gap-1.5`),children:[(0,Q.jsx)(`span`,{className:`tracking-[0.08em] uppercase`,children:e}),(0,Q.jsx)(`span`,{className:i(`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)(xe,{value:e,label:t})})}function Qe({label:e,value:t,hint:n,copy:r,copyLabel:a,warn:o=!1}){return(0,Q.jsxs)(`div`,{className:T,children:[(0,Q.jsx)(`dt`,{className:i(U,`w-[5.5rem] shrink-0`),children:e}),(0,Q.jsx)(`dd`,{className:i(`min-w-0 flex-1 truncate font-mono text-[11px]`,o&&`text-amber-800 dark:text-amber-400`),title:n,children:t}),r?(0,Q.jsx)(Ze,{value:r,label:a??`Copy ${e}`}):null]})}var $e=[`console.access.list`];function et(){return l({queryKey:$e,queryFn:async()=>{let e=await W();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:I,children:`Loading…`}):null,!r&&e.length===0&&n.trim().length>0?(0,Q.jsx)(`p`,{className:I,children:`No keys match.`}):null,(0,Q.jsx)(nt,{label:`User`,icon:C,rows:a,selectedKey:t,onSelect:i}),(0,Q.jsx)(nt,{label:`Operator`,icon:g,rows:o,selectedKey:t,onSelect:i})]})}function nt(e){return(0,Q.jsxs)(`section`,{className:d,"aria-label":e.label,children:[(0,Q.jsxs)(`div`,{className:t,children:[(0,Q.jsx)(B,{icon:e.icon,className:i(P,`text-muted-foreground`),"aria-hidden":!0}),(0,Q.jsx)(`span`,{className:i(E,`flex-1`),children:e.label}),(0,Q.jsx)(`span`,{className:M,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:i(T,n&&`bg-muted/70 text-foreground`),onClick:()=>e.onSelect(t.id),children:[(0,Q.jsx)(`span`,{className:i(L,n&&`bg-sky-500`)}),(0,Q.jsx)(B,{icon:H,className:i(P,`text-muted-foreground`)}),(0,Q.jsx)(`span`,{className:i(`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:i(`ml-auto tabular-nums text-[10px] text-muted-foreground`),children:t.scopes.length})]},t.id)})]})}function rt({entries:e,rateMax:t,rateCount:s,rateUnit:l,onEntries:d,onRateMax:f,onRateCount:p,onRateUnit:m}){let[h,g]=(0,Y.useState)(``),_=Re(h),b=h.trim().length>0&&_.length===0,x=()=>{if(_.length===0)return;let t=new Set(e),n=[...e];for(let e of _)t.has(e)||(t.add(e),n.push(e));d(n),g(``)};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:h,onChange:e=>g(e.target.value),onKeyDown:e=>{e.key===`Enter`&&(e.preventDefault(),x())},placeholder:`203.0.113.4 or ci.example.com`,autoComplete:`off`,"aria-label":`Add allow entry`,"aria-invalid":b,flat:!0,className:i(J,`min-w-0 flex-1 font-mono`)}),e.length>0?(0,Q.jsx)(`span`,{className:i(M,`flex h-8 items-center pr-2`),children:e.length}):null,(0,Q.jsx)(`button`,{type:`button`,className:i(y,`h-8`),"aria-label":`Add allow entry`,disabled:_.length===0,onClick:x,children:(0,Q.jsx)(B,{icon:n,className:`size-3.5`,"aria-hidden":!0})})]}),b?(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:i(T,`last:border-b-0`),children:[(0,Q.jsx)(`span`,{className:i(U,`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:i(`min-w-0 truncate font-mono text-[11px]`,n==null&&`text-destructive`),children:t}),(0,Q.jsx)(`button`,{type:`button`,className:i(k,`ml-auto opacity-0 group-hover:opacity-100 focus-visible:opacity-100`),"aria-label":`Remove ${t}`,onClick:()=>d(e.filter(e=>e!==t)),children:(0,Q.jsx)(B,{icon:r,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=>f(e.target.value),placeholder:`none`,inputMode:`numeric`,autoComplete:`off`,"aria-label":`Rate max`,flat:!0,className:i(J,`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:s,onChange:e=>p(e.target.value),placeholder:`1`,inputMode:`numeric`,autoComplete:`off`,"aria-label":`Rate window`,flat:!0,className:i(J,`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)(u,{children:[(0,Q.jsx)(c,{render:t=>(0,Q.jsx)(`button`,{...t,type:`button`,"aria-pressed":l===e,"aria-label":Pe[e],onClick:n=>{t.onClick?.(n),m(e)},className:i(v,`h-8 px-1.5 font-mono font-semibold`,l===e?ne:z),children:e})}),(0,Q.jsx)(o,{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)(ge,{label:`Expires`,children:[(0,Q.jsx)(K,{active:e===`never`,onClick:()=>n(`never`),children:`never`}),(0,Q.jsx)(K,{active:e===`30d`,onClick:()=>n(`30d`),children:`30d`}),(0,Q.jsx)(K,{active:e===`90d`,onClick:()=>n(`90d`),children:`90d`}),(0,Q.jsx)(K,{active:e===`custom`,onClick:()=>n(`custom`),children:`custom`})]}),e===`custom`?(0,Q.jsx)(he,{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:i(J,`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)(B,{icon:h,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:i(_e)})]})}function ot({scopes:e,selected:t,empty:n,onChange:r}){let[a,o]=(0,Y.useState)(``),s=new Set(t),c=(0,Y.useMemo)(()=>st(e,a),[e,a]),l=(0,Y.useMemo)(()=>He(c),[c]),u=e.join(`\0`);return(0,Y.useEffect)(()=>{o(``)},[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:a,placeholder:`Search scopes`,label:`Search scopes`,onChange:o}):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:i(`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:o,error:s,onOpenChange:c,onSubmit:l}){let[u,d]=(0,Y.useState)(`user`),[f,p]=(0,Y.useState)(``),[m,h]=(0,Y.useState)(``),[_,v]=(0,Y.useState)([]),[y,b]=(0,Y.useState)(`never`),[x,w]=(0,Y.useState)(``),[E,D]=(0,Y.useState)([]),[k,j]=(0,Y.useState)(``),[M,P]=(0,Y.useState)(``),[I,R]=(0,Y.useState)(`m`),[z,B]=(0,Y.useState)(``),V=t.find(e=>e.id===m)??null,te=(0,Y.useMemo)(()=>{let e=z.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 V&&!n.some(e=>e.id===V.id)?[V,...n]:n},[t,z,V]),H=(0,Y.useMemo)(()=>u===`operator`?r:V==null?[]:V.scopes.length>0?V.scopes:n,[u,n,r,V]);(0,Y.useEffect)(()=>{e||(d(`user`),p(``),h(``),v([]),b(`never`),w(``),D([]),j(``),P(``),R(`m`),B(``))},[e]),(0,Y.useEffect)(()=>{v(e=>{let t=e.filter(e=>H.includes(e));if(t.length>0)return t;let n=H[0];return n?[n]:[]})},[H]);let U=De(x),W=Fe(k,M,I),ne=f.trim().length>0&&_.length>0&&!o&&W!==void 0&&(u===`operator`||m.length>0)&&(y!==`custom`||U>0);return(0,Q.jsx)(O,{open:e,modal:!1,disablePointerDismissal:!0,onOpenChange:c,children:(0,Q.jsxs)(N,{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)(A,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(ee,{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:i(J,`min-w-0 flex-1`)})]}),(0,Q.jsxs)(ge,{label:`Plane`,children:[(0,Q.jsx)(K,{active:u===`user`,icon:C,onClick:()=>{d(`user`)},children:`user`}),(0,Q.jsx)(K,{active:u===`operator`,icon:g,onClick:()=>{d(`operator`),h(``),B(``)},children:`operator`})]}),(0,Q.jsx)(it,{expires:y,customExpires:x,onExpires:b,onCustomExpires:w}),(0,Q.jsx)(rt,{entries:E,rateMax:k,rateCount:M,rateUnit:I,onEntries:D,onRateMax:j,onRateCount:P,onRateUnit:R}),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:z,placeholder:`Search users`,label:`Search users`,onChange:B}):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.`}):te.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:te.map(e=>{let t=e.id===m;return(0,Q.jsxs)(`button`,{type:`button`,"data-slot":`access-creator-user`,"aria-pressed":t,className:i(T,t&&`bg-muted/70 text-foreground`),onClick:()=>h(e.id),children:[(0,Q.jsx)(`span`,{className:i(L,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:H,selected:_,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:v}),s?(0,Q.jsx)(ve,{slot:`access-create-error`,children:s}):null]}),(0,Q.jsxs)(S,{children:[(0,Q.jsx)(q,{split:!0,onClick:()=>c(!1),disabled:o,children:`Cancel`}),(0,Q.jsx)(q,{variant:`default`,disabled:!ne,"data-slot":`access-create-submit`,onClick:()=>{if(W===void 0)return;let e=Oe(y,Date.now(),x);l({plane:u,name:f.trim(),scopes:_,...u===`user`?{creatorUserId:m}:{},...e==null?{}:{expiresAt:e},...W==null?{}:{rateLimit:W},...E.length>0?{ipAllowlist:E}:{}})},children:o?`Creating…`:`Create`})]})]})})}function lt({open:e,keyRow:t,users:n,operators:r,operatorScopes:o,pending:s,error:c,now:l=Date.now(),onOpenChange:u,onSubmit:d}){let f=ke(t.expiresAt,l),[p,m]=(0,Y.useState)(t.name),[h,_]=(0,Y.useState)(t.scopes),[v,y]=(0,Y.useState)(f.choice),[b,x]=(0,Y.useState)(f.custom),[w,T]=(0,Y.useState)(t.ipAllowlist),E=Ie(t.rateLimit?.per??``),[D,k]=(0,Y.useState)(t.rateLimit?String(t.rateLimit.max):``),[j,M]=(0,Y.useState)(E.count),[P,I]=(0,Y.useState)(E.unit);(0,Y.useEffect)(()=>{if(!e)return;let n=ke(t.expiresAt,l);m(t.name),_(t.scopes),y(n.choice),x(n.custom),T(t.ipAllowlist);let r=Ie(t.rateLimit?.per??``);k(t.rateLimit?String(t.rateLimit.max):``),M(r.count),I(r.unit)},[e,t.id]);let L=t.creatorId??``,R=(0,Y.useMemo)(()=>L.length===0?null:n.find(e=>e.id===L)??r.find(e=>e.id===L)??null,[L,r,n]),z=R?R.name.trim()||R.email.trim()||R.id:L||`Unknown`,V=(0,Y.useMemo)(()=>{let e=t.creatorScopes??[];return e.length>0?e:t.plane===`operator`?R&&R.scopes.length>0?R.scopes:o:R?.scopes??[]},[R,t.creatorScopes,t.plane,o]),te=Array.from(new Set([...V,...t.scopes])),H=De(b),U=Fe(D,j,P),W=p.trim().length>0&&h.length>0&&!s&&U!==void 0&&(v!==`custom`||H>0);return(0,Q.jsx)(O,{open:e,modal:!1,disablePointerDismissal:!0,onOpenChange:u,children:(0,Q.jsxs)(N,{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)(A,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(ee,{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:p,onChange:e=>m(e.target.value),placeholder:`CI deploy`,autoComplete:`off`,"aria-label":`Key name`,flat:!0,className:i(J,`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 ${z}`,children:[(0,Q.jsx)(B,{icon:t.plane===`operator`?g:C,className:`size-3 shrink-0`,"aria-hidden":!0}),(0,Q.jsx)(`span`,{className:`min-w-0 truncate text-foreground`,children:z})]}),L.length>0&&L!==z?(0,Q.jsx)(`span`,{className:`flex h-8 shrink-0 items-center pr-4 font-mono text-[10px] text-muted-foreground`,children:L}):null]}),(0,Q.jsx)(it,{expires:v,customExpires:b,onExpires:y,onCustomExpires:x}),(0,Q.jsx)(rt,{entries:w,rateMax:D,rateCount:j,rateUnit:P,onEntries:T,onRateMax:k,onRateCount:M,onRateUnit:I}),(0,Q.jsx)(ot,{scopes:te,selected:h,empty:t.plane===`user`&&R==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:_}),c?(0,Q.jsx)(ve,{slot:`access-edit-error`,children:c}):null]}),(0,Q.jsxs)(S,{children:[(0,Q.jsx)(q,{split:!0,onClick:()=>u(!1),disabled:s,children:`Cancel`}),(0,Q.jsx)(q,{variant:`default`,disabled:!W,"data-slot":`access-edit-submit`,onClick:()=>{U!==void 0&&d({name:p.trim(),scopes:h,expiresAt:Oe(v,Date.now(),b),rateLimit:U,ipAllowlist:w})},children:s?`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)(O,{open:e,modal:!1,disablePointerDismissal:!0,onOpenChange:a,children:(0,Q.jsxs)(N,{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)(A,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(ee,{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)(ve,{slot:`access-refresh-error`,children:r}):null]}),(0,Q.jsxs)(S,{children:[(0,Q.jsx)(q,{split:!0,onClick:()=>a(!1),disabled:n,children:`Cancel`}),(0,Q.jsx)(q,{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)(O,{open:e!==null,onOpenChange:e=>{e||n()},children:(0,Q.jsxs)(N,{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)(A,{className:`gap-1 border-b border-border/50`,children:[(0,Q.jsx)(ee,{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)(S,{children:[(0,Q.jsx)(q,{split:!0,disabled:!e,onClick:()=>{e&&(navigator.clipboard?.writeText(e),i(!0))},children:r?`Copied`:`Copy (clipboard warning)`}),(0,Q.jsx)(q,{variant:`destructive`,onClick:()=>{i(!1),n()},children:`I have stored this key`})]})]})})}function ft(){let e=et(),t=s(),{query:r,selectedKey:i,action:a,setQuery:o,setSelectedKey:c,setAction:u}=ae(),d=le(),[p]=(0,Y.useState)(()=>Date.now()),[h,g]=(0,Y.useState)(null),[v,S]=(0,Y.useState)(`New API key`),C=(0,Y.useMemo)(()=>{let t=e.data?.userPlane.keys??[],n=e.data?.operatorPlane.keys??[];return[...t,...n]},[e.data]),T=(0,Y.useMemo)(()=>{let e=r.trim().toLowerCase();return e?C.filter(t=>t.name.toLowerCase().includes(e)||t.id.toLowerCase().includes(e)||t.scopes.some(t=>t.toLowerCase().includes(e))):C},[C,r]),E=T.find(e=>e.id===i)??C.find(e=>e.id===i),D=l({queryKey:[`console.access.blast`,E?.id],queryFn:async()=>{if(!E)throw Error(`no key`);let e=await R(E.id);if(e.error||!e.data)throw Error(e.error?.message??`blast failed`);return e.data},enabled:E!==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 O=()=>{t.invalidateQueries({queryKey:$e})},k=G({mutationFn:_,onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?m(e.error):`create failed`);S(`New API key`),g(e.data.secret),c(e.data.key.id),u(null),O()}}),A=G({mutationFn:e=>te({keyId:E.id,confirmation:e.confirmation,reason:e.reason}),onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?m(e.error):`rotate failed`);S(`Rotated API key`),g(e.data.secret),u(null),O()}}),M=G({mutationFn:e=>b({keyId:E.id,confirmation:e.confirmation,reason:e.reason}),onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?m(e.error):`revoke failed`);u(null),O()}}),N=G({mutationFn:f,onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?m(e.error):`update failed`);u(null),O()}}),P=G({mutationFn:e=>f({keyId:E.id,expiresAt:e}),onSuccess:e=>{if(e.error||!e.data)throw Error(e.error?m(e.error):`refresh failed`);u(null),O()}}),F=(0,Q.jsx)(ue,{open:d.open,onToggle:d.toggle,noun:`keys`,controlsId:`access-list`,dataSlot:`access-list-toggle`});return(0,Q.jsxs)(`div`,{className:w,"data-slot":`access-page`,children:[(0,Q.jsxs)(oe,{orientation:`horizontal`,className:`min-h-0 flex-1`,children:[(0,Q.jsx)(ce,{panelRef:d.panelRef,collapsible:!0,collapsedSize:0,defaultSize:j.start.defaultSize,minSize:j.start.minSize,onResize:d.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:x,children:[(0,Q.jsx)(se,{"data-slot":`access-search-input`,placeholder:`Search keys`,"aria-label":`Search keys`,value:r,onChange:e=>o(e.target.value)}),(0,Q.jsx)(fe,{label:`Create key`,className:`flex self-stretch`,children:(0,Q.jsx)(`button`,{type:`button`,className:y,"data-slot":`access-create`,"aria-label":`Create key`,onClick:()=>u(`create`),children:(0,Q.jsx)(B,{icon:n,className:`size-3.5`})})})]}),(0,Q.jsx)(tt,{rows:T,selectedKey:i,query:r,loading:e.isLoading,onSelect:c})]})}),d.open?(0,Q.jsx)(de,{withHandle:!0}):null,(0,Q.jsx)(ce,{defaultSize:j.end.defaultSize,minSize:j.end.minSize,className:`min-h-0 overflow-hidden`,children:E?(0,Q.jsx)(Ge,{keyRow:E,blast:D.data,now:p,leading:F,onEdit:()=>u(`edit`),onRefresh:()=>u(`refresh`),onRevoke:()=>u(`revoke`),onRotate:()=>u(`rotate`),rotatePending:A.isPending}):(0,Q.jsx)(me,{icon:pe.gate.icon,iconClassName:`border-border/70`,title:e.isLoading?`Loading keys…`:C.length>0?`Select a key`:`No keys yet`,leading:F,description:e.isLoading?`Reading planes and grantable scopes.`:C.length>0&&r.trim().length>0?(0,Q.jsxs)(Q.Fragment,{children:[`Nothing matches `,(0,Q.jsx)(`span`,{className:`font-mono`,children:r}),`.`,` `,(0,Q.jsx)(`button`,{type:`button`,className:`underline underline-offset-2 hover:text-foreground`,onClick:()=>o(``),children:`Clear search`})]}):`Create one to mint a secret once.`})})]}),(0,Q.jsx)(ct,{open:a===`create`,users:e.data?.userPlane.users??[],userScopes:e.data?.userPlane.grantableScopes??[],operatorScopes:e.data?.operatorPlane.grantableScopes??[],pending:k.isPending,error:k.error instanceof Error?k.error.message:null,onOpenChange:e=>{e||u(null)},onSubmit:e=>k.mutate(e)}),E?(0,Q.jsx)(lt,{open:a===`edit`,keyRow:E,users:e.data?.userPlane.users??[],operators:e.data?.operatorPlane.operators??[],operatorScopes:e.data?.operatorPlane.grantableScopes??[],pending:N.isPending,error:N.error instanceof Error?N.error.message:null,onOpenChange:e=>{e||u(null)},onSubmit:e=>N.mutate({keyId:E.id,...e})}):null,E?(0,Q.jsx)(ut,{open:a===`refresh`,keyRow:E,pending:P.isPending,error:P.error instanceof Error?P.error.message:null,onOpenChange:e=>{e||u(null)},onSubmit:e=>P.mutate(e)}):null,E?(0,Q.jsx)(be,{open:a===`revoke`,onOpenChange:e=>{e||u(null)},phrase:`REVOKE`,title:`Revoke ${E.name}`,description:`Irreversible. Residual sessions may continue for the access TTL.`,pending:M.isPending,error:M.error instanceof Error?M.error.message:null,confirmLabel:`Revoke key`,slot:`access-revoke-sheet`,onConfirm:e=>M.mutate({confirmation:`REVOKE`,reason:e.reason})}):null,E?(0,Q.jsx)(be,{open:a===`rotate`,onOpenChange:e=>{e||u(null)},phrase:`ROTATE`,title:`Rotate ${E.name}`,description:`Mints a new secret once. The current secret stops after residual TTL.`,pending:A.isPending,error:A.error instanceof Error?A.error.message:null,confirmLabel:`Rotate key`,confirmVariant:`ghost`,slot:`access-rotate-sheet`,onConfirm:e=>A.mutate({confirmation:`ROTATE`,reason:e.reason})}):null,(0,Q.jsx)(dt,{secret:h,title:v,onDismiss:()=>g(null)})]})}export{ft as AccessPage};
|