@lunora/studio 0.0.0 → 1.0.0-alpha.1

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.
Files changed (81) hide show
  1. package/LICENSE.md +105 -0
  2. package/README.md +123 -9
  3. package/__assets__/package-og.svg +14 -0
  4. package/dist/index.d.ts +1402 -0
  5. package/dist/index.js +41 -0
  6. package/dist/mount.d.ts +21 -0
  7. package/dist/mount.js +26 -0
  8. package/dist/packem_shared/ADMIN_FUNCTION_PREFIX-DmBqMZ-z.js +45 -0
  9. package/dist/packem_shared/ApiDocsPanel-DpRjJhG5.js +842 -0
  10. package/dist/packem_shared/ApiReferencePanel-DMIUp-kK.js +229 -0
  11. package/dist/packem_shared/ApiTab-DURGU15e.js +251 -0
  12. package/dist/packem_shared/AuditPanel-BC59Nhst.js +212 -0
  13. package/dist/packem_shared/CommandPalette-Dx_CoB9i.js +373 -0
  14. package/dist/packem_shared/ConfirmButton-WQVUoGFb.js +59 -0
  15. package/dist/packem_shared/ConnectionBadge-Bxagrip8.js +111 -0
  16. package/dist/packem_shared/DEFAULT_AUTO_REFRESH_MS-Vxwaxx51.js +50 -0
  17. package/dist/packem_shared/DEFAULT_INSIGHT_THRESHOLDS-DjF0h-gA.js +89 -0
  18. package/dist/packem_shared/DataBrowser-Coz6jJE6.js +4542 -0
  19. package/dist/packem_shared/DataFilters-FNquMaiu.js +249 -0
  20. package/dist/packem_shared/ErrorBoundary-BzAApI7J.js +66 -0
  21. package/dist/packem_shared/ExportImportPanel-WO34fJxy.js +193 -0
  22. package/dist/packem_shared/FileBrowser-Zcr-Qgxo.js +2932 -0
  23. package/dist/packem_shared/FunctionRunner-j0Rd5m9t.js +343 -0
  24. package/dist/packem_shared/FunctionStatsPanel-DboBl-XL.js +432 -0
  25. package/dist/packem_shared/GlobalDataBrowser-9MhPEfgN.js +318 -0
  26. package/dist/packem_shared/HealthPanel-DOIgbUtx.js +640 -0
  27. package/dist/packem_shared/HomePanel-bdOCNA-p.js +1273 -0
  28. package/dist/packem_shared/InsightsPanel-DaZPnSgt.js +423 -0
  29. package/dist/packem_shared/LogsPanel-CWdqAGpQ.js +839 -0
  30. package/dist/packem_shared/MailPanel-D_EGtDnS.js +447 -0
  31. package/dist/packem_shared/MetricsPanel-E4Gv6wTO.js +1625 -0
  32. package/dist/packem_shared/MigrationsPanel-DQdPY9io.js +246 -0
  33. package/dist/packem_shared/OpenRpcReferencePanel-j2p3HB0s.js +191 -0
  34. package/dist/packem_shared/PitrPanel-BbBkQR6t.js +252 -0
  35. package/dist/packem_shared/STUDIO_ROOT_CLASS-D12gX2dV.js +3 -0
  36. package/dist/packem_shared/ScheduledJobs-Ok1CYYwI.js +159 -0
  37. package/dist/packem_shared/SchemaViewer-D8XGnp-X.js +2512 -0
  38. package/dist/packem_shared/SecurityAdvisorPanel-Cdm2IxLW.js +79 -0
  39. package/dist/packem_shared/SettingsPanel-D3WF2mBU.js +176 -0
  40. package/dist/packem_shared/ShardInput-DNCsT1KW.js +107 -0
  41. package/dist/packem_shared/SqlEditorPanel-BuQ7f2Hs.js +13 -0
  42. package/dist/packem_shared/Studio-D36od9Oz.js +33 -0
  43. package/dist/packem_shared/StudioApp-dvywkJ8I.js +383 -0
  44. package/dist/packem_shared/StudioI18nProvider-Dcajsznk.js +48 -0
  45. package/dist/packem_shared/TableEditor-DIVDk3vT.js +371 -0
  46. package/dist/packem_shared/advisor-view-DBlzJi6C.js +159 -0
  47. package/dist/packem_shared/aggregateMetrics-D4nUHEKU.js +108 -0
  48. package/dist/packem_shared/app.d-CCmwDEVs.d.ts +300 -0
  49. package/dist/packem_shared/badge-B2PKA1-5.js +49 -0
  50. package/dist/packem_shared/bar-chart-CzJAgqkp.js +3245 -0
  51. package/dist/packem_shared/button-BhsN2uZH.js +49 -0
  52. package/dist/packem_shared/card-DURq3ElK.js +175 -0
  53. package/dist/packem_shared/cf-links-BZfRdxSE.js +8 -0
  54. package/dist/packem_shared/checkbox-UNkzAxl-.js +63 -0
  55. package/dist/packem_shared/createStudioI18n-CgvlmDkN.js +27 -0
  56. package/dist/packem_shared/data-grid-CCh2Couo.js +183 -0
  57. package/dist/packem_shared/dropdown-menu-WY4B_eJO.js +280 -0
  58. package/dist/packem_shared/empty-state-DY_oe0k6.js +98 -0
  59. package/dist/packem_shared/grid-features-DTjG6Sex.js +840 -0
  60. package/dist/packem_shared/input-XH4r1Pt1.js +53 -0
  61. package/dist/packem_shared/internal-BBZYexre.js +68 -0
  62. package/dist/packem_shared/label-D8ykjn5J.js +46 -0
  63. package/dist/packem_shared/live-status-bPff1O7Y.js +44 -0
  64. package/dist/packem_shared/reference-view-BCKIoai7.js +2180 -0
  65. package/dist/packem_shared/shard-history-DyebH1R5.js +38 -0
  66. package/dist/packem_shared/sparkline-10dG-_f0.js +93 -0
  67. package/dist/packem_shared/sql-editor-panel-CW2y2x9h.js +2562 -0
  68. package/dist/packem_shared/storage-tier-CL98eOvn.js +85 -0
  69. package/dist/packem_shared/studio-BDVd7rIV.js +10303 -0
  70. package/dist/packem_shared/table-_RzNvy3R.js +246 -0
  71. package/dist/packem_shared/table-list-sidebar-aZHLq70w.js +832 -0
  72. package/dist/packem_shared/textarea-D3gaCU_-.js +46 -0
  73. package/dist/packem_shared/use-live-admin-D1h1Fzsd.js +73 -0
  74. package/dist/packem_shared/use-live-shard-seed-B74RYcOy.js +76 -0
  75. package/dist/packem_shared/useDebounced-Dxncpg6z.js +32 -0
  76. package/dist/packem_shared/utils-B05Dmz_H.js +8 -0
  77. package/dist/packem_shared/virtual-rect-CVMUskSm.js +10 -0
  78. package/dist/standalone/studio.js +356 -0
  79. package/dist/styles.css +2 -0
  80. package/package.json +77 -17
  81. package/src/theme.css +59 -0
@@ -0,0 +1,1402 @@
1
+ import { F as FunctionDescriptor } from "./packem_shared/app.d-CCmwDEVs.js";
2
+ export { type a as FunctionKind, type R as RunStatus, b as ScheduledJobs, type c as ScheduledJobsProps, d as Studio, e as StudioApp, type S as StudioAppProps, type f as StudioProps, type g as StudioTab } from "./packem_shared/app.d-CCmwDEVs.js";
3
+ import { ReactElement, ReactNode, ErrorInfo, Component, ChangeEvent } from 'react';
4
+ import { CapturedMail } from '@lunora/mail';
5
+ export type { CapturedMail } from '@lunora/mail';
6
+ import { Messages, I18n } from '@lingui/core';
7
+ export type { LunoraClient, ScheduleRecord, StorageObject } from '@lunora/client';
8
+ /** A navigable destination shown in the palette. */
9
+ interface CommandItem {
10
+ /** Localised domain label, shown as a muted suffix to disambiguate. */
11
+ readonly group: string;
12
+ /** Localised sub-page label, the primary search target. */
13
+ readonly label: string;
14
+ /** Router path to navigate to on select (e.g. `/logs`). */
15
+ readonly to: string;
16
+ }
17
+ interface CommandPaletteProps {
18
+ /** Every navigable destination, in rail order. */
19
+ readonly items: ReadonlyArray<CommandItem>;
20
+ }
21
+ /** Open the command palette from anywhere (e.g. the top-bar Search button). */
22
+ declare const openCommandPalette: () => void;
23
+ /**
24
+ * Command palette (⌘K / Ctrl-K) — Supabase-style global search. Rendered inside
25
+ * the studio shell so its selection can drive the router's `useNavigate`. Opens
26
+ * on the keyboard shortcut or the {@link OPEN_EVENT} the top-bar Search button
27
+ * dispatches, filters the navigable destinations by a case-insensitive substring
28
+ * over their label and domain, and navigates to the chosen one. Built on the
29
+ * studio's Base UI dialog primitive — no `cmdk`/extra dependency — with a small
30
+ * arrow-key + Enter affordance over the filtered list.
31
+ */
32
+ declare const CommandPalette: ({
33
+ items
34
+ }: CommandPaletteProps) => ReactElement;
35
+ interface ConfirmButtonProps {
36
+ /** Label for the initial trigger (e.g. `Delete`). */
37
+ readonly children: string;
38
+ /** Label for the confirm step; defaults to a localised `Confirm`. */
39
+ readonly confirmLabel?: string;
40
+ /** Disable the trigger (e.g. while a write is in flight). */
41
+ readonly disabled?: boolean;
42
+ /** Action run only after the operator confirms. */
43
+ readonly onConfirm: () => void;
44
+ /** `data-testid` for the initial trigger; the confirm/cancel steps derive `${testId}-confirm` / `${testId}-cancel`. */
45
+ readonly testId: string;
46
+ }
47
+ /**
48
+ * A destructive-action button that requires a second click to fire. The first
49
+ * click swaps the trigger for an inline `Confirm` / `Cancel` pair rather than a
50
+ * blocking `window.confirm`, so the guard is testable and non-modal. The
51
+ * trigger keeps its `testId` (so existing tests that click it still reach the
52
+ * first step); the actual action only runs on the `${testId}-confirm` click.
53
+ */
54
+ declare const ConfirmButton: ({
55
+ children,
56
+ confirmLabel,
57
+ disabled,
58
+ onConfirm,
59
+ testId
60
+ }: ConfirmButtonProps) => ReactElement;
61
+ /**
62
+ * Live-socket status indicator. Reflects the client's aggregate WebSocket health
63
+ * so an operator can tell a healthy live channel from a silently-dropped socket
64
+ * (a panel showing "Live: on" while the socket is down would otherwise look
65
+ * identical to one that's simply idle).
66
+ */
67
+ declare const ConnectionBadge: () => ReactElement;
68
+ interface ErrorBoundaryProps {
69
+ readonly children: ReactNode;
70
+ /**
71
+ * Localised fallback heading. When omitted, falls back to `${label} failed`
72
+ * (or `Something went wrong` with no label). A class component can't use the
73
+ * `useT` hook, so localised text is passed in by its parents.
74
+ */
75
+ readonly fallbackTitle?: string;
76
+ /** Optional label naming the boundary's region, shown in the fallback. */
77
+ readonly label?: string;
78
+ /** Localised label for the retry button; defaults to `Try again`. */
79
+ readonly retryLabel?: string;
80
+ }
81
+ interface ErrorBoundaryState {
82
+ readonly error: Error | null;
83
+ }
84
+ /**
85
+ * Catches render/lifecycle errors in a panel so one throwing component doesn't
86
+ * blank the whole studio shell. Shows the error message with a "Try again"
87
+ * button that clears the boundary and re-renders its children.
88
+ */
89
+ declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
90
+ static getDerivedStateFromError(error: Error): ErrorBoundaryState;
91
+ override state: ErrorBoundaryState;
92
+ override componentDidCatch(error: Error, info: ErrorInfo): void;
93
+ readonly reset: () => void;
94
+ override render(): ReactNode;
95
+ }
96
+ interface ShardInputProps {
97
+ /** DOM `id` for the input, so an external label's `htmlFor` can target it. Optional. */
98
+ readonly id?: string;
99
+ readonly onChange: (value: string) => void;
100
+ /** `data-testid` for the input (panels keep their existing id, e.g. `mt-shard-input`). */
101
+ readonly testId: string;
102
+ readonly value: string;
103
+ }
104
+ /**
105
+ * Shard-key text field shared by every shard-scoped panel. Backed by a
106
+ * `&lt;datalist>` of recently-used shard keys (see {@link loadRecentShards}) so an
107
+ * operator can pick a shard they've visited instead of retyping it — the closest
108
+ * to a shard picker possible without server-side shard enumeration, which
109
+ * Durable Objects don't support. Panels remain responsible for recording a shard
110
+ * as used (via `recordShard`) when they actually query it.
111
+ */
112
+ declare const ShardInput: ({
113
+ id,
114
+ onChange,
115
+ testId,
116
+ value
117
+ }: ShardInputProps) => ReactElement;
118
+ declare const ADMIN_FUNCTION_PREFIX = "__lunora_admin__:";
119
+ /**
120
+ * Fully-qualified reserved paths the studio invokes via the client. The
121
+ * `__lunora_admin__:` prefix is spelled out inline rather than interpolated so
122
+ * the values stay emittable under `--isolatedDeclarations`. Every path is
123
+ * intercepted by `ShardDO` before user dispatch and gated by the server's
124
+ * `LUNORA_ADMIN_TOKEN`.
125
+ */
126
+ declare const ADMIN_FUNCTIONS: {
127
+ readonly clearCapturedMail: "__lunora_admin__:clearCapturedMail";
128
+ readonly clearTable: "__lunora_admin__:clearTable";
129
+ readonly createWorkflowInstance: "__lunora_admin__:createWorkflowInstance";
130
+ readonly deleteRows: "__lunora_admin__:deleteRows";
131
+ readonly describeTable: "__lunora_admin__:describeTable";
132
+ readonly describeTables: "__lunora_admin__:describeTables";
133
+ readonly exportShard: "__lunora_admin__:exportShard";
134
+ readonly facetColumn: "__lunora_admin__:facetColumn";
135
+ readonly getAdvisories: "__lunora_admin__:getAdvisories";
136
+ readonly getAuditLog: "__lunora_admin__:getAuditLog";
137
+ readonly getAuthMetrics: "__lunora_admin__:getAuthMetrics";
138
+ readonly getCapturedMail: "__lunora_admin__:getCapturedMail";
139
+ readonly getFunctionStats: "__lunora_admin__:getFunctionStats";
140
+ readonly listSubscriptions: "__lunora_admin__:listSubscriptions";
141
+ readonly listTableIndexes: "__lunora_admin__:listTableIndexes";
142
+ readonly listWorkflows: "__lunora_admin__:listWorkflows";
143
+ readonly getLogs: "__lunora_admin__:getLogs";
144
+ readonly getMetrics: "__lunora_admin__:getMetrics";
145
+ readonly getPitrBookmark: "__lunora_admin__:getPitrBookmark";
146
+ readonly getRequestLog: "__lunora_admin__:getRequestLog";
147
+ readonly getSecurityAudit: "__lunora_admin__:getSecurityAudit";
148
+ readonly getSettings: "__lunora_admin__:getSettings";
149
+ readonly getWorkflowInstanceStatus: "__lunora_admin__:getWorkflowInstanceStatus";
150
+ readonly importShard: "__lunora_admin__:importShard";
151
+ readonly listTables: "__lunora_admin__:listTables";
152
+ readonly maskPolicies: "__lunora_admin__:maskPolicies";
153
+ readonly migrationStatus: "__lunora_admin__:migrationStatus";
154
+ readonly pitrRestore: "__lunora_admin__:pitrRestore";
155
+ readonly readTablePage: "__lunora_admin__:readTablePage";
156
+ readonly rlsPolicies: "__lunora_admin__:rlsPolicies";
157
+ readonly runAs: "__lunora_admin__:runAs";
158
+ readonly runMigration: "__lunora_admin__:runMigration";
159
+ readonly runSql: "__lunora_admin__:runSql";
160
+ readonly sendTestMail: "__lunora_admin__:sendTestMail";
161
+ readonly storageOrphans: "__lunora_admin__:storageOrphans";
162
+ readonly storageReferences: "__lunora_admin__:storageReferences";
163
+ readonly storageRules: "__lunora_admin__:storageRules";
164
+ readonly studioFeatures: "__lunora_admin__:studioFeatures";
165
+ readonly writeRow: "__lunora_admin__:writeRow";
166
+ };
167
+ /** Comparison a {@link FilterClause} applies, mirroring `@lunora/do`'s `FilterOperator`. `contains` is a substring (LIKE). */
168
+ type FilterOperator = "contains" | "eq" | "gt" | "gte" | "lt" | "lte" | "ne";
169
+ /**
170
+ * One structured column filter passed to `readTablePage`, mirroring `@lunora/do`'s
171
+ * `FilterClause`. AND-combined with the substring search and the other clauses.
172
+ * `value` is sent as-is and bound server-side, so it never injects SQL.
173
+ */
174
+ interface FilterClause {
175
+ column: string;
176
+ operator: FilterOperator;
177
+ value?: unknown;
178
+ }
179
+ /** Which single-row mutation a {@link WriteRowArgs} performs. */
180
+ type WriteRowOp = "delete" | "insert" | "patch" | "replace";
181
+ /** Arguments for the `__lunora_admin__:writeRow` admin op. */
182
+ interface WriteRowArgs {
183
+ /** The row's fields. Required for insert/patch/replace; omitted for delete. */
184
+ doc?: Record<string, unknown>;
185
+ /** Primary key of the target row. Required for patch/replace/delete. */
186
+ id?: string;
187
+ op: WriteRowOp;
188
+ table: string;
189
+ }
190
+ /** Result of a {@link WriteRowArgs} op — the affected row's primary key. */
191
+ interface WriteRowResult {
192
+ id: null | string;
193
+ op: WriteRowOp;
194
+ }
195
+ /** Result of `__lunora_admin__:getCapturedMail` — the dev mail-catcher inbox, newest first. */
196
+ interface CapturedMailResult {
197
+ entries: CapturedMail[];
198
+ }
199
+ /** Reactive-cache hit/miss/eviction stats, present when a cache is configured. */
200
+ interface CacheStats {
201
+ bytes: number;
202
+ entries: number;
203
+ evictions: number;
204
+ hits: number;
205
+ misses: number;
206
+ }
207
+ /** Health snapshot returned by `__lunora_admin__:getMetrics` for one shard. */
208
+ interface ShardMetrics {
209
+ cache: CacheStats | null;
210
+ databaseSize: null | number;
211
+ errors: number;
212
+ requests: number;
213
+ shard: string;
214
+ sinceMs: number;
215
+ uptimeMs: number;
216
+ }
217
+ /**
218
+ * One full-scan attribution entry on a {@link FunctionCallStat}, mirroring
219
+ * `@lunora/do`'s `FunctionScanAttribution`: how many times the function
220
+ * full-scanned `table`. The causal evidence behind the "missing index" insight.
221
+ */
222
+ interface FunctionScanAttribution {
223
+ scans: number;
224
+ table: string;
225
+ }
226
+ /**
227
+ * Per-function execution counters returned by `__lunora_admin__:getFunctionStats`
228
+ * for one shard. Mirrors `@lunora/do`'s `FunctionCallStat`. Counters are
229
+ * per-DO-instance and reset on hibernation/restart — a "since this instance
230
+ * woke" readout. Durations are handler wall-clock milliseconds.
231
+ *
232
+ * `scans` / `scannedTables` carry the causal full-scan attribution (PLAN3 1.2).
233
+ * They're additive — a worker predating the feature reports `scans: 0` and
234
+ * `scannedTables: []`, so the fields are optional on the wire and the consumer
235
+ * defaults them. `conflicts` (OCC write-contention count, a subset of `errors`)
236
+ * is likewise additive and optional for the same back-compat reason.
237
+ */
238
+ interface FunctionCallStat {
239
+ calls: number;
240
+ /** OCC write-conflict count — a subset of `errors`; absent on a pre-conflict-tracking worker. */
241
+ conflicts?: number;
242
+ errors: number;
243
+ lastCalledAt: number;
244
+ lastErrorAt: null | number;
245
+ lastErrorMessage: null | string;
246
+ maxDurationMs: number;
247
+ path: string;
248
+ /** Per-table full-scan attribution, busiest scan first; absent on a pre-1.2 worker. */
249
+ scannedTables?: FunctionScanAttribution[];
250
+ /** Total full-table scans across every dispatch; absent on a pre-1.2 worker. */
251
+ scans?: number;
252
+ totalDurationMs: number;
253
+ }
254
+ /** Payload of a `__lunora_admin__:getFunctionStats` call, mirroring `@lunora/do`'s `FunctionStatsResult`. */
255
+ interface FunctionStatsResult {
256
+ functions: FunctionCallStat[];
257
+ sinceMs: number;
258
+ }
259
+ /**
260
+ * One declared index on a table, mirroring `@lunora/do`'s `TableIndexInfo`.
261
+ * `type` is the index kind; `fields` the indexed columns (sort fields for rank,
262
+ * text + filter fields for search, source field for vector); `unique` is set
263
+ * only for unique secondary indexes.
264
+ */
265
+ interface TableIndexInfo {
266
+ fields: string[];
267
+ name: string;
268
+ type: "index" | "rank" | "search" | "vector";
269
+ unique?: boolean;
270
+ }
271
+ /** Payload of a `__lunora_admin__:listTableIndexes` call, mirroring `@lunora/do`'s `TableIndexesResult`. */
272
+ interface TableIndexesResult {
273
+ indexes: TableIndexInfo[];
274
+ }
275
+ /** Severity of a buffered log entry, mirroring `@lunora/do`'s `LogLevel`. */
276
+ type LogLevel = "debug" | "error" | "info" | "warn";
277
+ /**
278
+ * One buffered log line returned by `__lunora_admin__:getLogs`. `functionPath`
279
+ * is the RPC that produced it (when known); `timestamp` is epoch-ms. Mirrors
280
+ * `@lunora/do`'s `LogEntry`.
281
+ */
282
+ interface LogEntry {
283
+ functionPath?: string;
284
+ level: LogLevel;
285
+ message: string;
286
+ timestamp: number;
287
+ }
288
+ /** Payload of a `__lunora_admin__:getLogs` call: the buffered entries, newest first. */
289
+ interface LogsResult {
290
+ entries: LogEntry[];
291
+ }
292
+ /**
293
+ * One recorded admin operation returned by `__lunora_admin__:getAuditLog`,
294
+ * mirroring `@lunora/do`'s `AuditEntry`. Unlike the in-memory logs, the audit
295
+ * log is durable and survives hibernation/restart. `seq` is a monotonic
296
+ * per-shard cursor; `op` the short op name (`writeRow`, `runMigration`,
297
+ * `importShard`, `applyCdc`); `table`/`id` are present when the op targets one;
298
+ * `detail` carries op-specific context (notably the acting `userId`).
299
+ */
300
+ interface AuditEntry {
301
+ detail?: Record<string, unknown>;
302
+ id?: string;
303
+ op: string;
304
+ seq: number;
305
+ table?: string;
306
+ ts: number;
307
+ }
308
+ /** Payload of a `__lunora_admin__:getAuditLog` call: the recorded entries, newest first. */
309
+ interface AuditLogResult {
310
+ entries: AuditEntry[];
311
+ }
312
+ /**
313
+ * How a deployment binding/var classifies, mirroring `@lunora/do`'s `SettingKind`.
314
+ * `var` is a plain Worker var, `secret` a sensitive string (always masked), and
315
+ * `binding` a non-string binding object (R2/KV/DO/D1/queue/service).
316
+ */
317
+ type SettingKind = "binding" | "secret" | "var";
318
+ /**
319
+ * One row of the read-only deployment-settings view, mirroring `@lunora/do`'s
320
+ * `SettingEntry`. `value` is a masked preview for `var`/`secret` strings (never
321
+ * the raw secret) and `null` for `binding` entries. The server masks every
322
+ * string value, so the studio only ever renders the masked text.
323
+ */
324
+ interface SettingEntry {
325
+ /** Coarse runtime class for `binding` entries (`r2`, `kv`, `durable-object`, …). */
326
+ bindingType?: string;
327
+ kind: SettingKind;
328
+ name: string;
329
+ value: null | string;
330
+ }
331
+ /**
332
+ * Best-effort deploy metadata, mirroring `@lunora/do`'s `DeployInfo`. Every
333
+ * field is optional: the server reads only what the Worker `env` exposes and
334
+ * omits the rest.
335
+ */
336
+ interface DeployInfo {
337
+ deploymentId?: string;
338
+ environment?: string;
339
+ versionTag?: string;
340
+ workerUrl?: string;
341
+ }
342
+ /** Payload of a `__lunora_admin__:getSettings` call, mirroring `@lunora/do`'s `SettingsResult`. */
343
+ interface SettingsResult {
344
+ deploy: DeployInfo;
345
+ settings: SettingEntry[];
346
+ }
347
+ /**
348
+ * Ordering/visual weight of a {@link SecurityFinding}, mirroring `@lunora/do`'s
349
+ * `SecurityFindingLevel`. Shares the studio's insight-severity vocabulary so the
350
+ * Security and Performance advisors render with one badge palette.
351
+ */
352
+ type SecurityFindingLevel = "error" | "info" | "warning";
353
+ /**
354
+ * Which deployment-level security heuristic fired, mirroring `@lunora/do`'s
355
+ * `SecurityFindingKind`. The studio maps each kind to a localized title,
356
+ * explanation, and remediation hint; the wire payload carries only the kind,
357
+ * level, and optional `detail`.
358
+ */
359
+ type SecurityFindingKind = "admin-token-weak" | "auth-secret-weak" | "cookies-insecure" | "cors-wildcard-credentials" | "csrf-disabled" | "dev-args-unredacted" | "security-headers-disabled" | "ws-gate-open";
360
+ /**
361
+ * One detected security issue from `__lunora_admin__:getSecurityAudit`, mirroring
362
+ * `@lunora/do`'s `SecurityFinding`. `detail` carries kind-specific context the
363
+ * studio interpolates into the localized copy (e.g. `{ length, min }` for a weak
364
+ * admin token); absent when the kind needs none.
365
+ */
366
+ interface SecurityFinding {
367
+ detail?: Record<string, unknown>;
368
+ kind: SecurityFindingKind;
369
+ level: SecurityFindingLevel;
370
+ }
371
+ /** Payload of a `__lunora_admin__:getSecurityAudit` call, mirroring `@lunora/do`'s `SecurityAuditResult`: every finding, worst-first. */
372
+ interface SecurityAuditResult {
373
+ findings: SecurityFinding[];
374
+ }
375
+ /** A user table plus its current row count. */
376
+ interface TableInfo {
377
+ name: string;
378
+ rowCount: number;
379
+ }
380
+ /** A window of rows from one table, plus the column list and total size. */
381
+ interface TablePage {
382
+ columns: string[];
383
+ /** Foreign-key columns (column → target table) for `v.id("target")` fields, so the UI can link those cells. */
384
+ refs?: Record<string, string>;
385
+ rows: Record<string, unknown>[];
386
+ total: number;
387
+ }
388
+ /** Direction a data migration is run in. Mirrors `@lunora/do`. */
389
+ type MigrationDirection = "down" | "up";
390
+ /** Lifecycle of a data-migration run. Mirrors `@lunora/do`. */
391
+ type MigrationStatus = "completed" | "failed" | "in_progress";
392
+ /**
393
+ * One persisted migration run-state row, as returned by the
394
+ * `__lunora_admin__:migrationStatus` RPC (`{ migrations: MigrationStatusRow[] }`).
395
+ */
396
+ interface MigrationStatusRow {
397
+ changed: number;
398
+ cursor: null | string;
399
+ direction: MigrationDirection;
400
+ error: null | string;
401
+ id: string;
402
+ processed: number;
403
+ startedAt: null | number;
404
+ status: MigrationStatus;
405
+ updatedAt: null | number;
406
+ }
407
+ /** Result of a single `__lunora_admin__:runMigration` invocation against one shard. */
408
+ interface MigrationRunResult {
409
+ changed: number;
410
+ cursor: null | string;
411
+ direction: MigrationDirection;
412
+ dryRun: boolean;
413
+ id: string;
414
+ processed: number;
415
+ status: MigrationStatus;
416
+ }
417
+ /** Arguments accepted by the `__lunora_admin__:runMigration` RPC. */
418
+ interface RunMigrationArgs {
419
+ batchSize?: number;
420
+ direction?: MigrationDirection;
421
+ dryRun?: boolean;
422
+ id: string;
423
+ maxBatches?: number;
424
+ }
425
+ /** One NDJSON line: a row from `table`, shaped per its schema. */
426
+ interface ExportRow {
427
+ doc: Record<string, unknown>;
428
+ table: string;
429
+ }
430
+ /** A row that could not be inserted during an import. */
431
+ interface ImportError {
432
+ code: string;
433
+ line: number;
434
+ message: string;
435
+ table: string;
436
+ }
437
+ /** Result of a single `__lunora_admin__:importShard` invocation against one shard. */
438
+ interface ImportShardResult {
439
+ conflicts: number;
440
+ errors: ImportError[];
441
+ inserted: Record<string, number>;
442
+ }
443
+ /**
444
+ * One shard's request total from the worker's `POST /_lunora/admin/shard-traffic`
445
+ * endpoint, mirroring `@lunora/runtime`'s `ShardTrafficEntry`. `requests` is the
446
+ * shard's lifetime dispatch count (`0` for a shard that failed/timed out);
447
+ * `shardKey` is the DO id name (`""` for the root shard). The cross-shard feed
448
+ * the `hot_shard` runtime advisor consumes to compute skew.
449
+ */
450
+ interface ShardTrafficEntry {
451
+ requests: number;
452
+ shardKey: string;
453
+ }
454
+ /**
455
+ * Payload of a `POST /_lunora/admin/shard-traffic` call, mirroring the runtime
456
+ * coordinator's shard-traffic fan-out result: one `{ shardKey, requests }` entry
457
+ * per live shard plus the ok / failed counts. Fanned out on demand (not on the
458
+ * metrics hot path) so the panel can feed `hot_shard` the whole shard set's
459
+ * request volumes.
460
+ */
461
+ interface ShardTrafficResult {
462
+ failed: number;
463
+ ok: number;
464
+ shards: ShardTrafficEntry[];
465
+ }
466
+ /** Visual + ordering weight of a detected issue. */
467
+ type InsightSeverity = "error" | "info" | "warning";
468
+ /**
469
+ * Which heuristic fired. The panel maps each kind to a localized title/detail,
470
+ * so the detection stays free of presentation strings (and trivially testable).
471
+ *
472
+ * `missing-index` is the causal upgrade of `slow-function`: a slow function
473
+ * whose latency is explained by a full-table scan. When the scan attribution
474
+ * pins the cause, the insight names the scanned table(s) (`tables`) and deep-
475
+ * links to the Schema/Indexes tab to add the index, rather than leaving the
476
+ * slowness an unattributed symptom.
477
+ */
478
+ type InsightKind = "high-error-rate" | "high-evictions" | "high-write-contention" | "low-cache-hit-rate" | "missing-index" | "slow-function";
479
+ /**
480
+ * One detected issue. `value` is the headline number whose meaning depends on
481
+ * `kind`: a 0–1 rate for cache-hit / error-rate, a millisecond figure for
482
+ * slow-function / missing-index, an entry count for evictions. `fn` is set only
483
+ * for per-function insights; `message` carries the last error for
484
+ * high-error-rate; `tables` carries the full-scanned tables (busiest first) for
485
+ * the causal `missing-index` kind. For `high-write-contention` it is the OCC
486
+ * conflict ratio (conflicts / calls).
487
+ */
488
+ interface Insight {
489
+ fn?: string;
490
+ kind: InsightKind;
491
+ message?: string;
492
+ severity: InsightSeverity;
493
+ tables?: string[];
494
+ value: number;
495
+ }
496
+ /** Tunable cut-offs for {@link deriveInsights}. Exposed so a host (or a test) can tighten/loosen them. */
497
+ interface InsightThresholds {
498
+ /** Flag functions whose error ratio is at or above this (0–1). */
499
+ highErrorRate: number;
500
+ /** Flag functions whose OCC write-conflict ratio is at or above this (0–1). */
501
+ highWriteContention: number;
502
+ /** Flag a cache whose hit rate is below this (0–1). */
503
+ lowCacheHitRate: number;
504
+ /** Require this many cache samples (hits + misses) before judging hit rate, to avoid cold-start noise. */
505
+ minCacheSamples: number;
506
+ /** Require this many calls before judging a function's conflict ratio. */
507
+ minConflictCalls: number;
508
+ /** Require this many calls before judging a function's error ratio. */
509
+ minErrorCalls: number;
510
+ /** Flag functions whose slowest call is at or above this many milliseconds. */
511
+ slowFunctionMs: number;
512
+ }
513
+ declare const DEFAULT_INSIGHT_THRESHOLDS: InsightThresholds;
514
+ /**
515
+ * Derive a prioritised list of issues from the two snapshots the studio
516
+ * already pulls — the `getMetrics` health snapshot and the `getFunctionStats`
517
+ * per-function table. Pure and side-effect-free: same inputs, same output, so
518
+ * the heuristics can be unit-tested without rendering.
519
+ *
520
+ * Heuristics: low-cache-hit-rate (cache below the threshold once enough samples
521
+ * exist — a cold cache isn't a problem); high-evictions (more evictions than
522
+ * hits, so the cache is too small or churning on invalidation); missing-index (a
523
+ * slow function whose latency is *explained* by a full-table scan — the causal
524
+ * upgrade of slow-function, naming the scanned table(s)); slow-function (a
525
+ * function whose slowest call crosses the threshold with no scan attribution to
526
+ * blame); high-error-rate (a function failing over a meaningful count);
527
+ * high-write-contention (a function whose OCC write conflicts make up a
528
+ * meaningful share of calls — a sharding candidate).
529
+ *
530
+ * A slow function with full-scan attribution emits `missing-index` (causal, with
531
+ * `tables`) instead of the bare `slow-function`, so the panel can link straight
532
+ * to the fix rather than restating the symptom.
533
+ */
534
+ declare const deriveInsights: (metrics: ShardMetrics | null, functions: FunctionCallStat[] | null, thresholds?: InsightThresholds) => Insight[];
535
+ interface InsightsPanelProps {
536
+ /** Shard key the snapshots target on first load. Defaults to the root shard. */
537
+ readonly initialShardKey?: string;
538
+ /**
539
+ * Fan the cross-shard traffic feed out for `table`, returning each shard's
540
+ * `{ shardKey, requests }` total — the input the `hot_shard` advisor lint
541
+ * needs. Defaults to `client.shardTraffic(table)` (the admin-gated
542
+ * `POST /_lunora/admin/shard-traffic` fan-out). Best-effort: a rejection
543
+ * leaves `hot_shard` dormant rather than blanking the panel. Injectable so
544
+ * tests can drive the skew without a worker.
545
+ */
546
+ readonly loadShardTraffic?: (table: string) => Promise<ShardTrafficResult>;
547
+ }
548
+ /**
549
+ * The Performance Advisor — a 1-to-1 of Supabase's Performance Advisor: severity
550
+ * tabs over a findings table (via {@link AdvisorView}). It pulls the `getMetrics`
551
+ * health snapshot and `getFunctionStats` per-function table for one shard, then
552
+ * maps the issues {@link deriveInsights} detects (low cache hit rate, high
553
+ * eviction, slow functions, missing indexes, error spikes) into rows. A
554
+ * `missing-index` row carries an inline "add the index" jump to the Schema tab.
555
+ * Both reads are best-effort — one failing still yields the other's insights.
556
+ */
557
+ declare const InsightsPanel: ({
558
+ initialShardKey,
559
+ loadShardTraffic
560
+ }: InsightsPanelProps) => ReactElement;
561
+ /**
562
+ * The Security Advisor — a 1-to-1 of Supabase's Security Advisor: severity tabs
563
+ * (Errors / Warnings / Info) over a findings table. It pulls `getSecurityAudit`
564
+ * (deployment-wide, so it targets the root shard and needs no shard selector) and
565
+ * maps each finding the server derived from the Worker `env` — weak admin token,
566
+ * an open WebSocket gate, a dev-mode request log keeping un-redacted args — into a
567
+ * row. These are signals only lunora can surface: Cloudflare's dashboard can't
568
+ * reason about lunora's admin/WS gates or its log-redaction policy.
569
+ */
570
+ declare const SecurityAdvisorPanel: () => ReactElement;
571
+ interface ApiDocsPanelProps {
572
+ /**
573
+ * Registered functions to document. Mirrors the list the Functions tab's
574
+ * runner and stats panels receive — a query/mutation/action's `kind` is
575
+ * compile-time-only, so it must be named here. When omitted the panel still
576
+ * renders (tables come from the admin RPC) and shows an empty functions list.
577
+ */
578
+ readonly functions?: FunctionDescriptor[];
579
+ /** Shard key the table list is read from. Defaults to the root shard. */
580
+ readonly initialShardKey?: string;
581
+ }
582
+ /** Inputs every function snippet builder closes over — the split path plus its `kind`. */
583
+ /**
584
+ * Per-resource "how to call this from your app" browser, generated from the
585
+ * registered functions and tables the studio already has — no new endpoints.
586
+ * The left rail lists functions grouped by file plus a Tables section; the right
587
+ * pane shows copy-paste snippets (React / Client / CLI for functions; the typed
588
+ * data-model usage for tables).
589
+ *
590
+ * Args are a placeholder: the real argument shape lives in the codegen'd `api`
591
+ * types this browser never loads, the same way Supabase's usage snippets show
592
+ * placeholders.
593
+ */
594
+ declare const ApiDocsPanel: ({
595
+ functions,
596
+ initialShardKey
597
+ }: ApiDocsPanelProps) => ReactElement;
598
+ interface ApiReferencePanelProps {
599
+ /**
600
+ * Inline OpenAPI document. When supplied the panel renders it directly and
601
+ * skips the fetch — used by the mock harness and by hosts that already hold
602
+ * the generated spec. When omitted the panel fetches the worker's
603
+ * admin-gated `GET /_lunora/admin/openapi` endpoint via the client.
604
+ */
605
+ readonly spec?: unknown;
606
+ }
607
+ /**
608
+ * In-studio OpenAPI reference: renders the generated OpenAPI 3.1 document with
609
+ * the studio-native {@link ReferenceView} — a tag-grouped operation browser,
610
+ * schema tables, a live "try it" console, and copy-paste request samples, all
611
+ * themed to the studio. The spec comes from an inline
612
+ * {@link ApiReferencePanelProps.spec} prop, or — by default — the worker's
613
+ * admin-gated `GET /_lunora/admin/openapi` endpoint fetched through the client.
614
+ *
615
+ * This replaced the embedded Scalar reference (a Vue app in React): Scalar's
616
+ * portal/overlay layers repeatedly intercepted clicks and froze the tab, and it
617
+ * shipped a multi-megabyte bundle. The native view is overlay-free and reuses
618
+ * the studio's own primitives.
619
+ */
620
+ declare const ApiReferencePanel: ({
621
+ spec: inlineSpec
622
+ }: ApiReferencePanelProps) => ReactElement;
623
+ interface ApiTabProps {
624
+ /** Registered functions documented by the snippets sub-view. Threaded host → studio. */
625
+ readonly functions?: FunctionDescriptor[];
626
+ /** Shard key the snippets view reads its table list from. */
627
+ readonly initialShardKey?: string;
628
+ /**
629
+ * Inline OpenAPI document for the reference sub-view. When omitted the
630
+ * reference fetches the worker's `GET /_lunora/admin/openapi` endpoint.
631
+ */
632
+ readonly openApiSpec?: unknown;
633
+ /**
634
+ * Inline OpenRPC document for the reference sub-view's OpenRPC format. When
635
+ * omitted the OpenRPC view fetches the worker's `GET /_lunora/admin/openrpc`
636
+ * endpoint. OpenRPC is the RPC-native spec (RPC functions only); OpenAPI
637
+ * additionally covers `httpRouter()` REST routes.
638
+ */
639
+ readonly openRpcSpec?: unknown;
640
+ }
641
+ /**
642
+ * The studio's API tab. Hosts two complementary surfaces behind a segmented
643
+ * toggle. The Reference view renders a machine-readable spec — the OpenAPI 3.1
644
+ * document or the RPC-native OpenRPC document — through the studio-native
645
+ * reference UI (operation browser, schema tables, a live "try it" console, and a
646
+ * request-sample rail), with a small format switch between them. The Snippets
647
+ * view is the per-function React / Client / CLI copy-paste browser
648
+ * (`api-docs-panel`), the lightweight "how do I call this" DX.
649
+ *
650
+ * Reference is the default; OpenAPI is the default format (the richer,
651
+ * spec-driven view that also covers REST). Each format degrades to a clear
652
+ * empty state when its spec isn't wired.
653
+ */
654
+ declare const ApiTab: ({
655
+ functions,
656
+ initialShardKey,
657
+ openApiSpec,
658
+ openRpcSpec
659
+ }: ApiTabProps) => ReactElement;
660
+ interface OpenRpcReferencePanelProps {
661
+ /**
662
+ * Inline OpenRPC document. When supplied the panel renders it directly and
663
+ * skips the fetch — used by the mock harness and by hosts that already hold
664
+ * the generated spec. When omitted the panel fetches the worker's
665
+ * admin-gated `GET /_lunora/admin/openrpc` endpoint via the client.
666
+ */
667
+ readonly spec?: unknown;
668
+ }
669
+ /**
670
+ * In-studio OpenRPC reference. OpenRPC is the RPC-native spec (a `methods` array
671
+ * over the JSON-RPC-shaped `POST /_lunora/rpc` transport), documenting the RPC
672
+ * functions only. It is parsed into the shared `ApiModel` and rendered by the
673
+ * same studio-native {@link ReferenceView} the OpenAPI panel uses, so both
674
+ * formats share one operation browser, schema view, try-it console, and sample
675
+ * rail.
676
+ *
677
+ * The spec comes from an inline {@link OpenRpcReferencePanelProps.spec} prop, or
678
+ * — by default — the worker's admin-gated `GET /_lunora/admin/openrpc` endpoint.
679
+ */
680
+ declare const OpenRpcReferencePanel: ({
681
+ spec: inlineSpec
682
+ }: OpenRpcReferencePanelProps) => ReactElement;
683
+ /**
684
+ * A shareable data-browser view: the table, storage tier, shard, structured
685
+ * filters, substring search, and sort that together reproduce exactly what the
686
+ * grid is showing. This is the unit that is serialized into the URL (so the link
687
+ * IS the query) and persisted by name in {@link loadSavedQueries}. Every field is
688
+ * optional so a partial/legacy URL still hydrates into a sensible default view.
689
+ */
690
+ interface DataView {
691
+ /** Structured `column operator value` clauses, AND-combined with the search. */
692
+ filters?: FilterClause[];
693
+ /** Single-column sort, server-side; absent → the table's natural order. */
694
+ orderBy?: {
695
+ column: string;
696
+ direction: "asc" | "desc";
697
+ };
698
+ /** Substring search across all columns. */
699
+ search?: string;
700
+ /** Shard key the view targets; absent/empty → the root shard. */
701
+ shard?: string;
702
+ /** The open table. */
703
+ table?: string;
704
+ /** Storage tier the table lives in; absent → the shard (SQLite) tier. */
705
+ tier?: "global" | "shard";
706
+ }
707
+ /** A user-named, persisted {@link DataView} — the "canned query" the saved-queries panel lists. */
708
+ interface SavedQuery {
709
+ name: string;
710
+ view: DataView;
711
+ }
712
+ /** Saved queries, most-recently-saved first. Empty when storage is unavailable or empty. */
713
+ interface DataBrowserProps {
714
+ /**
715
+ * Allow editing: surfaces insert/edit/delete actions that issue
716
+ * `__lunora_admin__:writeRow` ops through the schema-aware writer. Off by
717
+ * default — the browser is read-only unless the host opts in.
718
+ */
719
+ readonly editable?: boolean;
720
+ /**
721
+ * Names of the `.global()` (D1-backed) tables. A `v.id` ref cell whose target
722
+ * is one of these is followed cross-tier via `onNavigateToGlobal` instead of
723
+ * being read from this shard (where it doesn't exist). Supplied by the Table
724
+ * editor; defaults to none when the browser is used standalone.
725
+ */
726
+ readonly globalTableNames?: ReadonlySet<string>;
727
+ /** Structured filters to hydrate from a shared link / saved query. */
728
+ readonly initialFilters?: FilterClause[];
729
+ /** Sort to hydrate from a shared link / saved query. */
730
+ readonly initialOrderBy?: DataView["orderBy"];
731
+ /** Substring search to hydrate from a shared link / saved query. */
732
+ readonly initialSearch?: string;
733
+ /** Shard key the browser targets on first load. Defaults to the root shard. */
734
+ readonly initialShardKey?: string;
735
+ /**
736
+ * Follow a `v.id` ref whose target is a global table — the Table editor switches
737
+ * to the global tier and opens that table. When omitted (standalone use), a ref
738
+ * to a global table falls through to the in-shard read (and surfaces its error).
739
+ */
740
+ readonly onNavigateToGlobal?: (table: string, id: string) => void;
741
+ /**
742
+ * Called whenever the open table changes, so the host can mirror it to the URL
743
+ * (the Table editor pushes `?table=…`). Omitted in standalone use.
744
+ */
745
+ readonly onSelectTable?: (table: string) => void;
746
+ /**
747
+ * Called whenever the loaded view (shard / search / filters / sort) changes, so
748
+ * the host can mirror it to the URL — making every view a shareable link.
749
+ * Omitted in standalone use (view state stays in-component).
750
+ */
751
+ readonly onViewChange?: (view: Pick<DataView, "filters" | "orderBy" | "search" | "shard">) => void;
752
+ /** Rows requested per page. Clamped server-side to `[1, 500]`. */
753
+ readonly pageSize?: number;
754
+ /**
755
+ * The canned-query toolbar's handlers + saved list. Supplied by the Table editor
756
+ * (it owns the router and the `saved-queries` localStorage helper); omitted in
757
+ * standalone use, which hides the toolbar entirely. `onSaveQuery` receives the
758
+ * name plus the current view to persist.
759
+ */
760
+ readonly queryBar?: {
761
+ readonly onApplyQuery: (query: SavedQuery) => void;
762
+ readonly onCopyLink: () => void;
763
+ readonly onDeleteQuery: (name: string) => void;
764
+ readonly onSaveQuery: (name: string, view: DataView) => void;
765
+ readonly saved: ReadonlyArray<SavedQuery>;
766
+ };
767
+ /**
768
+ * The schema/source selector rendered at the top of the table-list sidebar —
769
+ * the Table editor's `schema public ▾` switch. Supplied when this browser is
770
+ * composed into the Table editor; omitted when it's used alone.
771
+ */
772
+ readonly schemaSwitch?: ReactNode;
773
+ /**
774
+ * The table named in the URL. Drives the selection — a deep link or browser
775
+ * back/forward to a different `?table=…` re-opens that table. Supplied by the
776
+ * Table editor; omitted in standalone use (selection stays purely in-component).
777
+ */
778
+ readonly tableParam?: string;
779
+ }
780
+ /**
781
+ * Read-only data browser for a single shard's SQLite database. Lists the user
782
+ * tables (via the `__lunora_admin__:listTables` RPC), then pages through the
783
+ * rows of whichever table is selected (`__lunora_admin__:readTablePage`).
784
+ *
785
+ * Both calls travel over the ordinary `useLunora` client transport; the
786
+ * admin RPCs are intercepted inside the Durable Object and are gated by the
787
+ * server's `LUNORA_ADMIN_TOKEN`. The host is responsible for configuring the
788
+ * client's auth token — this component issues no credentials of its own.
789
+ *
790
+ * The table view is built on a headless `@tanstack/react-table` model: column
791
+ * defs derive from `page.columns`, sorting and (global) filtering run
792
+ * page-locally over the loaded rows, and the rendered rows are virtualized with
793
+ * `@tanstack/react-virtual` so a large page never inflates the DOM. None of this
794
+ * touches the server — pagination still flows through `readTablePage`. All of
795
+ * that state lives in {@link useDataBrowser}; this component is just the markup.
796
+ */
797
+ declare const DataBrowser: ({
798
+ editable,
799
+ globalTableNames,
800
+ initialFilters,
801
+ initialOrderBy,
802
+ initialSearch,
803
+ initialShardKey,
804
+ onNavigateToGlobal,
805
+ onSelectTable,
806
+ onViewChange,
807
+ pageSize: initialPageSize,
808
+ queryBar,
809
+ schemaSwitch,
810
+ tableParam
811
+ }: DataBrowserProps) => ReactElement;
812
+ /** A filter row as edited in the UI — the value is always a string until coerced for the wire. */
813
+ interface EditableFilter {
814
+ column: string;
815
+ operator: FilterOperator;
816
+ value: string;
817
+ }
818
+ /**
819
+ * Convert the UI's string-valued filter rows into wire {@link FilterClause}s:
820
+ * drops rows with no column, and coerces a numeric string to a number for the
821
+ * comparison operators (so `age > 18` compares numerically, not lexically).
822
+ * `contains` always stays a string.
823
+ */
824
+ declare const toFilterClauses: (filters: ReadonlyArray<EditableFilter>) => FilterClause[];
825
+ /**
826
+ * The data browser's filtering controls: the substring search box plus a stack
827
+ * of structured `column operator value` rows. All state is owned by the parent
828
+ * (the data-browser model); this is the control markup, emitting the full
829
+ * filter array up on every edit. Raw strings (no i18n) to match the surrounding
830
+ * data-browser controls.
831
+ */
832
+ declare const DataFilters: ({
833
+ columns,
834
+ filters,
835
+ onFiltersChange,
836
+ onSearchChange,
837
+ search
838
+ }: {
839
+ columns: ReadonlyArray<string>;
840
+ filters: ReadonlyArray<EditableFilter>;
841
+ onFiltersChange: (filters: EditableFilter[]) => void;
842
+ onSearchChange: (event: ChangeEvent<HTMLInputElement>) => void;
843
+ search: string;
844
+ }) => ReactElement;
845
+ interface GlobalDataBrowserProps {
846
+ /**
847
+ * Table to open automatically on mount (and whenever it changes). Used by the
848
+ * Table editor when a `v.id` reference in a shard row points at a `.global()`
849
+ * table: clicking it switches to the global tier and lands here with that table
850
+ * pre-selected. Each distinct value is applied once, so the operator can still
851
+ * navigate away afterwards.
852
+ */
853
+ readonly initialTable?: string;
854
+ /**
855
+ * Called whenever the open table changes, so the host can mirror it to the URL
856
+ * (the Table editor pushes `?table=…`). Omitted in standalone use.
857
+ */
858
+ readonly onSelectTable?: (table: string) => void;
859
+ /** Rows requested per page. Clamped server-side to `[1, 500]`. */
860
+ readonly pageSize?: number;
861
+ /**
862
+ * The schema/source selector rendered at the top of the table-list sidebar —
863
+ * the Table editor's `schema public ▾` switch. Supplied when this browser is
864
+ * composed into the Table editor; omitted when it's used alone.
865
+ */
866
+ readonly schemaSwitch?: ReactNode;
867
+ }
868
+ /**
869
+ * Read-only browser for `.global()` (D1-backed) tables. Twin of `DataBrowser`,
870
+ * but not shard-scoped: it lists tables via `listGlobalTables()` and pages rows
871
+ * via `readGlobalTablePage()`. Laid out like Supabase's Table Editor — a left
872
+ * table sidebar + a bordered grid with a paginated footer — and gated by the
873
+ * server's `LUNORA_ADMIN_TOKEN`.
874
+ */
875
+ declare const GlobalDataBrowser: ({
876
+ initialTable,
877
+ onSelectTable,
878
+ pageSize: initialPageSize,
879
+ schemaSwitch
880
+ }?: GlobalDataBrowserProps) => ReactElement;
881
+ interface TableEditorProps {
882
+ /**
883
+ * Allow editing the shard-local tables (insert/edit/delete). Forwarded to the
884
+ * shard {@link DataBrowser}; the global D1 browser is always read-only. Off by
885
+ * default — see {@link DataBrowser}.
886
+ */
887
+ readonly editable?: boolean;
888
+ /** Shard key the shard browser targets on first load. Defaults to the root shard. */
889
+ readonly initialShardKey?: string;
890
+ }
891
+ /**
892
+ * The Table editor: browses your application's tables across both storage tiers
893
+ * from one section. A schema switch in the sidebar header (Supabase's
894
+ * `schema public ▾`) toggles between the per-shard SQLite browser
895
+ * (`.shardBy(...)`, editable when the host opts in) and the read-only global D1
896
+ * browser (`.global()`) — folding what used to be a separate "Global Tables" tab
897
+ * into a single editor (`STUDIO-REDESIGN-PLAN.md` §2).
898
+ *
899
+ * The active tier and open table live in the URL search params (`?schema=global`,
900
+ * `?table=…`) rather than component state, so every selection is a real, shareable
901
+ * URL and browser back/forward moves between tables and tiers. The browsers push on
902
+ * selection and re-open whatever the URL names.
903
+ */
904
+ declare const TableEditor: ({
905
+ editable,
906
+ initialShardKey
907
+ }: TableEditorProps) => ReactElement;
908
+ interface ExportImportPanelProps {
909
+ /** Shard key the panel targets. Defaults to the root shard. */
910
+ readonly initialShardKey?: string;
911
+ }
912
+ /**
913
+ * Snapshot and restore a single shard's data as NDJSON.
914
+ *
915
+ * "Export" reads every shard-local row via `__lunora_admin__:exportShard` and
916
+ * renders it as NDJSON for download/copy. "Import" parses NDJSON the operator
917
+ * pastes in and replays it through `__lunora_admin__:importShard`, reporting
918
+ * inserted counts, id conflicts and per-row errors. Globally-scoped (`.global()`)
919
+ * tables live in D1 and are intentionally out of scope here.
920
+ *
921
+ * Both calls travel over the {@link useLunora} client transport and are gated by
922
+ * the server's `LUNORA_ADMIN_TOKEN`.
923
+ */
924
+ declare const ExportImportPanel: ({
925
+ initialShardKey
926
+ }: ExportImportPanelProps) => ReactElement;
927
+ interface MigrationsPanelProps {
928
+ /** Shard key the panel targets. Defaults to the root shard. */
929
+ readonly initialShardKey?: string;
930
+ }
931
+ /**
932
+ * Inspect and drive data migrations on a single shard.
933
+ *
934
+ * Reads the persisted run-state via the `__lunora_admin__:migrationStatus` RPC
935
+ * and lets an operator kick off a migration by id (`__lunora_admin__:runMigration`)
936
+ * with a direction, an optional batch cap and a dry-run toggle. Both calls
937
+ * travel over the ordinary {@link useLunora} client transport and are gated by
938
+ * the server's `LUNORA_ADMIN_TOKEN` — this component issues no credentials of
939
+ * its own.
940
+ */
941
+ declare const MigrationsPanel: ({
942
+ initialShardKey
943
+ }: MigrationsPanelProps) => ReactElement;
944
+ interface PitrPanelProps {
945
+ /** Shard key the PITR ops target. Defaults to the root shard. */
946
+ readonly initialShardKey?: string;
947
+ }
948
+ /**
949
+ * Native Durable-Object point-in-time recovery for one shard — the **Time
950
+ * Travel** view.
951
+ *
952
+ * Reads the shard's current bookmark, previews the bookmark nearest a chosen
953
+ * time, and (behind a confirm step) restores the shard to a time or an explicit
954
+ * bookmark via the `__lunora_admin__:pitrRestore` RPC, surfacing the returned
955
+ * undo bookmark so the restore can be reversed. All ops run over the
956
+ * {@link useLunora} client and are gated by the server's `LUNORA_ADMIN_TOKEN`.
957
+ *
958
+ * In-place recovery covers the last 30 days; for older or off-platform recovery
959
+ * use the snapshot tier (`lunora backup` / the backup registry item).
960
+ */
961
+ declare const PitrPanel: ({
962
+ initialShardKey
963
+ }: PitrPanelProps) => ReactElement;
964
+ interface FunctionRunnerProps {
965
+ /**
966
+ * Functions to expose. When omitted, the runner auto-discovers them via the
967
+ * client's `listFunctions()` (the admin-gated `/_lunora/admin/functions`
968
+ * endpoint), so it works with no wiring when the worker is built with a
969
+ * `functions` registry. Supply the list to override discovery.
970
+ */
971
+ readonly functions?: FunctionDescriptor[];
972
+ /**
973
+ * Expose the "Run as identity" control — execute the selected function AS a
974
+ * chosen authenticated user so an operator can test auth + RLS behavior.
975
+ * Security-sensitive: the run is forwarded over the admin-gated
976
+ * `__lunora_admin__:runAs` RPC, which forges the per-request identity. The
977
+ * host sets this only on a trusted loopback-dev gate (the `Studio` component's
978
+ * `runAsIdentity` prop); off by default, the runner always runs with the
979
+ * caller's own (admin) identity.
980
+ */
981
+ readonly runAsIdentity?: boolean;
982
+ }
983
+ /**
984
+ * Interactive runner for the registered functions: pick one, edit its JSON
985
+ * arguments, optionally target a shard, then invoke it against the live
986
+ * {@link useLunora} client and inspect the result or error.
987
+ *
988
+ * By default the function list is auto-discovered from the worker's
989
+ * `/_lunora/admin/functions` endpoint; pass an explicit `functions` array to
990
+ * skip discovery (a query/mutation/action's `kind` is compile-time-only, so it
991
+ * must be named).
992
+ */
993
+ declare const FunctionRunner: ({
994
+ functions: functionsProp,
995
+ runAsIdentity
996
+ }?: FunctionRunnerProps) => ReactElement;
997
+ interface FunctionStatsPanelProps {
998
+ /** Descriptors from codegen, used to annotate each row with the function's `kind`. */
999
+ readonly functions?: FunctionDescriptor[];
1000
+ /** Shard key the panel reports on. Defaults to the root shard. */
1001
+ readonly initialShardKey?: string;
1002
+ }
1003
+ /**
1004
+ * Per-function execution metrics for one shard: call count, error count/rate,
1005
+ * mean and slowest handler latency, last-run time, and the most recent error
1006
+ * message. Reads via the `__lunora_admin__:getFunctionStats` RPC over the
1007
+ * {@link useLunora} client; gated by the server's `LUNORA_ADMIN_TOKEN`.
1008
+ *
1009
+ * Counters are per-DO-instance and reset on hibernation/restart — this is a
1010
+ * "since this instance woke" readout, mirroring the metrics panel. The panel is
1011
+ * always live: a subscription opens once the first seed commits a shard and
1012
+ * re-pushes on every server write-flush so the table updates as mutations land.
1013
+ */
1014
+ declare const FunctionStatsPanel: ({
1015
+ functions,
1016
+ initialShardKey
1017
+ }: FunctionStatsPanelProps) => ReactElement;
1018
+ interface HomePanelProps {
1019
+ /** Shard key the health digest targets on first load. Defaults to the root shard. */
1020
+ readonly initialShardKey?: string;
1021
+ }
1022
+ /**
1023
+ * The Home overview — the studio's landing page. It pulls the root shard's
1024
+ * health snapshot, the function stats, the two advisor signals, the live
1025
+ * subscription pulse, and the recent admin audit log, then presents an
1026
+ * at-a-glance digest: a KPI row (requests, errors, latency, database size), a
1027
+ * busiest-functions leaderboard, live connections, recent activity, the advisor
1028
+ * summary, and connect/quick-link shortcuts. Every read is best-effort — a
1029
+ * missing admin token or a cold instance leaves a card showing a muted
1030
+ * placeholder rather than blanking the page.
1031
+ */
1032
+ declare const HomePanel: ({
1033
+ initialShardKey
1034
+ }: HomePanelProps) => ReactElement;
1035
+ interface AuditPanelProps {
1036
+ /** Shard key the panel reports on. Defaults to the root shard. */
1037
+ readonly initialShardKey?: string;
1038
+ }
1039
+ /**
1040
+ * Durable audit log for one shard: the admin state-changing operations
1041
+ * (`writeRow`, `runMigration`, `importShard`, `applyCdc`) recorded to the
1042
+ * reserved `__lunora_audit__` table, newest first. Reads via the
1043
+ * `__lunora_admin__:getAuditLog` RPC over the {@link useLunora} client; gated by
1044
+ * the server's `LUNORA_ADMIN_TOKEN`.
1045
+ *
1046
+ * Unlike the logs panel (an in-memory ring that resets on hibernation), the
1047
+ * audit log is durable and bounded only by a retention cap. The panel is always
1048
+ * live: a subscription opens once the first seed commits a shard and re-pushes on
1049
+ * every server write-flush so new entries appear without a manual refresh. The op
1050
+ * filter is client-side over the already-fetched buffer — it never triggers a refetch.
1051
+ */
1052
+ declare const AuditPanel: ({
1053
+ initialShardKey
1054
+ }: AuditPanelProps) => ReactElement;
1055
+ interface LogsPanelProps {
1056
+ /** Shard key the panel reports on. Defaults to the root shard. */
1057
+ readonly initialShardKey?: string;
1058
+ }
1059
+ /** A relative time-range window over the Errors buffer, or `all` (no bound). */
1060
+ /**
1061
+ * The shard's log feed, newest first, over the gated `__lunora_admin__:*` RPC
1062
+ * layer (gated by the server's `LUNORA_ADMIN_TOKEN`). Two views.
1063
+ *
1064
+ * The Requests view (`getRequestLog`) is the durable, structured per-request log
1065
+ * `@lunora/do` writes once per `/rpc` dispatch (PLAN3 §1.1): function path,
1066
+ * shard, acting user/identity, redacted args, outcome, duration, and tables
1067
+ * read/written. It survives hibernation/restart (bounded retention) and is
1068
+ * filtered/correlated SERVER-side on function-path prefix, userId, shard,
1069
+ * outcome, and a touched table.
1070
+ *
1071
+ * The Errors view (`getLogs`) is the legacy in-memory RPC-error buffer, which
1072
+ * only captures dispatch failures (path + message) and resets on hibernation —
1073
+ * kept for the "what's failing on this instance right now" view, filtered
1074
+ * client-side.
1075
+ *
1076
+ * For the raw, un-attributed request firehose (which Lunora deliberately does
1077
+ * NOT re-stream), a deep-link to Cloudflare Workers Observability is provided.
1078
+ */
1079
+ declare const LogsPanel: ({
1080
+ initialShardKey
1081
+ }: LogsPanelProps) => ReactElement;
1082
+ interface MailPanelProps {
1083
+ /** Newest-N to load (default 100). */
1084
+ readonly limit?: number;
1085
+ }
1086
+ /**
1087
+ * Dev mail catcher — a unified inbox of every email the app sent. `@lunora/mail`'s
1088
+ * capture transport (wired in dev) intercepts each send and persists it to the
1089
+ * root-shard mailbox instead of delivering, so verification / forgot-password and
1090
+ * any app mail show up here with nothing leaving the machine. Reads the
1091
+ * `__lunora_admin__:getCapturedMail` RPC over the {@link useLunora} client;
1092
+ * gated by the server's `LUNORA_ADMIN_TOKEN`.
1093
+ *
1094
+ * The inbox is a single root-shard table with no write-flush to subscribe to, so
1095
+ * it polls on a fixed interval (paused while the tab is hidden) — new captured
1096
+ * mail appears without a manual refresh. The HTML body is rendered in a fully
1097
+ * sandboxed iframe (no script execution) so captured markup can't run in the studio.
1098
+ */
1099
+ declare const MailPanel: ({
1100
+ limit
1101
+ }: MailPanelProps) => ReactElement;
1102
+ interface HealthPanelProps {
1103
+ /** Shard key the metric/log reads target on first load. Defaults to the root shard. */
1104
+ readonly initialShardKey?: string;
1105
+ }
1106
+ /**
1107
+ * App-level health & SLO overview. On top of the original single-shard snapshot
1108
+ * (recent errors, request/error counts, shards seen) it composes the
1109
+ * lunora-attributed SLO signals the studio can already reach — app error
1110
+ * rate, auth-failure rate, scheduler backlog, and migration status — each with a
1111
+ * status badge, plus durable request/error and auth sparklines, and a
1112
+ * worst-first per-function error-rate list. None of this is CF's per-Worker
1113
+ * charting: it is attributed to lunora functions, the auth flow, and the
1114
+ * scheduler/migration subsystems.
1115
+ *
1116
+ * Every read is independent and best-effort (via `Promise.allSettled`): a
1117
+ * missing `LUNORA_ADMIN_TOKEN`, an unconfigured scheduler, or a cold instance
1118
+ * degrades that one tile to `—` without blanking the rest. The overview is always
1119
+ * live: a root-shard `getMetrics` subscription drives a full cross-shard re-pull
1120
+ * on every write-flush (coalesced so a burst yields at most one in-flight pull).
1121
+ */
1122
+ declare const HealthPanel: ({
1123
+ initialShardKey
1124
+ }: HealthPanelProps) => ReactElement;
1125
+ /** One shard's metrics fetch outcome: the snapshot, or the error that shard returned. */
1126
+ interface ShardMetricsResult {
1127
+ error: null | string;
1128
+ metrics: null | ShardMetrics;
1129
+ shard: string;
1130
+ }
1131
+ /** Totals rolled up across every successfully-fetched shard. */
1132
+ interface AggregateMetrics {
1133
+ /** Shards that returned an error (couldn't be reached / unauthorized). */
1134
+ failed: number;
1135
+ /** Combined reactive-cache hit rate across shards with a cache, or `null` when none has one. */
1136
+ hitRate: null | number;
1137
+ /** Shards that returned a snapshot. */
1138
+ reachable: number;
1139
+ /** Sum of `databaseSize` across reachable shards (skips shards reporting `null`). */
1140
+ totalDatabaseSize: number;
1141
+ totalErrors: number;
1142
+ totalRequests: number;
1143
+ }
1144
+ /**
1145
+ * Roll up per-shard metrics into repo-wide totals. Errors-per-shard are kept as
1146
+ * `failed` (a shard that's down is data, not a hard failure), and counters are
1147
+ * summed only over reachable shards. The combined cache hit-rate weights by each
1148
+ * shard's hits+misses so a busy shard dominates a quiet one.
1149
+ */
1150
+ declare const aggregateMetrics: (results: ReadonlyArray<ShardMetricsResult>) => AggregateMetrics;
1151
+ /**
1152
+ * The shard keys to aggregate over. Durable Objects aren't enumerable, so this
1153
+ * is the union of the root shard (`""`), an explicit current shard, and the
1154
+ * recently-visited shards — de-duplicated, order-stable (root first). It's a
1155
+ * best-effort "shards we know about", not every shard that exists.
1156
+ */
1157
+ declare const shardsToAggregate: (current: string, recents: ReadonlyArray<string>) => string[];
1158
+ interface MetricsPanelProps {
1159
+ /** Shard key the panel reports on. Defaults to the root shard. */
1160
+ readonly initialShardKey?: string;
1161
+ }
1162
+ /**
1163
+ * Health snapshot for a single shard: request / error counts (since the DO last
1164
+ * woke), its live SQLite size, and reactive-cache hit/miss stats when a cache is
1165
+ * configured. Reads via the `__lunora_admin__:getMetrics` RPC over the
1166
+ * {@link useLunora} client; gated by the server's `LUNORA_ADMIN_TOKEN`.
1167
+ *
1168
+ * Counters are per-DO-instance and reset on hibernation/restart — this is a
1169
+ * "since this instance woke" readout, not a durable time series.
1170
+ *
1171
+ * The panel is always live: a `getMetrics` WebSocket subscription opens once the
1172
+ * first one-shot seed commits a shard and re-pushes on every server write-flush,
1173
+ * accumulating a client-side, in-memory series of requests-per-sample (the delta
1174
+ * of `requests` between consecutive samples), rendered as an inline-SVG
1175
+ * sparkline. The series is capped at {@link MAX_HISTORY} points and is lost on
1176
+ * remount.
1177
+ */
1178
+ declare const MetricsPanel: ({
1179
+ initialShardKey
1180
+ }: MetricsPanelProps) => ReactElement;
1181
+ interface SchemaViewerProps {
1182
+ /** Shard key the viewer targets. Defaults to the root shard. */
1183
+ readonly initialShardKey?: string;
1184
+ /**
1185
+ * Table to auto-expand once the shard's tables load. Set by the Insights
1186
+ * "add the index" deep-link (`/schema?table=&lt;name>`) so the operator lands
1187
+ * directly on the scanned table's index list instead of hunting for it.
1188
+ * Re-applied whenever the value changes, so following the link a second time
1189
+ * (same tab already open) re-expands the target.
1190
+ */
1191
+ readonly initialTable?: string;
1192
+ /**
1193
+ * Enable the visual schema-editor overlay (add table / column / index). Off by
1194
+ * default so the diagram stays read-only. Set only by the loopback dev hosts
1195
+ * (see `StudioProps.schemaEditable`); when true, the authoring overlay
1196
+ * (plan 024 Item 4) renders above the table lists and applies additive edits
1197
+ * through the dev host's local schema-edit endpoint.
1198
+ */
1199
+ readonly schemaEditable?: boolean;
1200
+ }
1201
+ /**
1202
+ * Schema overview that shows both storage tiers so the distinction is never a
1203
+ * mystery. The shard section lists every user table in the selected Durable
1204
+ * Object with row counts, and probes a table's columns on expand via a one-row
1205
+ * `__lunora_admin__:readTablePage` (`PRAGMA table_info`). The global section
1206
+ * lists every `.global()` table — including the auth tables (`user`, `session`,
1207
+ * …) — via the client's `listGlobalTables()`, reading columns from a one-row
1208
+ * `readGlobalTablePage` on expand.
1209
+ *
1210
+ * Two presentations: a **Table list** (searchable, expandable cards per tier)
1211
+ * and a **Graph** — a single React Flow relationship diagram showing both tiers
1212
+ * on one canvas, with cross-tier FK edges and its own in-canvas find-table box,
1213
+ * tier filter, and legend.
1214
+ *
1215
+ * Read-only and gated by the server's `LUNORA_ADMIN_TOKEN`, like the rest of the
1216
+ * studio's admin surface. Global discovery is best-effort: if D1 isn't
1217
+ * configured the global section simply reports it, and the shard section still
1218
+ * works.
1219
+ */
1220
+ declare const SchemaViewer: ({
1221
+ initialShardKey,
1222
+ initialTable,
1223
+ schemaEditable
1224
+ }: SchemaViewerProps) => ReactElement;
1225
+ interface SettingsPanelProps {
1226
+ /** Shard key the settings read targets on first load. Defaults to the root shard. */
1227
+ readonly initialShardKey?: string;
1228
+ }
1229
+ /**
1230
+ * Read-only **Settings** view of the deployment's config: the Worker vars,
1231
+ * secrets, and bindings exposed via `env`, plus best-effort deploy metadata.
1232
+ * Reads the `__lunora_admin__:getSettings` RPC over the {@link useLunora} client
1233
+ * (gated by the server's `LUNORA_ADMIN_TOKEN`).
1234
+ *
1235
+ * Strictly view-only: secret values are masked server-side and never returned
1236
+ * raw, and there is no editing here. The infrastructure plane lives in
1237
+ * Cloudflare/wrangler — a deep-link to the Cloudflare dashboard is provided so
1238
+ * you can edit there. Deployment config is static at runtime (it only changes on
1239
+ * redeploy), so this loads once on mount — there is no live channel or poll.
1240
+ */
1241
+ declare const SettingsPanel: ({
1242
+ initialShardKey
1243
+ }: SettingsPanelProps) => ReactElement;
1244
+ interface SqlEditorPanelProps {
1245
+ /** Shard key the query runs against on first load. Defaults to the root shard. */
1246
+ readonly initialShardKey?: string;
1247
+ }
1248
+ /**
1249
+ * A full-height, Supabase-style SQL editor: a left query sidebar (search + new,
1250
+ * a browser-persisted PRIVATE list, and REFERENCE templates), a line-numbered
1251
+ * editor pane, and a Results / Explain pane with a Run control + shard selector.
1252
+ * Read-only — the `__lunora_admin__:runSql` RPC rejects everything but
1253
+ * SELECT / WITH / EXPLAIN, so raw writes can't desync the doc-store's shadow
1254
+ * tables (use the Data grid's inline edit for mutations).
1255
+ */
1256
+ declare const SqlEditorPanel: ({
1257
+ initialShardKey
1258
+ }: SqlEditorPanelProps) => ReactElement;
1259
+ interface FileBrowserProps {
1260
+ /** Object-key prefix the browser filters by on first load. */
1261
+ readonly initialPrefix?: string;
1262
+ /** Objects requested per page. Forwarded to the storage `list` limit. */
1263
+ readonly pageSize?: number;
1264
+ }
1265
+ /**
1266
+ * Browse — and mutate — objects in the storage (R2) bucket. Lists keys under an
1267
+ * optional prefix via the client's `listStorageObjects`, which hits the worker's
1268
+ * admin-gated `GET /_lunora/admin/storage` endpoint — so the worker must be built
1269
+ * with a `storageList` function and `adminToken`. Paginates forward by cursor.
1270
+ *
1271
+ * Each row offers a "Copy URL" (signed/public URL via `signedStorageUrl`) and a
1272
+ * confirm-gated "Delete" (`deleteStorageObject`); the toolbar offers an upload
1273
+ * (`uploadStorageObject`) into the current prefix. Those write paths require the
1274
+ * worker to be built with `storageSignedUrl` / `storageDelete` / `storageUpload`
1275
+ * respectively — when absent, the worker responds with a clear `*_NOT_CONFIGURED`
1276
+ * error that surfaces inline rather than crashing the panel.
1277
+ *
1278
+ * All state + behavior lives in {@link useFileBrowser}; this shell only wires the
1279
+ * view-model into the toolbar, breadcrumbs, selection bar, list/gallery and the
1280
+ * load-more / error / empty affordances.
1281
+ */
1282
+ declare const FileBrowser: ({
1283
+ initialPrefix,
1284
+ pageSize
1285
+ }: FileBrowserProps) => ReactElement;
1286
+ /** Default polling cadence for auto-refresh, in milliseconds. */
1287
+ declare const DEFAULT_AUTO_REFRESH_MS = 5e3;
1288
+ /**
1289
+ * Call `onTick` on a fixed interval while `enabled`, for panels whose backend
1290
+ * has no live subscription channel (the scheduler, R2, D1, the SessionDO — all
1291
+ * HTTP-only). Polling is the honest "live" here: a timer-driven scheduler has no
1292
+ * client-observable write event to push on, so the UI watches jobs count down
1293
+ * and disappear by re-asking.
1294
+ *
1295
+ * Ticks are skipped while the tab is hidden (`document.hidden`) so a backgrounded
1296
+ * studio doesn't keep hammering the worker. `onTick` is held in a ref so a
1297
+ * fresh closure each render doesn't reset the interval; only `enabled`/`intervalMs`
1298
+ * do. The interval is cleared on disable and unmount.
1299
+ */
1300
+ declare const useAutoRefresh: (onTick: () => void, enabled: boolean, intervalMs?: number) => void;
1301
+ /**
1302
+ * Debounced mirror of `value`: returns the latest value only after it has been
1303
+ * stable for `delayMs`. Used so a per-keystroke search box drives at most one
1304
+ * server round-trip per pause, instead of one request per character.
1305
+ */
1306
+ declare const useDebounced: <T>(value: T, delayMs?: number) => T;
1307
+ /**
1308
+ * The registry of every English source string a call site may pass to `t(...)`.
1309
+ *
1310
+ * English is the source locale, so each id doubles as the rendered text: Lingui
1311
+ * compiles an id verbatim when a catalog has no entry for it. This list is the
1312
+ * single source of known strings — {@link MessageId} is derived from it and
1313
+ * `TFunction` is typed against that union, so `t("Dat")` (or any string absent
1314
+ * here) is a compile error rather than a silently-rendered typo.
1315
+ *
1316
+ * Add a string here the moment a new call site needs it. To translate, create a
1317
+ * sibling catalog (for example `de.ts`) mapping each id to its translation and
1318
+ * register it via `createStudioI18n(locale, { en: enMessages, de: deMessages })`.
1319
+ */
1320
+ declare const MESSAGE_IDS: readonly ["Lunora AI rules aren't installed.", "lets your coding agent use Lunora correctly.", "Dismiss", ", changed", "(no subject)", "(root)", "{count} active", "{count} calls", "{count} failed", "{total} total", "No subscriptions yet", "Payments", "Plan", "Provider", "Recent webhook events", "Renews", "State", "Subscriptions", "Synced customers, subscriptions, and webhook events.", "{count} messages", "{count} pending changes", "{count} running", "{name} ({rowCount})", "{rangeStart}-{rangeEnd} of {total}", "{rate} ({count} entries)", "{reachable} reachable", "{reachable} reachable, {failed} unreachable", "{status} — processed", "{title} failed", "Actions", "Actions have no React hook — call them through the client.", "Add a widget to chart a saved SQL query on this browser.", "Add index on {table}", "Add row", "Add widget", "admin token", "Aggregating…", "all", "All shards", "API", "API reference unavailable", "API resources", "API usage snippets", "API view", "Arguments", "Auth", "Auth failures", "Auth failures over time", "Cache hit rate", "Call this {kind} from your app.", "Cancel", "Cancel job?", "Cc", "changed", "Chart widgets backed by saved read-only SQL queries.", "Lunora surfaces slow functions, error spikes, and cache problems here.", "Clear", "Clear inbox", "Columns unavailable", "CLI", "Client", "collecting samples…", "Combined cache hit rate", "Commit", "Committing…", "Breadcrumb", "Confirm", "Connect", "Connected", "Connecting…", "Local", "Not connected", "content-type", "Copy", "Copy link", "Copy-paste snippets for calling your functions and tables.", "created", "Cron triggers", "Dashboards", "Data", "Data migrations you run against this shard will be tracked here.", "Data model", "Database", "Database size", "db size", "Delete", "Delete saved query {name}", "Delete?", "direction", "Direction", "Discard", "down", "Dry run", "Dry run: ", "Edit", "Edit widget", "email", "Email preview", "Email your app sends in dev is captured here — nothing is delivered.", "Email your app sent, captured in dev.", "Enter a migration id", "error", "Error rate", "errors", "Errors", "Errors over time", "expires", "Export", "PNG", "SVG", "Export / Import", "Exported {count} rows.", "Facets", "file:function", "Files", "Filter messages", "Filter tables", "Find table…", "Foreign key", "From", "function", "Function", "Function path", "Functions", "Functions by error rate", "Graph", "Headers", "Health", "Indexes", "Hide", "HTML", "id", "Idle", "Import", "Import (writes rows)?", "Inserted {inserted}, {conflicts} conflicts, {errors} errors.", "Interactive OpenAPI reference and copy-paste snippets for your functions.", "Invalid JSON args: {message}", "Invalid JSON: {message}", "Invalid NDJSON: {message}", "ip", "Jobs queued with runAfter / runAt will appear here.", "JSON", "key", "Key prefix", "key prefix (optional)", "Level filter", "line {line} ({table}): {message}", "List", "Live", "Live — changes stream in automatically", "Live unavailable", "Live unavailable: {liveError}", "Live: on", "Load", "Load more", "Load tables", "Logic", "Logs", "Mail", "Mask sensitive columns", "Metrics", "migration id", "Migration id", "Migrations", "Missing index", "name", "Next", "no", "No active sessions.", "no cache configured", "No captured email.", "No cron triggers.", "No function activity yet.", "No functions or tables to document yet.", "No global tables.", "No headers.", "No HTML body.", "No logs.", "No migrations have run on this shard.", "No objects.", "No recent errors.", "No scheduled jobs.", "No tables to graph.", "No tables match your filter.", "No text body.", "No users.", "No widgets yet", "Objects you upload to your R2 buckets will appear here.", "Observability", "of {pages}", "off", "Offline", "ok", "OK", "on", "Open {target} {id}", "Open in new tab", "Outcome filter", "Page", "Plain text", "Prefill", "Previous", "Primary key", "processed", "React", "Read and write this table through the typed data model.", "Recent errors", "Recent logs", "Recently visited shards — click to switch", "Refresh", "Reload tables", "Remove widget", "RLS Policies", "Policies", "No policies defined", "No `definePolicy` is wired through `.use(rls(...))` in this deployment. Add one to guard a table's rows.", "Read", "Insert", "Update", "Guarded by", "Guarded", "Roles", "No roles defined", "No `defineRole` is registered via `rls(policies, { roles })`. Roles back `ctx.auth.can(...)` permission checks.", "Permissions", "Run as identity (userId)", "Leave empty to run as admin", "Dev only: runs the function as this user so you can test auth and RLS. Forged over the admin gate.", "as {userId}", "No policy", "Covered by {procedure}", "Uncovered — reachable without a policy", "Masked columns", "No tables in this deployment's schema.", "Add a `definePolicy` and wire it through `.use(rls(...))` to populate this matrix.", "Pick a function and an identity, then run it to see the access outcome.", "Probe", "Probe this", "Run as (userId)", "Identity (userId) to run as", "Run probe", "Allowed", "Denied", "Probing…", "Set `runAsIdentity` to forge an identity and probe access.", "Dev only: runs the selected function as this user over the admin gate so you can test auth and RLS.", "Inspect access policies per table, and probe a function as any identity.", "Scaffold access rules", "Writes a new deny-by-default policy file under lunora/, or wires one into a procedure, then reruns codegen. Local dev only.", "New policy file", "Wire into a procedure", "Policy name", "Create policy file", "Procedure file path", "Exported procedure", "Policy set identifier", "Wire RLS", "Creating…", "Wiring…", "Scaffolded {label} and reran codegen. Fill in the `when` predicates before relying on it.", "This change must be made by hand — the scaffolder only adds new, deny-by-default rules.", "requests", "Requests", "Requests / interval", "Requests over time", "Requests per interval over time", "Row actions", "Row document JSON", "Rows per page", "Run", "Run migration", "Run migration?", "Running…", "Query name", "Save", "Save query", "Save widget", "Saved", "schedule", "target", "workflow", "Run now", "Run now?", "Running…", "ran", "attempts", "backlog", "Dead letter", "Drop", "Drop job?", "in flight", "Jobs that exhaust their retry budget are parked here instead of being dropped.", "last tried", "max concurrency", "No dead-letter jobs.", "No workpools.", "pool", "Pools", "pools", "Pools created with createWorkpool appear here once they have activity.", "queued", "Retry", "Schedule view", "Scheduled", "scheduled for", "Scheduled jobs", "Scheduler backlog", "Schema", "Schema graph", "Schema view", "search message", "Search messages", "Search rows", "search table…", "Search…", "Select a function or table to see how to call it from your app.", "Select all rows", "Select row", "Send test", "Sent", "Service level", "Sessions", "Sessions for {userId}", "shard", "Shard", "Shard key", "shard key (optional)", "Shard key (optional)", "Shards", "Shards seen", "Signature", "size", "Snippet flavour", "State-changing admin operations are recorded here.", "status", "Storage", "Storage tier", "Storage tiers", "Studio", "Studio areas", "Studio failed", "Switch to dark theme", "Switch to light theme", "Table", "Table list", "Table touched", "Tables", "To", "Token rides the WebSocket URL — it can surface in browser DevTools and server logs. Use a dev-only token.", "Total database size", "Total errors", "Total requests", "Triggers declared with the cronJobs() builder appear here.", "Try again", "unreachable", "up", "updated", "Uptime", "user agent", "User id", "userId", "Users", "Users who sign up to your app will appear here.", "verified", "Widget title", "yes", "A live stream of recent function logs.", "Browse and edit rows across your shard and global tables.", "Browse auth users and their active sessions.", "Browse objects in your R2 storage buckets.", "Export a shard to NDJSON, or import rows from it.", "At-a-glance connection, error, and shard signals.", "Inspect and cancel scheduled jobs.", "Inspect each table and its columns.", "Inspect row-level-security policies and roles, per table.", "Per-shard health and aggregate metrics.", "Review migration status and run them.", "Run registered queries, mutations, and actions.", "Global tables (D1)", "Shard tables", "{shard} tables", "Tables marked .global() (D1-backed, region-replicated) will appear here.", "Select a table to browse its rows.", "Shared across every tenant, stored once in D1. Includes auth tables.", "Partitioned per shard key into separate Durable Objects — scoped to the shard above.", "avg", "calls", "conflicts", "kind", "last error", "last run", "max", "Most called", "No functions have run on this shard yet.", "Recent", "Slowest", "Insights", "Surface slow functions, error spikes, and cache problems.", "No issues detected.", "Low cache hit rate", "High cache eviction rate", "Slow function", "High error rate", "High write contention", "{rate} hit rate over recent traffic.", "{count} entries evicted recently.", "Slowest call took {duration}.", "Slowest call took {duration} — it full-scanned {tables} with no index.", "{rate} of calls failed.", "{rate} of calls hit a write conflict — consider sharding to cut contention.", "Home", "Reports", "SQL / Functions", "Table editor", "Connection, health, and advisor summary for your deployment.", "Collapse sidebar", "Expand sidebar", "SQL editor", "Run read-only SQL against a shard.", "Run", "SQL query", "{count} rows", "Showing the first {max} of {count} rows.", "Showing the {n} most common values.", "No rows returned.", "Private", "Reference", "Search queries…", "New query", "Untitled query", "Delete query", "No saved queries yet — they save to this browser as you type.", "Results", "Explain", "Chart", "History", "Format", "Clear history", "No numeric column to chart.", "Click Run to execute your query.", "Untitled", "New tab", "Close tab", "Tab title", "Double-click to rename", "Discard?", "Discard changes", "Keep editing", "Close other tabs", "Close tabs to the right", "Close all tabs", "Discard unsaved tabs?", "column", "keyword", "Columns", "Show all", "Hide all", "Transpose", "Swap rows and columns", "Field", "Row {n}", "Loading…", "No matching row.", "CSV", "{count} selected", "Delete {count}", "Delete {count} rows?", "Copy", "Copied", "Cell value", "Close", "Form", "Invalid JSON", "Command palette", "No results.", "Quick links", "Security findings", "Performance issues", "View", "All clear", "No data yet", "Get connected", "No issues found", "No security or performance issues detected.", "Client SDK", "React", "CLI", "Advisors", "Security", "Performance", "Warnings", "Info", "Issue type", "Entity/item", "Description", "{count} errors", "{count} warnings", "{count} suggestions", "No errors detected", "No warnings detected", "No suggestions", "Nothing to report for this deployment.", "Security and performance findings for your deployment.", "Review admin gates, credentials, and log redaction.", "Lunora checks admin-token strength, the live-subscription gate, and request-log redaction here.", "No security issues detected.", "Weak admin token", "Weak auth secret", "Session cookies are not Secure", "Wildcard CORS with credentials", "CSRF/origin guard is off", "Security headers are off", "Live admin subscriptions are ungated", "Request log keeps un-redacted args", "Unknown security finding", "Update your worker to a version of Lunora that describes this finding.", "Your admin token is {length} characters — use at least {min} for a brute-force-resistant secret.", "Your auth secret is {length} characters — use at least {min} (e.g. `openssl rand -hex 32`) to sign sessions safely.", "BETTER_AUTH_URL is a plaintext http:// origin, so session cookies cannot be Secure and ride in cleartext. Serve auth over https:// in production.", "LUNORA_ALLOWED_ORIGINS includes a wildcard while credentials are allowed — browsers reject this and it defeats the allowlist. Name explicit origins instead of *.", "LUNORA_SECURITY_CSRF is off, so cross-origin state-changing cookie requests are not blocked. Re-enable it in production to keep mutations un-forgeable.", "LUNORA_SECURITY_HEADERS is off, so HSTS, CSP, nosniff, and frame-options are not applied. Re-enable the baseline headers in production.", "Apply index", "Apply index on {table}", "Apply?", "CREATE INDEX SQL copied to clipboard.", "LUNORA_WS_BEARER is unset, so the WebSocket upgrade gate is open: live admin subscriptions need no credential. Set it to gate them like the HTTP admin RPCs.", "This worker reports a development environment, so the request log stores raw args and identity. Confirm it isn't a mislabeled production deploy.", "Audit", "A durable log of admin state-changing operations.", "Filter audit log", "filter op, table, id", "No audit entries.", "time", "op", "table", "detail", "Settings", "Deployment", "Read-only deployment config — vars, secrets, and bindings.", "Environment & bindings", "No environment variables or bindings.", "Open in Cloudflare", "Remove filter", "View-only — values are masked. Edit vars, secrets, and bindings in wrangler or the Cloudflare dashboard.", "URL", "Environment", "Version", "value", "Cascade impact", "Delete preview — rows that would cascade or be blocked", "No related rows found.", "Restrict relations will block this delete.", "Generate rows", "Generate dummy rows", "Seed {table} with Faker-generated rows. Existing rows are not affected.", "Row count", "(max {max})", "Columns to seed", "FK: no rows in {ref} — will skip", "→ {ref}", "No rows generated — all columns were skipped.", "Inserted {count} rows. Skipped FK columns: {cols}", "Inserted {count} rows successfully.", "Generate & insert", "Inserting…", "Time Travel", "Restore a shard to a point in the last 30 days.", "root", "In-place recovery to any moment in the last 30 days. For older or portable recovery, use the snapshot backup tier.", "Current bookmark", "Restore", "Time (ISO or epoch-ms, last 30 days)", "Preview", "Bookmark for that time", "Or an explicit bookmark (wins over time)", "bookmark string", "Restart the shard now so recovery applies immediately", "Confirm restore", "restarted now", "on next restart", "Restore armed", "Restored to", "Undo bookmark", "Confirm undo", "Undo restore", "role", "Role", "Role (optional)", "Active", "Banned", "unverified", "Manage", "New user", "Create", "Create user", "Creating…", "Password (optional)", "Search users", "Search by email or name…", "Filter by role", "Set role", "Ban user", "Ban reason (optional)", "Days", "Unban", "New password", "Set password", "Impersonate", "Impersonation token", "Revoke", "Revoke all sessions", "Delete user", "Confirm delete", "User details", "Fields", "Linked accounts", "No linked accounts.", "provider", "Unlink", "Security", "Disable two-factor", "No passkeys.", "Operations", "Organizations", "slug", "Members", "Invitations", "Remove", "No organizations.", "Select an organization to view its members and invitations.", "Organizations are not enabled.", "Enable the organization() plugin in your auth config to manage organizations here.", "Browse and manage organizations, members, and invitations.", "Reload", "Manage auth users — roles, bans, sessions, and identity.", "Auth config", "Configuration", "Enabled plugins and session config (read-only).", "Enabled capabilities", "Loading auth configuration…", "Accounts", "Admin", "Passkeys", "Two-factor", "Enabled", "Disabled", "OAuth providers, email templates, and rate limits are configured at deploy time in the better-auth setup and aren't editable here. See the Mail tab for email output.", "Sessions", "Browse and revoke active sessions across all users.", "user", "impersonated by", "Log drains", "Forward logs to Logpush, Tail Workers, or a webhook collector.", "Cloudflare destinations", "Lunora does not ship logs itself — forwarding is handled by Cloudflare. Configure a destination below, then test your collector.", "Logpush", "Stream every request log to R2, a SIEM, or a third-party log service.", "Tail Workers", "Send logs programmatically to a Worker for custom capture and forwarding.", "Workers Logs", "Retain and query recent request logs directly in Cloudflare's dashboard.", "Webhook test", "POST a sample Lunora request-log envelope to your collector to confirm it is reachable.", "https://example.com/logs", "Send test event", "Delivered — status {status} in {latency}ms", "Failed: {message}", "fetch is unavailable in this environment.", "Realtime", "Active WebSocket subscriptions on this shard.", "{count} connections", "{count} subscriptions", "No active subscriptions.", "Connection", "admin", "Folder path", "Grid", "Sort", "Name", "Type", "Modified", "Toggle sort direction", "Thumbnail size", "Link expiry", "15m", "1h", "24h", "7d", "Upload", "Uploading…", "Copy URL", "Download", "Delete object?", "Uploaded {key}", "Deleted {key}", "Summary", "Time range", "All time", "Last 5m", "Last 15m", "Last hour", "filter path", "By level", "By function", "Count", "{count} entries", "Snippets", "Couldn't load the OpenAPI spec: {message}", "No OpenAPI spec configured", "Run `lunora codegen` and wire `_generated/openapi.json` to the worker to render the API reference here.", "API operations", "Filter operations", "No operations match your filter.", "Try it", "Request arguments", "Response body", "Response", "application/json", "Arguments (JSON)", "Send", "Sending…", "Send a request to see the response.", "No example for this response.", "Error", "{ms} ms", "Range", "Value in", "relation", "API spec format", "OpenAPI", "OpenRPC", "Params", "Result", "Field", "Required", "JSON-RPC request", "Couldn't load the OpenRPC spec: {message}", "No OpenRPC spec configured", "Run `lunora codegen --api-spec openrpc` and wire `_generated/openrpc.json` to the worker to render the OpenRPC reference here.", "used by", "Orphan", "1 record", "{count} records", "References shard", "Which shard's records are checked for references to these files. Empty = root shard.", "Orphaned objects", "Find records whose file reference points at an object the bucket no longer has.", "Check for orphans", "Checking…", "No dangling references.", "Every record's file reference points at an object that exists in the bucket.", "Missing object", "→", "Showing the first {count} dangling references — the scan was truncated.", "Per-function call counts, error rates, and latency land here after your first request.", "Function and request logs for this shard show up here as your app handles traffic.", "No tables in this shard.", "Browse Vectorize indexes and run similarity searches.", "dimensions", "field", "Indexes declared with .vectorize() or defineVectorIndex() appear here.", "metadata", "metric", "No matches.", "No vector indexes.", "score", "Search", "Search by similarity…", "Searching…", "vectors", "Vectors", "vs. prev.", "Top functions", "No functions called yet.", "Calls", "Avg", "Err", "Avg latency", "cache hit", "Live connections", "sockets", "active subscriptions", "Recent activity", "No recent activity.", "last interval", "{rate} error rate", "cache entries", "Critical", "Degraded", "All systems healthy", "One or more service levels are breached.", "Some service levels need attention.", "All service levels are within target.", "Analytics", "Analytics is not configured.", "Hot shards", "Latency p50 / p95 per function", "No data points yet.", "Request volume per function", "Set CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN (Analytics Read) in your .dev.vars to enable usage panels.", "Usage and latency from Analytics Engine — request volume, p50/p95, and hot shards.", "(whole bucket)", "Access Rules", "Bucket", "Inspect storage access rules — per bucket, operation, and key prefix.", "No defineStorageRule is wired through .use(storageRules(...)) in this deployment. Add one to gate object access by key prefix.", "No storage rules defined", "Operation", "Storage rules are declared in code with defineStorageRule and gate ctx.storage access per bucket. This view is read-only.", "Write", "Workflows", "Inspect declared Cloudflare Workflows and their bindings.", "Binding", "Class", "No workflows defined", "No defineWorkflow is declared in lunora/workflows.ts in this deployment. Add one to run a durable, multi-step workflow.", "Workflows are declared in code with defineWorkflow and run as durable Cloudflare Workflows. This view is read-only.", "Workflows are declared in code with defineWorkflow and run as durable Cloudflare Workflows. Start an instance and observe its status below.", "Start instance", "Starting…", "Workflow", "Instance id", "Instance id (optional)", "Params (JSON)", "Params (JSON, optional)", "Params must be valid JSON", "Instances", "Status", "Output", "Refresh", "Refreshing…", "Instance history", "Filter by status", "All statuses", "Workflow inspection not configured", "Set CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN in your .dev.vars to enable workflow instance history.", "No instances", "No instances match this filter for the selected workflow.", "Created", "Ended", "Steps", "Step", "Attempts", "Started", "This instance has no recorded steps yet.", "pause", "resume", "terminate", ">100ms avg execution", "50–100ms avg execution", "<50ms avg execution", "{count} tracked statements", "Avg time", "avg", "avg time", "avgTime", "Critical queries", "Exec count", "exec count", "execCount", "Execution count", "Fast queries", "Full statement", "Moderate queries", "No query insights yet", "Overview", "P90 latency", "P95 latency", "Query insights", "Query insights appear once statements are executed against this shard.", "Query leaderboard", "Rows read", "Rows written", "rowsRead", "Slow queries sorted by {sortField}", "Sort by", "Sort queries by", "Statements", "total", "Total time", "total time", "totalTime", "Edit schema", "Add table", "Add column", "Add index", "Rename / drop / change type…", "Table name", "Column name", "Column type", "Index name", "Index fields (comma-separated)", "Optional", "Unique", "Cancel", "Apply", "Applying…", "This edit changes stored data and must go through a migration. Review the migration before applying.", "Open Migrations", "Schema updated.", "Codegen reported diagnostics:", "Editing the schema is only available in local dev.", "Adds a table, column, or index to lunora/schema.ts and reruns codegen.", "Theme", "Dark theme", "Light theme", "System theme", "Integrity"];
1321
+ /** A known studio message id — one of the entries in {@link MESSAGE_IDS}. */
1322
+ type MessageId = (typeof MESSAGE_IDS)[number];
1323
+ /**
1324
+ * English message catalog.
1325
+ *
1326
+ * English is the source locale: every call site passes its English string as the
1327
+ * message id (e.g. `t("Save")`), and Lingui compiles the id verbatim when a
1328
+ * catalog has no entry for it. So English needs no translations — this stays
1329
+ * empty and the source strings render as-is. The known ids live in
1330
+ * {@link MESSAGE_IDS}, which types the `t` function.
1331
+ */
1332
+ /** The locale the studio ships with and falls back to. */
1333
+ declare const DEFAULT_LOCALE = "en";
1334
+ /**
1335
+ * Locale code to catalog. Each catalog maps an English source string (which
1336
+ * doubles as the message id) to its translation. English ships empty: Lingui
1337
+ * compiles the id verbatim when a translation is missing, so the source strings
1338
+ * render as-is. To add a language, register `{ "Some English text": "…" }`.
1339
+ */
1340
+ type StudioCatalogs = Readonly<Record<string, Messages>>;
1341
+ /**
1342
+ * Translate function: `t("Clear")` or `t("{title} failed", { title })`.
1343
+ *
1344
+ * `id` is constrained to a known {@link MessageId}, so a typo is a compile error.
1345
+ * The interpolation `values` stay loosely typed: mapping each id to its exact
1346
+ * placeholder set isn't worth the machinery for the handful of interpolated
1347
+ * strings, so a wrong or missing value key isn't caught at this boundary.
1348
+ */
1349
+ type TFunction = (id: MessageId, values?: Record<string, unknown>) => string;
1350
+ /**
1351
+ * Build a studio-scoped Lingui instance. We deliberately use `@lingui/core`'s
1352
+ * `setupI18n` (a fresh instance) rather than the global singleton so the
1353
+ * studio can never clobber — or be clobbered by — a host app that also uses
1354
+ * Lingui.
1355
+ *
1356
+ * The message compiler is installed explicitly. `@lingui/core` only auto-installs
1357
+ * it when `NODE_ENV !== "production"`, but the studio ships as a library and
1358
+ * relies on the compiler at runtime to interpolate uncompiled source strings
1359
+ * (e.g. `t("{title} failed", { title })`). Without this, a consumer's production
1360
+ * build would render `{title}` literally and `console.warn` on every `t(...)`.
1361
+ *
1362
+ * Pass extra `catalogs` to ship more locales; unknown `locale` codes fall back
1363
+ * to `DEFAULT_LOCALE`.
1364
+ */
1365
+ declare const createStudioI18n: (locale?: string, catalogs?: StudioCatalogs) => I18n;
1366
+ /**
1367
+ * Shared default instance. Backs the i18n context's default value so the
1368
+ * composable studio and individual exported panels resolve their strings even
1369
+ * when rendered without `StudioI18nProvider` (e.g. in tests, or a host's own
1370
+ * admin UI). English-only, so it renders source strings as-is.
1371
+ */
1372
+ declare const studioI18n: I18n;
1373
+ /**
1374
+ * Hook returning a `t` bound to the nearest `StudioI18nProvider` (or the
1375
+ * shared instance when there's none). This is the runtime stand-in for Lingui's
1376
+ * `t` macro — the studio builds with esbuild and tests under Vite 8/Rolldown,
1377
+ * neither of which runs Lingui's Babel macro transform, so call sites pass the
1378
+ * English string as the id directly.
1379
+ */
1380
+ declare const useT: () => TFunction;
1381
+ interface StudioI18nProviderProps {
1382
+ /** Catalogs to register in addition to the built-in English one. */
1383
+ readonly catalogs?: StudioCatalogs;
1384
+ readonly children: ReactNode;
1385
+ /** Reuse an existing instance (wins over `locale`/`catalogs`). */
1386
+ readonly i18n?: I18n;
1387
+ /** Active locale; ignored when `i18n` is supplied. Defaults to `en`. */
1388
+ readonly locale?: string;
1389
+ }
1390
+ /**
1391
+ * Provides a studio-scoped Lingui instance to `useT`. Nesting is safe:
1392
+ * providers sharing the same instance resolve to the same context value.
1393
+ */
1394
+ declare const StudioI18nProvider: ({
1395
+ catalogs,
1396
+ children,
1397
+ i18n,
1398
+ locale
1399
+ }: StudioI18nProviderProps) => ReactElement;
1400
+ /** Root class the batteries-included app sets so the studio styles stay scoped. */
1401
+ declare const STUDIO_ROOT_CLASS = "lunora-studio-root";
1402
+ export { ADMIN_FUNCTIONS, ADMIN_FUNCTION_PREFIX, type AggregateMetrics, ApiDocsPanel, type ApiDocsPanelProps, ApiReferencePanel, type ApiReferencePanelProps, ApiTab, type ApiTabProps, type AuditEntry, type AuditLogResult, AuditPanel, type AuditPanelProps, type CacheStats, type CapturedMailResult, type CommandItem, CommandPalette, type CommandPaletteProps, ConfirmButton, type ConfirmButtonProps, ConnectionBadge, DEFAULT_AUTO_REFRESH_MS, DEFAULT_INSIGHT_THRESHOLDS, DEFAULT_LOCALE, DataBrowser, type DataBrowserProps, DataFilters, type DeployInfo, type EditableFilter, ErrorBoundary, type ErrorBoundaryProps, ExportImportPanel, type ExportImportPanelProps, type ExportRow, FileBrowser, type FileBrowserProps, type FilterClause, type FilterOperator, type FunctionCallStat, type FunctionDescriptor, FunctionRunner, type FunctionRunnerProps, FunctionStatsPanel, type FunctionStatsPanelProps, type FunctionStatsResult, GlobalDataBrowser, type GlobalDataBrowserProps, HealthPanel, type HealthPanelProps, HomePanel, type HomePanelProps, type ImportError, type ImportShardResult, type Insight, type InsightKind, type InsightSeverity, type InsightThresholds, InsightsPanel, type InsightsPanelProps, type LogEntry, type LogLevel, LogsPanel, type LogsPanelProps, type LogsResult, MailPanel, type MailPanelProps, type MessageId, MetricsPanel, type MetricsPanelProps, type MigrationDirection, type MigrationRunResult, type MigrationStatus, type MigrationStatusRow, MigrationsPanel, type MigrationsPanelProps, OpenRpcReferencePanel, type OpenRpcReferencePanelProps, PitrPanel, type PitrPanelProps, type RunMigrationArgs, STUDIO_ROOT_CLASS, SchemaViewer, type SchemaViewerProps, SecurityAdvisorPanel, type SecurityAuditResult, type SecurityFinding, type SecurityFindingKind, type SecurityFindingLevel, type SettingEntry, type SettingKind, SettingsPanel, type SettingsPanelProps, type SettingsResult, ShardInput, type ShardInputProps, type ShardMetrics, type ShardMetricsResult, SqlEditorPanel, type SqlEditorPanelProps, type StudioCatalogs, StudioI18nProvider, type StudioI18nProviderProps, type TFunction, TableEditor, type TableEditorProps, type TableIndexInfo, type TableIndexesResult, type TableInfo, type TablePage, type WriteRowArgs, type WriteRowOp, type WriteRowResult, aggregateMetrics, createStudioI18n, deriveInsights, openCommandPalette, shardsToAggregate, studioI18n, toFilterClauses, useAutoRefresh, useDebounced, useT };