@bravostudioai/react 0.1.30 → 0.1.32

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 (72) hide show
  1. package/dist/cli/commands/generate.js +69 -65
  2. package/dist/cli/commands/generate.js.map +1 -1
  3. package/dist/codegen/generator.js.map +1 -1
  4. package/dist/codegen/parser.js +256 -593
  5. package/dist/codegen/parser.js.map +1 -1
  6. package/dist/codegen/propQualification.js +117 -0
  7. package/dist/codegen/propQualification.js.map +1 -0
  8. package/dist/components/DynamicComponent.js.map +1 -1
  9. package/dist/components/EncoreApp.js +142 -275
  10. package/dist/components/EncoreApp.js.map +1 -1
  11. package/dist/components/EncoreContextProviders.js +24 -0
  12. package/dist/components/EncoreContextProviders.js.map +1 -0
  13. package/dist/components.js +179 -174
  14. package/dist/components.js.map +1 -1
  15. package/dist/hooks/useFontLoader.js +41 -0
  16. package/dist/hooks/useFontLoader.js.map +1 -0
  17. package/dist/hooks/usePusherUpdates.js +41 -45
  18. package/dist/hooks/usePusherUpdates.js.map +1 -1
  19. package/dist/hooks/useRepeatingContainers.js +79 -0
  20. package/dist/hooks/useRepeatingContainers.js.map +1 -0
  21. package/dist/index.js +13 -14
  22. package/dist/index.js.map +1 -1
  23. package/dist/lib/dataPatching.js +24 -0
  24. package/dist/lib/dataPatching.js.map +1 -0
  25. package/dist/lib/dynamicModules.js +44 -45
  26. package/dist/lib/dynamicModules.js.map +1 -1
  27. package/dist/lib/fetcher.js +6 -13
  28. package/dist/lib/fetcher.js.map +1 -1
  29. package/dist/lib/logger.js +35 -0
  30. package/dist/lib/logger.js.map +1 -0
  31. package/dist/lib/moduleRegistry.js +9 -8
  32. package/dist/lib/moduleRegistry.js.map +1 -1
  33. package/dist/src/cli/commands/generate.d.ts.map +1 -1
  34. package/dist/src/codegen/generator.d.ts +74 -0
  35. package/dist/src/codegen/generator.d.ts.map +1 -1
  36. package/dist/src/codegen/parser.d.ts +39 -0
  37. package/dist/src/codegen/parser.d.ts.map +1 -1
  38. package/dist/src/codegen/propQualification.d.ts +42 -0
  39. package/dist/src/codegen/propQualification.d.ts.map +1 -0
  40. package/dist/src/components/DynamicComponent.d.ts +1 -1
  41. package/dist/src/components/DynamicComponent.d.ts.map +1 -1
  42. package/dist/src/components/EncoreApp.d.ts +55 -2
  43. package/dist/src/components/EncoreApp.d.ts.map +1 -1
  44. package/dist/src/components/EncoreContextProviders.d.ts +34 -0
  45. package/dist/src/components/EncoreContextProviders.d.ts.map +1 -0
  46. package/dist/src/components.d.ts.map +1 -1
  47. package/dist/src/hooks/useFontLoader.d.ts +17 -0
  48. package/dist/src/hooks/useFontLoader.d.ts.map +1 -0
  49. package/dist/src/hooks/usePusherUpdates.d.ts.map +1 -1
  50. package/dist/src/hooks/useRepeatingContainers.d.ts +31 -0
  51. package/dist/src/hooks/useRepeatingContainers.d.ts.map +1 -0
  52. package/dist/src/index.d.ts +2 -0
  53. package/dist/src/index.d.ts.map +1 -1
  54. package/dist/src/lib/dataPatching.d.ts +18 -0
  55. package/dist/src/lib/dataPatching.d.ts.map +1 -0
  56. package/dist/src/lib/dynamicModules.d.ts.map +1 -1
  57. package/dist/src/lib/fetcher.d.ts.map +1 -1
  58. package/dist/src/lib/logger.d.ts +33 -0
  59. package/dist/src/lib/logger.d.ts.map +1 -0
  60. package/dist/src/lib/moduleRegistry.d.ts.map +1 -1
  61. package/dist/src/stores/useEncoreState.d.ts +43 -1
  62. package/dist/src/stores/useEncoreState.d.ts.map +1 -1
  63. package/dist/src/version.d.ts +1 -1
  64. package/dist/stores/useEncoreState.js.map +1 -1
  65. package/dist/version.js +1 -1
  66. package/dist/version.js.map +1 -1
  67. package/package.json +1 -1
  68. package/src/cli/commands/generate.ts +7 -2
  69. package/src/components/DynamicComponent.tsx +1 -1
  70. package/src/components.tsx +6 -1
  71. package/src/hooks/useRepeatingContainers.ts +1 -1
  72. package/src/version.ts +1 -1
@@ -3,15 +3,15 @@ import { join as i, dirname as W } from "path";
3
3
  import { m as Y } from "../../_virtual/main.js";
4
4
  import { CONST_APPS_SERVICE_URL as q, CONST_COMPONENTS_CDN_URL as z } from "../../packages/encore-lib/constants.js";
5
5
  import { findSlidersAndDataBindings as X, findStandaloneComponents as Z, findInputGroups as H, findForms as Q, qualifyFormInputs as ee, findStandaloneSelectInputs as te, findActionButtons as oe, sanitizePropName as A } from "../../codegen/parser.js";
6
- import { generateComponentCode as ae, generateReadme as ne } from "../../codegen/generator.js";
6
+ import { generateComponentCode as ne, generateReadme as ae } from "../../codegen/generator.js";
7
7
  const { writeFile: P, mkdir: G, readFile: R } = k;
8
8
  Y.config();
9
9
  const E = process.env.APPS_SERVICE_URL || process.env.VITE_APPS_SERVICE_URL || q;
10
10
  console.log(`Using APPS_SERVICE_URL: ${E}`);
11
11
  const se = z;
12
- async function U(o, n) {
12
+ async function U(o, s) {
13
13
  const t = await fetch(o, {
14
- headers: n || {}
14
+ headers: s || {}
15
15
  });
16
16
  if (!t.ok)
17
17
  throw new Error(
@@ -19,47 +19,47 @@ async function U(o, n) {
19
19
  );
20
20
  return await t.text();
21
21
  }
22
- function re(o, n) {
23
- const t = A(o), p = A(n), g = t.charAt(0).toUpperCase() + t.slice(1), d = p.charAt(0).toUpperCase() + p.slice(1);
22
+ function re(o, s) {
23
+ const t = A(o), p = A(s), u = t.charAt(0).toUpperCase() + t.slice(1), f = p.charAt(0).toUpperCase() + p.slice(1);
24
24
  return {
25
- directoryPath: i(g, d),
26
- componentName: d
25
+ directoryPath: i(u, f),
26
+ componentName: f
27
27
  };
28
28
  }
29
29
  async function ie(o) {
30
- const n = `${E}/devices/apps/${o}`;
31
- console.log(`Fetching app data from ${n}...`);
30
+ const s = `${E}/devices/apps/${o}`;
31
+ console.log(`Fetching app data from ${s}...`);
32
32
  try {
33
- const t = await U(n), p = JSON.parse(t);
33
+ const t = await U(s), p = JSON.parse(t);
34
34
  return { pages: p?.app?.data?.pages || [], appData: p };
35
35
  } catch (t) {
36
36
  throw console.error("Failed to fetch app data:", t), t;
37
37
  }
38
38
  }
39
- async function K({
39
+ async function b({
40
40
  appId: o,
41
- pageId: n,
41
+ pageId: s,
42
42
  outputPath: t,
43
43
  cachedAppData: p,
44
- isProduction: g,
45
- usedNames: d
44
+ isProduction: u,
45
+ usedNames: f
46
46
  }) {
47
- console.log(`Generating wrapper for app: ${o}, page: ${n}`);
48
- let s = t, u = !1;
47
+ console.log(`Generating wrapper for app: ${o}, page: ${s}`);
48
+ let n = t, h = !1;
49
49
  const l = t.split(".").pop()?.toLowerCase();
50
50
  if (l !== "tsx" && l !== "ts" && l !== "jsx" && l !== "js") {
51
51
  const { stat: e } = await import("fs/promises");
52
52
  try {
53
- (await e(t)).isDirectory() && (u = !0);
53
+ (await e(t)).isDirectory() && (h = !0);
54
54
  } catch {
55
- (!l || t.endsWith("/")) && (u = !0);
55
+ (!l || t.endsWith("/")) && (h = !0);
56
56
  }
57
57
  }
58
- u && console.log(
58
+ h && console.log(
59
59
  "Output path is a directory, will generate filename from app/page names"
60
60
  ), console.log(`Output path: ${t}`);
61
- const f = i(process.cwd(), ".temp-bravo", o, n);
62
- v(f) || await G(f, { recursive: !0 });
61
+ const d = i(process.cwd(), ".temp-bravo", o, s);
62
+ v(d) || await G(d, { recursive: !0 });
63
63
  const _ = [
64
64
  {
65
65
  url: `${E}/devices/apps/${o}`,
@@ -67,18 +67,18 @@ async function K({
67
67
  skipIfCached: !0
68
68
  },
69
69
  {
70
- url: `${E}/devices/apps/${o}/node/${n}`,
70
+ url: `${E}/devices/apps/${o}/node/${s}`,
71
71
  filename: "page.json"
72
72
  },
73
73
  {
74
- url: `${se}/${o}/draft/components/${n}.js`,
74
+ url: `${se}/${o}/draft/components/${s}.js`,
75
75
  filename: "component.js"
76
76
  }
77
77
  ];
78
78
  for (const e of _) {
79
79
  if (e.skipIfCached && p) {
80
80
  console.log(`Using cached ${e.filename} (skipping download)`);
81
- const r = i(f, e.filename);
81
+ const r = i(d, e.filename);
82
82
  await P(
83
83
  r,
84
84
  JSON.stringify(p, null, 2),
@@ -88,23 +88,23 @@ async function K({
88
88
  }
89
89
  try {
90
90
  console.log(`Downloading ${e.filename} from ${e.url}...`);
91
- const r = await U(e.url, e.headers), c = i(f, e.filename);
91
+ const r = await U(e.url, e.headers), c = i(d, e.filename);
92
92
  await P(c, r, "utf-8"), console.log(`✓ Saved ${e.filename}`);
93
93
  } catch (r) {
94
94
  throw console.error(`✗ Failed to download ${e.filename}:`, r), r;
95
95
  }
96
96
  }
97
- const w = i(f, "page.json"), C = await R(w, "utf-8"), x = JSON.parse(C);
97
+ const w = i(d, "page.json"), C = await R(w, "utf-8"), x = JSON.parse(C);
98
98
  let a = x.data || x;
99
99
  if (!a.body && !a.data?.body) {
100
100
  console.log("Page data doesn't have body, trying app.json...");
101
101
  try {
102
102
  let e = p;
103
103
  if (!e) {
104
- const h = `${E}/devices/apps/${o}`, y = await U(h);
104
+ const g = `${E}/devices/apps/${o}`, y = await U(g);
105
105
  e = JSON.parse(y);
106
106
  }
107
- const c = (e?.app?.data?.pages || []).find((h) => h.id === n);
107
+ const c = (e?.app?.data?.pages || []).find((g) => g.id === s);
108
108
  c && (a = c, console.log("✓ Found page data in app.json"));
109
109
  } catch (e) {
110
110
  console.warn("Could not load app.json:", e);
@@ -117,7 +117,7 @@ async function K({
117
117
  try {
118
118
  let e = p;
119
119
  if (!e) {
120
- const r = i(f, "app.json");
120
+ const r = i(d, "app.json");
121
121
  if (v(r)) {
122
122
  const c = await R(r, "utf-8");
123
123
  e = JSON.parse(c);
@@ -128,27 +128,27 @@ async function K({
128
128
  }
129
129
  N = a.name || a.id || N;
130
130
  let { directoryPath: L, componentName: m } = re(S, N);
131
- if (d) {
131
+ if (f) {
132
132
  let e = m, r = 2;
133
- for (; d.has(e); )
133
+ for (; f.has(e); )
134
134
  e = `${m}${r}`, r++;
135
135
  if (e !== m) {
136
136
  m = e;
137
- const c = A(S), h = c.charAt(0).toUpperCase() + c.slice(1);
138
- L = i(h, m);
137
+ const c = A(S), g = c.charAt(0).toUpperCase() + c.slice(1);
138
+ L = i(g, m);
139
139
  }
140
- d.add(m);
140
+ f.add(m);
141
141
  }
142
142
  const T = L;
143
- if (u)
144
- s = i(t, T);
143
+ if (h)
144
+ n = i(t, T);
145
145
  else {
146
- const e = W(s);
147
- s = i(e, T);
146
+ const e = W(n);
147
+ n = i(e, T);
148
148
  }
149
- const V = ae(
149
+ const K = ne(
150
150
  o,
151
- n,
151
+ s,
152
152
  m,
153
153
  O,
154
154
  j,
@@ -156,15 +156,15 @@ async function K({
156
156
  $,
157
157
  F,
158
158
  J,
159
- !!g,
159
+ !!u,
160
160
  {
161
161
  width: a.style?.width,
162
162
  height: a.style?.height,
163
163
  aspectRatio: a.style?.width && a.style?.height ? a.style.width / a.style.height : void 0
164
164
  }
165
- ), b = ne(
165
+ ), V = ae(
166
166
  o,
167
- n,
167
+ s,
168
168
  S,
169
169
  N,
170
170
  m,
@@ -175,8 +175,8 @@ async function K({
175
175
  F,
176
176
  J
177
177
  );
178
- if (v(s) || await G(s, { recursive: !0 }), g) {
179
- const e = i(f, "component.js");
178
+ if (v(n) || await G(n, { recursive: !0 }), u) {
179
+ const e = i(d, "component.js");
180
180
  let r = "";
181
181
  try {
182
182
  r = await R(e, "utf-8");
@@ -185,23 +185,23 @@ async function K({
185
185
  let c = p;
186
186
  if (!c)
187
187
  try {
188
- const y = i(f, "app.json"), M = await R(y, "utf-8");
188
+ const y = i(d, "app.json"), M = await R(y, "utf-8");
189
189
  c = JSON.parse(M);
190
190
  } catch {
191
191
  }
192
- const h = {
192
+ const g = {
193
193
  app: c,
194
194
  page: a,
195
195
  componentCode: r
196
196
  };
197
197
  await P(
198
- i(s, "data.json"),
199
- JSON.stringify(h, null, 2),
198
+ i(n, "data.json"),
199
+ JSON.stringify(g, null, 2),
200
200
  "utf-8"
201
201
  );
202
202
  }
203
- const I = i(s, "index.tsx"), B = i(s, "README.md");
204
- await P(I, V, "utf-8"), await P(B, b, "utf-8"), console.log(`✓ Generated wrapper component at: ${I}`);
203
+ const I = i(n, "index.tsx"), B = i(n, "README.md");
204
+ await P(I, K, "utf-8"), await P(B, V, "utf-8"), console.log(`✓ Generated wrapper component at: ${I}`);
205
205
  }
206
206
  function pe() {
207
207
  console.log(`
@@ -211,6 +211,8 @@ Arguments:
211
211
  appId The Encore app ID
212
212
  pageId The Encore page ID (optional - if omitted, generates wrappers for ALL pages)
213
213
  outputPath Path where the generated TSX file(s) should be saved
214
+ --production Generate for production (bundles data)
215
+ --preseed Alias for --production (bundles data)
214
216
 
215
217
  Environment variables:
216
218
  APPS_SERVICE_URL Base URL for the apps service
@@ -219,14 +221,16 @@ Example:
219
221
  generate-wrapper.ts 01KA964B1T6KCKSKCNMYSTKRKZ 01KA964B2F42MN4WGCYDTG1Y70 ./src/components/MyEncoreApp.tsx
220
222
  `);
221
223
  }
222
- async function he(o) {
223
- const n = o.includes("--production"), t = o.filter((s) => s !== "--production");
224
+ async function ge(o) {
225
+ const s = o.includes("--production") || o.includes("--preseed"), t = o.filter(
226
+ (n) => n !== "--production" && n !== "--preseed"
227
+ );
224
228
  if ((t.length < 2 || t.includes("--help") || t.includes("-h")) && (pe(), process.exit(
225
229
  t.includes("--help") || t.includes("-h") ? 0 : 1
226
230
  )), t.length === 2) {
227
- const [s, u] = t;
231
+ const [n, h] = t;
228
232
  try {
229
- const { pages: l, appData: f } = await ie(s);
233
+ const { pages: l, appData: d } = await ie(n);
230
234
  if (l.length === 0) {
231
235
  console.warn("No pages found for this app.");
232
236
  return;
@@ -235,12 +239,12 @@ async function he(o) {
235
239
  for (const w of l)
236
240
  if (w.id)
237
241
  try {
238
- await K({
239
- appId: s,
242
+ await b({
243
+ appId: n,
240
244
  pageId: w.id,
241
- outputPath: u,
242
- cachedAppData: f,
243
- isProduction: n,
245
+ outputPath: h,
246
+ cachedAppData: d,
247
+ isProduction: s,
244
248
  usedNames: _
245
249
  });
246
250
  } catch (C) {
@@ -255,15 +259,15 @@ Error:`, l instanceof Error ? l.message : l), process.exit(1);
255
259
  }
256
260
  return;
257
261
  }
258
- const [p, g, d] = t;
262
+ const [p, u, f] = t;
259
263
  try {
260
- await K({ appId: p, pageId: g, outputPath: d, isProduction: n });
261
- } catch (s) {
264
+ await b({ appId: p, pageId: u, outputPath: f, isProduction: s });
265
+ } catch (n) {
262
266
  console.error(`
263
- Error:`, s instanceof Error ? s.message : s), process.exit(1);
267
+ Error:`, n instanceof Error ? n.message : n), process.exit(1);
264
268
  }
265
269
  }
266
270
  export {
267
- he as runGenerate
271
+ ge as runGenerate
268
272
  };
269
273
  //# sourceMappingURL=generate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate.js","sources":["../../../src/cli/commands/generate.ts"],"sourcesContent":["import { promises as fs } from \"fs\";\nimport { join, dirname } from \"path\";\nimport { existsSync } from \"fs\";\nimport * as dotenv from \"dotenv\";\nimport {\n CONST_APPS_SERVICE_URL,\n CONST_COMPONENTS_CDN_URL,\n} from \"../../../constants\";\nimport {\n findSlidersAndDataBindings,\n findStandaloneComponents,\n findInputGroups,\n findForms,\n findStandaloneSelectInputs,\n findActionButtons,\n qualifyFormInputs,\n generateComponentCode,\n generateReadme,\n sanitizePropName,\n} from \"../../codegen\";\n\nconst { writeFile, mkdir, readFile } = fs;\n\ndotenv.config();\n\n// Default apps service URL (can be overridden with APPS_SERVICE_URL env var)\nconst APPS_SERVICE_URL =\n process.env.APPS_SERVICE_URL ||\n process.env.VITE_APPS_SERVICE_URL ||\n CONST_APPS_SERVICE_URL;\nconsole.log(`Using APPS_SERVICE_URL: ${APPS_SERVICE_URL}`);\nconst COMPONENTS_CDN_URL = CONST_COMPONENTS_CDN_URL;\n\nasync function downloadFile(\n url: string,\n headers?: Record<string, string>\n): Promise<string> {\n const response = await fetch(url, {\n headers: headers || {},\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to download ${url}: ${response.status} ${response.statusText}`\n );\n }\n\n return await response.text();\n}\n\nfunction generateNames(\n appName: string,\n pageName: string\n): { directoryPath: string; componentName: string } {\n const appCamel = sanitizePropName(appName);\n const pageCamel = sanitizePropName(pageName);\n // Capitalize first letter for PascalCase\n const appPascal = appCamel.charAt(0).toUpperCase() + appCamel.slice(1);\n const pagePascal = pageCamel.charAt(0).toUpperCase() + pageCamel.slice(1);\n return {\n directoryPath: join(appPascal, pagePascal),\n componentName: pagePascal,\n };\n}\n\nasync function getAppPages(\n appId: string\n): Promise<{ pages: any[]; appData: any }> {\n const url = `${APPS_SERVICE_URL}/devices/apps/${appId}`;\n console.log(`Fetching app data from ${url}...`);\n try {\n const content = await downloadFile(url);\n const appData = JSON.parse(content);\n const pages = appData?.app?.data?.pages || [];\n return { pages, appData };\n } catch (error) {\n console.error(\"Failed to fetch app data:\", error);\n throw error;\n }\n}\n\nasync function generateWrapper({\n appId,\n pageId,\n outputPath,\n cachedAppData,\n isProduction,\n usedNames,\n}: {\n appId: string;\n pageId: string;\n outputPath: string;\n cachedAppData?: any;\n isProduction?: boolean;\n usedNames?: Set<string>;\n}) {\n console.log(`Generating wrapper for app: ${appId}, page: ${pageId}`);\n\n // Determine final output path - we'll update it after we get app/page names\n let finalOutputPath = outputPath;\n let needsFilenameGeneration = false;\n const pathExt = outputPath.split(\".\").pop()?.toLowerCase();\n if (\n pathExt !== \"tsx\" &&\n pathExt !== \"ts\" &&\n pathExt !== \"jsx\" &&\n pathExt !== \"js\"\n ) {\n // Path doesn't have a file extension, treat as directory\n const { stat } = await import(\"fs/promises\");\n try {\n const pathStats = await stat(outputPath);\n if (pathStats.isDirectory()) {\n needsFilenameGeneration = true;\n }\n } catch {\n // Path doesn't exist, check if it looks like a directory (no extension)\n if (!pathExt || outputPath.endsWith(\"/\")) {\n needsFilenameGeneration = true;\n }\n }\n }\n\n if (needsFilenameGeneration) {\n console.log(\n `Output path is a directory, will generate filename from app/page names`\n );\n }\n\n console.log(`Output path: ${outputPath}`);\n\n // Create temp directory for downloaded files\n const tempDir = join(process.cwd(), \".temp-bravo\", appId, pageId);\n if (!existsSync(tempDir)) {\n await mkdir(tempDir, { recursive: true });\n }\n\n // Download files (skip app.json if we have cached data)\n const files: Array<{\n url: string;\n filename: string;\n headers?: Record<string, string>;\n skipIfCached?: boolean;\n }> = [\n {\n url: `${APPS_SERVICE_URL}/devices/apps/${appId}`,\n filename: \"app.json\",\n skipIfCached: true,\n },\n {\n url: `${APPS_SERVICE_URL}/devices/apps/${appId}/node/${pageId}`,\n filename: \"page.json\",\n },\n {\n url: `${COMPONENTS_CDN_URL}/${appId}/draft/components/${pageId}.js`,\n filename: \"component.js\",\n },\n ];\n\n for (const file of files) {\n // Skip app.json if we have cached data\n if (file.skipIfCached && cachedAppData) {\n console.log(`Using cached ${file.filename} (skipping download)`);\n const filePath = join(tempDir, file.filename);\n await writeFile(\n filePath,\n JSON.stringify(cachedAppData, null, 2),\n \"utf-8\"\n );\n console.log(`✓ Saved ${file.filename} from cache`);\n continue;\n }\n\n try {\n console.log(`Downloading ${file.filename} from ${file.url}...`);\n const content = await downloadFile(file.url, file.headers);\n const filePath = join(tempDir, file.filename);\n await writeFile(filePath, content, \"utf-8\");\n console.log(`✓ Saved ${file.filename}`);\n } catch (error) {\n console.error(`✗ Failed to download ${file.filename}:`, error);\n throw error;\n }\n }\n\n // Read and parse page.json\n const pageJsonPath = join(tempDir, \"page.json\");\n const pageJsonContent = await readFile(pageJsonPath, \"utf-8\");\n const pageResponse = JSON.parse(pageJsonContent);\n\n // Extract page data - API response has it under 'data' field\n let pageData = pageResponse.data || pageResponse;\n\n // If pageData doesn't have body, try using cached app.json or downloading as fallback\n if (!pageData.body && !(pageData as any).data?.body) {\n console.log(\"Page data doesn't have body, trying app.json...\");\n try {\n let appData = cachedAppData;\n\n // If we don't have cached data, download it\n if (!appData) {\n const appUrl = `${APPS_SERVICE_URL}/devices/apps/${appId}`;\n const appContent = await downloadFile(appUrl);\n appData = JSON.parse(appContent);\n }\n\n // Find the page in app.data.pages\n const pages = appData?.app?.data?.pages || [];\n const page = pages.find((p: any) => p.id === pageId);\n if (page) {\n pageData = page;\n console.log(\"✓ Found page data in app.json\");\n }\n } catch (error) {\n console.warn(\"Could not load app.json:\", error);\n }\n }\n\n // Find components using extracted logic\n const sliders = findSlidersAndDataBindings(pageData);\n const standaloneComponents = findStandaloneComponents(pageData);\n const inputGroups = findInputGroups(pageData);\n const forms = findForms(pageData);\n\n // Qualify form input prop names\n qualifyFormInputs(forms);\n\n const selectInputs = findStandaloneSelectInputs(pageData, forms);\n const actionButtons = findActionButtons(pageData);\n\n // Extract app name and page name\n let appName = \"Encore App\";\n let pageName = \"Page\";\n\n try {\n let appDataForName = cachedAppData;\n if (!appDataForName) {\n const appJsonPath = join(tempDir, \"app.json\");\n if (existsSync(appJsonPath)) {\n const appJsonContent = await readFile(appJsonPath, \"utf-8\");\n appDataForName = JSON.parse(appJsonContent);\n }\n }\n if (appDataForName) {\n appName = appDataForName?.app?.store?.name || appName;\n }\n } catch (error) {\n // Ignore errors, use defaults\n }\n\n pageName = pageData.name || pageData.id || pageName;\n\n // Generate component name and directory name\n let { directoryPath, componentName } = generateNames(appName, pageName);\n\n // Ensure unique component name\n if (usedNames) {\n let uniqueName = componentName;\n let counter = 2;\n while (usedNames.has(uniqueName)) {\n uniqueName = `${componentName}${counter}`;\n counter++;\n }\n if (uniqueName !== componentName) {\n componentName = uniqueName;\n // Reconstitute directory path with new component name\n // generateNames uses: join(appPascal, pagePascal) where pagePascal is componentName\n const appCamel = sanitizePropName(appName);\n const appPascal = appCamel.charAt(0).toUpperCase() + appCamel.slice(1);\n directoryPath = join(appPascal, componentName);\n }\n usedNames.add(componentName);\n }\n\n const directoryName = directoryPath;\n\n // Update output path\n if (needsFilenameGeneration) {\n finalOutputPath = join(outputPath, directoryName);\n } else {\n const providedDir = dirname(finalOutputPath);\n finalOutputPath = join(providedDir, directoryName);\n }\n\n // Generate component code and README\n const componentCode = generateComponentCode(\n appId,\n pageId,\n componentName,\n sliders,\n standaloneComponents,\n inputGroups,\n forms,\n selectInputs,\n actionButtons,\n !!isProduction,\n {\n width: pageData.style?.width,\n height: pageData.style?.height,\n aspectRatio:\n pageData.style?.width && pageData.style?.height\n ? pageData.style.width / pageData.style.height\n : undefined,\n }\n );\n\n const readmeContent = generateReadme(\n appId,\n pageId,\n appName,\n pageName,\n componentName,\n sliders,\n standaloneComponents,\n inputGroups,\n forms,\n selectInputs,\n actionButtons\n );\n\n // Ensure output directory exists\n if (!existsSync(finalOutputPath)) {\n await mkdir(finalOutputPath, { recursive: true });\n }\n\n // Write files\n if (isProduction) {\n const componentJsPath = join(tempDir, \"component.js\");\n let componentCodeContent = \"\";\n try {\n componentCodeContent = await readFile(componentJsPath, \"utf-8\");\n } catch (e) {}\n\n let appDataForProd = cachedAppData;\n if (!appDataForProd) {\n try {\n const appJsonPath = join(tempDir, \"app.json\");\n const appJsonContent = await readFile(appJsonPath, \"utf-8\");\n appDataForProd = JSON.parse(appJsonContent);\n } catch (e) {}\n }\n\n const productionData = {\n app: appDataForProd,\n page: pageData,\n componentCode: componentCodeContent,\n };\n await writeFile(\n join(finalOutputPath, \"data.json\"),\n JSON.stringify(productionData, null, 2),\n \"utf-8\"\n );\n }\n\n const indexPath = join(finalOutputPath, \"index.tsx\");\n const readmePath = join(finalOutputPath, \"README.md\");\n\n await writeFile(indexPath, componentCode, \"utf-8\");\n await writeFile(readmePath, readmeContent, \"utf-8\");\n\n console.log(`✓ Generated wrapper component at: ${indexPath}`);\n}\n\nfunction printUsage() {\n console.log(`\nUsage: generate-wrapper.ts <appId> [pageId] <outputPath>\n\nArguments:\n appId The Encore app ID\n pageId The Encore page ID (optional - if omitted, generates wrappers for ALL pages)\n outputPath Path where the generated TSX file(s) should be saved\n\nEnvironment variables:\n APPS_SERVICE_URL Base URL for the apps service\n\nExample:\n generate-wrapper.ts 01KA964B1T6KCKSKCNMYSTKRKZ 01KA964B2F42MN4WGCYDTG1Y70 ./src/components/MyEncoreApp.tsx\n`);\n}\n\nexport async function runGenerate(args: string[]) {\n const isProduction = args.includes(\"--production\");\n const cleanArgs = args.filter((arg) => arg !== \"--production\");\n\n if (\n cleanArgs.length < 2 ||\n cleanArgs.includes(\"--help\") ||\n cleanArgs.includes(\"-h\")\n ) {\n printUsage();\n process.exit(\n cleanArgs.includes(\"--help\") || cleanArgs.includes(\"-h\") ? 0 : 1\n );\n }\n\n if (cleanArgs.length === 2) {\n const [appId, outputPath] = cleanArgs;\n\n try {\n const { pages, appData } = await getAppPages(appId);\n if (pages.length === 0) {\n console.warn(\"No pages found for this app.\");\n return;\n }\n\n const usedNames = new Set<string>();\n for (const page of pages) {\n if (!page.id) continue;\n try {\n await generateWrapper({\n appId,\n pageId: page.id,\n outputPath,\n cachedAppData: appData,\n isProduction,\n usedNames,\n });\n } catch (error) {\n console.warn(\n `Error with page ${page.id}:`,\n error instanceof Error ? error.message : error\n );\n }\n }\n } catch (error) {\n console.error(\"\\nError:\", error instanceof Error ? error.message : error);\n process.exit(1);\n }\n return;\n }\n\n const [appId, pageId, outputPath] = cleanArgs;\n\n try {\n await generateWrapper({ appId, pageId, outputPath, isProduction }); // Single page generation, no collision context needed unless we wanted global uniqueness but usually used for one-off\n } catch (error) {\n console.error(\"\\nError:\", error instanceof Error ? error.message : error);\n process.exit(1);\n }\n}\n"],"names":["writeFile","mkdir","readFile","fs","dotenv.config","APPS_SERVICE_URL","CONST_APPS_SERVICE_URL","COMPONENTS_CDN_URL","CONST_COMPONENTS_CDN_URL","downloadFile","url","headers","response","generateNames","appName","pageName","appCamel","sanitizePropName","pageCamel","appPascal","pagePascal","join","getAppPages","appId","content","appData","error","generateWrapper","pageId","outputPath","cachedAppData","isProduction","usedNames","finalOutputPath","needsFilenameGeneration","pathExt","stat","tempDir","existsSync","files","file","filePath","pageJsonPath","pageJsonContent","pageResponse","pageData","appUrl","appContent","page","p","sliders","findSlidersAndDataBindings","standaloneComponents","findStandaloneComponents","inputGroups","findInputGroups","forms","findForms","qualifyFormInputs","selectInputs","findStandaloneSelectInputs","actionButtons","findActionButtons","appDataForName","appJsonPath","appJsonContent","directoryPath","componentName","uniqueName","counter","directoryName","providedDir","dirname","componentCode","generateComponentCode","readmeContent","generateReadme","componentJsPath","componentCodeContent","appDataForProd","productionData","indexPath","readmePath","printUsage","runGenerate","args","cleanArgs","arg","pages"],"mappings":"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"}
1
+ {"version":3,"file":"generate.js","sources":["../../../src/cli/commands/generate.ts"],"sourcesContent":["import { promises as fs } from \"fs\";\nimport { join, dirname } from \"path\";\nimport { existsSync } from \"fs\";\nimport * as dotenv from \"dotenv\";\nimport {\n CONST_APPS_SERVICE_URL,\n CONST_COMPONENTS_CDN_URL,\n} from \"../../../constants\";\nimport {\n findSlidersAndDataBindings,\n findStandaloneComponents,\n findInputGroups,\n findForms,\n findStandaloneSelectInputs,\n findActionButtons,\n qualifyFormInputs,\n generateComponentCode,\n generateReadme,\n sanitizePropName,\n} from \"../../codegen\";\n\nconst { writeFile, mkdir, readFile } = fs;\n\ndotenv.config();\n\n// Default apps service URL (can be overridden with APPS_SERVICE_URL env var)\nconst APPS_SERVICE_URL =\n process.env.APPS_SERVICE_URL ||\n process.env.VITE_APPS_SERVICE_URL ||\n CONST_APPS_SERVICE_URL;\nconsole.log(`Using APPS_SERVICE_URL: ${APPS_SERVICE_URL}`);\nconst COMPONENTS_CDN_URL = CONST_COMPONENTS_CDN_URL;\n\nasync function downloadFile(\n url: string,\n headers?: Record<string, string>\n): Promise<string> {\n const response = await fetch(url, {\n headers: headers || {},\n });\n\n if (!response.ok) {\n throw new Error(\n `Failed to download ${url}: ${response.status} ${response.statusText}`\n );\n }\n\n return await response.text();\n}\n\nfunction generateNames(\n appName: string,\n pageName: string\n): { directoryPath: string; componentName: string } {\n const appCamel = sanitizePropName(appName);\n const pageCamel = sanitizePropName(pageName);\n // Capitalize first letter for PascalCase\n const appPascal = appCamel.charAt(0).toUpperCase() + appCamel.slice(1);\n const pagePascal = pageCamel.charAt(0).toUpperCase() + pageCamel.slice(1);\n return {\n directoryPath: join(appPascal, pagePascal),\n componentName: pagePascal,\n };\n}\n\nasync function getAppPages(\n appId: string\n): Promise<{ pages: any[]; appData: any }> {\n const url = `${APPS_SERVICE_URL}/devices/apps/${appId}`;\n console.log(`Fetching app data from ${url}...`);\n try {\n const content = await downloadFile(url);\n const appData = JSON.parse(content);\n const pages = appData?.app?.data?.pages || [];\n return { pages, appData };\n } catch (error) {\n console.error(\"Failed to fetch app data:\", error);\n throw error;\n }\n}\n\nasync function generateWrapper({\n appId,\n pageId,\n outputPath,\n cachedAppData,\n isProduction,\n usedNames,\n}: {\n appId: string;\n pageId: string;\n outputPath: string;\n cachedAppData?: any;\n isProduction?: boolean;\n usedNames?: Set<string>;\n}) {\n console.log(`Generating wrapper for app: ${appId}, page: ${pageId}`);\n\n // Determine final output path - we'll update it after we get app/page names\n let finalOutputPath = outputPath;\n let needsFilenameGeneration = false;\n const pathExt = outputPath.split(\".\").pop()?.toLowerCase();\n if (\n pathExt !== \"tsx\" &&\n pathExt !== \"ts\" &&\n pathExt !== \"jsx\" &&\n pathExt !== \"js\"\n ) {\n // Path doesn't have a file extension, treat as directory\n const { stat } = await import(\"fs/promises\");\n try {\n const pathStats = await stat(outputPath);\n if (pathStats.isDirectory()) {\n needsFilenameGeneration = true;\n }\n } catch {\n // Path doesn't exist, check if it looks like a directory (no extension)\n if (!pathExt || outputPath.endsWith(\"/\")) {\n needsFilenameGeneration = true;\n }\n }\n }\n\n if (needsFilenameGeneration) {\n console.log(\n `Output path is a directory, will generate filename from app/page names`\n );\n }\n\n console.log(`Output path: ${outputPath}`);\n\n // Create temp directory for downloaded files\n const tempDir = join(process.cwd(), \".temp-bravo\", appId, pageId);\n if (!existsSync(tempDir)) {\n await mkdir(tempDir, { recursive: true });\n }\n\n // Download files (skip app.json if we have cached data)\n const files: Array<{\n url: string;\n filename: string;\n headers?: Record<string, string>;\n skipIfCached?: boolean;\n }> = [\n {\n url: `${APPS_SERVICE_URL}/devices/apps/${appId}`,\n filename: \"app.json\",\n skipIfCached: true,\n },\n {\n url: `${APPS_SERVICE_URL}/devices/apps/${appId}/node/${pageId}`,\n filename: \"page.json\",\n },\n {\n url: `${COMPONENTS_CDN_URL}/${appId}/draft/components/${pageId}.js`,\n filename: \"component.js\",\n },\n ];\n\n for (const file of files) {\n // Skip app.json if we have cached data\n if (file.skipIfCached && cachedAppData) {\n console.log(`Using cached ${file.filename} (skipping download)`);\n const filePath = join(tempDir, file.filename);\n await writeFile(\n filePath,\n JSON.stringify(cachedAppData, null, 2),\n \"utf-8\"\n );\n console.log(`✓ Saved ${file.filename} from cache`);\n continue;\n }\n\n try {\n console.log(`Downloading ${file.filename} from ${file.url}...`);\n const content = await downloadFile(file.url, file.headers);\n const filePath = join(tempDir, file.filename);\n await writeFile(filePath, content, \"utf-8\");\n console.log(`✓ Saved ${file.filename}`);\n } catch (error) {\n console.error(`✗ Failed to download ${file.filename}:`, error);\n throw error;\n }\n }\n\n // Read and parse page.json\n const pageJsonPath = join(tempDir, \"page.json\");\n const pageJsonContent = await readFile(pageJsonPath, \"utf-8\");\n const pageResponse = JSON.parse(pageJsonContent);\n\n // Extract page data - API response has it under 'data' field\n let pageData = pageResponse.data || pageResponse;\n\n // If pageData doesn't have body, try using cached app.json or downloading as fallback\n if (!pageData.body && !(pageData as any).data?.body) {\n console.log(\"Page data doesn't have body, trying app.json...\");\n try {\n let appData = cachedAppData;\n\n // If we don't have cached data, download it\n if (!appData) {\n const appUrl = `${APPS_SERVICE_URL}/devices/apps/${appId}`;\n const appContent = await downloadFile(appUrl);\n appData = JSON.parse(appContent);\n }\n\n // Find the page in app.data.pages\n const pages = appData?.app?.data?.pages || [];\n const page = pages.find((p: any) => p.id === pageId);\n if (page) {\n pageData = page;\n console.log(\"✓ Found page data in app.json\");\n }\n } catch (error) {\n console.warn(\"Could not load app.json:\", error);\n }\n }\n\n // Find components using extracted logic\n const sliders = findSlidersAndDataBindings(pageData);\n const standaloneComponents = findStandaloneComponents(pageData);\n const inputGroups = findInputGroups(pageData);\n const forms = findForms(pageData);\n\n // Qualify form input prop names\n qualifyFormInputs(forms);\n\n const selectInputs = findStandaloneSelectInputs(pageData, forms);\n const actionButtons = findActionButtons(pageData);\n\n // Extract app name and page name\n let appName = \"Encore App\";\n let pageName = \"Page\";\n\n try {\n let appDataForName = cachedAppData;\n if (!appDataForName) {\n const appJsonPath = join(tempDir, \"app.json\");\n if (existsSync(appJsonPath)) {\n const appJsonContent = await readFile(appJsonPath, \"utf-8\");\n appDataForName = JSON.parse(appJsonContent);\n }\n }\n if (appDataForName) {\n appName = appDataForName?.app?.store?.name || appName;\n }\n } catch (error) {\n // Ignore errors, use defaults\n }\n\n pageName = pageData.name || pageData.id || pageName;\n\n // Generate component name and directory name\n let { directoryPath, componentName } = generateNames(appName, pageName);\n\n // Ensure unique component name\n if (usedNames) {\n let uniqueName = componentName;\n let counter = 2;\n while (usedNames.has(uniqueName)) {\n uniqueName = `${componentName}${counter}`;\n counter++;\n }\n if (uniqueName !== componentName) {\n componentName = uniqueName;\n // Reconstitute directory path with new component name\n // generateNames uses: join(appPascal, pagePascal) where pagePascal is componentName\n const appCamel = sanitizePropName(appName);\n const appPascal = appCamel.charAt(0).toUpperCase() + appCamel.slice(1);\n directoryPath = join(appPascal, componentName);\n }\n usedNames.add(componentName);\n }\n\n const directoryName = directoryPath;\n\n // Update output path\n if (needsFilenameGeneration) {\n finalOutputPath = join(outputPath, directoryName);\n } else {\n const providedDir = dirname(finalOutputPath);\n finalOutputPath = join(providedDir, directoryName);\n }\n\n // Generate component code and README\n const componentCode = generateComponentCode(\n appId,\n pageId,\n componentName,\n sliders,\n standaloneComponents,\n inputGroups,\n forms,\n selectInputs,\n actionButtons,\n !!isProduction,\n {\n width: pageData.style?.width,\n height: pageData.style?.height,\n aspectRatio:\n pageData.style?.width && pageData.style?.height\n ? pageData.style.width / pageData.style.height\n : undefined,\n }\n );\n\n const readmeContent = generateReadme(\n appId,\n pageId,\n appName,\n pageName,\n componentName,\n sliders,\n standaloneComponents,\n inputGroups,\n forms,\n selectInputs,\n actionButtons\n );\n\n // Ensure output directory exists\n if (!existsSync(finalOutputPath)) {\n await mkdir(finalOutputPath, { recursive: true });\n }\n\n // Write files\n if (isProduction) {\n const componentJsPath = join(tempDir, \"component.js\");\n let componentCodeContent = \"\";\n try {\n componentCodeContent = await readFile(componentJsPath, \"utf-8\");\n } catch (e) {}\n\n let appDataForProd = cachedAppData;\n if (!appDataForProd) {\n try {\n const appJsonPath = join(tempDir, \"app.json\");\n const appJsonContent = await readFile(appJsonPath, \"utf-8\");\n appDataForProd = JSON.parse(appJsonContent);\n } catch (e) {}\n }\n\n const productionData = {\n app: appDataForProd,\n page: pageData,\n componentCode: componentCodeContent,\n };\n await writeFile(\n join(finalOutputPath, \"data.json\"),\n JSON.stringify(productionData, null, 2),\n \"utf-8\"\n );\n }\n\n const indexPath = join(finalOutputPath, \"index.tsx\");\n const readmePath = join(finalOutputPath, \"README.md\");\n\n await writeFile(indexPath, componentCode, \"utf-8\");\n await writeFile(readmePath, readmeContent, \"utf-8\");\n\n console.log(`✓ Generated wrapper component at: ${indexPath}`);\n}\n\nfunction printUsage() {\n console.log(`\nUsage: generate-wrapper.ts <appId> [pageId] <outputPath>\n\nArguments:\n appId The Encore app ID\n pageId The Encore page ID (optional - if omitted, generates wrappers for ALL pages)\n outputPath Path where the generated TSX file(s) should be saved\n --production Generate for production (bundles data)\n --preseed Alias for --production (bundles data)\n\nEnvironment variables:\n APPS_SERVICE_URL Base URL for the apps service\n\nExample:\n generate-wrapper.ts 01KA964B1T6KCKSKCNMYSTKRKZ 01KA964B2F42MN4WGCYDTG1Y70 ./src/components/MyEncoreApp.tsx\n`);\n}\n\nexport async function runGenerate(args: string[]) {\n const isProduction =\n args.includes(\"--production\") || args.includes(\"--preseed\");\n const cleanArgs = args.filter(\n (arg) => arg !== \"--production\" && arg !== \"--preseed\"\n );\n\n if (\n cleanArgs.length < 2 ||\n cleanArgs.includes(\"--help\") ||\n cleanArgs.includes(\"-h\")\n ) {\n printUsage();\n process.exit(\n cleanArgs.includes(\"--help\") || cleanArgs.includes(\"-h\") ? 0 : 1\n );\n }\n\n if (cleanArgs.length === 2) {\n const [appId, outputPath] = cleanArgs;\n\n try {\n const { pages, appData } = await getAppPages(appId);\n if (pages.length === 0) {\n console.warn(\"No pages found for this app.\");\n return;\n }\n\n const usedNames = new Set<string>();\n for (const page of pages) {\n if (!page.id) continue;\n try {\n await generateWrapper({\n appId,\n pageId: page.id,\n outputPath,\n cachedAppData: appData,\n isProduction,\n usedNames,\n });\n } catch (error) {\n console.warn(\n `Error with page ${page.id}:`,\n error instanceof Error ? error.message : error\n );\n }\n }\n } catch (error) {\n console.error(\"\\nError:\", error instanceof Error ? error.message : error);\n process.exit(1);\n }\n return;\n }\n\n const [appId, pageId, outputPath] = cleanArgs;\n\n try {\n await generateWrapper({ appId, pageId, outputPath, isProduction }); // Single page generation, no collision context needed unless we wanted global uniqueness but usually used for one-off\n } catch (error) {\n console.error(\"\\nError:\", error instanceof Error ? error.message : error);\n process.exit(1);\n }\n}\n"],"names":["writeFile","mkdir","readFile","fs","dotenv.config","APPS_SERVICE_URL","CONST_APPS_SERVICE_URL","COMPONENTS_CDN_URL","CONST_COMPONENTS_CDN_URL","downloadFile","url","headers","response","generateNames","appName","pageName","appCamel","sanitizePropName","pageCamel","appPascal","pagePascal","join","getAppPages","appId","content","appData","error","generateWrapper","pageId","outputPath","cachedAppData","isProduction","usedNames","finalOutputPath","needsFilenameGeneration","pathExt","stat","tempDir","existsSync","files","file","filePath","pageJsonPath","pageJsonContent","pageResponse","pageData","appUrl","appContent","page","p","sliders","findSlidersAndDataBindings","standaloneComponents","findStandaloneComponents","inputGroups","findInputGroups","forms","findForms","qualifyFormInputs","selectInputs","findStandaloneSelectInputs","actionButtons","findActionButtons","appDataForName","appJsonPath","appJsonContent","directoryPath","componentName","uniqueName","counter","directoryName","providedDir","dirname","componentCode","generateComponentCode","readmeContent","generateReadme","componentJsPath","componentCodeContent","appDataForProd","productionData","indexPath","readmePath","printUsage","runGenerate","args","cleanArgs","arg","pages"],"mappings":"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"}