@jxsuite/server 0.35.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jxsuite/server",
3
- "version": "0.35.0",
3
+ "version": "0.36.0",
4
4
  "description": "Jx development server with live reload, server-side proxy, and studio integration",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,13 +31,13 @@
31
31
  "test:coverage": "bun test --isolate --coverage"
32
32
  },
33
33
  "dependencies": {
34
- "@jxsuite/compiler": "^0.34.1",
35
- "@jxsuite/create": "^0.35.0",
36
- "@jxsuite/import": "^0.35.0",
37
- "@jxsuite/parser": "^0.35.0",
38
- "@jxsuite/runtime": "^0.34.1",
39
- "@jxsuite/schema": "^0.34.0",
40
- "@jxsuite/starters": "^0.35.0",
34
+ "@jxsuite/compiler": "^0.35.0",
35
+ "@jxsuite/create": "^0.36.0",
36
+ "@jxsuite/import": "^0.35.1",
37
+ "@jxsuite/parser": "^0.35.1",
38
+ "@jxsuite/runtime": "^0.34.2",
39
+ "@jxsuite/schema": "^0.35.0",
40
+ "@jxsuite/starters": "^0.35.1",
41
41
  "chokidar": "^5.0.0",
42
42
  "zod": "^4.4.3"
43
43
  }
package/src/ai-api.ts CHANGED
@@ -385,7 +385,7 @@ export async function handleModels(req: Request): Promise<Response> {
385
385
  { id: "gpt-4o-mini", name: "GPT-4o Mini", contextWindow: 128_000 },
386
386
  ];
387
387
  return Response.json(
388
- { models: defaults, configured: false },
388
+ { models: defaults, configured: false, managed: false },
389
389
  {
390
390
  headers: { "Content-Type": "application/json" },
391
391
  },
@@ -403,7 +403,7 @@ export async function handleModels(req: Request): Promise<Response> {
403
403
  // Upstream failed — return defaults with configured flag so user can still try.
404
404
  const defaults = [{ id: "gpt-4o", name: "GPT-4o", contextWindow: 128_000 }];
405
405
  return Response.json(
406
- { models: defaults, configured: true, upstreamError: upstreamResp.status },
406
+ { models: defaults, configured: true, managed: false, upstreamError: upstreamResp.status },
407
407
  {
408
408
  headers: { "Content-Type": "application/json" },
409
409
  },
@@ -426,7 +426,7 @@ export async function handleModels(req: Request): Promise<Response> {
426
426
  }));
427
427
 
428
428
  return Response.json(
429
- { models, configured: true },
429
+ { models, configured: true, managed: false },
430
430
  {
431
431
  headers: { "Content-Type": "application/json" },
432
432
  },
@@ -435,7 +435,7 @@ export async function handleModels(req: Request): Promise<Response> {
435
435
  // Network error → return defaults.
436
436
  const defaults = [{ id: "gpt-4o", name: "GPT-4o", contextWindow: 128_000 }];
437
437
  return Response.json(
438
- { models: defaults, configured: true, upstreamError: "network" },
438
+ { models: defaults, configured: true, managed: false, upstreamError: "network" },
439
439
  {
440
440
  headers: { "Content-Type": "application/json" },
441
441
  },
package/src/studio-api.ts CHANGED
@@ -1072,6 +1072,46 @@ export async function handleStudioApi(
1072
1072
  }
1073
1073
 
1074
1074
  // Discover a plugin module's schema for studio form rendering
1075
+ /* Cloudflare API passthrough — the backend of the publish surface's `cfApi`.
1076
+ Stateless: the credential arrives per-request in X-CF-Token (the user's
1077
+ pasted API token, kept client-side) and is never stored. Only account
1078
+ listing and Pages project/deployment paths are reachable. */
1079
+ if (path === "/__studio/cf/proxy" && req.method === "POST") {
1080
+ const CF_PROXY_ALLOWLIST = [
1081
+ /^\/accounts$/,
1082
+ /^\/accounts\/[0-9a-f]{32}\/pages\/projects(?:\/[\w-]+)?$/,
1083
+ /^\/accounts\/[0-9a-f]{32}\/pages\/projects\/[\w-]+\/deployments(?:\/[\w-]+)?$/,
1084
+ /^\/accounts\/[0-9a-f]{32}\/pages\/projects\/[\w-]+\/deployments\/[\w-]+\/retry$/,
1085
+ ];
1086
+ const cfToken = req.headers.get("X-CF-Token");
1087
+ if (!cfToken) {
1088
+ return Response.json({ error: "Missing X-CF-Token header" }, { status: 401 });
1089
+ }
1090
+ let payload: { path?: string; method?: string; body?: unknown };
1091
+ try {
1092
+ payload = (await req.json()) as typeof payload;
1093
+ } catch {
1094
+ return Response.json({ error: "Invalid JSON body" }, { status: 400 });
1095
+ }
1096
+ const apiPath = payload.path ?? "";
1097
+ if (!CF_PROXY_ALLOWLIST.some((re) => re.test(apiPath))) {
1098
+ return Response.json({ error: `Path not allowed: ${apiPath}` }, { status: 403 });
1099
+ }
1100
+ const method = payload.method ?? "GET";
1101
+ const upstream = await fetch(`https://api.cloudflare.com/client/v4${apiPath}`, {
1102
+ method,
1103
+ headers: {
1104
+ Authorization: `Bearer ${cfToken}`,
1105
+ ...(payload.body === undefined ? {} : { "Content-Type": "application/json" }),
1106
+ },
1107
+ ...(payload.body === undefined ? {} : { body: JSON.stringify(payload.body) }),
1108
+ });
1109
+ return new Response(upstream.body, {
1110
+ headers: { "Content-Type": upstream.headers.get("Content-Type") ?? "application/json" },
1111
+ status: upstream.status,
1112
+ });
1113
+ }
1114
+
1075
1115
  // Format capability proxy — studio fallback for capabilities whose timing excludes "client".
1076
1116
  // Dispatches parse/serialize through the project's format registry by import name.
1077
1117
  if (path === "/__studio/format" && req.method === "POST") {