@bravostudioai/react 0.1.31 → 0.1.34

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 (83) hide show
  1. package/dist/cli/commands/download.js +22 -39
  2. package/dist/cli/commands/download.js.map +1 -1
  3. package/dist/cli/commands/generate.js +130 -147
  4. package/dist/cli/commands/generate.js.map +1 -1
  5. package/dist/cli.js +21 -24
  6. package/dist/cli.js.map +1 -1
  7. package/dist/codegen/generator.js +126 -125
  8. package/dist/codegen/generator.js.map +1 -1
  9. package/dist/codegen/parser.js +256 -593
  10. package/dist/codegen/parser.js.map +1 -1
  11. package/dist/codegen/propQualification.js +117 -0
  12. package/dist/codegen/propQualification.js.map +1 -0
  13. package/dist/components/DynamicComponent.js.map +1 -1
  14. package/dist/components/EncoreApp.js +156 -265
  15. package/dist/components/EncoreApp.js.map +1 -1
  16. package/dist/components/EncoreContextProviders.js +24 -0
  17. package/dist/components/EncoreContextProviders.js.map +1 -0
  18. package/dist/components.js +179 -174
  19. package/dist/components.js.map +1 -1
  20. package/dist/hooks/useFontLoader.js +41 -0
  21. package/dist/hooks/useFontLoader.js.map +1 -0
  22. package/dist/hooks/usePusherUpdates.js +41 -45
  23. package/dist/hooks/usePusherUpdates.js.map +1 -1
  24. package/dist/hooks/useRepeatingContainers.js +79 -0
  25. package/dist/hooks/useRepeatingContainers.js.map +1 -0
  26. package/dist/index.js +13 -14
  27. package/dist/index.js.map +1 -1
  28. package/dist/lib/dataPatching.js +24 -0
  29. package/dist/lib/dataPatching.js.map +1 -0
  30. package/dist/lib/dynamicModules.js +44 -45
  31. package/dist/lib/dynamicModules.js.map +1 -1
  32. package/dist/lib/fetcher.js +6 -13
  33. package/dist/lib/fetcher.js.map +1 -1
  34. package/dist/lib/logger.js +35 -0
  35. package/dist/lib/logger.js.map +1 -0
  36. package/dist/lib/moduleRegistry.js +9 -8
  37. package/dist/lib/moduleRegistry.js.map +1 -1
  38. package/dist/src/cli/commands/download.d.ts +1 -1
  39. package/dist/src/cli/commands/download.d.ts.map +1 -1
  40. package/dist/src/cli/commands/generate.d.ts +1 -1
  41. package/dist/src/cli/commands/generate.d.ts.map +1 -1
  42. package/dist/src/codegen/generator.d.ts +75 -1
  43. package/dist/src/codegen/generator.d.ts.map +1 -1
  44. package/dist/src/codegen/parser.d.ts +39 -0
  45. package/dist/src/codegen/parser.d.ts.map +1 -1
  46. package/dist/src/codegen/propQualification.d.ts +42 -0
  47. package/dist/src/codegen/propQualification.d.ts.map +1 -0
  48. package/dist/src/components/DynamicComponent.d.ts +1 -1
  49. package/dist/src/components/DynamicComponent.d.ts.map +1 -1
  50. package/dist/src/components/EncoreApp.d.ts +58 -3
  51. package/dist/src/components/EncoreApp.d.ts.map +1 -1
  52. package/dist/src/components/EncoreContextProviders.d.ts +34 -0
  53. package/dist/src/components/EncoreContextProviders.d.ts.map +1 -0
  54. package/dist/src/components.d.ts.map +1 -1
  55. package/dist/src/hooks/useFontLoader.d.ts +17 -0
  56. package/dist/src/hooks/useFontLoader.d.ts.map +1 -0
  57. package/dist/src/hooks/usePusherUpdates.d.ts.map +1 -1
  58. package/dist/src/hooks/useRepeatingContainers.d.ts +31 -0
  59. package/dist/src/hooks/useRepeatingContainers.d.ts.map +1 -0
  60. package/dist/src/index.d.ts +2 -0
  61. package/dist/src/index.d.ts.map +1 -1
  62. package/dist/src/lib/dataPatching.d.ts +18 -0
  63. package/dist/src/lib/dataPatching.d.ts.map +1 -0
  64. package/dist/src/lib/dynamicModules.d.ts.map +1 -1
  65. package/dist/src/lib/fetcher.d.ts.map +1 -1
  66. package/dist/src/lib/logger.d.ts +33 -0
  67. package/dist/src/lib/logger.d.ts.map +1 -0
  68. package/dist/src/lib/moduleRegistry.d.ts.map +1 -1
  69. package/dist/src/stores/useEncoreState.d.ts +43 -1
  70. package/dist/src/stores/useEncoreState.d.ts.map +1 -1
  71. package/dist/src/version.d.ts +1 -1
  72. package/dist/stores/useEncoreState.js.map +1 -1
  73. package/dist/version.js +1 -1
  74. package/dist/version.js.map +1 -1
  75. package/package.json +2 -1
  76. package/src/cli/commands/download.ts +8 -28
  77. package/src/cli/commands/generate.ts +44 -45
  78. package/src/cli/index.ts +49 -32
  79. package/src/codegen/generator.ts +6 -3
  80. package/src/components/DynamicComponent.tsx +1 -1
  81. package/src/components/EncoreApp.tsx +111 -21
  82. package/src/hooks/useRepeatingContainers.ts +1 -1
  83. package/src/version.ts +1 -1
@@ -1,10 +1,10 @@
1
- import { mkdir as c, writeFile as d } from "fs/promises";
2
- import { join as p } from "path";
3
- import { existsSync as f } from "fs";
1
+ import { mkdir as a, writeFile as c } from "fs/promises";
2
+ import { join as f } from "path";
3
+ import { existsSync as d } from "fs";
4
4
  import m from "../../_virtual/main.js";
5
- import { CONST_APPS_SERVICE_URL as u, CONST_COMPONENTS_CDN_URL as E } from "../../packages/encore-lib/constants.js";
5
+ import { CONST_APPS_SERVICE_URL as u, CONST_COMPONENTS_CDN_URL as $ } from "../../packages/encore-lib/constants.js";
6
6
  m.config();
7
- const i = process.env.VITE_APPS_SERVICE_URL || u, h = E;
7
+ const l = process.env.VITE_APPS_SERVICE_URL || u, p = $;
8
8
  async function w(e, r) {
9
9
  const o = await fetch(e, {
10
10
  headers: r || {}
@@ -15,68 +15,51 @@ async function w(e, r) {
15
15
  );
16
16
  return await o.text();
17
17
  }
18
- async function $({
18
+ async function E({
19
19
  appId: e,
20
20
  pageId: r,
21
21
  targetPath: o
22
22
  }) {
23
- console.log(`Downloading Encore files for app: ${e}, page: ${r}`), console.log(`Target path: ${o}`), f(o) || (await c(o, { recursive: !0 }), console.log(`Created directory: ${o}`));
23
+ console.log(`Downloading Encore files for app: ${e}, page: ${r}`), console.log(`Target path: ${o}`), d(o) || (await a(o, { recursive: !0 }), console.log(`Created directory: ${o}`));
24
24
  const s = [
25
25
  {
26
- url: `${i}/devices/apps/${e}`,
26
+ url: `${l}/devices/apps/${e}`,
27
27
  filename: "app.json",
28
28
  headers: { "x-app-clientrendered": "true" }
29
29
  },
30
30
  {
31
- url: `${i}/devices/apps/${e}/node/${r}`,
31
+ url: `${l}/devices/apps/${e}/node/${r}`,
32
32
  filename: "page.json",
33
33
  headers: { "x-app-clientrendered": "true" }
34
34
  },
35
35
  {
36
- url: `${h}/${e}/draft/components/${r}.js`,
36
+ url: `${p}/${e}/draft/components/${r}.js`,
37
37
  filename: "component.js"
38
38
  }
39
39
  ];
40
40
  for (const n of s)
41
41
  try {
42
42
  console.log(`Downloading ${n.filename} from ${n.url}...`);
43
- const a = await w(n.url, n.headers), t = p(o, n.filename);
44
- await d(t, a, "utf-8"), console.log(`✓ Saved ${n.filename} to ${t}`);
45
- } catch (a) {
46
- throw console.error(`✗ Failed to download ${n.filename} at :`, a), a;
43
+ const i = await w(n.url, n.headers), t = f(o, n.filename);
44
+ await c(t, i, "utf-8"), console.log(`✓ Saved ${n.filename} to ${t}`);
45
+ } catch (i) {
46
+ throw console.error(`✗ Failed to download ${n.filename} at :`, i), i;
47
47
  }
48
48
  console.log(`
49
49
  ✓ All files downloaded successfully!`);
50
50
  }
51
- function l() {
52
- console.log(`
53
- Usage: download-bravo.ts <appId> <pageId> <targetPath>
54
-
55
- Arguments:
56
- appId The Encore app ID
57
- pageId The Encore page ID
58
- targetPath Path where files should be saved
59
-
60
- Environment variables:
61
- APPS_SERVICE_URL Base URL for the apps service
62
-
63
- Example:
64
- download-bravo.ts my-app-id my-page-id ./bravo-files
65
- APPS_SERVICE_URL=https://api.example.com download-bravo.ts my-app-id my-page-id ./bravo-files
66
- `);
67
- }
68
- async function R(e) {
69
- (e.length < 3 || e.includes("--help") || e.includes("-h")) && (l(), process.exit(e.includes("--help") || e.includes("-h") ? 0 : 1));
70
- const [r, o, s] = e;
71
- (!r || !o || !s) && (console.error("Error: Missing required arguments"), l(), process.exit(1));
51
+ async function y(e, r, o) {
52
+ (!e || !r || !o) && (console.error(
53
+ "Error: Missing required arguments. Usage: download <appId> <pageId> <targetPath>"
54
+ ), process.exit(1));
72
55
  try {
73
- await $({ appId: r, pageId: o, targetPath: s });
74
- } catch (n) {
56
+ await E({ appId: e, pageId: r, targetPath: o });
57
+ } catch (s) {
75
58
  console.error(`
76
- Error:`, n instanceof Error ? n.message : n), process.exit(1);
59
+ Error:`, s instanceof Error ? s.message : s), process.exit(1);
77
60
  }
78
61
  }
79
62
  export {
80
- R as runDownload
63
+ y as runDownload
81
64
  };
82
65
  //# sourceMappingURL=download.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"download.js","sources":["../../../src/cli/commands/download.ts"],"sourcesContent":["import { writeFile, mkdir } from \"fs/promises\";\nimport { join } from \"path\";\nimport { existsSync } from \"fs\";\nimport dotenv from \"dotenv\";\nimport {\n CONST_APPS_SERVICE_URL,\n CONST_COMPONENTS_CDN_URL,\n} from \"../../../constants\";\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.VITE_APPS_SERVICE_URL || CONST_APPS_SERVICE_URL;\nconst COMPONENTS_CDN_URL = CONST_COMPONENTS_CDN_URL;\n\ninterface DownloadOptions {\n appId: string;\n pageId: string;\n targetPath: string;\n}\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\nasync function downloadEncoreFiles({\n appId,\n pageId,\n targetPath,\n}: DownloadOptions) {\n console.log(`Downloading Encore files for app: ${appId}, page: ${pageId}`);\n console.log(`Target path: ${targetPath}`);\n\n // Ensure target directory exists\n if (!existsSync(targetPath)) {\n await mkdir(targetPath, { recursive: true });\n console.log(`Created directory: ${targetPath}`);\n }\n\n const files: Array<{\n url: string;\n filename: string;\n headers?: Record<string, string>;\n }> = [\n {\n url: `${APPS_SERVICE_URL}/devices/apps/${appId}`,\n filename: \"app.json\",\n headers: { \"x-app-clientrendered\": \"true\" },\n },\n {\n url: `${APPS_SERVICE_URL}/devices/apps/${appId}/node/${pageId}`,\n filename: \"page.json\",\n headers: { \"x-app-clientrendered\": \"true\" },\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 try {\n console.log(`Downloading ${file.filename} from ${file.url}...`);\n const content = await downloadFile(file.url, file.headers);\n const filePath = join(targetPath, file.filename);\n await writeFile(filePath, content, \"utf-8\");\n console.log(`✓ Saved ${file.filename} to ${filePath}`);\n } catch (error) {\n console.error(`✗ Failed to download ${file.filename} at :`, error);\n throw error;\n }\n }\n\n console.log(\"\\n✓ All files downloaded successfully!\");\n}\n\nfunction printUsage() {\n console.log(`\nUsage: download-bravo.ts <appId> <pageId> <targetPath>\n\nArguments:\n appId The Encore app ID\n pageId The Encore page ID\n targetPath Path where files should be saved\n\nEnvironment variables:\n APPS_SERVICE_URL Base URL for the apps service\n\nExample:\n download-bravo.ts my-app-id my-page-id ./bravo-files\n APPS_SERVICE_URL=https://api.example.com download-bravo.ts my-app-id my-page-id ./bravo-files\n`);\n}\n\nexport async function runDownload(args: string[]) {\n if (args.length < 3 || args.includes(\"--help\") || args.includes(\"-h\")) {\n printUsage();\n process.exit(args.includes(\"--help\") || args.includes(\"-h\") ? 0 : 1);\n }\n\n const [appId, pageId, targetPath] = args;\n\n if (!appId || !pageId || !targetPath) {\n console.error(\"Error: Missing required arguments\");\n printUsage();\n process.exit(1);\n }\n\n try {\n await downloadEncoreFiles({ appId, pageId, targetPath });\n } catch (error) {\n console.error(\"\\nError:\", error instanceof Error ? error.message : error);\n process.exit(1);\n }\n}\n"],"names":["dotenv","APPS_SERVICE_URL","CONST_APPS_SERVICE_URL","COMPONENTS_CDN_URL","CONST_COMPONENTS_CDN_URL","downloadFile","url","headers","response","downloadEncoreFiles","appId","pageId","targetPath","existsSync","mkdir","files","file","content","filePath","join","writeFile","error","printUsage","runDownload","args"],"mappings":";;;;;AASAA,EAAO,OAAA;AAGP,MAAMC,IACJ,QAAQ,IAAI,yBAAyBC,GACjCC,IAAqBC;AAQ3B,eAAeC,EACbC,GACAC,GACiB;AACjB,QAAMC,IAAW,MAAM,MAAMF,GAAK;AAAA,IAChC,SAASC,KAAW,CAAA;AAAA,EAAC,CACtB;AAED,MAAI,CAACC,EAAS;AACZ,UAAM,IAAI;AAAA,MACR,sBAAsBF,CAAG,KAAKE,EAAS,MAAM,IAAIA,EAAS,UAAU;AAAA,IAAA;AAIxE,SAAO,MAAMA,EAAS,KAAA;AACxB;AAEA,eAAeC,EAAoB;AAAA,EACjC,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,YAAAC;AACF,GAAoB;AAClB,UAAQ,IAAI,qCAAqCF,CAAK,WAAWC,CAAM,EAAE,GACzE,QAAQ,IAAI,gBAAgBC,CAAU,EAAE,GAGnCC,EAAWD,CAAU,MACxB,MAAME,EAAMF,GAAY,EAAE,WAAW,IAAM,GAC3C,QAAQ,IAAI,sBAAsBA,CAAU,EAAE;AAGhD,QAAMG,IAID;AAAA,IACH;AAAA,MACE,KAAK,GAAGd,CAAgB,iBAAiBS,CAAK;AAAA,MAC9C,UAAU;AAAA,MACV,SAAS,EAAE,wBAAwB,OAAA;AAAA,IAAO;AAAA,IAE5C;AAAA,MACE,KAAK,GAAGT,CAAgB,iBAAiBS,CAAK,SAASC,CAAM;AAAA,MAC7D,UAAU;AAAA,MACV,SAAS,EAAE,wBAAwB,OAAA;AAAA,IAAO;AAAA,IAE5C;AAAA,MACE,KAAK,GAAGR,CAAkB,IAAIO,CAAK,qBAAqBC,CAAM;AAAA,MAC9D,UAAU;AAAA,IAAA;AAAA,EACZ;AAGF,aAAWK,KAAQD;AACjB,QAAI;AACF,cAAQ,IAAI,eAAeC,EAAK,QAAQ,SAASA,EAAK,GAAG,KAAK;AAC9D,YAAMC,IAAU,MAAMZ,EAAaW,EAAK,KAAKA,EAAK,OAAO,GACnDE,IAAWC,EAAKP,GAAYI,EAAK,QAAQ;AAC/C,YAAMI,EAAUF,GAAUD,GAAS,OAAO,GAC1C,QAAQ,IAAI,WAAWD,EAAK,QAAQ,OAAOE,CAAQ,EAAE;AAAA,IACvD,SAASG,GAAO;AACd,oBAAQ,MAAM,wBAAwBL,EAAK,QAAQ,SAASK,CAAK,GAC3DA;AAAA,IACR;AAGF,UAAQ,IAAI;AAAA,qCAAwC;AACtD;AAEA,SAASC,IAAa;AACpB,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAcb;AACD;AAEA,eAAsBC,EAAYC,GAAgB;AAChD,GAAIA,EAAK,SAAS,KAAKA,EAAK,SAAS,QAAQ,KAAKA,EAAK,SAAS,IAAI,OAClEF,EAAA,GACA,QAAQ,KAAKE,EAAK,SAAS,QAAQ,KAAKA,EAAK,SAAS,IAAI,IAAI,IAAI,CAAC;AAGrE,QAAM,CAACd,GAAOC,GAAQC,CAAU,IAAIY;AAEpC,GAAI,CAACd,KAAS,CAACC,KAAU,CAACC,OACxB,QAAQ,MAAM,mCAAmC,GACjDU,EAAA,GACA,QAAQ,KAAK,CAAC;AAGhB,MAAI;AACF,UAAMb,EAAoB,EAAE,OAAAC,GAAO,QAAAC,GAAQ,YAAAC,GAAY;AAAA,EACzD,SAASS,GAAO;AACd,YAAQ,MAAM;AAAA,SAAYA,aAAiB,QAAQA,EAAM,UAAUA,CAAK,GACxE,QAAQ,KAAK,CAAC;AAAA,EAChB;AACF;"}
1
+ {"version":3,"file":"download.js","sources":["../../../src/cli/commands/download.ts"],"sourcesContent":["import { writeFile, mkdir } from \"fs/promises\";\nimport { join } from \"path\";\nimport { existsSync } from \"fs\";\nimport dotenv from \"dotenv\";\nimport {\n CONST_APPS_SERVICE_URL,\n CONST_COMPONENTS_CDN_URL,\n} from \"../../../constants\";\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.VITE_APPS_SERVICE_URL || CONST_APPS_SERVICE_URL;\nconst COMPONENTS_CDN_URL = CONST_COMPONENTS_CDN_URL;\n\ninterface DownloadOptions {\n appId: string;\n pageId: string;\n targetPath: string;\n}\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\nasync function downloadEncoreFiles({\n appId,\n pageId,\n targetPath,\n}: DownloadOptions) {\n console.log(`Downloading Encore files for app: ${appId}, page: ${pageId}`);\n console.log(`Target path: ${targetPath}`);\n\n // Ensure target directory exists\n if (!existsSync(targetPath)) {\n await mkdir(targetPath, { recursive: true });\n console.log(`Created directory: ${targetPath}`);\n }\n\n const files: Array<{\n url: string;\n filename: string;\n headers?: Record<string, string>;\n }> = [\n {\n url: `${APPS_SERVICE_URL}/devices/apps/${appId}`,\n filename: \"app.json\",\n headers: { \"x-app-clientrendered\": \"true\" },\n },\n {\n url: `${APPS_SERVICE_URL}/devices/apps/${appId}/node/${pageId}`,\n filename: \"page.json\",\n headers: { \"x-app-clientrendered\": \"true\" },\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 try {\n console.log(`Downloading ${file.filename} from ${file.url}...`);\n const content = await downloadFile(file.url, file.headers);\n const filePath = join(targetPath, file.filename);\n await writeFile(filePath, content, \"utf-8\");\n console.log(`✓ Saved ${file.filename} to ${filePath}`);\n } catch (error) {\n console.error(`✗ Failed to download ${file.filename} at :`, error);\n throw error;\n }\n }\n\n console.log(\"\\n✓ All files downloaded successfully!\");\n}\n\nexport async function runDownload(\n appId: string,\n pageId: string,\n targetPath: string\n) {\n if (!appId || !pageId || !targetPath) {\n console.error(\n \"Error: Missing required arguments. Usage: download <appId> <pageId> <targetPath>\"\n );\n process.exit(1);\n }\n\n try {\n await downloadEncoreFiles({ appId, pageId, targetPath });\n } catch (error) {\n console.error(\"\\nError:\", error instanceof Error ? error.message : error);\n process.exit(1);\n }\n}\n"],"names":["dotenv","APPS_SERVICE_URL","CONST_APPS_SERVICE_URL","COMPONENTS_CDN_URL","CONST_COMPONENTS_CDN_URL","downloadFile","url","headers","response","downloadEncoreFiles","appId","pageId","targetPath","existsSync","mkdir","files","file","content","filePath","join","writeFile","error","runDownload"],"mappings":";;;;;AASAA,EAAO,OAAA;AAGP,MAAMC,IACJ,QAAQ,IAAI,yBAAyBC,GACjCC,IAAqBC;AAQ3B,eAAeC,EACbC,GACAC,GACiB;AACjB,QAAMC,IAAW,MAAM,MAAMF,GAAK;AAAA,IAChC,SAASC,KAAW,CAAA;AAAA,EAAC,CACtB;AAED,MAAI,CAACC,EAAS;AACZ,UAAM,IAAI;AAAA,MACR,sBAAsBF,CAAG,KAAKE,EAAS,MAAM,IAAIA,EAAS,UAAU;AAAA,IAAA;AAIxE,SAAO,MAAMA,EAAS,KAAA;AACxB;AAEA,eAAeC,EAAoB;AAAA,EACjC,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,YAAAC;AACF,GAAoB;AAClB,UAAQ,IAAI,qCAAqCF,CAAK,WAAWC,CAAM,EAAE,GACzE,QAAQ,IAAI,gBAAgBC,CAAU,EAAE,GAGnCC,EAAWD,CAAU,MACxB,MAAME,EAAMF,GAAY,EAAE,WAAW,IAAM,GAC3C,QAAQ,IAAI,sBAAsBA,CAAU,EAAE;AAGhD,QAAMG,IAID;AAAA,IACH;AAAA,MACE,KAAK,GAAGd,CAAgB,iBAAiBS,CAAK;AAAA,MAC9C,UAAU;AAAA,MACV,SAAS,EAAE,wBAAwB,OAAA;AAAA,IAAO;AAAA,IAE5C;AAAA,MACE,KAAK,GAAGT,CAAgB,iBAAiBS,CAAK,SAASC,CAAM;AAAA,MAC7D,UAAU;AAAA,MACV,SAAS,EAAE,wBAAwB,OAAA;AAAA,IAAO;AAAA,IAE5C;AAAA,MACE,KAAK,GAAGR,CAAkB,IAAIO,CAAK,qBAAqBC,CAAM;AAAA,MAC9D,UAAU;AAAA,IAAA;AAAA,EACZ;AAGF,aAAWK,KAAQD;AACjB,QAAI;AACF,cAAQ,IAAI,eAAeC,EAAK,QAAQ,SAASA,EAAK,GAAG,KAAK;AAC9D,YAAMC,IAAU,MAAMZ,EAAaW,EAAK,KAAKA,EAAK,OAAO,GACnDE,IAAWC,EAAKP,GAAYI,EAAK,QAAQ;AAC/C,YAAMI,EAAUF,GAAUD,GAAS,OAAO,GAC1C,QAAQ,IAAI,WAAWD,EAAK,QAAQ,OAAOE,CAAQ,EAAE;AAAA,IACvD,SAASG,GAAO;AACd,oBAAQ,MAAM,wBAAwBL,EAAK,QAAQ,SAASK,CAAK,GAC3DA;AAAA,IACR;AAGF,UAAQ,IAAI;AAAA,qCAAwC;AACtD;AAEA,eAAsBC,EACpBZ,GACAC,GACAC,GACA;AACA,GAAI,CAACF,KAAS,CAACC,KAAU,CAACC,OACxB,QAAQ;AAAA,IACN;AAAA,EAAA,GAEF,QAAQ,KAAK,CAAC;AAGhB,MAAI;AACF,UAAMH,EAAoB,EAAE,OAAAC,GAAO,QAAAC,GAAQ,YAAAC,GAAY;AAAA,EACzD,SAASS,GAAO;AACd,YAAQ,MAAM;AAAA,SAAYA,aAAiB,QAAQA,EAAM,UAAUA,CAAK,GACxE,QAAQ,KAAK,CAAC;AAAA,EAChB;AACF;"}
@@ -1,15 +1,15 @@
1
- import { promises as k, existsSync as v } from "fs";
2
- import { join as i, dirname as W } from "path";
3
- import { m as Y } from "../../_virtual/main.js";
4
- import { CONST_APPS_SERVICE_URL as q, CONST_COMPONENTS_CDN_URL as z } from "../../packages/encore-lib/constants.js";
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";
7
- const { writeFile: P, mkdir: G, readFile: R } = k;
8
- Y.config();
9
- const E = process.env.APPS_SERVICE_URL || process.env.VITE_APPS_SERVICE_URL || q;
10
- console.log(`Using APPS_SERVICE_URL: ${E}`);
11
- const se = z;
12
- async function U(o, n) {
1
+ import { promises as z, existsSync as P } from "fs";
2
+ import { join as c, dirname as H } from "path";
3
+ import { m as K } from "../../_virtual/main.js";
4
+ import { CONST_APPS_SERVICE_URL as Q, CONST_COMPONENTS_CDN_URL as X } from "../../packages/encore-lib/constants.js";
5
+ import { findSlidersAndDataBindings as Y, findStandaloneComponents as Z, findInputGroups as I, findForms as ee, qualifyFormInputs as te, findStandaloneSelectInputs as oe, findActionButtons as ne, sanitizePropName as _ } from "../../codegen/parser.js";
6
+ import { generateComponentCode as ae, generateReadme as se } from "../../codegen/generator.js";
7
+ const { writeFile: C, mkdir: L, readFile: N } = z;
8
+ K.config();
9
+ const S = process.env.APPS_SERVICE_URL || process.env.VITE_APPS_SERVICE_URL || Q;
10
+ console.log(`Using APPS_SERVICE_URL: ${S}`);
11
+ const re = X;
12
+ async function O(o, n) {
13
13
  const t = await fetch(o, {
14
14
  headers: n || {}
15
15
  });
@@ -19,251 +19,234 @@ 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 ie(o, n) {
23
+ const t = _(o), i = _(n), a = t.charAt(0).toUpperCase() + t.slice(1), d = i.charAt(0).toUpperCase() + i.slice(1);
24
24
  return {
25
- directoryPath: i(g, d),
25
+ directoryPath: c(a, d),
26
26
  componentName: d
27
27
  };
28
28
  }
29
- async function ie(o) {
30
- const n = `${E}/devices/apps/${o}`;
29
+ async function ce(o) {
30
+ const n = `${S}/devices/apps/${o}`;
31
31
  console.log(`Fetching app data from ${n}...`);
32
32
  try {
33
- const t = await U(n), p = JSON.parse(t);
34
- return { pages: p?.app?.data?.pages || [], appData: p };
33
+ const t = await O(n), i = JSON.parse(t);
34
+ return { pages: i?.app?.data?.pages || [], appData: i };
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 G({
40
40
  appId: o,
41
41
  pageId: n,
42
42
  outputPath: t,
43
- cachedAppData: p,
44
- isProduction: g,
43
+ cachedAppData: i,
44
+ mode: a = "dynamic",
45
45
  usedNames: d
46
46
  }) {
47
- console.log(`Generating wrapper for app: ${o}, page: ${n}`);
48
- let s = t, u = !1;
49
- const l = t.split(".").pop()?.toLowerCase();
50
- if (l !== "tsx" && l !== "ts" && l !== "jsx" && l !== "js") {
47
+ console.log(
48
+ `Generating wrapper for app: ${o}, page: ${n}, mode: ${a}`
49
+ );
50
+ let l = t, m = !1;
51
+ const f = t.split(".").pop()?.toLowerCase();
52
+ if (f !== "tsx" && f !== "ts" && f !== "jsx" && f !== "js") {
51
53
  const { stat: e } = await import("fs/promises");
52
54
  try {
53
- (await e(t)).isDirectory() && (u = !0);
55
+ (await e(t)).isDirectory() && (m = !0);
54
56
  } catch {
55
- (!l || t.endsWith("/")) && (u = !0);
57
+ (!f || t.endsWith("/")) && (m = !0);
56
58
  }
57
59
  }
58
- u && console.log(
60
+ m && console.log(
59
61
  "Output path is a directory, will generate filename from app/page names"
60
62
  ), console.log(`Output path: ${t}`);
61
- const f = i(process.cwd(), ".temp-bravo", o, n);
62
- v(f) || await G(f, { recursive: !0 });
63
- const _ = [
63
+ const g = c(process.cwd(), ".temp-bravo", o, n);
64
+ P(g) || await L(g, { recursive: !0 });
65
+ const T = [
64
66
  {
65
- url: `${E}/devices/apps/${o}`,
67
+ url: `${S}/devices/apps/${o}`,
66
68
  filename: "app.json",
67
69
  skipIfCached: !0
68
70
  },
69
71
  {
70
- url: `${E}/devices/apps/${o}/node/${n}`,
72
+ url: `${S}/devices/apps/${o}/node/${n}`,
71
73
  filename: "page.json"
72
74
  },
73
75
  {
74
- url: `${se}/${o}/draft/components/${n}.js`,
76
+ url: `${re}/${o}/draft/components/${n}.js`,
75
77
  filename: "component.js"
76
78
  }
77
79
  ];
78
- for (const e of _) {
79
- if (e.skipIfCached && p) {
80
+ for (const e of T) {
81
+ if (e.skipIfCached && i) {
80
82
  console.log(`Using cached ${e.filename} (skipping download)`);
81
- const r = i(f, e.filename);
82
- await P(
83
+ const r = c(g, e.filename);
84
+ await C(
83
85
  r,
84
- JSON.stringify(p, null, 2),
86
+ JSON.stringify(i, null, 2),
85
87
  "utf-8"
86
88
  ), console.log(`✓ Saved ${e.filename} from cache`);
87
89
  continue;
88
90
  }
89
91
  try {
90
92
  console.log(`Downloading ${e.filename} from ${e.url}...`);
91
- const r = await U(e.url, e.headers), c = i(f, e.filename);
92
- await P(c, r, "utf-8"), console.log(`✓ Saved ${e.filename}`);
93
+ const r = await O(e.url, e.headers), p = c(g, e.filename);
94
+ await C(p, r, "utf-8"), console.log(`✓ Saved ${e.filename}`);
93
95
  } catch (r) {
94
96
  throw console.error(`✗ Failed to download ${e.filename}:`, r), r;
95
97
  }
96
98
  }
97
- const w = i(f, "page.json"), C = await R(w, "utf-8"), x = JSON.parse(C);
98
- let a = x.data || x;
99
- if (!a.body && !a.data?.body) {
99
+ const V = c(g, "page.json"), k = await N(V, "utf-8"), R = JSON.parse(k);
100
+ let s = R.data || R;
101
+ if (!s.body && !s.data?.body) {
100
102
  console.log("Page data doesn't have body, trying app.json...");
101
103
  try {
102
- let e = p;
104
+ let e = i;
103
105
  if (!e) {
104
- const h = `${E}/devices/apps/${o}`, y = await U(h);
106
+ const h = `${S}/devices/apps/${o}`, y = await O(h);
105
107
  e = JSON.parse(y);
106
108
  }
107
- const c = (e?.app?.data?.pages || []).find((h) => h.id === n);
108
- c && (a = c, console.log("✓ Found page data in app.json"));
109
+ const p = (e?.app?.data?.pages || []).find((h) => h.id === n);
110
+ p && (s = p, console.log("✓ Found page data in app.json"));
109
111
  } catch (e) {
110
112
  console.warn("Could not load app.json:", e);
111
113
  }
112
114
  }
113
- const O = X(a), j = Z(a), D = H(a), $ = Q(a);
114
- ee($);
115
- const F = te(a, $), J = oe(a);
116
- let S = "Encore App", N = "Page";
115
+ const j = Y(s), x = Z(s), v = I(s), $ = ee(s);
116
+ te($);
117
+ const J = oe(s, $), U = ne(s);
118
+ let w = "Encore App", E = "Page";
117
119
  try {
118
- let e = p;
120
+ let e = i;
119
121
  if (!e) {
120
- const r = i(f, "app.json");
121
- if (v(r)) {
122
- const c = await R(r, "utf-8");
123
- e = JSON.parse(c);
122
+ const r = c(g, "app.json");
123
+ if (P(r)) {
124
+ const p = await N(r, "utf-8");
125
+ e = JSON.parse(p);
124
126
  }
125
127
  }
126
- e && (S = e?.app?.store?.name || S);
128
+ e && (w = e?.app?.store?.name || w);
127
129
  } catch {
128
130
  }
129
- N = a.name || a.id || N;
130
- let { directoryPath: L, componentName: m } = re(S, N);
131
+ E = s.name || s.id || E;
132
+ let { directoryPath: D, componentName: u } = ie(w, E);
131
133
  if (d) {
132
- let e = m, r = 2;
134
+ let e = u, r = 2;
133
135
  for (; d.has(e); )
134
- e = `${m}${r}`, r++;
135
- if (e !== m) {
136
- m = e;
137
- const c = A(S), h = c.charAt(0).toUpperCase() + c.slice(1);
138
- L = i(h, m);
136
+ e = `${u}${r}`, r++;
137
+ if (e !== u) {
138
+ u = e;
139
+ const p = _(w), h = p.charAt(0).toUpperCase() + p.slice(1);
140
+ D = c(h, u);
139
141
  }
140
- d.add(m);
142
+ d.add(u);
141
143
  }
142
- const T = L;
143
- if (u)
144
- s = i(t, T);
144
+ const F = D;
145
+ if (m)
146
+ l = c(t, F);
145
147
  else {
146
- const e = W(s);
147
- s = i(e, T);
148
+ const e = H(l);
149
+ l = c(e, F);
148
150
  }
149
- const V = ae(
151
+ const M = a === "production" || a === "optimistic", b = ae(
150
152
  o,
151
153
  n,
152
- m,
153
- O,
154
+ u,
154
155
  j,
155
- D,
156
+ x,
157
+ v,
156
158
  $,
157
- F,
158
159
  J,
159
- !!g,
160
+ U,
161
+ a,
160
162
  {
161
- width: a.style?.width,
162
- height: a.style?.height,
163
- aspectRatio: a.style?.width && a.style?.height ? a.style.width / a.style.height : void 0
163
+ width: s.style?.width,
164
+ height: s.style?.height,
165
+ aspectRatio: s.style?.width && s.style?.height ? s.style.width / s.style.height : void 0
164
166
  }
165
- ), b = ne(
167
+ ), B = se(
166
168
  o,
167
169
  n,
168
- S,
169
- N,
170
- m,
171
- O,
170
+ w,
171
+ E,
172
+ u,
172
173
  j,
173
- D,
174
+ x,
175
+ v,
174
176
  $,
175
- F,
176
- J
177
+ J,
178
+ U
177
179
  );
178
- if (v(s) || await G(s, { recursive: !0 }), g) {
179
- const e = i(f, "component.js");
180
+ if (P(l) || await L(l, { recursive: !0 }), M) {
181
+ const e = c(g, "component.js");
180
182
  let r = "";
181
183
  try {
182
- r = await R(e, "utf-8");
184
+ r = await N(e, "utf-8");
183
185
  } catch {
184
186
  }
185
- let c = p;
186
- if (!c)
187
+ let p = i;
188
+ if (!p)
187
189
  try {
188
- const y = i(f, "app.json"), M = await R(y, "utf-8");
189
- c = JSON.parse(M);
190
+ const y = c(g, "app.json"), W = await N(y, "utf-8");
191
+ p = JSON.parse(W);
190
192
  } catch {
191
193
  }
192
194
  const h = {
193
- app: c,
194
- page: a,
195
+ app: p,
196
+ page: s,
195
197
  componentCode: r
196
198
  };
197
- await P(
198
- i(s, "data.json"),
199
+ await C(
200
+ c(l, "data.json"),
199
201
  JSON.stringify(h, null, 2),
200
202
  "utf-8"
201
203
  );
202
204
  }
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}`);
205
- }
206
- function pe() {
207
- console.log(`
208
- Usage: generate-wrapper.ts <appId> [pageId] <outputPath>
209
-
210
- Arguments:
211
- appId The Encore app ID
212
- pageId The Encore page ID (optional - if omitted, generates wrappers for ALL pages)
213
- outputPath Path where the generated TSX file(s) should be saved
214
-
215
- Environment variables:
216
- APPS_SERVICE_URL Base URL for the apps service
217
-
218
- Example:
219
- generate-wrapper.ts 01KA964B1T6KCKSKCNMYSTKRKZ 01KA964B2F42MN4WGCYDTG1Y70 ./src/components/MyEncoreApp.tsx
220
- `);
205
+ const A = c(l, "index.tsx"), q = c(l, "README.md");
206
+ await C(A, b, "utf-8"), await C(q, B, "utf-8"), console.log(`✓ Generated wrapper component at: ${A}`);
221
207
  }
222
- async function he(o) {
223
- const n = o.includes("--production"), t = o.filter((s) => s !== "--production");
224
- if ((t.length < 2 || t.includes("--help") || t.includes("-h")) && (pe(), process.exit(
225
- t.includes("--help") || t.includes("-h") ? 0 : 1
226
- )), t.length === 2) {
227
- const [s, u] = t;
208
+ async function ue(o, n, t, i) {
209
+ if ((!o || !n && !t) && (console.error(
210
+ "Error: Missing required arguments. Usage: generate <appId> [pageId] <outputPath>"
211
+ ), process.exit(1)), t || (console.error("Error: Missing output path."), process.exit(1)), !n) {
228
212
  try {
229
- const { pages: l, appData: f } = await ie(s);
230
- if (l.length === 0) {
213
+ const { pages: a, appData: d } = await ce(o);
214
+ if (a.length === 0) {
231
215
  console.warn("No pages found for this app.");
232
216
  return;
233
217
  }
234
- const _ = /* @__PURE__ */ new Set();
235
- for (const w of l)
236
- if (w.id)
218
+ const l = /* @__PURE__ */ new Set();
219
+ for (const m of a)
220
+ if (m.id)
237
221
  try {
238
- await K({
239
- appId: s,
240
- pageId: w.id,
241
- outputPath: u,
242
- cachedAppData: f,
243
- isProduction: n,
244
- usedNames: _
222
+ await G({
223
+ appId: o,
224
+ pageId: m.id,
225
+ outputPath: t,
226
+ cachedAppData: d,
227
+ mode: i,
228
+ usedNames: l
245
229
  });
246
- } catch (C) {
230
+ } catch (f) {
247
231
  console.warn(
248
- `Error with page ${w.id}:`,
249
- C instanceof Error ? C.message : C
232
+ `Error with page ${m.id}:`,
233
+ f instanceof Error ? f.message : f
250
234
  );
251
235
  }
252
- } catch (l) {
236
+ } catch (a) {
253
237
  console.error(`
254
- Error:`, l instanceof Error ? l.message : l), process.exit(1);
238
+ Error:`, a instanceof Error ? a.message : a), process.exit(1);
255
239
  }
256
240
  return;
257
241
  }
258
- const [p, g, d] = t;
259
242
  try {
260
- await K({ appId: p, pageId: g, outputPath: d, isProduction: n });
261
- } catch (s) {
243
+ await G({ appId: o, pageId: n, outputPath: t, mode: i });
244
+ } catch (a) {
262
245
  console.error(`
263
- Error:`, s instanceof Error ? s.message : s), process.exit(1);
246
+ Error:`, a instanceof Error ? a.message : a), process.exit(1);
264
247
  }
265
248
  }
266
249
  export {
267
- he as runGenerate
250
+ ue as runGenerate
268
251
  };
269
252
  //# 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 mode = \"dynamic\",\n usedNames,\n}: {\n appId: string;\n pageId: string;\n outputPath: string;\n cachedAppData?: any;\n mode?: string;\n usedNames?: Set<string>;\n}) {\n console.log(\n `Generating wrapper for app: ${appId}, page: ${pageId}, mode: ${mode}`\n );\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 shouldBundleData = mode === \"production\" || mode === \"optimistic\";\n const componentCode = generateComponentCode(\n appId,\n pageId,\n componentName,\n sliders,\n standaloneComponents,\n inputGroups,\n forms,\n selectInputs,\n actionButtons,\n mode,\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 (shouldBundleData) {\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\nexport async function runGenerate(\n appId: string,\n pageId: string | undefined,\n outputPath: string | undefined,\n mode: string\n) {\n if (!appId || (!pageId && !outputPath)) {\n console.error(\n \"Error: Missing required arguments. Usage: generate <appId> [pageId] <outputPath>\"\n );\n process.exit(1);\n }\n\n // If outputPath is missing but we have 2 args logic from caller, handle it.\n // actually caller logic:\n // if 2 args (appId, pageId/output), caller puts output in output and pageId=undefined.\n // so if we are here, we have appId and outputPath. pageId might be undefined.\n\n // Wait, if I changed the caller to pass (appId, undefined, outputPath), I need to be sure.\n // arguments: appId, pageId, outputPath.\n // If user ran: generate app out\n // caller: appId=app, pageId=out, output=undefined.\n // caller logic: if (pageId && !output) -> output=pageId, pageId=undefined.\n // caller calls: runGenerate(app, undefined, out, prod).\n\n // If user ran: generate app page out\n // caller: appId=app, pageId=page, output=out.\n // caller calls: runGenerate(app, page, out, prod).\n\n // So outputPath MUST be defined here effectively if the CLI usage was correct.\n if (!outputPath) {\n console.error(\"Error: Missing output path.\");\n process.exit(1);\n }\n\n // Default mode: Generate all pages\n if (!pageId) {\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 mode,\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 // Single page generation\n try {\n await generateWrapper({ appId, pageId, outputPath, mode });\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","mode","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","shouldBundleData","componentCode","generateComponentCode","readmeContent","generateReadme","componentJsPath","componentCodeContent","appDataForProd","productionData","indexPath","readmePath","runGenerate","pages"],"mappings":"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"}