@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.
- package/README.md +116 -0
- package/bin/embeddables.mjs +2 -0
- package/dist/auth/index.d.ts +43 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +100 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +75 -0
- package/dist/commands/build-workbench.d.ts +5 -0
- package/dist/commands/build-workbench.d.ts.map +1 -0
- package/dist/commands/build-workbench.js +122 -0
- package/dist/commands/build.d.ts +7 -0
- package/dist/commands/build.d.ts.map +1 -0
- package/dist/commands/build.js +22 -0
- package/dist/commands/dev.d.ts +11 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +153 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +112 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +18 -0
- package/dist/commands/pull.d.ts +7 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +97 -0
- package/dist/compiler/errors.d.ts +20 -0
- package/dist/compiler/errors.d.ts.map +1 -0
- package/dist/compiler/errors.js +35 -0
- package/dist/compiler/evalStatic.d.ts +3 -0
- package/dist/compiler/evalStatic.d.ts.map +1 -0
- package/dist/compiler/evalStatic.js +57 -0
- package/dist/compiler/flatten.js +1 -0
- package/dist/compiler/helpers/duplicateIds.d.ts +9 -0
- package/dist/compiler/helpers/duplicateIds.d.ts.map +1 -0
- package/dist/compiler/helpers/duplicateIds.js +71 -0
- package/dist/compiler/index.d.ts +16 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/index.js +934 -0
- package/dist/compiler/parsePage.d.ts +15 -0
- package/dist/compiler/parsePage.d.ts.map +1 -0
- package/dist/compiler/parsePage.js +562 -0
- package/dist/compiler/registry.d.ts +4 -0
- package/dist/compiler/registry.d.ts.map +1 -0
- package/dist/compiler/registry.js +44 -0
- package/dist/compiler/reverse.d.ts +17 -0
- package/dist/compiler/reverse.d.ts.map +1 -0
- package/dist/compiler/reverse.js +1632 -0
- package/dist/compiler/types.d.ts +21 -0
- package/dist/compiler/types.d.ts.map +1 -0
- package/dist/compiler/types.js +1 -0
- package/dist/components/index.d.ts +21 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +21 -0
- package/dist/components/primitives/BaseComponent.d.ts +32 -0
- package/dist/components/primitives/BaseComponent.d.ts.map +1 -0
- package/dist/components/primitives/BaseComponent.js +26 -0
- package/dist/components/primitives/BookMeeting.d.ts +18 -0
- package/dist/components/primitives/BookMeeting.d.ts.map +1 -0
- package/dist/components/primitives/BookMeeting.js +5 -0
- package/dist/components/primitives/Chart.d.ts +41 -0
- package/dist/components/primitives/Chart.d.ts.map +1 -0
- package/dist/components/primitives/Chart.js +5 -0
- package/dist/components/primitives/Container.d.ts +8 -0
- package/dist/components/primitives/Container.d.ts.map +1 -0
- package/dist/components/primitives/Container.js +5 -0
- package/dist/components/primitives/CustomButton.d.ts +37 -0
- package/dist/components/primitives/CustomButton.d.ts.map +1 -0
- package/dist/components/primitives/CustomButton.js +10 -0
- package/dist/components/primitives/CustomHTML.d.ts +8 -0
- package/dist/components/primitives/CustomHTML.d.ts.map +1 -0
- package/dist/components/primitives/CustomHTML.js +5 -0
- package/dist/components/primitives/FileUpload.d.ts +18 -0
- package/dist/components/primitives/FileUpload.d.ts.map +1 -0
- package/dist/components/primitives/FileUpload.js +16 -0
- package/dist/components/primitives/InputBox.d.ts +34 -0
- package/dist/components/primitives/InputBox.d.ts.map +1 -0
- package/dist/components/primitives/InputBox.js +25 -0
- package/dist/components/primitives/Lottie.d.ts +11 -0
- package/dist/components/primitives/Lottie.d.ts.map +1 -0
- package/dist/components/primitives/Lottie.js +5 -0
- package/dist/components/primitives/MediaEmbed.d.ts +13 -0
- package/dist/components/primitives/MediaEmbed.d.ts.map +1 -0
- package/dist/components/primitives/MediaEmbed.js +6 -0
- package/dist/components/primitives/MediaImage.d.ts +8 -0
- package/dist/components/primitives/MediaImage.d.ts.map +1 -0
- package/dist/components/primitives/MediaImage.js +5 -0
- package/dist/components/primitives/OptionSelector.d.ts +35 -0
- package/dist/components/primitives/OptionSelector.d.ts.map +1 -0
- package/dist/components/primitives/OptionSelector.js +8 -0
- package/dist/components/primitives/PaypalCheckout.d.ts +25 -0
- package/dist/components/primitives/PaypalCheckout.d.ts.map +1 -0
- package/dist/components/primitives/PaypalCheckout.js +5 -0
- package/dist/components/primitives/PlainText.d.ts +6 -0
- package/dist/components/primitives/PlainText.d.ts.map +1 -0
- package/dist/components/primitives/PlainText.js +5 -0
- package/dist/components/primitives/ProgressBar.d.ts +15 -0
- package/dist/components/primitives/ProgressBar.d.ts.map +1 -0
- package/dist/components/primitives/ProgressBar.js +5 -0
- package/dist/components/primitives/RichText.d.ts +6 -0
- package/dist/components/primitives/RichText.d.ts.map +1 -0
- package/dist/components/primitives/RichText.js +5 -0
- package/dist/components/primitives/RichTextMarkdown.d.ts +6 -0
- package/dist/components/primitives/RichTextMarkdown.d.ts.map +1 -0
- package/dist/components/primitives/RichTextMarkdown.js +5 -0
- package/dist/components/primitives/Rive.d.ts +16 -0
- package/dist/components/primitives/Rive.d.ts.map +1 -0
- package/dist/components/primitives/Rive.js +8 -0
- package/dist/components/primitives/StripeCheckout.d.ts +52 -0
- package/dist/components/primitives/StripeCheckout.d.ts.map +1 -0
- package/dist/components/primitives/StripeCheckout.js +5 -0
- package/dist/components/primitives/StripeCheckout2.d.ts +30 -0
- package/dist/components/primitives/StripeCheckout2.d.ts.map +1 -0
- package/dist/components/primitives/StripeCheckout2.js +7 -0
- package/dist/proxy/injectApiInterceptor.d.ts +6 -0
- package/dist/proxy/injectApiInterceptor.d.ts.map +1 -0
- package/dist/proxy/injectApiInterceptor.js +66 -0
- package/dist/proxy/injectReload.d.ts +2 -0
- package/dist/proxy/injectReload.d.ts.map +1 -0
- package/dist/proxy/injectReload.js +14 -0
- package/dist/proxy/injectWorkbench.d.ts +4 -0
- package/dist/proxy/injectWorkbench.d.ts.map +1 -0
- package/dist/proxy/injectWorkbench.js +16 -0
- package/dist/proxy/server.d.ts +11 -0
- package/dist/proxy/server.d.ts.map +1 -0
- package/dist/proxy/server.js +246 -0
- package/dist/proxy/sse.d.ts +5 -0
- package/dist/proxy/sse.d.ts.map +1 -0
- package/dist/proxy/sse.js +17 -0
- package/dist/types-builder.d.ts +800 -0
- package/dist/types-builder.d.ts.map +1 -0
- package/dist/types-builder.js +20 -0
- package/dist/workbench/ActionsPanel.d.ts +6 -0
- package/dist/workbench/ActionsPanel.d.ts.map +1 -0
- package/dist/workbench/ActionsPanel.js +47 -0
- package/dist/workbench/AutofillPanel.d.ts +6 -0
- package/dist/workbench/AutofillPanel.d.ts.map +1 -0
- package/dist/workbench/AutofillPanel.js +543 -0
- package/dist/workbench/ComputedFieldsPanel.d.ts +6 -0
- package/dist/workbench/ComputedFieldsPanel.d.ts.map +1 -0
- package/dist/workbench/ComputedFieldsPanel.js +31 -0
- package/dist/workbench/ExperimentsPanel.d.ts +6 -0
- package/dist/workbench/ExperimentsPanel.d.ts.map +1 -0
- package/dist/workbench/ExperimentsPanel.js +182 -0
- package/dist/workbench/FieldEditorPanel.d.ts +9 -0
- package/dist/workbench/FieldEditorPanel.d.ts.map +1 -0
- package/dist/workbench/FieldEditorPanel.js +650 -0
- package/dist/workbench/InspectorPanel.d.ts +6 -0
- package/dist/workbench/InspectorPanel.d.ts.map +1 -0
- package/dist/workbench/InspectorPanel.js +341 -0
- package/dist/workbench/PageNavigator.d.ts +6 -0
- package/dist/workbench/PageNavigator.d.ts.map +1 -0
- package/dist/workbench/PageNavigator.js +123 -0
- package/dist/workbench/SchemaPanel.d.ts +6 -0
- package/dist/workbench/SchemaPanel.d.ts.map +1 -0
- package/dist/workbench/SchemaPanel.js +222 -0
- package/dist/workbench/UserDataPanel.d.ts +6 -0
- package/dist/workbench/UserDataPanel.d.ts.map +1 -0
- package/dist/workbench/UserDataPanel.js +350 -0
- package/dist/workbench/WorkbenchApp.d.ts +6 -0
- package/dist/workbench/WorkbenchApp.d.ts.map +1 -0
- package/dist/workbench/WorkbenchApp.js +193 -0
- package/dist/workbench/cloudflare-worker/README.md +31 -0
- package/dist/workbench/cloudflare-worker/public/workbench.css +1614 -0
- package/dist/workbench/cloudflare-worker/public/workbench.js +77 -0
- package/dist/workbench/cloudflare-worker/worker.js +40 -0
- package/dist/workbench/cloudflare-worker/wrangler.toml +10 -0
- package/dist/workbench/index.d.ts +9 -0
- package/dist/workbench/index.d.ts.map +1 -0
- package/dist/workbench/index.js +44 -0
- package/dist/workbench/workbench.css +1614 -0
- package/dist/workbench/workbench.js +77 -0
- 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,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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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"}
|