@auersperg/flare 0.3.17 → 0.3.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/{chunk-xn3e3gev.js → chunk-6zw21b1h.js} +1 -1
- package/dist/cli/{chunk-8gzfscca.js → chunk-arads6c9.js} +1 -1
- package/dist/cli/{chunk-7ym0f672.js → chunk-k496964h.js} +6 -6
- package/dist/cli/{chunk-1yvbecac.js → chunk-twhp5nd5.js} +30 -4
- package/dist/cli/{chunk-yhvbksrm.js → chunk-xsqrjbhb.js} +1 -1
- package/dist/cli/flare.js +4 -4
- package/dist/platform/admin.js +1 -1
- package/dist/platform/dashboard/_astro/{ai-view.D6ouaMiL.js → ai-view.DcYKk5W_.js} +1 -1
- package/dist/platform/dashboard/_astro/{auth-view.0CuFK-xf.js → auth-view.KnVtTZYn.js} +1 -1
- package/dist/platform/dashboard/_astro/{data-view.jmNzQKhW.js → data-view.BFL2F3o9.js} +1 -1
- package/dist/platform/dashboard/_astro/{functions-view.Bqamd_KY.js → functions-view.vsmqlnUa.js} +1 -1
- package/dist/platform/dashboard/_astro/{index.astro_astro_type_script_index_0_lang.DlEchDEE.js → index.astro_astro_type_script_index_0_lang.DBs-yURk.js} +2 -2
- package/dist/platform/dashboard/_astro/{sdk-view.DuMOEfZu.js → sdk-view.BPVWrAC3.js} +1 -1
- package/dist/platform/dashboard/_astro/{services-view.B7BR4JD3.js → services-view.Dx1rjMWa.js} +1 -1
- package/dist/platform/dashboard/_astro/{settings-view.DM-igZ4O.js → settings-view.DPwEyqzv.js} +1 -1
- package/dist/platform/dashboard/index.html +1 -1
- package/dist/platform/manifest.json +25 -24
- package/dist/platform/runtime.js +122 -19
- package/dist/sdk/protocol.d.ts +2 -0
- package/dist/sdk/protocol.js +1 -1
- package/package.json +1 -1
|
@@ -102,7 +102,7 @@ ${url}`);
|
|
|
102
102
|
await writeFile(join(directory, key + ".json"), JSON.stringify({ token, expiresAt: result.expiresAt }) + `
|
|
103
103
|
`, { mode: 384 });
|
|
104
104
|
process.env.FLARE_DEPLOY_TOKEN = token;
|
|
105
|
-
const { link } = await import("./chunk-
|
|
105
|
+
const { link } = await import("./chunk-k496964h.js");
|
|
106
106
|
return link({ platform, project: result.project });
|
|
107
107
|
}
|
|
108
108
|
throw Error("Login expired. Run flare dev again.");
|
|
@@ -26,7 +26,7 @@ async function request(platform, path, body) {
|
|
|
26
26
|
return "null";
|
|
27
27
|
}));
|
|
28
28
|
if (config) {
|
|
29
|
-
const { storedToken } = await import("./chunk-
|
|
29
|
+
const { storedToken } = await import("./chunk-6zw21b1h.js");
|
|
30
30
|
token = await storedToken(platform, config.project);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
@@ -107,7 +107,7 @@ async function deploy(options = {}) {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
const { prepare, generateApi } = await import("./chunk-fv98dfg5.js");
|
|
110
|
-
const { buildApplication } = await import("./chunk-
|
|
110
|
+
const { buildApplication } = await import("./chunk-xsqrjbhb.js");
|
|
111
111
|
const source = await prepare(), directory = resolve(".flare/releases/" + randomUUID());
|
|
112
112
|
try {
|
|
113
113
|
await buildApplication({ ...source, outdir: directory });
|
|
@@ -160,7 +160,7 @@ async function dev(options = {}) {
|
|
|
160
160
|
} catch (e) {
|
|
161
161
|
if (e.code !== "ENOENT")
|
|
162
162
|
throw e;
|
|
163
|
-
const { connect } = await import("./chunk-
|
|
163
|
+
const { connect } = await import("./chunk-6zw21b1h.js");
|
|
164
164
|
await connect();
|
|
165
165
|
}
|
|
166
166
|
}
|
|
@@ -172,11 +172,11 @@ async function dev(options = {}) {
|
|
|
172
172
|
} catch (e) {
|
|
173
173
|
if (process.env.FLARE_DEPLOY_TOKEN || e.status !== 401 && !e.message.startsWith("Sign in"))
|
|
174
174
|
throw e;
|
|
175
|
-
const { connect } = await import("./chunk-
|
|
175
|
+
const { connect } = await import("./chunk-6zw21b1h.js");
|
|
176
176
|
await connect();
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
|
-
const { buildApplication } = await import("./chunk-
|
|
179
|
+
const { buildApplication } = await import("./chunk-xsqrjbhb.js");
|
|
180
180
|
let busy = false, pending = false, timer, hash;
|
|
181
181
|
const publish = async (initial = false) => {
|
|
182
182
|
if (busy) {
|
|
@@ -308,7 +308,7 @@ async function releaseOperation(options, operation) {
|
|
|
308
308
|
const bundle = await request(config.platform, `/api/projects/${config.project}/${source}/release-bundle?hash=${options.hash}`);
|
|
309
309
|
if (bundle.release.hash !== options.hash)
|
|
310
310
|
throw Error("Release hash mismatch");
|
|
311
|
-
const { generateReferences } = await import("./chunk-
|
|
311
|
+
const { generateReferences } = await import("./chunk-xsqrjbhb.js");
|
|
312
312
|
const { withGeneratedApi } = await import("./chunk-fv98dfg5.js");
|
|
313
313
|
await mkdir(".flare", { recursive: true });
|
|
314
314
|
const directory = await mkdtemp(resolve(".flare/release-contract-"));
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
storedToken2
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-arads6c9.js";
|
|
5
5
|
|
|
6
6
|
// packages/flare/src/cli/platform.mjs
|
|
7
7
|
import { readFile as readFile4, mkdir as mkdir2, mkdtemp, writeFile as writeFile2, rm, cp } from "fs/promises";
|
|
@@ -297,8 +297,8 @@ import { randomUUID } from "crypto";
|
|
|
297
297
|
import { readFile as readFile2 } from "fs/promises";
|
|
298
298
|
function validatePlatformConfig(value = {}) {
|
|
299
299
|
const object = (v) => v && typeof v === "object" && !Array.isArray(v);
|
|
300
|
-
if (!object(value) || Object.keys(value).some((k) => !["capabilities", "secrets", "search", "codex"].includes(k)))
|
|
301
|
-
throw Error("Platform config accepts only capabilities, secrets, search and
|
|
300
|
+
if (!object(value) || Object.keys(value).some((k) => !["capabilities", "secrets", "search", "codex", "mcpAuth"].includes(k)))
|
|
301
|
+
throw Error("Platform config accepts only capabilities, secrets, search, codex and mcpAuth references");
|
|
302
302
|
const capabilities = value.capabilities ?? {}, secrets = value.secrets ?? [];
|
|
303
303
|
if (!object(capabilities) || !Array.isArray(secrets) || secrets.length > 64)
|
|
304
304
|
throw Error("Invalid platform capabilities/secrets references");
|
|
@@ -339,11 +339,28 @@ function validatePlatformConfig(value = {}) {
|
|
|
339
339
|
codexServices.add(r.service);
|
|
340
340
|
return { binding: r.binding, service: r.service, scope: r.scope };
|
|
341
341
|
}).sort((a, b) => a.binding.localeCompare(b.binding));
|
|
342
|
+
const mcpAuth = value.mcpAuth ?? [];
|
|
343
|
+
if (!Array.isArray(mcpAuth) || mcpAuth.length > 16)
|
|
344
|
+
throw Error("Invalid MCP auth references");
|
|
345
|
+
const authNames = new Set, authServices = new Set, authIssuers = new Set;
|
|
346
|
+
const authReferences = mcpAuth.map((r) => {
|
|
347
|
+
if (!object(r) || Object.keys(r).sort().join() !== "binding,issuer,scope,service" || !/^APP_MCP_AUTH_[A-Z0-9_]{1,64}$/.test(r.binding) || !/^[a-z0-9][a-z0-9-]{0,62}$/.test(r.service) || !/^https:\/\/[a-z0-9]+(?:[.-][a-z0-9]+)*\.[a-z]{2,63}$/.test(r.issuer) || !/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\/(dev|prod)$/.test(r.scope) || authNames.has(r.binding) || authServices.has(r.service) || authIssuers.has(r.issuer))
|
|
348
|
+
throw Error("Invalid or duplicate MCP authorization reference");
|
|
349
|
+
authNames.add(r.binding);
|
|
350
|
+
authServices.add(r.service);
|
|
351
|
+
authIssuers.add(r.issuer);
|
|
352
|
+
return {
|
|
353
|
+
binding: r.binding,
|
|
354
|
+
service: r.service,
|
|
355
|
+
issuer: r.issuer,
|
|
356
|
+
scope: r.scope
|
|
357
|
+
};
|
|
358
|
+
}).sort((a, b) => a.binding.localeCompare(b.binding));
|
|
342
359
|
const result = {};
|
|
343
360
|
const used = new Set;
|
|
344
361
|
for (const scope of Object.keys(capabilities).sort()) {
|
|
345
362
|
const p = capabilities[scope];
|
|
346
|
-
if (!/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\/(dev|prod)$/.test(scope) || !object(p) || Object.keys(p).some((k) => !["outbound", "secrets", "search", "codex"].includes(k)))
|
|
363
|
+
if (!/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}\/(dev|prod)$/.test(scope) || !object(p) || Object.keys(p).some((k) => !["outbound", "secrets", "search", "codex", "mcpAuth"].includes(k)))
|
|
347
364
|
throw Error("Invalid capability scope");
|
|
348
365
|
const hosts = p.outbound ?? [], mapping = p.secrets ?? {};
|
|
349
366
|
if (!Array.isArray(hosts) || hosts.length > 20 || !object(mapping) || Object.keys(mapping).length > 16)
|
|
@@ -360,7 +377,10 @@ function validatePlatformConfig(value = {}) {
|
|
|
360
377
|
throw Error("Search grant must reference an instance owned by this environment");
|
|
361
378
|
if (p.codex !== undefined && !codexReferences.some((r) => r.binding === p.codex && r.scope === scope))
|
|
362
379
|
throw Error("Codex grant must reference a runner owned by this environment");
|
|
380
|
+
if (p.mcpAuth !== undefined && (!object(p.mcpAuth) || Object.keys(p.mcpAuth).sort().join() !== "binding,issuer" || !authReferences.some((r) => r.binding === p.mcpAuth.binding && r.issuer === p.mcpAuth.issuer && r.scope === scope)))
|
|
381
|
+
throw Error("MCP auth grant must reference its environment's authorization service");
|
|
363
382
|
result[scope] = {
|
|
383
|
+
...p.mcpAuth === undefined ? {} : { mcpAuth: { ...p.mcpAuth } },
|
|
364
384
|
...p.codex === undefined ? {} : { codex: p.codex },
|
|
365
385
|
...p.search === undefined ? {} : { search: p.search },
|
|
366
386
|
outbound: [...new Set(hosts)].sort(),
|
|
@@ -373,6 +393,7 @@ function validatePlatformConfig(value = {}) {
|
|
|
373
393
|
throw Error("Capabilities exceed 16 KiB");
|
|
374
394
|
return {
|
|
375
395
|
capabilities: result,
|
|
396
|
+
...authReferences.length ? { mcpAuth: authReferences } : {},
|
|
376
397
|
secrets: references,
|
|
377
398
|
...codexReferences.length ? { codex: codexReferences } : {},
|
|
378
399
|
...searchReferences.length ? { search: searchReferences } : {}
|
|
@@ -922,6 +943,11 @@ function workerConfiguration(state, release, role, bootstrap = false) {
|
|
|
922
943
|
}
|
|
923
944
|
],
|
|
924
945
|
services: bootstrap ? [] : [
|
|
946
|
+
...(validatePlatformConfig(state.config).mcpAuth ?? []).map(({ binding, service }) => ({
|
|
947
|
+
binding,
|
|
948
|
+
service,
|
|
949
|
+
entrypoint: "McpAuthorization"
|
|
950
|
+
})),
|
|
925
951
|
...(validatePlatformConfig(state.config).codex ?? []).map(({ binding, service }) => ({
|
|
926
952
|
binding,
|
|
927
953
|
service,
|
|
@@ -80,7 +80,7 @@ function assertMcpTools(functions) {
|
|
|
80
80
|
if (fn.mcp === undefined)
|
|
81
81
|
continue;
|
|
82
82
|
const m = fn.mcp;
|
|
83
|
-
if (!m || typeof m !== "object" || Object.keys(m).
|
|
83
|
+
if (!m || typeof m !== "object" || Object.keys(m).some((key) => !["name", "description", "readOnly"].includes(key)) || m.readOnly !== undefined && typeof m.readOnly !== "boolean" || fn.kind === "mutation" && m.readOnly === true || fn.kind === "query" && m.readOnly === false || typeof m.name !== "string" || !/^[A-Za-z][A-Za-z0-9_.-]{0,63}$/.test(m.name) || typeof m.description !== "string" || !m.description.trim() || m.description.length > 1000 || names.has(m.name) || fn.auth === "internal" || fn.input.type !== "object")
|
|
84
84
|
throw new FlareError("INVALID_CONTRACT", "Invalid MCP tool contract");
|
|
85
85
|
boundedJson({ mcp: m, input: fn.input }, 16384);
|
|
86
86
|
names.add(m.name);
|
package/dist/cli/flare.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// packages/flare/package.json
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@auersperg/flare",
|
|
6
|
-
version: "0.3.
|
|
6
|
+
version: "0.3.18",
|
|
7
7
|
license: "MIT",
|
|
8
8
|
type: "module",
|
|
9
9
|
description: "Flare client, server declarations and development CLI",
|
|
@@ -147,7 +147,7 @@ Uses the platform payload bundled with this CLI release. Never updates applicati
|
|
|
147
147
|
options[key] = args[++i];
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
|
-
const { platform } = await import("./chunk-
|
|
150
|
+
const { platform } = await import("./chunk-twhp5nd5.js");
|
|
151
151
|
console.log(JSON.stringify(await platform(options), null, 2));
|
|
152
152
|
}
|
|
153
153
|
} catch (error) {
|
|
@@ -187,12 +187,12 @@ Uses the platform payload bundled with this CLI release. Never updates applicati
|
|
|
187
187
|
if (command === "build") {
|
|
188
188
|
if (!options.entry || !options.outdir)
|
|
189
189
|
throw Error("Required: --entry, --outdir");
|
|
190
|
-
const { buildApplication } = await import("./chunk-
|
|
190
|
+
const { buildApplication } = await import("./chunk-xsqrjbhb.js");
|
|
191
191
|
const x = await buildApplication(options);
|
|
192
192
|
console.log(`Built immutable release ${x.hash}
|
|
193
193
|
${x.outdir}`);
|
|
194
194
|
} else {
|
|
195
|
-
const cloud = await import("./chunk-
|
|
195
|
+
const cloud = await import("./chunk-k496964h.js");
|
|
196
196
|
const x = await cloud[command](options);
|
|
197
197
|
if (x)
|
|
198
198
|
console.log(JSON.stringify(x, null, 2));
|
package/dist/platform/admin.js
CHANGED
|
@@ -309,7 +309,7 @@ async function collectCatalog(database, now = Date.now()) {
|
|
|
309
309
|
// packages/core/package.json
|
|
310
310
|
var package_default = {
|
|
311
311
|
name: "@flare/platform",
|
|
312
|
-
version: "0.3.
|
|
312
|
+
version: "0.3.18",
|
|
313
313
|
type: "module",
|
|
314
314
|
license: "MIT",
|
|
315
315
|
private: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,r as t}from"./client.BeKNsjPN.js";import{At as n,g as r,j as i,m as a,p as o,pt as s,q as c,s as l,u}from"./common.9pujiaSZ.js";import{i as d,t as f}from"./client.BSf433s6.js";var p=e(t(),1),m=n();function h({project:e,env:t,session:n}){let h=r(e,t),g=u(h+`/ai`),[_,v]=(0,p.useState)(``),[y,b]=(0,p.useState)(``),[x,S]=(0,p.useState)(`{"query":""}`),[C,w]=(0,p.useState)(``),[T,E]=(0,p.useState)(``),[D,O]=(0,p.useState)(!1);(0,p.useEffect)(()=>{v(``),w(``),E(``)},[h]);async function k(){O(!0),E(``),w(``);let r=f({url:`${n.runtime}/p/${e.id}/${t}`,getToken:()=>_});try{let e=await r.action(d(y,`action`),JSON.parse(x));w(JSON.stringify(e,null,2))}catch(e){E(a(e))}finally{r.dispose(),O(!1)}}async function A(){if(confirm(`Exclude all indexed files in ${e.name}/${t}? Originals remain in Files. Provider cleanup is asynchronous.`)){O(!0),E(``);try{await o(h+`/search-clear`,t===`prod`?{confirm:e.id}:{}),g.refresh()}catch(e){E(a(e))}finally{O(!1)}}}return(0,m.jsxs)(`div`,{className:`space-y-6 p-6`,children:[(0,m.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,m.jsx)(`h1`,{className:`page-title`,children:`AI`}),(0,m.jsx)(s,{variant:`outline`,onClick:g.refresh,children:`Refresh`})]}),(0,m.jsx)(l,{loading:g.loading,error:g.error||T}),g.data&&(0,m.jsxs)(m.Fragment,{children:[(0,m.jsxs)(`section`,{className:`space-y-3`,children:[(0,m.jsx)(`h2`,{className:`text-lg font-medium`,children:`Search`}),(0,m.jsx)(`p`,{children:g.data.search.binding?`Binding: ${g.data.search.binding}`:`Not connected. Configure an existing AI Search instance through platform update --config. No resource is created here.`}),(0,m.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`TXT/PDF · up to 10 MiB · explicit file indexing from application actions. File permissions belong to your application.`}),(0,m.jsxs)(`p`,{children:[`Tracked index items: `,g.data.search.remaining]}),g.data.search.states.map(e=>(0,m.jsxs)(`p`,{children:[e.status,`: `,e.count]},e.status)),g.data.search.errors>0&&(0,m.jsxs)(`p`,{role:`alert`,children:[g.data.search.errors,` operations need attention. Retry indexing through the application; retry pending cleanup with Exclude all.`]}),(0,m.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Processing states are last observed, not a live provider status. Use action search.status(fileId) to refresh a document. Files, Functions and Logs remain in their existing sections.`}),n.role!==`viewer`&&g.data.search.remaining>0&&(0,m.jsx)(s,{variant:`outline`,disabled:D,onClick:A,children:`Exclude all / retry cleanup`})]}),(0,m.jsxs)(`section`,{className:`space-y-3`,children:[(0,m.jsx)(`h2`,{className:`text-lg font-medium`,children:`Test application search`}),(0,m.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Calls your existing search action with a real application session, not dashboard/admin identity. The application must authorize each result. Session is held only in this view, never saved. Dashboard origin must be allowed by the application.`}),(0,m.jsxs)(`label`,{className:`block`,children:[`Application session`,(0,m.jsx)(c,{type:`password`,autoComplete:`off`,value:_,onChange:e=>v(e.target.value),placeholder:`flared_session_…`})]}),(0,m.jsxs)(`label`,{className:`block`,children:[`Search action path`,(0,m.jsx)(c,{value:y,onChange:e=>b(e.target.value),placeholder:`documents/search`})]}),(0,m.jsxs)(`label`,{className:`block`,children:[`Arguments (JSON)`,(0,m.jsx)(i,{value:x,onChange:e=>S(e.target.value)})]}),(0,m.jsx)(s,{disabled:D||!_.startsWith(`flared_session_`)||!y||!g.data.search.binding,onClick:k,children:`Run once`}),C&&(0,m.jsx)(`pre`,{className:`whitespace-pre-wrap break-words text-sm`,children:C})]}),(0,m.jsxs)(`section`,{className:`space-y-3`,children:[(0,m.jsx)(`h2`,{className:`text-lg font-medium`,children:`MCP`}),(0,m.jsx)(`code`,{className:`break-all`,children:g.data.endpoint}),(0,m.
|
|
1
|
+
import{a as e,r as t}from"./client.BeKNsjPN.js";import{At as n,g as r,j as i,m as a,p as o,pt as s,q as c,s as l,u}from"./common.9pujiaSZ.js";import{i as d,t as f}from"./client.BSf433s6.js";var p=e(t(),1),m=n();function h({project:e,env:t,session:n}){let h=r(e,t),g=u(h+`/ai`),[_,v]=(0,p.useState)(``),[y,b]=(0,p.useState)(``),[x,S]=(0,p.useState)(`{"query":""}`),[C,w]=(0,p.useState)(``),[T,E]=(0,p.useState)(``),[D,O]=(0,p.useState)(!1);(0,p.useEffect)(()=>{v(``),w(``),E(``)},[h]);async function k(){O(!0),E(``),w(``);let r=f({url:`${n.runtime}/p/${e.id}/${t}`,getToken:()=>_});try{let e=await r.action(d(y,`action`),JSON.parse(x));w(JSON.stringify(e,null,2))}catch(e){E(a(e))}finally{r.dispose(),O(!1)}}async function A(){if(confirm(`Exclude all indexed files in ${e.name}/${t}? Originals remain in Files. Provider cleanup is asynchronous.`)){O(!0),E(``);try{await o(h+`/search-clear`,t===`prod`?{confirm:e.id}:{}),g.refresh()}catch(e){E(a(e))}finally{O(!1)}}}return(0,m.jsxs)(`div`,{className:`space-y-6 p-6`,children:[(0,m.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,m.jsx)(`h1`,{className:`page-title`,children:`AI`}),(0,m.jsx)(s,{variant:`outline`,onClick:g.refresh,children:`Refresh`})]}),(0,m.jsx)(l,{loading:g.loading,error:g.error||T}),g.data&&(0,m.jsxs)(m.Fragment,{children:[(0,m.jsxs)(`section`,{className:`space-y-3`,children:[(0,m.jsx)(`h2`,{className:`text-lg font-medium`,children:`Search`}),(0,m.jsx)(`p`,{children:g.data.search.binding?`Binding: ${g.data.search.binding}`:`Not connected. Configure an existing AI Search instance through platform update --config. No resource is created here.`}),(0,m.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`TXT/PDF · up to 10 MiB · explicit file indexing from application actions. File permissions belong to your application.`}),(0,m.jsxs)(`p`,{children:[`Tracked index items: `,g.data.search.remaining]}),g.data.search.states.map(e=>(0,m.jsxs)(`p`,{children:[e.status,`: `,e.count]},e.status)),g.data.search.errors>0&&(0,m.jsxs)(`p`,{role:`alert`,children:[g.data.search.errors,` operations need attention. Retry indexing through the application; retry pending cleanup with Exclude all.`]}),(0,m.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Processing states are last observed, not a live provider status. Use action search.status(fileId) to refresh a document. Files, Functions and Logs remain in their existing sections.`}),n.role!==`viewer`&&g.data.search.remaining>0&&(0,m.jsx)(s,{variant:`outline`,disabled:D,onClick:A,children:`Exclude all / retry cleanup`})]}),(0,m.jsxs)(`section`,{className:`space-y-3`,children:[(0,m.jsx)(`h2`,{className:`text-lg font-medium`,children:`Test application search`}),(0,m.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Calls your existing search action with a real application session, not dashboard/admin identity. The application must authorize each result. Session is held only in this view, never saved. Dashboard origin must be allowed by the application.`}),(0,m.jsxs)(`label`,{className:`block`,children:[`Application session`,(0,m.jsx)(c,{type:`password`,autoComplete:`off`,value:_,onChange:e=>v(e.target.value),placeholder:`flared_session_…`})]}),(0,m.jsxs)(`label`,{className:`block`,children:[`Search action path`,(0,m.jsx)(c,{value:y,onChange:e=>b(e.target.value),placeholder:`documents/search`})]}),(0,m.jsxs)(`label`,{className:`block`,children:[`Arguments (JSON)`,(0,m.jsx)(i,{value:x,onChange:e=>S(e.target.value)})]}),(0,m.jsx)(s,{disabled:D||!_.startsWith(`flared_session_`)||!y||!g.data.search.binding,onClick:k,children:`Run once`}),C&&(0,m.jsx)(`pre`,{className:`whitespace-pre-wrap break-words text-sm`,children:C})]}),(0,m.jsxs)(`section`,{className:`space-y-3`,children:[(0,m.jsx)(`h2`,{className:`text-lg font-medium`,children:`MCP`}),(0,m.jsx)(`code`,{className:`break-all`,children:g.data.endpoint}),(0,m.jsxs)(`p`,{className:`text-sm text-muted-foreground`,children:[g.data.oauth?`OAuth enabled: ${g.data.oauth.authorization_servers[0]}. Connect this URL from an OAuth-capable MCP client. Read and write grants are separate; manage them in the application.`:`OAuth is not configured for this environment. Use a dedicated application-session Bearer header from a compatible MCP client.`,` `,`Admin, deploy and dev tokens are not accepted. Application logout ends that session, not independent OAuth connections. Disabling the user revokes both.`]}),g.data.tools.length?g.data.tools.map(e=>(0,m.jsxs)(`p`,{children:[(0,m.jsx)(`strong`,{children:e.name}),` — `,e.description]},e.name)):(0,m.jsx)(`p`,{children:`No tools exposed. Add explicit mcp metadata to selected application functions and deploy that application.`})]})]})]})}export{h as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,r as t}from"./client.BeKNsjPN.js";import{At as n,S as r,_ as i,a,b as o,f as s,g as c,n as l,p as u,pt as d,s as f,u as p,v as m,x as h,y as g}from"./common.9pujiaSZ.js";import{o as _}from"./index.astro_astro_type_script_index_0_lang.
|
|
1
|
+
import{a as e,r as t}from"./client.BeKNsjPN.js";import{At as n,S as r,_ as i,a,b as o,f as s,g as c,n as l,p as u,pt as d,s as f,u as p,v as m,x as h,y as g}from"./common.9pujiaSZ.js";import{o as _}from"./index.astro_astro_type_script_index_0_lang.DBs-yURk.js";var v=e(t(),1),y=n();function b(e){let t=c(e.project,e.env),[n,b]=(0,v.useState)(``),[x,S]=(0,v.useState)(),C=p(t+`/auth-users`+(n?`?cursor=`+encodeURIComponent(n):``)),w=p(t+`/auth-settings`),T=e.session.role===`owner`,E=(n,r,i,a=[])=>{S({title:r,description:`Passwords are never displayed. Changes revoke existing sessions.`,productionId:e.env===`prod`?e.project.id:void 0,fields:a,submit:async r=>{try{await u(t+`/`+n,{...i,...s(a,e=>new FormData(r).get(e)),confirm:e.project.id})}catch(e){throw e instanceof Error&&e.message===`INVALID_PASSWORD`?Error(`Password must contain 6–128 characters. Spaces are allowed; the password is not trimmed.`):e instanceof Error&&e.message===`REGISTRATION_UNAVAILABLE`?Error(`This login is already registered. Choose another login or manage the existing user.`):e}C.refresh(),w.refresh()}})},D={name:`password`,type:`password`,required:!0,description:`6–128 characters.`};return(0,y.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,y.jsx)(`h1`,{className:`page-title`,children:`Auth`}),(0,y.jsx)(f,{loading:C.loading||w.loading,error:C.error||w.error}),w.data&&(0,y.jsxs)(`div`,{className:`flex flex-wrap items-center gap-2`,children:[(0,y.jsx)(_,{status:w.data.enabled?`Enabled`:`Disabled`}),(0,y.jsx)(_,{status:w.data.registration?`Public registration`:`Registration closed`}),T&&(0,y.jsx)(d,{variant:`outline`,onClick:()=>E(`auth-configure`,`Configure authentication`,{},[{name:`enabled`,type:`boolean`,value:w.data.enabled},{name:`registration`,type:`boolean`,value:w.data.registration}]),children:`Configure`}),T&&(0,y.jsx)(d,{onClick:()=>E(`auth-create`,`Create user`,{},[{name:`login`,type:`string`,required:!0},D]),children:`Create user`})]}),C.data&&(0,y.jsxs)(y.Fragment,{children:[(0,y.jsxs)(i,{children:[(0,y.jsx)(h,{children:(0,y.jsxs)(r,{children:[(0,y.jsx)(o,{children:`Login`}),(0,y.jsx)(o,{children:`User ID`}),(0,y.jsx)(o,{children:`Status`}),(0,y.jsx)(o,{children:`Created`}),(0,y.jsx)(o,{children:`Actions`})]})}),(0,y.jsx)(m,{children:C.data.users.map(e=>(0,y.jsxs)(r,{children:[(0,y.jsx)(g,{children:e.login}),(0,y.jsx)(g,{children:(0,y.jsx)(`code`,{children:e.id})}),(0,y.jsx)(g,{children:(0,y.jsx)(_,{status:e.disabled?`Blocked`:`Active`})}),(0,y.jsx)(g,{children:new Date(e.createdAt).toLocaleString()}),(0,y.jsx)(g,{children:(0,y.jsx)(`div`,{className:`flex flex-wrap gap-2`,children:T&&(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(d,{variant:`outline`,size:`sm`,onClick:()=>E(`auth-password`,`Change user password`,{id:e.id},[D]),children:`Change password`}),(0,y.jsx)(d,{variant:`outline`,size:`sm`,onClick:()=>E(`auth-revoke`,`Revoke all sessions`,{id:e.id}),children:`Revoke sessions`}),(0,y.jsx)(d,{variant:`outline`,size:`sm`,onClick:()=>E(`auth-disable`,e.disabled?`Unblock user`:`Block user`,{id:e.id,disabled:!e.disabled}),children:e.disabled?`Unblock`:`Block`})]})})})]},e.id))})]}),!C.data.users.length&&(0,y.jsx)(l,{title:`No users`}),(0,y.jsxs)(`div`,{className:`flex gap-2`,children:[(0,y.jsx)(d,{variant:`outline`,disabled:!n,onClick:()=>b(``),children:`First page`}),(0,y.jsx)(d,{variant:`outline`,disabled:!C.data.next,onClick:()=>b(C.data.next),children:`Next page`})]})]}),x&&(0,y.jsx)(a,{modal:x,onClose:()=>S(void 0)})]})}export{b as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,r as t}from"./client.BeKNsjPN.js";import{At as n,Ot as r,S as i,_ as a,a as o,b as s,d as c,g as l,h as u,l as d,n as f,p,pt as m,s as h,u as g,v as _,x as v,y}from"./common.9pujiaSZ.js";import{f as b,h as x,m as S,p as C,s as w}from"./index.astro_astro_type_script_index_0_lang.
|
|
1
|
+
import{a as e,r as t}from"./client.BeKNsjPN.js";import{At as n,Ot as r,S as i,_ as a,a as o,b as s,d as c,g as l,h as u,l as d,n as f,p,pt as m,s as h,u as g,v as _,x as v,y}from"./common.9pujiaSZ.js";import{f as b,h as x,m as S,p as C,s as w}from"./index.astro_astro_type_script_index_0_lang.DBs-yURk.js";import{n as T,r as E,t as D}from"./input-group.Dsc4z0iT.js";var O={name:`chevron-right`,size:24,node:[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]};O.node;var k=r(O),A=e(t(),1),j=n();function M(e,t){return e.filter(e=>e.name!==`_id`&&e.name!==`_creationTime`).map(e=>{let n=c({properties:{[e.name]:e.schema??{type:/INT|REAL/i.test(e.type)?`number`:`string`}},required:e.notnull?[e.name]:[]})[0];return{...n,defaultMode:!t&&e.dflt_value!==null,value:t?t[e.name]:n.value}})}function N(e){let t=l(e.project,e.env),n=g(t+`/schema`),[r,i]=(0,A.useState)(``),[a,o]=(0,A.useState)(``),s=n.data?.tables??[],c=s.find(e=>e.name===r)?.name??s[0]?.name;return(0,j.jsxs)(`div`,{className:`flex h-full min-h-0`,children:[(0,j.jsxs)(`section`,{className:`explorer-sidebar overflow-y-auto`,"aria-label":`Application tables`,children:[(0,j.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,j.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,j.jsx)(`h1`,{className:`page-title`,children:`Data`}),(0,j.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[s.length,` tables`]})]}),(0,j.jsxs)(D,{children:[(0,j.jsx)(T,{children:(0,j.jsx)(b,{})}),(0,j.jsx)(E,{"aria-label":`Search tables`,placeholder:`Search tables…`,value:a,onChange:e=>o(e.target.value)})]})]}),(0,j.jsx)(`div`,{className:`space-y-1 px-2`,children:s.filter(e=>e.name.toLowerCase().includes(a.toLowerCase())).map(e=>(0,j.jsxs)(m,{variant:`ghost`,className:`w-full justify-start gap-2 ${c===e.name?`bg-accent`:``}`,onClick:()=>i(e.name),children:[(0,j.jsx)(x,{}),e.name]},e.name))}),(0,j.jsx)(`p`,{className:`p-4 text-xs text-muted-foreground`,children:`Tables are defined in code.`})]}),(0,j.jsxs)(`section`,{className:`flex min-h-0 min-w-0 flex-1 flex-col`,children:[(0,j.jsx)(h,{...n}),c?(0,j.jsx)(P,{...e,table:c},c):n.data?(0,j.jsx)(f,{title:`No application tables in this release`}):null]})]})}function P({project:e,env:t,session:n,table:r}){let[c,b]=(0,A.useState)(void 0),[x,T]=(0,A.useState)(),E=l(e,t),D=g(E+`/data?table=`+encodeURIComponent(r)+(c===void 0?``:`&cursor=`+encodeURIComponent(c))),O=D.data,N=O?.columns.find(e=>e.pk===1)?.name,P=n.role!==`viewer`,F=(n,i)=>{if(!O)return;let a=n===`delete`?void 0:M(O.columns,i);T({title:n===`insert`?`Add row`:n===`update`?`Edit row`:`Delete row`,description:n===`delete`?`This deletes the selected row. The change is audited.`:`Primary keys are immutable. NULL and defaults are explicit. Changes are revision-checked and audited.`,fields:a,productionId:t===`prod`?e.id:void 0,submit:async e=>{await p(E+`/edit`,{operation:n,table:r,key:i&&N?i[N]:void 0,values:a?d(e,a):void 0,expectedRevision:O.revision,confirm:t===`prod`?new FormData(e).get(`confirm`):void 0}),D.refresh()}})};return(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`div`,{className:`detail-header`,children:[(0,j.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,j.jsx)(`h2`,{className:`font-mono text-sm font-semibold`,children:r}),O&&(0,j.jsxs)(w,{variant:`secondary`,children:[O.rows.length,` rows`]})]}),(0,j.jsxs)(`div`,{className:`flex gap-2`,children:[(0,j.jsx)(m,{variant:`ghost`,size:`icon-sm`,"aria-label":`Reload snapshot`,title:`Reload snapshot`,disabled:D.loading,onClick:D.refresh,children:(0,j.jsx)(C,{})}),P&&(0,j.jsxs)(m,{disabled:!O||D.loading,onClick:()=>F(`insert`),children:[(0,j.jsx)(S,{}),`Add row`]})]})]}),(0,j.jsxs)(`div`,{className:`flex justify-between border-b px-4 py-2 text-xs text-muted-foreground`,children:[(0,j.jsx)(`span`,{children:O?`${O.columns.length} columns · revision ${O.revision}`:`Loading table`}),(0,j.jsx)(`span`,{children:`Snapshot · updates after edits and when returning to this tab`})]}),(0,j.jsx)(h,{...D}),O&&(0,j.jsxs)(j.Fragment,{children:[(0,j.jsxs)(`div`,{className:`min-h-0 flex-1 overflow-auto`,"aria-label":`Table rows`,role:`region`,tabIndex:0,children:[(0,j.jsxs)(a,{containerClassName:`overflow-visible`,children:[(0,j.jsx)(v,{className:`sticky top-0 z-10 bg-background`,children:(0,j.jsxs)(i,{children:[O.columns.map(e=>(0,j.jsxs)(s,{children:[(0,j.jsx)(`span`,{children:e.name}),(0,j.jsxs)(`small`,{className:`block font-normal text-muted-foreground`,children:[e.type.toLowerCase(),e.pk?` · primary`:``]})]},e.name)),P&&(0,j.jsx)(s,{children:`Actions`})]})}),(0,j.jsx)(_,{children:O.rows.map((e,t)=>(0,j.jsxs)(i,{children:[O.columns.map(t=>(0,j.jsx)(y,{className:`max-w-sm truncate font-mono`,title:u(e[t.name]),children:u(e[t.name])},t.name)),P&&(0,j.jsx)(y,{children:N?(0,j.jsxs)(`div`,{className:`flex gap-1`,children:[(0,j.jsx)(m,{size:`xs`,variant:`ghost`,onClick:()=>F(`update`,e),disabled:D.loading,children:`Edit`}),(0,j.jsx)(m,{size:`xs`,variant:`destructive`,onClick:()=>F(`delete`,e),disabled:D.loading,children:`Delete`})]}):`Read only`})]},N?String(e[N]):t))})]}),!O.rows.length&&(0,j.jsx)(f,{title:`No rows yet`,children:`Add a row or call a mutation from your app.`})]}),(0,j.jsxs)(`footer`,{className:`flex shrink-0 flex-wrap items-center justify-between gap-4 border-t p-4`,children:[(0,j.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`Up to 50 rows per page · changes are audited`}),(0,j.jsxs)(`div`,{className:`flex gap-2`,children:[(0,j.jsx)(m,{variant:`outline`,disabled:c===void 0||D.loading,onClick:()=>b(void 0),children:`First page`}),(0,j.jsxs)(m,{variant:`outline`,disabled:O.next===null||D.loading,onClick:()=>b(O.next??void 0),children:[`Next page`,(0,j.jsx)(k,{})]})]})]})]}),x&&(0,j.jsx)(o,{modal:x,onClose:()=>T(void 0)})]})}export{M as columnFields,N as default};
|
package/dist/platform/dashboard/_astro/{functions-view.Bqamd_KY.js → functions-view.vsmqlnUa.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,r as t}from"./client.BeKNsjPN.js";import{At as n,Ot as r,c as i,d as a,g as o,i as s,l as c,m as l,n as u,p as d,pt as f,r as p,s as m,u as h}from"./common.9pujiaSZ.js";import{a as g,c as _,d as v,f as y,g as b,l as x,o as S,u as C}from"./index.astro_astro_type_script_index_0_lang.
|
|
1
|
+
import{a as e,r as t}from"./client.BeKNsjPN.js";import{At as n,Ot as r,c as i,d as a,g as o,i as s,l as c,m as l,n as u,p as d,pt as f,r as p,s as m,u as h}from"./common.9pujiaSZ.js";import{a as g,c as _,d as v,f as y,g as b,l as x,o as S,u as C}from"./index.astro_astro_type_script_index_0_lang.DBs-yURk.js";import{i as w,t as T}from"./client.BSf433s6.js";import{n as E,r as D,t as O}from"./input-group.Dsc4z0iT.js";var k={name:`folder`,size:24,node:[[`path`,{d:`M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z`,key:`1kt360`}]]};k.node;var A=r(k),j={name:`play`,size:24,node:[[`path`,{d:`M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z`,key:`10ikf1`}]]};j.node;var M=r(j),N=e(t(),1),P=n();function F(e){let t=h(o(e.project,e.env)+`/functions`),[n,r]=(0,N.useState)(``),[i,a]=(0,N.useState)(``),s=Object.entries(t.data?.functions??{}),c=s.find(([e])=>e===i)??s[0],l=new Map;return s.filter(([e])=>e.toLowerCase().includes(n.toLowerCase())).forEach(e=>{let t=e[0].includes(`/`)?e[0].slice(0,e[0].lastIndexOf(`/`)):`Functions`,n=l.get(t)??[];n.push(e),l.set(t,n)}),(0,P.jsxs)(`div`,{className:`flex min-h-full`,children:[(0,P.jsxs)(`section`,{className:`explorer-sidebar`,"aria-label":`Deployed functions`,children:[(0,P.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,P.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,P.jsx)(`h1`,{className:`page-title`,children:`Functions`}),(0,P.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:s.length})]}),(0,P.jsxs)(O,{children:[(0,P.jsx)(E,{children:(0,P.jsx)(y,{})}),(0,P.jsx)(D,{"aria-label":`Search functions`,placeholder:`Search functions…`,value:n,onChange:e=>r(e.target.value)})]})]}),(0,P.jsx)(`div`,{className:`space-y-2 px-2`,children:[...l].map(([e,t])=>(0,P.jsxs)(`details`,{open:!0,children:[(0,P.jsxs)(`summary`,{className:`flex cursor-pointer items-center gap-2 px-2 py-2 text-xs text-muted-foreground`,children:[(0,P.jsx)(A,{className:`size-4`}),e]}),(0,P.jsx)(`div`,{className:`space-y-1`,children:t.map(([e,t])=>(0,P.jsxs)(f,{variant:`ghost`,onClick:()=>a(e),className:`w-full justify-between ${c?.[0]===e?`bg-accent`:``}`,children:[(0,P.jsx)(`span`,{className:`truncate`,children:e.split(`/`).pop()}),(0,P.jsx)(g,{kind:t.kind})]},e))})]},e))}),(0,P.jsxs)(`p`,{className:`p-4 text-xs text-muted-foreground`,children:[`Active release · `,e.env]})]}),(0,P.jsxs)(`section`,{className:`min-w-0 flex-1`,children:[(0,P.jsx)(m,{...t}),c?(0,P.jsx)(L,{...e,path:c[0],fn:c[1]},c[0]+`:`+JSON.stringify(c[1])):t.data?(0,P.jsx)(u,{title:`No deployed functions`}):null]})]})}function I(e,t,n){return e===`dev`&&t!==`viewer`&&[`query`,`mutation`,`action`].includes(n)}function L({project:e,env:t,session:n,path:r,fn:m}){let h=a(m.input),y=I(t,n.role,m.kind)&&m.auth!==`internal`,[E,D]=(0,N.useState)(!1),[O,k]=(0,N.useState)(``),[A,j]=(0,N.useState)(),[F,L]=(0,N.useState)(!1),[R,z]=(0,N.useState)(),B=(0,N.useRef)(!0),V=(0,N.useRef)(void 0),H=(0,N.useRef)(void 0);return(0,N.useEffect)(()=>(B.current=!0,()=>{B.current=!1,H.current?.abort(),V.current?.dispose()}),[]),(0,P.jsxs)(P.Fragment,{children:[(0,P.jsxs)(`div`,{className:`detail-header`,children:[(0,P.jsxs)(`div`,{className:`flex flex-wrap items-center gap-3`,children:[(0,P.jsx)(`h2`,{className:`font-mono text-sm font-semibold`,children:r}),(0,P.jsx)(g,{kind:m.kind}),(0,P.jsx)(S,{status:m.auth,children:m.auth===`required`?`Authentication required`:m.auth})]}),(0,P.jsxs)(f,{type:`submit`,form:`function-run`,disabled:!y||E,children:[(0,P.jsx)(M,{}),E?`Running…`:`Run Function`]})]}),(0,P.jsxs)(_,{defaultValue:`runner`,children:[(0,P.jsxs)(C,{variant:`line`,className:`mx-4 mt-4`,children:[(0,P.jsx)(v,{value:`runner`,children:`Function runner`}),(0,P.jsx)(v,{value:`contract`,children:`Contract`})]}),(0,P.jsx)(x,{value:`runner`,className:`mt-4`,children:(0,P.jsxs)(`div`,{className:`grid lg:grid-cols-2`,children:[(0,P.jsxs)(`section`,{className:`space-y-4 border-b p-4 lg:border-r lg:border-b-0`,children:[(0,P.jsxs)(`div`,{className:`flex justify-between`,children:[(0,P.jsx)(`h3`,{className:`text-sm font-medium`,children:`Arguments`}),(0,P.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[h.length,` fields`]})]}),(0,P.jsx)(`form`,{id:`function-run`,onSubmit:async n=>{if(n.preventDefault(),!y||E||H.current)return;let i=new AbortController;H.current=i,D(!0),k(``),z(void 0),j(void 0),L(!1);try{let a=c(n.currentTarget,h),s=await d(o(e,t)+`/dev-token`,{},i.signal);if(!B.current||i.signal.aborted)return;V.current=T({url:s.url,getToken:()=>s.token});let l=performance.now(),u=await V.current[m.kind](w(r,m.kind),a);B.current&&!i.signal.aborted&&(j(u),L(!0),z(Math.round(performance.now()-l)))}catch(e){B.current&&!i.signal.aborted&&k(l(e))}finally{V.current?.dispose(),H.current===i&&(H.current=void 0),B.current&&D(!1)}},children:(0,P.jsx)(s,{items:h})}),(0,P.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Development execution only. Mutations and actions can change data. Live subscriptions use the SDK. Writes are not automatically retried. Internal functions are called only by server capabilities or scheduled jobs, not this HTTP runner.`})]}),(0,P.jsxs)(`section`,{className:`space-y-4 p-4`,children:[(0,P.jsxs)(`div`,{className:`flex justify-between`,children:[(0,P.jsx)(`h3`,{className:`text-sm font-medium`,children:`Result`}),(0,P.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:E?`Running…`:O?`Failed`:R===void 0?`Not executed`:`Completed · ${R} ms round trip`})]}),O?(0,P.jsx)(p,{children:O}):F?(0,P.jsx)(i,{value:A}):(0,P.jsx)(u,{title:`Run this function to see its result`,children:(0,P.jsx)(b,{className:`mx-auto mt-3 size-7`})})]})]})}),(0,P.jsxs)(x,{value:`contract`,className:`space-y-4 p-4`,children:[(0,P.jsxs)(`section`,{className:`space-y-3`,children:[(0,P.jsx)(`h3`,{className:`text-sm font-medium`,children:`Input contract`}),(0,P.jsx)(i,{value:m.input})]}),(0,P.jsxs)(`section`,{className:`space-y-3`,children:[(0,P.jsx)(`h3`,{className:`text-sm font-medium`,children:`Output contract`}),(0,P.jsx)(i,{value:m.output})]})]})]})]})}export{I as canRun,F as default};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["_astro/services-view.
|
|
2
|
-
import{a as e,r as t,t as n}from"./client.BeKNsjPN.js";import{$ as r,A as i,At as a,B as o,C as s,Ct as c,D as l,Dt as u,E as d,Et as f,F as p,G as m,H as h,I as g,J as _,K as v,L as y,M as b,N as x,O as S,Ot as C,P as w,Q as T,S as E,St as D,T as O,Tt as k,U as A,V as j,W as M,X as N,Y as ee,Z as P,_ as F,_t as I,a as L,at as R,b as z,bt as te,dt as ne,et as B,ft as re,g as V,gt as H,h as ie,ht as ae,it as U,j as oe,k as se,kt as ce,lt as le,m as ue,mt as W,n as de,nt as fe,o as pe,ot as me,p as G,pt as K,q as he,r as ge,rt as _e,s as q,t as ve,tt as ye,u as J,ut as be,v as xe,vt as Se,w as Ce,wt as we,x as Te,xt as Ee,y as Y,yt as De,z as Oe}from"./common.9pujiaSZ.js";var ke={name:`activity`,size:24,node:[[`path`,{d:`M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2`,key:`169zse`}]]};ke.node;var Ae=C(ke),je={name:`box`,size:24,node:[[`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`,key:`hh9hay`}],[`path`,{d:`m3.3 7 8.7 5 8.7-5`,key:`g66t2b`}],[`path`,{d:`M12 22V12`,key:`d0xqtd`}]]};je.node;var Me=C(je),Ne={name:`code`,size:24,node:[[`path`,{d:`m16 18 6-6-6-6`,key:`eg8j8`}],[`path`,{d:`m8 6-6 6 6 6`,key:`ppft3o`}]]};Ne.node;var Pe=C(Ne),Fe={name:`database`,size:24,node:[[`ellipse`,{cx:`12`,cy:`5`,rx:`9`,ry:`3`,key:`msslwz`}],[`path`,{d:`M3 5V19A9 3 0 0 0 21 19V5`,key:`1wlel7`}],[`path`,{d:`M3 12A9 3 0 0 0 21 12`,key:`mv7ke4`}]]};Fe.node;var Ie=C(Fe),Le={name:`file`,size:24,node:[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}]]};Le.node;var Re=C(Le),ze={name:`logs`,size:24,node:[[`path`,{d:`M3 5h1`,key:`1mv5vm`}],[`path`,{d:`M3 12h1`,key:`lp3yf2`}],[`path`,{d:`M3 19h1`,key:`w6f3n9`}],[`path`,{d:`M8 5h1`,key:`1nxr5w`}],[`path`,{d:`M8 12h1`,key:`1con00`}],[`path`,{d:`M8 19h1`,key:`k7p10e`}],[`path`,{d:`M13 5h8`,key:`a7qcls`}],[`path`,{d:`M13 12h8`,key:`h98zly`}],[`path`,{d:`M13 19h8`,key:`c3s6r1`}]]};ze.node;var Be=C(ze),Ve={name:`panel-left-close`,size:24,node:[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}],[`path`,{d:`m16 15-3-3 3-3`,key:`14y99z`}]],aliases:[`sidebar-close`]};Ve.node;var He=C(Ve),Ue={name:`panel-left-open`,size:24,node:[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}],[`path`,{d:`m14 9 3 3-3 3`,key:`8010ee`}]],aliases:[`sidebar-open`]};Ue.node;var We=C(Ue),Ge={name:`plus`,size:24,node:[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`M12 5v14`,key:`s699le`}]]};Ge.node;var Ke=C(Ge),qe={name:`refresh-cw`,size:24,node:[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]};qe.node;var Je=C(qe),Ye={name:`search`,size:24,node:[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]};Ye.node;var Xe=C(Ye),Ze={name:`settings`,size:24,node:[[`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`,key:`1i5ecw`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]};Ze.node;var Qe=C(Ze),$e={name:`shield`,size:24,node:[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}]]};$e.node;var et=C($e),tt={name:`timer`,size:24,node:[[`line`,{x1:`10`,x2:`14`,y1:`2`,y2:`2`,key:`14vaq8`}],[`line`,{x1:`12`,x2:`15`,y1:`14`,y2:`11`,key:`17fdiu`}],[`circle`,{cx:`12`,cy:`14`,r:`8`,key:`1e1u0o`}]]};tt.node;var nt=C(tt),X=e(t(),1),rt=X.createContext(void 0);function it(){let e=X.useContext(rt);if(e===void 0)throw Error(we(64));return e}var at=`data-activation-direction`,ot={tabActivationDirection:e=>({[at]:e})},Z=a(),st=X.forwardRef(function(e,t){let{className:n,defaultValue:r=0,onValueChange:i,orientation:a=`horizontal`,render:o,value:s,style:c,...l}=e,d=e.defaultValue!==void 0,p=X.useRef([]),[h,g]=X.useState(()=>new Map),[y,b]=v({controlled:s,default:r,name:`Tabs`,state:`value`}),x=s!==void 0,[S,C]=X.useState(()=>new Map),w=X.useRef(void 0),E=X.useCallback(e=>ct(S,e),[S]),[D,O]=X.useState(()=>({previousValue:y,tabActivationDirection:`none`})),{previousValue:k,tabActivationDirection:A}=D,j=A,M=!1;k!==y&&(j=lt(k,y,a,S),M=k!=null&&y!=null&&E(y)==null);let P=M?k:y,F=k!==P||A!==j;f(()=>{F&&O({previousValue:P,tabActivationDirection:j})},[P,F,j]);let I=u((e,t)=>{t.activationDirection=lt(y,e,a,S),i?.(e,t),!t.isCanceled&&b(()=>e)}),L=u((e,t)=>{i?.(e,T(t,void 0,void 0,{activationDirection:`none`}))}),R=u((e,t)=>(g(n=>{let r=new Map(n);return r.set(e,t),r}),()=>{g(n=>{if(n.get(e)!==t)return n;let r=new Map(n);return r.delete(e),r})})),z=X.useCallback(e=>h.get(e),[h]),te=X.useCallback(e=>{for(let t of S.values())if(e===t.value)return t.id},[S]),ne=X.useMemo(()=>({getTabElementBySelectedValue:E,getTabIdByPanelValue:te,getTabPanelIdByValue:z,onValueChange:I,orientation:a,registerMountedTabPanel:R,setTabMap:C,tabActivationDirection:j,value:y}),[E,te,z,I,a,R,C,j,y]),B=X.useMemo(()=>{for(let e of S.values())if(e.value===y)return e},[S,y]),re=X.useMemo(()=>{for(let e of S.values())if(!e.disabled)return e.value},[S]),V=X.useRef(!d),ie=X.useRef(r),ae=X.useRef(d),U=X.useRef(!1);f(()=>{if(x)return;function e(e,t){b(()=>e),O({previousValue:e,tabActivationDirection:`none`}),L(e,t),V.current=!1}if(S.size===0){U.current&&y!==null&&!w.current?.isConnected&&e(null,N);return}U.current=!0,w.current=S.keys().next().value;let t=B?.disabled,n=B==null&&y!==null;if(!t&&y===ie.current&&(ae.current=!1),ae.current&&t&&y===ie.current)return;let r=V.current;if(t||n){let n=re??null;if(y===n){V.current=!1;return}let i=N;r?i=ee:t&&(i=_),e(n,i)}else r&&B!=null&&(L(y,ee),V.current=!1)},[re,x,L,B,b,S,y]);let oe=H(`div`,e,{state:{orientation:a,tabActivationDirection:j},ref:t,props:l,stateAttributesMapping:ot});return(0,Z.jsx)(rt.Provider,{value:ne,children:(0,Z.jsx)(m,{elementsRef:p,children:oe})})});function ct(e,t){for(let[n,r]of e.entries())if(t===r.value)return n;return null}function lt(e,t,n,r){if(e==null||t==null)return`none`;let[i,a,o]=n===`horizontal`?[`left`,`left`,`right`]:[`top`,`up`,`down`],s=ct(r,e),c=ct(r,t);if(s==null||c==null)return s!==c&&(typeof e==`number`||typeof e==`string`)&&typeof e==typeof t?t>e?o:a:`none`;let l=s.getBoundingClientRect()[i],u=c.getBoundingClientRect()[i];return u<l?a:u>l?o:`none`}var ut=`data-composite-item-active`;function dt(e={}){let{highlightItemOnHover:t,highlightedIndex:n,onHighlightedIndexChange:r}=c(),{ref:i,index:a}=M(e),o=n===a,s=X.useRef(null),l=De(i,s);return{compositeProps:{tabIndex:o?0:-1,onFocus(){r(a)},onMouseMove(){let e=s.current;if(!t||!e)return;let n=e.hasAttribute(`disabled`)||e.ariaDisabled===`true`;!o&&!n&&e.focus()}},compositeRef:l,index:a}}var ft=X.createContext(void 0);function pt(){let e=X.useContext(ft);if(e===void 0)throw Error(we(65));return e}var mt=X.forwardRef(function(e,t){let{className:n,disabled:r=!1,render:i,value:a,id:o,nativeButton:s=!0,style:l,...d}=e,{value:p,getTabPanelIdByValue:m,onValueChange:h,orientation:g,tabActivationDirection:_}=it(),{activateOnFocus:v,registerTabResizeObserverElement:y,tabsListElement:b}=pt(),{highlightedIndex:x,onHighlightedIndexChange:S}=c(),C=re(o),{compositeProps:w,compositeRef:E,index:D}=dt({metadata:X.useMemo(()=>({disabled:r,id:C,value:a}),[r,C,a])}),O=a===p,k=X.useRef(!1),A=X.useRef(null),j=u(e=>{A.current?.(),A.current=e?y(e):null});f(()=>{if(k.current){k.current=!1;return}if(!(O&&D>-1&&x!==D))return;let e=b;if(e!=null){let t=le(Ee(e));if(t&&be(e,t))return}r||S(D)},[O,D,x,S,r,b]);let{getButtonProps:M,buttonRef:N}=te({disabled:r,native:s,focusableWhenDisabled:!0}),ee=m(a),F=X.useRef(!1),I=X.useRef(!1);function L(e){h(a,T(P,e.nativeEvent,void 0,{activationDirection:`none`}))}function R(e){O||r||L(e)}function z(e){O||r||v&&(!F.current||I.current)&&L(e)}function ne(e){if(O||r)return;F.current=!0,I.current=e.button===0;let t=Ee(e.currentTarget);function n(){F.current=!1,I.current=!1,t.removeEventListener(`pointerup`,n),t.removeEventListener(`pointercancel`,n)}t.addEventListener(`pointerup`,n),t.addEventListener(`pointercancel`,n)}return H(`button`,e,{state:{disabled:r,active:O,orientation:g,tabActivationDirection:_},ref:[t,N,E,j],props:[w,{role:`tab`,"aria-controls":ee,"aria-selected":O,id:C,onClick:R,onFocus:z,onPointerDown:ne,[ut]:O?``:void 0,onKeyDownCapture(){k.current=!0}},d,M],stateAttributesMapping:ot})}),ht=`data-index`,gt={...ot,...me},_t=X.forwardRef(function(e,t){let{className:n,value:i,render:a,keepMounted:o=!1,style:s,...c}=e,{value:l,getTabIdByPanelValue:u,orientation:d,tabActivationDirection:p,registerMountedTabPanel:m}=it(),h=re(),{ref:g,index:_}=M(),v=i===l,{mounted:y,transitionStatus:b,setMounted:x}=r(v),S=!y,C=u(i),w={hidden:S,orientation:d,tabActivationDirection:p,transitionStatus:b},T=X.useRef(null),E=H(`div`,e,{state:w,ref:[t,g,T],props:[{"aria-labelledby":C,hidden:S,id:h,role:`tabpanel`,tabIndex:v?0:-1,inert:A(!v),[ht]:_},c],stateAttributesMapping:gt});return B({open:v,ref:T,onComplete(){v||x(!1)}}),f(()=>{if(!(h==null||S&&!o))return m(i,h)},[S,o,i,h,m]),o||y?E:null});function vt(e){let{loopFocus:t=!0,orientation:n=`both`,grid:r,onLoop:i,direction:a,highlightedIndex:s,onHighlightedIndexChange:c,rootRef:l,enableHomeAndEndKeys:d=!1,stopEventPropagation:m,disabledIndices:_,modifierKeys:v=I}=e,[b,S]=X.useState(0),C=r!=null,T=X.useRef(null),E=De(T,l),D=X.useRef([]),O=X.useRef(!1),k=X.useRef(null),A=s??b,M=u((e,t=!1)=>{if(k.current=D.current[e]??null,(c??S)(e),t){let t=D.current[e];j(T.current,t,a,n)}}),N=u(e=>{if(e.size===0)return;if(O.current){let e=D.current,t=e.indexOf(k.current);if(t===-1){let t=e[A];!t||R(e,A,_)?M(yt(e,_)):k.current=t}else t!==A&&M(t);return}O.current=!0;let t=Array.from(e.keys()),r=t.find(e=>e?.hasAttribute(`data-composite-item-active`))??null,i=r?e.get(r)?.index??-1:-1;if(i!==-1)M(i);else if(R(t,A,_)){let e=ye(t,{disabledIndices:_});U(t,e)||M(e)}j(T.current,r,a,n)});f(()=>{if(_==null||s!=null||!O.current)return;let e=D.current;if(R(e,A,_)){let t=ye(e,{disabledIndices:_});U(e,t)||M(t)}},[_,s,A,D,M]);let ee=u((e,t,n)=>i?i(e,t,n,D):n),P=u(e=>{let s=e.key===`Home`||e.key===`End`;if(!y.has(e.key)||!d&&s||bt(e,v)||!T.current)return;let c=a===`rtl`,l=c?w:p,u=c?p:w,f=n===`vertical`?x:l,b=n===`vertical`?g:u,S=ne(e.nativeEvent);if(S!=null&&o(S)&&!h(S)){let t=S.selectionStart,n=S.selectionEnd,r=S.value;if(t==null||e.shiftKey||t!==n||e.key!==b&&t<r.length||e.key!==f&&t>0)return}let E=A,O=_e(D,_),k=fe(D,_);r!=null&&(E=r({disabledIndices:_,elementsRef:D,event:e,highlightedIndex:A,loopFocus:t,maxIndex:k,minIndex:O,onLoop:ee,orientation:n,rtl:c}));let j=n!==`vertical`&&e.key===l||n!==`horizontal`&&e.key===`ArrowDown`,N=n!==`vertical`&&e.key===u||n!==`horizontal`&&e.key===`ArrowUp`;d&&(e.key===`Home`?E=O:e.key===`End`&&(E=k)),E===A&&(j||N)&&(t&&E===k&&j?(E=O,i&&(E=i(e,A,E,D))):t&&E===O&&N?(E=k,i&&(E=i(e,A,E,D))):E=ye(D.current,{startingIndex:E,decrement:N,disabledIndices:_})),E!==A&&!U(D.current,E)&&(m&&e.stopPropagation(),(C||s||j||N)&&e.preventDefault(),M(E,!0),queueMicrotask(()=>{D.current[E]?.focus()}))});return{props:{ref:E,onFocus(e){let t=T.current,n=ne(e.nativeEvent);t&&n!=null&&o(n)&&n.setSelectionRange(0,n.value.length)},onKeyDown:P},highlightedIndex:A,onHighlightedIndexChange:M,elementsRef:D,onMapChange:N,relayKeyboardEvent:P}}function yt(e,t){let n=-1;for(let r=0;r<e.length;r+=1){let i=e[r];if(i&&!R(e,r,t)){if(i.hasAttribute(`data-composite-item-active`))return r;n===-1&&(n=r)}}return Math.max(n,0)}function bt(e,t){for(let n of Oe)if(!t.includes(n)&&e.getModifierState(n))return!0;return!1}function xt(e){let{render:t,className:n,style:r,refs:i=I,props:a=I,state:o=Se,stateAttributesMapping:s,highlightedIndex:c,onHighlightedIndexChange:l,orientation:u,grid:d,loopFocus:f,onLoop:p,enableHomeAndEndKeys:h,onMapChange:g,stopEventPropagation:_=!0,rootRef:v,disabledIndices:y,modifierKeys:x,highlightItemOnHover:S=!1,tag:C=`div`,...w}=e,{props:T,highlightedIndex:E,onHighlightedIndexChange:O,elementsRef:k,onMapChange:A,relayKeyboardEvent:j}=vt({grid:d,loopFocus:f,onLoop:p,orientation:u,highlightedIndex:c,onHighlightedIndexChange:l,rootRef:v,stopEventPropagation:_,enableHomeAndEndKeys:h,direction:b(),disabledIndices:y,modifierKeys:x}),M=H(C,e,{state:o,ref:i,props:[T,...a,w],stateAttributesMapping:s}),N=X.useMemo(()=>({highlightedIndex:E,onHighlightedIndexChange:O,highlightItemOnHover:S,relayKeyboardEvent:j}),[E,O,S,j]);return(0,Z.jsx)(D.Provider,{value:N,children:(0,Z.jsx)(m,{elementsRef:k,onMapChange:e=>{g?.(e),A(e)},children:M})})}var St=X.forwardRef(function(e,t){let{activateOnFocus:n=!1,className:r,loopFocus:i=!0,render:a,style:o,...s}=e,{orientation:c,setTabMap:l,tabActivationDirection:d}=it(),[p,m]=X.useState(0),[h,g]=X.useState(null),_=X.useRef(new Set),v=X.useRef(new Set),y=X.useRef(null);f(()=>{if(typeof ResizeObserver>`u`)return;let e=new ResizeObserver(()=>{_.current.forEach(e=>{e()})});return y.current=e,h&&e.observe(h),v.current.forEach(t=>{e.observe(t)}),()=>{e.disconnect(),y.current=null}},[h]);let b=u(e=>(_.current.add(e),()=>{_.current.delete(e)})),x=u(e=>(v.current.add(e),y.current?.observe(e),()=>{v.current.delete(e),y.current?.unobserve(e)})),S={orientation:c,tabActivationDirection:d},C={"aria-orientation":c===`vertical`?`vertical`:void 0,role:`tablist`},w=X.useMemo(()=>({activateOnFocus:n,registerIndicatorUpdateListener:b,registerTabResizeObserverElement:x,tabsListElement:h}),[n,b,x,h]);return(0,Z.jsx)(ft.Provider,{value:w,children:(0,Z.jsx)(xt,{render:a,className:r,style:o,state:S,refs:[t,g],props:[C,s],stateAttributesMapping:ot,highlightedIndex:p,enableHomeAndEndKeys:!0,loopFocus:i,orientation:c,onHighlightedIndexChange:m,onMapChange:l,disabledIndices:I})})}),Ct=n();function wt({className:e,orientation:t=`horizontal`,...n}){return(0,Z.jsx)(st,{"data-slot":`tabs`,"data-orientation":t,className:W(`group/tabs flex gap-2 data-horizontal:flex-col`,e),...n})}var Tt=ae(`group/tabs-list inline-flex w-fit items-center justify-center rounded-none p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none`,{variants:{variant:{default:`bg-muted`,line:`gap-1 bg-transparent`}},defaultVariants:{variant:`default`}});function Et({className:e,variant:t=`default`,...n}){return(0,Z.jsx)(St,{"data-slot":`tabs-list`,"data-variant":t,className:W(Tt({variant:t}),e),...n})}function Dt({className:e,...t}){return(0,Z.jsx)(mt,{"data-slot":`tabs-trigger`,className:W(`relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-none border border-transparent px-1.5 py-0.5 text-xs font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start group-data-vertical/tabs:py-[calc(--spacing(1.25))] hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,`group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent`,`data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground`,`after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100`,e),...t})}function Ot({className:e,...t}){return(0,Z.jsx)(_t,{"data-slot":`tabs-content`,className:W(`flex-1 text-xs/relaxed outline-none`,e),...t})}function kt(e){return H(e.defaultTagName??`div`,e,e)}var At=ae(`group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-none border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!`,{variants:{variant:{default:`bg-primary text-primary-foreground [a]:hover:bg-primary/80`,secondary:`bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80`,success:`border-emerald-600/20 bg-emerald-100/50 text-emerald-700 dark:border-emerald-400/20 dark:bg-emerald-900/50 dark:text-emerald-200`,warning:`border-amber-600/20 bg-amber-100/50 text-amber-700 dark:border-amber-400/20 dark:bg-amber-900/50 dark:text-amber-200`,info:`border-blue-600/20 bg-blue-100/50 text-blue-700 dark:border-blue-400/20 dark:bg-blue-900/50 dark:text-blue-200`,destructive:`bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20`,outline:`border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground`,ghost:`hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50`,link:`text-primary underline-offset-4 hover:underline`}},defaultVariants:{variant:`default`}});function jt({className:e,variant:t=`default`,render:n,...r}){return kt({defaultTagName:`span`,props:k({className:W(At({variant:t}),e)},r),render:n,state:{slot:`badge`,variant:t}})}var Mt=new Map([...[`ready`,`active`,`enabled`,`ok`,`completed`,`development`].map(e=>[e,`success`]),...[`pending`,`paused`,`activating`,`restoring`,`incomplete`,`required`].map(e=>[e,`warning`]),...[`uploading`,`running`,`queued`,`enqueued`,`production`,`public registration`,`public`].map(e=>[e,`info`]),...[`error`,`failed`,`blocked`,`unavailable`].map(e=>[e,`destructive`])]);function Q({status:e,children:t}){return(0,Z.jsx)(jt,{variant:Mt.get(e.toLowerCase())??`secondary`,children:t??e})}var Nt={query:`bg-yellow-100/50 text-yellow-700 dark:bg-yellow-900/50 dark:text-yellow-200`,mutation:`bg-blue-100/50 text-blue-700 dark:bg-blue-900/50 dark:text-blue-200`,action:`bg-purple-100/50 text-purple-700 dark:bg-purple-900/50 dark:text-purple-200`};function Pt({kind:e}){return(0,Z.jsx)(jt,{variant:`secondary`,className:Nt[e],children:e})}function Ft(e){let[t,n]=(0,X.useState)(!1);return(0,Z.jsxs)(`details`,{className:`rounded-lg border`,onToggle:e=>n(e.currentTarget.open),children:[(0,Z.jsx)(`summary`,{className:`cursor-pointer p-4 font-medium`,children:`Deployment history`}),t&&(0,Z.jsx)(`div`,{className:`p-4 pt-0`,children:(0,Z.jsx)(It,{...e})})]})}function It(e){let[t,n]=(0,X.useState)(),[r,i]=(0,X.useState)(),a=V(e.project,e.env),o=V(e.project,e.env),s=J(a+`/history`),c=e.session.role!==`viewer`,l=async(t,n)=>{let r=n?V(e.project,`prod`):o,a=await G(r+`/health`);i({title:n?`Promote backend to production`:`Rollback backend`,description:`Activate this exact backend hash after native schema/job validation. Data, files and settings stay unchanged. Frontend is not published by this button; use the CLI release flow for that.`,productionId:n||e.env===`prod`?e.project.id:void 0,submit:async()=>{await G(r+(n?`/release-promote`:`/release-rollback`),{hash:t,expected:a.active,confirm:e.project.id}),s.refresh(),e.refresh()}})},[u,d]=(0,X.useState)();return(0,Z.jsxs)(`div`,{className:`space-y-3`,children:[(0,Z.jsx)(q,{loading:s.loading,error:u||s.error}),(0,Z.jsxs)(F,{children:[(0,Z.jsx)(Te,{children:(0,Z.jsxs)(E,{children:[(0,Z.jsx)(z,{children:`First published`}),(0,Z.jsx)(z,{children:`Backend hash`}),(0,Z.jsx)(z,{children:`Actions`})]})}),(0,Z.jsx)(xe,{children:s.data?.map(t=>(0,Z.jsxs)(E,{children:[(0,Z.jsx)(Y,{children:new Date(t.at).toLocaleString()}),(0,Z.jsxs)(Y,{children:[(0,Z.jsx)(`code`,{className:`text-xs`,children:t.hash.slice(0,12)}),e.active===t.hash&&(0,Z.jsx)(Q,{status:`Active`})]}),(0,Z.jsx)(Y,{children:(0,Z.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,Z.jsx)(K,{variant:`outline`,size:`sm`,onClick:()=>n(t.hash),children:`View contracts`}),c&&e.active!==t.hash&&(0,Z.jsx)(K,{variant:`outline`,size:`sm`,onClick:()=>void l(t.hash,!1).catch(e=>d(e.message)),children:`Rollback backend`}),c&&e.env===`dev`&&(0,Z.jsx)(K,{variant:`outline`,size:`sm`,onClick:()=>void l(t.hash,!0).catch(e=>d(e.message)),children:`Promote backend`})]})})]},t.hash))})]}),t&&(0,Z.jsx)(Lt,{path:a,hash:t,close:()=>n(void 0)}),r&&(0,Z.jsx)(L,{modal:r,onClose:()=>i(void 0)})]})}function Lt({path:e,hash:t,close:n}){let r=J(e+`/release?hash=`+t);return(0,Z.jsx)(s,{open:!0,onOpenChange:e=>{e||n()},children:(0,Z.jsxs)(Ce,{className:`max-h-[80vh] overflow-auto`,children:[(0,Z.jsxs)(d,{children:[(0,Z.jsx)(l,{children:`Backend release`}),(0,Z.jsx)(O,{className:`break-all`,children:t})]}),(0,Z.jsx)(q,{...r}),r.data&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`h3`,{className:`font-medium`,children:`Tables`}),(0,Z.jsxs)(F,{children:[(0,Z.jsx)(Te,{children:(0,Z.jsxs)(E,{children:[(0,Z.jsx)(z,{children:`Table`}),(0,Z.jsx)(z,{children:`Fields`})]})}),(0,Z.jsx)(xe,{children:Object.entries(r.data.schema).map(([e,t])=>(0,Z.jsxs)(E,{children:[(0,Z.jsx)(Y,{children:e}),(0,Z.jsx)(Y,{children:Object.keys(t.document.properties??{}).join(`, `)||`No declared fields`})]},e))})]}),(0,Z.jsx)(`h3`,{className:`font-medium`,children:`Functions`}),(0,Z.jsxs)(F,{children:[(0,Z.jsx)(Te,{children:(0,Z.jsxs)(E,{children:[(0,Z.jsx)(z,{children:`Function`}),(0,Z.jsx)(z,{children:`Kind`}),(0,Z.jsx)(z,{children:`Access`})]})}),(0,Z.jsx)(xe,{children:Object.entries(r.data.manifest.functions).map(([e,t])=>(0,Z.jsxs)(E,{children:[(0,Z.jsx)(Y,{children:e}),(0,Z.jsx)(Y,{children:(0,Z.jsx)(Pt,{kind:t.kind})}),(0,Z.jsx)(Y,{children:(0,Z.jsx)(Q,{status:t.auth})})]},e))})]})]})]})})}function Rt({className:e,size:t=`default`,...n}){return(0,Z.jsx)(`div`,{"data-slot":`card`,"data-size":t,className:W(`group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-none bg-card py-(--card-spacing) text-xs/relaxed text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none`,e),...n})}function zt({className:e,...t}){return(0,Z.jsx)(`div`,{"data-slot":`card-header`,className:W(`group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-none px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)`,e),...t})}function Bt({className:e,...t}){return(0,Z.jsx)(`div`,{"data-slot":`card-title`,className:W(`font-heading text-sm font-medium group-data-[size=sm]/card:text-sm`,e),...t})}function Vt({className:e,...t}){return(0,Z.jsx)(`div`,{"data-slot":`card-content`,className:W(`px-(--card-spacing)`,e),...t})}function Ht({project:e,env:t,session:n,connect:r}){let i=J(V(e,t)+`/health`),a=J(V(e,t)+`/settings`);return(0,Z.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,Z.jsx)(`h1`,{className:`page-title`,children:`Health`}),(0,Z.jsx)(q,{loading:i.loading||a.loading,error:i.error||a.error}),i.data&&a.data&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`h2`,{className:`section-title`,children:`Summary`}),(0,Z.jsx)(Rt,{children:(0,Z.jsxs)(Vt,{className:`grid gap-4 md:grid-cols-2`,children:[(0,Z.jsxs)(`div`,{className:`space-y-3`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(Q,{status:t===`dev`?`Development`:`Production`}),(0,Z.jsx)(`strong`,{children:e.name})]}),(0,Z.jsx)(`p`,{className:`text-muted-foreground`,children:`Cloudflare · Durable Objects · SQLite`}),(0,Z.jsxs)(`p`,{className:`font-mono text-xs text-muted-foreground`,children:[`Release `,i.data.active?.slice(0,12)??`not deployed`]})]}),(0,Z.jsxs)(`div`,{className:`space-y-2`,children:[(0,Z.jsx)(`p`,{className:`text-muted-foreground`,children:`Cloud URL`}),(0,Z.jsx)(`code`,{className:`block select-all break-all text-xs`,children:a.data.url}),(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 text-muted-foreground`,children:[(0,Z.jsx)(Q,{status:i.data.status}),i.data.connections,` connections · `,i.data.subscriptions,` `,`subscriptions`]})]})]})}),(0,Z.jsx)(Ft,{project:e,env:t,session:n,active:i.data.active,refresh:i.refresh}),(0,Z.jsx)(K,{variant:`outline`,onClick:r,children:`Connect SDK`})]})]})}function Ut({project:e,env:t}){let n=J(V(e,t)+`/schema`);return(0,Z.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Z.jsx)(`h1`,{className:`page-title`,children:`Schema`}),(0,Z.jsx)(`div`,{className:`flex gap-2`,children:(0,Z.jsx)(K,{variant:`ghost`,size:`icon-sm`,"aria-label":`Reload snapshot`,title:`Reload snapshot`,onClick:n.refresh,disabled:n.loading,children:(0,Z.jsx)(Je,{})})})]}),(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Defined in code; validated documents and indexes activate atomically. System tables are hidden.`}),(0,Z.jsx)(q,{...n}),n.data?.tables.map(e=>(0,Z.jsxs)(Rt,{children:[(0,Z.jsx)(zt,{children:(0,Z.jsx)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:(0,Z.jsx)(Bt,{className:`font-mono`,children:e.name})})}),(0,Z.jsxs)(Vt,{className:`space-y-4`,children:[(0,Z.jsx)(pe,{rows:e.columns.map(e=>({Field:e.name,Type:e.type,Required:!!e.notnull,Primary:!!e.pk,Default:e.dflt_value})),columns:[`Field`,`Type`,`Required`,`Primary`,`Default`]}),(0,Z.jsx)(pe,{rows:Object.entries(e.indexes).map(([e,t])=>({Index:e,Fields:t.join(`, `)})),columns:[`Index`,`Fields`]}),(0,Z.jsxs)(`details`,{children:[(0,Z.jsx)(`summary`,{className:`cursor-pointer text-muted-foreground`,children:`Document contract`}),(0,Z.jsx)(`pre`,{className:`code-block mt-3`,children:JSON.stringify(e.document,null,2)})]})]})]},e.name)),n.data&&!n.data.tables.length&&(0,Z.jsx)(de,{title:`No application tables`})]})}function Wt({project:e,env:t}){let n=J(V(e,t)+`/logs`);return(0,Z.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Z.jsx)(`h1`,{className:`page-title`,children:`Logs`}),(0,Z.jsx)(K,{variant:`ghost`,size:`icon-sm`,"aria-label":`Reload snapshot`,title:`Reload snapshot`,onClick:n.refresh,disabled:n.loading,children:(0,Z.jsx)(Je,{})})]}),(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Last 100 invocation summaries. Successful queries are held in memory and disappear on hibernation/restart; writes and failures are persisted. Not Cloudflare Tail logs or billing analytics.`}),(0,Z.jsx)(q,{...n}),n.data&&(n.data.length?(0,Z.jsx)(pe,{rows:n.data,renderCell:(e,t)=>e===`kind`&&[`query`,`mutation`,`action`].includes(String(t))?(0,Z.jsx)(Pt,{kind:t}):e===`status`?(0,Z.jsx)(Q,{status:t===`ok`?`ok`:`error`,children:ie(t)}):e===`at`&&typeof t==`number`?new Date(t).toLocaleString():ie(t),columns:[`at`,`path`,`kind`,`status`,`ms`],labels:{at:`Time`,path:`Function`,kind:`Type`,status:`Status`,ms:`Duration (ms)`}}):(0,Z.jsx)(de,{title:`No recent function calls`}))]})}var Gt=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Kt=function(e){return`/`+e},qt={},Jt=function(e){return e.pathname.endsWith(`.css`)},Yt=function(e,t,n){if(t in e)return e[t];let r=n();if(!r){e[t]=void 0;return}let i=r.then(()=>{e[t]=void 0},n=>{throw e[t]=void 0,n});return e[t]=i,i},$=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=function(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))},i=function(e){return import.meta.resolve?new URL(import.meta.resolve(e)):new URL(e,import.meta.url)},a,o=document.querySelector(`meta[property=csp-nonce]`),s=o?.nonce||o?.getAttribute(`nonce`);r=e(t.map(e=>{e=Kt(e,n);let t=i(e),r=Jt(t);return Yt(qt,t.href,()=>{if(a===void 0){a={all:new Set,styles:new Set};let e=document.getElementsByTagName(`link`);for(let t=e.length-1;t>=0;t--){let n=e[t];a.all.add(n.href),n.rel===`stylesheet`&&a.styles.add(n.href)}}if((r?a.styles:a.all).has(t.href))return;let e=document.createElement(`link`);if(e.rel=r?`stylesheet`:Gt,r||(e.as=`script`),e.crossOrigin=``,e.href=t.href,s&&e.setAttribute(`nonce`,s),document.head.appendChild(e),r)return new Promise((n,r)=>{e.addEventListener(`load`,n),e.addEventListener(`error`,()=>r(Error(`Unable to preload CSS for ${t}`)))})})}).filter(e=>e!==void 0))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Xt=(0,X.lazy)(()=>$(()=>import(`./services-view.B7BR4JD3.js`).then(e=>({default:e.FilesView})),__vite__mapDeps([0,1,2,3]))),Zt=(0,X.lazy)(()=>$(()=>import(`./services-view.B7BR4JD3.js`).then(e=>({default:e.SchedulesView})),__vite__mapDeps([0,1,2,3]))),Qt=(0,X.lazy)(()=>$(()=>import(`./data-view.jmNzQKhW.js`),__vite__mapDeps([4,1,2,5]))),$t=(0,X.lazy)(()=>$(()=>import(`./functions-view.Bqamd_KY.js`),__vite__mapDeps([6,1,2,3,5]))),en=(0,X.lazy)(()=>$(()=>import(`./ai-view.D6ouaMiL.js`),__vite__mapDeps([7,1,2,3]))),tn=(0,X.lazy)(()=>$(()=>import(`./auth-view.0CuFK-xf.js`),__vite__mapDeps([8,1,2]))),nn=(0,X.lazy)(()=>$(()=>import(`./settings-view.DM-igZ4O.js`),__vite__mapDeps([9,1,2]))),rn=(0,X.lazy)(()=>$(()=>import(`./sdk-view.DuMOEfZu.js`),__vite__mapDeps([10,1,2]))),an=[{key:`health`,label:`Health`,icon:Ae},{key:`data`,label:`Data`,icon:Ie},{key:`schema`,label:`Schema`,icon:Me},{key:`functions`,label:`Functions`,icon:Pe},{key:`files`,label:`Files`,icon:Re},{key:`schedules`,label:`Schedules`,icon:nt},{key:`ai`,label:`AI`,icon:Xe},{key:`auth`,label:`Auth`,icon:et},{key:`logs`,label:`Logs`,icon:Be}],on=(0,X.lazy)(()=>$(()=>import(`./cli-approval.emPTVRqn.js`),__vite__mapDeps([11,1,2])));function sn(){return new URLSearchParams(location.search).has(`cli`)?(0,Z.jsx)(X.Suspense,{fallback:(0,Z.jsx)(`p`,{children:`Loading…`}),children:(0,Z.jsx)(on,{})}):(0,Z.jsx)(cn,{})}function cn(){let[e,t]=(0,X.useState)(),[n,r]=(0,X.useState)([]),[a,o]=(0,X.useState)(),[s,c]=(0,X.useState)(`dev`),[l,u]=(0,X.useState)(`health`),[d,f]=(0,X.useState)(``),[p,m]=(0,X.useState)(!0),[h,g]=(0,X.useState)(),[_,v]=(0,X.useState)(!1);(0,X.useEffect)(()=>{let e=new AbortController;return v(localStorage.getItem(`flare.sidebar`)===`collapsed`),Promise.all([G(`session`,void 0,e.signal),G(`projects`,void 0,e.signal)]).then(([n,i])=>{e.signal.aborted||(t(n),r(i),o(i.find(e=>e.id===localStorage.getItem(`flare.project`))??i[0]),m(!1))}).catch(t=>{e.signal.aborted||(f(ue(t)),m(!1))}),()=>e.abort()},[]);let y=e=>{let t=n.find(t=>t.id===e);t&&(o(t),c(`dev`),u(`health`),g(void 0),localStorage.setItem(`flare.project`,e))},b=()=>g({title:`Create project`,description:`Creates separate development and production environments.`,content:(0,Z.jsxs)(se,{children:[(0,Z.jsxs)(S,{children:[(0,Z.jsx)(i,{htmlFor:`project-name`,children:`Project name`}),(0,Z.jsx)(he,{id:`project-name`,name:`name`,required:!0,maxLength:100,placeholder:`CRM`})]}),(0,Z.jsxs)(S,{children:[(0,Z.jsx)(i,{htmlFor:`project-alias`,children:`Short URL name (optional)`}),(0,Z.jsx)(he,{id:`project-alias`,name:`alias`,maxLength:48,pattern:`[a-z][a-z0-9]*(?:-[a-z0-9]+)*`,placeholder:`crm`})]}),(0,Z.jsxs)(S,{children:[(0,Z.jsx)(i,{htmlFor:`project-origins`,children:`Allowed frontend origins · one per line`}),(0,Z.jsx)(oe,{id:`project-origins`,name:`origins`,placeholder:`http://127.0.0.1:5173`})]})]}),submit:async e=>{let t=new FormData(e),n=await G(`projects`,{name:t.get(`name`),alias:t.get(`alias`)||void 0,origins:[location.origin,...String(t.get(`origins`)).split(`
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["_astro/services-view.Dx1rjMWa.js","_astro/client.BeKNsjPN.js","_astro/common.9pujiaSZ.js","_astro/client.BSf433s6.js","_astro/data-view.BFL2F3o9.js","_astro/input-group.Dsc4z0iT.js","_astro/functions-view.vsmqlnUa.js","_astro/ai-view.DcYKk5W_.js","_astro/auth-view.KnVtTZYn.js","_astro/settings-view.DPwEyqzv.js","_astro/sdk-view.BPVWrAC3.js","_astro/cli-approval.emPTVRqn.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{a as e,r as t,t as n}from"./client.BeKNsjPN.js";import{$ as r,A as i,At as a,B as o,C as s,Ct as c,D as l,Dt as u,E as d,Et as f,F as p,G as m,H as h,I as g,J as _,K as v,L as y,M as b,N as x,O as S,Ot as C,P as w,Q as T,S as E,St as D,T as O,Tt as k,U as A,V as j,W as M,X as N,Y as ee,Z as P,_ as F,_t as I,a as L,at as R,b as z,bt as te,dt as ne,et as B,ft as re,g as V,gt as H,h as ie,ht as ae,it as U,j as oe,k as se,kt as ce,lt as le,m as ue,mt as W,n as de,nt as fe,o as pe,ot as me,p as G,pt as K,q as he,r as ge,rt as _e,s as q,t as ve,tt as ye,u as J,ut as be,v as xe,vt as Se,w as Ce,wt as we,x as Te,xt as Ee,y as Y,yt as De,z as Oe}from"./common.9pujiaSZ.js";var ke={name:`activity`,size:24,node:[[`path`,{d:`M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2`,key:`169zse`}]]};ke.node;var Ae=C(ke),je={name:`box`,size:24,node:[[`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`,key:`hh9hay`}],[`path`,{d:`m3.3 7 8.7 5 8.7-5`,key:`g66t2b`}],[`path`,{d:`M12 22V12`,key:`d0xqtd`}]]};je.node;var Me=C(je),Ne={name:`code`,size:24,node:[[`path`,{d:`m16 18 6-6-6-6`,key:`eg8j8`}],[`path`,{d:`m8 6-6 6 6 6`,key:`ppft3o`}]]};Ne.node;var Pe=C(Ne),Fe={name:`database`,size:24,node:[[`ellipse`,{cx:`12`,cy:`5`,rx:`9`,ry:`3`,key:`msslwz`}],[`path`,{d:`M3 5V19A9 3 0 0 0 21 19V5`,key:`1wlel7`}],[`path`,{d:`M3 12A9 3 0 0 0 21 12`,key:`mv7ke4`}]]};Fe.node;var Ie=C(Fe),Le={name:`file`,size:24,node:[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M14 2v5a1 1 0 0 0 1 1h5`,key:`wfsgrz`}]]};Le.node;var Re=C(Le),ze={name:`logs`,size:24,node:[[`path`,{d:`M3 5h1`,key:`1mv5vm`}],[`path`,{d:`M3 12h1`,key:`lp3yf2`}],[`path`,{d:`M3 19h1`,key:`w6f3n9`}],[`path`,{d:`M8 5h1`,key:`1nxr5w`}],[`path`,{d:`M8 12h1`,key:`1con00`}],[`path`,{d:`M8 19h1`,key:`k7p10e`}],[`path`,{d:`M13 5h8`,key:`a7qcls`}],[`path`,{d:`M13 12h8`,key:`h98zly`}],[`path`,{d:`M13 19h8`,key:`c3s6r1`}]]};ze.node;var Be=C(ze),Ve={name:`panel-left-close`,size:24,node:[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}],[`path`,{d:`m16 15-3-3 3-3`,key:`14y99z`}]],aliases:[`sidebar-close`]};Ve.node;var He=C(Ve),Ue={name:`panel-left-open`,size:24,node:[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M9 3v18`,key:`fh3hqa`}],[`path`,{d:`m14 9 3 3-3 3`,key:`8010ee`}]],aliases:[`sidebar-open`]};Ue.node;var We=C(Ue),Ge={name:`plus`,size:24,node:[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`M12 5v14`,key:`s699le`}]]};Ge.node;var Ke=C(Ge),qe={name:`refresh-cw`,size:24,node:[[`path`,{d:`M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8`,key:`v9h5vc`}],[`path`,{d:`M21 3v5h-5`,key:`1q7to0`}],[`path`,{d:`M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16`,key:`3uifl3`}],[`path`,{d:`M8 16H3v5`,key:`1cv678`}]]};qe.node;var Je=C(qe),Ye={name:`search`,size:24,node:[[`path`,{d:`m21 21-4.34-4.34`,key:`14j7rj`}],[`circle`,{cx:`11`,cy:`11`,r:`8`,key:`4ej97u`}]]};Ye.node;var Xe=C(Ye),Ze={name:`settings`,size:24,node:[[`path`,{d:`M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915`,key:`1i5ecw`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]};Ze.node;var Qe=C(Ze),$e={name:`shield`,size:24,node:[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}]]};$e.node;var et=C($e),tt={name:`timer`,size:24,node:[[`line`,{x1:`10`,x2:`14`,y1:`2`,y2:`2`,key:`14vaq8`}],[`line`,{x1:`12`,x2:`15`,y1:`14`,y2:`11`,key:`17fdiu`}],[`circle`,{cx:`12`,cy:`14`,r:`8`,key:`1e1u0o`}]]};tt.node;var nt=C(tt),X=e(t(),1),rt=X.createContext(void 0);function it(){let e=X.useContext(rt);if(e===void 0)throw Error(we(64));return e}var at=`data-activation-direction`,ot={tabActivationDirection:e=>({[at]:e})},Z=a(),st=X.forwardRef(function(e,t){let{className:n,defaultValue:r=0,onValueChange:i,orientation:a=`horizontal`,render:o,value:s,style:c,...l}=e,d=e.defaultValue!==void 0,p=X.useRef([]),[h,g]=X.useState(()=>new Map),[y,b]=v({controlled:s,default:r,name:`Tabs`,state:`value`}),x=s!==void 0,[S,C]=X.useState(()=>new Map),w=X.useRef(void 0),E=X.useCallback(e=>ct(S,e),[S]),[D,O]=X.useState(()=>({previousValue:y,tabActivationDirection:`none`})),{previousValue:k,tabActivationDirection:A}=D,j=A,M=!1;k!==y&&(j=lt(k,y,a,S),M=k!=null&&y!=null&&E(y)==null);let P=M?k:y,F=k!==P||A!==j;f(()=>{F&&O({previousValue:P,tabActivationDirection:j})},[P,F,j]);let I=u((e,t)=>{t.activationDirection=lt(y,e,a,S),i?.(e,t),!t.isCanceled&&b(()=>e)}),L=u((e,t)=>{i?.(e,T(t,void 0,void 0,{activationDirection:`none`}))}),R=u((e,t)=>(g(n=>{let r=new Map(n);return r.set(e,t),r}),()=>{g(n=>{if(n.get(e)!==t)return n;let r=new Map(n);return r.delete(e),r})})),z=X.useCallback(e=>h.get(e),[h]),te=X.useCallback(e=>{for(let t of S.values())if(e===t.value)return t.id},[S]),ne=X.useMemo(()=>({getTabElementBySelectedValue:E,getTabIdByPanelValue:te,getTabPanelIdByValue:z,onValueChange:I,orientation:a,registerMountedTabPanel:R,setTabMap:C,tabActivationDirection:j,value:y}),[E,te,z,I,a,R,C,j,y]),B=X.useMemo(()=>{for(let e of S.values())if(e.value===y)return e},[S,y]),re=X.useMemo(()=>{for(let e of S.values())if(!e.disabled)return e.value},[S]),V=X.useRef(!d),ie=X.useRef(r),ae=X.useRef(d),U=X.useRef(!1);f(()=>{if(x)return;function e(e,t){b(()=>e),O({previousValue:e,tabActivationDirection:`none`}),L(e,t),V.current=!1}if(S.size===0){U.current&&y!==null&&!w.current?.isConnected&&e(null,N);return}U.current=!0,w.current=S.keys().next().value;let t=B?.disabled,n=B==null&&y!==null;if(!t&&y===ie.current&&(ae.current=!1),ae.current&&t&&y===ie.current)return;let r=V.current;if(t||n){let n=re??null;if(y===n){V.current=!1;return}let i=N;r?i=ee:t&&(i=_),e(n,i)}else r&&B!=null&&(L(y,ee),V.current=!1)},[re,x,L,B,b,S,y]);let oe=H(`div`,e,{state:{orientation:a,tabActivationDirection:j},ref:t,props:l,stateAttributesMapping:ot});return(0,Z.jsx)(rt.Provider,{value:ne,children:(0,Z.jsx)(m,{elementsRef:p,children:oe})})});function ct(e,t){for(let[n,r]of e.entries())if(t===r.value)return n;return null}function lt(e,t,n,r){if(e==null||t==null)return`none`;let[i,a,o]=n===`horizontal`?[`left`,`left`,`right`]:[`top`,`up`,`down`],s=ct(r,e),c=ct(r,t);if(s==null||c==null)return s!==c&&(typeof e==`number`||typeof e==`string`)&&typeof e==typeof t?t>e?o:a:`none`;let l=s.getBoundingClientRect()[i],u=c.getBoundingClientRect()[i];return u<l?a:u>l?o:`none`}var ut=`data-composite-item-active`;function dt(e={}){let{highlightItemOnHover:t,highlightedIndex:n,onHighlightedIndexChange:r}=c(),{ref:i,index:a}=M(e),o=n===a,s=X.useRef(null),l=De(i,s);return{compositeProps:{tabIndex:o?0:-1,onFocus(){r(a)},onMouseMove(){let e=s.current;if(!t||!e)return;let n=e.hasAttribute(`disabled`)||e.ariaDisabled===`true`;!o&&!n&&e.focus()}},compositeRef:l,index:a}}var ft=X.createContext(void 0);function pt(){let e=X.useContext(ft);if(e===void 0)throw Error(we(65));return e}var mt=X.forwardRef(function(e,t){let{className:n,disabled:r=!1,render:i,value:a,id:o,nativeButton:s=!0,style:l,...d}=e,{value:p,getTabPanelIdByValue:m,onValueChange:h,orientation:g,tabActivationDirection:_}=it(),{activateOnFocus:v,registerTabResizeObserverElement:y,tabsListElement:b}=pt(),{highlightedIndex:x,onHighlightedIndexChange:S}=c(),C=re(o),{compositeProps:w,compositeRef:E,index:D}=dt({metadata:X.useMemo(()=>({disabled:r,id:C,value:a}),[r,C,a])}),O=a===p,k=X.useRef(!1),A=X.useRef(null),j=u(e=>{A.current?.(),A.current=e?y(e):null});f(()=>{if(k.current){k.current=!1;return}if(!(O&&D>-1&&x!==D))return;let e=b;if(e!=null){let t=le(Ee(e));if(t&&be(e,t))return}r||S(D)},[O,D,x,S,r,b]);let{getButtonProps:M,buttonRef:N}=te({disabled:r,native:s,focusableWhenDisabled:!0}),ee=m(a),F=X.useRef(!1),I=X.useRef(!1);function L(e){h(a,T(P,e.nativeEvent,void 0,{activationDirection:`none`}))}function R(e){O||r||L(e)}function z(e){O||r||v&&(!F.current||I.current)&&L(e)}function ne(e){if(O||r)return;F.current=!0,I.current=e.button===0;let t=Ee(e.currentTarget);function n(){F.current=!1,I.current=!1,t.removeEventListener(`pointerup`,n),t.removeEventListener(`pointercancel`,n)}t.addEventListener(`pointerup`,n),t.addEventListener(`pointercancel`,n)}return H(`button`,e,{state:{disabled:r,active:O,orientation:g,tabActivationDirection:_},ref:[t,N,E,j],props:[w,{role:`tab`,"aria-controls":ee,"aria-selected":O,id:C,onClick:R,onFocus:z,onPointerDown:ne,[ut]:O?``:void 0,onKeyDownCapture(){k.current=!0}},d,M],stateAttributesMapping:ot})}),ht=`data-index`,gt={...ot,...me},_t=X.forwardRef(function(e,t){let{className:n,value:i,render:a,keepMounted:o=!1,style:s,...c}=e,{value:l,getTabIdByPanelValue:u,orientation:d,tabActivationDirection:p,registerMountedTabPanel:m}=it(),h=re(),{ref:g,index:_}=M(),v=i===l,{mounted:y,transitionStatus:b,setMounted:x}=r(v),S=!y,C=u(i),w={hidden:S,orientation:d,tabActivationDirection:p,transitionStatus:b},T=X.useRef(null),E=H(`div`,e,{state:w,ref:[t,g,T],props:[{"aria-labelledby":C,hidden:S,id:h,role:`tabpanel`,tabIndex:v?0:-1,inert:A(!v),[ht]:_},c],stateAttributesMapping:gt});return B({open:v,ref:T,onComplete(){v||x(!1)}}),f(()=>{if(!(h==null||S&&!o))return m(i,h)},[S,o,i,h,m]),o||y?E:null});function vt(e){let{loopFocus:t=!0,orientation:n=`both`,grid:r,onLoop:i,direction:a,highlightedIndex:s,onHighlightedIndexChange:c,rootRef:l,enableHomeAndEndKeys:d=!1,stopEventPropagation:m,disabledIndices:_,modifierKeys:v=I}=e,[b,S]=X.useState(0),C=r!=null,T=X.useRef(null),E=De(T,l),D=X.useRef([]),O=X.useRef(!1),k=X.useRef(null),A=s??b,M=u((e,t=!1)=>{if(k.current=D.current[e]??null,(c??S)(e),t){let t=D.current[e];j(T.current,t,a,n)}}),N=u(e=>{if(e.size===0)return;if(O.current){let e=D.current,t=e.indexOf(k.current);if(t===-1){let t=e[A];!t||R(e,A,_)?M(yt(e,_)):k.current=t}else t!==A&&M(t);return}O.current=!0;let t=Array.from(e.keys()),r=t.find(e=>e?.hasAttribute(`data-composite-item-active`))??null,i=r?e.get(r)?.index??-1:-1;if(i!==-1)M(i);else if(R(t,A,_)){let e=ye(t,{disabledIndices:_});U(t,e)||M(e)}j(T.current,r,a,n)});f(()=>{if(_==null||s!=null||!O.current)return;let e=D.current;if(R(e,A,_)){let t=ye(e,{disabledIndices:_});U(e,t)||M(t)}},[_,s,A,D,M]);let ee=u((e,t,n)=>i?i(e,t,n,D):n),P=u(e=>{let s=e.key===`Home`||e.key===`End`;if(!y.has(e.key)||!d&&s||bt(e,v)||!T.current)return;let c=a===`rtl`,l=c?w:p,u=c?p:w,f=n===`vertical`?x:l,b=n===`vertical`?g:u,S=ne(e.nativeEvent);if(S!=null&&o(S)&&!h(S)){let t=S.selectionStart,n=S.selectionEnd,r=S.value;if(t==null||e.shiftKey||t!==n||e.key!==b&&t<r.length||e.key!==f&&t>0)return}let E=A,O=_e(D,_),k=fe(D,_);r!=null&&(E=r({disabledIndices:_,elementsRef:D,event:e,highlightedIndex:A,loopFocus:t,maxIndex:k,minIndex:O,onLoop:ee,orientation:n,rtl:c}));let j=n!==`vertical`&&e.key===l||n!==`horizontal`&&e.key===`ArrowDown`,N=n!==`vertical`&&e.key===u||n!==`horizontal`&&e.key===`ArrowUp`;d&&(e.key===`Home`?E=O:e.key===`End`&&(E=k)),E===A&&(j||N)&&(t&&E===k&&j?(E=O,i&&(E=i(e,A,E,D))):t&&E===O&&N?(E=k,i&&(E=i(e,A,E,D))):E=ye(D.current,{startingIndex:E,decrement:N,disabledIndices:_})),E!==A&&!U(D.current,E)&&(m&&e.stopPropagation(),(C||s||j||N)&&e.preventDefault(),M(E,!0),queueMicrotask(()=>{D.current[E]?.focus()}))});return{props:{ref:E,onFocus(e){let t=T.current,n=ne(e.nativeEvent);t&&n!=null&&o(n)&&n.setSelectionRange(0,n.value.length)},onKeyDown:P},highlightedIndex:A,onHighlightedIndexChange:M,elementsRef:D,onMapChange:N,relayKeyboardEvent:P}}function yt(e,t){let n=-1;for(let r=0;r<e.length;r+=1){let i=e[r];if(i&&!R(e,r,t)){if(i.hasAttribute(`data-composite-item-active`))return r;n===-1&&(n=r)}}return Math.max(n,0)}function bt(e,t){for(let n of Oe)if(!t.includes(n)&&e.getModifierState(n))return!0;return!1}function xt(e){let{render:t,className:n,style:r,refs:i=I,props:a=I,state:o=Se,stateAttributesMapping:s,highlightedIndex:c,onHighlightedIndexChange:l,orientation:u,grid:d,loopFocus:f,onLoop:p,enableHomeAndEndKeys:h,onMapChange:g,stopEventPropagation:_=!0,rootRef:v,disabledIndices:y,modifierKeys:x,highlightItemOnHover:S=!1,tag:C=`div`,...w}=e,{props:T,highlightedIndex:E,onHighlightedIndexChange:O,elementsRef:k,onMapChange:A,relayKeyboardEvent:j}=vt({grid:d,loopFocus:f,onLoop:p,orientation:u,highlightedIndex:c,onHighlightedIndexChange:l,rootRef:v,stopEventPropagation:_,enableHomeAndEndKeys:h,direction:b(),disabledIndices:y,modifierKeys:x}),M=H(C,e,{state:o,ref:i,props:[T,...a,w],stateAttributesMapping:s}),N=X.useMemo(()=>({highlightedIndex:E,onHighlightedIndexChange:O,highlightItemOnHover:S,relayKeyboardEvent:j}),[E,O,S,j]);return(0,Z.jsx)(D.Provider,{value:N,children:(0,Z.jsx)(m,{elementsRef:k,onMapChange:e=>{g?.(e),A(e)},children:M})})}var St=X.forwardRef(function(e,t){let{activateOnFocus:n=!1,className:r,loopFocus:i=!0,render:a,style:o,...s}=e,{orientation:c,setTabMap:l,tabActivationDirection:d}=it(),[p,m]=X.useState(0),[h,g]=X.useState(null),_=X.useRef(new Set),v=X.useRef(new Set),y=X.useRef(null);f(()=>{if(typeof ResizeObserver>`u`)return;let e=new ResizeObserver(()=>{_.current.forEach(e=>{e()})});return y.current=e,h&&e.observe(h),v.current.forEach(t=>{e.observe(t)}),()=>{e.disconnect(),y.current=null}},[h]);let b=u(e=>(_.current.add(e),()=>{_.current.delete(e)})),x=u(e=>(v.current.add(e),y.current?.observe(e),()=>{v.current.delete(e),y.current?.unobserve(e)})),S={orientation:c,tabActivationDirection:d},C={"aria-orientation":c===`vertical`?`vertical`:void 0,role:`tablist`},w=X.useMemo(()=>({activateOnFocus:n,registerIndicatorUpdateListener:b,registerTabResizeObserverElement:x,tabsListElement:h}),[n,b,x,h]);return(0,Z.jsx)(ft.Provider,{value:w,children:(0,Z.jsx)(xt,{render:a,className:r,style:o,state:S,refs:[t,g],props:[C,s],stateAttributesMapping:ot,highlightedIndex:p,enableHomeAndEndKeys:!0,loopFocus:i,orientation:c,onHighlightedIndexChange:m,onMapChange:l,disabledIndices:I})})}),Ct=n();function wt({className:e,orientation:t=`horizontal`,...n}){return(0,Z.jsx)(st,{"data-slot":`tabs`,"data-orientation":t,className:W(`group/tabs flex gap-2 data-horizontal:flex-col`,e),...n})}var Tt=ae(`group/tabs-list inline-flex w-fit items-center justify-center rounded-none p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none`,{variants:{variant:{default:`bg-muted`,line:`gap-1 bg-transparent`}},defaultVariants:{variant:`default`}});function Et({className:e,variant:t=`default`,...n}){return(0,Z.jsx)(St,{"data-slot":`tabs-list`,"data-variant":t,className:W(Tt({variant:t}),e),...n})}function Dt({className:e,...t}){return(0,Z.jsx)(mt,{"data-slot":`tabs-trigger`,className:W(`relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-none border border-transparent px-1.5 py-0.5 text-xs font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start group-data-vertical/tabs:py-[calc(--spacing(1.25))] hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4`,`group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent`,`data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground`,`after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100`,e),...t})}function Ot({className:e,...t}){return(0,Z.jsx)(_t,{"data-slot":`tabs-content`,className:W(`flex-1 text-xs/relaxed outline-none`,e),...t})}function kt(e){return H(e.defaultTagName??`div`,e,e)}var At=ae(`group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-none border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!`,{variants:{variant:{default:`bg-primary text-primary-foreground [a]:hover:bg-primary/80`,secondary:`bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80`,success:`border-emerald-600/20 bg-emerald-100/50 text-emerald-700 dark:border-emerald-400/20 dark:bg-emerald-900/50 dark:text-emerald-200`,warning:`border-amber-600/20 bg-amber-100/50 text-amber-700 dark:border-amber-400/20 dark:bg-amber-900/50 dark:text-amber-200`,info:`border-blue-600/20 bg-blue-100/50 text-blue-700 dark:border-blue-400/20 dark:bg-blue-900/50 dark:text-blue-200`,destructive:`bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20`,outline:`border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground`,ghost:`hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50`,link:`text-primary underline-offset-4 hover:underline`}},defaultVariants:{variant:`default`}});function jt({className:e,variant:t=`default`,render:n,...r}){return kt({defaultTagName:`span`,props:k({className:W(At({variant:t}),e)},r),render:n,state:{slot:`badge`,variant:t}})}var Mt=new Map([...[`ready`,`active`,`enabled`,`ok`,`completed`,`development`].map(e=>[e,`success`]),...[`pending`,`paused`,`activating`,`restoring`,`incomplete`,`required`].map(e=>[e,`warning`]),...[`uploading`,`running`,`queued`,`enqueued`,`production`,`public registration`,`public`].map(e=>[e,`info`]),...[`error`,`failed`,`blocked`,`unavailable`].map(e=>[e,`destructive`])]);function Q({status:e,children:t}){return(0,Z.jsx)(jt,{variant:Mt.get(e.toLowerCase())??`secondary`,children:t??e})}var Nt={query:`bg-yellow-100/50 text-yellow-700 dark:bg-yellow-900/50 dark:text-yellow-200`,mutation:`bg-blue-100/50 text-blue-700 dark:bg-blue-900/50 dark:text-blue-200`,action:`bg-purple-100/50 text-purple-700 dark:bg-purple-900/50 dark:text-purple-200`};function Pt({kind:e}){return(0,Z.jsx)(jt,{variant:`secondary`,className:Nt[e],children:e})}function Ft(e){let[t,n]=(0,X.useState)(!1);return(0,Z.jsxs)(`details`,{className:`rounded-lg border`,onToggle:e=>n(e.currentTarget.open),children:[(0,Z.jsx)(`summary`,{className:`cursor-pointer p-4 font-medium`,children:`Deployment history`}),t&&(0,Z.jsx)(`div`,{className:`p-4 pt-0`,children:(0,Z.jsx)(It,{...e})})]})}function It(e){let[t,n]=(0,X.useState)(),[r,i]=(0,X.useState)(),a=V(e.project,e.env),o=V(e.project,e.env),s=J(a+`/history`),c=e.session.role!==`viewer`,l=async(t,n)=>{let r=n?V(e.project,`prod`):o,a=await G(r+`/health`);i({title:n?`Promote backend to production`:`Rollback backend`,description:`Activate this exact backend hash after native schema/job validation. Data, files and settings stay unchanged. Frontend is not published by this button; use the CLI release flow for that.`,productionId:n||e.env===`prod`?e.project.id:void 0,submit:async()=>{await G(r+(n?`/release-promote`:`/release-rollback`),{hash:t,expected:a.active,confirm:e.project.id}),s.refresh(),e.refresh()}})},[u,d]=(0,X.useState)();return(0,Z.jsxs)(`div`,{className:`space-y-3`,children:[(0,Z.jsx)(q,{loading:s.loading,error:u||s.error}),(0,Z.jsxs)(F,{children:[(0,Z.jsx)(Te,{children:(0,Z.jsxs)(E,{children:[(0,Z.jsx)(z,{children:`First published`}),(0,Z.jsx)(z,{children:`Backend hash`}),(0,Z.jsx)(z,{children:`Actions`})]})}),(0,Z.jsx)(xe,{children:s.data?.map(t=>(0,Z.jsxs)(E,{children:[(0,Z.jsx)(Y,{children:new Date(t.at).toLocaleString()}),(0,Z.jsxs)(Y,{children:[(0,Z.jsx)(`code`,{className:`text-xs`,children:t.hash.slice(0,12)}),e.active===t.hash&&(0,Z.jsx)(Q,{status:`Active`})]}),(0,Z.jsx)(Y,{children:(0,Z.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,Z.jsx)(K,{variant:`outline`,size:`sm`,onClick:()=>n(t.hash),children:`View contracts`}),c&&e.active!==t.hash&&(0,Z.jsx)(K,{variant:`outline`,size:`sm`,onClick:()=>void l(t.hash,!1).catch(e=>d(e.message)),children:`Rollback backend`}),c&&e.env===`dev`&&(0,Z.jsx)(K,{variant:`outline`,size:`sm`,onClick:()=>void l(t.hash,!0).catch(e=>d(e.message)),children:`Promote backend`})]})})]},t.hash))})]}),t&&(0,Z.jsx)(Lt,{path:a,hash:t,close:()=>n(void 0)}),r&&(0,Z.jsx)(L,{modal:r,onClose:()=>i(void 0)})]})}function Lt({path:e,hash:t,close:n}){let r=J(e+`/release?hash=`+t);return(0,Z.jsx)(s,{open:!0,onOpenChange:e=>{e||n()},children:(0,Z.jsxs)(Ce,{className:`max-h-[80vh] overflow-auto`,children:[(0,Z.jsxs)(d,{children:[(0,Z.jsx)(l,{children:`Backend release`}),(0,Z.jsx)(O,{className:`break-all`,children:t})]}),(0,Z.jsx)(q,{...r}),r.data&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`h3`,{className:`font-medium`,children:`Tables`}),(0,Z.jsxs)(F,{children:[(0,Z.jsx)(Te,{children:(0,Z.jsxs)(E,{children:[(0,Z.jsx)(z,{children:`Table`}),(0,Z.jsx)(z,{children:`Fields`})]})}),(0,Z.jsx)(xe,{children:Object.entries(r.data.schema).map(([e,t])=>(0,Z.jsxs)(E,{children:[(0,Z.jsx)(Y,{children:e}),(0,Z.jsx)(Y,{children:Object.keys(t.document.properties??{}).join(`, `)||`No declared fields`})]},e))})]}),(0,Z.jsx)(`h3`,{className:`font-medium`,children:`Functions`}),(0,Z.jsxs)(F,{children:[(0,Z.jsx)(Te,{children:(0,Z.jsxs)(E,{children:[(0,Z.jsx)(z,{children:`Function`}),(0,Z.jsx)(z,{children:`Kind`}),(0,Z.jsx)(z,{children:`Access`})]})}),(0,Z.jsx)(xe,{children:Object.entries(r.data.manifest.functions).map(([e,t])=>(0,Z.jsxs)(E,{children:[(0,Z.jsx)(Y,{children:e}),(0,Z.jsx)(Y,{children:(0,Z.jsx)(Pt,{kind:t.kind})}),(0,Z.jsx)(Y,{children:(0,Z.jsx)(Q,{status:t.auth})})]},e))})]})]})]})})}function Rt({className:e,size:t=`default`,...n}){return(0,Z.jsx)(`div`,{"data-slot":`card`,"data-size":t,className:W(`group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-none bg-card py-(--card-spacing) text-xs/relaxed text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-none *:[img:last-child]:rounded-none`,e),...n})}function zt({className:e,...t}){return(0,Z.jsx)(`div`,{"data-slot":`card-header`,className:W(`group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-none px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)`,e),...t})}function Bt({className:e,...t}){return(0,Z.jsx)(`div`,{"data-slot":`card-title`,className:W(`font-heading text-sm font-medium group-data-[size=sm]/card:text-sm`,e),...t})}function Vt({className:e,...t}){return(0,Z.jsx)(`div`,{"data-slot":`card-content`,className:W(`px-(--card-spacing)`,e),...t})}function Ht({project:e,env:t,session:n,connect:r}){let i=J(V(e,t)+`/health`),a=J(V(e,t)+`/settings`);return(0,Z.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,Z.jsx)(`h1`,{className:`page-title`,children:`Health`}),(0,Z.jsx)(q,{loading:i.loading||a.loading,error:i.error||a.error}),i.data&&a.data&&(0,Z.jsxs)(Z.Fragment,{children:[(0,Z.jsx)(`h2`,{className:`section-title`,children:`Summary`}),(0,Z.jsx)(Rt,{children:(0,Z.jsxs)(Vt,{className:`grid gap-4 md:grid-cols-2`,children:[(0,Z.jsxs)(`div`,{className:`space-y-3`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,Z.jsx)(Q,{status:t===`dev`?`Development`:`Production`}),(0,Z.jsx)(`strong`,{children:e.name})]}),(0,Z.jsx)(`p`,{className:`text-muted-foreground`,children:`Cloudflare · Durable Objects · SQLite`}),(0,Z.jsxs)(`p`,{className:`font-mono text-xs text-muted-foreground`,children:[`Release `,i.data.active?.slice(0,12)??`not deployed`]})]}),(0,Z.jsxs)(`div`,{className:`space-y-2`,children:[(0,Z.jsx)(`p`,{className:`text-muted-foreground`,children:`Cloud URL`}),(0,Z.jsx)(`code`,{className:`block select-all break-all text-xs`,children:a.data.url}),(0,Z.jsxs)(`div`,{className:`flex items-center gap-2 text-muted-foreground`,children:[(0,Z.jsx)(Q,{status:i.data.status}),i.data.connections,` connections · `,i.data.subscriptions,` `,`subscriptions`]})]})]})}),(0,Z.jsx)(Ft,{project:e,env:t,session:n,active:i.data.active,refresh:i.refresh}),(0,Z.jsx)(K,{variant:`outline`,onClick:r,children:`Connect SDK`})]})]})}function Ut({project:e,env:t}){let n=J(V(e,t)+`/schema`);return(0,Z.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,Z.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:[(0,Z.jsx)(`h1`,{className:`page-title`,children:`Schema`}),(0,Z.jsx)(`div`,{className:`flex gap-2`,children:(0,Z.jsx)(K,{variant:`ghost`,size:`icon-sm`,"aria-label":`Reload snapshot`,title:`Reload snapshot`,onClick:n.refresh,disabled:n.loading,children:(0,Z.jsx)(Je,{})})})]}),(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Defined in code; validated documents and indexes activate atomically. System tables are hidden.`}),(0,Z.jsx)(q,{...n}),n.data?.tables.map(e=>(0,Z.jsxs)(Rt,{children:[(0,Z.jsx)(zt,{children:(0,Z.jsx)(`div`,{className:`flex flex-wrap items-center justify-between gap-2`,children:(0,Z.jsx)(Bt,{className:`font-mono`,children:e.name})})}),(0,Z.jsxs)(Vt,{className:`space-y-4`,children:[(0,Z.jsx)(pe,{rows:e.columns.map(e=>({Field:e.name,Type:e.type,Required:!!e.notnull,Primary:!!e.pk,Default:e.dflt_value})),columns:[`Field`,`Type`,`Required`,`Primary`,`Default`]}),(0,Z.jsx)(pe,{rows:Object.entries(e.indexes).map(([e,t])=>({Index:e,Fields:t.join(`, `)})),columns:[`Index`,`Fields`]}),(0,Z.jsxs)(`details`,{children:[(0,Z.jsx)(`summary`,{className:`cursor-pointer text-muted-foreground`,children:`Document contract`}),(0,Z.jsx)(`pre`,{className:`code-block mt-3`,children:JSON.stringify(e.document,null,2)})]})]})]},e.name)),n.data&&!n.data.tables.length&&(0,Z.jsx)(de,{title:`No application tables`})]})}function Wt({project:e,env:t}){let n=J(V(e,t)+`/logs`);return(0,Z.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,Z.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,Z.jsx)(`h1`,{className:`page-title`,children:`Logs`}),(0,Z.jsx)(K,{variant:`ghost`,size:`icon-sm`,"aria-label":`Reload snapshot`,title:`Reload snapshot`,onClick:n.refresh,disabled:n.loading,children:(0,Z.jsx)(Je,{})})]}),(0,Z.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Last 100 invocation summaries. Successful queries are held in memory and disappear on hibernation/restart; writes and failures are persisted. Not Cloudflare Tail logs or billing analytics.`}),(0,Z.jsx)(q,{...n}),n.data&&(n.data.length?(0,Z.jsx)(pe,{rows:n.data,renderCell:(e,t)=>e===`kind`&&[`query`,`mutation`,`action`].includes(String(t))?(0,Z.jsx)(Pt,{kind:t}):e===`status`?(0,Z.jsx)(Q,{status:t===`ok`?`ok`:`error`,children:ie(t)}):e===`at`&&typeof t==`number`?new Date(t).toLocaleString():ie(t),columns:[`at`,`path`,`kind`,`status`,`ms`],labels:{at:`Time`,path:`Function`,kind:`Type`,status:`Status`,ms:`Duration (ms)`}}):(0,Z.jsx)(de,{title:`No recent function calls`}))]})}var Gt=(function(){let e=typeof document<`u`&&document.createElement(`link`).relList;return e&&e.supports&&e.supports(`modulepreload`)?`modulepreload`:`preload`})(),Kt=function(e){return`/`+e},qt={},Jt=function(e){return e.pathname.endsWith(`.css`)},Yt=function(e,t,n){if(t in e)return e[t];let r=n();if(!r){e[t]=void 0;return}let i=r.then(()=>{e[t]=void 0},n=>{throw e[t]=void 0,n});return e[t]=i,i},$=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=function(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))},i=function(e){return import.meta.resolve?new URL(import.meta.resolve(e)):new URL(e,import.meta.url)},a,o=document.querySelector(`meta[property=csp-nonce]`),s=o?.nonce||o?.getAttribute(`nonce`);r=e(t.map(e=>{e=Kt(e,n);let t=i(e),r=Jt(t);return Yt(qt,t.href,()=>{if(a===void 0){a={all:new Set,styles:new Set};let e=document.getElementsByTagName(`link`);for(let t=e.length-1;t>=0;t--){let n=e[t];a.all.add(n.href),n.rel===`stylesheet`&&a.styles.add(n.href)}}if((r?a.styles:a.all).has(t.href))return;let e=document.createElement(`link`);if(e.rel=r?`stylesheet`:Gt,r||(e.as=`script`),e.crossOrigin=``,e.href=t.href,s&&e.setAttribute(`nonce`,s),document.head.appendChild(e),r)return new Promise((n,r)=>{e.addEventListener(`load`,n),e.addEventListener(`error`,()=>r(Error(`Unable to preload CSS for ${t}`)))})})}).filter(e=>e!==void 0))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},Xt=(0,X.lazy)(()=>$(()=>import(`./services-view.Dx1rjMWa.js`).then(e=>({default:e.FilesView})),__vite__mapDeps([0,1,2,3]))),Zt=(0,X.lazy)(()=>$(()=>import(`./services-view.Dx1rjMWa.js`).then(e=>({default:e.SchedulesView})),__vite__mapDeps([0,1,2,3]))),Qt=(0,X.lazy)(()=>$(()=>import(`./data-view.BFL2F3o9.js`),__vite__mapDeps([4,1,2,5]))),$t=(0,X.lazy)(()=>$(()=>import(`./functions-view.vsmqlnUa.js`),__vite__mapDeps([6,1,2,3,5]))),en=(0,X.lazy)(()=>$(()=>import(`./ai-view.DcYKk5W_.js`),__vite__mapDeps([7,1,2,3]))),tn=(0,X.lazy)(()=>$(()=>import(`./auth-view.KnVtTZYn.js`),__vite__mapDeps([8,1,2]))),nn=(0,X.lazy)(()=>$(()=>import(`./settings-view.DPwEyqzv.js`),__vite__mapDeps([9,1,2]))),rn=(0,X.lazy)(()=>$(()=>import(`./sdk-view.BPVWrAC3.js`),__vite__mapDeps([10,1,2]))),an=[{key:`health`,label:`Health`,icon:Ae},{key:`data`,label:`Data`,icon:Ie},{key:`schema`,label:`Schema`,icon:Me},{key:`functions`,label:`Functions`,icon:Pe},{key:`files`,label:`Files`,icon:Re},{key:`schedules`,label:`Schedules`,icon:nt},{key:`ai`,label:`AI`,icon:Xe},{key:`auth`,label:`Auth`,icon:et},{key:`logs`,label:`Logs`,icon:Be}],on=(0,X.lazy)(()=>$(()=>import(`./cli-approval.emPTVRqn.js`),__vite__mapDeps([11,1,2])));function sn(){return new URLSearchParams(location.search).has(`cli`)?(0,Z.jsx)(X.Suspense,{fallback:(0,Z.jsx)(`p`,{children:`Loading…`}),children:(0,Z.jsx)(on,{})}):(0,Z.jsx)(cn,{})}function cn(){let[e,t]=(0,X.useState)(),[n,r]=(0,X.useState)([]),[a,o]=(0,X.useState)(),[s,c]=(0,X.useState)(`dev`),[l,u]=(0,X.useState)(`health`),[d,f]=(0,X.useState)(``),[p,m]=(0,X.useState)(!0),[h,g]=(0,X.useState)(),[_,v]=(0,X.useState)(!1);(0,X.useEffect)(()=>{let e=new AbortController;return v(localStorage.getItem(`flare.sidebar`)===`collapsed`),Promise.all([G(`session`,void 0,e.signal),G(`projects`,void 0,e.signal)]).then(([n,i])=>{e.signal.aborted||(t(n),r(i),o(i.find(e=>e.id===localStorage.getItem(`flare.project`))??i[0]),m(!1))}).catch(t=>{e.signal.aborted||(f(ue(t)),m(!1))}),()=>e.abort()},[]);let y=e=>{let t=n.find(t=>t.id===e);t&&(o(t),c(`dev`),u(`health`),g(void 0),localStorage.setItem(`flare.project`,e))},b=()=>g({title:`Create project`,description:`Creates separate development and production environments.`,content:(0,Z.jsxs)(se,{children:[(0,Z.jsxs)(S,{children:[(0,Z.jsx)(i,{htmlFor:`project-name`,children:`Project name`}),(0,Z.jsx)(he,{id:`project-name`,name:`name`,required:!0,maxLength:100,placeholder:`CRM`})]}),(0,Z.jsxs)(S,{children:[(0,Z.jsx)(i,{htmlFor:`project-alias`,children:`Short URL name (optional)`}),(0,Z.jsx)(he,{id:`project-alias`,name:`alias`,maxLength:48,pattern:`[a-z][a-z0-9]*(?:-[a-z0-9]+)*`,placeholder:`crm`})]}),(0,Z.jsxs)(S,{children:[(0,Z.jsx)(i,{htmlFor:`project-origins`,children:`Allowed frontend origins · one per line`}),(0,Z.jsx)(oe,{id:`project-origins`,name:`origins`,placeholder:`http://127.0.0.1:5173`})]})]}),submit:async e=>{let t=new FormData(e),n=await G(`projects`,{name:t.get(`name`),alias:t.get(`alias`)||void 0,origins:[location.origin,...String(t.get(`origins`)).split(`
|
|
3
3
|
`).map(e=>e.trim()).filter(Boolean)]}),i=await G(`projects`);r(i),o(i.find(e=>e.id===n.id)??i[0]),c(`dev`),u(`health`)}}),x=a&&e?{project:a,env:s,session:e}:null,C=()=>{let e=n.filter(e=>e.id!==a?.id);r(e),o(e[0]),c(`dev`),u(`health`),e[0]?localStorage.setItem(`flare.project`,e[0].id):localStorage.removeItem(`flare.project`)},w=e=>{g(void 0),u(e)};return(0,Z.jsxs)(`div`,{className:`flex h-dvh min-h-0 flex-col overflow-hidden text-sm`,children:[(0,Z.jsxs)(`header`,{className:`flex h-14 shrink-0 items-center justify-between gap-3 border-b bg-sidebar px-4`,children:[(0,Z.jsxs)(`div`,{className:`flex min-w-0 items-center gap-3`,children:[(0,Z.jsx)(ve,{label:`Select project`,value:a?.id??``,onChange:y,items:n.map(e=>({value:e.id,label:e.name})),className:`max-w-48`}),x&&(0,Z.jsx)(wt,{value:s,onValueChange:e=>{(e===`dev`||e===`prod`)&&(c(e),g(void 0))},"aria-label":`Select environment`,children:(0,Z.jsxs)(Et,{children:[(0,Z.jsx)(Dt,{value:`dev`,children:`Dev`}),(0,Z.jsx)(Dt,{value:`prod`,children:`Production`})]})})]}),(0,Z.jsxs)(`div`,{className:`flex items-center gap-2`,children:[e?.role!==`viewer`&&e&&(0,Z.jsx)(K,{"aria-label":`Create project`,size:`icon-sm`,variant:`ghost`,onClick:b,children:(0,Z.jsx)(Ke,{})}),x&&(0,Z.jsx)(K,{"aria-label":`Project settings`,size:`icon-sm`,variant:`ghost`,onClick:()=>w(`settings`),children:(0,Z.jsx)(Qe,{})}),e&&(0,Z.jsx)(`span`,{className:`flex size-7 items-center justify-center rounded-full bg-muted text-xs font-medium`,title:e.email,"aria-label":`Signed in as ${e.email}`,children:e.email.slice(0,2).toUpperCase()})]})]}),(0,Z.jsxs)(`div`,{className:`flex min-h-0 flex-1`,children:[(0,Z.jsxs)(`aside`,{className:`flex shrink-0 flex-col border-r bg-sidebar px-2 py-3 ${_?`w-12`:`w-36`}`,children:[(0,Z.jsx)(`nav`,{"aria-label":`Deployment`,className:`flex flex-col gap-1`,children:an.map(({key:e,label:t,icon:n})=>(0,Z.jsxs)(K,{variant:`ghost`,disabled:!x,"aria-current":l===e?`page`:void 0,title:_?t:void 0,"aria-label":_?t:void 0,className:`w-full justify-start ${l===e?`bg-sidebar-accent text-sidebar-accent-foreground`:`text-muted-foreground`}`,onClick:()=>w(e),children:[(0,Z.jsx)(n,{className:`size-4`}),!_&&t]},e))}),(0,Z.jsxs)(K,{"aria-label":_?`Expand sidebar`:`Collapse sidebar`,className:`mt-auto justify-start text-muted-foreground`,variant:`ghost`,onClick:()=>v(e=>(localStorage.setItem(`flare.sidebar`,e?`expanded`:`collapsed`),!e)),children:[_?(0,Z.jsx)(We,{}):(0,Z.jsx)(He,{}),!_&&`Collapse`]})]}),(0,Z.jsxs)(`main`,{className:`min-h-0 min-w-0 flex-1 ${l===`data`?`overflow-hidden`:`overflow-auto`}`,"aria-label":`Deployment content`,children:[d&&(0,Z.jsx)(`div`,{className:`p-4`,children:(0,Z.jsx)(ge,{children:d})}),p?(0,Z.jsx)(q,{loading:!0}):x?(0,Z.jsx)(ce,{scope:`projects/${a.id}/${s}`,children:(0,Z.jsx)(X.Suspense,{fallback:(0,Z.jsx)(q,{loading:!0}),children:(0,Z.jsx)(`div`,{className:l===`data`?`h-full min-h-0`:`min-h-full`,children:l===`health`?(0,Z.jsx)(Ht,{...x,connect:()=>w(`sdk`)}):l===`data`?(0,Z.jsx)(Qt,{...x}):l===`schema`?(0,Z.jsx)(Ut,{...x}):l===`functions`?(0,Z.jsx)($t,{...x}):l===`files`?(0,Z.jsx)(Xt,{...x}):l===`schedules`?(0,Z.jsx)(Zt,{...x}):l===`ai`?(0,Z.jsx)(en,{...x}):l===`auth`?(0,Z.jsx)(tn,{...x}):l===`logs`?(0,Z.jsx)(Wt,{...x}):l===`settings`?(0,Z.jsx)(nn,{...x,onDeleted:C}):(0,Z.jsx)(rn,{...x})},`${a.id}/${s}/${l}`)})},`${a.id}/${s}`):d?null:(0,Z.jsxs)(`div`,{className:`p-4`,children:[(0,Z.jsx)(`h1`,{className:`page-title`,children:`Select a project`}),(0,Z.jsx)(`p`,{className:`mt-2 text-muted-foreground`,children:`Create a project to get started.`}),e?.role!==`viewer`&&(0,Z.jsxs)(K,{className:`mt-4`,onClick:b,children:[(0,Z.jsx)(Ke,{}),`New project`]})]})]})]}),h&&(0,Z.jsx)(L,{modal:h,onClose:()=>g(void 0)})]})}var ln=document.getElementById(`flare-dashboard`);if(!ln)throw Error(`Dashboard mount missing`);(0,Ct.createRoot)(ln).render((0,X.createElement)(sn));export{Pt as a,wt as c,Dt as d,Xe as f,Pe as g,Ie as h,Bt as i,Ot as l,Ke as m,Vt as n,Q as o,Je as p,zt as r,jt as s,Rt as t,Et as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,r as t}from"./client.BeKNsjPN.js";import{At as n,Ot as r,g as i,m as a,p as o,pt as s,r as c,s as l,u}from"./common.9pujiaSZ.js";import{i as d,n as f,r as p,t as m}from"./index.astro_astro_type_script_index_0_lang.
|
|
1
|
+
import{a as e,r as t}from"./client.BeKNsjPN.js";import{At as n,Ot as r,g as i,m as a,p as o,pt as s,r as c,s as l,u}from"./common.9pujiaSZ.js";import{i as d,n as f,r as p,t as m}from"./index.astro_astro_type_script_index_0_lang.DBs-yURk.js";var h={name:`key-round`,size:24,node:[[`path`,{d:`M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z`,key:`1s6t7t`}],[`circle`,{cx:`16.5`,cy:`7.5`,r:`.5`,fill:`currentColor`,key:`w0ekpg`}]]};h.node;var g=r(h),_=e(t(),1),v=n();function y({project:e,env:t,session:n}){let r=i(e,t),h=u(r+`/settings`),[y,b]=(0,_.useState)(),[x,S]=(0,_.useState)(``),[C,w]=(0,_.useState)(!1),T=(0,_.useRef)(void 0);(0,_.useEffect)(()=>()=>T.current?.abort(),[]);let E=async()=>{if(C||t!==`dev`||n.role===`viewer`)return;let e=new AbortController;T.current=e,w(!0),S(``),b(void 0);try{let t=await o(r+`/dev-token`,{},e.signal);e.signal.aborted||b(t)}catch(t){e.signal.aborted||S(a(t))}finally{e.signal.aborted||w(!1)}};return(0,v.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,v.jsx)(`h1`,{className:`page-title`,children:`SDK · Live`}),(0,v.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`One environment URL for browser, server and mobile clients. Use the generated API references from your application build.`}),(0,v.jsx)(l,{...h}),h.data&&(0,v.jsxs)(m,{children:[(0,v.jsx)(p,{children:(0,v.jsx)(d,{children:`Connect your application`})}),(0,v.jsxs)(f,{className:`space-y-4`,children:[(0,v.jsx)(`pre`,{className:`code-block`,children:`import { createClient } from '@auersperg/flare';\nimport { api } from './flare/_generated/api';\n\nconst client = createClient({\n url: '${h.data.url}',\n getToken: () => yourUserAccessToken,\n});\n\n// Use your generated query / mutation / action references.\n// Example: replace this path with your own query:\nconst stop = client.onUpdate(api.tasks.list, { limit: 50 },\n tasks => console.log(tasks));\n\n// On logout: client.refreshAuth().\n// On teardown: stop(); client.dispose();`}),(0,v.jsx)(`p`,{className:`text-muted-foreground`,children:`The task function is an illustrative name, not a requirement for other projects. Run your app locally to test live updates; this page opens no background subscription and does not write application data.`})]})]}),(0,v.jsxs)(m,{children:[(0,v.jsx)(p,{children:(0,v.jsx)(d,{children:t===`dev`?`Local developer session`:`Production authentication`})}),(0,v.jsxs)(f,{className:`space-y-4`,children:[(0,v.jsx)(`p`,{className:`text-muted-foreground`,children:t===`dev`?`A 15-minute identity for this project's development environment. Keep it in a git-ignored local file, never in a bundle or commit. Request a new token after expiry.`:`Use enabled built-in password authentication or a configured OIDC provider. Developer identities cannot access production; application handlers enforce record permissions.`}),t===`dev`&&n.role!==`viewer`&&(0,v.jsxs)(s,{variant:`outline`,onClick:E,disabled:C,children:[(0,v.jsx)(g,{}),C?`Requesting…`:`Get developer session`]}),x&&(0,v.jsx)(c,{children:x}),y&&(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(`pre`,{className:`code-block`,children:JSON.stringify(y,null,2)}),(0,v.jsx)(s,{variant:`ghost`,onClick:()=>b(void 0),children:`Clear from view`})]})]})]})]})}export{y as default};
|
package/dist/platform/dashboard/_astro/{services-view.B7BR4JD3.js → services-view.Dx1rjMWa.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,r as t}from"./client.BeKNsjPN.js";import{At as n,Ot as r,S as i,_ as a,b as o,g as s,h as c,m as l,n as u,o as d,p as f,pt as p,q as m,s as h,u as g,v as _,x as v,y}from"./common.9pujiaSZ.js";import{c as b,d as x,l as S,o as C,p as w,u as T}from"./index.astro_astro_type_script_index_0_lang.
|
|
1
|
+
import{a as e,r as t}from"./client.BeKNsjPN.js";import{At as n,Ot as r,S as i,_ as a,b as o,g as s,h as c,m as l,n as u,o as d,p as f,pt as p,q as m,s as h,u as g,v as _,x as v,y}from"./common.9pujiaSZ.js";import{c as b,d as x,l as S,o as C,p as w,u as T}from"./index.astro_astro_type_script_index_0_lang.DBs-yURk.js";import{n as E,r as D}from"./client.BSf433s6.js";var O={name:`download`,size:24,node:[[`path`,{d:`M12 15V3`,key:`m9g1x1`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}],[`path`,{d:`m7 10 5 5 5-5`,key:`brsn70`}]]};O.node;var k=r(O),A={name:`trash`,size:24,node:[[`path`,{d:`M10 11v6`,key:`nco0om`}],[`path`,{d:`M14 11v6`,key:`outv1u`}],[`path`,{d:`M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6`,key:`miytrc`}],[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2`,key:`e791ji`}]],aliases:[`trash-2`]};A.node;var j=r(A),M=e(t(),1),N=n();function P({project:e,env:t,session:n}){let[r,c]=(0,M.useState)([null]),d=r.at(-1),b=s(e,t),x=g(b+`/files`+(d?`?cursor=`+encodeURIComponent(d):``)),S=(0,M.useRef)(null),[T,O]=(0,M.useState)(!1),[A,P]=(0,M.useState)(!1),[F,I]=(0,M.useState)(``),[L,R]=(0,M.useState)(``),z=n.role!==`viewer`;async function B(){let n=S.current?.files?.[0];if(!n)return;O(!0),I(``),R(``);let r=!1;try{let i=E(n);if(t===`prod`&&!confirm(`Upload to production ${e.name}?`))return;R(`Preparing upload…`),r=!0;let a=await f(b+`/file-upload`,{...i,...t===`prod`?{confirm:e.id}:{}});R(`Uploading ${n.name}…`),await D(a,n),S.current&&(S.current.value=``),P(!1),R(`Upload complete`)}catch(e){R(``),I(l(e)+(r?`. Check the refreshed list before retrying. Incomplete uploads expire automatically; they are not queue jobs.`:``))}finally{O(!1),r&&x.refresh()}}async function V(e){I(``);try{let t=await f(b+`/file-download?id=`+encodeURIComponent(e)),n=document.createElement(`a`);n.href=t.url,n.rel=`noreferrer`,n.click()}catch(e){I(l(e))}}async function H(n){if(confirm(`Permanently delete this ${t} file?`)){O(!0),I(``);try{await f(b+`/file-delete`,{id:n,...t===`prod`?{confirm:e.id}:{}}),x.refresh()}catch(e){I(l(e))}finally{O(!1)}}}return(0,N.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,N.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,N.jsx)(`h1`,{className:`page-title`,children:`Files`}),(0,N.jsx)(p,{variant:`ghost`,size:`icon-sm`,"aria-label":`Reload snapshot`,title:`Reload snapshot`,onClick:x.refresh,disabled:x.loading,children:(0,N.jsx)(w,{})})]}),(0,N.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Private R2 storage · streaming uploads · maximum 10 MiB · download links expire after 5 minutes. 50 files per page.`}),(0,N.jsx)(h,{loading:x.loading,error:F||x.error}),L&&(0,N.jsx)(`p`,{role:`status`,className:`text-xs text-muted-foreground`,children:L}),z&&(0,N.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[(0,N.jsx)(m,{ref:S,type:`file`,className:`max-w-sm`,disabled:T,"aria-label":`Choose file to upload`,onChange:e=>P(!!e.target.files?.length)}),(0,N.jsx)(p,{onClick:B,disabled:T||!A,children:`Upload file`})]}),x.data?.page.length?(0,N.jsxs)(a,{children:[(0,N.jsx)(v,{children:(0,N.jsx)(i,{children:[`Name`,`Type`,`Size`,`State`,`Created`,`Actions`].map(e=>(0,N.jsx)(o,{children:e},e))})}),(0,N.jsx)(_,{children:x.data.page.map(e=>(0,N.jsxs)(i,{children:[(0,N.jsx)(y,{children:e.name}),(0,N.jsx)(y,{children:e.type}),(0,N.jsx)(y,{children:e.size>=1048576?`${(e.size/1048576).toFixed(1)} MiB`:e.size<1024?`${e.size} B`:`${(e.size/1024).toFixed(1)} KiB`}),(0,N.jsx)(y,{children:(0,N.jsx)(C,{status:e.state,children:e.state===`pending`?`Awaiting upload`:e.state===`uploading`?`Uploading / recovering`:e.state})}),(0,N.jsx)(y,{children:new Date(e.createdAt).toLocaleString()}),(0,N.jsx)(y,{children:(0,N.jsxs)(`div`,{className:`flex gap-2`,children:[(0,N.jsx)(p,{size:`icon`,variant:`outline`,"aria-label":`Download ${e.name}`,disabled:e.state!==`ready`||T,onClick:()=>void V(e.id),children:(0,N.jsx)(k,{})}),z&&(0,N.jsx)(p,{size:`icon`,variant:`outline`,"aria-label":`Delete ${e.name}`,disabled:T,onClick:()=>void H(e.id),children:(0,N.jsx)(j,{})})]})})]},e.id))})]}):x.data&&(0,N.jsx)(u,{title:`No stored files`}),x.data&&(0,N.jsxs)(`div`,{className:`flex items-center justify-between gap-2`,children:[(0,N.jsxs)(`p`,{className:`text-xs text-muted-foreground`,children:[`Page `,r.length,` · `,x.data.page.length,` files`]}),(0,N.jsxs)(`div`,{className:`flex gap-2`,children:[(0,N.jsx)(p,{variant:`outline`,disabled:x.loading||r.length===1,onClick:()=>c(e=>e.slice(0,-1)),children:`Previous`}),(0,N.jsx)(p,{variant:`outline`,disabled:x.loading||x.data.isDone,onClick:()=>{x.data?.continueCursor&&c(e=>[...e,x.data.continueCursor])},children:`Next`})]})]})]})}function F({project:e,env:t,session:n}){let r=s(e,t),m=g(r+`/jobs`),[E,D]=(0,M.useState)(``);async function O(n){if(t!==`prod`||confirm(`Pause production cron ${n}?`))try{await f(r+`/cron-cancel`,{name:n,...t===`prod`?{confirm:e.id}:{}}),m.refresh()}catch(e){D(l(e))}}async function k(n){if(t!==`prod`||confirm(`Cancel this pending production job?`)){D(``);try{(await f(r+`/job-cancel`,{id:n,...t===`prod`?{confirm:e.id}:{}})).cancelled||D(`This job is already enqueued; it cannot be cancelled here.`)}catch(e){D(l(e))}finally{m.refresh()}}}return(0,N.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,N.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,N.jsx)(`h1`,{className:`page-title`,children:`Schedules`}),(0,N.jsx)(p,{variant:`ghost`,size:`icon-sm`,"aria-label":`Reload snapshot`,title:`Reload snapshot`,onClick:m.refresh,disabled:m.loading,children:(0,N.jsx)(w,{})})]}),(0,N.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Durable scheduling → transactional outbox → Cloudflare Queues. At-least-once delivery; handlers must be idempotent. Times use UTC.`}),(0,N.jsx)(h,{loading:m.loading,error:m.error||E}),(0,N.jsxs)(b,{defaultValue:`scheduled`,children:[(0,N.jsxs)(T,{variant:`line`,children:[(0,N.jsx)(x,{value:`scheduled`,children:`Scheduled Functions`}),(0,N.jsx)(x,{value:`cron`,children:`Cron Jobs`})]}),(0,N.jsxs)(S,{value:`scheduled`,className:`space-y-4 pt-4`,children:[(0,N.jsx)(`h2`,{className:`section-title`,children:`Waiting to enqueue`}),m.data&&(m.data.pending.length?(0,N.jsxs)(a,{children:[(0,N.jsx)(v,{children:(0,N.jsx)(i,{children:[`Function`,`Due (UTC)`,`Job ID`,``].map((e,t)=>(0,N.jsx)(o,{children:e},t))})}),(0,N.jsx)(_,{children:m.data.pending.map(e=>(0,N.jsxs)(i,{children:[(0,N.jsx)(y,{className:`font-mono`,children:String(e.path)}),(0,N.jsx)(y,{children:new Date(Number(e.dueAt)).toISOString()}),(0,N.jsx)(y,{className:`font-mono`,children:String(e.id)}),(0,N.jsx)(y,{children:n.role!==`viewer`&&(0,N.jsx)(p,{variant:`outline`,disabled:m.loading,onClick:()=>void k(String(e.id)),children:`Cancel`})})]},String(e.id)))})]}):(0,N.jsx)(u,{title:`No delayed jobs`})),(0,N.jsx)(`h2`,{className:`section-title`,children:`Recent queue deliveries`}),m.data&&(m.data.recent.length?(0,N.jsx)(d,{rows:m.data.recent,columns:[`id`,`path`,`state`,`attempts`,`error`,`at`],renderCell:(e,t)=>e===`state`?(0,N.jsx)(C,{status:String(t)}):e===`at`&&typeof t==`number`?new Date(t).toLocaleString():c(t)}):(0,N.jsx)(u,{title:`No queue deliveries yet`}))]}),(0,N.jsxs)(S,{value:`cron`,className:`space-y-4 pt-4`,children:[m.data?.crons.length?(0,N.jsxs)(a,{children:[(0,N.jsx)(v,{children:(0,N.jsx)(i,{children:[`Name`,`Function`,`Cron (UTC)`,`State`,``].map((e,t)=>(0,N.jsx)(o,{children:e},t))})}),(0,N.jsx)(_,{children:m.data.crons.map(e=>(0,N.jsxs)(i,{children:[(0,N.jsx)(y,{children:e.name}),(0,N.jsx)(y,{className:`font-mono`,children:e.path}),(0,N.jsx)(y,{className:`font-mono`,children:e.cron}),(0,N.jsx)(y,{children:(0,N.jsx)(C,{status:e.enabled?`Enabled`:`Paused`})}),(0,N.jsx)(y,{children:n.role!==`viewer`&&e.enabled&&(0,N.jsx)(p,{variant:`outline`,onClick:()=>void O(e.name),children:`Pause`})})]},e.name))})]}):m.data&&(0,N.jsx)(u,{title:`No cron jobs`}),(0,N.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Define schedules through an application action using ctx.schedules.set(). Five-field cron expressions, minimum one minute, maximum 20 per environment. No permanent frontend timers.`})]})]})]})}export{P as FilesView,F as SchedulesView};
|
package/dist/platform/dashboard/_astro/{settings-view.DM-igZ4O.js → settings-view.DPwEyqzv.js}
RENAMED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{a as e,r as t}from"./client.BeKNsjPN.js";import{A as n,At as r,O as i,S as a,_ as o,a as s,b as c,g as l,j as u,k as d,m as f,p,pt as m,q as h,r as g,s as _,u as v,v as y,x as b,y as x}from"./common.9pujiaSZ.js";import{i as S,n as C,o as w,r as T,t as E}from"./index.astro_astro_type_script_index_0_lang.
|
|
1
|
+
import{a as e,r as t}from"./client.BeKNsjPN.js";import{A as n,At as r,O as i,S as a,_ as o,a as s,b as c,g as l,j as u,k as d,m as f,p,pt as m,q as h,r as g,s as _,u as v,v as y,x as b,y as x}from"./common.9pujiaSZ.js";import{i as S,n as C,o as w,r as T,t as E}from"./index.astro_astro_type_script_index_0_lang.DBs-yURk.js";var D=e(t(),1),O=r();function k(e){return(0,O.jsxs)(`div`,{className:`space-y-3 p-4 pt-0`,children:[(0,O.jsx)(`p`,{className:`text-muted-foreground`,children:`On-demand data, user accounts, files and backend code snapshots. Restore only into an empty environment. Sessions, secrets and schedules are not copied. No background polling.`}),(0,O.jsx)(A,{...e})]})}function A(e){let[t,n]=(0,D.useState)(e.env),[r,i]=(0,D.useState)(null),[u,d]=(0,D.useState)(),f=l(e.project,t),h=l(e.project,e.env),g=v(f+`/backups`+(r?`?cursor=${encodeURIComponent(r)}`:``)),S=v(h+`/backup-status`),C=e.session.role===`owner`,T=(t,n,r,i)=>d({title:t,description:n,productionId:e.project.id,submit:async()=>{await p(r,{...i,confirm:e.project.id}),g.refresh(),S.refresh()}});return(0,O.jsxs)(`div`,{className:`space-y-3`,children:[(0,O.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Limits: 10,000 documents / 4 MiB data; 100 files / 100 MiB. Pause cron and drain jobs before creating a backup. Partial restores stay closed; retry the same backup ID.`}),S.data?.status===`restoring`&&(0,O.jsxs)(`p`,{role:`alert`,children:[(0,O.jsx)(w,{status:`restoring`,children:`Restore in progress`}),`:`,` `,S.data.id,`. Select its source environment and retry Restore to finish.`]}),(0,O.jsxs)(`div`,{className:`flex flex-wrap gap-2`,children:[[`dev`,`prod`].map(e=>(0,O.jsxs)(m,{variant:t===e?`secondary`:`outline`,onClick:()=>{n(e),i(null)},children:[e===`dev`?`Development`:`Production`,` backups`]},e)),C&&(0,O.jsxs)(m,{onClick:()=>{let t=crypto.randomUUID();T(`Create backup`,`Snapshot ${e.env}. Backup ID: ${t}. No data will be deleted.`,h+`/backup-create`,{id:t})},children:[`Create `,e.env,` backup`]})]}),(0,O.jsx)(_,{loading:g.loading||S.loading,error:g.error||S.error}),g.data&&(0,O.jsxs)(`p`,{role:`status`,className:`text-xs text-muted-foreground`,children:[`Recovery point: `,g.data.recoveryPoint,`.`,` `,g.data.latest&&`Latest completed: ${new Date(g.data.latest.at).toLocaleString()} (${Math.floor((g.data.ageMs??0)/36e5)} hours old).`,` `,`Manual daily backup required for the 24-hour objective; no automatic schedule.`,g.data.inventory===`partial`&&(0,O.jsx)(m,{variant:`outline`,onClick:()=>{i(null),g.refresh()},children:`Continue inventory`})]}),g.data&&(0,O.jsxs)(o,{children:[(0,O.jsx)(b,{children:(0,O.jsxs)(a,{children:[(0,O.jsx)(c,{children:`Created`}),(0,O.jsx)(c,{children:`Backup / release`}),(0,O.jsx)(c,{children:`Documents`}),(0,O.jsx)(c,{children:`Files`}),(0,O.jsx)(c,{children:`Actions`})]})}),(0,O.jsxs)(y,{children:[g.data.page.map(n=>(0,O.jsxs)(a,{children:[(0,O.jsx)(x,{children:n.at?new Date(n.at).toLocaleString():(0,O.jsx)(w,{status:`Incomplete`})}),(0,O.jsxs)(x,{children:[(0,O.jsx)(`code`,{className:`text-xs select-all`,children:n.id}),(0,O.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:n.hash?.slice(0,12)??`Not restorable`})]}),(0,O.jsx)(x,{children:n.rows??`—`}),(0,O.jsx)(x,{children:n.files??`—`}),(0,O.jsx)(x,{children:(0,O.jsxs)(`div`,{className:`flex gap-2`,children:[C&&t!==e.env&&n.hash&&(0,O.jsxs)(m,{variant:`outline`,size:`sm`,onClick:()=>T(`Restore backup`,`Restore ${n.id} from ${t} into empty ${e.env}. Existing data will never be overwritten. Origin/auth settings stay unchanged.`,h+`/backup-restore`,{id:n.id,sourceEnv:t}),children:[`Restore into `,e.env]}),C&&(0,O.jsx)(m,{variant:`outline`,size:`sm`,onClick:()=>T(`Delete backup`,`Permanently delete snapshot ${n.id}. Live application data is not affected. Do not delete a backup needed by an unfinished restore.`,f+`/backup-delete`,{id:n.id}),children:`Delete`})]})})]},n.id)),!g.data.page.length&&(0,O.jsx)(a,{children:(0,O.jsx)(x,{colSpan:5,children:`No backups.`})})]})]}),(0,O.jsxs)(`div`,{className:`flex gap-2`,children:[(0,O.jsx)(m,{variant:`outline`,disabled:!r,onClick:()=>i(null),children:`First page`}),(0,O.jsx)(m,{variant:`outline`,disabled:!g.data?.cursor,onClick:()=>i(g.data?.cursor??null),children:`Next page`})]}),u&&(0,O.jsx)(s,{modal:u,onClose:()=>d(void 0)})]})}function j({onDeleted:e,...t}){let n=l(t.project,t.env),r=v(n+`/settings`),[i,a]=(0,D.useState)(!1);return(0,O.jsxs)(`div`,{className:`space-y-4 p-4`,children:[(0,O.jsx)(`h1`,{className:`page-title`,children:`Settings`}),(0,O.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Environment identity and frontend permissions.`}),(0,O.jsx)(_,{...r}),r.data&&(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)(N,{...t,settings:r.data,refresh:r.refresh}),(0,O.jsxs)(`details`,{className:`rounded-lg border`,onToggle:e=>a(e.currentTarget.open),children:[(0,O.jsx)(`summary`,{className:`cursor-pointer p-4 font-medium`,children:`Backups`}),i&&(0,O.jsx)(k,{...t})]})]}),t.session.role===`owner`&&(0,O.jsx)(M,{...t,onDeleted:e})]})}function M({project:e,onDeleted:t}){let[r,a]=(0,D.useState)();return(0,O.jsxs)(O.Fragment,{children:[(0,O.jsxs)(E,{children:[(0,O.jsx)(T,{children:(0,O.jsx)(S,{children:`Delete project`})}),(0,O.jsxs)(C,{className:`space-y-3`,children:[(0,O.jsx)(`p`,{className:`text-muted-foreground`,children:`Permanently delete both development and production: data, users, files, releases, backups and schedules. This cannot be undone.`}),e.deleting?(0,O.jsx)(`p`,{role:`alert`,children:`Deletion was started. Retry to finish cleanup.`}):null,(0,O.jsx)(m,{variant:`destructive`,onClick:()=>a({title:`Delete project`,description:`Delete ${e.name} and both environments permanently? The short URL stays reserved; other projects are not affected.`,destructive:!0,submitLabel:`Delete project`,content:(0,O.jsxs)(i,{children:[(0,O.jsxs)(n,{htmlFor:`delete-project-name`,children:[`Type the project name: `,e.name]}),(0,O.jsx)(h,{id:`delete-project-name`,name:`name`,required:!0,autoComplete:`off`,maxLength:100})]}),submit:async n=>{let r=new FormData(n).get(`name`);if(r!==e.name)throw Error(`Project name does not match`);try{await p(`projects/${e.id}/delete`,{name:r,confirm:e.id})}catch(t){if(f(t)!==`NOT_FOUND`||(await p(`projects`)).some(t=>t.id===e.id))throw t}t()}}),children:`Delete project`})]})]}),r&&(0,O.jsx)(s,{modal:r,onClose:()=>a(void 0)})]})}function N({project:e,env:t,session:r,settings:a,refresh:o}){let c=l(e,t),_=r.role!==`viewer`,[v,y]=(0,D.useState)(),[b,x]=(0,D.useState)(``),[w,k]=(0,D.useState)(``),[A,j]=(0,D.useState)(!1),M=async e=>{if(!A){j(!0),k(``);try{await e()}catch(e){k(f(e))}finally{j(!1)}}},N=(n,r,i)=>y({title:n,description:r,productionId:t===`prod`?e.id:void 0,submit:async e=>i(t===`prod`?String(new FormData(e).get(`confirm`)):void 0)});return(0,O.jsxs)(O.Fragment,{children:[w&&(0,O.jsx)(g,{children:w}),(0,O.jsxs)(E,{children:[(0,O.jsx)(T,{children:(0,O.jsx)(S,{children:`Cloud URL`})}),(0,O.jsxs)(C,{className:`space-y-3`,children:[(0,O.jsx)(`code`,{className:`block select-all break-all`,children:a.url}),(0,O.jsx)(`p`,{className:`text-muted-foreground`,children:`Permanent project name. Existing UUID URLs remain valid.`}),!a.alias&&r.role===`owner`&&(0,O.jsxs)(`form`,{className:`flex gap-2`,onSubmit:t=>{t.preventDefault();let n=new FormData(t.currentTarget).get(`alias`);M(async()=>{await p(`projects/${e.id}/alias`,{alias:n}),o()})},children:[(0,O.jsx)(h,{name:`alias`,"aria-label":`Short URL name`,required:!0,maxLength:48,pattern:`[a-z][a-z0-9]*(?:-[a-z0-9]+)*`,placeholder:`crm`}),(0,O.jsx)(m,{type:`submit`,disabled:A,children:`Set short URL`})]})]})]}),(0,O.jsxs)(E,{children:[(0,O.jsx)(T,{children:(0,O.jsx)(S,{children:`Environment access`})}),(0,O.jsx)(C,{children:(0,O.jsx)(`form`,{className:`max-w-xl`,onSubmit:e=>{if(e.preventDefault(),!_)return;let t=new FormData(e.currentTarget),n={origins:String(t.get(`origins`)).split(`
|
|
2
2
|
`).map(e=>e.trim()).filter(Boolean),oidc:[`issuer`,`audience`,`jwks`].some(e=>String(t.get(e)).trim())?Object.fromEntries([`issuer`,`audience`,`jwks`].map(e=>[e,String(t.get(e)).trim()])):null};N(`Save environment`,`Updates frontend origins and user token verification. Existing applications continue to use this environment.`,async e=>{await p(c+`/settings`,{...n,confirm:e}),o()})},children:(0,O.jsxs)(d,{children:[(0,O.jsxs)(i,{children:[(0,O.jsx)(n,{htmlFor:`settings-origins`,children:`Frontend origins · one per line`}),(0,O.jsx)(u,{id:`settings-origins`,name:`origins`,defaultValue:a.origins.join(`
|
|
3
3
|
`),disabled:!_})]}),(0,O.jsx)(`h3`,{className:`text-sm font-medium`,children:`Authentication · OIDC / RS256`}),(0,O.jsxs)(i,{children:[(0,O.jsx)(n,{htmlFor:`settings-issuer`,children:`Issuer`}),(0,O.jsx)(h,{id:`settings-issuer`,type:`url`,name:`issuer`,defaultValue:a.oidc?.issuer??``,disabled:!_,placeholder:`https://your-provider.example`})]}),(0,O.jsxs)(i,{children:[(0,O.jsx)(n,{htmlFor:`settings-audience`,children:`Audience`}),(0,O.jsx)(h,{id:`settings-audience`,name:`audience`,defaultValue:a.oidc?.audience??``,disabled:!_})]}),(0,O.jsxs)(i,{children:[(0,O.jsx)(n,{htmlFor:`settings-jwks`,children:`JWKS URL`}),(0,O.jsx)(h,{id:`settings-jwks`,type:`url`,name:`jwks`,defaultValue:a.oidc?.jwks??``,disabled:!_,placeholder:`https://your-provider.example/.well-known/jwks.json`})]}),(0,O.jsx)(`p`,{className:`text-muted-foreground`,children:`Leave all three empty to disable OIDC. Protected production functions remain closed.`}),_&&(0,O.jsx)(m,{type:`submit`,children:`Save environment`})]})})})]}),(0,O.jsxs)(E,{children:[(0,O.jsx)(T,{children:(0,O.jsx)(S,{children:`CLI access`})}),(0,O.jsxs)(C,{className:`space-y-4`,children:[(0,O.jsx)(`p`,{children:`Project-scoped deploy credential, valid for 30 days. Never put it in frontend code. Keep it in your shell or CI secret store.`}),r.role===`owner`&&(0,O.jsxs)(`div`,{className:`flex gap-2`,children:[(0,O.jsx)(m,{variant:`outline`,onClick:()=>N(`Issue CLI credential`,`The token is shown once. It grants deployment rights only for this project.`,async t=>{let n=await p(c+`/credential`,{confirm:t});x(`export FLARE_DEPLOY_TOKEN=${n.token}\nflare link --platform ${n.platform} --project ${e.id}\nflare deploy --env dev --release ./release`)}),children:`Issue credential`}),(0,O.jsx)(m,{variant:`destructive`,onClick:()=>N(`Revoke project credentials`,`All existing CLI credentials for this project will stop working.`,async e=>{await p(c+`/revoke-credentials`,{confirm:e}),x(`Credentials revoked.`)}),children:`Revoke credentials`})]}),b&&(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)(`pre`,{className:`code-block`,children:b}),(0,O.jsx)(m,{variant:`ghost`,onClick:()=>x(``),children:`Clear from view`})]})]})]}),v&&(0,O.jsx)(s,{modal:v,onClose:()=>y(void 0)})]})}export{j as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="en" class="dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="robots" content="noindex,nofollow"><title>Flare · Dashboard</title><meta http-equiv="content-security-policy" content="script-src 'self' 'sha256-xIb/Pa7FUshAu4ihwjchYcQpyCI8eS8kt40GpOAYCz8=' 'sha256-1BvDVWLr3QCC20uHhUDi27eDFVJpk1uMQJGIWKUks2I=' 'sha256-kmZE/W8I1iuTnl1b3yqzv9/DQZenPngd3NjSKMQl7y0=' 'sha256-Y8t0ntteBwH+PqGKUyjWW3CAk+BNJKSoQc0xZ68FjhM=' 'sha256-0O7iB6zr9x0r6X6eWYITC9V5q+yWCGAoFvcysBGbY9Q=' 'sha256-tQIkdAw2vqfQ1PjgUE4ML2A4pIV8SByQ1Seeehy6UIc=' 'sha256-4f86GpVBksx63uHEB4f15jGyhnVEOKjwqYxwnfDVOik='; style-src 'self' 'sha256-vv9IoKo7BSLbWcUHr3tNmfNVmm5L/9Cfn2H6LMk7/ow=' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=';"><link rel="stylesheet" href="/_astro/index.CDrYoVkO.css"></head><body><div id="flare-dashboard"><div class="p-6 text-sm text-muted-foreground" role="status">Loading Flare…</div></div><script type="module" src="/_astro/index.astro_astro_type_script_index_0_lang.
|
|
1
|
+
<!DOCTYPE html><html lang="en" class="dark"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="robots" content="noindex,nofollow"><title>Flare · Dashboard</title><meta http-equiv="content-security-policy" content="script-src 'self' 'sha256-xIb/Pa7FUshAu4ihwjchYcQpyCI8eS8kt40GpOAYCz8=' 'sha256-1BvDVWLr3QCC20uHhUDi27eDFVJpk1uMQJGIWKUks2I=' 'sha256-kmZE/W8I1iuTnl1b3yqzv9/DQZenPngd3NjSKMQl7y0=' 'sha256-Y8t0ntteBwH+PqGKUyjWW3CAk+BNJKSoQc0xZ68FjhM=' 'sha256-0O7iB6zr9x0r6X6eWYITC9V5q+yWCGAoFvcysBGbY9Q=' 'sha256-tQIkdAw2vqfQ1PjgUE4ML2A4pIV8SByQ1Seeehy6UIc=' 'sha256-4f86GpVBksx63uHEB4f15jGyhnVEOKjwqYxwnfDVOik='; style-src 'self' 'sha256-vv9IoKo7BSLbWcUHr3tNmfNVmm5L/9Cfn2H6LMk7/ow=' 'sha256-47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=';"><link rel="stylesheet" href="/_astro/index.CDrYoVkO.css"></head><body><div id="flare-dashboard"><div class="p-6 text-sm text-muted-foreground" role="status">Loading Flare…</div></div><script type="module" src="/_astro/index.astro_astro_type_script_index_0_lang.DBs-yURk.js"></script></body></html>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"format": 1,
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.18",
|
|
4
4
|
"stateFormat": 1,
|
|
5
5
|
"protocol": 1,
|
|
6
6
|
"runtimeAbi": 4,
|
|
@@ -8,23 +8,24 @@
|
|
|
8
8
|
"wranglerVersion": "4.150.0",
|
|
9
9
|
"upgradeFrom": [
|
|
10
10
|
"0.3.13",
|
|
11
|
-
"0.3.16"
|
|
11
|
+
"0.3.16",
|
|
12
|
+
"0.3.17"
|
|
12
13
|
],
|
|
13
14
|
"files": [
|
|
14
15
|
{
|
|
15
16
|
"path": "admin.js",
|
|
16
17
|
"bytes": 37491,
|
|
17
|
-
"sha256": "
|
|
18
|
+
"sha256": "e4b0f4d69c2b3598e431ab44ab3779dfd4546acb140b18c5c22faac56a26fb33"
|
|
18
19
|
},
|
|
19
20
|
{
|
|
20
|
-
"path": "dashboard/_astro/ai-view.
|
|
21
|
-
"bytes":
|
|
22
|
-
"sha256": "
|
|
21
|
+
"path": "dashboard/_astro/ai-view.DcYKk5W_.js",
|
|
22
|
+
"bytes": 4759,
|
|
23
|
+
"sha256": "991d1dbf4cbad8673bfdccc46498f0df6811018a9ec6ca20a82de27405545727"
|
|
23
24
|
},
|
|
24
25
|
{
|
|
25
|
-
"path": "dashboard/_astro/auth-view.
|
|
26
|
+
"path": "dashboard/_astro/auth-view.KnVtTZYn.js",
|
|
26
27
|
"bytes": 3494,
|
|
27
|
-
"sha256": "
|
|
28
|
+
"sha256": "845572dc334400d07bcdc1aaf6410b3b6d2fdce6ea4d1767418994053e411bf5"
|
|
28
29
|
},
|
|
29
30
|
{
|
|
30
31
|
"path": "dashboard/_astro/cli-approval.emPTVRqn.js",
|
|
@@ -52,14 +53,14 @@
|
|
|
52
53
|
"sha256": "d2313bf971c2c4e73f6ed7e5bd9f687c8ece4969f1405e8cc774cbc8885e335d"
|
|
53
54
|
},
|
|
54
55
|
{
|
|
55
|
-
"path": "dashboard/_astro/data-view.
|
|
56
|
+
"path": "dashboard/_astro/data-view.BFL2F3o9.js",
|
|
56
57
|
"bytes": 5806,
|
|
57
|
-
"sha256": "
|
|
58
|
+
"sha256": "d48107a85f3552ad204581924e1368c84a5b9b75f08be0d55c80d454861cab80"
|
|
58
59
|
},
|
|
59
60
|
{
|
|
60
|
-
"path": "dashboard/_astro/functions-view.
|
|
61
|
+
"path": "dashboard/_astro/functions-view.vsmqlnUa.js",
|
|
61
62
|
"bytes": 6206,
|
|
62
|
-
"sha256": "
|
|
63
|
+
"sha256": "ba7e2bfb5595d62ba6a88e662353988af9d7e5ae40ceae15941837b72e4719a3"
|
|
63
64
|
},
|
|
64
65
|
{
|
|
65
66
|
"path": "dashboard/_astro/geist-cyrillic-ext-wght-normal.DjL33-gN.woff2",
|
|
@@ -92,9 +93,9 @@
|
|
|
92
93
|
"sha256": "be7da729dc120b16d178fcd2606642e03a47fe2f1a2a1a8c4aa40cfcc59e848c"
|
|
93
94
|
},
|
|
94
95
|
{
|
|
95
|
-
"path": "dashboard/_astro/index.astro_astro_type_script_index_0_lang.
|
|
96
|
+
"path": "dashboard/_astro/index.astro_astro_type_script_index_0_lang.DBs-yURk.js",
|
|
96
97
|
"bytes": 37394,
|
|
97
|
-
"sha256": "
|
|
98
|
+
"sha256": "004838343d2b988eed21ec4d1d60c24030e9ce58f033ecc0e4cc7502837c5ab1"
|
|
98
99
|
},
|
|
99
100
|
{
|
|
100
101
|
"path": "dashboard/_astro/input-group.Dsc4z0iT.js",
|
|
@@ -102,19 +103,19 @@
|
|
|
102
103
|
"sha256": "7ab083f8bbd656b2a49951f076afb10f008ca5630369955481018aeb27325c50"
|
|
103
104
|
},
|
|
104
105
|
{
|
|
105
|
-
"path": "dashboard/_astro/sdk-view.
|
|
106
|
+
"path": "dashboard/_astro/sdk-view.BPVWrAC3.js",
|
|
106
107
|
"bytes": 3363,
|
|
107
|
-
"sha256": "
|
|
108
|
+
"sha256": "52190ae8162f76220eec548c2f4664459265528d6716a8c7b20701b521729e99"
|
|
108
109
|
},
|
|
109
110
|
{
|
|
110
|
-
"path": "dashboard/_astro/services-view.
|
|
111
|
+
"path": "dashboard/_astro/services-view.Dx1rjMWa.js",
|
|
111
112
|
"bytes": 8249,
|
|
112
|
-
"sha256": "
|
|
113
|
+
"sha256": "574adb9a4209902e8baf74580af21efe3336fdea999e456ca53ad82e4b0bafee"
|
|
113
114
|
},
|
|
114
115
|
{
|
|
115
|
-
"path": "dashboard/_astro/settings-view.
|
|
116
|
+
"path": "dashboard/_astro/settings-view.DPwEyqzv.js",
|
|
116
117
|
"bytes": 10768,
|
|
117
|
-
"sha256": "
|
|
118
|
+
"sha256": "f5384854e892e4d3bf507f5ac48231ac259593bf94827a2676dd83e1ed89f38a"
|
|
118
119
|
},
|
|
119
120
|
{
|
|
120
121
|
"path": "dashboard/_headers",
|
|
@@ -159,7 +160,7 @@
|
|
|
159
160
|
{
|
|
160
161
|
"path": "dashboard/index.html",
|
|
161
162
|
"bytes": 1095,
|
|
162
|
-
"sha256": "
|
|
163
|
+
"sha256": "88767a2cd15669c2f765bbc68a3f666b3f26eb88586477d78fe55a2f3e7fb40c"
|
|
163
164
|
},
|
|
164
165
|
{
|
|
165
166
|
"path": "migrations/0001.sql",
|
|
@@ -193,9 +194,9 @@
|
|
|
193
194
|
},
|
|
194
195
|
{
|
|
195
196
|
"path": "runtime.js",
|
|
196
|
-
"bytes":
|
|
197
|
-
"sha256": "
|
|
197
|
+
"bytes": 1235276,
|
|
198
|
+
"sha256": "0732ed74b8ec8cdea7ca2a964973b744c0153e41cc0eb9b4dfd48edba87cf663"
|
|
198
199
|
}
|
|
199
200
|
],
|
|
200
|
-
"digest": "
|
|
201
|
+
"digest": "0ca53e96e1f8606024eb7eed83fcfc5656a8448f1871f7ecc1c8b4ccd5eca518"
|
|
201
202
|
}
|
package/dist/platform/runtime.js
CHANGED
|
@@ -22956,7 +22956,7 @@ function assertMcpTools(functions) {
|
|
|
22956
22956
|
if (fn.mcp === undefined)
|
|
22957
22957
|
continue;
|
|
22958
22958
|
const m = fn.mcp;
|
|
22959
|
-
if (!m || typeof m !== "object" || Object.keys(m).
|
|
22959
|
+
if (!m || typeof m !== "object" || Object.keys(m).some((key) => !["name", "description", "readOnly"].includes(key)) || m.readOnly !== undefined && typeof m.readOnly !== "boolean" || fn.kind === "mutation" && m.readOnly === true || fn.kind === "query" && m.readOnly === false || typeof m.name !== "string" || !/^[A-Za-z][A-Za-z0-9_.-]{0,63}$/.test(m.name) || typeof m.description !== "string" || !m.description.trim() || m.description.length > 1000 || names.has(m.name) || fn.auth === "internal" || fn.input.type !== "object")
|
|
22960
22960
|
throw new FlareError("INVALID_CONTRACT", "Invalid MCP tool contract");
|
|
22961
22961
|
boundedJson({ mcp: m, input: fn.input }, 16384);
|
|
22962
22962
|
names.add(m.name);
|
|
@@ -22975,7 +22975,7 @@ function appPolicy(env, scope) {
|
|
|
22975
22975
|
throw new FlareError("INVALID_CONFIG", "Invalid app capabilities");
|
|
22976
22976
|
cached = Object.create(null);
|
|
22977
22977
|
for (const [key, value] of Object.entries(raw)) {
|
|
22978
|
-
if (!/^[0-9a-f-]{36}\/(dev|prod)$/.test(key) || !value || Object.keys(value).some((k) => !["outbound", "secrets", "search", "codex"].includes(k)))
|
|
22978
|
+
if (!/^[0-9a-f-]{36}\/(dev|prod)$/.test(key) || !value || Object.keys(value).some((k) => !["outbound", "secrets", "search", "codex", "mcpAuth"].includes(k)))
|
|
22979
22979
|
throw new FlareError("INVALID_CONFIG", "Invalid capability scope");
|
|
22980
22980
|
const outbound = value.outbound ?? [], secrets = value.secrets ?? {};
|
|
22981
22981
|
if (!Array.isArray(outbound) || outbound.length > 20 || !secrets || Array.isArray(secrets) || typeof secrets !== "object" || Object.keys(secrets).length > 16)
|
|
@@ -22990,7 +22990,13 @@ function appPolicy(env, scope) {
|
|
|
22990
22990
|
throw new FlareError("INVALID_CONFIG", "Invalid search binding");
|
|
22991
22991
|
if (value.codex !== undefined && (typeof value.codex !== "string" || !/^APP_CODEX_[A-Z0-9_]{1,64}$/.test(value.codex)))
|
|
22992
22992
|
throw new FlareError("INVALID_CONFIG", "Invalid Codex binding");
|
|
22993
|
+
if (value.mcpAuth !== undefined) {
|
|
22994
|
+
const a = value.mcpAuth;
|
|
22995
|
+
if (!a || Object.keys(a).sort().join() !== "binding,issuer" || !/^APP_MCP_AUTH_[A-Z0-9_]{1,64}$/.test(a.binding) || typeof a.issuer !== "string" || !/^https:\/\/[a-z0-9.-]+$/.test(a.issuer))
|
|
22996
|
+
throw new FlareError("INVALID_CONFIG", "Invalid MCP authorization binding");
|
|
22997
|
+
}
|
|
22993
22998
|
cached[key] = Object.freeze({
|
|
22999
|
+
...value.mcpAuth === undefined ? {} : { mcpAuth: Object.freeze({ ...value.mcpAuth }) },
|
|
22994
23000
|
...value.codex === undefined ? {} : { codex: value.codex },
|
|
22995
23001
|
...value.search === undefined ? {} : { search: value.search },
|
|
22996
23002
|
outbound: Object.freeze([...new Set(outbound)]),
|
|
@@ -24003,16 +24009,16 @@ class SearchStore {
|
|
|
24003
24009
|
}
|
|
24004
24010
|
|
|
24005
24011
|
// packages/core/src/mcp.ts
|
|
24006
|
-
function mcpTools(manifest) {
|
|
24007
|
-
return Object.values(manifest.functions).flatMap((fn) => fn.mcp && fn.auth !== "internal" ? [
|
|
24012
|
+
function mcpTools(manifest, scopes) {
|
|
24013
|
+
return Object.values(manifest.functions).flatMap((fn) => fn.mcp && fn.auth !== "internal" && (!scopes || scopes.includes("mcp:write") || fn.kind === "query" || fn.mcp.readOnly === true) ? [
|
|
24008
24014
|
{
|
|
24009
24015
|
name: fn.mcp.name,
|
|
24010
24016
|
description: fn.mcp.description,
|
|
24011
24017
|
inputSchema: fn.input,
|
|
24012
24018
|
annotations: {
|
|
24013
|
-
readOnlyHint: fn.kind === "query",
|
|
24014
|
-
destructiveHint: fn.kind !== "query",
|
|
24015
|
-
idempotentHint: fn.kind === "query",
|
|
24019
|
+
readOnlyHint: fn.kind === "query" || fn.mcp.readOnly === true,
|
|
24020
|
+
destructiveHint: fn.kind !== "query" && fn.mcp.readOnly !== true,
|
|
24021
|
+
idempotentHint: fn.kind === "query" || fn.mcp.readOnly === true,
|
|
24016
24022
|
openWorldHint: fn.kind === "action"
|
|
24017
24023
|
}
|
|
24018
24024
|
}
|
|
@@ -24087,6 +24093,38 @@ async function mcpResponse(request, supervisor) {
|
|
|
24087
24093
|
return out;
|
|
24088
24094
|
}
|
|
24089
24095
|
|
|
24096
|
+
// packages/core/src/mcp-auth.ts
|
|
24097
|
+
function mcpResource(env, scope) {
|
|
24098
|
+
return `${env.RUNTIME_URL}/p/${scope}/v1/mcp`;
|
|
24099
|
+
}
|
|
24100
|
+
function mcpMetadata(env, scope) {
|
|
24101
|
+
const configured = appPolicy(env, scope).mcpAuth;
|
|
24102
|
+
if (!configured)
|
|
24103
|
+
return null;
|
|
24104
|
+
return {
|
|
24105
|
+
resource: mcpResource(env, scope),
|
|
24106
|
+
authorization_servers: [configured.issuer],
|
|
24107
|
+
scopes_supported: ["mcp:read"],
|
|
24108
|
+
bearer_methods_supported: ["header"],
|
|
24109
|
+
resource_name: "Flare application MCP"
|
|
24110
|
+
};
|
|
24111
|
+
}
|
|
24112
|
+
function mcpChallenge(env, scope) {
|
|
24113
|
+
return `Bearer resource_metadata="${env.RUNTIME_URL}/.well-known/oauth-protected-resource/p/${scope}/v1/mcp", scope="mcp:read"`;
|
|
24114
|
+
}
|
|
24115
|
+
async function validateMcpToken(env, scope, token) {
|
|
24116
|
+
const configured = appPolicy(env, scope).mcpAuth;
|
|
24117
|
+
if (!configured || !token || token.length > 8192)
|
|
24118
|
+
fail("UNAUTHORIZED");
|
|
24119
|
+
const binding = env[configured.binding];
|
|
24120
|
+
if (!binding?.validateToken)
|
|
24121
|
+
fail("UNAUTHORIZED");
|
|
24122
|
+
const validated = await binding.validateToken(mcpResource(env, scope), token);
|
|
24123
|
+
if (!validated || validated.audience !== mcpResource(env, scope) || !Number.isFinite(validated.expiresAt) || validated.expiresAt * 1000 <= Date.now() || !Array.isArray(validated.scope) || !validated.scope.includes("mcp:read") || typeof validated.clientId !== "string" || !validated.clientId || !validated.props || validated.props.scope !== scope || typeof validated.props.userId !== "string" || validated.props.userId !== validated.userId || typeof validated.props.epoch !== "string")
|
|
24124
|
+
fail("UNAUTHORIZED");
|
|
24125
|
+
return validated;
|
|
24126
|
+
}
|
|
24127
|
+
|
|
24090
24128
|
// packages/core/src/auth.ts
|
|
24091
24129
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
24092
24130
|
import { scrypt, timingSafeEqual } from "node:crypto";
|
|
@@ -24155,7 +24193,8 @@ class PasswordAuth {
|
|
|
24155
24193
|
"CREATE INDEX IF NOT EXISTS auth_sessions_expires ON auth_sessions(expires)",
|
|
24156
24194
|
"CREATE TABLE IF NOT EXISTS auth_config (id INTEGER PRIMARY KEY,enabled INTEGER NOT NULL DEFAULT 0,registration INTEGER NOT NULL DEFAULT 0)",
|
|
24157
24195
|
"INSERT OR IGNORE INTO auth_config VALUES (1,0,0)",
|
|
24158
|
-
"CREATE TABLE IF NOT EXISTS auth_limits (id TEXT PRIMARY KEY,at INTEGER NOT NULL,count INTEGER NOT NULL)"
|
|
24196
|
+
"CREATE TABLE IF NOT EXISTS auth_limits (id TEXT PRIMARY KEY,at INTEGER NOT NULL,count INTEGER NOT NULL)",
|
|
24197
|
+
"CREATE TABLE IF NOT EXISTS auth_delegations (userId TEXT PRIMARY KEY,epoch TEXT NOT NULL)"
|
|
24159
24198
|
])
|
|
24160
24199
|
storage.sql.exec(sql);
|
|
24161
24200
|
}
|
|
@@ -24175,6 +24214,7 @@ class PasswordAuth {
|
|
|
24175
24214
|
validateAuthBackup(users);
|
|
24176
24215
|
this.storage.transactionSync(() => {
|
|
24177
24216
|
this.storage.sql.exec("DELETE FROM auth_sessions");
|
|
24217
|
+
this.storage.sql.exec("DELETE FROM auth_delegations");
|
|
24178
24218
|
this.storage.sql.exec("DELETE FROM auth_users");
|
|
24179
24219
|
for (const u of users)
|
|
24180
24220
|
this.storage.sql.exec("INSERT INTO auth_users VALUES (?,?,?,?,?)", u.id, u.login, u.password, u.disabled, u.createdAt);
|
|
@@ -24240,7 +24280,35 @@ class PasswordAuth {
|
|
|
24240
24280
|
claims: { flaredSession: id, login: String(row.login) }
|
|
24241
24281
|
};
|
|
24242
24282
|
}
|
|
24283
|
+
async delegation(userId) {
|
|
24284
|
+
this.storage.sql.exec("INSERT OR IGNORE INTO auth_delegations VALUES (?,?)", userId, crypto.randomUUID());
|
|
24285
|
+
const epoch = String(this.storage.sql.exec("SELECT epoch FROM auth_delegations WHERE userId=?", userId).one().epoch);
|
|
24286
|
+
await this.storage.sync();
|
|
24287
|
+
return { userId, epoch, login: this.user(userId).login, scope: this.scope };
|
|
24288
|
+
}
|
|
24289
|
+
delegated(userId, epoch, expiresAt, clientId) {
|
|
24290
|
+
if (!this.settings().enabled || !Number.isFinite(expiresAt) || expiresAt <= Date.now())
|
|
24291
|
+
fail("UNAUTHORIZED");
|
|
24292
|
+
const row = this.storage.sql.exec("SELECT u.login FROM auth_users u JOIN auth_delegations d ON d.userId=u.id WHERE u.id=? AND d.epoch=? AND u.disabled=0", userId, epoch).toArray()[0];
|
|
24293
|
+
if (!row)
|
|
24294
|
+
fail("UNAUTHORIZED");
|
|
24295
|
+
return {
|
|
24296
|
+
subject: userId,
|
|
24297
|
+
issuer: this.issuer + "/auth/" + this.scope,
|
|
24298
|
+
expiresAt,
|
|
24299
|
+
claims: {
|
|
24300
|
+
login: String(row.login),
|
|
24301
|
+
flaredDelegation: epoch,
|
|
24302
|
+
flaredMcp: true,
|
|
24303
|
+
flaredMcpClient: clientId
|
|
24304
|
+
}
|
|
24305
|
+
};
|
|
24306
|
+
}
|
|
24243
24307
|
assert(auth) {
|
|
24308
|
+
if (typeof auth?.claims.flaredDelegation === "string") {
|
|
24309
|
+
this.delegated(auth.subject, auth.claims.flaredDelegation, auth.expiresAt, String(auth.claims.flaredMcpClient ?? ""));
|
|
24310
|
+
return;
|
|
24311
|
+
}
|
|
24244
24312
|
const session = auth?.claims.flaredSession;
|
|
24245
24313
|
if (typeof session !== "string")
|
|
24246
24314
|
return;
|
|
@@ -24250,7 +24318,7 @@ class PasswordAuth {
|
|
|
24250
24318
|
async public(op, input, token) {
|
|
24251
24319
|
if (!this.settings().enabled)
|
|
24252
24320
|
fail("AUTH_DISABLED");
|
|
24253
|
-
if (op === "register" || op === "login") {
|
|
24321
|
+
if (op === "register" || op === "login" || op === "delegate") {
|
|
24254
24322
|
this.limit("global", 30);
|
|
24255
24323
|
const login = loginName(input.login);
|
|
24256
24324
|
this.limit("login:" + login, 5);
|
|
@@ -24264,11 +24332,15 @@ class PasswordAuth {
|
|
|
24264
24332
|
const valid = await verifyPassword(input.password, row ? String(row.password) : undefined);
|
|
24265
24333
|
if (!valid || !row || row.disabled)
|
|
24266
24334
|
fail("UNAUTHORIZED");
|
|
24335
|
+
if (op === "delegate")
|
|
24336
|
+
return this.delegation(String(row.id));
|
|
24267
24337
|
return this.issue(String(row.id));
|
|
24268
24338
|
}
|
|
24269
24339
|
if (!token)
|
|
24270
24340
|
fail("UNAUTHORIZED");
|
|
24271
24341
|
const auth = await this.authenticate(token);
|
|
24342
|
+
if (op === "mcp-identity")
|
|
24343
|
+
return this.delegation(auth.subject);
|
|
24272
24344
|
if (op === "me")
|
|
24273
24345
|
return this.user(auth.subject);
|
|
24274
24346
|
if (op === "logout") {
|
|
@@ -24292,6 +24364,7 @@ class PasswordAuth {
|
|
|
24292
24364
|
this.storage.transactionSync(() => {
|
|
24293
24365
|
this.storage.sql.exec("UPDATE auth_users SET password=? WHERE id=?", hash, id);
|
|
24294
24366
|
this.storage.sql.exec("DELETE FROM auth_sessions WHERE userId=?", id);
|
|
24367
|
+
this.storage.sql.exec("DELETE FROM auth_delegations WHERE userId=?", id);
|
|
24295
24368
|
});
|
|
24296
24369
|
}
|
|
24297
24370
|
async admin(op, input) {
|
|
@@ -24302,8 +24375,10 @@ class PasswordAuth {
|
|
|
24302
24375
|
fail("INVALID_INPUT");
|
|
24303
24376
|
this.storage.transactionSync(() => {
|
|
24304
24377
|
this.storage.sql.exec("UPDATE auth_config SET enabled=?,registration=? WHERE id=1", +input.enabled, +input.registration);
|
|
24305
|
-
if (!input.enabled)
|
|
24378
|
+
if (!input.enabled) {
|
|
24306
24379
|
this.storage.sql.exec("DELETE FROM auth_sessions");
|
|
24380
|
+
this.storage.sql.exec("DELETE FROM auth_delegations");
|
|
24381
|
+
}
|
|
24307
24382
|
});
|
|
24308
24383
|
await this.storage.sync();
|
|
24309
24384
|
return this.settings();
|
|
@@ -24333,6 +24408,7 @@ class PasswordAuth {
|
|
|
24333
24408
|
this.storage.sql.exec("UPDATE auth_users SET disabled=? WHERE id=?", +input.disabled, input.id);
|
|
24334
24409
|
}
|
|
24335
24410
|
this.storage.sql.exec("DELETE FROM auth_sessions WHERE userId=?", input.id);
|
|
24411
|
+
this.storage.sql.exec("DELETE FROM auth_delegations WHERE userId=?", input.id);
|
|
24336
24412
|
});
|
|
24337
24413
|
} else
|
|
24338
24414
|
fail("INVALID_OPERATION");
|
|
@@ -24351,7 +24427,7 @@ function dashboardIdentity(value) {
|
|
|
24351
24427
|
// packages/core/package.json
|
|
24352
24428
|
var package_default = {
|
|
24353
24429
|
name: "@flare/platform",
|
|
24354
|
-
version: "0.3.
|
|
24430
|
+
version: "0.3.18",
|
|
24355
24431
|
type: "module",
|
|
24356
24432
|
license: "MIT",
|
|
24357
24433
|
private: true,
|
|
@@ -31361,8 +31437,8 @@ function projectAlias(value) {
|
|
|
31361
31437
|
return value;
|
|
31362
31438
|
}
|
|
31363
31439
|
function applicationRoute(path) {
|
|
31364
|
-
const old = path.match(/^\/p\/([^/]+)\/(dev|prod)\/v1\/(call|codex\/events|mcp|auth\/(?:register|login|logout|me|change-password)|live(?:\/ticket)?|files\/(?:upload|download))$/);
|
|
31365
|
-
const short = old ? null : path.match(/^\/([^/]+)\/(dev|prod)\/v1\/(call|codex\/events|mcp|auth\/(?:register|login|logout|me|change-password)|live(?:\/ticket)?|files\/(?:upload|download))$/);
|
|
31440
|
+
const old = path.match(/^\/p\/([^/]+)\/(dev|prod)\/v1\/(call|codex\/events|mcp|auth\/(?:register|login|logout|me|change-password|delegate|mcp-identity)|live(?:\/ticket)?|files\/(?:upload|download))$/);
|
|
31441
|
+
const short = old ? null : path.match(/^\/([^/]+)\/(dev|prod)\/v1\/(call|codex\/events|mcp|auth\/(?:register|login|logout|me|change-password|delegate|mcp-identity)|live(?:\/ticket)?|files\/(?:upload|download))$/);
|
|
31366
31442
|
try {
|
|
31367
31443
|
if (old)
|
|
31368
31444
|
return {
|
|
@@ -32162,6 +32238,8 @@ class EnvironmentSupervisor extends DurableObject {
|
|
|
32162
32238
|
allowedOrigin = input.origin;
|
|
32163
32239
|
if (input.operation === "preflight")
|
|
32164
32240
|
return null;
|
|
32241
|
+
if (["delegate", "mcp-identity"].includes(input.operation) && !appPolicy(this.env, this.config().scope).mcpAuth)
|
|
32242
|
+
fail("FORBIDDEN");
|
|
32165
32243
|
if (input.authorization && !input.authorization.startsWith("Bearer "))
|
|
32166
32244
|
fail("UNAUTHORIZED");
|
|
32167
32245
|
const auth = await this.authenticate(input.authorization?.slice(7) ?? null);
|
|
@@ -32199,16 +32277,26 @@ class EnvironmentSupervisor extends DurableObject {
|
|
|
32199
32277
|
if (input.origin && !this.config().origins.includes(input.origin))
|
|
32200
32278
|
fail("FORBIDDEN");
|
|
32201
32279
|
const token = input.authorization;
|
|
32202
|
-
if (!token?.startsWith("Bearer
|
|
32280
|
+
if (!token?.startsWith("Bearer "))
|
|
32203
32281
|
fail("UNAUTHORIZED");
|
|
32204
|
-
|
|
32282
|
+
let auth, scopes;
|
|
32283
|
+
if (token.startsWith("Bearer flared_session_"))
|
|
32284
|
+
auth = await this.passwords().authenticate(token.slice(7));
|
|
32285
|
+
else {
|
|
32286
|
+
const validated = await validateMcpToken(this.env, this.config().scope, token.slice(7));
|
|
32287
|
+
auth = this.passwords().delegated(validated.props.userId, validated.props.epoch, validated.expiresAt * 1000, validated.clientId);
|
|
32288
|
+
scopes = validated.scope;
|
|
32289
|
+
}
|
|
32290
|
+
const tools = mcpTools(this.metadata().manifest, scopes);
|
|
32205
32291
|
if (input.name === undefined)
|
|
32206
|
-
return
|
|
32292
|
+
return tools;
|
|
32293
|
+
if (!tools.some((tool) => tool.name === input.name))
|
|
32294
|
+
fail("FORBIDDEN");
|
|
32207
32295
|
const result = await this.call({
|
|
32208
32296
|
path: "mcp",
|
|
32209
32297
|
kind: "query",
|
|
32210
32298
|
args: input.args ?? {},
|
|
32211
|
-
auth,
|
|
32299
|
+
auth: { ...auth, claims: { ...auth.claims, flaredMcp: true } },
|
|
32212
32300
|
mcp: input.name
|
|
32213
32301
|
});
|
|
32214
32302
|
this.checkPasswordSession(auth);
|
|
@@ -32228,7 +32316,7 @@ class EnvironmentSupervisor extends DurableObject {
|
|
|
32228
32316
|
return this.passwordAuth ??= new PasswordAuth(this.ctx.storage, this.config().scope, this.env.RUNTIME_URL);
|
|
32229
32317
|
}
|
|
32230
32318
|
checkPasswordSession(auth) {
|
|
32231
|
-
if (typeof auth?.claims.flaredSession === "string")
|
|
32319
|
+
if (typeof auth?.claims.flaredSession === "string" || typeof auth?.claims.flaredDelegation === "string")
|
|
32232
32320
|
this.passwords().assert(auth);
|
|
32233
32321
|
}
|
|
32234
32322
|
closeRevokedSockets() {
|
|
@@ -32633,6 +32721,7 @@ class EnvironmentSupervisor extends DurableObject {
|
|
|
32633
32721
|
search: this.search().summary(),
|
|
32634
32722
|
tools: mcpTools(this.metadata().manifest).map(({ name, description }) => ({ name, description })),
|
|
32635
32723
|
auth: "app-session",
|
|
32724
|
+
oauth: mcpMetadata(this.env, this.config().scope),
|
|
32636
32725
|
endpoint: `${this.env.RUNTIME_URL}/p/${this.config().scope}/v1/mcp`
|
|
32637
32726
|
};
|
|
32638
32727
|
if (op === "search-clear")
|
|
@@ -33102,7 +33191,9 @@ var runtime_default = {
|
|
|
33102
33191
|
target.pathname = target.pathname.slice("/control".length);
|
|
33103
33192
|
return env.ADMIN_API.request(new Request(target, request));
|
|
33104
33193
|
}
|
|
33105
|
-
const
|
|
33194
|
+
const metadataPrefix = "/.well-known/oauth-protected-resource";
|
|
33195
|
+
const metadataRequest = url.pathname.startsWith(metadataPrefix + "/");
|
|
33196
|
+
const route = applicationRoute(metadataRequest ? url.pathname.slice(metadataPrefix.length) : url.pathname);
|
|
33106
33197
|
if (!route)
|
|
33107
33198
|
return new Response("Not found", { status: 404 });
|
|
33108
33199
|
if (!await env.RATE_LIMITER.limit({
|
|
@@ -33116,6 +33207,17 @@ var runtime_default = {
|
|
|
33116
33207
|
if (!projectId)
|
|
33117
33208
|
return new Response("Not found", { status: 404 });
|
|
33118
33209
|
scope = `${projectId}/${route.env}`;
|
|
33210
|
+
if (metadataRequest) {
|
|
33211
|
+
const metadata = route.operation === "mcp" && mcpMetadata(env, scope);
|
|
33212
|
+
if (!metadata || request.method !== "GET")
|
|
33213
|
+
return new Response("Not found", { status: 404 });
|
|
33214
|
+
return Response.json(metadata, {
|
|
33215
|
+
headers: {
|
|
33216
|
+
"cache-control": "no-store",
|
|
33217
|
+
"access-control-allow-origin": "*"
|
|
33218
|
+
}
|
|
33219
|
+
});
|
|
33220
|
+
}
|
|
33119
33221
|
const supervisor = getSupervisor(env, scope);
|
|
33120
33222
|
const requestedOrigin = request.headers.get("origin");
|
|
33121
33223
|
if (route.operation === "mcp")
|
|
@@ -33212,6 +33314,7 @@ var runtime_default = {
|
|
|
33212
33314
|
status: out.status,
|
|
33213
33315
|
headers: {
|
|
33214
33316
|
"cache-control": "no-store",
|
|
33317
|
+
...route.operation === "mcp" && scope && out.status === 401 && mcpMetadata(env, scope) ? { "www-authenticate": mcpChallenge(env, scope) } : {},
|
|
33215
33318
|
...origin ? { "access-control-allow-origin": origin, vary: "Origin" } : {}
|
|
33216
33319
|
}
|
|
33217
33320
|
});
|
package/dist/sdk/protocol.d.ts
CHANGED
|
@@ -37,6 +37,8 @@ export declare function boundedJson(value: unknown, maxBytes: number): string;
|
|
|
37
37
|
export type McpTool = {
|
|
38
38
|
name: string;
|
|
39
39
|
description: string;
|
|
40
|
+
/** A reviewed action may be read-only even though it performs external I/O. Not an authorization grant. */
|
|
41
|
+
readOnly?: boolean;
|
|
40
42
|
};
|
|
41
43
|
export declare function assertMcpTools(functions: Record<string, FunctionContract>): void;
|
|
42
44
|
export interface FunctionContract {
|
package/dist/sdk/protocol.js
CHANGED
|
@@ -80,7 +80,7 @@ export function assertMcpTools(functions) {
|
|
|
80
80
|
if (fn.mcp === undefined)
|
|
81
81
|
continue;
|
|
82
82
|
const m = fn.mcp;
|
|
83
|
-
if (!m || typeof m !== "object" || Object.keys(m).
|
|
83
|
+
if (!m || typeof m !== "object" || Object.keys(m).some((key) => !["name", "description", "readOnly"].includes(key)) || m.readOnly !== undefined && typeof m.readOnly !== "boolean" || fn.kind === "mutation" && m.readOnly === true || fn.kind === "query" && m.readOnly === false || typeof m.name !== "string" || !/^[A-Za-z][A-Za-z0-9_.-]{0,63}$/.test(m.name) || typeof m.description !== "string" || !m.description.trim() || m.description.length > 1000 || names.has(m.name) || fn.auth === "internal" || fn.input.type !== "object")
|
|
84
84
|
throw new FlareError("INVALID_CONTRACT", "Invalid MCP tool contract");
|
|
85
85
|
boundedJson({ mcp: m, input: fn.input }, 16384);
|
|
86
86
|
names.add(m.name);
|