@auersperg/flare 0.3.2 → 0.3.4

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 (52) hide show
  1. package/README.md +10 -4
  2. package/dist/cli/{chunk-x14smx1y.js → chunk-5s6zv1h9.js} +1 -1
  3. package/dist/cli/chunk-5tjevcsj.js +1174 -0
  4. package/dist/cli/{chunk-5cq8wgte.js → chunk-5yg1zj5n.js} +48 -29
  5. package/dist/cli/{chunk-786w6vrj.js → chunk-fv98dfg5.js} +21 -1
  6. package/dist/cli/flare.js +120 -4
  7. package/dist/platform/admin.js +790 -0
  8. package/dist/platform/dashboard/_astro/auth-view.CuxQ12Fa.js +1 -0
  9. package/dist/platform/dashboard/_astro/badge.DwKWvVfO.js +1 -0
  10. package/dist/platform/dashboard/_astro/card.Bdqmram9.js +1 -0
  11. package/dist/platform/dashboard/_astro/cli-approval.VKPc8wYS.js +1 -0
  12. package/dist/platform/dashboard/_astro/client.BUUZgEFj.js +1 -0
  13. package/dist/platform/dashboard/_astro/client.DYdPL2z4.js +9 -0
  14. package/dist/platform/dashboard/_astro/common.HrRZXwD9.js +1 -0
  15. package/dist/platform/dashboard/_astro/dashboard.CH594XTw.js +3 -0
  16. package/dist/platform/dashboard/_astro/data-view.CcyUYvId.js +1 -0
  17. package/dist/platform/dashboard/_astro/function-badge.MlTRYkqM.js +1 -0
  18. package/dist/platform/dashboard/_astro/functions-view.C8JWdNAh.js +1 -0
  19. package/dist/platform/dashboard/_astro/geist-cyrillic-ext-wght-normal.DjL33-gN.woff2 +0 -0
  20. package/dist/platform/dashboard/_astro/geist-cyrillic-wght-normal.BEAKL7Jp.woff2 +0 -0
  21. package/dist/platform/dashboard/_astro/geist-latin-ext-wght-normal.DC-KSUi6.woff2 +0 -0
  22. package/dist/platform/dashboard/_astro/geist-latin-wght-normal.BgDaEnEv.woff2 +0 -0
  23. package/dist/platform/dashboard/_astro/geist-vietnamese-wght-normal.6IgcOCM7.woff2 +0 -0
  24. package/dist/platform/dashboard/_astro/index.DiiMDa7R.css +2 -0
  25. package/dist/platform/dashboard/_astro/input-group.3twGpQ77.js +1 -0
  26. package/dist/platform/dashboard/_astro/react-dom.DwX89IcG.js +1 -0
  27. package/dist/platform/dashboard/_astro/refresh-cw.B0Cj85jJ.js +1 -0
  28. package/dist/platform/dashboard/_astro/sdk-view.CRFkbEyS.js +1 -0
  29. package/dist/platform/dashboard/_astro/services-view.B2suYnaG.js +1 -0
  30. package/dist/platform/dashboard/_astro/settings-view.BFP47ySK.js +3 -0
  31. package/dist/platform/dashboard/_astro/status-badge.BV1dzbX9.js +1 -0
  32. package/dist/platform/dashboard/_astro/table-guide.DzBDP6fC.js +2 -0
  33. package/dist/platform/dashboard/_astro/tabs.GRO5rCrK.js +1 -0
  34. package/dist/platform/dashboard/_headers +3 -0
  35. package/dist/platform/dashboard/bootstrap/action.js +263 -0
  36. package/dist/platform/dashboard/bootstrap/api.ts +5 -0
  37. package/dist/platform/dashboard/bootstrap/facet.js +914 -0
  38. package/dist/platform/dashboard/bootstrap/manifest.json +5 -0
  39. package/dist/platform/dashboard/bootstrap/openapi.json +18 -0
  40. package/dist/platform/dashboard/bootstrap/release.json +11 -0
  41. package/dist/platform/dashboard/bootstrap/schema.json +1 -0
  42. package/dist/platform/dashboard/index.html +1 -0
  43. package/dist/platform/manifest.json +230 -0
  44. package/dist/platform/migrations/0001.sql +8 -0
  45. package/dist/platform/migrations/0002_project_aliases.sql +6 -0
  46. package/dist/platform/migrations/0003_cli_login.sql +9 -0
  47. package/dist/platform/migrations/0004_retention.sql +4 -0
  48. package/dist/platform/migrations/0005_project_deletion.sql +11 -0
  49. package/dist/platform/migrations/0006_platform_installation.sql +8 -0
  50. package/dist/platform/runtime.js +9392 -0
  51. package/dist/sdk/client.js +10 -2
  52. package/package.json +1 -1
@@ -26,26 +26,46 @@ async function request(platform, path, body) {
26
26
  return "null";
27
27
  }));
28
28
  if (config) {
29
- const { storedToken } = await import("./chunk-x14smx1y.js");
29
+ const { storedToken } = await import("./chunk-5s6zv1h9.js");
30
30
  token = await storedToken(platform, config.project);
31
31
  }
32
32
  }
33
33
  if (!token)
34
34
  throw Error("Sign in with flare dev; CI can set FLARE_DEPLOY_TOKEN");
35
- const r = await fetch(allowedUrl(platform) + path, {
36
- method: body === undefined ? "GET" : "POST",
37
- headers: {
38
- authorization: `Bearer ${token}`,
39
- ...body === undefined ? {} : { "content-type": "application/json" }
40
- },
41
- body: body === undefined ? undefined : JSON.stringify(body),
42
- redirect: "error",
43
- signal: AbortSignal.timeout(60000)
44
- });
45
- const result = await r.json();
35
+ const url = allowedUrl(platform) + path;
36
+ const write = body !== undefined;
37
+ const encoded = write ? JSON.stringify(body) : undefined;
38
+ let r;
39
+ try {
40
+ r = await fetch(url, {
41
+ method: write ? "POST" : "GET",
42
+ headers: {
43
+ authorization: `Bearer ${token}`,
44
+ ...write ? { "content-type": "application/json" } : {}
45
+ },
46
+ body: encoded,
47
+ redirect: "error",
48
+ signal: AbortSignal.timeout(60000)
49
+ });
50
+ } catch {
51
+ const error = Error(write ? "Management write outcome is unknown; inspect current state before retrying. Writes are not automatically retried." : "Management request interrupted or timed out");
52
+ error.ambiguous = write;
53
+ throw error;
54
+ }
55
+ let result;
56
+ try {
57
+ result = await r.json();
58
+ } catch {
59
+ const error = Error(`Invalid management response (HTTP ${r.status}); ${write && (r.ok || r.status >= 500) ? "write outcome is unknown; inspect current state before retrying" : "check platform availability and authorization"}`);
60
+ error.status = r.status;
61
+ error.ambiguous = write && (r.ok || r.status >= 500);
62
+ throw error;
63
+ }
46
64
  if (!r.ok) {
47
- const error = Error(`${result.error ?? "Deployment failed"} (HTTP ${r.status}); writes are not automatically retried`);
65
+ const code = typeof result?.error === "string" && /^[A-Z][A-Z0-9_]{0,63}$/.test(result.error) ? result.error : "Management request failed";
66
+ const error = Error(`${code} (HTTP ${r.status}); writes are not automatically retried`);
48
67
  error.status = r.status;
68
+ error.ambiguous = write && r.status >= 500;
49
69
  throw error;
50
70
  }
51
71
  return result;
@@ -68,9 +88,6 @@ async function link(options) {
68
88
  async function deploy(options = {}) {
69
89
  if (!options.release) {
70
90
  const config = JSON.parse(await readFile(".flare/project.json", "utf8"));
71
- const { prepare, generateApi } = await import("./chunk-786w6vrj.js");
72
- const { buildApplication } = await import("./chunk-vx7kmczm.js");
73
- const source = await prepare(), directory = resolve(".flare/releases/" + randomUUID());
74
91
  const env = options.env ?? "prod";
75
92
  if (!["dev", "prod"].includes(env))
76
93
  throw Error("Environment must be dev or prod");
@@ -89,6 +106,9 @@ async function deploy(options = {}) {
89
106
  prompt.close();
90
107
  }
91
108
  }
109
+ const { prepare, generateApi } = await import("./chunk-fv98dfg5.js");
110
+ const { buildApplication } = await import("./chunk-vx7kmczm.js");
111
+ const source = await prepare(), directory = resolve(".flare/releases/" + randomUUID());
92
112
  try {
93
113
  await buildApplication({ ...source, outdir: directory });
94
114
  const result = await deploy({
@@ -118,13 +138,13 @@ async function deploy(options = {}) {
118
138
  facet: await read("facet.js"),
119
139
  action: await read("action.js")
120
140
  };
121
- let expected;
141
+ const health = await request(config.platform, `/api/projects/${config.project}/${env}/health`);
142
+ const expected = health?.active;
143
+ if (!/^[a-f0-9]{64}$/.test(expected ?? ""))
144
+ throw Error("Environment has no active backend; inspect dashboard Health before deploying");
122
145
  if (options.cmd) {
123
- const health = await request(config.platform, `/api/projects/${config.project}/${env}/health`);
124
- expected = health.active;
125
- const { generateApi } = await import("./chunk-786w6vrj.js");
126
- await generateApi(directory);
127
- await frontendBuild(config, env, options.cmd);
146
+ const { withGeneratedApi } = await import("./chunk-fv98dfg5.js");
147
+ await withGeneratedApi(directory, () => frontendBuild(config, env, options.cmd));
128
148
  }
129
149
  return request(config.platform, `/api/projects/${config.project}/${env}/deploy`, { bundle, confirm: options.confirm, expected });
130
150
  }
@@ -133,14 +153,14 @@ async function dev(options = {}) {
133
153
  throw Error("Watch publishes only to dev; use deploy for production");
134
154
  const simple = !options.entry;
135
155
  if (simple) {
136
- const { scaffold } = await import("./chunk-786w6vrj.js");
156
+ const { scaffold } = await import("./chunk-fv98dfg5.js");
137
157
  await scaffold();
138
158
  try {
139
159
  await access(".flare/project.json");
140
160
  } catch (e) {
141
161
  if (e.code !== "ENOENT")
142
162
  throw e;
143
- const { connect } = await import("./chunk-x14smx1y.js");
163
+ const { connect } = await import("./chunk-5s6zv1h9.js");
144
164
  await connect();
145
165
  }
146
166
  }
@@ -152,7 +172,7 @@ async function dev(options = {}) {
152
172
  } catch (e) {
153
173
  if (process.env.FLARE_DEPLOY_TOKEN || e.status !== 401 && !e.message.startsWith("Sign in"))
154
174
  throw e;
155
- const { connect } = await import("./chunk-x14smx1y.js");
175
+ const { connect } = await import("./chunk-5s6zv1h9.js");
156
176
  await connect();
157
177
  }
158
178
  }
@@ -167,7 +187,7 @@ async function dev(options = {}) {
167
187
  try {
168
188
  const outdir = resolve(".flare/releases/" + randomUUID());
169
189
  try {
170
- const { prepare, generateApi, frontendEnvironment } = await import("./chunk-786w6vrj.js");
190
+ const { prepare, generateApi, frontendEnvironment } = await import("./chunk-fv98dfg5.js");
171
191
  const source = simple ? await prepare() : { entry: options.entry };
172
192
  const release = await buildApplication({ ...source, outdir });
173
193
  if (release.hash !== hash) {
@@ -289,14 +309,13 @@ async function releaseOperation(options, operation) {
289
309
  if (bundle.release.hash !== options.hash)
290
310
  throw Error("Release hash mismatch");
291
311
  const { generateReferences } = await import("./chunk-vx7kmczm.js");
292
- const { generateApi } = await import("./chunk-786w6vrj.js");
312
+ const { withGeneratedApi } = await import("./chunk-fv98dfg5.js");
293
313
  await mkdir(".flare", { recursive: true });
294
314
  const directory = await mkdtemp(resolve(".flare/release-contract-"));
295
315
  try {
296
316
  await writeFile(join(directory, "api.ts"), await generateReferences(bundle.manifest));
297
317
  await writeFile(join(directory, "manifest.json"), JSON.stringify(bundle.manifest));
298
- await generateApi(directory);
299
- await frontendBuild(config, env, options.cmd);
318
+ await withGeneratedApi(directory, () => frontendBuild(config, env, options.cmd));
300
319
  } finally {
301
320
  await rm(directory, { recursive: true, force: true });
302
321
  }
@@ -140,6 +140,25 @@ async function generateApi(directory) {
140
140
  export const api = ${serialize(tree)} as const;
141
141
  `);
142
142
  }
143
+ async function withGeneratedApi(directory, build) {
144
+ const files = ["flare/_generated/api.ts", "flare/_generated/references.ts"];
145
+ const previous = await Promise.all(files.map((file) => readFile(file).catch((error) => {
146
+ if (error.code !== "ENOENT")
147
+ throw error;
148
+ return null;
149
+ })));
150
+ try {
151
+ await generateApi(directory);
152
+ return await build();
153
+ } catch (error) {
154
+ try {
155
+ await Promise.all(files.map((file, i) => previous[i] === null ? rm(file, { force: true }) : writeFile(file, previous[i])));
156
+ } catch (restoreError) {
157
+ throw new AggregateError([error, restoreError], "Build failed and local client references could not be restored");
158
+ }
159
+ throw error;
160
+ }
161
+ }
143
162
  async function frontendEnvironment(url) {
144
163
  const pkg = JSON.parse(await readFile("package.json", "utf8"));
145
164
  const dependencies = { ...pkg.dependencies, ...pkg.devDependencies };
@@ -165,5 +184,6 @@ export {
165
184
  frontendEnvironment,
166
185
  generateApi,
167
186
  prepare,
168
- scaffold
187
+ scaffold,
188
+ withGeneratedApi
169
189
  };
package/dist/cli/flare.js CHANGED
@@ -1,5 +1,73 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
+ // packages/flare/package.json
4
+ var package_default = {
5
+ name: "@auersperg/flare",
6
+ version: "0.3.4",
7
+ license: "MIT",
8
+ type: "module",
9
+ description: "Flare client, server declarations and development CLI",
10
+ bin: {
11
+ flare: "./dist/cli/flare.js"
12
+ },
13
+ files: [
14
+ "dist",
15
+ "README.md",
16
+ "LICENSE"
17
+ ],
18
+ exports: {
19
+ ".": {
20
+ types: "./dist/sdk/client.d.ts",
21
+ import: "./dist/sdk/client.js"
22
+ },
23
+ "./server": {
24
+ types: "./dist/sdk/server.d.ts",
25
+ import: "./dist/sdk/server.js"
26
+ },
27
+ "./react": {
28
+ types: "./dist/sdk/react.d.ts",
29
+ import: "./dist/sdk/react.js"
30
+ },
31
+ "./protocol": {
32
+ types: "./dist/sdk/protocol.d.ts",
33
+ import: "./dist/sdk/protocol.js"
34
+ },
35
+ "./cloudflare": {
36
+ types: "./dist/sdk/cloudflare.d.ts",
37
+ import: "./dist/sdk/cloudflare.js"
38
+ }
39
+ },
40
+ dependencies: {
41
+ "@standard-schema/spec": "1.1.0",
42
+ zod: "4.6.5",
43
+ "json-schema-to-typescript": "16.0.0"
44
+ },
45
+ engines: {
46
+ bun: ">=1.4.3"
47
+ },
48
+ repository: {
49
+ type: "git",
50
+ url: "https://github.com/auersperg/flare.git",
51
+ directory: "packages/flare"
52
+ },
53
+ sideEffects: false,
54
+ peerDependencies: {
55
+ react: ">=19"
56
+ },
57
+ peerDependenciesMeta: {
58
+ react: {
59
+ optional: true
60
+ }
61
+ },
62
+ publishConfig: {
63
+ access: "public",
64
+ registry: "https://registry.npmjs.org/",
65
+ tag: "next"
66
+ },
67
+ scripts: {
68
+ prepack: "bun run --cwd ../.. verify"
69
+ }
70
+ };
3
71
 
4
72
  // packages/flare/src/cli/main.mjs
5
73
  if (typeof Bun === "undefined" || !Bun.semver.satisfies(Bun.version, ">=1.4.3")) {
@@ -8,11 +76,17 @@ if (typeof Bun === "undefined" || !Bun.semver.satisfies(Bun.version, ">=1.4.3"))
8
76
  }
9
77
  var [command, ...args] = process.argv.slice(2);
10
78
  if (!command || ["--help", "help"].includes(command))
11
- console.log(`Flare 0.3 private minimum
79
+ console.log(`Flare ${package_default.version} trusted-team preview
12
80
 
13
81
  flare dev Browser login, setup and cloud dev watch
14
82
  flare deploy Confirmed production build and deploy
15
83
 
84
+ Platform lifecycle (Cloudflare account authorization):
85
+ flare platform install
86
+ flare platform status
87
+ flare platform update --dry-run
88
+ flare platform update
89
+
16
90
  Advanced commands:
17
91
  flare releases --env dev|prod
18
92
  flare promote --hash <dev release hash> [--cmd "bun run build"]
@@ -24,8 +98,50 @@ flare dev --entry <app.ts>
24
98
  flare backup create|list|restore|delete|status --env dev|prod
25
99
  restore --from dev|prod --id <backup ID> (empty target only)
26
100
 
27
- Dashboard is Cloudflare-only. Local tooling does not run a dashboard or backend. CLI authentication uses FLARE_DEPLOY_TOKEN from the online dashboard. Run flare dev with no flags for browser login, project selection and automatic schema/API generation. Run flare deploy with no flags for a confirmed production release. Platform installation is separate.`);
28
- else if ([
101
+ Dashboard is Cloudflare-only. Local tooling does not run a dashboard or backend. Run flare dev for Access-protected browser approval and project-scoped credentials stored outside the application; CI can use FLARE_DEPLOY_TOKEN. Backend dev runs in Cloudflare; start the frontend separately. Production changes require project confirmation. Platform installation is separate.`);
102
+ else if (command === "platform") {
103
+ try {
104
+ const operation = args.shift();
105
+ if (["help", "--help"].includes(operation)) {
106
+ console.log(`flare platform install|status|update [--account <ID>] [--name <name>]
107
+ install: [--owner <email>] [--dashboard-host <host> --runtime-host <host>] [--subdomain <workers.dev prefix>]
108
+ install/update: [--dry-run] [--confirm <account ID>] [--resume]
109
+ Uses the platform payload bundled with this CLI release. Never updates applications or runs a local dashboard. Requires separate Cloudflare account permissions; FLARE_DEPLOY_TOKEN is not an account token.`);
110
+ } else {
111
+ if (!["install", "status", "update"].includes(operation))
112
+ throw Error("Supported: flare platform install|status|update; no deployment has occurred.");
113
+ const options = { operation };
114
+ const allowed = operation === "install" ? [
115
+ "account",
116
+ "name",
117
+ "owner",
118
+ "dashboard-host",
119
+ "runtime-host",
120
+ "subdomain",
121
+ "confirm",
122
+ "dry-run",
123
+ "resume"
124
+ ] : operation === "update" ? ["account", "name", "confirm", "dry-run", "resume"] : ["account", "name"];
125
+ for (let i = 0;i < args.length; i++) {
126
+ const key = args[i]?.slice(2);
127
+ if (!args[i]?.startsWith("--") || !allowed.includes(key) || key in options)
128
+ throw Error("Expected supported unique platform options; no deployment has occurred.");
129
+ if (["dry-run", "resume"].includes(key))
130
+ options[key] = true;
131
+ else {
132
+ if (!args[i + 1] || args[i + 1].startsWith("--"))
133
+ throw Error("Platform option requires a value; no deployment has occurred.");
134
+ options[key] = args[++i];
135
+ }
136
+ }
137
+ const { platform } = await import("./chunk-5tjevcsj.js");
138
+ console.log(JSON.stringify(await platform(options), null, 2));
139
+ }
140
+ } catch (error) {
141
+ console.error(error instanceof Error ? error.message : "Platform command failed");
142
+ process.exitCode = 1;
143
+ }
144
+ } else if ([
29
145
  "build",
30
146
  "link",
31
147
  "deploy",
@@ -63,7 +179,7 @@ else if ([
63
179
  console.log(`Built immutable release ${x.hash}
64
180
  ${x.outdir}`);
65
181
  } else {
66
- const cloud = await import("./chunk-5cq8wgte.js");
182
+ const cloud = await import("./chunk-5yg1zj5n.js");
67
183
  const x = await cloud[command](options);
68
184
  if (x)
69
185
  console.log(JSON.stringify(x, null, 2));