@embeddables/cli 0.7.19 → 0.8.1

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 (256) hide show
  1. package/.prompts/embeddables-cli.md +7 -4
  2. package/dist/auth/index.d.ts +43 -0
  3. package/dist/auth/index.d.ts.map +1 -0
  4. package/dist/auth/index.js +102 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +210 -0
  8. package/dist/command-history.d.ts +13 -0
  9. package/dist/command-history.d.ts.map +1 -0
  10. package/dist/command-history.js +34 -0
  11. package/dist/commands/branch.d.ts +4 -0
  12. package/dist/commands/branch.d.ts.map +1 -0
  13. package/dist/commands/branch.js +67 -0
  14. package/dist/commands/build-workbench.d.ts +5 -0
  15. package/dist/commands/build-workbench.d.ts.map +1 -0
  16. package/dist/commands/build-workbench.js +116 -0
  17. package/dist/commands/build.d.ts +8 -0
  18. package/dist/commands/build.d.ts.map +1 -0
  19. package/dist/commands/build.js +60 -0
  20. package/dist/commands/builder-open.d.ts +4 -0
  21. package/dist/commands/builder-open.d.ts.map +1 -0
  22. package/dist/commands/builder-open.js +74 -0
  23. package/dist/commands/dev.d.ts +12 -0
  24. package/dist/commands/dev.d.ts.map +1 -0
  25. package/dist/commands/dev.js +226 -0
  26. package/dist/commands/diff.d.ts +76 -0
  27. package/dist/commands/diff.d.ts.map +1 -0
  28. package/dist/commands/diff.js +653 -0
  29. package/dist/commands/experiments-connect.d.ts +6 -0
  30. package/dist/commands/experiments-connect.d.ts.map +1 -0
  31. package/dist/commands/experiments-connect.js +140 -0
  32. package/dist/commands/feedback.d.ts +29 -0
  33. package/dist/commands/feedback.d.ts.map +1 -0
  34. package/dist/commands/feedback.js +267 -0
  35. package/dist/commands/init.d.ts +5 -0
  36. package/dist/commands/init.d.ts.map +1 -0
  37. package/dist/commands/init.js +384 -0
  38. package/dist/commands/inspect.d.ts +9 -0
  39. package/dist/commands/inspect.d.ts.map +1 -0
  40. package/dist/commands/inspect.js +293 -0
  41. package/dist/commands/login.d.ts +2 -0
  42. package/dist/commands/login.d.ts.map +1 -0
  43. package/dist/commands/login.js +117 -0
  44. package/dist/commands/logout.d.ts +2 -0
  45. package/dist/commands/logout.d.ts.map +1 -0
  46. package/dist/commands/logout.js +19 -0
  47. package/dist/commands/pull.d.ts +16 -0
  48. package/dist/commands/pull.d.ts.map +1 -0
  49. package/dist/commands/pull.js +395 -0
  50. package/dist/commands/save.d.ts +30 -0
  51. package/dist/commands/save.d.ts.map +1 -0
  52. package/dist/commands/save.js +597 -0
  53. package/dist/commands/upgrade.d.ts +2 -0
  54. package/dist/commands/upgrade.d.ts.map +1 -0
  55. package/dist/commands/upgrade.js +50 -0
  56. package/dist/compiler/errors.d.ts +20 -0
  57. package/dist/compiler/errors.d.ts.map +1 -0
  58. package/dist/compiler/errors.js +35 -0
  59. package/dist/compiler/evalStatic.d.ts +3 -0
  60. package/dist/compiler/evalStatic.d.ts.map +1 -0
  61. package/dist/compiler/evalStatic.js +57 -0
  62. package/dist/compiler/flatten.js +1 -0
  63. package/dist/compiler/helpers/duplicateIds.d.ts +9 -0
  64. package/dist/compiler/helpers/duplicateIds.d.ts.map +1 -0
  65. package/dist/compiler/helpers/duplicateIds.js +71 -0
  66. package/dist/compiler/helpers/numericLeadingKeys.d.ts +8 -0
  67. package/dist/compiler/helpers/numericLeadingKeys.d.ts.map +1 -0
  68. package/dist/compiler/helpers/numericLeadingKeys.js +17 -0
  69. package/dist/compiler/index.d.ts +18 -0
  70. package/dist/compiler/index.d.ts.map +1 -0
  71. package/dist/compiler/index.js +1272 -0
  72. package/dist/compiler/parsePage.d.ts +15 -0
  73. package/dist/compiler/parsePage.d.ts.map +1 -0
  74. package/dist/compiler/parsePage.js +654 -0
  75. package/dist/compiler/registry.d.ts +4 -0
  76. package/dist/compiler/registry.d.ts.map +1 -0
  77. package/dist/compiler/registry.js +44 -0
  78. package/dist/compiler/reverse.d.ts +23 -0
  79. package/dist/compiler/reverse.d.ts.map +1 -0
  80. package/dist/compiler/reverse.js +1920 -0
  81. package/dist/compiler/types.d.ts +21 -0
  82. package/dist/compiler/types.d.ts.map +1 -0
  83. package/dist/compiler/types.js +1 -0
  84. package/dist/components/index.d.ts +21 -0
  85. package/dist/components/index.d.ts.map +1 -0
  86. package/dist/components/index.js +21 -0
  87. package/dist/components/primitives/BaseComponent.d.ts +33 -0
  88. package/dist/components/primitives/BaseComponent.d.ts.map +1 -0
  89. package/dist/components/primitives/BaseComponent.js +26 -0
  90. package/dist/components/primitives/BookMeeting.d.ts +18 -0
  91. package/dist/components/primitives/BookMeeting.d.ts.map +1 -0
  92. package/dist/components/primitives/BookMeeting.js +5 -0
  93. package/dist/components/primitives/Chart.d.ts +41 -0
  94. package/dist/components/primitives/Chart.d.ts.map +1 -0
  95. package/dist/components/primitives/Chart.js +5 -0
  96. package/dist/components/primitives/Container.d.ts +8 -0
  97. package/dist/components/primitives/Container.d.ts.map +1 -0
  98. package/dist/components/primitives/Container.js +5 -0
  99. package/dist/components/primitives/CustomButton.d.ts +37 -0
  100. package/dist/components/primitives/CustomButton.d.ts.map +1 -0
  101. package/dist/components/primitives/CustomButton.js +10 -0
  102. package/dist/components/primitives/CustomHTML.d.ts +8 -0
  103. package/dist/components/primitives/CustomHTML.d.ts.map +1 -0
  104. package/dist/components/primitives/CustomHTML.js +5 -0
  105. package/dist/components/primitives/FileUpload.d.ts +18 -0
  106. package/dist/components/primitives/FileUpload.d.ts.map +1 -0
  107. package/dist/components/primitives/FileUpload.js +16 -0
  108. package/dist/components/primitives/InputBox.d.ts +34 -0
  109. package/dist/components/primitives/InputBox.d.ts.map +1 -0
  110. package/dist/components/primitives/InputBox.js +25 -0
  111. package/dist/components/primitives/Lottie.d.ts +11 -0
  112. package/dist/components/primitives/Lottie.d.ts.map +1 -0
  113. package/dist/components/primitives/Lottie.js +5 -0
  114. package/dist/components/primitives/MediaEmbed.d.ts +13 -0
  115. package/dist/components/primitives/MediaEmbed.d.ts.map +1 -0
  116. package/dist/components/primitives/MediaEmbed.js +6 -0
  117. package/dist/components/primitives/MediaImage.d.ts +8 -0
  118. package/dist/components/primitives/MediaImage.d.ts.map +1 -0
  119. package/dist/components/primitives/MediaImage.js +5 -0
  120. package/dist/components/primitives/OptionSelector.d.ts +38 -0
  121. package/dist/components/primitives/OptionSelector.d.ts.map +1 -0
  122. package/dist/components/primitives/OptionSelector.js +8 -0
  123. package/dist/components/primitives/PaypalCheckout.d.ts +25 -0
  124. package/dist/components/primitives/PaypalCheckout.d.ts.map +1 -0
  125. package/dist/components/primitives/PaypalCheckout.js +5 -0
  126. package/dist/components/primitives/PlainText.d.ts +6 -0
  127. package/dist/components/primitives/PlainText.d.ts.map +1 -0
  128. package/dist/components/primitives/PlainText.js +5 -0
  129. package/dist/components/primitives/ProgressBar.d.ts +15 -0
  130. package/dist/components/primitives/ProgressBar.d.ts.map +1 -0
  131. package/dist/components/primitives/ProgressBar.js +5 -0
  132. package/dist/components/primitives/RichText.d.ts +6 -0
  133. package/dist/components/primitives/RichText.d.ts.map +1 -0
  134. package/dist/components/primitives/RichText.js +5 -0
  135. package/dist/components/primitives/RichTextMarkdown.d.ts +6 -0
  136. package/dist/components/primitives/RichTextMarkdown.d.ts.map +1 -0
  137. package/dist/components/primitives/RichTextMarkdown.js +5 -0
  138. package/dist/components/primitives/Rive.d.ts +16 -0
  139. package/dist/components/primitives/Rive.d.ts.map +1 -0
  140. package/dist/components/primitives/Rive.js +8 -0
  141. package/dist/components/primitives/StripeCheckout.d.ts +52 -0
  142. package/dist/components/primitives/StripeCheckout.d.ts.map +1 -0
  143. package/dist/components/primitives/StripeCheckout.js +5 -0
  144. package/dist/components/primitives/StripeCheckout2.d.ts +30 -0
  145. package/dist/components/primitives/StripeCheckout2.d.ts.map +1 -0
  146. package/dist/components/primitives/StripeCheckout2.js +7 -0
  147. package/dist/config/index.d.ts +23 -0
  148. package/dist/config/index.d.ts.map +1 -0
  149. package/dist/config/index.js +42 -0
  150. package/dist/constants.d.ts +9 -0
  151. package/dist/constants.d.ts.map +1 -0
  152. package/dist/constants.js +9 -0
  153. package/dist/helpers/TEMP helpers file.d.ts +1 -0
  154. package/dist/helpers/TEMP helpers file.d.ts.map +1 -0
  155. package/dist/helpers/TEMP helpers file.js +1 -0
  156. package/dist/helpers/dates.d.ts +5 -0
  157. package/dist/helpers/dates.d.ts.map +1 -0
  158. package/dist/helpers/dates.js +7 -0
  159. package/dist/helpers/json.d.ts +47 -0
  160. package/dist/helpers/json.d.ts.map +1 -0
  161. package/dist/helpers/json.js +622 -0
  162. package/dist/helpers/prompt.d.ts +15 -0
  163. package/dist/helpers/prompt.d.ts.map +1 -0
  164. package/dist/helpers/prompt.js +35 -0
  165. package/dist/helpers/utils.d.ts +13 -0
  166. package/dist/helpers/utils.d.ts.map +1 -0
  167. package/dist/helpers/utils.js +28 -0
  168. package/dist/logger.d.ts +11 -0
  169. package/dist/logger.d.ts.map +1 -0
  170. package/dist/logger.js +21 -0
  171. package/dist/patches/prompts-escape.d.ts +14 -0
  172. package/dist/patches/prompts-escape.d.ts.map +1 -0
  173. package/dist/patches/prompts-escape.js +23 -0
  174. package/dist/prompts/branches.d.ts +20 -0
  175. package/dist/prompts/branches.d.ts.map +1 -0
  176. package/dist/prompts/branches.js +86 -0
  177. package/dist/prompts/embeddables.d.ts +43 -0
  178. package/dist/prompts/embeddables.d.ts.map +1 -0
  179. package/dist/prompts/embeddables.js +200 -0
  180. package/dist/prompts/experiments.d.ts +28 -0
  181. package/dist/prompts/experiments.d.ts.map +1 -0
  182. package/dist/prompts/experiments.js +89 -0
  183. package/dist/prompts/index.d.ts +11 -0
  184. package/dist/prompts/index.d.ts.map +1 -0
  185. package/dist/prompts/index.js +6 -0
  186. package/dist/prompts/projects.d.ts +22 -0
  187. package/dist/prompts/projects.d.ts.map +1 -0
  188. package/dist/prompts/projects.js +92 -0
  189. package/dist/prompts/versions.d.ts +18 -0
  190. package/dist/prompts/versions.d.ts.map +1 -0
  191. package/dist/prompts/versions.js +95 -0
  192. package/dist/proxy/injectApiInterceptor.d.ts +6 -0
  193. package/dist/proxy/injectApiInterceptor.d.ts.map +1 -0
  194. package/dist/proxy/injectApiInterceptor.js +66 -0
  195. package/dist/proxy/injectReload.d.ts +2 -0
  196. package/dist/proxy/injectReload.d.ts.map +1 -0
  197. package/dist/proxy/injectReload.js +14 -0
  198. package/dist/proxy/injectWorkbench.d.ts +5 -0
  199. package/dist/proxy/injectWorkbench.d.ts.map +1 -0
  200. package/dist/proxy/injectWorkbench.js +22 -0
  201. package/dist/proxy/server.d.ts +11 -0
  202. package/dist/proxy/server.d.ts.map +1 -0
  203. package/dist/proxy/server.js +304 -0
  204. package/dist/proxy/sse.d.ts +5 -0
  205. package/dist/proxy/sse.d.ts.map +1 -0
  206. package/dist/proxy/sse.js +17 -0
  207. package/dist/sentry-context.d.ts +48 -0
  208. package/dist/sentry-context.d.ts.map +1 -0
  209. package/dist/sentry-context.js +156 -0
  210. package/dist/stdout.d.ts +61 -0
  211. package/dist/stdout.d.ts.map +1 -0
  212. package/dist/stdout.js +163 -0
  213. package/dist/types-builder.d.ts +800 -0
  214. package/dist/types-builder.d.ts.map +1 -0
  215. package/dist/types-builder.js +20 -0
  216. package/dist/workbench/ActionsPanel.d.ts +6 -0
  217. package/dist/workbench/ActionsPanel.d.ts.map +1 -0
  218. package/dist/workbench/ActionsPanel.js +47 -0
  219. package/dist/workbench/AutofillPanel.d.ts +6 -0
  220. package/dist/workbench/AutofillPanel.d.ts.map +1 -0
  221. package/dist/workbench/AutofillPanel.js +543 -0
  222. package/dist/workbench/ComputedFieldsPanel.d.ts +6 -0
  223. package/dist/workbench/ComputedFieldsPanel.d.ts.map +1 -0
  224. package/dist/workbench/ComputedFieldsPanel.js +31 -0
  225. package/dist/workbench/ExperimentsPanel.d.ts +6 -0
  226. package/dist/workbench/ExperimentsPanel.d.ts.map +1 -0
  227. package/dist/workbench/ExperimentsPanel.js +182 -0
  228. package/dist/workbench/FieldEditorPanel.d.ts +9 -0
  229. package/dist/workbench/FieldEditorPanel.d.ts.map +1 -0
  230. package/dist/workbench/FieldEditorPanel.js +650 -0
  231. package/dist/workbench/InspectorPanel.d.ts +6 -0
  232. package/dist/workbench/InspectorPanel.d.ts.map +1 -0
  233. package/dist/workbench/InspectorPanel.js +341 -0
  234. package/dist/workbench/PageNavigator.d.ts +6 -0
  235. package/dist/workbench/PageNavigator.d.ts.map +1 -0
  236. package/dist/workbench/PageNavigator.js +123 -0
  237. package/dist/workbench/SchemaPanel.d.ts +6 -0
  238. package/dist/workbench/SchemaPanel.d.ts.map +1 -0
  239. package/dist/workbench/SchemaPanel.js +222 -0
  240. package/dist/workbench/UserDataPanel.d.ts +6 -0
  241. package/dist/workbench/UserDataPanel.d.ts.map +1 -0
  242. package/dist/workbench/UserDataPanel.js +350 -0
  243. package/dist/workbench/WorkbenchApp.d.ts +7 -0
  244. package/dist/workbench/WorkbenchApp.d.ts.map +1 -0
  245. package/dist/workbench/WorkbenchApp.js +193 -0
  246. package/dist/workbench/cloudflare-worker/README.md +31 -0
  247. package/dist/workbench/cloudflare-worker/public/workbench.css +1614 -0
  248. package/dist/workbench/cloudflare-worker/public/workbench.js +77 -0
  249. package/dist/workbench/cloudflare-worker/worker.js +40 -0
  250. package/dist/workbench/cloudflare-worker/wrangler.toml +10 -0
  251. package/dist/workbench/index.d.ts +10 -0
  252. package/dist/workbench/index.d.ts.map +1 -0
  253. package/dist/workbench/index.js +44 -0
  254. package/dist/workbench/workbench.css +1614 -0
  255. package/dist/workbench/workbench.js +77 -0
  256. package/package.json +4 -1
@@ -0,0 +1,293 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import pc from 'picocolors';
4
+ import { reverseCompile } from '../compiler/reverse.js';
5
+ import { compileAllPages } from '../compiler/index.js';
6
+ import { formatError } from '../compiler/errors.js';
7
+ import { captureException, createLogger, exit } from '../logger.js';
8
+ import * as stdout from '../stdout.js';
9
+ /**
10
+ * Normalize custom_validation_function strings so literal "\\n" (backslash-n) becomes real newline.
11
+ * (Copied from pull.ts — the engine sometimes returns double-escaped newlines.)
12
+ */
13
+ function normalizeCustomValidationFunctionsInFlow(flow) {
14
+ function walkComponent(comp) {
15
+ const v = comp.custom_validation_function;
16
+ if (typeof v === 'string') {
17
+ comp.custom_validation_function = v.replace(/\\n/g, '\n');
18
+ }
19
+ const children = comp.components ?? comp.buttons;
20
+ if (Array.isArray(children)) {
21
+ for (const c of children) {
22
+ if (c && typeof c === 'object')
23
+ walkComponent(c);
24
+ }
25
+ }
26
+ }
27
+ const pages = flow.pages;
28
+ if (Array.isArray(pages)) {
29
+ for (const page of pages) {
30
+ if (page && typeof page === 'object' && Array.isArray(page.components)) {
31
+ for (const comp of page.components) {
32
+ if (comp && typeof comp === 'object')
33
+ walkComponent(comp);
34
+ }
35
+ }
36
+ }
37
+ }
38
+ const components = flow.components;
39
+ if (Array.isArray(components)) {
40
+ for (const comp of components) {
41
+ if (comp && typeof comp === 'object')
42
+ walkComponent(comp);
43
+ }
44
+ }
45
+ }
46
+ /**
47
+ * Compare two JSON objects and return a summary of differences.
48
+ * Returns null if they are identical.
49
+ */
50
+ function compareJson(original, rebuilt) {
51
+ const originalStr = JSON.stringify(original, null, 2);
52
+ const rebuiltStr = JSON.stringify(rebuilt, null, 2);
53
+ if (originalStr === rebuiltStr) {
54
+ return { identical: true, summary: 'Original and rebuilt JSON are identical.' };
55
+ }
56
+ // Find key-level differences at the top level
57
+ const allKeys = new Set([...Object.keys(original), ...Object.keys(rebuilt)]);
58
+ const diffs = [];
59
+ for (const key of allKeys) {
60
+ const inOrig = key in original;
61
+ const inRebuilt = key in rebuilt;
62
+ if (!inOrig && inRebuilt) {
63
+ diffs.push(` + "${key}": present in rebuilt but not original`);
64
+ }
65
+ else if (inOrig && !inRebuilt) {
66
+ diffs.push(` - "${key}": present in original but not rebuilt`);
67
+ }
68
+ else {
69
+ const origVal = JSON.stringify(original[key]);
70
+ const rebuiltVal = JSON.stringify(rebuilt[key]);
71
+ if (origVal !== rebuiltVal) {
72
+ if (key === 'pages' && Array.isArray(original[key]) && Array.isArray(rebuilt[key])) {
73
+ const origPages = original[key];
74
+ const rebuiltPages = rebuilt[key];
75
+ if (origPages.length !== rebuiltPages.length) {
76
+ diffs.push(` ~ "pages": ${origPages.length} pages in original, ${rebuiltPages.length} in rebuilt`);
77
+ }
78
+ else {
79
+ const changedPages = [];
80
+ for (let i = 0; i < origPages.length; i++) {
81
+ if (JSON.stringify(origPages[i]) !== JSON.stringify(rebuiltPages[i])) {
82
+ changedPages.push(origPages[i].key || `index ${i}`);
83
+ }
84
+ }
85
+ diffs.push(` ~ "pages": ${changedPages.length}/${origPages.length} page(s) differ: ${changedPages.join(', ')}`);
86
+ }
87
+ }
88
+ else if (key === 'styles') {
89
+ const origCount = typeof original[key] === 'object' ? Object.keys(original[key]).length : 0;
90
+ const rebuiltCount = typeof rebuilt[key] === 'object' ? Object.keys(rebuilt[key]).length : 0;
91
+ diffs.push(` ~ "styles": ${origCount} selector(s) in original, ${rebuiltCount} in rebuilt`);
92
+ }
93
+ else {
94
+ // Truncate for readability
95
+ const maxLen = 80;
96
+ const origPreview = origVal && origVal.length > maxLen ? origVal.slice(0, maxLen) + '...' : origVal;
97
+ const rebuiltPreview = rebuiltVal && rebuiltVal.length > maxLen
98
+ ? rebuiltVal.slice(0, maxLen) + '...'
99
+ : rebuiltVal;
100
+ diffs.push(` ~ "${key}": differs`);
101
+ diffs.push(` original: ${origPreview}`);
102
+ diffs.push(` rebuilt: ${rebuiltPreview}`);
103
+ }
104
+ }
105
+ }
106
+ }
107
+ return {
108
+ identical: false,
109
+ summary: `Found ${diffs.filter((d) => d.startsWith(' ')).length} top-level difference(s):\n${diffs.join('\n')}`,
110
+ };
111
+ }
112
+ export async function runInspect(opts) {
113
+ const logger = createLogger('runInspect');
114
+ const embeddableId = opts.id;
115
+ const totalTimer = stdout.timer();
116
+ stdout.header('Embeddable Inspector', 'Fetches, reverse-compiles, and rebuilds an embeddable for debugging.');
117
+ // 1. Fetch embeddable JSON from engine
118
+ const versionParam = opts.version || 'latest';
119
+ const engineOrigin = opts.engine || 'https://engine.embeddables.com';
120
+ let url = `${engineOrigin}/${embeddableId}?version=${versionParam}`;
121
+ if (opts.branch)
122
+ url += `&embeddable_branch=${opts.branch}`;
123
+ let flow;
124
+ let pullVersion;
125
+ try {
126
+ const result = await stdout.withSpinner(`Fetching from ${engineOrigin}…`, async () => {
127
+ const response = await fetch(url);
128
+ if (!response.ok) {
129
+ throw new Error(`Failed to fetch embeddable: ${response.status} ${response.statusText}`);
130
+ }
131
+ const data = await response.json();
132
+ if (!data.flow) {
133
+ throw new Error("Response does not contain a 'flow' property");
134
+ }
135
+ return data;
136
+ }, { successText: 'Fetched embeddable' });
137
+ flow = result.flow;
138
+ pullVersion = result.version ?? result.embeddable_version ?? flow.version;
139
+ normalizeCustomValidationFunctionsInFlow(flow);
140
+ stdout.kvRow([
141
+ ['ID', embeddableId],
142
+ ['Version', String(pullVersion ?? 'unknown')],
143
+ ['Pages', String(flow.pages?.length ?? 0)],
144
+ ]);
145
+ }
146
+ catch (error) {
147
+ captureException(error);
148
+ stdout.error(`Failed to fetch embeddable: ${error instanceof Error ? error.message : String(error)}`);
149
+ logger.error('inspect fetch failed', {
150
+ message: error instanceof Error ? error.message : String(error),
151
+ });
152
+ await exit(1);
153
+ return;
154
+ }
155
+ // 2. Write original JSON to disk
156
+ const baseDir = path.join('embeddables', embeddableId);
157
+ const generatedDir = path.join(baseDir, '.generated');
158
+ const originalJsonPath = path.join(generatedDir, 'embeddable-original.json');
159
+ fs.mkdirSync(generatedDir, { recursive: true });
160
+ const originalJson = JSON.stringify(flow, null, 2);
161
+ fs.writeFileSync(originalJsonPath, originalJson, 'utf8');
162
+ // 3. Clear any existing files before reverse-compiling
163
+ const pagesDir = path.join(baseDir, 'pages');
164
+ const stylesDir = path.join(baseDir, 'styles');
165
+ const computedFieldsDir = path.join(baseDir, 'computed-fields');
166
+ const actionsDir = path.join(baseDir, 'actions');
167
+ const globalComponentsDir = path.join(baseDir, 'global-components');
168
+ let clearedCount = 0;
169
+ for (const [dir, ext] of [
170
+ [pagesDir, '.page.tsx'],
171
+ [stylesDir, '.css'],
172
+ [computedFieldsDir, '.js'],
173
+ [actionsDir, '.js'],
174
+ [globalComponentsDir, '.location.tsx'],
175
+ ]) {
176
+ if (fs.existsSync(dir)) {
177
+ const files = fs.readdirSync(dir).filter((f) => f.endsWith(ext));
178
+ for (const file of files) {
179
+ fs.unlinkSync(path.join(dir, file));
180
+ }
181
+ clearedCount += files.length;
182
+ }
183
+ }
184
+ if (clearedCount > 0) {
185
+ stdout.dim(`Cleaned up ${clearedCount} existing files`);
186
+ }
187
+ // 4. Reverse compile: JSON -> React code
188
+ try {
189
+ await stdout.withSpinner('Reverse-compiling JSON → React…', async () => {
190
+ stdout.mute();
191
+ try {
192
+ await reverseCompile(flow, embeddableId, {
193
+ fix: opts.fix ?? true, // Default to fix mode for inspect
194
+ preserve: true,
195
+ });
196
+ }
197
+ finally {
198
+ stdout.unmute();
199
+ }
200
+ }, {
201
+ successText: 'Reverse compile complete',
202
+ });
203
+ }
204
+ catch (error) {
205
+ captureException(error);
206
+ stdout.error(`Reverse compile failed: ${error instanceof Error ? error.message : String(error)}`);
207
+ logger.error('inspect reverse-compile failed', {
208
+ message: error instanceof Error ? error.message : String(error),
209
+ });
210
+ await exit(1);
211
+ return;
212
+ }
213
+ // 5. List generated files for visibility
214
+ stdout.gap();
215
+ const treeEntries = [];
216
+ const collectDir = (dir, label) => {
217
+ if (!fs.existsSync(dir))
218
+ return;
219
+ const files = fs.readdirSync(dir).filter((f) => !f.startsWith('.'));
220
+ if (files.length === 0)
221
+ return;
222
+ treeEntries.push(`${label}/ (${files.length} files)`);
223
+ };
224
+ collectDir(pagesDir, 'pages');
225
+ collectDir(stylesDir, 'styles');
226
+ collectDir(computedFieldsDir, 'computed-fields');
227
+ collectDir(actionsDir, 'actions');
228
+ collectDir(globalComponentsDir, 'global-components');
229
+ if (treeEntries.length > 0) {
230
+ stdout.fileTree(`embeddables/${embeddableId}/`, treeEntries);
231
+ }
232
+ // 6. Build: React code -> JSON
233
+ const rebuiltJsonPath = path.join(generatedDir, 'embeddable-rebuilt.json');
234
+ const pagesGlob = `embeddables/${embeddableId}/pages/**/*.page.tsx`;
235
+ try {
236
+ await stdout.withSpinner('Rebuilding React → JSON…', async () => {
237
+ await compileAllPages({
238
+ pagesGlob,
239
+ outPath: rebuiltJsonPath,
240
+ pageKeyFrom: 'filename',
241
+ stylesDir,
242
+ embeddableId,
243
+ fixLint: true,
244
+ });
245
+ }, {
246
+ successText: `Build complete → ${rebuiltJsonPath}`,
247
+ });
248
+ }
249
+ catch (error) {
250
+ captureException(error);
251
+ stdout.error(`Build failed: ${formatError(error)}`);
252
+ logger.error('inspect build failed', {
253
+ message: error instanceof Error ? error.message : String(error),
254
+ });
255
+ await exit(1);
256
+ return;
257
+ }
258
+ // 7. Compare original vs rebuilt
259
+ stdout.gap();
260
+ try {
261
+ const rebuiltContent = fs.readFileSync(rebuiltJsonPath, 'utf8');
262
+ const rebuilt = JSON.parse(rebuiltContent);
263
+ const result = compareJson(flow, rebuilt);
264
+ if (result.identical) {
265
+ stdout.box(`${pc.green(result.summary)}`, {
266
+ borderColor: 'green',
267
+ title: 'Comparison',
268
+ });
269
+ }
270
+ else {
271
+ stdout.box(`${pc.yellow(result.summary)}`, {
272
+ borderColor: 'yellow',
273
+ title: 'Comparison',
274
+ });
275
+ }
276
+ }
277
+ catch (error) {
278
+ stdout.error(`Comparison failed: ${error instanceof Error ? error.message : String(error)}`);
279
+ }
280
+ // 8. Summary
281
+ stdout.gap();
282
+ stdout.kvBlock([
283
+ ['Original JSON', originalJsonPath],
284
+ ['Rebuilt JSON', rebuiltJsonPath],
285
+ ['React code', `${baseDir}/pages/`],
286
+ ]);
287
+ stdout.gap();
288
+ stdout.successBox(`Completed in ${totalTimer()} ${stdout.symbols.sparkles}`);
289
+ logger.info('inspect complete', {
290
+ version: String(pullVersion ?? 'unknown'),
291
+ embeddableId,
292
+ });
293
+ }
@@ -0,0 +1,2 @@
1
+ export declare function runLogin(): Promise<void>;
2
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAYA,wBAAsB,QAAQ,kBA2H7B"}
@@ -0,0 +1,117 @@
1
+ import { getSupabaseClient, writeAuthConfig, readAuthConfig, SUPABASE_URL, SUPABASE_ANON_KEY, } from '../auth/index.js';
2
+ import { prompt } from '../helpers/prompt.js';
3
+ import { captureException, createLogger, exit } from '../logger.js';
4
+ import * as stdout from '../stdout.js';
5
+ export async function runLogin() {
6
+ const logger = createLogger('runLogin');
7
+ try {
8
+ const supabase = getSupabaseClient();
9
+ // Check if already logged in
10
+ const existingConfig = readAuthConfig();
11
+ if (existingConfig?.access_token) {
12
+ const { overwrite } = await prompt({
13
+ type: 'confirm',
14
+ name: 'overwrite',
15
+ message: 'You are already logged in. Do you want to log in again?',
16
+ initial: false,
17
+ });
18
+ if (!overwrite) {
19
+ stdout.dim('Login cancelled.');
20
+ return;
21
+ }
22
+ }
23
+ // Prompt for email
24
+ const { email } = await prompt({
25
+ type: 'text',
26
+ name: 'email',
27
+ message: 'Enter your email address:',
28
+ validate: (value) => {
29
+ if (!value)
30
+ return 'Email is required';
31
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
32
+ return 'Please enter a valid email address';
33
+ }
34
+ return true;
35
+ },
36
+ });
37
+ if (!email) {
38
+ stdout.dim('Login cancelled.');
39
+ return;
40
+ }
41
+ // Send OTP code
42
+ const sendSpinner = stdout.spinner('Sending verification code…');
43
+ const { error: sendError } = await supabase.auth.signInWithOtp({ email });
44
+ if (sendError) {
45
+ sendSpinner.fail('Failed to send verification code');
46
+ stdout.error(`Error sending verification code: ${sendError.message}`);
47
+ logger.error('failed to send OTP', { message: sendError.message });
48
+ await exit(1);
49
+ }
50
+ sendSpinner.succeed('Verification code sent!');
51
+ stdout.dim('Check your email for the code.');
52
+ stdout.gap();
53
+ // Prompt for OTP code
54
+ const { code } = await prompt({
55
+ type: 'text',
56
+ name: 'code',
57
+ message: 'Enter the verification code from your email:',
58
+ validate: (value) => {
59
+ if (!value)
60
+ return 'Verification code is required';
61
+ if (!/^\d{6}$/.test(value.trim())) {
62
+ return 'Please enter a valid 6-digit code';
63
+ }
64
+ return true;
65
+ },
66
+ });
67
+ if (!code) {
68
+ stdout.dim('Login cancelled.');
69
+ return;
70
+ }
71
+ // Verify OTP code
72
+ const verifySpinner = stdout.spinner('Verifying code…');
73
+ const { data, error: verifyError } = await supabase.auth.verifyOtp({
74
+ email,
75
+ token: code.trim(),
76
+ type: 'email',
77
+ });
78
+ if (verifyError) {
79
+ verifySpinner.fail('Verification failed');
80
+ stdout.error(`Error verifying code: ${verifyError.message}`);
81
+ logger.error('failed to verify OTP', { message: verifyError.message });
82
+ await exit(1);
83
+ }
84
+ if (!data.session) {
85
+ verifySpinner.fail('No session returned');
86
+ stdout.error('No session returned from verification');
87
+ logger.error('no session returned from verification');
88
+ await exit(1);
89
+ return;
90
+ }
91
+ // Store auth config
92
+ const config = {
93
+ access_token: data.session.access_token,
94
+ refresh_token: data.session.refresh_token,
95
+ expires_at: data.session.expires_at || Math.floor(Date.now() / 1000) + 3600, // Default 1 hour if not provided
96
+ supabase_url: SUPABASE_URL,
97
+ supabase_anon_key: SUPABASE_ANON_KEY,
98
+ };
99
+ writeAuthConfig(config);
100
+ verifySpinner.succeed(`Logged in! ${stdout.randomMessage('login')}`);
101
+ logger.info('login complete');
102
+ }
103
+ catch (error) {
104
+ if (error.name === 'ExitPrompt') {
105
+ // User cancelled prompt (Ctrl+C)
106
+ stdout.gap();
107
+ stdout.dim('Login cancelled.');
108
+ await exit(0);
109
+ }
110
+ else {
111
+ captureException(error);
112
+ stdout.error(`Error during login: ${error.message}`);
113
+ logger.error('login failed', { message: error.message });
114
+ await exit(1);
115
+ }
116
+ }
117
+ }
@@ -0,0 +1,2 @@
1
+ export declare function runLogout(): Promise<void>;
2
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAIA,wBAAsB,SAAS,kBAe9B"}
@@ -0,0 +1,19 @@
1
+ import { deleteAuthConfig, isLoggedIn } from '../auth/index.js';
2
+ import { createLogger, exit } from '../logger.js';
3
+ import * as stdout from '../stdout.js';
4
+ export async function runLogout() {
5
+ const logger = createLogger('runLogout');
6
+ try {
7
+ if (!isLoggedIn()) {
8
+ stdout.dim('You are not currently logged in.');
9
+ return;
10
+ }
11
+ deleteAuthConfig();
12
+ stdout.success('Logged out. See you next time!');
13
+ }
14
+ catch (error) {
15
+ stdout.error(`Error during logout: ${error.message}`);
16
+ logger.error('logout failed', { message: error.message });
17
+ await exit(1);
18
+ }
19
+ }
@@ -0,0 +1,16 @@
1
+ export type RunPullOptions = {
2
+ id?: string;
3
+ out?: string;
4
+ branch?: string;
5
+ branchName?: string;
6
+ /** Explicit version number to pull. If omitted, defaults to "latest" unless selectVersion is true. */
7
+ version?: string | number;
8
+ /** When true, show interactive version selector (triggered by `--version` with no value). */
9
+ selectVersion?: boolean;
10
+ /** When true, pull main and clear saved branch (e.g. when user explicitly selects "main" in branch switcher). */
11
+ useMain?: boolean;
12
+ fix?: boolean;
13
+ preserve?: boolean;
14
+ };
15
+ export declare function runPull(opts: RunPullOptions): Promise<void>;
16
+ //# sourceMappingURL=pull.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAiIA,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sGAAsG;IACtG,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB,6FAA6F;IAC7F,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,iHAAiH;IACjH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,cAAc,iBA6UjD"}