@auersperg/flare 0.3.10 → 0.3.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/cli/{chunk-m0698kap.js → chunk-1yvbecac.js} +88 -5
  2. package/dist/cli/{chunk-znktbexz.js → chunk-7ym0f672.js} +6 -6
  3. package/dist/cli/{chunk-jrptpjmm.js → chunk-8gzfscca.js} +5 -7
  4. package/dist/cli/chunk-xn3e3gev.js +9 -0
  5. package/dist/cli/{chunk-zt96ghm7.js → chunk-yhvbksrm.js} +20 -1
  6. package/dist/cli/flare.js +4 -4
  7. package/dist/platform/admin.js +5 -2
  8. package/dist/platform/dashboard/_astro/ai-view.De8j8CVD.js +1 -0
  9. package/dist/platform/dashboard/_astro/{auth-view.BhUFPmNv.js → auth-view.C9j0-OzH.js} +1 -1
  10. package/dist/platform/dashboard/_astro/client.BvQ8bQkQ.js +4 -0
  11. package/dist/platform/dashboard/_astro/{data-view.C-VU8Oxm.js → data-view.Bw2dG8Wg.js} +1 -1
  12. package/dist/platform/dashboard/_astro/{functions-view.3yLrtS0h.js → functions-view.Bsazyfej.js} +1 -1
  13. package/dist/platform/dashboard/_astro/index.CDrYoVkO.css +2 -0
  14. package/dist/platform/dashboard/_astro/index.astro_astro_type_script_index_0_lang.C_U84Sz-.js +3 -0
  15. package/dist/platform/dashboard/_astro/input-group.Dsc4z0iT.js +1 -0
  16. package/dist/platform/dashboard/_astro/{sdk-view.BAiQKNm8.js → sdk-view.vdDnLZ5g.js} +1 -1
  17. package/dist/platform/dashboard/_astro/{services-view.BSrqpyr5.js → services-view.C1FjN8NY.js} +1 -1
  18. package/dist/platform/dashboard/_astro/{settings-view.C_eYjlIE.js → settings-view.DZldw4Vy.js} +1 -1
  19. package/dist/platform/dashboard/bootstrap/action.js +43 -0
  20. package/dist/platform/dashboard/bootstrap/openapi.json +1 -1
  21. package/dist/platform/dashboard/bootstrap/release.json +2 -2
  22. package/dist/platform/dashboard/index.html +1 -1
  23. package/dist/platform/manifest.json +43 -38
  24. package/dist/platform/runtime.js +24294 -836
  25. package/dist/sdk/client.d.ts +6 -0
  26. package/dist/sdk/client.js +29 -0
  27. package/dist/sdk/cloudflare.d.ts +4 -0
  28. package/dist/sdk/cloudflare.js +4 -0
  29. package/dist/sdk/codex-stream.d.ts +28 -0
  30. package/dist/sdk/codex-stream.js +147 -0
  31. package/dist/sdk/codex.d.ts +20 -0
  32. package/dist/sdk/codex.js +17 -0
  33. package/dist/sdk/protocol.d.ts +6 -0
  34. package/dist/sdk/protocol.js +12 -0
  35. package/dist/sdk/react.d.ts +4 -0
  36. package/dist/sdk/search.d.ts +25 -0
  37. package/dist/sdk/search.js +22 -0
  38. package/dist/sdk/server.d.ts +15 -1
  39. package/dist/sdk/server.js +9 -1
  40. package/package.json +1 -1
  41. package/dist/platform/dashboard/_astro/client.4z54xJ_z.js +0 -1
  42. package/dist/platform/dashboard/_astro/index.BPQdjJ4j.css +0 -2
  43. package/dist/platform/dashboard/_astro/index.astro_astro_type_script_index_0_lang.Dsfj1oeZ.js +0 -3
  44. package/dist/platform/dashboard/_astro/input-group.BZ1TZT7L.js +0 -1
@@ -1,4 +1,8 @@
1
1
  // @bun
2
+ import {
3
+ storedToken2
4
+ } from "./chunk-8gzfscca.js";
5
+
2
6
  // packages/flare/src/cli/platform.mjs
3
7
  import { readFile as readFile4, mkdir as mkdir2, mkdtemp, writeFile as writeFile2, rm, cp } from "fs/promises";
4
8
  import { join as join3 } from "path";
@@ -293,8 +297,8 @@ import { randomUUID } from "crypto";
293
297
  import { readFile as readFile2 } from "fs/promises";
294
298
  function validatePlatformConfig(value = {}) {
295
299
  const object = (v) => v && typeof v === "object" && !Array.isArray(v);
296
- if (!object(value) || Object.keys(value).some((k) => !["capabilities", "secrets"].includes(k)))
297
- throw Error("Platform config accepts only capabilities and secrets references");
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 codex references");
298
302
  const capabilities = value.capabilities ?? {}, secrets = value.secrets ?? [];
299
303
  if (!object(capabilities) || !Array.isArray(secrets) || secrets.length > 64)
300
304
  throw Error("Invalid platform capabilities/secrets references");
@@ -309,11 +313,37 @@ function validatePlatformConfig(value = {}) {
309
313
  secret_name: r.secret_name
310
314
  };
311
315
  }).sort((a, b) => a.binding.localeCompare(b.binding));
316
+ const search = value.search ?? [];
317
+ if (!Array.isArray(search) || search.length > 64)
318
+ throw Error("Invalid search references");
319
+ const searchNames = new Set, instances = new Set;
320
+ const searchReferences = search.map((r) => {
321
+ if (!object(r) || Object.keys(r).sort().join() !== "binding,instance_name,scope" || !/^APP_SEARCH_[A-Z0-9_]{1,64}$/.test(r.binding) || typeof r.instance_name !== "string" || r.instance_name.length > 64 || !/^[a-z0-9_]+(?:-[a-z0-9_]+)*$/.test(r.instance_name) || !/^[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) || searchNames.has(r.binding) || instances.has(r.instance_name))
322
+ throw Error("Invalid or duplicate native search reference");
323
+ searchNames.add(r.binding);
324
+ instances.add(r.instance_name);
325
+ return {
326
+ binding: r.binding,
327
+ instance_name: r.instance_name,
328
+ scope: r.scope
329
+ };
330
+ }).sort((a, b) => a.binding.localeCompare(b.binding));
331
+ const codex = value.codex ?? [];
332
+ if (!Array.isArray(codex) || codex.length > 16)
333
+ throw Error("Invalid Codex references");
334
+ const codexBindings = new Set, codexServices = new Set;
335
+ const codexReferences = codex.map((r) => {
336
+ if (!object(r) || Object.keys(r).sort().join() !== "binding,scope,service" || !/^APP_CODEX_[A-Z0-9_]{1,64}$/.test(r.binding) || typeof r.service !== "string" || !/^[a-z0-9][a-z0-9-]{0,62}$/.test(r.service) || typeof r.scope !== "string" || !/^[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) || codexBindings.has(r.binding) || codexServices.has(r.service))
337
+ throw Error("Invalid or duplicate Codex runner reference");
338
+ codexBindings.add(r.binding);
339
+ codexServices.add(r.service);
340
+ return { binding: r.binding, service: r.service, scope: r.scope };
341
+ }).sort((a, b) => a.binding.localeCompare(b.binding));
312
342
  const result = {};
313
343
  const used = new Set;
314
344
  for (const scope of Object.keys(capabilities).sort()) {
315
345
  const p = capabilities[scope];
316
- 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"].includes(k)))
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)))
317
347
  throw Error("Invalid capability scope");
318
348
  const hosts = p.outbound ?? [], mapping = p.secrets ?? {};
319
349
  if (!Array.isArray(hosts) || hosts.length > 20 || !object(mapping) || Object.keys(mapping).length > 16)
@@ -326,7 +356,13 @@ function validatePlatformConfig(value = {}) {
326
356
  throw Error("Secret grant must reference an explicit APP_SECRET binding");
327
357
  used.add(binding);
328
358
  }
359
+ if (p.search !== undefined && !searchReferences.some((r) => r.binding === p.search && r.scope === scope))
360
+ throw Error("Search grant must reference an instance owned by this environment");
361
+ if (p.codex !== undefined && !codexReferences.some((r) => r.binding === p.codex && r.scope === scope))
362
+ throw Error("Codex grant must reference a runner owned by this environment");
329
363
  result[scope] = {
364
+ ...p.codex === undefined ? {} : { codex: p.codex },
365
+ ...p.search === undefined ? {} : { search: p.search },
330
366
  outbound: [...new Set(hosts)].sort(),
331
367
  secrets: Object.fromEntries(Object.entries(mapping).sort())
332
368
  };
@@ -335,7 +371,12 @@ function validatePlatformConfig(value = {}) {
335
371
  throw Error("Unused secret binding; grant it explicitly or remove it");
336
372
  if (JSON.stringify(result).length > 16384)
337
373
  throw Error("Capabilities exceed 16 KiB");
338
- return { capabilities: result, secrets: references };
374
+ return {
375
+ capabilities: result,
376
+ secrets: references,
377
+ ...codexReferences.length ? { codex: codexReferences } : {},
378
+ ...searchReferences.length ? { search: searchReferences } : {}
379
+ };
339
380
  }
340
381
  async function readPlatformConfig(path) {
341
382
  const bytes = await readFile2(path);
@@ -361,6 +402,19 @@ async function accessSnapshot(cf, id) {
361
402
  digest: configurationDigest(accessConfiguration(app, policies))
362
403
  };
363
404
  }
405
+ async function validateSearchTransition(previous, next, inspect) {
406
+ const old = validatePlatformConfig(previous), desired = validatePlatformConfig(next);
407
+ for (const ref of old.search ?? []) {
408
+ const retained = desired.search?.find((r) => r.binding === ref.binding);
409
+ if (retained && JSON.stringify(retained) === JSON.stringify(ref))
410
+ continue;
411
+ if (old.capabilities[ref.scope]?.search === ref.binding)
412
+ throw Error("Disable the search grant first, keeping its reference for durable cleanup");
413
+ const state = await inspect(ref.scope);
414
+ if (state?.search?.remaining !== 0)
415
+ throw Error("Search cleanup is pending; keep the old binding and retry after cleanup");
416
+ }
417
+ }
364
418
 
365
419
  // packages/flare/src/cli/platform-state.mjs
366
420
  var leaseMilliseconds = 15 * 60 * 1000;
@@ -831,7 +885,12 @@ function workerConfiguration(state, release, role, bootstrap = false) {
831
885
  return {
832
886
  ...common,
833
887
  worker_loaders: [{ binding: "LOADER" }],
834
- ...state.config ? { secrets_store_secrets: validatePlatformConfig(state.config).secrets } : {},
888
+ ...state.config ? {
889
+ secrets_store_secrets: validatePlatformConfig(state.config).secrets,
890
+ ...validatePlatformConfig(state.config).search?.length ? {
891
+ ai_search: validatePlatformConfig(state.config).search.map(({ binding, instance_name }) => ({ binding, instance_name }))
892
+ } : {}
893
+ } : {},
835
894
  durable_objects: {
836
895
  bindings: [{ name: "SUPERVISORS", class_name: "EnvironmentSupervisor" }]
837
896
  },
@@ -863,6 +922,11 @@ function workerConfiguration(state, release, role, bootstrap = false) {
863
922
  }
864
923
  ],
865
924
  services: bootstrap ? [] : [
925
+ ...(validatePlatformConfig(state.config).codex ?? []).map(({ binding, service }) => ({
926
+ binding,
927
+ service,
928
+ entrypoint: "CodexService"
929
+ })),
866
930
  {
867
931
  binding: "ADMIN_API",
868
932
  service: state.workers.admin.name,
@@ -1340,6 +1404,25 @@ async function runPlatform(options, dependencies = {}) {
1340
1404
  const configChanged = requestedConfig && configurationDigest(requestedConfig) !== configurationDigest(validatePlatformConfig(state.config));
1341
1405
  if (state.operation && requestedConfig && configurationDigest(requestedConfig) !== state.operation.configDigest)
1342
1406
  throw Error("Pending config differs; resume with the original config or omit --config");
1407
+ if (configChanged && !state.operation)
1408
+ await validateSearchTransition(state.config, requestedConfig, async (scope) => {
1409
+ const [project, environment] = scope.split("/");
1410
+ const environments = await cf.sql(state.resources.catalog.id, "SELECT 1 FROM environments WHERE projectId=? AND env=?", [project, environment]);
1411
+ if (!environments.results.length)
1412
+ return { search: { remaining: 0 } };
1413
+ const platform = "https://" + state.addresses.runtimeHost + "/control";
1414
+ const token = process.env.FLARE_DEPLOY_TOKEN ?? await storedToken2(platform, project);
1415
+ if (!token)
1416
+ throw Error("Sign in to the affected project before removing a search binding");
1417
+ const response = await fetch(`${platform}/api/projects/${project}/${environment}/ai`, {
1418
+ headers: { authorization: `Bearer ${token}` },
1419
+ redirect: "error",
1420
+ signal: AbortSignal.timeout(1e4)
1421
+ });
1422
+ if (!response.ok)
1423
+ throw Error("Cannot verify search cleanup; old binding must be retained");
1424
+ return response.json();
1425
+ });
1343
1426
  let accessChanged = false;
1344
1427
  if (options["accept-access"]) {
1345
1428
  if (!/^[a-f0-9]{64}$/.test(options["accept-access"]) || operation !== "update" || state.operation)
@@ -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-jrptpjmm.js");
29
+ const { storedToken } = await import("./chunk-xn3e3gev.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-zt96ghm7.js");
110
+ const { buildApplication } = await import("./chunk-yhvbksrm.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-jrptpjmm.js");
163
+ const { connect } = await import("./chunk-xn3e3gev.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-jrptpjmm.js");
175
+ const { connect } = await import("./chunk-xn3e3gev.js");
176
176
  await connect();
177
177
  }
178
178
  }
179
- const { buildApplication } = await import("./chunk-zt96ghm7.js");
179
+ const { buildApplication } = await import("./chunk-yhvbksrm.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-zt96ghm7.js");
311
+ const { generateReferences } = await import("./chunk-yhvbksrm.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-"));
@@ -14,7 +14,7 @@ import { createInterface } from "readline/promises";
14
14
  import { spawn } from "child_process";
15
15
  import { setTimeout as sleep } from "timers/promises";
16
16
  var credentialDirectory = () => join(process.env.FLARE_CONFIG_HOME ?? join(homedir(), ".config", "flare"));
17
- async function storedToken(platform, project) {
17
+ async function storedToken2(platform, project) {
18
18
  const key = createHash("sha256").update(platform + "/" + project).digest("hex");
19
19
  const record = JSON.parse(await readFile(join(credentialDirectory(), key + ".json"), "utf8").catch((e) => {
20
20
  if (e.code !== "ENOENT")
@@ -25,7 +25,7 @@ async function storedToken(platform, project) {
25
25
  return record.token;
26
26
  return null;
27
27
  }
28
- async function connect() {
28
+ async function connect2() {
29
29
  if (!process.stdin.isTTY)
30
30
  throw Error("First run needs an interactive terminal: run flare dev to sign in. CI can use FLARE_DEPLOY_TOKEN with a linked project.");
31
31
  let dashboard, platform;
@@ -102,12 +102,10 @@ ${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-znktbexz.js");
105
+ const { link } = await import("./chunk-7ym0f672.js");
106
106
  return link({ platform, project: result.project });
107
107
  }
108
108
  throw Error("Login expired. Run flare dev again.");
109
109
  }
110
- export {
111
- connect,
112
- storedToken
113
- };
110
+
111
+ export { storedToken2, connect2 };
@@ -0,0 +1,9 @@
1
+ // @bun
2
+ import {
3
+ storedToken2,
4
+ connect2
5
+ } from "./chunk-8gzfscca.js";
6
+ export {
7
+ connect2 as connect,
8
+ storedToken2 as storedToken
9
+ };
@@ -74,6 +74,18 @@ function boundedJson(value, maxBytes) {
74
74
  throw new FlareError("TOO_LARGE", "JSON payload exceeds limit");
75
75
  return json;
76
76
  }
77
+ function assertMcpTools(functions) {
78
+ const names = new Set;
79
+ for (const fn of Object.values(functions)) {
80
+ if (fn.mcp === undefined)
81
+ continue;
82
+ const m = fn.mcp;
83
+ if (!m || typeof m !== "object" || Object.keys(m).sort().join() !== "description,name" || 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
+ throw new FlareError("INVALID_CONTRACT", "Invalid MCP tool contract");
85
+ boundedJson({ mcp: m, input: fn.input }, 16384);
86
+ names.add(m.name);
87
+ }
88
+ }
77
89
 
78
90
  // packages/flare/src/sdk/schema.ts
79
91
  function identifier(name) {
@@ -176,8 +188,15 @@ function manifest(app) {
176
188
  });
177
189
  if (!input || !output)
178
190
  throw new FlareError("INVALID_CONTRACT", `${path} requires JSON Schema converters`);
179
- functions[path] = { kind: fn.kind, auth: fn.auth, input, output };
191
+ functions[path] = {
192
+ kind: fn.kind,
193
+ auth: fn.auth,
194
+ input,
195
+ output,
196
+ ...fn.mcp !== undefined ? { mcp: fn.mcp } : {}
197
+ };
180
198
  }
199
+ assertMcpTools(functions);
181
200
  boundedJson(functions, 1048576);
182
201
  return { protocol: 1, runtimeAbi: 4, functions };
183
202
  }
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.10",
6
+ version: "0.3.12",
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-m0698kap.js");
150
+ const { platform } = await import("./chunk-1yvbecac.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-zt96ghm7.js");
190
+ const { buildApplication } = await import("./chunk-yhvbksrm.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-znktbexz.js");
195
+ const cloud = await import("./chunk-7ym0f672.js");
196
196
  const x = await cloud[command](options);
197
197
  if (x)
198
198
  console.log(JSON.stringify(x, null, 2));
@@ -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.10",
312
+ version: "0.3.12",
313
313
  type: "module",
314
314
  license: "MIT",
315
315
  private: true,
@@ -321,7 +321,8 @@ var package_default = {
321
321
  "README.md"
322
322
  ],
323
323
  dependencies: {
324
- agents: "0.28.0"
324
+ agents: "0.28.0",
325
+ "@modelcontextprotocol/server": "2.3.0"
325
326
  },
326
327
  repository: {
327
328
  type: "git",
@@ -668,6 +669,7 @@ async function api(request, env, a) {
668
669
  "schema",
669
670
  "data",
670
671
  "functions",
672
+ "ai",
671
673
  "logs",
672
674
  "history",
673
675
  "jobs",
@@ -739,6 +741,7 @@ async function api(request, env, a) {
739
741
  if ([
740
742
  "file-upload",
741
743
  "file-delete",
744
+ "search-clear",
742
745
  "job-cancel",
743
746
  "cron-set",
744
747
  "cron-cancel"
@@ -0,0 +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.BvQ8bQkQ.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.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Stateless HTTP. Use a client supporting an Authorization: Bearer application-session header. No OAuth discovery. Admin, deploy and dev tokens are not accepted. Logout, expiry and disabling the user revoke access.`}),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.Dsfj1oeZ.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
+ 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.C_U84Sz-.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};
@@ -0,0 +1,4 @@
1
+ var e=Object.freeze({inputBytes:65536,outputBytes:262144,frameBytes:8192,subscriptions:64,fileBytes:10485760}),t=class extends Error{code;ambiguous;constructor(e,t,n=!1){super(t),this.code=e,this.ambiguous=n,this.name=`FlareError`}};function n(e){if(e.length>256||!/^[A-Za-z][A-Za-z0-9_]*(\/[A-Za-z][A-Za-z0-9_]*)*$/.test(e)||e.split(`/`).some(e=>[`__proto__`,`prototype`,`constructor`].includes(e)))throw new t(`INVALID_PATH`,`Invalid function path`)}function r(e,t){return n(e),Object.freeze({path:e,kind:t})}function i(e){let n=new Set;function r(e,i){if(i>40)throw new t(`INVALID_JSON`,`JSON nesting limit exceeded`);if(e===null||typeof e==`string`||typeof e==`boolean`||typeof e==`number`&&Number.isFinite(e))return e;if(typeof e!=`object`||!e||n.has(e))throw new t(`INVALID_JSON`,`Expected lossless JSON`);if(!Array.isArray(e)&&Object.getPrototypeOf(e)!==Object.prototype&&Object.getPrototypeOf(e)!==null)throw new t(`INVALID_JSON`,`Expected plain JSON object`);if(Object.getOwnPropertySymbols(e).length)throw new t(`INVALID_JSON`,`Symbol keys are unsupported`);n.add(e);let a;if(Array.isArray(e))a=Array.from(e,e=>r(e,i+1));else{let n=Object.create(null);for(let a of Object.keys(e).sort()){let o=Object.getOwnPropertyDescriptor(e,a);if(!(`value`in o))throw new t(`INVALID_JSON`,`Getters are unsupported`);n[a]=r(o.value,i+1)}a=n}return n.delete(e),a}return JSON.stringify(r(e,0))}function a(e,n){let r=i(e);if(new TextEncoder().encode(r).byteLength>n)throw new t(`TOO_LARGE`,`JSON payload exceeds limit`);return r}async function o(e,t,n){let r=e.getReader(),i=[],a=0;try{for(;;){let{done:e,value:o}=await r.read();if(e)break;a+=o.byteLength,a>t&&n(),i.push(o)}}finally{await r.cancel().catch(()=>{})}if(i.length===1)return i[0];let o=new Uint8Array(a),s=0;for(let e of i)o.set(e,s),s+=e.byteLength;return o}async function*s(n){if(n.ref.kind!==`query`)throw new t(`INVALID_KIND`,`Stream authorization must be a read-only query`);let r=n.after??0,i=0;if(!Number.isSafeInteger(r)||r<0||r>4096)throw new t(`INVALID_ARGUMENT`,`Invalid cursor`);let s=n.signal;for(;!s.aborted;){let c,l=new AbortController,u=()=>l.abort(s.reason);s.addEventListener(`abort`,u,{once:!0}),s.aborted&&u();let d,f=()=>{clearTimeout(d),d=setTimeout(()=>l.abort(),45e3)};try{f();let u=await n.token();if(s.aborted)return;let d=await n.transport(n.url,{method:`POST`,redirect:`error`,signal:l.signal,headers:{"Content-Type":`application/json`,...u?{Authorization:`Bearer ${u}`}:{}},body:a({path:n.ref.path,kind:`query`,args:n.args,after:r},e.inputBytes)});if(!d.ok){let e=d.body?await o(d.body,8192,()=>{throw new t(`INVALID_RESPONSE`,`Oversized error`)}):new Uint8Array,n=`HTTP_${d.status}`;try{let t=JSON.parse(new TextDecoder().decode(e));/^[A-Z][A-Z0-9_]{0,63}$/.test(t.error)&&(n=t.error)}catch{}throw new t(n,`Event subscription failed`)}if(!d.headers.get(`content-type`)?.startsWith(`text/event-stream`)||!d.body)throw new t(`INVALID_RESPONSE`,`Expected SSE`);c=d.body.getReader();let p=new TextDecoder(`utf-8`,{fatal:!0}),m=``,h=0;for(;!s.aborted;){let e=await c.read();if(e.done)break;if(f(),h+=e.value.byteLength,h>1048576)throw new t(`INVALID_RESPONSE`,`Stream exceeds bound`);m+=p.decode(e.value,{stream:!0});let n;for(;(n=m.indexOf(`
2
+
3
+ `))>=0;){let e=m.slice(0,n);if(m=m.slice(n+2),e.length>524288)throw new t(`INVALID_RESPONSE`,`Oversized event`);let a=``,o=``,s=``;for(let t of e.split(`
4
+ `))t.startsWith(`event:`)&&(a=t.slice(6).trim()),t.startsWith(`data:`)&&(o+=t.slice(5).trimStart()),t.startsWith(`id:`)&&(s=t.slice(3).trim());if(!o||a===`reconnect`)continue;let c=JSON.parse(o);if(a===`task`){if(!c||typeof c.id!=`string`||![`succeeded`,`failed`,`cancelled`,`interrupted`].includes(c.state))throw new t(`INVALID_RESPONSE`,`Invalid task`);yield{type:`task`,task:c};return}if(a!==`progress`||!Number.isSafeInteger(c.seq)||String(c.seq)!==s||c.seq>4096||![`status`,`text`,`output`,`item`,`truncated`].includes(c.type))throw new t(`INVALID_RESPONSE`,`Invalid event`);if(!(c.seq<=r)){if(c.seq!==r+1)throw new t(`CODEX_EVENT_GAP`,`Event gap`);r=c.seq,i=0,yield c}}if(m.length>524288)throw new t(`INVALID_RESPONSE`,`Oversized frame`)}}catch(e){if(s.aborted)return;let n=e instanceof t?e.code:``;if(n&&![`HTTP_429`,`HTTP_500`,`HTTP_502`,`HTTP_503`,`HTTP_504`,`CODEX_UNAVAILABLE`].includes(n))throw e;if(++i>5)throw new t(`CODEX_STREAM_INTERRUPTED`,`Reconnect failed; task continues independently`)}finally{clearTimeout(d),s.removeEventListener(`abort`,u),l.abort(),await c?.cancel().catch(()=>{})}if(s.aborted)return;await new Promise(e=>{let t=()=>{clearTimeout(n),s.removeEventListener(`abort`,t),e()},n=setTimeout(t,Math.min(5e3,500*2**i));s.addEventListener(`abort`,t,{once:!0})})}}function c(n){if(n.size>e.fileBytes)throw new t(`TOO_LARGE`,`Maximum file size: 10 MiB`);if(!n.name||n.name.length>120||/[\x00-\x1f\x7f/\\]/.test(n.name))throw new t(`INVALID_INPUT`,`File name must be 1–120 characters, without path separators`);return{name:n.name,size:n.size,type:[`text/plain`,`image/png`,`image/jpeg`,`image/webp`,`application/pdf`].includes(n.type)?n.type:`application/octet-stream`}}async function l(n,r,i={}){if(r.size>e.fileBytes)throw new t(`TOO_LARGE`,`Maximum file size: 10 MiB`);let a=new URL(n.url);if(a.username||a.password||a.protocol!==`https:`&&!(a.protocol===`http:`&&[`localhost`,`127.0.0.1`,`[::1]`].includes(a.hostname)))throw new t(`INVALID_URL`,`Expected secure upload URL`);let s;try{s=await(i.fetch??globalThis.fetch)(a.href,{method:`POST`,body:r,redirect:`error`,credentials:`omit`,signal:AbortSignal.any([...i.signal?[i.signal]:[],AbortSignal.timeout(i.timeoutMs??12e4)])})}catch{throw new t(`UPLOAD_UNKNOWN`,`Connection interrupted or upload timed out; refresh the file list before trying again`,!0)}let c=s.body?await o(s.body,e.outputBytes,()=>{throw Error(`Upload response exceeds limit`)}).then(e=>JSON.parse(new TextDecoder(`utf-8`,{fatal:!0}).decode(e))).catch(()=>null):null;if(!s.ok){let e=c&&typeof c==`object`&&`error`in c&&typeof c.error==`string`?c.error:`HTTP_${s.status}`;throw new t(e,`Upload failed: ${e}`,s.status>=500)}if(!c||typeof c!=`object`||!(`id`in c)||typeof c.id!=`string`)throw new t(`INVALID_RESPONSE`,`Upload outcome is unknown; refresh the file list before uploading again`,!0);return{id:c.id}}var u=new Set([`UNAUTHORIZED`,`AUTH_EXPIRED`,`FORBIDDEN`,`AUTH_DISABLED`,`HTTP_401`,`HTTP_403`]);function d(r){let c=new URL(r.url);if(!/^https?:$/.test(c.protocol)||c.username||c.password||c.search||c.hash)throw new t(`INVALID_URL`,`Expected backend HTTP URL`);if(c.protocol===`http:`&&![`localhost`,`127.0.0.1`,`[::1]`].includes(c.hostname))throw new t(`INVALID_URL`,`Remote backends require HTTPS`);c.pathname=c.pathname.replace(/\/$/,``);let l=r.fetch??globalThis.fetch;if(!l)throw new t(`TRANSPORT_UNAVAILABLE`,`Provide a fetch implementation`);let d=new Map,f=!1,p,m=!1,h=0,g=0,_=0,v,y=new Set,b=e=>`${c.href.replace(/\/$/,``)}${e}`,x=(e,t,n)=>{for(let r of e.observers)try{r[t]?.(t===`next`?JSON.parse(n):n)}catch{}};function S(){if(f)throw new t(`DISPOSED`,`Client is disposed`)}async function C(n,i,s){S();let c=a(i,e.inputBytes),u;try{u=await r.getToken?.()??null}catch{throw new t(`AUTH_UNAVAILABLE`,`Cannot obtain access token`)}S();let d=new AbortController,f=setTimeout(()=>d.abort(),r.requestTimeoutMs??3e4);try{let r=await l(b(n),{method:`POST`,headers:{"Content-Type":`application/json`,...u?{Authorization:`Bearer ${u}`}:{}},body:c,signal:d.signal,redirect:`error`});if(!r.body)throw new t(`INVALID_RESPONSE`,`Missing response body`,s);let i=await o(r.body,e.outputBytes,()=>{throw new t(`INVALID_RESPONSE`,`Response exceeds limit`,s)}),f;try{f=JSON.parse(new TextDecoder(`utf-8`,{fatal:!0}).decode(i))}catch(e){throw r.ok?e:new t(`HTTP_${r.status}`,`Backend request failed`,s&&r.status>=500)}if(!r.ok)throw new t(f&&typeof f==`object`&&`error`in f&&typeof f.error==`string`&&/^[A-Z][A-Z0-9_]{0,63}$/.test(f.error)?f.error:`HTTP_${r.status}`,`Backend request failed`,s&&r.status>=500);if(!f||typeof f!=`object`||!(`result`in f))throw new t(`INVALID_RESPONSE`,`Invalid protocol envelope`,s);return a(f.result,e.outputBytes),f.result}catch(e){throw e instanceof t?e:e instanceof SyntaxError?new t(`INVALID_RESPONSE`,`Invalid JSON response`,s):new t(`TRANSPORT_ERROR`,s?`Write outcome is unknown; do not replay automatically`:`Backend request interrupted`,s)}finally{clearTimeout(f)}}function w(t){p?.send(a(t,e.frameBytes))}function T(e){w({type:`subscribe`,id:e.id,path:e.ref.path,args:e.args})}function E(){if(f||!d.size||v)return;let e=Math.min(3e4,250*2**Math.min(h++,7));v=setTimeout(()=>{v=void 0,D()},e)}async function D(){if(f||m||p||!d.size)return;m=!0;let n=++g;try{let i=await C(`/v1/live/ticket`,{},!1);if(f||n!==g||!d.size)return;if(!i||typeof i.ticket!=`string`||i.ticket.length>1024)throw new t(`INVALID_RESPONSE`,`Invalid live ticket`);let o=new URL(b(`/v1/live`));o.protocol=o.protocol===`https:`?`wss:`:`ws:`,o.searchParams.set(`ticket`,i.ticket);let s=r.createWebSocket?r.createWebSocket(o.href):new globalThis.WebSocket(o.href);p=s;let c=()=>{if(!(p!==s||f)){h=0;for(let e of d.values())e.revision=-1,e.snapshot=void 0,e.terminal||T(e)}},l=n=>{if(!(p!==s||f))try{if(typeof n.data!=`string`||new TextEncoder().encode(n.data).byteLength>e.outputBytes+1024)throw Error(`Invalid frame`);let r=JSON.parse(n.data);if(r.type===`ready`)return;let i=[...d.values()].find(e=>e.id===r.id);if(!i||i.terminal)return;if(r.type===`error`){i.terminal=!0,u.has(r.code)&&(i.snapshot=void 0),x(i,`error`,new t(typeof r.code==`string`?r.code:`LIVE_ERROR`,`Live subscription failed`));return}if(r.type!==`snapshot`||!Number.isSafeInteger(r.revision)||r.revision<0||!(`result`in r))throw Error(`Invalid snapshot`);let o=a(r.result,e.outputBytes);if(r.revision>i.revision){let e=i.snapshot!==o;i.revision=r.revision,i.snapshot=o,e&&x(i,`next`,i.snapshot)}w({type:`ack`,id:i.id,revision:i.revision})}catch{s.close(1002,`Invalid protocol frame`)}},m=e=>{if(v(),p===s){p=void 0;for(let n of d.values())e.code===1008&&(n.snapshot=void 0,n.revision=-1),n.terminal||x(n,`error`,new t(e.code===1008?`AUTH_EXPIRED`:`LIVE_DISCONNECTED`,`Live reconnecting; next snapshot will be current`));E()}},_=()=>s.close(),v=()=>{s.removeEventListener(`open`,c),s.removeEventListener(`message`,l),s.removeEventListener(`close`,m),s.removeEventListener(`error`,_),y.delete(v)};y.add(v),s.addEventListener(`open`,c),s.addEventListener(`message`,l),s.addEventListener(`close`,m),s.addEventListener(`error`,_)}catch(e){if(f||n!==g)return;for(let n of d.values())e instanceof t&&u.has(e.code)&&(n.snapshot=void 0,n.revision=-1),x(n,`error`,e instanceof t?e:new t(`LIVE_UNAVAILABLE`,`Live connection failed`));E()}finally{m=!1,!f&&n!==g&&!p&&d.size&&E()}}function O(e){return async(r,i)=>{if(n(r.path),r.kind!==e)throw new t(`INVALID_KIND`,`Expected a ${e} function`);return C(`/v1/call`,{path:r.path,kind:r.kind,args:i},r.kind===`mutation`||r.kind===`action`)}}return{query:O(`query`),mutation:O(`mutation`),action:O(`action`),async*codexEvents(e,t,i={}){S(),n(e.path);let a=new AbortController,o=()=>a.abort();y.add(o),i.signal?.addEventListener(`abort`,o,{once:!0}),i.signal?.aborted&&o();try{yield*s({url:b(`/v1/codex/events`),ref:e,args:t,after:i.after,transport:l,signal:a.signal,token:async()=>(S(),await r.getToken?.()??null)})}finally{o(),y.delete(o),i.signal?.removeEventListener(`abort`,o)}},onUpdate(r,o,s,c){let l={next:s,error:c};if(S(),n(r.path),r.kind!==`query`)throw new t(`INVALID_KIND`,`Only queries are subscribable`);a({type:`subscribe`,id:`subscription-9999999999`,path:r.path,args:o},e.frameBytes);let u=i({path:r.path,args:o}),f=d.get(u);if(!f){if(d.size>=e.subscriptions)throw new t(`TOO_MANY_SUBSCRIPTIONS`,`Subscription limit exceeded`);f={id:`subscription-${++_}`,ref:r,args:JSON.parse(i(o)),observers:new Set,revision:-1,terminal:!1},d.set(u,f),p?.readyState===1&&T(f)}let m={next:l.next,error:l.error};f.observers.add(m),f.snapshot!==void 0&&x({...f,observers:new Set([l])},`next`,f.snapshot),D();let h=!1;return()=>{if(!h&&(h=!0,f.observers.delete(m),f.observers.size||(d.delete(u),p?.readyState===1&&w({type:`unsubscribe`,id:f.id})),!d.size)){++g,v&&clearTimeout(v),v=void 0;let e=p;p=void 0;for(let e of[...y])e();e?.close(1e3,`No subscriptions`)}}},refreshAuth(){S(),++g,v&&clearTimeout(v),v=void 0;for(let e of[...y])e();let e=p;p=void 0,e?.close(1e3,`Authorization changed`);for(let e of d.values())e.snapshot=void 0,e.revision=-1,e.terminal=!1,x(e,`error`,new t(`AUTH_CHANGED`,`Authorization changed; cached value invalidated`));D()},dispose(){if(!f){f=!0,++g,v&&clearTimeout(v),v=void 0;for(let e of[...y])e();d.clear(),p?.close(1e3,`Disposed`),p=void 0}}}}export{r as i,c as n,l as r,d as t};
@@ -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{i as b,n as x,r as S,t as C}from"./input-group.BZ1TZT7L.js";import{f as w,m as T,p as E,s as D}from"./index.astro_astro_type_script_index_0_lang.Dsfj1oeZ.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)(C,{children:[(0,j.jsx)(x,{children:(0,j.jsx)(b,{})}),(0,j.jsx)(S,{"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)(T,{}),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,S]=(0,A.useState)(),C=l(e,t),T=g(C+`/data?table=`+encodeURIComponent(r)+(c===void 0?``:`&cursor=`+encodeURIComponent(c))),O=T.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);S({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(C+`/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}),T.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)(D,{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:T.loading,onClick:T.refresh,children:(0,j.jsx)(w,{})}),P&&(0,j.jsxs)(m,{disabled:!O||T.loading,onClick:()=>F(`insert`),children:[(0,j.jsx)(E,{}),`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,{...T}),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:T.loading,children:`Edit`}),(0,j.jsx)(m,{size:`xs`,variant:`destructive`,onClick:()=>F(`delete`,e),disabled:T.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||T.loading,onClick:()=>b(void 0),children:`First page`}),(0,j.jsxs)(m,{variant:`outline`,disabled:O.next===null||T.loading,onClick:()=>b(O.next??void 0),children:[`Next page`,(0,j.jsx)(k,{})]})]})]})]}),x&&(0,j.jsx)(o,{modal:x,onClose:()=>S(void 0)})]})}export{M as columnFields,N as default};
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.C_U84Sz-.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};
@@ -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{i as g,n as _,r as v,t as y}from"./input-group.BZ1TZT7L.js";import{a as b,c as x,d as S,h as C,l as w,o as T,u as E}from"./index.astro_astro_type_script_index_0_lang.Dsfj1oeZ.js";import{i as D,t as O}from"./client.4z54xJ_z.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)(y,{children:[(0,P.jsx)(_,{children:(0,P.jsx)(g,{})}),(0,P.jsx)(v,{"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)(b,{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),g=I(t,n.role,m.kind)&&m.auth!==`internal`,[_,v]=(0,N.useState)(!1),[y,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)(b,{kind:m.kind}),(0,P.jsx)(T,{status:m.auth,children:m.auth===`required`?`Authentication required`:m.auth})]}),(0,P.jsxs)(f,{type:`submit`,form:`function-run`,disabled:!g||_,children:[(0,P.jsx)(M,{}),_?`Running…`:`Run Function`]})]}),(0,P.jsxs)(x,{defaultValue:`runner`,children:[(0,P.jsxs)(E,{variant:`line`,className:`mx-4 mt-4`,children:[(0,P.jsx)(S,{value:`runner`,children:`Function runner`}),(0,P.jsx)(S,{value:`contract`,children:`Contract`})]}),(0,P.jsx)(w,{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(),!g||_||H.current)return;let i=new AbortController;H.current=i,v(!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=O({url:s.url,getToken:()=>s.token});let l=performance.now(),u=await V.current[m.kind](D(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&&v(!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:_?`Running…`:y?`Failed`:R===void 0?`Not executed`:`Completed · ${R} ms round trip`})]}),y?(0,P.jsx)(p,{children:y}):F?(0,P.jsx)(i,{value:A}):(0,P.jsx)(u,{title:`Run this function to see its result`,children:(0,P.jsx)(C,{className:`mx-auto mt-3 size-7`})})]})]})}),(0,P.jsxs)(w,{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
+ 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.C_U84Sz-.js";import{i as w,t as T}from"./client.BvQ8bQkQ.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};