@strata-ds/core 2.1.17 → 2.1.19

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 CHANGED
@@ -98,7 +98,7 @@ Your React Application
98
98
 
99
99
  ## Quick Start (< 5 Minutes)
100
100
 
101
- > 🚀 **New to Strata?** Get your first component rendering in 4 steps.
101
+ Get your first component rendering in 4 steps.
102
102
 
103
103
  ### Step 1: Install
104
104
 
@@ -117,7 +117,7 @@ Go to [strata.charisol.io](https://strata.charisol.io) → **Your Project** →
117
117
 
118
118
  ### Step 3: Wrap Your App
119
119
 
120
- **✅ Recommended: CDN Snapshot Sync** (1 request per poll, edge-cached)
120
+ **Recommended: CDN Snapshot Sync** (1 request per poll, edge-cached)
121
121
 
122
122
  ```tsx
123
123
  "use client"; // Next.js App Router only
@@ -142,12 +142,12 @@ export default function RootLayout({
142
142
  }
143
143
  ```
144
144
 
145
- > 💡 Replace `YOUR_PROJECT_ID` and `pt_live_your_token_here` with values from **Step 2**.
145
+ > Replace `YOUR_PROJECT_ID` and `pt_live_your_token_here` with values from **Step 2**.
146
146
 
147
147
  ---
148
148
 
149
149
  <details>
150
- <summary><strong>⚠️ Legacy Sync</strong> (3 requests per poll — for migration only)</summary>
150
+ <summary><strong>Legacy Sync</strong> (3 requests per poll — for migration only)</summary>
151
151
 
152
152
  ```tsx
153
153
  "use client";
@@ -173,9 +173,9 @@ export default function RootLayout({
173
173
 
174
174
  **Why CDN is better:**
175
175
 
176
- - ✅ 1 request instead of 3 (faster, cheaper)
177
- - ✅ Edge-cached for global performance
178
- - ✅ Atomic updates (no partial states)
176
+ - 1 request instead of 3 (faster, cheaper)
177
+ - Edge-cached for global performance
178
+ - Atomic updates (no partial states)
179
179
 
180
180
  </details>
181
181
 
@@ -224,10 +224,10 @@ Use this checklist to verify your setup after following [Quick Start](#quick-sta
224
224
 
225
225
  **Verification:**
226
226
 
227
- - [ ] Opened DevTools → Console and saw `🔄 Starting design system sync...`
228
- - [ ] Console shows `📊 Components available: ...`
227
+ - [ ] Opened DevTools → Console and saw `Starting design system sync...`
228
+ - [ ] Console shows `Components available: ...`
229
229
  - [ ] Component renders on screen with correct styles
230
- - [ ] Added `<StrataDebug />` and verified connection status is **✅ Connected**
230
+ - [ ] Added `<StrataDebug />` and verified connection status is **Connected**
231
231
 
232
232
  **Stuck?** → Jump to [Debugging and Troubleshooting](#debugging-and-troubleshooting).
233
233
 
@@ -287,7 +287,7 @@ export default function RootLayout({
287
287
  }
288
288
  ```
289
289
 
290
- > 💡 Replace `YOUR_PROJECT_ID` with the ID from your Strata project dashboard. For private projects, add `syncToken="pt_live_your_token_here"` (get it from the **Publish & Sync** tab).
290
+ > Replace `YOUR_PROJECT_ID` with the ID from your Strata project dashboard. For private projects, add `syncToken="pt_live_your_token_here"` (get it from the **Publish & Sync** tab).
291
291
 
292
292
  ### Sync token authentication
293
293
 
@@ -359,10 +359,10 @@ function StatusBar() {
359
359
 
360
360
  Add `<StrataDebug />` anywhere inside `<StrataProvider>` to inspect:
361
361
 
362
- - ✅ Active sync mode (CDN vs Legacy)
363
- - ✅ Connection status
364
- - ✅ Loaded components
365
- - ✅ Sync token presence (never shows the actual token)
362
+ - Active sync mode (CDN vs Legacy)
363
+ - Connection status
364
+ - Loaded components
365
+ - Sync token presence (never shows the actual token)
366
366
 
367
367
  ```tsx
368
368
  "use client";
@@ -380,11 +380,11 @@ function App() {
380
380
 
381
381
  The panel automatically displays the relevant fields for the active sync mode:
382
382
 
383
- - **CDN mode** (`snapshotCdnBase` + `projectId` set): shows `✅ CDN Snapshot`, Project ID, resolved Snapshot URL, token presence, and sync interval.
384
- - **Legacy mode** (`syncUrl` set): shows `⚠️ Legacy (3 requests/poll)`, Sync URL, token presence, and sync interval.
385
- - **Disabled**: shows `❌ Disabled`.
383
+ - **CDN mode** (`snapshotCdnBase` + `projectId` set): shows `CDN Snapshot`, Project ID, resolved Snapshot URL, token presence, and sync interval.
384
+ - **Legacy mode** (`syncUrl` set): shows `Legacy (3 requests/poll)`, Sync URL, token presence, and sync interval.
385
+ - **Disabled**: shows `Disabled`.
386
386
 
387
- > 🔒 The `syncToken` value is **never** rendered — the panel only shows `✅ Present` or `❌ None`.
387
+ > The `syncToken` value is **never** rendered — the panel only shows `Present` or `None`.
388
388
 
389
389
  ---
390
390
 
@@ -424,11 +424,11 @@ Open **DevTools → Network tab** and filter by:
424
424
 
425
425
  Check for these messages:
426
426
 
427
- - ✅ `🔄 Starting design system sync...` → Sync is working
428
- - ✅ `📊 Components available: Button, Navbar, Card` → Components loaded
429
- - ✅ `🎨 Variables available: colors, spacing, typography` → Tokens loaded
430
- - ❌ `❌ Sync failed: 401` → Token issue (see table above)
431
- - ❌ `❌ Sync failed: 403` → CORS issue (see table above)
427
+ - `Starting design system sync...` → Sync is working
428
+ - `Components available: Button, Navbar, Card` → Components loaded
429
+ - `Variables available: colors, spacing, typography` → Tokens loaded
430
+ - `Sync failed: 401` → Token issue (see table above)
431
+ - `Sync failed: 403` → CORS issue (see table above)
432
432
 
433
433
  ---
434
434
 
@@ -543,18 +543,27 @@ const MyComponent = StrataComponentFactory.createComponent(
543
543
 
544
544
  Any project using the Strata Design System can enable full offline resilience in three quick steps:
545
545
 
546
- #### Step 1: Generate the Local Snapshot and Fallback CSS
547
- Run the CLI snapshot tool locally or add it to your project's build process:
546
+ #### Step 1: Initialize Configuration with strata.json
547
+ Run the initialization CLI tool to prompt for configuration fields and generate a `strata.json` file in your application's root directory:
548
548
  ```bash
549
- npx strata-ds snapshot \
550
- --project-id "YOUR_PROJECT_ID" \
551
- --cdn-base "https://your-cdn-base-url.cloudfront.net" \
552
- --output "./src/data/strata-snapshot.json" \
553
- --output-css "./src/styles/strata-fallbacks.css" \
554
- --variables-only
549
+ npx strata init
555
550
  ```
551
+ This will create a `strata.json` file at your project's root:
552
+ ```json
553
+ {
554
+ "projectId": "YOUR_PROJECT_ID",
555
+ "snapshotCdnBase": "https://your-cdn-base-url.cloudfront.net",
556
+ "output": "./src/data/strata-snapshot.json",
557
+ "outputCss": "./src/styles/strata-fallbacks.css",
558
+ "variablesOnly": true
559
+ }
560
+ ```
561
+
556
562
  *(Commit the generated JSON and CSS files to your Git repository as your baseline fallback).*
557
563
 
564
+ > **Manual Generation**: You can run the CLI snapshot tool manually if you need to fetch updates:
565
+ > `npx strata run`
566
+
558
567
  #### Step 2: Import Fallback Styles
559
568
  Reference the CSS file in your main style entry point (e.g., `src/index.css` or `src/App.css`):
560
569
  ```css
@@ -585,13 +594,13 @@ export default function App() {
585
594
 
586
595
  ## Key Features
587
596
 
588
- - 🔁 Live sync with Strata backend
589
- - 🧠 Token-driven styling
590
- - 🧩 Dynamic component registry
591
- - 🛠 Inline style overrides supported
592
- - 📦 Installable via npm
593
- - 📴 Offline-first fallback
594
- - 🧪 Debug tools included (`StrataDebug`)
597
+ - Live sync with Strata backend
598
+ - Token-driven styling
599
+ - Dynamic component registry
600
+ - Inline style overrides supported
601
+ - Installable via npm
602
+ - Offline-first fallback
603
+ - Debug tools included (`StrataDebug`)
595
604
 
596
605
  ## License
597
606
 
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,177 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+
4
+ async function retrieveSnapshot(options) {
5
+ const { projectId, cdnBase, outputPath, outputCssPath, syncToken, variablesOnly } = options;
6
+ const base = cdnBase.replace(/\/+$/, '');
7
+ const snapshotUrl = base.endsWith('/snapshots')
8
+ ? `${base}/${projectId}/strata.json`
9
+ : `${base}/snapshots/${projectId}/strata.json`;
10
+ console.log(`📡 Fetching snapshot from: ${snapshotUrl}`);
11
+ try {
12
+ const headers = {};
13
+ if (syncToken) {
14
+ headers['Authorization'] = `Bearer ${syncToken}`;
15
+ }
16
+ const res = await fetch(snapshotUrl, { headers });
17
+ if (!res.ok) {
18
+ throw new Error(`Server returned ${res.status} ${res.statusText}`);
19
+ }
20
+ const data = await res.json();
21
+ // Validate shape
22
+ if (!data || typeof data !== 'object' || typeof data.variables !== 'object') {
23
+ throw new Error('Invalid snapshot response shape: missing variables');
24
+ }
25
+ // Sanitize variables to prevent malformed values from breaking outputs
26
+ const variables = data.variables || {};
27
+ for (const [key, val] of Object.entries(variables)) {
28
+ if (val && typeof val === 'object') {
29
+ let value = val.value;
30
+ let resolvedValue = val.resolvedValue;
31
+ // Sanitize value
32
+ if (typeof value === 'string') {
33
+ if (value.endsWith('\\')) {
34
+ value += '\\';
35
+ }
36
+ if (value.startsWith('url(') && !value.endsWith(')')) {
37
+ if (value === 'url(\\' || value === 'url(\\\\' || value === 'url(\\;') {
38
+ value = 'none';
39
+ }
40
+ else {
41
+ value += ')';
42
+ }
43
+ }
44
+ val.value = value;
45
+ }
46
+ // Sanitize resolvedValue
47
+ if (typeof resolvedValue === 'string') {
48
+ if (resolvedValue.endsWith('\\')) {
49
+ resolvedValue += '\\';
50
+ }
51
+ if (resolvedValue.startsWith('url(') && !resolvedValue.endsWith(')')) {
52
+ if (resolvedValue === 'url(\\' || resolvedValue === 'url(\\\\' || resolvedValue === 'url(\\;') {
53
+ resolvedValue = 'none';
54
+ }
55
+ else {
56
+ resolvedValue += ')';
57
+ }
58
+ }
59
+ val.resolvedValue = resolvedValue;
60
+ }
61
+ }
62
+ }
63
+ let snapshotJson = data;
64
+ if (variablesOnly) {
65
+ snapshotJson = {
66
+ variables: data.variables,
67
+ };
68
+ }
69
+ // Write JSON output if requested
70
+ if (outputPath) {
71
+ const resolvedOutput = path.resolve(outputPath);
72
+ fs.mkdirSync(path.dirname(resolvedOutput), { recursive: true });
73
+ fs.writeFileSync(resolvedOutput, JSON.stringify(snapshotJson, null, 2), 'utf-8');
74
+ console.log(`✅ Snapshot JSON written to: ${resolvedOutput}`);
75
+ }
76
+ // Write CSS output if requested
77
+ if (outputCssPath) {
78
+ const resolvedCssOutput = path.resolve(outputCssPath);
79
+ fs.mkdirSync(path.dirname(resolvedCssOutput), { recursive: true });
80
+ let cssContent = `/* @strata-ds/core — Auto-generated CSS fallback variables\n`;
81
+ cssContent += ` * Project: ${projectId}\n`;
82
+ cssContent += ` * Generated: ${new Date().toISOString()}\n`;
83
+ cssContent += ` * DO NOT EDIT MANUALLY — regenerate with CLI snapshot tool\n`;
84
+ cssContent += ` */\n\n`;
85
+ cssContent += `:root {\n`;
86
+ const variables = data.variables || {};
87
+ for (const [key, val] of Object.entries(variables)) {
88
+ const resolvedVal = val.resolvedValue ?? val.value;
89
+ cssContent += ` ${key}: ${resolvedVal};\n`;
90
+ }
91
+ cssContent += `}\n`;
92
+ fs.writeFileSync(resolvedCssOutput, cssContent, 'utf-8');
93
+ console.log(`✅ CSS fallback written to: ${resolvedCssOutput}`);
94
+ }
95
+ }
96
+ catch (error) {
97
+ console.warn(`⚠️ Warning: Fetch failed: ${error.message || error}`);
98
+ // If fetch failed, check if output files already exist to degrade gracefully (exit 0)
99
+ let jsonExists = false;
100
+ let cssExists = false;
101
+ if (outputPath && fs.existsSync(path.resolve(outputPath))) {
102
+ jsonExists = true;
103
+ }
104
+ if (outputCssPath && fs.existsSync(path.resolve(outputCssPath))) {
105
+ cssExists = true;
106
+ }
107
+ const requestedOutputs = [];
108
+ if (outputPath)
109
+ requestedOutputs.push('JSON');
110
+ if (outputCssPath)
111
+ requestedOutputs.push('CSS');
112
+ const existingOutputs = [];
113
+ if (jsonExists)
114
+ existingOutputs.push('JSON');
115
+ if (cssExists)
116
+ existingOutputs.push('CSS');
117
+ if (requestedOutputs.length > 0 && requestedOutputs.length === existingOutputs.length) {
118
+ console.warn(`ℹ️ Existing output file(s) found. Graceful degradation: exiting 0.`);
119
+ return;
120
+ }
121
+ else {
122
+ throw new Error('Fetch failed and no existing local outputs found to fall back on.');
123
+ }
124
+ }
125
+ }
126
+
127
+ function findHostStrataJson() {
128
+ let currentDir = process.cwd();
129
+ // Traverse up to find the host application's strata.json
130
+ while (true) {
131
+ const jsonPath = path.join(currentDir, 'strata.json');
132
+ if (fs.existsSync(jsonPath)) {
133
+ try {
134
+ const config = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
135
+ return { jsonPath, rootDir: currentDir, config };
136
+ }
137
+ catch (e) { }
138
+ }
139
+ const parentDir = path.dirname(currentDir);
140
+ if (parentDir === currentDir)
141
+ break;
142
+ currentDir = parentDir;
143
+ }
144
+ return null;
145
+ }
146
+ async function run() {
147
+ const hostInfo = findHostStrataJson();
148
+ if (!hostInfo) {
149
+ console.log('[Strata] No strata.json configuration file found. Run "npx strata init" to initialize design token fallback configuration.');
150
+ return;
151
+ }
152
+ const { rootDir, config } = hostInfo;
153
+ const { projectId, snapshotCdnBase, output, outputCss, syncToken, variablesOnly } = config;
154
+ if (!projectId || !snapshotCdnBase) {
155
+ console.warn('[Strata] Warning: "projectId" and "snapshotCdnBase" are required in strata.json config.');
156
+ return;
157
+ }
158
+ const outputPath = output ? path.resolve(rootDir, output) : undefined;
159
+ const outputCssPath = outputCss ? path.resolve(rootDir, outputCss) : undefined;
160
+ console.log(`[Strata] Postinstall: Fetching snapshot for project ${projectId}...`);
161
+ try {
162
+ await retrieveSnapshot({
163
+ projectId,
164
+ cdnBase: snapshotCdnBase,
165
+ outputPath,
166
+ outputCssPath,
167
+ syncToken,
168
+ variablesOnly: variablesOnly !== false,
169
+ });
170
+ console.log('[Strata] Postinstall snapshot retrieval complete.');
171
+ }
172
+ catch (error) {
173
+ // Graceful degradation: log warning but do not throw error so install succeeds
174
+ console.warn(`[Strata] Postinstall snapshot failed: ${error.message || error}`);
175
+ }
176
+ }
177
+ run();
@@ -0,0 +1,9 @@
1
+ export interface RetrieveOptions {
2
+ projectId: string;
3
+ cdnBase: string;
4
+ outputPath?: string;
5
+ outputCssPath?: string;
6
+ syncToken?: string;
7
+ variablesOnly?: boolean;
8
+ }
9
+ export declare function retrieveSnapshot(options: RetrieveOptions): Promise<void>;
@@ -2,51 +2,10 @@
2
2
 
3
3
  import * as fs from 'fs';
4
4
  import * as path from 'path';
5
+ import * as readline from 'readline';
5
6
 
6
- function printHelp() {
7
- console.log(`
8
- Strata Design System Snapshot CLI
9
-
10
- Usage:
11
- npx strata-ds [options]
12
-
13
- Options:
14
- --project-id Strata Project ID (required)
15
- --cdn-base CDN base URL (e.g. https://dx2nhw7wqn4nn.cloudfront.net) (required)
16
- --output Path to write the snapshot JSON file (optional)
17
- --output-css Path to write the CSS fallback file (optional)
18
- --sync-token Authorization Sync Token (optional)
19
- --variables-only Only output variables in the snapshot JSON (optional)
20
- --help, -h Show help
21
- `);
22
- }
23
- async function run() {
24
- const args = process.argv.slice(2);
25
- if (args.includes('--help') || args.includes('-h') || args.length === 0) {
26
- printHelp();
27
- process.exit(0);
28
- }
29
- const getArgValue = (flag) => {
30
- const idx = args.indexOf(flag);
31
- if (idx !== -1 && idx + 1 < args.length) {
32
- return args[idx + 1];
33
- }
34
- return undefined;
35
- };
36
- const hasFlag = (flag) => {
37
- return args.includes(flag);
38
- };
39
- const projectId = getArgValue('--project-id');
40
- const cdnBase = getArgValue('--cdn-base');
41
- const outputPath = getArgValue('--output');
42
- const outputCssPath = getArgValue('--output-css');
43
- const syncToken = getArgValue('--sync-token');
44
- const variablesOnly = hasFlag('--variables-only');
45
- if (!projectId || !cdnBase) {
46
- console.error('❌ Error: --project-id and --cdn-base are required.');
47
- printHelp();
48
- process.exit(1);
49
- }
7
+ async function retrieveSnapshot(options) {
8
+ const { projectId, cdnBase, outputPath, outputCssPath, syncToken, variablesOnly } = options;
50
9
  const base = cdnBase.replace(/\/+$/, '');
51
10
  const snapshotUrl = base.endsWith('/snapshots')
52
11
  ? `${base}/${projectId}/strata.json`
@@ -66,6 +25,44 @@ async function run() {
66
25
  if (!data || typeof data !== 'object' || typeof data.variables !== 'object') {
67
26
  throw new Error('Invalid snapshot response shape: missing variables');
68
27
  }
28
+ // Sanitize variables to prevent malformed values from breaking outputs
29
+ const variables = data.variables || {};
30
+ for (const [key, val] of Object.entries(variables)) {
31
+ if (val && typeof val === 'object') {
32
+ let value = val.value;
33
+ let resolvedValue = val.resolvedValue;
34
+ // Sanitize value
35
+ if (typeof value === 'string') {
36
+ if (value.endsWith('\\')) {
37
+ value += '\\';
38
+ }
39
+ if (value.startsWith('url(') && !value.endsWith(')')) {
40
+ if (value === 'url(\\' || value === 'url(\\\\' || value === 'url(\\;') {
41
+ value = 'none';
42
+ }
43
+ else {
44
+ value += ')';
45
+ }
46
+ }
47
+ val.value = value;
48
+ }
49
+ // Sanitize resolvedValue
50
+ if (typeof resolvedValue === 'string') {
51
+ if (resolvedValue.endsWith('\\')) {
52
+ resolvedValue += '\\';
53
+ }
54
+ if (resolvedValue.startsWith('url(') && !resolvedValue.endsWith(')')) {
55
+ if (resolvedValue === 'url(\\' || resolvedValue === 'url(\\\\' || resolvedValue === 'url(\\;') {
56
+ resolvedValue = 'none';
57
+ }
58
+ else {
59
+ resolvedValue += ')';
60
+ }
61
+ }
62
+ val.resolvedValue = resolvedValue;
63
+ }
64
+ }
65
+ }
69
66
  let snapshotJson = data;
70
67
  if (variablesOnly) {
71
68
  snapshotJson = {
@@ -122,12 +119,149 @@ async function run() {
122
119
  existingOutputs.push('CSS');
123
120
  if (requestedOutputs.length > 0 && requestedOutputs.length === existingOutputs.length) {
124
121
  console.warn(`ℹ️ Existing output file(s) found. Graceful degradation: exiting 0.`);
125
- process.exit(0);
122
+ return;
126
123
  }
127
124
  else {
128
- console.error('❌ Error: Fetch failed and no existing local outputs found to fall back on.');
125
+ throw new Error('Fetch failed and no existing local outputs found to fall back on.');
126
+ }
127
+ }
128
+ }
129
+
130
+ function printHelp() {
131
+ console.log(`
132
+ Strata Design System Snapshot CLI
133
+
134
+ Usage:
135
+ npx strata [command] [options]
136
+
137
+ Commands:
138
+ init Interactively initialize strata.json configuration file
139
+ run Fetch snapshot and generate fallbacks using strata.json
140
+ snapshot Legacy command to fetch snapshot using options
141
+
142
+ Options:
143
+ --project-id Strata Project ID (overrides strata.json)
144
+ --cdn-base CDN base URL (overrides strata.json)
145
+ --output Path to write the snapshot JSON file (overrides strata.json)
146
+ --output-css Path to write the CSS fallback file (overrides strata.json)
147
+ --sync-token Authorization Sync Token (overrides strata.json)
148
+ --variables-only Only output variables in the snapshot JSON (overrides strata.json)
149
+ --help, -h Show help
150
+ `);
151
+ }
152
+ function askQuestion(query) {
153
+ const rl = readline.createInterface({
154
+ input: process.stdin,
155
+ output: process.stdout,
156
+ });
157
+ return new Promise((resolve) => rl.question(query, (ans) => {
158
+ rl.close();
159
+ resolve(ans.trim());
160
+ }));
161
+ }
162
+ async function runInit() {
163
+ console.log('Strata Design System Initialization\n');
164
+ let projectId = '';
165
+ while (!projectId) {
166
+ projectId = await askQuestion('Enter your Strata Project ID (required): ');
167
+ if (!projectId) {
168
+ console.log('Error: Project ID is required.');
169
+ }
170
+ }
171
+ const cdnBase = (await askQuestion('Enter CDN Base URL (default: https://dx2nhw7wqn4nn.cloudfront.net): ')) || 'https://dx2nhw7wqn4nn.cloudfront.net';
172
+ const output = (await askQuestion('Enter path to write snapshot JSON file (default: ./src/data/strata-snapshot.json): ')) || './src/data/strata-snapshot.json';
173
+ const outputCss = (await askQuestion('Enter path to write CSS fallback file (default: ./src/styles/strata-fallbacks.css): ')) || './src/styles/strata-fallbacks.css';
174
+ const varsOnlyInput = await askQuestion('Only output variables in snapshot JSON? (Y/n): ');
175
+ const variablesOnly = varsOnlyInput.toLowerCase() !== 'n';
176
+ const config = {
177
+ projectId,
178
+ snapshotCdnBase: cdnBase,
179
+ output,
180
+ outputCss,
181
+ variablesOnly,
182
+ };
183
+ const strataJsonPath = path.join(process.cwd(), 'strata.json');
184
+ fs.writeFileSync(strataJsonPath, JSON.stringify(config, null, 2), 'utf8');
185
+ console.log(`\nConfig file written successfully to: ${strataJsonPath}`);
186
+ console.log('To fetch your design tokens, run: npx strata run');
187
+ }
188
+ async function runRetrieve(command) {
189
+ const args = process.argv.slice(2);
190
+ const getArgValue = (flag) => {
191
+ const idx = args.indexOf(flag);
192
+ if (idx !== -1 && idx + 1 < args.length) {
193
+ return args[idx + 1];
194
+ }
195
+ return undefined;
196
+ };
197
+ const hasFlag = (flag) => {
198
+ return args.includes(flag);
199
+ };
200
+ // Load config from strata.json if it exists
201
+ const strataJsonPath = path.join(process.cwd(), 'strata.json');
202
+ let config = {};
203
+ if (fs.existsSync(strataJsonPath)) {
204
+ try {
205
+ config = JSON.parse(fs.readFileSync(strataJsonPath, 'utf8'));
206
+ }
207
+ catch (e) {
208
+ console.error(`Error reading strata.json: ${e.message}`);
129
209
  process.exit(1);
130
210
  }
131
211
  }
212
+ else if (command === 'run') {
213
+ console.error('Error: strata.json not found. Run "npx strata init" to initialize configuration.');
214
+ process.exit(1);
215
+ }
216
+ const projectId = getArgValue('--project-id') || config.projectId;
217
+ const cdnBase = getArgValue('--cdn-base') || config.snapshotCdnBase;
218
+ const outputPath = getArgValue('--output') || config.output;
219
+ const outputCssPath = getArgValue('--output-css') || config.outputCss;
220
+ const syncToken = getArgValue('--sync-token') || config.syncToken;
221
+ // variables-only is true by default if not set to false
222
+ let variablesOnly = true;
223
+ if (hasFlag('--variables-only')) {
224
+ variablesOnly = true;
225
+ }
226
+ else if (config.variablesOnly !== undefined) {
227
+ variablesOnly = config.variablesOnly;
228
+ }
229
+ if (!projectId || !cdnBase) {
230
+ console.error('Error: --project-id and --cdn-base are required (or must be configured in strata.json).');
231
+ printHelp();
232
+ process.exit(1);
233
+ }
234
+ try {
235
+ await retrieveSnapshot({
236
+ projectId,
237
+ cdnBase,
238
+ outputPath: outputPath ? path.resolve(outputPath) : undefined,
239
+ outputCssPath: outputCssPath ? path.resolve(outputCssPath) : undefined,
240
+ syncToken,
241
+ variablesOnly,
242
+ });
243
+ }
244
+ catch (error) {
245
+ console.error(`Error: ${error.message || error}`);
246
+ process.exit(1);
247
+ }
248
+ }
249
+ async function main() {
250
+ const args = process.argv.slice(2);
251
+ const command = args[0];
252
+ if (args.includes('--help') || args.includes('-h') || !command) {
253
+ printHelp();
254
+ process.exit(0);
255
+ }
256
+ if (command === 'init') {
257
+ await runInit();
258
+ }
259
+ else if (command === 'run' || command === 'snapshot') {
260
+ await runRetrieve(command);
261
+ }
262
+ else {
263
+ // If it's not a recognized command, default to legacy options-based fetch
264
+ await runRetrieve('legacy');
265
+ }
132
266
  }
133
- run();
267
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strata-ds/core",
3
- "version": "2.1.17",
3
+ "version": "2.1.19",
4
4
  "type": "module",
5
5
  "description": "The runtime component library for Strata — design once, sync everywhere.",
6
6
  "homepage": "https://strata.charisol.io",
@@ -8,7 +8,8 @@
8
8
  "module": "dist/index.esm.js",
9
9
  "types": "dist/index.d.ts",
10
10
  "bin": {
11
- "strata-ds": "./dist/cli/snapshot.js"
11
+ "strata-ds": "./dist/cli/snapshot.js",
12
+ "strata": "./dist/cli/snapshot.js"
12
13
  },
13
14
  "exports": {
14
15
  ".": {
@@ -25,7 +26,8 @@
25
26
  "build": "rollup -c",
26
27
  "dev": "rollup -c -w",
27
28
  "build:css": "tailwindcss -i ./src/styles.css -o ./dist/styles.css --minify",
28
- "prepublishOnly": "npm run build"
29
+ "prepublishOnly": "npm run build",
30
+ "postinstall": "node -e \"if (require('fs').existsSync('./dist/cli/postinstall.js')) import('./dist/cli/postinstall.js')\""
29
31
  },
30
32
  "keywords": [
31
33
  "strata",