@embeddables/cli 0.7.13 → 0.7.15

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 (236) hide show
  1. package/.prompts/custom/build-funnel.md +1 -1
  2. package/.prompts/embeddables-cli.md +9 -2
  3. package/package.json +1 -1
  4. package/dist/auth/index.d.ts +0 -43
  5. package/dist/auth/index.d.ts.map +0 -1
  6. package/dist/auth/index.js +0 -102
  7. package/dist/cli.d.ts +0 -2
  8. package/dist/cli.d.ts.map +0 -1
  9. package/dist/cli.js +0 -174
  10. package/dist/commands/branch.d.ts +0 -4
  11. package/dist/commands/branch.d.ts.map +0 -1
  12. package/dist/commands/branch.js +0 -68
  13. package/dist/commands/build-workbench.d.ts +0 -5
  14. package/dist/commands/build-workbench.d.ts.map +0 -1
  15. package/dist/commands/build-workbench.js +0 -128
  16. package/dist/commands/build.d.ts +0 -8
  17. package/dist/commands/build.d.ts.map +0 -1
  18. package/dist/commands/build.js +0 -55
  19. package/dist/commands/dev.d.ts +0 -12
  20. package/dist/commands/dev.d.ts.map +0 -1
  21. package/dist/commands/dev.js +0 -221
  22. package/dist/commands/experiments-connect.d.ts +0 -6
  23. package/dist/commands/experiments-connect.d.ts.map +0 -1
  24. package/dist/commands/experiments-connect.js +0 -140
  25. package/dist/commands/init.d.ts +0 -5
  26. package/dist/commands/init.d.ts.map +0 -1
  27. package/dist/commands/init.js +0 -327
  28. package/dist/commands/login.d.ts +0 -2
  29. package/dist/commands/login.d.ts.map +0 -1
  30. package/dist/commands/login.js +0 -122
  31. package/dist/commands/logout.d.ts +0 -2
  32. package/dist/commands/logout.d.ts.map +0 -1
  33. package/dist/commands/logout.js +0 -22
  34. package/dist/commands/pull.d.ts +0 -14
  35. package/dist/commands/pull.d.ts.map +0 -1
  36. package/dist/commands/pull.js +0 -383
  37. package/dist/commands/save.d.ts +0 -30
  38. package/dist/commands/save.d.ts.map +0 -1
  39. package/dist/commands/save.js +0 -591
  40. package/dist/commands/upgrade.d.ts +0 -2
  41. package/dist/commands/upgrade.d.ts.map +0 -1
  42. package/dist/commands/upgrade.js +0 -51
  43. package/dist/compiler/errors.d.ts +0 -20
  44. package/dist/compiler/errors.d.ts.map +0 -1
  45. package/dist/compiler/errors.js +0 -35
  46. package/dist/compiler/evalStatic.d.ts +0 -3
  47. package/dist/compiler/evalStatic.d.ts.map +0 -1
  48. package/dist/compiler/evalStatic.js +0 -57
  49. package/dist/compiler/flatten.js +0 -1
  50. package/dist/compiler/helpers/duplicateIds.d.ts +0 -9
  51. package/dist/compiler/helpers/duplicateIds.d.ts.map +0 -1
  52. package/dist/compiler/helpers/duplicateIds.js +0 -71
  53. package/dist/compiler/helpers/numericLeadingKeys.d.ts +0 -8
  54. package/dist/compiler/helpers/numericLeadingKeys.d.ts.map +0 -1
  55. package/dist/compiler/helpers/numericLeadingKeys.js +0 -17
  56. package/dist/compiler/index.d.ts +0 -18
  57. package/dist/compiler/index.d.ts.map +0 -1
  58. package/dist/compiler/index.js +0 -1245
  59. package/dist/compiler/parsePage.d.ts +0 -15
  60. package/dist/compiler/parsePage.d.ts.map +0 -1
  61. package/dist/compiler/parsePage.js +0 -631
  62. package/dist/compiler/registry.d.ts +0 -4
  63. package/dist/compiler/registry.d.ts.map +0 -1
  64. package/dist/compiler/registry.js +0 -44
  65. package/dist/compiler/reverse.d.ts +0 -23
  66. package/dist/compiler/reverse.d.ts.map +0 -1
  67. package/dist/compiler/reverse.js +0 -1875
  68. package/dist/compiler/types.d.ts +0 -21
  69. package/dist/compiler/types.d.ts.map +0 -1
  70. package/dist/compiler/types.js +0 -1
  71. package/dist/components/index.d.ts +0 -21
  72. package/dist/components/index.d.ts.map +0 -1
  73. package/dist/components/index.js +0 -21
  74. package/dist/components/primitives/BaseComponent.d.ts +0 -32
  75. package/dist/components/primitives/BaseComponent.d.ts.map +0 -1
  76. package/dist/components/primitives/BaseComponent.js +0 -26
  77. package/dist/components/primitives/BookMeeting.d.ts +0 -18
  78. package/dist/components/primitives/BookMeeting.d.ts.map +0 -1
  79. package/dist/components/primitives/BookMeeting.js +0 -5
  80. package/dist/components/primitives/Chart.d.ts +0 -41
  81. package/dist/components/primitives/Chart.d.ts.map +0 -1
  82. package/dist/components/primitives/Chart.js +0 -5
  83. package/dist/components/primitives/Container.d.ts +0 -8
  84. package/dist/components/primitives/Container.d.ts.map +0 -1
  85. package/dist/components/primitives/Container.js +0 -5
  86. package/dist/components/primitives/CustomButton.d.ts +0 -37
  87. package/dist/components/primitives/CustomButton.d.ts.map +0 -1
  88. package/dist/components/primitives/CustomButton.js +0 -10
  89. package/dist/components/primitives/CustomHTML.d.ts +0 -8
  90. package/dist/components/primitives/CustomHTML.d.ts.map +0 -1
  91. package/dist/components/primitives/CustomHTML.js +0 -5
  92. package/dist/components/primitives/FileUpload.d.ts +0 -18
  93. package/dist/components/primitives/FileUpload.d.ts.map +0 -1
  94. package/dist/components/primitives/FileUpload.js +0 -16
  95. package/dist/components/primitives/InputBox.d.ts +0 -34
  96. package/dist/components/primitives/InputBox.d.ts.map +0 -1
  97. package/dist/components/primitives/InputBox.js +0 -25
  98. package/dist/components/primitives/Lottie.d.ts +0 -11
  99. package/dist/components/primitives/Lottie.d.ts.map +0 -1
  100. package/dist/components/primitives/Lottie.js +0 -5
  101. package/dist/components/primitives/MediaEmbed.d.ts +0 -13
  102. package/dist/components/primitives/MediaEmbed.d.ts.map +0 -1
  103. package/dist/components/primitives/MediaEmbed.js +0 -6
  104. package/dist/components/primitives/MediaImage.d.ts +0 -8
  105. package/dist/components/primitives/MediaImage.d.ts.map +0 -1
  106. package/dist/components/primitives/MediaImage.js +0 -5
  107. package/dist/components/primitives/OptionSelector.d.ts +0 -35
  108. package/dist/components/primitives/OptionSelector.d.ts.map +0 -1
  109. package/dist/components/primitives/OptionSelector.js +0 -8
  110. package/dist/components/primitives/PaypalCheckout.d.ts +0 -25
  111. package/dist/components/primitives/PaypalCheckout.d.ts.map +0 -1
  112. package/dist/components/primitives/PaypalCheckout.js +0 -5
  113. package/dist/components/primitives/PlainText.d.ts +0 -6
  114. package/dist/components/primitives/PlainText.d.ts.map +0 -1
  115. package/dist/components/primitives/PlainText.js +0 -5
  116. package/dist/components/primitives/ProgressBar.d.ts +0 -15
  117. package/dist/components/primitives/ProgressBar.d.ts.map +0 -1
  118. package/dist/components/primitives/ProgressBar.js +0 -5
  119. package/dist/components/primitives/RichText.d.ts +0 -6
  120. package/dist/components/primitives/RichText.d.ts.map +0 -1
  121. package/dist/components/primitives/RichText.js +0 -5
  122. package/dist/components/primitives/RichTextMarkdown.d.ts +0 -6
  123. package/dist/components/primitives/RichTextMarkdown.d.ts.map +0 -1
  124. package/dist/components/primitives/RichTextMarkdown.js +0 -5
  125. package/dist/components/primitives/Rive.d.ts +0 -16
  126. package/dist/components/primitives/Rive.d.ts.map +0 -1
  127. package/dist/components/primitives/Rive.js +0 -8
  128. package/dist/components/primitives/StripeCheckout.d.ts +0 -52
  129. package/dist/components/primitives/StripeCheckout.d.ts.map +0 -1
  130. package/dist/components/primitives/StripeCheckout.js +0 -5
  131. package/dist/components/primitives/StripeCheckout2.d.ts +0 -30
  132. package/dist/components/primitives/StripeCheckout2.d.ts.map +0 -1
  133. package/dist/components/primitives/StripeCheckout2.js +0 -7
  134. package/dist/config/index.d.ts +0 -23
  135. package/dist/config/index.d.ts.map +0 -1
  136. package/dist/config/index.js +0 -42
  137. package/dist/constants.d.ts +0 -9
  138. package/dist/constants.d.ts.map +0 -1
  139. package/dist/constants.js +0 -9
  140. package/dist/helpers/TEMP helpers file.d.ts +0 -1
  141. package/dist/helpers/TEMP helpers file.d.ts.map +0 -1
  142. package/dist/helpers/TEMP helpers file.js +0 -1
  143. package/dist/helpers/dates.d.ts +0 -5
  144. package/dist/helpers/dates.d.ts.map +0 -1
  145. package/dist/helpers/dates.js +0 -7
  146. package/dist/helpers/json.d.ts +0 -47
  147. package/dist/helpers/json.d.ts.map +0 -1
  148. package/dist/helpers/json.js +0 -622
  149. package/dist/helpers/utils.d.ts +0 -13
  150. package/dist/helpers/utils.d.ts.map +0 -1
  151. package/dist/helpers/utils.js +0 -28
  152. package/dist/logger.d.ts +0 -11
  153. package/dist/logger.d.ts.map +0 -1
  154. package/dist/logger.js +0 -21
  155. package/dist/prompts/branches.d.ts +0 -20
  156. package/dist/prompts/branches.d.ts.map +0 -1
  157. package/dist/prompts/branches.js +0 -90
  158. package/dist/prompts/embeddables.d.ts +0 -43
  159. package/dist/prompts/embeddables.d.ts.map +0 -1
  160. package/dist/prompts/embeddables.js +0 -198
  161. package/dist/prompts/experiments.d.ts +0 -28
  162. package/dist/prompts/experiments.d.ts.map +0 -1
  163. package/dist/prompts/experiments.js +0 -87
  164. package/dist/prompts/index.d.ts +0 -11
  165. package/dist/prompts/index.d.ts.map +0 -1
  166. package/dist/prompts/index.js +0 -6
  167. package/dist/prompts/projects.d.ts +0 -22
  168. package/dist/prompts/projects.d.ts.map +0 -1
  169. package/dist/prompts/projects.js +0 -86
  170. package/dist/prompts/versions.d.ts +0 -18
  171. package/dist/prompts/versions.d.ts.map +0 -1
  172. package/dist/prompts/versions.js +0 -99
  173. package/dist/proxy/injectApiInterceptor.d.ts +0 -6
  174. package/dist/proxy/injectApiInterceptor.d.ts.map +0 -1
  175. package/dist/proxy/injectApiInterceptor.js +0 -66
  176. package/dist/proxy/injectReload.d.ts +0 -2
  177. package/dist/proxy/injectReload.d.ts.map +0 -1
  178. package/dist/proxy/injectReload.js +0 -14
  179. package/dist/proxy/injectWorkbench.d.ts +0 -5
  180. package/dist/proxy/injectWorkbench.d.ts.map +0 -1
  181. package/dist/proxy/injectWorkbench.js +0 -22
  182. package/dist/proxy/server.d.ts +0 -11
  183. package/dist/proxy/server.d.ts.map +0 -1
  184. package/dist/proxy/server.js +0 -316
  185. package/dist/proxy/sse.d.ts +0 -5
  186. package/dist/proxy/sse.d.ts.map +0 -1
  187. package/dist/proxy/sse.js +0 -17
  188. package/dist/sentry-context.d.ts +0 -48
  189. package/dist/sentry-context.d.ts.map +0 -1
  190. package/dist/sentry-context.js +0 -156
  191. package/dist/stdout.d.ts +0 -17
  192. package/dist/stdout.d.ts.map +0 -1
  193. package/dist/stdout.js +0 -23
  194. package/dist/types-builder.d.ts +0 -800
  195. package/dist/types-builder.d.ts.map +0 -1
  196. package/dist/types-builder.js +0 -20
  197. package/dist/workbench/ActionsPanel.d.ts +0 -6
  198. package/dist/workbench/ActionsPanel.d.ts.map +0 -1
  199. package/dist/workbench/ActionsPanel.js +0 -47
  200. package/dist/workbench/AutofillPanel.d.ts +0 -6
  201. package/dist/workbench/AutofillPanel.d.ts.map +0 -1
  202. package/dist/workbench/AutofillPanel.js +0 -543
  203. package/dist/workbench/ComputedFieldsPanel.d.ts +0 -6
  204. package/dist/workbench/ComputedFieldsPanel.d.ts.map +0 -1
  205. package/dist/workbench/ComputedFieldsPanel.js +0 -31
  206. package/dist/workbench/ExperimentsPanel.d.ts +0 -6
  207. package/dist/workbench/ExperimentsPanel.d.ts.map +0 -1
  208. package/dist/workbench/ExperimentsPanel.js +0 -182
  209. package/dist/workbench/FieldEditorPanel.d.ts +0 -9
  210. package/dist/workbench/FieldEditorPanel.d.ts.map +0 -1
  211. package/dist/workbench/FieldEditorPanel.js +0 -650
  212. package/dist/workbench/InspectorPanel.d.ts +0 -6
  213. package/dist/workbench/InspectorPanel.d.ts.map +0 -1
  214. package/dist/workbench/InspectorPanel.js +0 -341
  215. package/dist/workbench/PageNavigator.d.ts +0 -6
  216. package/dist/workbench/PageNavigator.d.ts.map +0 -1
  217. package/dist/workbench/PageNavigator.js +0 -123
  218. package/dist/workbench/SchemaPanel.d.ts +0 -6
  219. package/dist/workbench/SchemaPanel.d.ts.map +0 -1
  220. package/dist/workbench/SchemaPanel.js +0 -222
  221. package/dist/workbench/UserDataPanel.d.ts +0 -6
  222. package/dist/workbench/UserDataPanel.d.ts.map +0 -1
  223. package/dist/workbench/UserDataPanel.js +0 -350
  224. package/dist/workbench/WorkbenchApp.d.ts +0 -7
  225. package/dist/workbench/WorkbenchApp.d.ts.map +0 -1
  226. package/dist/workbench/WorkbenchApp.js +0 -193
  227. package/dist/workbench/cloudflare-worker/README.md +0 -31
  228. package/dist/workbench/cloudflare-worker/public/workbench.css +0 -1614
  229. package/dist/workbench/cloudflare-worker/public/workbench.js +0 -77
  230. package/dist/workbench/cloudflare-worker/worker.js +0 -40
  231. package/dist/workbench/cloudflare-worker/wrangler.toml +0 -10
  232. package/dist/workbench/index.d.ts +0 -10
  233. package/dist/workbench/index.d.ts.map +0 -1
  234. package/dist/workbench/index.js +0 -44
  235. package/dist/workbench/workbench.css +0 -1614
  236. package/dist/workbench/workbench.js +0 -77
@@ -1,99 +0,0 @@
1
- import pc from 'picocolors';
2
- import prompts from 'prompts';
3
- import { getAuthenticatedSupabaseClient } from '../auth/index.js';
4
- import * as stdout from '../stdout.js';
5
- import { formatDate } from '../helpers/dates.js';
6
- const RECENT_VERSIONS_LIMIT = 100;
7
- /**
8
- * Fetch up to 100 most recent version numbers for an embeddable (flow).
9
- * Uses flow_versions for the given flow_id and branch (null = main).
10
- * Returns unique version numbers in descending order.
11
- */
12
- export async function fetchRecentVersions(flowId, branchId) {
13
- const supabase = await getAuthenticatedSupabaseClient();
14
- if (!supabase) {
15
- return [];
16
- }
17
- try {
18
- let query = supabase
19
- .from('flow_versions')
20
- .select('version_number, created_at')
21
- .eq('flow_id', flowId)
22
- .order('version_number', { ascending: false })
23
- .limit(RECENT_VERSIONS_LIMIT * 2); // fetch extra then dedupe
24
- if (branchId === null) {
25
- query = query.is('branch_id', null);
26
- }
27
- else {
28
- query = query.eq('branch_id', branchId);
29
- }
30
- const { data, error } = await query;
31
- if (error) {
32
- stdout.warn(pc.yellow(`Could not fetch versions: ${error.message}`));
33
- return [];
34
- }
35
- // Dedupe by version_number, preserving order (most recent first)
36
- const seen = new Set();
37
- const versions = [];
38
- for (const row of data || []) {
39
- const v = row.version_number;
40
- if (typeof v !== 'number' || seen.has(v))
41
- continue;
42
- seen.add(v);
43
- versions.push({
44
- version_number: v,
45
- created_at: row.created_at ?? null,
46
- });
47
- if (versions.length >= RECENT_VERSIONS_LIMIT)
48
- break;
49
- }
50
- return versions;
51
- }
52
- catch (err) {
53
- stdout.warn(pc.yellow(`Could not fetch versions: ${err}`));
54
- return [];
55
- }
56
- }
57
- /**
58
- * Prompt the user to select a version from the list.
59
- * Returns the selected version number, or null for "Latest".
60
- */
61
- export async function promptForVersion(versions, options = {}) {
62
- const choices = [];
63
- if (versions.length === 0) {
64
- choices.push({
65
- title: pc.bold('Latest'),
66
- value: 'latest',
67
- description: 'Current published version',
68
- });
69
- }
70
- else {
71
- for (let i = 0; i < versions.length; i++) {
72
- const v = versions[i];
73
- const date = v.created_at ? formatDate(v.created_at) : '';
74
- const isLatest = i === 0;
75
- choices.push({
76
- title: isLatest ? `Version ${v.version_number} (Latest)` : `Version ${v.version_number}`,
77
- value: isLatest ? 'latest' : v.version_number,
78
- description: date || undefined,
79
- });
80
- }
81
- }
82
- const response = await prompts({
83
- type: 'autocomplete',
84
- name: 'version',
85
- message: options.message ?? 'Select a version to pull:',
86
- choices,
87
- suggest: (input, choicesList) => Promise.resolve(choicesList.filter((c) => c.value === 'latest' ||
88
- String(c.value).includes(input) ||
89
- (typeof c.title === 'string' && c.title.toLowerCase().includes(input.toLowerCase())))),
90
- }, {
91
- onCancel: () => {
92
- process.exit(0);
93
- },
94
- });
95
- if (response.version === 'latest' || response.version === undefined) {
96
- return null;
97
- }
98
- return typeof response.version === 'number' ? response.version : null;
99
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * Injects a script that intercepts fetch/XHR calls to the remote engine
3
- * and rewrites them to go through the local proxy instead.
4
- */
5
- export declare function injectApiInterceptor(html: string, remoteOrigin: string): string;
6
- //# sourceMappingURL=injectApiInterceptor.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"injectApiInterceptor.d.ts","sourceRoot":"","sources":["../../src/proxy/injectApiInterceptor.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAiE/E"}
@@ -1,66 +0,0 @@
1
- /**
2
- * Injects a script that intercepts fetch/XHR calls to the remote engine
3
- * and rewrites them to go through the local proxy instead.
4
- */
5
- export function injectApiInterceptor(html, remoteOrigin) {
6
- // This script needs to run BEFORE any other scripts, so inject into <head>
7
- const lower = html.toLowerCase();
8
- const headCloseIndex = lower.indexOf('</head>');
9
- // The interceptor script - patches fetch and XMLHttpRequest
10
- const interceptorScript = `<script>(function(){
11
- var remoteOrigin = ${JSON.stringify(remoteOrigin)};
12
- var localOrigin = window.location.origin;
13
-
14
- // Helper to rewrite URLs
15
- function rewriteUrl(url) {
16
- if (typeof url === 'string' && url.startsWith(remoteOrigin)) {
17
- var newUrl = url.replace(remoteOrigin, localOrigin);
18
- console.log('[DevProxy] Intercepted:', url, '->', newUrl);
19
- return newUrl;
20
- }
21
- if (url instanceof URL && url.origin === remoteOrigin) {
22
- var newUrl = new URL(url.pathname + url.search + url.hash, localOrigin);
23
- console.log('[DevProxy] Intercepted:', url.href, '->', newUrl.href);
24
- return newUrl;
25
- }
26
- return url;
27
- }
28
-
29
- // Patch fetch
30
- var originalFetch = window.fetch;
31
- window.fetch = function(input, init) {
32
- if (typeof input === 'string') {
33
- input = rewriteUrl(input);
34
- } else if (input instanceof Request) {
35
- var newUrl = rewriteUrl(input.url);
36
- if (newUrl !== input.url) {
37
- input = new Request(newUrl, input);
38
- }
39
- } else if (input instanceof URL) {
40
- input = rewriteUrl(input);
41
- }
42
- return originalFetch.call(this, input, init);
43
- };
44
-
45
- // Patch XMLHttpRequest
46
- var originalXHROpen = XMLHttpRequest.prototype.open;
47
- XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
48
- url = rewriteUrl(url);
49
- return originalXHROpen.call(this, method, url, async, user, password);
50
- };
51
-
52
- console.log('[DevProxy] API interceptor installed, rewriting', remoteOrigin, 'to', localOrigin);
53
- })();</script>`;
54
- const injection = `\n${interceptorScript}\n`;
55
- if (headCloseIndex === -1) {
56
- // No </head> tag found; try to inject after <head> or at the start
57
- const headOpenIndex = lower.indexOf('<head>');
58
- if (headOpenIndex !== -1) {
59
- const insertPos = headOpenIndex + '<head>'.length;
60
- return html.slice(0, insertPos) + injection + html.slice(insertPos);
61
- }
62
- // No head at all, prepend to document
63
- return injection + html;
64
- }
65
- return html.slice(0, headCloseIndex) + injection + html.slice(headCloseIndex);
66
- }
@@ -1,2 +0,0 @@
1
- export declare function injectReloadScript(html: string): string;
2
- //# sourceMappingURL=injectReload.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"injectReload.d.ts","sourceRoot":"","sources":["../../src/proxy/injectReload.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBvD"}
@@ -1,14 +0,0 @@
1
- export function injectReloadScript(html) {
2
- const lower = html.toLowerCase();
3
- const bodyCloseIndex = lower.lastIndexOf('</body>');
4
- const reloadScript = '<script>(function(){' +
5
- 'var es = new EventSource("/__embeddables_reload");' +
6
- 'es.addEventListener("reload", function() { window.location.reload(); });' +
7
- '})();</script>';
8
- const injection = `\n${reloadScript}\n`;
9
- if (bodyCloseIndex === -1) {
10
- // No </body> tag found; append at the end
11
- return html + injection;
12
- }
13
- return html.slice(0, bodyCloseIndex) + injection + html.slice(bodyCloseIndex);
14
- }
@@ -1,5 +0,0 @@
1
- export declare function injectWorkbenchHtml(html: string, opts: {
2
- embeddableId: string;
3
- workbenchOrigin?: string;
4
- }): string;
5
- //# sourceMappingURL=injectWorkbench.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"injectWorkbench.d.ts","sourceRoot":"","sources":["../../src/proxy/injectWorkbench.ts"],"names":[],"mappings":"AAAA,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GACvD,MAAM,CA8BR"}
@@ -1,22 +0,0 @@
1
- export function injectWorkbenchHtml(html, opts) {
2
- const lower = html.toLowerCase();
3
- const bodyCloseIndex = lower.lastIndexOf('</body>');
4
- const isLocalDev = !opts.workbenchOrigin;
5
- const container = '<div id="__embeddables_workbench_root"></div>';
6
- const configScript = `<script>(function(){` +
7
- 'window.__EMBEDDABLES_WORKBENCH = window.__EMBEDDABLES_WORKBENCH || {};' +
8
- `window.__EMBEDDABLES_WORKBENCH.embeddableId = ${JSON.stringify(opts.embeddableId)};` +
9
- `window.__EMBEDDABLES_WORKBENCH.localDev = ${JSON.stringify(isLocalDev)};` +
10
- '})();</script>';
11
- // When a remote origin is provided, load from the CDN; otherwise use the local proxy path.
12
- const jsUrl = opts.workbenchOrigin
13
- ? `${opts.workbenchOrigin}/workbench.js`
14
- : '/__embeddables_workbench.js';
15
- const scriptTag = `<script src="${jsUrl}" onload="if(typeof window.__embeddables_bootstrap_workbench==='function'){window.__embeddables_bootstrap_workbench({embeddableId:window.__EMBEDDABLES_WORKBENCH.embeddableId,localDev:window.__EMBEDDABLES_WORKBENCH.localDev});}"></script>`;
16
- const injection = `\n${container}\n${configScript}\n${scriptTag}\n`;
17
- if (bodyCloseIndex === -1) {
18
- // No </body> tag found; append at the end
19
- return html + injection;
20
- }
21
- return html.slice(0, bodyCloseIndex) + injection + html.slice(bodyCloseIndex);
22
- }
@@ -1,11 +0,0 @@
1
- export declare function startProxyServer(opts: {
2
- port: number;
3
- engineOrigin: string;
4
- overrideRoute: string;
5
- generatedJsonPath: string;
6
- embeddableId: string;
7
- watchWorkbench?: boolean;
8
- }): Promise<{
9
- broadcastReload: () => void;
10
- }>;
11
- //# sourceMappingURL=server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAoCA,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,iBAAiB,EAAE,MAAM,CAAA;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;;GA0UA"}
@@ -1,316 +0,0 @@
1
- import express from 'express';
2
- import fs from 'node:fs';
3
- import path from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- import { createProxyMiddleware } from 'http-proxy-middleware';
6
- import * as esbuild from 'esbuild';
7
- import chokidar from 'chokidar';
8
- import postcss from 'postcss';
9
- import tailwindcss from '@tailwindcss/postcss';
10
- import autoprefixer from 'autoprefixer';
11
- import { attachSse } from './sse.js';
12
- import { injectWorkbenchHtml } from './injectWorkbench.js';
13
- import { injectReloadScript } from './injectReload.js';
14
- import { injectApiInterceptor } from './injectApiInterceptor.js';
15
- import { WORKBENCH_CDN_ORIGIN } from '../constants.js';
16
- import * as stdout from '../stdout.js';
17
- // Resolve the CLI package root so workbench paths work regardless of cwd.
18
- // This file lives at src/proxy/server.ts (or dist/proxy/server.js when compiled),
19
- // so the package root is two directories up.
20
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
21
- const CLI_ROOT = path.resolve(__dirname, '..', '..');
22
- /**
23
- * Detect whether the CLI is running from a local development checkout
24
- * (e.g. via `npm link` or `tsx`) rather than a regular `npm install -g`.
25
- *
26
- * Heuristic: the `src/workbench/` source directory only exists in the repo
27
- * checkout — it is excluded from the published package (`files` in package.json
28
- * only ships `bin/` and `dist/`).
29
- */
30
- function isLocalDev() {
31
- const workbenchSrcDir = path.join(CLI_ROOT, 'src', 'workbench', 'index.tsx');
32
- return fs.existsSync(workbenchSrcDir);
33
- }
34
- export async function startProxyServer(opts) {
35
- const app = express();
36
- const localDev = isLocalDev();
37
- // ---------- Local-dev mode: build workbench from source ----------
38
- // Resolve workbench paths relative to the CLI package root, not process.cwd()
39
- const workbenchEntry = path.join(CLI_ROOT, 'src', 'workbench', 'index.tsx');
40
- const workbenchDir = path.join(CLI_ROOT, 'src', 'workbench');
41
- const workbenchCssEntry = path.join(CLI_ROOT, 'src', 'workbench', 'workbench.css');
42
- let workbenchBundle = null;
43
- let workbenchCss = null;
44
- // The origin used when injecting the workbench <script>/<link> tags.
45
- // undefined → local proxy paths (/__embeddables_workbench.{js,css})
46
- // string → remote CDN origin (e.g. https://embeddables-workbench.heysavvy.workers.dev)
47
- const workbenchOrigin = localDev ? undefined : WORKBENCH_CDN_ORIGIN;
48
- if (localDev) {
49
- stdout.print('[Workbench] Local dev mode — building workbench from source');
50
- }
51
- else {
52
- stdout.print(`[Workbench] Installed mode — loading workbench from CDN (${WORKBENCH_CDN_ORIGIN})`);
53
- }
54
- const buildWorkbench = async () => {
55
- try {
56
- const result = await esbuild.build({
57
- entryPoints: [workbenchEntry],
58
- bundle: true,
59
- format: 'iife',
60
- globalName: '__EmbeddablesWorkbenchBundle',
61
- platform: 'browser',
62
- write: false,
63
- sourcemap: 'inline',
64
- });
65
- const outputFile = result.outputFiles?.[0];
66
- if (outputFile) {
67
- workbenchBundle = outputFile.contents;
68
- }
69
- else {
70
- workbenchBundle = null;
71
- }
72
- const rawCss = fs.readFileSync(workbenchCssEntry, 'utf8');
73
- const cssResult = await postcss([tailwindcss(), autoprefixer]).process(rawCss, {
74
- from: workbenchCssEntry,
75
- });
76
- workbenchCss = cssResult.css;
77
- if (workbenchBundle) {
78
- stdout.print('[Workbench] Bundle built successfully');
79
- return true;
80
- }
81
- stdout.warn('[Workbench] Bundle build completed but no output file found');
82
- return false;
83
- }
84
- catch (err) {
85
- stdout.warn(`[Workbench] Failed to build Workbench bundle. Workbench UI will be unavailable. ${err instanceof Error ? err.message : String(err)}`);
86
- workbenchCss = null;
87
- return false;
88
- }
89
- };
90
- // Only build from source in local-dev mode
91
- if (localDev) {
92
- await buildWorkbench();
93
- }
94
- // Add JSON body parsing middleware
95
- app.use(express.json());
96
- app.use(express.urlencoded({ extended: true }));
97
- const { broadcastReload } = attachSse(app);
98
- // Watch workbench files if enabled (only meaningful in local-dev mode)
99
- if (localDev && opts.watchWorkbench) {
100
- const workbenchGlob = path.join(workbenchDir, '**/*');
101
- const watcher = chokidar.watch(workbenchGlob, {
102
- ignoreInitial: true,
103
- });
104
- let rebuildTimeout;
105
- watcher.on('all', async () => {
106
- clearTimeout(rebuildTimeout);
107
- rebuildTimeout = setTimeout(async () => {
108
- stdout.print('[Workbench] Files changed, rebuilding bundle...');
109
- const success = await buildWorkbench();
110
- if (success) {
111
- broadcastReload();
112
- stdout.print('[Workbench] Bundle rebuilt and reload broadcast');
113
- }
114
- }, 100);
115
- });
116
- stdout.print(`[Workbench] Watching ${workbenchGlob} for changes`);
117
- }
118
- // Serve the Workbench bundle as a static asset (local-dev mode only)
119
- if (localDev) {
120
- app.get('/__embeddables_workbench.js', (_req, res) => {
121
- if (!workbenchBundle) {
122
- res
123
- .status(503)
124
- .type('text/plain')
125
- .send('Workbench bundle is not available. Check dev server logs.');
126
- return;
127
- }
128
- res.setHeader('Content-Type', 'application/javascript; charset=utf-8');
129
- res.setHeader('Cache-Control', 'no-store');
130
- res.send(Buffer.from(workbenchBundle));
131
- });
132
- app.get('/__embeddables_workbench.css', (_req, res) => {
133
- if (!workbenchCss) {
134
- res
135
- .status(503)
136
- .type('text/plain')
137
- .send('Workbench CSS is not available. Check dev server logs.');
138
- return;
139
- }
140
- res.setHeader('Content-Type', 'text/css; charset=utf-8');
141
- res.setHeader('Cache-Control', 'no-store');
142
- res.send(workbenchCss);
143
- });
144
- }
145
- // Intercept GET requests to overrideRoute: convert to POST and add generated JSON to body
146
- app.get(opts.overrideRoute, async (req, res) => {
147
- stdout.print(`[/init] Intercepted GET ${opts.overrideRoute}, query: ${JSON.stringify(req.query)}`);
148
- try {
149
- // Load the generated JSON
150
- const raw = fs.readFileSync(opts.generatedJsonPath, 'utf8');
151
- const generatedJson = JSON.parse(raw);
152
- generatedJson.id = opts.embeddableId;
153
- stdout.print(`[/init] Loaded local JSON, pages: ${generatedJson.pages?.length ?? 0}`);
154
- // When the flow has content_sources (CMS), the remote engine needs flow metadata
155
- // (project_id) to load them. Without an engine that supports dev + CMS, the request
156
- // fails. So we omit content_sources so the page loads; CMS-backed content will be
157
- // empty in dev.
158
- const hasContentSources = Array.isArray(generatedJson.content_sources) && generatedJson.content_sources.length > 0;
159
- const flowToSend = hasContentSources
160
- ? (() => {
161
- const { content_sources: _, ...rest } = generatedJson;
162
- return rest;
163
- })()
164
- : generatedJson;
165
- if (hasContentSources) {
166
- stdout.print(`[/init] Omitting content_sources so dev loads (CMS content will be empty in preview).`);
167
- }
168
- // Create POST request body with the JSON
169
- const postBody = {
170
- json: {
171
- flow: flowToSend,
172
- flowId: generatedJson.id,
173
- groupId: 'group_test',
174
- },
175
- };
176
- // Build the target URL with query parameters
177
- const queryString = new URLSearchParams(req.query).toString();
178
- const targetUrl = `${opts.engineOrigin}/init${queryString ? `?${queryString}` : ''}`;
179
- stdout.print(`[/init] Forwarding to engine: POST ${targetUrl}`);
180
- // Forward headers from original request (excluding problematic ones)
181
- const headers = {};
182
- for (const [key, value] of Object.entries(req.headers)) {
183
- if (!['host', 'connection', 'content-length'].includes(key.toLowerCase())) {
184
- if (typeof value === 'string') {
185
- headers[key] = value;
186
- }
187
- else if (Array.isArray(value) && value.length > 0) {
188
- headers[key] = value[0];
189
- }
190
- }
191
- }
192
- headers['Content-Type'] = 'application/json';
193
- // Forward the modified request to the engine as POST
194
- const engineResponse = await fetch(targetUrl, {
195
- method: 'POST',
196
- headers,
197
- body: JSON.stringify(postBody),
198
- });
199
- // Parse and forward the response
200
- const responseBody = await engineResponse.json();
201
- stdout.print(`[/init] Engine response: status=${engineResponse.status}, hasFlow=${!!responseBody?.flow}, flowPages=${responseBody?.flow?.pages?.length ?? 'N/A'}`);
202
- res.setHeader('Content-Type', 'application/json; charset=utf-8');
203
- res.setHeader('Cache-Control', 'no-store');
204
- return res.status(engineResponse.status).send(JSON.stringify(responseBody));
205
- }
206
- catch (err) {
207
- stdout.error(`Failed to modify /init request: ${err instanceof Error ? err.message : String(err)}`);
208
- if (!res.headersSent) {
209
- res.status(500).json({
210
- error: 'Failed to modify /init request',
211
- details: err?.message ?? String(err),
212
- path: opts.generatedJsonPath,
213
- });
214
- }
215
- }
216
- });
217
- // For GET / from localhost: fetch HTML from engine, inject Workbench, then send.
218
- // This avoids selfHandleResponse/responseInterceptor which were causing the proxy to hang.
219
- app.get('/', async (req, res, next) => {
220
- const host = (req.headers.host ?? '').toString();
221
- const isLocalhost = host.startsWith('localhost') || host.startsWith('127.0.0.1');
222
- stdout.print(`[Workbench] GET / handler: host=${host}, isLocalhost=${isLocalhost}, url=${req.url}`);
223
- if (!isLocalhost) {
224
- stdout.print('[Workbench] Not localhost, skipping injection');
225
- return next();
226
- }
227
- const targetUrl = `${opts.engineOrigin}${req.url}`;
228
- stdout.print(`[Workbench] Fetching from engine: ${targetUrl}`);
229
- try {
230
- const headers = {};
231
- for (const [key, value] of Object.entries(req.headers)) {
232
- if (!['host', 'connection'].includes(key.toLowerCase())) {
233
- if (typeof value === 'string')
234
- headers[key] = value;
235
- else if (Array.isArray(value) && value[0])
236
- headers[key] = value[0];
237
- }
238
- }
239
- const engineRes = await fetch(targetUrl, { method: 'GET', headers });
240
- const contentType = engineRes.headers.get('content-type') ?? '';
241
- stdout.print(`[Workbench] Engine response: status=${engineRes.status}, content-type=${contentType}`);
242
- if (!contentType.includes('text/html')) {
243
- stdout.print('[Workbench] Not HTML, proxying normally');
244
- return next();
245
- }
246
- const html = await engineRes.text();
247
- stdout.print(`[Workbench] Got HTML (${html.length} chars), injecting Workbench...`);
248
- let modifiedHtml = html;
249
- // If proxying to a remote engine, inject API interceptor to rewrite absolute URLs
250
- const isRemoteEngine = !opts.engineOrigin.includes('localhost') && !opts.engineOrigin.includes('127.0.0.1');
251
- if (isRemoteEngine) {
252
- modifiedHtml = injectApiInterceptor(modifiedHtml, opts.engineOrigin);
253
- stdout.print(`[Workbench] Injected API interceptor for ${opts.engineOrigin}`);
254
- }
255
- modifiedHtml = injectReloadScript(modifiedHtml);
256
- const includeWorkbench = req.query?.workbench !== 'false';
257
- if (includeWorkbench) {
258
- modifiedHtml = injectWorkbenchHtml(modifiedHtml, {
259
- embeddableId: opts.embeddableId,
260
- workbenchOrigin,
261
- });
262
- }
263
- else {
264
- console.log('[Workbench] Skipping workbench (workbench=false in URL)');
265
- }
266
- stdout.print(`[Workbench] Injection complete (${modifiedHtml.length} chars), sending response`);
267
- res.setHeader('Content-Type', 'text/html; charset=utf-8');
268
- res.setHeader('Cache-Control', engineRes.headers.get('cache-control') ?? 'no-store');
269
- res.status(engineRes.status).send(modifiedHtml);
270
- }
271
- catch (err) {
272
- stdout.error(`[Workbench] Error fetching/injecting HTML: ${err instanceof Error ? err.message : String(err)}`);
273
- next();
274
- }
275
- });
276
- // Proxy everything else to the engine (no response interception)
277
- app.use('/', createProxyMiddleware({
278
- target: opts.engineOrigin,
279
- changeOrigin: true,
280
- ws: true,
281
- on: {
282
- proxyReq: (proxyReq, req) => {
283
- stdout.print(`[Proxy] ${req.method} ${req.url} → ${opts.engineOrigin}${req.url}`);
284
- },
285
- error: (err, req, res) => {
286
- // ECONNRESET/ECONNABORTED often happen when the client navigates away or the
287
- // upstream closes the connection; treat as non-fatal and log at debug level.
288
- const code = err?.code ?? err?.errno;
289
- const isConnectionClosed = code === 'ECONNRESET' || code === 'ECONNABORTED' || code === -54;
290
- if (isConnectionClosed) {
291
- stdout.print(`[Proxy] Connection closed (client or upstream): ${err.message}`);
292
- }
293
- else {
294
- stdout.error(`[Proxy] Error proxying request: ${err instanceof Error ? err.message : String(err)}`);
295
- }
296
- if (!res.headersSent) {
297
- res.status(500).send('Proxy error');
298
- }
299
- },
300
- },
301
- }));
302
- app.listen(opts.port, () => {
303
- stdout.print(`Dev proxy: http://localhost:${opts.port}`);
304
- stdout.print(` → Engine: ${opts.engineOrigin}`);
305
- stdout.print(`Override route: GET ${opts.overrideRoute}`);
306
- stdout.print(`Serving: ${opts.generatedJsonPath}`);
307
- stdout.print(`Reload SSE: /__embeddables_reload`);
308
- if (localDev) {
309
- stdout.print(`Workbench: built from local source`);
310
- }
311
- else {
312
- stdout.print(`Workbench: served from ${WORKBENCH_CDN_ORIGIN}`);
313
- }
314
- });
315
- return { broadcastReload };
316
- }
@@ -1,5 +0,0 @@
1
- import type express from 'express';
2
- export declare function attachSse(app: express.Express): {
3
- broadcastReload: () => void;
4
- };
5
- //# sourceMappingURL=sse.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/proxy/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAElC,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO;;EAoB7C"}
package/dist/proxy/sse.js DELETED
@@ -1,17 +0,0 @@
1
- export function attachSse(app) {
2
- const clients = new Set();
3
- app.get('/__embeddables_reload', (req, res) => {
4
- res.setHeader('Content-Type', 'text/event-stream');
5
- res.setHeader('Cache-Control', 'no-store');
6
- res.setHeader('Connection', 'keep-alive');
7
- res.flushHeaders?.();
8
- clients.add(res);
9
- req.on('close', () => clients.delete(res));
10
- });
11
- function broadcastReload() {
12
- for (const res of clients) {
13
- res.write(`event: reload\ndata: ${Date.now()}\n\n`);
14
- }
15
- }
16
- return { broadcastReload };
17
- }
@@ -1,48 +0,0 @@
1
- export interface SentryContextUser {
2
- id: string;
3
- email?: string | null;
4
- }
5
- export interface SentryContextProject {
6
- id: string;
7
- title?: string | null;
8
- }
9
- export interface SentryContextOrg {
10
- id: string;
11
- title?: string | null;
12
- }
13
- export interface SentryContextEmbeddable {
14
- id: string;
15
- title?: string | null;
16
- }
17
- export interface SentryContextBranch {
18
- id: string;
19
- name?: string | null;
20
- }
21
- export interface SentryContextInput {
22
- user?: SentryContextUser | null;
23
- project?: SentryContextProject | null;
24
- org?: SentryContextOrg | null;
25
- embeddable?: SentryContextEmbeddable | null;
26
- branch?: SentryContextBranch | null;
27
- versionNumber?: number | null;
28
- }
29
- /**
30
- * Set Sentry scope with the given context. Only sets keys that are present and have valid values.
31
- * Uses setUser/setContext for error events and setAttributes on the current scope so values
32
- * (project, org, embeddable, branch, versionNumber) are included in log events.
33
- */
34
- export declare function setSentryContext(ctx: SentryContextInput): void;
35
- /**
36
- * Return project and org context from embeddables.json when present.
37
- */
38
- export declare function getSentryContextFromProjectConfig(): Partial<SentryContextInput>;
39
- /**
40
- * Return embeddable title (from metadata.json), branch and versionNumber (from config.json)
41
- * for embeddables/{embeddableId}/ when present.
42
- */
43
- export declare function getSentryContextFromEmbeddableConfig(embeddableId: string): Partial<SentryContextInput>;
44
- /**
45
- * Set Sentry user from auth when logged in. Call after requireLogin for commands that need user context.
46
- */
47
- export declare function setSentryUserFromAuth(): Promise<void>;
48
- //# sourceMappingURL=sentry-context.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sentry-context.d.ts","sourceRoot":"","sources":["../src/sentry-context.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC/B,OAAO,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAA;IACrC,GAAG,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAA;IAC7B,UAAU,CAAC,EAAE,uBAAuB,GAAG,IAAI,CAAA;IAC3C,MAAM,CAAC,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACnC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI,CA4D9D;AAED;;GAEG;AACH,wBAAgB,iCAAiC,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAW/E;AAED;;;GAGG;AACH,wBAAgB,oCAAoC,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA6CtG;AAED;;GAEG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAY3D"}