@embeddables/cli 0.1.0

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 (173) hide show
  1. package/README.md +116 -0
  2. package/bin/embeddables.mjs +2 -0
  3. package/dist/auth/index.d.ts +43 -0
  4. package/dist/auth/index.d.ts.map +1 -0
  5. package/dist/auth/index.js +100 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +75 -0
  9. package/dist/commands/build-workbench.d.ts +5 -0
  10. package/dist/commands/build-workbench.d.ts.map +1 -0
  11. package/dist/commands/build-workbench.js +122 -0
  12. package/dist/commands/build.d.ts +7 -0
  13. package/dist/commands/build.d.ts.map +1 -0
  14. package/dist/commands/build.js +22 -0
  15. package/dist/commands/dev.d.ts +11 -0
  16. package/dist/commands/dev.d.ts.map +1 -0
  17. package/dist/commands/dev.js +153 -0
  18. package/dist/commands/login.d.ts +2 -0
  19. package/dist/commands/login.d.ts.map +1 -0
  20. package/dist/commands/login.js +112 -0
  21. package/dist/commands/logout.d.ts +2 -0
  22. package/dist/commands/logout.d.ts.map +1 -0
  23. package/dist/commands/logout.js +18 -0
  24. package/dist/commands/pull.d.ts +7 -0
  25. package/dist/commands/pull.d.ts.map +1 -0
  26. package/dist/commands/pull.js +97 -0
  27. package/dist/compiler/errors.d.ts +20 -0
  28. package/dist/compiler/errors.d.ts.map +1 -0
  29. package/dist/compiler/errors.js +35 -0
  30. package/dist/compiler/evalStatic.d.ts +3 -0
  31. package/dist/compiler/evalStatic.d.ts.map +1 -0
  32. package/dist/compiler/evalStatic.js +57 -0
  33. package/dist/compiler/flatten.js +1 -0
  34. package/dist/compiler/helpers/duplicateIds.d.ts +9 -0
  35. package/dist/compiler/helpers/duplicateIds.d.ts.map +1 -0
  36. package/dist/compiler/helpers/duplicateIds.js +71 -0
  37. package/dist/compiler/index.d.ts +16 -0
  38. package/dist/compiler/index.d.ts.map +1 -0
  39. package/dist/compiler/index.js +934 -0
  40. package/dist/compiler/parsePage.d.ts +15 -0
  41. package/dist/compiler/parsePage.d.ts.map +1 -0
  42. package/dist/compiler/parsePage.js +562 -0
  43. package/dist/compiler/registry.d.ts +4 -0
  44. package/dist/compiler/registry.d.ts.map +1 -0
  45. package/dist/compiler/registry.js +44 -0
  46. package/dist/compiler/reverse.d.ts +17 -0
  47. package/dist/compiler/reverse.d.ts.map +1 -0
  48. package/dist/compiler/reverse.js +1632 -0
  49. package/dist/compiler/types.d.ts +21 -0
  50. package/dist/compiler/types.d.ts.map +1 -0
  51. package/dist/compiler/types.js +1 -0
  52. package/dist/components/index.d.ts +21 -0
  53. package/dist/components/index.d.ts.map +1 -0
  54. package/dist/components/index.js +21 -0
  55. package/dist/components/primitives/BaseComponent.d.ts +32 -0
  56. package/dist/components/primitives/BaseComponent.d.ts.map +1 -0
  57. package/dist/components/primitives/BaseComponent.js +26 -0
  58. package/dist/components/primitives/BookMeeting.d.ts +18 -0
  59. package/dist/components/primitives/BookMeeting.d.ts.map +1 -0
  60. package/dist/components/primitives/BookMeeting.js +5 -0
  61. package/dist/components/primitives/Chart.d.ts +41 -0
  62. package/dist/components/primitives/Chart.d.ts.map +1 -0
  63. package/dist/components/primitives/Chart.js +5 -0
  64. package/dist/components/primitives/Container.d.ts +8 -0
  65. package/dist/components/primitives/Container.d.ts.map +1 -0
  66. package/dist/components/primitives/Container.js +5 -0
  67. package/dist/components/primitives/CustomButton.d.ts +37 -0
  68. package/dist/components/primitives/CustomButton.d.ts.map +1 -0
  69. package/dist/components/primitives/CustomButton.js +10 -0
  70. package/dist/components/primitives/CustomHTML.d.ts +8 -0
  71. package/dist/components/primitives/CustomHTML.d.ts.map +1 -0
  72. package/dist/components/primitives/CustomHTML.js +5 -0
  73. package/dist/components/primitives/FileUpload.d.ts +18 -0
  74. package/dist/components/primitives/FileUpload.d.ts.map +1 -0
  75. package/dist/components/primitives/FileUpload.js +16 -0
  76. package/dist/components/primitives/InputBox.d.ts +34 -0
  77. package/dist/components/primitives/InputBox.d.ts.map +1 -0
  78. package/dist/components/primitives/InputBox.js +25 -0
  79. package/dist/components/primitives/Lottie.d.ts +11 -0
  80. package/dist/components/primitives/Lottie.d.ts.map +1 -0
  81. package/dist/components/primitives/Lottie.js +5 -0
  82. package/dist/components/primitives/MediaEmbed.d.ts +13 -0
  83. package/dist/components/primitives/MediaEmbed.d.ts.map +1 -0
  84. package/dist/components/primitives/MediaEmbed.js +6 -0
  85. package/dist/components/primitives/MediaImage.d.ts +8 -0
  86. package/dist/components/primitives/MediaImage.d.ts.map +1 -0
  87. package/dist/components/primitives/MediaImage.js +5 -0
  88. package/dist/components/primitives/OptionSelector.d.ts +35 -0
  89. package/dist/components/primitives/OptionSelector.d.ts.map +1 -0
  90. package/dist/components/primitives/OptionSelector.js +8 -0
  91. package/dist/components/primitives/PaypalCheckout.d.ts +25 -0
  92. package/dist/components/primitives/PaypalCheckout.d.ts.map +1 -0
  93. package/dist/components/primitives/PaypalCheckout.js +5 -0
  94. package/dist/components/primitives/PlainText.d.ts +6 -0
  95. package/dist/components/primitives/PlainText.d.ts.map +1 -0
  96. package/dist/components/primitives/PlainText.js +5 -0
  97. package/dist/components/primitives/ProgressBar.d.ts +15 -0
  98. package/dist/components/primitives/ProgressBar.d.ts.map +1 -0
  99. package/dist/components/primitives/ProgressBar.js +5 -0
  100. package/dist/components/primitives/RichText.d.ts +6 -0
  101. package/dist/components/primitives/RichText.d.ts.map +1 -0
  102. package/dist/components/primitives/RichText.js +5 -0
  103. package/dist/components/primitives/RichTextMarkdown.d.ts +6 -0
  104. package/dist/components/primitives/RichTextMarkdown.d.ts.map +1 -0
  105. package/dist/components/primitives/RichTextMarkdown.js +5 -0
  106. package/dist/components/primitives/Rive.d.ts +16 -0
  107. package/dist/components/primitives/Rive.d.ts.map +1 -0
  108. package/dist/components/primitives/Rive.js +8 -0
  109. package/dist/components/primitives/StripeCheckout.d.ts +52 -0
  110. package/dist/components/primitives/StripeCheckout.d.ts.map +1 -0
  111. package/dist/components/primitives/StripeCheckout.js +5 -0
  112. package/dist/components/primitives/StripeCheckout2.d.ts +30 -0
  113. package/dist/components/primitives/StripeCheckout2.d.ts.map +1 -0
  114. package/dist/components/primitives/StripeCheckout2.js +7 -0
  115. package/dist/proxy/injectApiInterceptor.d.ts +6 -0
  116. package/dist/proxy/injectApiInterceptor.d.ts.map +1 -0
  117. package/dist/proxy/injectApiInterceptor.js +66 -0
  118. package/dist/proxy/injectReload.d.ts +2 -0
  119. package/dist/proxy/injectReload.d.ts.map +1 -0
  120. package/dist/proxy/injectReload.js +14 -0
  121. package/dist/proxy/injectWorkbench.d.ts +4 -0
  122. package/dist/proxy/injectWorkbench.d.ts.map +1 -0
  123. package/dist/proxy/injectWorkbench.js +16 -0
  124. package/dist/proxy/server.d.ts +11 -0
  125. package/dist/proxy/server.d.ts.map +1 -0
  126. package/dist/proxy/server.js +246 -0
  127. package/dist/proxy/sse.d.ts +5 -0
  128. package/dist/proxy/sse.d.ts.map +1 -0
  129. package/dist/proxy/sse.js +17 -0
  130. package/dist/types-builder.d.ts +800 -0
  131. package/dist/types-builder.d.ts.map +1 -0
  132. package/dist/types-builder.js +20 -0
  133. package/dist/workbench/ActionsPanel.d.ts +6 -0
  134. package/dist/workbench/ActionsPanel.d.ts.map +1 -0
  135. package/dist/workbench/ActionsPanel.js +47 -0
  136. package/dist/workbench/AutofillPanel.d.ts +6 -0
  137. package/dist/workbench/AutofillPanel.d.ts.map +1 -0
  138. package/dist/workbench/AutofillPanel.js +543 -0
  139. package/dist/workbench/ComputedFieldsPanel.d.ts +6 -0
  140. package/dist/workbench/ComputedFieldsPanel.d.ts.map +1 -0
  141. package/dist/workbench/ComputedFieldsPanel.js +31 -0
  142. package/dist/workbench/ExperimentsPanel.d.ts +6 -0
  143. package/dist/workbench/ExperimentsPanel.d.ts.map +1 -0
  144. package/dist/workbench/ExperimentsPanel.js +182 -0
  145. package/dist/workbench/FieldEditorPanel.d.ts +9 -0
  146. package/dist/workbench/FieldEditorPanel.d.ts.map +1 -0
  147. package/dist/workbench/FieldEditorPanel.js +650 -0
  148. package/dist/workbench/InspectorPanel.d.ts +6 -0
  149. package/dist/workbench/InspectorPanel.d.ts.map +1 -0
  150. package/dist/workbench/InspectorPanel.js +341 -0
  151. package/dist/workbench/PageNavigator.d.ts +6 -0
  152. package/dist/workbench/PageNavigator.d.ts.map +1 -0
  153. package/dist/workbench/PageNavigator.js +123 -0
  154. package/dist/workbench/SchemaPanel.d.ts +6 -0
  155. package/dist/workbench/SchemaPanel.d.ts.map +1 -0
  156. package/dist/workbench/SchemaPanel.js +222 -0
  157. package/dist/workbench/UserDataPanel.d.ts +6 -0
  158. package/dist/workbench/UserDataPanel.d.ts.map +1 -0
  159. package/dist/workbench/UserDataPanel.js +350 -0
  160. package/dist/workbench/WorkbenchApp.d.ts +6 -0
  161. package/dist/workbench/WorkbenchApp.d.ts.map +1 -0
  162. package/dist/workbench/WorkbenchApp.js +193 -0
  163. package/dist/workbench/cloudflare-worker/README.md +31 -0
  164. package/dist/workbench/cloudflare-worker/public/workbench.css +1614 -0
  165. package/dist/workbench/cloudflare-worker/public/workbench.js +77 -0
  166. package/dist/workbench/cloudflare-worker/worker.js +40 -0
  167. package/dist/workbench/cloudflare-worker/wrangler.toml +10 -0
  168. package/dist/workbench/index.d.ts +9 -0
  169. package/dist/workbench/index.d.ts.map +1 -0
  170. package/dist/workbench/index.js +44 -0
  171. package/dist/workbench/workbench.css +1614 -0
  172. package/dist/workbench/workbench.js +77 -0
  173. package/package.json +79 -0
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # Embeddables CLI
2
+
3
+ A CLI for authoring and managing Embeddables locally using TypeScript/TSX.
4
+
5
+ ## Features
6
+
7
+ - **Pull** existing Embeddables from the cloud and reverse-compile to TSX
8
+ - **Build** TSX pages into the canonical Embeddable JSON format
9
+ - **Dev** mode with hot reload and proxy to a live Engine instance
10
+ - Full **TypeScript support** with autocomplete for all component primitives
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install @embeddables/cli
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ```bash
21
+ # Login to your Embeddables account
22
+ npx embeddables login
23
+
24
+ # Pull an existing embeddable
25
+ npx embeddables pull --id <embeddable-id>
26
+
27
+ # Start dev server with hot reload
28
+ npx embeddables dev --id <embeddable-id>
29
+ ```
30
+
31
+ This creates the following structure in your repo:
32
+
33
+ ```
34
+ embeddables/
35
+ <embeddable-id>/
36
+ pages/ # TSX page files
37
+ styles/ # CSS styles
38
+ computed-fields/ # Custom computed field logic
39
+ actions/ # Data output actions
40
+ config.json # Embeddable configuration
41
+ .generated/ # Compiled JSON output
42
+ ```
43
+
44
+ ## Commands
45
+
46
+ ### `embeddables login`
47
+ Authenticate with your Embeddables account.
48
+
49
+ ### `embeddables logout`
50
+ Clear stored authentication.
51
+
52
+ ### `embeddables pull --id <id>`
53
+ Fetch an embeddable from the cloud and reverse-compile it into local TSX files.
54
+
55
+ Options:
56
+ - `--id <id>` (required): Embeddable ID to pull
57
+ - `--branch <branch_id>`: Pull a specific branch version
58
+ - `--fix`: Remove components with missing required props instead of erroring
59
+
60
+ ### `embeddables build --id <id>`
61
+ Compile TSX pages into the canonical JSON format.
62
+
63
+ Options:
64
+ - `--id <id>` (required): Embeddable ID
65
+ - `--pages <glob>`: Custom pages glob pattern
66
+ - `--out <path>`: Custom output path
67
+
68
+ ### `embeddables dev`
69
+ Start a dev server with hot reload.
70
+
71
+ Options:
72
+ - `--id <id>`: Embeddable ID (will prompt if not provided)
73
+ - `--engine <url>`: Engine origin (default: `http://localhost:8787`)
74
+ - `--remote`: Use production engine (`https://engine.embeddables.com`)
75
+ - `--port <n>`: Dev proxy port (default: `3000`)
76
+
77
+ ## Authoring with TypeScript
78
+
79
+ Import component primitives for full autocomplete:
80
+
81
+ ```tsx
82
+ import { Container, InputBox, PlainText, CustomButton } from '@embeddables/cli/components'
83
+
84
+ export default function MyPage() {
85
+ return (
86
+ <Container id="main" key="main">
87
+ <PlainText id="title" key="title" text="Welcome!" />
88
+ <InputBox
89
+ id="email"
90
+ key="email"
91
+ input_type="email"
92
+ label="Email"
93
+ placeholder="you@example.com"
94
+ isRequired
95
+ />
96
+ <CustomButton id="submit" key="submit" text="Continue" action="next-page" />
97
+ </Container>
98
+ )
99
+ }
100
+ ```
101
+
102
+ ## Development (Contributing)
103
+
104
+ ```bash
105
+ # Install dependencies
106
+ npm install
107
+
108
+ # Build the CLI
109
+ npm run build
110
+
111
+ # Link for local testing
112
+ npm link
113
+
114
+ # Run tests
115
+ npm test
116
+ ```
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/cli.js'
@@ -0,0 +1,43 @@
1
+ import { SupabaseClient } from '@supabase/supabase-js';
2
+ export declare const SUPABASE_URL = "https://ierxexdtyashuotcsjyo.supabase.co";
3
+ export declare const SUPABASE_ANON_KEY = "sb_publishable_Vt8-msWNtn2hhOY3AA6RsQ_ueTx79Vo";
4
+ export interface AuthConfig {
5
+ access_token: string;
6
+ refresh_token: string;
7
+ expires_at: number;
8
+ supabase_url: string;
9
+ supabase_anon_key: string;
10
+ }
11
+ /**
12
+ * Get the path to the auth config file
13
+ */
14
+ export declare function getAuthFilePath(): string;
15
+ /**
16
+ * Read auth config from file
17
+ */
18
+ export declare function readAuthConfig(): AuthConfig | null;
19
+ /**
20
+ * Write auth config to file
21
+ */
22
+ export declare function writeAuthConfig(config: AuthConfig): void;
23
+ /**
24
+ * Delete auth config file (logout)
25
+ */
26
+ export declare function deleteAuthConfig(): void;
27
+ /**
28
+ * Check if user is logged in (has valid auth config)
29
+ */
30
+ export declare function isLoggedIn(): boolean;
31
+ /**
32
+ * Get Supabase client instance
33
+ */
34
+ export declare function getSupabaseClient(): SupabaseClient;
35
+ /**
36
+ * Get authenticated Supabase client (with stored session)
37
+ */
38
+ export declare function getAuthenticatedSupabaseClient(): SupabaseClient | null;
39
+ /**
40
+ * Get access token for authenticated requests
41
+ */
42
+ export declare function getAccessToken(): string | null;
43
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAGpE,eAAO,MAAM,YAAY,6CAA6C,CAAA;AACtE,eAAO,MAAM,iBAAiB,mDAAmD,CAAA;AAEjF,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;CAC1B;AAKD;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,UAAU,GAAG,IAAI,CAUlD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAGxD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAcpC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,CAWlD;AAED;;GAEG;AACH,wBAAgB,8BAA8B,IAAI,cAAc,GAAG,IAAI,CActE;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAM9C"}
@@ -0,0 +1,100 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createClient } from '@supabase/supabase-js';
4
+ // TODO: Move to environment variables
5
+ export const SUPABASE_URL = 'https://ierxexdtyashuotcsjyo.supabase.co'; // Replace with actual Supabase URL
6
+ export const SUPABASE_ANON_KEY = 'sb_publishable_Vt8-msWNtn2hhOY3AA6RsQ_ueTx79Vo'; // Replace with actual Supabase anon key
7
+ const AUTH_DIR = path.join(process.cwd(), '.auth');
8
+ const AUTH_FILE = path.join(AUTH_DIR, 'auth.json');
9
+ /**
10
+ * Get the path to the auth config file
11
+ */
12
+ export function getAuthFilePath() {
13
+ return AUTH_FILE;
14
+ }
15
+ /**
16
+ * Read auth config from file
17
+ */
18
+ export function readAuthConfig() {
19
+ try {
20
+ if (!fs.existsSync(AUTH_FILE)) {
21
+ return null;
22
+ }
23
+ const content = fs.readFileSync(AUTH_FILE, 'utf8');
24
+ return JSON.parse(content);
25
+ }
26
+ catch (error) {
27
+ return null;
28
+ }
29
+ }
30
+ /**
31
+ * Write auth config to file
32
+ */
33
+ export function writeAuthConfig(config) {
34
+ fs.mkdirSync(AUTH_DIR, { recursive: true });
35
+ fs.writeFileSync(AUTH_FILE, JSON.stringify(config, null, 2), 'utf8');
36
+ }
37
+ /**
38
+ * Delete auth config file (logout)
39
+ */
40
+ export function deleteAuthConfig() {
41
+ if (fs.existsSync(AUTH_FILE)) {
42
+ fs.unlinkSync(AUTH_FILE);
43
+ }
44
+ }
45
+ /**
46
+ * Check if user is logged in (has valid auth config)
47
+ */
48
+ export function isLoggedIn() {
49
+ const config = readAuthConfig();
50
+ if (!config) {
51
+ return false;
52
+ }
53
+ // Check if token is expired (with 5 minute buffer)
54
+ const now = Math.floor(Date.now() / 1000);
55
+ const expiresAt = config.expires_at;
56
+ if (expiresAt && expiresAt < now + 300) {
57
+ return false;
58
+ }
59
+ return !!config.access_token;
60
+ }
61
+ /**
62
+ * Get Supabase client instance
63
+ */
64
+ export function getSupabaseClient() {
65
+ const config = readAuthConfig();
66
+ const url = config?.supabase_url || SUPABASE_URL;
67
+ const anonKey = config?.supabase_anon_key || SUPABASE_ANON_KEY;
68
+ return createClient(url, anonKey, {
69
+ auth: {
70
+ persistSession: false, // We handle session persistence ourselves
71
+ autoRefreshToken: false, // No auto refresh for now
72
+ },
73
+ });
74
+ }
75
+ /**
76
+ * Get authenticated Supabase client (with stored session)
77
+ */
78
+ export function getAuthenticatedSupabaseClient() {
79
+ const config = readAuthConfig();
80
+ if (!config || !isLoggedIn()) {
81
+ return null;
82
+ }
83
+ const client = getSupabaseClient();
84
+ // Set the session manually
85
+ client.auth.setSession({
86
+ access_token: config.access_token,
87
+ refresh_token: config.refresh_token,
88
+ });
89
+ return client;
90
+ }
91
+ /**
92
+ * Get access token for authenticated requests
93
+ */
94
+ export function getAccessToken() {
95
+ const config = readAuthConfig();
96
+ if (!config || !isLoggedIn()) {
97
+ return null;
98
+ }
99
+ return config.access_token;
100
+ }
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,75 @@
1
+ import { Command } from 'commander';
2
+ import pc from 'picocolors';
3
+ import { runBuild } from './commands/build.js';
4
+ import { runBuildWorkbench } from './commands/build-workbench.js';
5
+ import { runDev } from './commands/dev.js';
6
+ import { runLogin } from './commands/login.js';
7
+ import { runLogout } from './commands/logout.js';
8
+ import { runPull } from './commands/pull.js';
9
+ // Make all console.warn output yellow
10
+ const originalWarn = console.warn.bind(console);
11
+ console.warn = (...args) => {
12
+ originalWarn(...args.map((arg) => typeof arg === 'string' ? `${pc.bold(pc.bgYellow(' WARN '))} ${pc.yellow(arg)}` : arg));
13
+ };
14
+ const originalError = console.error.bind(console);
15
+ console.error = (...args) => {
16
+ originalError(...args.map((arg) => typeof arg === 'string' ? `${pc.bold(pc.bgRed(' ERROR '))} ${pc.red(arg)}` : arg));
17
+ };
18
+ const program = new Command();
19
+ program.name('embeddables').description('Embeddables CLI').version('0.1.0');
20
+ program
21
+ .command('build')
22
+ .requiredOption('--id <id>', 'Embeddable ID')
23
+ .option('--pages <glob>', 'Pages glob')
24
+ .option('--out <path>', 'Output json path')
25
+ .option('--pageKeyFrom <mode>', 'filename|export', 'filename')
26
+ .action(async (opts) => {
27
+ await runBuild(opts);
28
+ });
29
+ program
30
+ .command('dev')
31
+ .option('--id <id>', 'Embeddable ID (will prompt if not provided)')
32
+ .option('--pages <glob>', 'Pages glob')
33
+ .option('--out <path>', 'Output json path')
34
+ .option('--remote', 'Use remote engine (https://engine.embeddables.com)')
35
+ .option('--engine <url>', 'Engine origin', 'http://localhost:8787')
36
+ .option('--port <n>', 'Dev proxy port', '3000')
37
+ .option('--overrideRoute <path>', 'Route to override in proxy (exact match, no wildcards yet)', '/init')
38
+ .option('--pageKeyFrom <mode>', 'filename|export', 'filename')
39
+ .action(async (opts) => {
40
+ // --remote flag overrides --engine to use production engine
41
+ if (opts.remote) {
42
+ opts.engine = 'https://engine.embeddables.com';
43
+ }
44
+ await runDev(opts);
45
+ });
46
+ program
47
+ .command('login')
48
+ .description('Login to Embeddables')
49
+ .action(async () => {
50
+ await runLogin();
51
+ });
52
+ program
53
+ .command('logout')
54
+ .description('Logout from Embeddables')
55
+ .action(async () => {
56
+ await runLogout();
57
+ });
58
+ program
59
+ .command('pull')
60
+ .requiredOption('--id <id>', 'Embeddable ID to pull')
61
+ .option('--out <path>', 'Output json path')
62
+ .option('--branch <branch_id>', 'Embeddable branch ID')
63
+ .option('--fix', 'Fix by removing components missing required props (warn instead of error)')
64
+ .action(async (opts) => {
65
+ await runPull(opts);
66
+ });
67
+ program
68
+ .command('build-workbench')
69
+ .description('Build Workbench for CDN deployment')
70
+ .option('--out <path>', 'Output directory', 'dist/workbench')
71
+ .option('--no-minify', 'Disable minification (for debugging)')
72
+ .action(async (opts) => {
73
+ await runBuildWorkbench(opts);
74
+ });
75
+ await program.parseAsync(process.argv);
@@ -0,0 +1,5 @@
1
+ export declare function runBuildWorkbench(opts: {
2
+ out?: string;
3
+ minify?: boolean;
4
+ }): Promise<void>;
5
+ //# sourceMappingURL=build-workbench.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-workbench.d.ts","sourceRoot":"","sources":["../../src/commands/build-workbench.ts"],"names":[],"mappings":"AAQA,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,iBA2H/E"}
@@ -0,0 +1,122 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import * as esbuild from 'esbuild';
4
+ import postcss from 'postcss';
5
+ import tailwindcss from '@tailwindcss/postcss';
6
+ import autoprefixer from 'autoprefixer';
7
+ import pc from 'picocolors';
8
+ export async function runBuildWorkbench(opts) {
9
+ const outDir = opts.out || 'dist/workbench';
10
+ const shouldMinify = opts.minify ?? true;
11
+ // Check if wrangler config exists in outDir (native Cloudflare Git integration mode)
12
+ const hasWranglerConfig = fs.existsSync(path.join(outDir, 'wrangler.jsonc')) ||
13
+ fs.existsSync(path.join(outDir, 'wrangler.toml'));
14
+ console.log(pc.cyan('Building Workbench for CDN deployment...'));
15
+ console.log();
16
+ // Ensure output directory exists
17
+ fs.mkdirSync(outDir, { recursive: true });
18
+ const workbenchEntry = path.join(process.cwd(), 'src', 'workbench', 'index.tsx');
19
+ const workbenchCssEntry = path.join(process.cwd(), 'src', 'workbench', 'workbench.css');
20
+ // Check that source files exist
21
+ if (!fs.existsSync(workbenchEntry)) {
22
+ console.error(`Workbench entry not found: ${workbenchEntry}`);
23
+ process.exit(1);
24
+ }
25
+ if (!fs.existsSync(workbenchCssEntry)) {
26
+ console.error(`Workbench CSS not found: ${workbenchCssEntry}`);
27
+ process.exit(1);
28
+ }
29
+ // Build JavaScript bundle
30
+ console.log(pc.dim(' Building JavaScript bundle...'));
31
+ const jsResult = await esbuild.build({
32
+ entryPoints: [workbenchEntry],
33
+ bundle: true,
34
+ format: 'iife',
35
+ globalName: '__EmbeddablesWorkbenchBundle',
36
+ platform: 'browser',
37
+ minify: shouldMinify,
38
+ sourcemap: shouldMinify ? false : 'inline',
39
+ write: false,
40
+ target: ['es2020', 'chrome80', 'firefox78', 'safari14'],
41
+ });
42
+ const jsOutput = jsResult.outputFiles?.[0];
43
+ if (!jsOutput) {
44
+ console.error('Failed to build JavaScript bundle');
45
+ process.exit(1);
46
+ }
47
+ // Build CSS
48
+ console.log(pc.dim(' Building CSS...'));
49
+ const rawCss = fs.readFileSync(workbenchCssEntry, 'utf8');
50
+ const cssResult = await postcss([tailwindcss(), autoprefixer]).process(rawCss, {
51
+ from: workbenchCssEntry,
52
+ });
53
+ // CORS headers file for Cloudflare static assets
54
+ const headersContent = `/*
55
+ Access-Control-Allow-Origin: *
56
+ Access-Control-Allow-Methods: GET, OPTIONS
57
+ Access-Control-Allow-Headers: Content-Type
58
+ `;
59
+ if (hasWranglerConfig) {
60
+ // Native Cloudflare Git integration mode:
61
+ // Output directly to outDir/public
62
+ const publicDir = path.join(outDir, 'public');
63
+ fs.mkdirSync(publicDir, { recursive: true });
64
+ fs.writeFileSync(path.join(publicDir, 'workbench.js'), jsOutput.contents);
65
+ const jsSize = (jsOutput.contents.length / 1024).toFixed(1);
66
+ console.log(pc.green(` ✓ ${publicDir}/workbench.js (${jsSize} KB)`));
67
+ fs.writeFileSync(path.join(publicDir, 'workbench.css'), cssResult.css);
68
+ const cssSize = (cssResult.css.length / 1024).toFixed(1);
69
+ console.log(pc.green(` ✓ ${publicDir}/workbench.css (${cssSize} KB)`));
70
+ fs.writeFileSync(path.join(publicDir, '_headers'), headersContent);
71
+ console.log(pc.green(` ✓ ${publicDir}/_headers`));
72
+ console.log();
73
+ console.log(pc.bold(pc.green('Build complete!')));
74
+ console.log();
75
+ console.log(pc.dim('Using existing wrangler.toml for Cloudflare Git integration'));
76
+ }
77
+ else {
78
+ // Standalone mode: output to outDir with nested cloudflare-worker folder
79
+ const jsPath = path.join(outDir, 'workbench.js');
80
+ fs.writeFileSync(jsPath, jsOutput.contents);
81
+ const jsSize = (jsOutput.contents.length / 1024).toFixed(1);
82
+ console.log(pc.green(` ✓ ${jsPath} (${jsSize} KB)`));
83
+ const cssPath = path.join(outDir, 'workbench.css');
84
+ fs.writeFileSync(cssPath, cssResult.css);
85
+ const cssSize = (cssResult.css.length / 1024).toFixed(1);
86
+ console.log(pc.green(` ✓ ${cssPath} (${cssSize} KB)`));
87
+ // Generate Cloudflare static site files
88
+ console.log(pc.dim(' Generating Cloudflare deployment files...'));
89
+ const workerDir = path.join(outDir, 'cloudflare');
90
+ fs.mkdirSync(workerDir, { recursive: true });
91
+ const wranglerConfig = generateWranglerConfig();
92
+ fs.writeFileSync(path.join(workerDir, 'wrangler.jsonc'), wranglerConfig);
93
+ console.log(pc.green(` ✓ ${workerDir}/wrangler.jsonc`));
94
+ const publicDir = path.join(workerDir, 'public');
95
+ fs.mkdirSync(publicDir, { recursive: true });
96
+ fs.copyFileSync(jsPath, path.join(publicDir, 'workbench.js'));
97
+ fs.copyFileSync(cssPath, path.join(publicDir, 'workbench.css'));
98
+ fs.writeFileSync(path.join(publicDir, '_headers'), headersContent);
99
+ console.log(pc.green(` ✓ ${publicDir}/ (assets + _headers)`));
100
+ console.log();
101
+ console.log(pc.bold(pc.green('Build complete!')));
102
+ console.log();
103
+ console.log(pc.cyan('Deploy to Cloudflare:'));
104
+ console.log(pc.dim(` cd ${workerDir} && npx wrangler deploy`));
105
+ }
106
+ console.log();
107
+ console.log(pc.cyan('Usage:'));
108
+ console.log(pc.dim(' Add ?workbench=true to any engine preview URL'));
109
+ console.log();
110
+ }
111
+ function generateWranglerConfig() {
112
+ return `{
113
+ // Embeddables Workbench - Static Assets
114
+ // Deploy: npx wrangler deploy
115
+ "name": "embeddables-workbench",
116
+ "compatibility_date": "2024-01-01",
117
+ "assets": {
118
+ "directory": "./public"
119
+ }
120
+ }
121
+ `;
122
+ }
@@ -0,0 +1,7 @@
1
+ export declare function runBuild(opts: {
2
+ id: string;
3
+ pages?: string;
4
+ out?: string;
5
+ pageKeyFrom: 'filename' | 'export';
6
+ }): Promise<void>;
7
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAIA,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IACnC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,UAAU,GAAG,QAAQ,CAAA;CACnC,iBAmBA"}
@@ -0,0 +1,22 @@
1
+ import path from 'node:path';
2
+ import { compileAllPages } from '../compiler/index.js';
3
+ import { formatError } from '../compiler/errors.js';
4
+ export async function runBuild(opts) {
5
+ const embeddableId = opts.id;
6
+ const pagesGlob = opts.pages || `embeddables/${embeddableId}/pages/**/*.page.tsx`;
7
+ const outPath = opts.out || path.join('embeddables', embeddableId, '.generated', 'embeddable.json');
8
+ const stylesDir = path.join('embeddables', embeddableId, 'styles');
9
+ try {
10
+ await compileAllPages({
11
+ pagesGlob,
12
+ outPath,
13
+ pageKeyFrom: opts.pageKeyFrom,
14
+ stylesDir,
15
+ embeddableId,
16
+ });
17
+ }
18
+ catch (e) {
19
+ console.error(formatError(e));
20
+ process.exit(1);
21
+ }
22
+ }
@@ -0,0 +1,11 @@
1
+ export declare function runDev(opts: {
2
+ id?: string;
3
+ pages?: string;
4
+ out?: string;
5
+ remote?: boolean;
6
+ engine: string;
7
+ port: string;
8
+ overrideRoute: string;
9
+ pageKeyFrom: 'filename' | 'export';
10
+ }): Promise<void>;
11
+ //# sourceMappingURL=dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/commands/dev.ts"],"names":[],"mappings":"AAoFA,wBAAsB,MAAM,CAAC,IAAI,EAAE;IACjC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,UAAU,GAAG,QAAQ,CAAA;CACnC,iBAgGA"}