@onexapis/cli 1.1.64 → 1.1.66

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/dist/index.js CHANGED
@@ -2,16 +2,16 @@
2
2
 
3
3
  var chalk4 = require('chalk');
4
4
  var ora = require('ora');
5
- var esbuild = require('esbuild');
6
- var path8 = require('path');
7
- var fs7 = require('fs/promises');
8
- var crypto = require('crypto');
5
+ var path10 = require('path');
9
6
  var glob = require('glob');
7
+ var fs = require('fs-extra');
8
+ var crypto = require('crypto');
9
+ var esbuild = require('esbuild');
10
+ var fs8 = require('fs/promises');
10
11
  var module$1 = require('module');
11
12
  var fs3 = require('fs');
12
13
  var child_process = require('child_process');
13
14
  var inquirer = require('inquirer');
14
- var fs = require('fs-extra');
15
15
  var ejs = require('ejs');
16
16
  var os = require('os');
17
17
  var AdmZip = require('adm-zip');
@@ -39,13 +39,13 @@ function _interopNamespace(e) {
39
39
 
40
40
  var chalk4__default = /*#__PURE__*/_interopDefault(chalk4);
41
41
  var ora__default = /*#__PURE__*/_interopDefault(ora);
42
- var esbuild__namespace = /*#__PURE__*/_interopNamespace(esbuild);
43
- var path8__default = /*#__PURE__*/_interopDefault(path8);
44
- var fs7__default = /*#__PURE__*/_interopDefault(fs7);
42
+ var path10__default = /*#__PURE__*/_interopDefault(path10);
43
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
45
44
  var crypto__default = /*#__PURE__*/_interopDefault(crypto);
45
+ var esbuild__namespace = /*#__PURE__*/_interopNamespace(esbuild);
46
+ var fs8__default = /*#__PURE__*/_interopDefault(fs8);
46
47
  var fs3__default = /*#__PURE__*/_interopDefault(fs3);
47
48
  var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
48
- var fs__default = /*#__PURE__*/_interopDefault(fs);
49
49
  var ejs__default = /*#__PURE__*/_interopDefault(ejs);
50
50
  var os__default = /*#__PURE__*/_interopDefault(os);
51
51
  var AdmZip__default = /*#__PURE__*/_interopDefault(AdmZip);
@@ -121,6 +121,187 @@ var init_logger = __esm({
121
121
  exports.logger = new exports.Logger();
122
122
  }
123
123
  });
124
+ function sortedCopy(value) {
125
+ if (Array.isArray(value)) {
126
+ return value.map((v) => sortedCopy(v));
127
+ }
128
+ if (value && typeof value === "object") {
129
+ const sorted = {};
130
+ for (const key of Object.keys(value).sort()) {
131
+ sorted[key] = sortedCopy(value[key]);
132
+ }
133
+ return sorted;
134
+ }
135
+ return value;
136
+ }
137
+ function normalizeField(raw) {
138
+ const out = {
139
+ id: String(raw.id),
140
+ type: String(raw.type)
141
+ };
142
+ if (raw.required === true) out.required = true;
143
+ if (raw.default !== void 0) out.default = raw.default;
144
+ if (Array.isArray(raw.aliases) && raw.aliases.length > 0) {
145
+ out.aliases = [...raw.aliases].map(String).sort();
146
+ }
147
+ if (typeof raw.maxLength === "number") out.maxLength = raw.maxLength;
148
+ if (typeof raw.min === "number") out.min = raw.min;
149
+ if (typeof raw.max === "number") out.max = raw.max;
150
+ if (typeof raw.step === "number") out.step = raw.step;
151
+ if (Array.isArray(raw.accept)) {
152
+ out.accept = [...raw.accept].map(String).sort();
153
+ }
154
+ if (Array.isArray(raw.options)) {
155
+ out.options = raw.options.map((o) => String(o?.value ?? o)).sort();
156
+ }
157
+ return out;
158
+ }
159
+ function normalizeBlock(raw) {
160
+ return {
161
+ type: String(raw.type),
162
+ settings: Array.isArray(raw.settings) ? raw.settings.map(normalizeField).sort(sortFieldsById) : [],
163
+ defaults: raw.defaults && typeof raw.defaults === "object" ? sortedCopy(raw.defaults) : {},
164
+ ...typeof raw.limit === "number" ? { limit: raw.limit } : {},
165
+ ...typeof raw.min === "number" ? { min: raw.min } : {},
166
+ ...raw.sortable === true ? { sortable: true } : {},
167
+ ...raw.baseType ? { baseType: String(raw.baseType) } : {}
168
+ };
169
+ }
170
+ function normalizeTemplate(raw) {
171
+ const out = { id: String(raw.id) };
172
+ if (raw.isDefault === true) out.isDefault = true;
173
+ if (Array.isArray(raw.settings)) {
174
+ out.settings = raw.settings.map(normalizeField).sort(sortFieldsById);
175
+ }
176
+ if (raw.defaults && typeof raw.defaults === "object") {
177
+ out.defaults = sortedCopy(raw.defaults);
178
+ }
179
+ return out;
180
+ }
181
+ function sortFieldsById(a, b) {
182
+ return a.id.localeCompare(b.id);
183
+ }
184
+ function sortByType(a, b) {
185
+ return a.type.localeCompare(b.type);
186
+ }
187
+ function normalizeSection(raw) {
188
+ return {
189
+ type: String(raw.type),
190
+ settings: Array.isArray(raw.settings) ? raw.settings.map(normalizeField).sort(sortFieldsById) : [],
191
+ defaults: raw.defaults && typeof raw.defaults === "object" ? sortedCopy(raw.defaults) : {},
192
+ blocks: Array.isArray(raw.blocks) ? raw.blocks.map(normalizeBlock).sort(sortByType) : [],
193
+ templates: Array.isArray(raw.templates) ? raw.templates.map(normalizeTemplate).sort(sortFieldsById) : [],
194
+ dataRequirements: raw.dataRequirements && typeof raw.dataRequirements === "object" ? sortedCopy(raw.dataRequirements) : null,
195
+ ...raw.global === true ? { global: true } : {},
196
+ ...typeof raw.maxBlocks === "number" ? { maxBlocks: raw.maxBlocks } : {}
197
+ };
198
+ }
199
+ async function extractSchemas(themePath) {
200
+ const { createJiti } = await import('jiti');
201
+ const jiti = createJiti((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)));
202
+ const schemaFiles = await glob.glob("sections/**/*.schema.ts", { cwd: themePath });
203
+ const sections = {};
204
+ for (const file of schemaFiles) {
205
+ try {
206
+ const mod = await jiti.import(path10__default.default.join(themePath, file));
207
+ const exports$1 = mod;
208
+ for (const value of Object.values(exports$1)) {
209
+ if (value && typeof value === "object" && typeof value.type === "string" && Array.isArray(value.settings)) {
210
+ const section = normalizeSection(value);
211
+ sections[section.type] = section;
212
+ }
213
+ }
214
+ } catch {
215
+ }
216
+ }
217
+ const manifest = {
218
+ manifestVersion: 1,
219
+ sections: {}
220
+ };
221
+ for (const type of Object.keys(sections).sort()) {
222
+ manifest.sections[type] = sections[type];
223
+ }
224
+ return manifest;
225
+ }
226
+ function serializeManifest(manifest) {
227
+ return JSON.stringify(sortedCopy(manifest), null, 2);
228
+ }
229
+ var init_extract_schemas = __esm({
230
+ "src/utils/extract-schemas.ts"() {
231
+ }
232
+ });
233
+ function mimeFor(filename) {
234
+ const ext = path10__default.default.extname(filename).toLowerCase();
235
+ return MIME_MAP[ext] || "application/octet-stream";
236
+ }
237
+ async function sha256Prefix(absPath, len) {
238
+ const buf = await fs__default.default.readFile(absPath);
239
+ return crypto__default.default.createHash("sha256").update(buf).digest("hex").slice(0, len);
240
+ }
241
+ function insertHashIntoName(relPath, hash) {
242
+ const dir = path10__default.default.posix.dirname(relPath);
243
+ const base = path10__default.default.posix.basename(relPath);
244
+ const ext = path10__default.default.posix.extname(base);
245
+ const stem = ext ? base.slice(0, -ext.length) : base;
246
+ const hashed = `${stem}-${hash}${ext}`;
247
+ return dir === "." ? hashed : `${dir}/${hashed}`;
248
+ }
249
+ async function scanThemeAssets(distDir) {
250
+ const assetsDir = path10__default.default.join(distDir, "theme-assets");
251
+ if (!await fs__default.default.pathExists(assetsDir)) return [];
252
+ const files = await glob.glob("**/*", {
253
+ cwd: assetsDir,
254
+ nodir: true,
255
+ dot: false
256
+ });
257
+ const results = [];
258
+ for (const rel of files) {
259
+ const absPath = path10__default.default.join(assetsDir, rel);
260
+ const stat = await fs__default.default.stat(absPath);
261
+ if (!stat.isFile()) continue;
262
+ const originalPath = rel.split(path10__default.default.sep).join("/");
263
+ const hash = await sha256Prefix(absPath, HASH_LEN);
264
+ const hashedPath = insertHashIntoName(originalPath, hash);
265
+ const contentType = mimeFor(rel);
266
+ results.push({
267
+ originalPath,
268
+ hashedPath,
269
+ hash,
270
+ size: stat.size,
271
+ contentType,
272
+ absPath
273
+ });
274
+ }
275
+ results.sort((a, b) => a.originalPath.localeCompare(b.originalPath));
276
+ return results;
277
+ }
278
+ var MIME_MAP, HASH_LEN;
279
+ var init_scan_theme_assets = __esm({
280
+ "src/utils/scan-theme-assets.ts"() {
281
+ MIME_MAP = {
282
+ ".png": "image/png",
283
+ ".jpg": "image/jpeg",
284
+ ".jpeg": "image/jpeg",
285
+ ".gif": "image/gif",
286
+ ".webp": "image/webp",
287
+ ".avif": "image/avif",
288
+ ".svg": "image/svg+xml",
289
+ ".ico": "image/x-icon",
290
+ ".bmp": "image/bmp",
291
+ ".woff": "font/woff",
292
+ ".woff2": "font/woff2",
293
+ ".ttf": "font/ttf",
294
+ ".otf": "font/otf",
295
+ ".eot": "application/vnd.ms-fontobject",
296
+ ".mp4": "video/mp4",
297
+ ".webm": "video/webm",
298
+ ".mov": "video/quicktime",
299
+ ".ogg": "video/ogg",
300
+ ".json": "application/json"
301
+ };
302
+ HASH_LEN = 8;
303
+ }
304
+ });
124
305
 
125
306
  // src/utils/compile-theme.ts
126
307
  var compile_theme_exports = {};
@@ -136,8 +317,8 @@ async function generateThemeCSS(themePath, outDir) {
136
317
  const tailwindcss = (await import('tailwindcss')).default;
137
318
  const tailwindConfig = {
138
319
  content: [
139
- path8__default.default.join(themePath, "sections/**/*.{ts,tsx}"),
140
- path8__default.default.join(themePath, "components/**/*.{ts,tsx}")
320
+ path10__default.default.join(themePath, "sections/**/*.{ts,tsx}"),
321
+ path10__default.default.join(themePath, "components/**/*.{ts,tsx}")
141
322
  ],
142
323
  theme: { extend: {} },
143
324
  plugins: []
@@ -147,7 +328,7 @@ async function generateThemeCSS(themePath, outDir) {
147
328
  inputCSS,
148
329
  { from: void 0 }
149
330
  );
150
- await fs7__default.default.writeFile(path8__default.default.join(outDir, "bundle.css"), result.css);
331
+ await fs8__default.default.writeFile(path10__default.default.join(outDir, "bundle.css"), result.css);
151
332
  exports.logger.info("Generated bundle.css");
152
333
  } catch (err) {
153
334
  exports.logger.warning(
@@ -158,12 +339,12 @@ async function generateThemeCSS(themePath, outDir) {
158
339
  async function resolveNodeModulesFile(startDir, relativePath) {
159
340
  let dir = startDir;
160
341
  while (true) {
161
- const candidate = path8__default.default.join(dir, "node_modules", relativePath);
342
+ const candidate = path10__default.default.join(dir, "node_modules", relativePath);
162
343
  try {
163
- await fs7__default.default.access(candidate);
344
+ await fs8__default.default.access(candidate);
164
345
  return candidate;
165
346
  } catch {
166
- const parent = path8__default.default.dirname(dir);
347
+ const parent = path10__default.default.dirname(dir);
167
348
  if (parent === dir) break;
168
349
  dir = parent;
169
350
  }
@@ -187,7 +368,7 @@ async function scanImportsFromPackage(sourceDir, packageName) {
187
368
  });
188
369
  for (const file of sourceFiles) {
189
370
  try {
190
- const content = await fs7__default.default.readFile(path8__default.default.join(sourceDir, file), "utf-8");
371
+ const content = await fs8__default.default.readFile(path10__default.default.join(sourceDir, file), "utf-8");
191
372
  for (const match of content.matchAll(namespaceImportRegex)) {
192
373
  const subpath = match[1] ? match[1].slice(1) : "";
193
374
  if (!result[subpath]) result[subpath] = /* @__PURE__ */ new Set();
@@ -241,17 +422,17 @@ function createCoreGlobalPlugin(themePath) {
241
422
  const distFileName = subpath ? `${subpath}.mjs` : "index.mjs";
242
423
  let distPath = await resolveNodeModulesFile(
243
424
  themePath,
244
- path8__default.default.join("@onexapis", "core", "dist", distFileName)
425
+ path10__default.default.join("@onexapis", "core", "dist", distFileName)
245
426
  );
246
427
  if (!distPath) {
247
428
  distPath = await resolveNodeModulesFile(
248
429
  __dirname,
249
- path8__default.default.join("@onexapis", "core", "dist", distFileName)
430
+ path10__default.default.join("@onexapis", "core", "dist", distFileName)
250
431
  );
251
432
  }
252
433
  try {
253
434
  if (!distPath) throw new Error("not found");
254
- const distContent = await fs7__default.default.readFile(distPath, "utf-8");
435
+ const distContent = await fs8__default.default.readFile(distPath, "utf-8");
255
436
  const exportMatches = distContent.matchAll(/export\s*\{([^}]+)\}/g);
256
437
  for (const m of exportMatches) {
257
438
  const names = m[1].split(",").map((n) => {
@@ -480,7 +661,7 @@ async function generateThemeData(themePath, outputDir, themeId) {
480
661
  const pages = {};
481
662
  for (const ext of [".ts", ".js"]) {
482
663
  try {
483
- const mod = await jiti.import(path8__default.default.join(themePath, `theme.config${ext}`));
664
+ const mod = await jiti.import(path10__default.default.join(themePath, `theme.config${ext}`));
484
665
  themeConfig = mod.default || mod;
485
666
  break;
486
667
  } catch {
@@ -488,20 +669,20 @@ async function generateThemeData(themePath, outputDir, themeId) {
488
669
  }
489
670
  for (const ext of [".ts", ".js"]) {
490
671
  try {
491
- const mod = await jiti.import(path8__default.default.join(themePath, `theme.layout${ext}`));
672
+ const mod = await jiti.import(path10__default.default.join(themePath, `theme.layout${ext}`));
492
673
  layoutConfig = mod.default || mod;
493
674
  break;
494
675
  } catch {
495
676
  }
496
677
  }
497
678
  const schemas = {};
498
- const sectionsDir = path8__default.default.join(themePath, "sections");
679
+ const sectionsDir = path10__default.default.join(themePath, "sections");
499
680
  try {
500
- const sectionDirs = await fs7__default.default.readdir(sectionsDir);
681
+ const sectionDirs = await fs8__default.default.readdir(sectionsDir);
501
682
  for (const dir of sectionDirs) {
502
- const schemaFile = path8__default.default.join(sectionsDir, dir, `${dir}.schema.ts`);
683
+ const schemaFile = path10__default.default.join(sectionsDir, dir, `${dir}.schema.ts`);
503
684
  try {
504
- await fs7__default.default.access(schemaFile);
685
+ await fs8__default.default.access(schemaFile);
505
686
  const mod = await jiti.import(schemaFile);
506
687
  for (const [key, value] of Object.entries(mod)) {
507
688
  if (key.endsWith("Schema") && value && typeof value === "object" && value.type) {
@@ -513,14 +694,14 @@ async function generateThemeData(themePath, outputDir, themeId) {
513
694
  }
514
695
  } catch {
515
696
  }
516
- const pagesDir = path8__default.default.join(themePath, "pages");
697
+ const pagesDir = path10__default.default.join(themePath, "pages");
517
698
  try {
518
- const files = await fs7__default.default.readdir(pagesDir);
699
+ const files = await fs8__default.default.readdir(pagesDir);
519
700
  for (const file of files) {
520
701
  if (!file.match(/\.(ts|js)$/)) continue;
521
702
  const name = file.replace(/\.(ts|js)$/, "");
522
703
  try {
523
- const mod = await jiti.import(path8__default.default.join(pagesDir, file));
704
+ const mod = await jiti.import(path10__default.default.join(pagesDir, file));
524
705
  const config = mod.default || mod;
525
706
  const sections = (config.sections || []).map((section) => {
526
707
  const schema = schemas[section.type];
@@ -548,8 +729,8 @@ async function generateThemeData(themePath, outputDir, themeId) {
548
729
  }
549
730
  } catch {
550
731
  }
551
- await fs7__default.default.writeFile(
552
- path8__default.default.join(outputDir, "theme-data.json"),
732
+ await fs8__default.default.writeFile(
733
+ path10__default.default.join(outputDir, "theme-data.json"),
553
734
  JSON.stringify(
554
735
  {
555
736
  themeId,
@@ -572,22 +753,22 @@ async function generateThemeData(themePath, outputDir, themeId) {
572
753
  exports.logger.info(`Generated theme-data.json (${Object.keys(pages).length} pages)`);
573
754
  }
574
755
  async function contentHashEntry(outputDir) {
575
- const entryPath = path8__default.default.join(outputDir, "bundle-entry.js");
576
- const mapPath = path8__default.default.join(outputDir, "bundle-entry.js.map");
756
+ const entryPath = path10__default.default.join(outputDir, "bundle-entry.js");
757
+ const mapPath = path10__default.default.join(outputDir, "bundle-entry.js.map");
577
758
  let entryContent;
578
759
  try {
579
- entryContent = await fs7__default.default.readFile(entryPath, "utf-8");
760
+ entryContent = await fs8__default.default.readFile(entryPath, "utf-8");
580
761
  } catch {
581
- const indexPath = path8__default.default.join(outputDir, "index.js");
762
+ const indexPath = path10__default.default.join(outputDir, "index.js");
582
763
  try {
583
- entryContent = await fs7__default.default.readFile(indexPath, "utf-8");
764
+ entryContent = await fs8__default.default.readFile(indexPath, "utf-8");
584
765
  } catch {
585
766
  exports.logger.warning("No entry file found in output, skipping content hash");
586
767
  return;
587
768
  }
588
769
  const hash2 = crypto__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
589
770
  const hashedName2 = `bundle-entry-${hash2}.js`;
590
- const indexMapPath = path8__default.default.join(outputDir, "index.js.map");
771
+ const indexMapPath = path10__default.default.join(outputDir, "index.js.map");
591
772
  const hashedMapName2 = `bundle-entry-${hash2}.js.map`;
592
773
  entryContent = entryContent.replace(
593
774
  /\/\/# sourceMappingURL=index\.js\.map/,
@@ -595,18 +776,18 @@ async function contentHashEntry(outputDir) {
595
776
  );
596
777
  const oldFiles2 = await glob.glob("bundle-entry-*.js*", { cwd: outputDir });
597
778
  for (const f of oldFiles2) {
598
- await fs7__default.default.unlink(path8__default.default.join(outputDir, f));
779
+ await fs8__default.default.unlink(path10__default.default.join(outputDir, f));
599
780
  }
600
- await fs7__default.default.writeFile(path8__default.default.join(outputDir, hashedName2), entryContent);
601
- await fs7__default.default.unlink(indexPath);
781
+ await fs8__default.default.writeFile(path10__default.default.join(outputDir, hashedName2), entryContent);
782
+ await fs8__default.default.unlink(indexPath);
602
783
  try {
603
- await fs7__default.default.unlink(entryPath);
784
+ await fs8__default.default.unlink(entryPath);
604
785
  } catch {
605
786
  }
606
- await fs7__default.default.writeFile(entryPath, entryContent);
787
+ await fs8__default.default.writeFile(entryPath, entryContent);
607
788
  try {
608
- await fs7__default.default.access(indexMapPath);
609
- await fs7__default.default.rename(indexMapPath, path8__default.default.join(outputDir, hashedMapName2));
789
+ await fs8__default.default.access(indexMapPath);
790
+ await fs8__default.default.rename(indexMapPath, path10__default.default.join(outputDir, hashedMapName2));
610
791
  } catch {
611
792
  }
612
793
  exports.logger.info(`Entry hashed: ${hashedName2}`);
@@ -621,17 +802,17 @@ async function contentHashEntry(outputDir) {
621
802
  );
622
803
  const oldFiles = await glob.glob("bundle-entry-*.js*", { cwd: outputDir });
623
804
  for (const f of oldFiles) {
624
- await fs7__default.default.unlink(path8__default.default.join(outputDir, f));
805
+ await fs8__default.default.unlink(path10__default.default.join(outputDir, f));
625
806
  }
626
- await fs7__default.default.writeFile(path8__default.default.join(outputDir, hashedName), entryContent);
807
+ await fs8__default.default.writeFile(path10__default.default.join(outputDir, hashedName), entryContent);
627
808
  try {
628
- await fs7__default.default.unlink(entryPath);
809
+ await fs8__default.default.unlink(entryPath);
629
810
  } catch {
630
811
  }
631
- await fs7__default.default.writeFile(entryPath, entryContent);
812
+ await fs8__default.default.writeFile(entryPath, entryContent);
632
813
  try {
633
- await fs7__default.default.access(mapPath);
634
- await fs7__default.default.rename(mapPath, path8__default.default.join(outputDir, hashedMapName));
814
+ await fs8__default.default.access(mapPath);
815
+ await fs8__default.default.rename(mapPath, path10__default.default.join(outputDir, hashedMapName));
635
816
  } catch {
636
817
  }
637
818
  exports.logger.info(`Entry hashed: ${hashedName}`);
@@ -643,7 +824,7 @@ async function extractDataRequirements(themePath) {
643
824
  const requirements = {};
644
825
  for (const file of schemaFiles) {
645
826
  try {
646
- const mod = await jiti.import(path8__default.default.join(themePath, file));
827
+ const mod = await jiti.import(path10__default.default.join(themePath, file));
647
828
  const exports$1 = mod;
648
829
  for (const value of Object.values(exports$1)) {
649
830
  if (value && typeof value === "object" && typeof value.type === "string" && value.dataRequirements && typeof value.dataRequirements === "object") {
@@ -658,12 +839,46 @@ async function extractDataRequirements(themePath) {
658
839
  }
659
840
  return requirements;
660
841
  }
842
+ async function writeGateManifests(themePath, outputDir) {
843
+ try {
844
+ const schemas = await extractSchemas(themePath);
845
+ await fs8__default.default.writeFile(
846
+ path10__default.default.join(outputDir, "schemas.json"),
847
+ serializeManifest(schemas)
848
+ );
849
+ exports.logger.info(
850
+ `Generated schemas.json (${Object.keys(schemas.sections).length} sections)`
851
+ );
852
+ } catch (err) {
853
+ exports.logger.warning(
854
+ `schemas.json not written: ${err instanceof Error ? err.message : String(err)}`
855
+ );
856
+ }
857
+ try {
858
+ const entries = await scanThemeAssets(outputDir);
859
+ const assets = entries.map((e) => ({
860
+ path: e.originalPath,
861
+ hash: e.hash,
862
+ size: e.size,
863
+ contentType: e.contentType
864
+ }));
865
+ await fs8__default.default.writeFile(
866
+ path10__default.default.join(outputDir, "asset-manifest.json"),
867
+ JSON.stringify({ manifestVersion: 1, assets }, null, 2)
868
+ );
869
+ exports.logger.info(`Generated asset-manifest.json (${assets.length} assets)`);
870
+ } catch (err) {
871
+ exports.logger.warning(
872
+ `asset-manifest.json not written: ${err instanceof Error ? err.message : String(err)}`
873
+ );
874
+ }
875
+ }
661
876
  async function generateManifest(themeName, themePath, outputDir) {
662
877
  let version = "1.0.0";
663
878
  let themeId = themeName;
664
879
  try {
665
- const pkgContent = await fs7__default.default.readFile(
666
- path8__default.default.join(themePath, "package.json"),
880
+ const pkgContent = await fs8__default.default.readFile(
881
+ path10__default.default.join(themePath, "package.json"),
667
882
  "utf-8"
668
883
  );
669
884
  const pkg = JSON.parse(pkgContent);
@@ -681,7 +896,7 @@ async function generateManifest(themeName, themePath, outputDir) {
681
896
  const dataRequirements = await extractDataRequirements(themePath);
682
897
  let hasThemeConfig = false;
683
898
  try {
684
- await fs7__default.default.access(path8__default.default.join(themePath, "theme.config.ts"));
899
+ await fs8__default.default.access(path10__default.default.join(themePath, "theme.config.ts"));
685
900
  hasThemeConfig = true;
686
901
  } catch {
687
902
  }
@@ -722,24 +937,24 @@ async function generateManifest(themeName, themePath, outputDir) {
722
937
  // Section data requirements for server-side prefetching (keyed by section type)
723
938
  dataRequirements
724
939
  };
725
- await fs7__default.default.writeFile(
726
- path8__default.default.join(outputDir, "manifest.json"),
940
+ await fs8__default.default.writeFile(
941
+ path10__default.default.join(outputDir, "manifest.json"),
727
942
  JSON.stringify(manifest, null, 2)
728
943
  );
729
944
  }
730
945
  async function compileStandaloneTheme(themePath, themeName) {
731
- const outputDir = path8__default.default.join(themePath, "dist");
732
- const bundleEntry = path8__default.default.join(themePath, "bundle-entry.ts");
733
- const indexEntry = path8__default.default.join(themePath, "index.ts");
946
+ const outputDir = path10__default.default.join(themePath, "dist");
947
+ const bundleEntry = path10__default.default.join(themePath, "bundle-entry.ts");
948
+ const indexEntry = path10__default.default.join(themePath, "index.ts");
734
949
  let entryPoint = indexEntry;
735
950
  try {
736
- await fs7__default.default.access(bundleEntry);
951
+ await fs8__default.default.access(bundleEntry);
737
952
  entryPoint = bundleEntry;
738
953
  } catch {
739
954
  }
740
- const shimPath = path8__default.default.join(outputDir, ".process-shim.js");
741
- await fs7__default.default.mkdir(outputDir, { recursive: true });
742
- await fs7__default.default.writeFile(shimPath, PROCESS_SHIM);
955
+ const shimPath = path10__default.default.join(outputDir, ".process-shim.js");
956
+ await fs8__default.default.mkdir(outputDir, { recursive: true });
957
+ await fs8__default.default.writeFile(shimPath, PROCESS_SHIM);
743
958
  const buildOptions = {
744
959
  entryPoints: [entryPoint],
745
960
  bundle: true,
@@ -790,19 +1005,20 @@ async function compileStandaloneTheme(themePath, themeName) {
790
1005
  try {
791
1006
  const result = await esbuild__namespace.build(buildOptions);
792
1007
  try {
793
- await fs7__default.default.unlink(shimPath);
1008
+ await fs8__default.default.unlink(shimPath);
794
1009
  } catch {
795
1010
  }
796
1011
  await contentHashEntry(outputDir);
797
- const themeAssetsDir = path8__default.default.join(themePath, "assets");
798
- const distThemeAssets = path8__default.default.join(outputDir, "theme-assets");
1012
+ const themeAssetsDir = path10__default.default.join(themePath, "assets");
1013
+ const distThemeAssets = path10__default.default.join(outputDir, "theme-assets");
799
1014
  try {
800
- await fs7__default.default.access(themeAssetsDir);
801
- await fs7__default.default.cp(themeAssetsDir, distThemeAssets, { recursive: true });
1015
+ await fs8__default.default.access(themeAssetsDir);
1016
+ await fs8__default.default.cp(themeAssetsDir, distThemeAssets, { recursive: true });
802
1017
  exports.logger.info("Copied static assets to dist/theme-assets/");
803
1018
  } catch {
804
1019
  }
805
1020
  await generateManifest(themeName, themePath, outputDir);
1021
+ await writeGateManifests(themePath, outputDir);
806
1022
  await generateThemeData(themePath, outputDir, themeName);
807
1023
  await generateThemeCSS(themePath, outputDir);
808
1024
  if (result.metafile) {
@@ -817,7 +1033,7 @@ async function compileStandaloneTheme(themePath, themeName) {
817
1033
  return true;
818
1034
  } catch (error) {
819
1035
  try {
820
- await fs7__default.default.unlink(shimPath);
1036
+ await fs8__default.default.unlink(shimPath);
821
1037
  } catch {
822
1038
  }
823
1039
  exports.logger.error(`esbuild compilation failed: ${error}`);
@@ -825,18 +1041,18 @@ async function compileStandaloneTheme(themePath, themeName) {
825
1041
  }
826
1042
  }
827
1043
  async function compileStandaloneThemeDev(themePath, themeName) {
828
- const outputDir = path8__default.default.join(themePath, "dist");
829
- const bundleEntry = path8__default.default.join(themePath, "bundle-entry.ts");
830
- const indexEntry = path8__default.default.join(themePath, "index.ts");
1044
+ const outputDir = path10__default.default.join(themePath, "dist");
1045
+ const bundleEntry = path10__default.default.join(themePath, "bundle-entry.ts");
1046
+ const indexEntry = path10__default.default.join(themePath, "index.ts");
831
1047
  let entryPoint = indexEntry;
832
1048
  try {
833
- await fs7__default.default.access(bundleEntry);
1049
+ await fs8__default.default.access(bundleEntry);
834
1050
  entryPoint = bundleEntry;
835
1051
  } catch {
836
1052
  }
837
- const shimPath = path8__default.default.join(outputDir, ".process-shim.js");
838
- await fs7__default.default.mkdir(outputDir, { recursive: true });
839
- await fs7__default.default.writeFile(shimPath, PROCESS_SHIM);
1053
+ const shimPath = path10__default.default.join(outputDir, ".process-shim.js");
1054
+ await fs8__default.default.mkdir(outputDir, { recursive: true });
1055
+ await fs8__default.default.writeFile(shimPath, PROCESS_SHIM);
840
1056
  const buildOptions = {
841
1057
  entryPoints: [entryPoint],
842
1058
  bundle: true,
@@ -890,18 +1106,18 @@ async function compileStandaloneThemeDev(themePath, themeName) {
890
1106
  return { context: context2, outputDir };
891
1107
  }
892
1108
  async function compilePreviewRuntime(themePath) {
893
- const outputDir = path8__default.default.join(themePath, "dist");
894
- await fs7__default.default.mkdir(outputDir, { recursive: true });
895
- const outputPath = path8__default.default.join(outputDir, "preview-runtime.js");
1109
+ const outputDir = path10__default.default.join(themePath, "dist");
1110
+ await fs8__default.default.mkdir(outputDir, { recursive: true });
1111
+ const outputPath = path10__default.default.join(outputDir, "preview-runtime.js");
896
1112
  const locations = [
897
- path8__default.default.join(__dirname, "..", "preview", "preview-app.tsx"),
898
- path8__default.default.join(__dirname, "preview", "preview-app.tsx"),
899
- path8__default.default.join(__dirname, "..", "..", "src", "preview", "preview-app.tsx")
1113
+ path10__default.default.join(__dirname, "..", "preview", "preview-app.tsx"),
1114
+ path10__default.default.join(__dirname, "preview", "preview-app.tsx"),
1115
+ path10__default.default.join(__dirname, "..", "..", "src", "preview", "preview-app.tsx")
900
1116
  ];
901
1117
  let previewEntryPath = null;
902
1118
  for (const loc of locations) {
903
1119
  try {
904
- await fs7__default.default.access(loc);
1120
+ await fs8__default.default.access(loc);
905
1121
  previewEntryPath = loc;
906
1122
  break;
907
1123
  } catch {
@@ -984,10 +1200,10 @@ ${locations.join("\n")}`
984
1200
  if (!lucideScanned) {
985
1201
  lucideScanned = true;
986
1202
  const coreSrcCandidates = [
987
- path8__default.default.join(themePath, "node_modules", "@onexapis", "core", "src"),
988
- path8__default.default.join(themePath, "..", "..", "packages", "core", "src"),
1203
+ path10__default.default.join(themePath, "node_modules", "@onexapis", "core", "src"),
1204
+ path10__default.default.join(themePath, "..", "..", "packages", "core", "src"),
989
1205
  // monorepo sibling
990
- path8__default.default.join(
1206
+ path10__default.default.join(
991
1207
  __dirname,
992
1208
  "..",
993
1209
  "..",
@@ -1002,7 +1218,7 @@ ${locations.join("\n")}`
1002
1218
  let coreSourceDir = null;
1003
1219
  for (const candidate of coreSrcCandidates) {
1004
1220
  try {
1005
- await fs7__default.default.access(candidate);
1221
+ await fs8__default.default.access(candidate);
1006
1222
  coreSourceDir = candidate;
1007
1223
  break;
1008
1224
  } catch {
@@ -1021,21 +1237,21 @@ ${locations.join("\n")}`
1021
1237
  }
1022
1238
  } else {
1023
1239
  const coreDistCandidates = [
1024
- path8__default.default.join(themePath, "node_modules", "@onexapis", "core", "dist")
1240
+ path10__default.default.join(themePath, "node_modules", "@onexapis", "core", "dist")
1025
1241
  ];
1026
1242
  const resolvedDist = await resolveNodeModulesFile(
1027
1243
  __dirname,
1028
- path8__default.default.join("@onexapis", "core", "dist")
1244
+ path10__default.default.join("@onexapis", "core", "dist")
1029
1245
  );
1030
1246
  if (resolvedDist) coreDistCandidates.push(resolvedDist);
1031
1247
  for (const candidate of coreDistCandidates) {
1032
1248
  try {
1033
- await fs7__default.default.access(candidate);
1249
+ await fs8__default.default.access(candidate);
1034
1250
  const mjsFiles = await glob.glob("*.mjs", { cwd: candidate });
1035
1251
  const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']lucide-react["']/g;
1036
1252
  for (const file of mjsFiles) {
1037
- const content = await fs7__default.default.readFile(
1038
- path8__default.default.join(candidate, file),
1253
+ const content = await fs8__default.default.readFile(
1254
+ path10__default.default.join(candidate, file),
1039
1255
  "utf-8"
1040
1256
  );
1041
1257
  for (const match of content.matchAll(importRegex)) {
@@ -1090,7 +1306,7 @@ export default new Proxy({}, { get: (_, name) => name === '__esModule' ? true :
1090
1306
  const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) || __filename);
1091
1307
  const cjsPath = req.resolve("framer-motion");
1092
1308
  const pkgDir = cjsPath.replace(/[/\\]dist[/\\].*$/, "");
1093
- const esmEntry = path8__default.default.join(pkgDir, "dist", "es", "index.mjs");
1309
+ const esmEntry = path10__default.default.join(pkgDir, "dist", "es", "index.mjs");
1094
1310
  const { existsSync } = await import('fs');
1095
1311
  if (existsSync(esmEntry)) {
1096
1312
  return { path: esmEntry, namespace: "file" };
@@ -1189,8 +1405,8 @@ export function headers() { return new Headers(); }
1189
1405
  });
1190
1406
  }
1191
1407
  };
1192
- const shimPath = path8__default.default.join(outputDir, ".process-shim-preview.js");
1193
- await fs7__default.default.writeFile(shimPath, PROCESS_SHIM);
1408
+ const shimPath = path10__default.default.join(outputDir, ".process-shim-preview.js");
1409
+ await fs8__default.default.writeFile(shimPath, PROCESS_SHIM);
1194
1410
  await esbuild__namespace.build({
1195
1411
  entryPoints: [previewEntryPath],
1196
1412
  bundle: true,
@@ -1225,7 +1441,7 @@ export function headers() { return new Headers(); }
1225
1441
  }
1226
1442
  });
1227
1443
  try {
1228
- await fs7__default.default.unlink(shimPath);
1444
+ await fs8__default.default.unlink(shimPath);
1229
1445
  } catch {
1230
1446
  }
1231
1447
  return outputPath;
@@ -1234,6 +1450,8 @@ var PROCESS_SHIM, reactGlobalPlugin, reactQueryGlobalPlugin;
1234
1450
  var init_compile_theme = __esm({
1235
1451
  "src/utils/compile-theme.ts"() {
1236
1452
  init_logger();
1453
+ init_extract_schemas();
1454
+ init_scan_theme_assets();
1237
1455
  PROCESS_SHIM = `
1238
1456
  if (typeof process === "undefined") {
1239
1457
  globalThis.process = {
@@ -1403,8 +1621,8 @@ function validateThemeName(name) {
1403
1621
  return /^[a-z][a-z0-9-]*$/.test(name);
1404
1622
  }
1405
1623
  function pathExists(filePath) {
1406
- const fs11 = __require("fs-extra");
1407
- return fs11.existsSync(filePath);
1624
+ const fs12 = __require("fs-extra");
1625
+ return fs12.existsSync(filePath);
1408
1626
  }
1409
1627
  function validateCategory(category) {
1410
1628
  const validCategories = [
@@ -1445,18 +1663,18 @@ async function renderTemplate(templatePath, data) {
1445
1663
  return ejs__default.default.render(template, data);
1446
1664
  }
1447
1665
  async function writeFile(filePath, content) {
1448
- await fs__default.default.ensureDir(path8__default.default.dirname(filePath));
1666
+ await fs__default.default.ensureDir(path10__default.default.dirname(filePath));
1449
1667
  await fs__default.default.writeFile(filePath, content, "utf-8");
1450
1668
  }
1451
1669
  function getTemplatesDir() {
1452
1670
  const locations = [
1453
- path8__default.default.join(__dirname, "../../templates"),
1671
+ path10__default.default.join(__dirname, "../../templates"),
1454
1672
  // Development
1455
- path8__default.default.join(__dirname, "../templates"),
1673
+ path10__default.default.join(__dirname, "../templates"),
1456
1674
  // Production (dist/)
1457
- path8__default.default.join(process.cwd(), "templates"),
1675
+ path10__default.default.join(process.cwd(), "templates"),
1458
1676
  // Fallback
1459
- path8__default.default.join(process.cwd(), "packages/cli/templates")
1677
+ path10__default.default.join(process.cwd(), "packages/cli/templates")
1460
1678
  // Monorepo
1461
1679
  ];
1462
1680
  for (const location of locations) {
@@ -1468,7 +1686,7 @@ function getTemplatesDir() {
1468
1686
  }
1469
1687
  async function copyTemplate(templateName, targetDir, data) {
1470
1688
  const templatesDir = getTemplatesDir();
1471
- const templateDir = path8__default.default.join(templatesDir, templateName);
1689
+ const templateDir = path10__default.default.join(templatesDir, templateName);
1472
1690
  if (!fs__default.default.existsSync(templateDir)) {
1473
1691
  throw new Error(
1474
1692
  `Template "${templateName}" not found at ${templateDir}. Available templates: ${fs__default.default.readdirSync(templatesDir).join(", ")}`
@@ -1477,8 +1695,8 @@ async function copyTemplate(templateName, targetDir, data) {
1477
1695
  await fs__default.default.ensureDir(targetDir);
1478
1696
  const files = await fs__default.default.readdir(templateDir);
1479
1697
  for (const file of files) {
1480
- const templatePath = path8__default.default.join(templateDir, file);
1481
- const targetPath = path8__default.default.join(targetDir, file);
1698
+ const templatePath = path10__default.default.join(templateDir, file);
1699
+ const targetPath = path10__default.default.join(targetDir, file);
1482
1700
  const stat = await fs__default.default.stat(templatePath);
1483
1701
  if (stat.isDirectory()) {
1484
1702
  await copyTemplateDir(templatePath, targetPath, data);
@@ -1495,8 +1713,8 @@ async function copyTemplateDir(templateDir, targetDir, data) {
1495
1713
  await fs__default.default.ensureDir(targetDir);
1496
1714
  const files = await fs__default.default.readdir(templateDir);
1497
1715
  for (const file of files) {
1498
- const templatePath = path8__default.default.join(templateDir, file);
1499
- const targetPath = path8__default.default.join(targetDir, file);
1716
+ const templatePath = path10__default.default.join(templateDir, file);
1717
+ const targetPath = path10__default.default.join(targetDir, file);
1500
1718
  const stat = await fs__default.default.stat(templatePath);
1501
1719
  if (stat.isDirectory()) {
1502
1720
  await copyTemplateDir(templatePath, targetPath, data);
@@ -1511,32 +1729,32 @@ async function copyTemplateDir(templateDir, targetDir, data) {
1511
1729
  }
1512
1730
  function getProjectRoot() {
1513
1731
  let currentDir = process.cwd();
1514
- while (currentDir !== path8__default.default.parse(currentDir).root) {
1515
- const packageJsonPath = path8__default.default.join(currentDir, "package.json");
1732
+ while (currentDir !== path10__default.default.parse(currentDir).root) {
1733
+ const packageJsonPath = path10__default.default.join(currentDir, "package.json");
1516
1734
  if (fs__default.default.existsSync(packageJsonPath)) {
1517
1735
  const packageJson = fs__default.default.readJsonSync(packageJsonPath);
1518
- if (packageJson.workspaces || fs__default.default.existsSync(path8__default.default.join(currentDir, "src/themes")) || fs__default.default.existsSync(path8__default.default.join(currentDir, "themes"))) {
1736
+ if (packageJson.workspaces || fs__default.default.existsSync(path10__default.default.join(currentDir, "src/themes")) || fs__default.default.existsSync(path10__default.default.join(currentDir, "themes"))) {
1519
1737
  return currentDir;
1520
1738
  }
1521
1739
  }
1522
- currentDir = path8__default.default.dirname(currentDir);
1740
+ currentDir = path10__default.default.dirname(currentDir);
1523
1741
  }
1524
1742
  return process.cwd();
1525
1743
  }
1526
1744
  function getThemesDir() {
1527
1745
  const root = getProjectRoot();
1528
- if (fs__default.default.existsSync(path8__default.default.join(root, "themes")))
1529
- return path8__default.default.join(root, "themes");
1530
- if (fs__default.default.existsSync(path8__default.default.join(root, "src/themes")))
1531
- return path8__default.default.join(root, "src/themes");
1532
- return path8__default.default.dirname(root);
1746
+ if (fs__default.default.existsSync(path10__default.default.join(root, "themes")))
1747
+ return path10__default.default.join(root, "themes");
1748
+ if (fs__default.default.existsSync(path10__default.default.join(root, "src/themes")))
1749
+ return path10__default.default.join(root, "src/themes");
1750
+ return path10__default.default.dirname(root);
1533
1751
  }
1534
1752
  function getFeaturesDir() {
1535
- return path8__default.default.join(getProjectRoot(), "src/features");
1753
+ return path10__default.default.join(getProjectRoot(), "src/features");
1536
1754
  }
1537
1755
  function isOneXProject() {
1538
1756
  const root = getProjectRoot();
1539
- return fs__default.default.existsSync(path8__default.default.join(root, "themes")) || fs__default.default.existsSync(path8__default.default.join(root, "src/themes")) || fs__default.default.existsSync(path8__default.default.join(root, "theme.config.ts")) || fs__default.default.existsSync(path8__default.default.join(root, "bundle-entry.ts"));
1757
+ return fs__default.default.existsSync(path10__default.default.join(root, "themes")) || fs__default.default.existsSync(path10__default.default.join(root, "src/themes")) || fs__default.default.existsSync(path10__default.default.join(root, "theme.config.ts")) || fs__default.default.existsSync(path10__default.default.join(root, "bundle-entry.ts"));
1540
1758
  }
1541
1759
  function ensureOneXProject() {
1542
1760
  if (!isOneXProject()) {
@@ -1552,13 +1770,13 @@ function listThemes() {
1552
1770
  return [];
1553
1771
  }
1554
1772
  return fs__default.default.readdirSync(themesDir).filter((name) => {
1555
- const themePath = path8__default.default.join(themesDir, name);
1556
- return fs__default.default.statSync(themePath).isDirectory() && (fs__default.default.existsSync(path8__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path8__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path8__default.default.join(themePath, "manifest.ts")));
1773
+ const themePath = path10__default.default.join(themesDir, name);
1774
+ return fs__default.default.statSync(themePath).isDirectory() && (fs__default.default.existsSync(path10__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path10__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path10__default.default.join(themePath, "manifest.ts")));
1557
1775
  });
1558
1776
  }
1559
1777
  function themeExists(themeName) {
1560
- const themePath = path8__default.default.join(getThemesDir(), themeName);
1561
- return fs__default.default.existsSync(themePath) && (fs__default.default.existsSync(path8__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path8__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path8__default.default.join(themePath, "manifest.ts")));
1778
+ const themePath = path10__default.default.join(getThemesDir(), themeName);
1779
+ return fs__default.default.existsSync(themePath) && (fs__default.default.existsSync(path10__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path10__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path10__default.default.join(themePath, "manifest.ts")));
1562
1780
  }
1563
1781
  function detectPackageManager() {
1564
1782
  const userAgent = process.env.npm_config_user_agent || "";
@@ -1566,9 +1784,9 @@ function detectPackageManager() {
1566
1784
  if (userAgent.includes("yarn")) return "yarn";
1567
1785
  if (userAgent.includes("bun")) return "bun";
1568
1786
  const cwd = process.cwd();
1569
- if (fs__default.default.existsSync(path8__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
1570
- if (fs__default.default.existsSync(path8__default.default.join(cwd, "yarn.lock"))) return "yarn";
1571
- if (fs__default.default.existsSync(path8__default.default.join(cwd, "bun.lockb"))) return "bun";
1787
+ if (fs__default.default.existsSync(path10__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
1788
+ if (fs__default.default.existsSync(path10__default.default.join(cwd, "yarn.lock"))) return "yarn";
1789
+ if (fs__default.default.existsSync(path10__default.default.join(cwd, "bun.lockb"))) return "bun";
1572
1790
  return "npm";
1573
1791
  }
1574
1792
  async function installDependencies(projectPath, packageManager = "npm") {
@@ -1585,22 +1803,45 @@ async function installDependencies(projectPath, packageManager = "npm") {
1585
1803
  }
1586
1804
  });
1587
1805
  }
1588
- var AUTH_DIR = path8__default.default.join(os__default.default.homedir(), ".onexthm");
1589
- var AUTH_FILE = path8__default.default.join(AUTH_DIR, "auth.json");
1590
- function getApiUrl() {
1591
- return process.env.ONEXTHM_API_URL || "https://platform-dev.onexeos.com";
1806
+ var AUTH_DIR = path10__default.default.join(os__default.default.homedir(), ".onexthm");
1807
+ var ENV_URLS = {
1808
+ dev: "https://platform-dev.onexeos.com",
1809
+ staging: "https://platform-staging.onexeos.com",
1810
+ prod: "https://platform-apis.onexeos.com"
1811
+ };
1812
+ function getAuthFile(env = "dev") {
1813
+ const newFile = path10__default.default.join(AUTH_DIR, `auth-${env}.json`);
1814
+ if (env === "dev") {
1815
+ const legacyFile = path10__default.default.join(AUTH_DIR, "auth.json");
1816
+ if (fs__default.default.existsSync(legacyFile) && !fs__default.default.existsSync(newFile)) {
1817
+ try {
1818
+ fs__default.default.moveSync(legacyFile, newFile);
1819
+ } catch {
1820
+ try {
1821
+ fs__default.default.copySync(legacyFile, newFile);
1822
+ fs__default.default.removeSync(legacyFile);
1823
+ } catch {
1824
+ }
1825
+ }
1826
+ }
1827
+ }
1828
+ return newFile;
1829
+ }
1830
+ function getApiUrl(env = "dev") {
1831
+ return process.env.ONEXTHM_API_URL || ENV_URLS[env];
1592
1832
  }
1593
- async function saveAuthTokens(tokens) {
1833
+ async function saveAuthTokens(tokens, env = "dev") {
1594
1834
  await fs__default.default.ensureDir(AUTH_DIR);
1595
1835
  const key = getMachineKey();
1596
1836
  const data = JSON.stringify(tokens);
1597
1837
  const encrypted = encrypt(data, key);
1598
- await fs__default.default.writeFile(AUTH_FILE, encrypted, "utf-8");
1838
+ await fs__default.default.writeFile(getAuthFile(env), encrypted, "utf-8");
1599
1839
  }
1600
- function loadAuthTokens() {
1840
+ function loadAuthTokens(env = "dev") {
1601
1841
  try {
1602
- if (!fs__default.default.existsSync(AUTH_FILE)) return null;
1603
- const encrypted = fs__default.default.readFileSync(AUTH_FILE, "utf-8");
1842
+ const file = getAuthFile(env);
1843
+ if (!fs__default.default.existsSync(file)) return null;
1844
+ const encrypted = fs__default.default.readFileSync(file, "utf-8");
1604
1845
  const key = getMachineKey();
1605
1846
  const data = decrypt(encrypted, key);
1606
1847
  return JSON.parse(data);
@@ -1608,34 +1849,34 @@ function loadAuthTokens() {
1608
1849
  return null;
1609
1850
  }
1610
1851
  }
1611
- async function clearAuthTokens() {
1852
+ async function clearAuthTokens(env = "dev") {
1612
1853
  try {
1613
- await fs__default.default.remove(AUTH_FILE);
1854
+ await fs__default.default.remove(getAuthFile(env));
1614
1855
  } catch {
1615
1856
  }
1616
1857
  }
1617
1858
  function isTokenExpired(tokens) {
1618
1859
  return Date.now() / 1e3 > tokens.expiresAt - 300;
1619
1860
  }
1620
- async function getValidTokens() {
1621
- const tokens = loadAuthTokens();
1861
+ async function getValidTokens(env = "dev") {
1862
+ const tokens = loadAuthTokens(env);
1622
1863
  if (!tokens) return null;
1623
1864
  if (!isTokenExpired(tokens)) return tokens;
1624
1865
  try {
1625
- const apiUrl = getApiUrl();
1866
+ const apiUrl = getApiUrl(env);
1626
1867
  const response = await fetch(`${apiUrl}/auth/refresh`, {
1627
1868
  method: "POST",
1628
1869
  headers: { "Content-Type": "application/json" },
1629
1870
  body: JSON.stringify({ refresh_token: tokens.refreshToken })
1630
1871
  });
1631
1872
  if (!response.ok) {
1632
- await clearAuthTokens();
1873
+ await clearAuthTokens(env);
1633
1874
  return null;
1634
1875
  }
1635
1876
  const data = await response.json();
1636
1877
  const body = data.statusCode ? data.body : data;
1637
1878
  if (!body.IdToken) {
1638
- await clearAuthTokens();
1879
+ await clearAuthTokens(env);
1639
1880
  return null;
1640
1881
  }
1641
1882
  const refreshed = {
@@ -1644,17 +1885,19 @@ async function getValidTokens() {
1644
1885
  idToken: body.IdToken,
1645
1886
  expiresAt: Math.floor(Date.now() / 1e3) + (body.ExpiresIn || 3600)
1646
1887
  };
1647
- await saveAuthTokens(refreshed);
1888
+ await saveAuthTokens(refreshed, env);
1648
1889
  return refreshed;
1649
1890
  } catch {
1650
- await clearAuthTokens();
1891
+ await clearAuthTokens(env);
1651
1892
  return null;
1652
1893
  }
1653
1894
  }
1654
- async function authenticatedFetch(url, init) {
1655
- const tokens = await getValidTokens();
1895
+ async function authenticatedFetch(url, init, env = "dev") {
1896
+ const tokens = await getValidTokens(env);
1656
1897
  if (!tokens) {
1657
- throw new Error("Not logged in. Run: onexthm login");
1898
+ throw new Error(
1899
+ `Not logged in to ${env} environment. Run: onexthm login --env ${env}`
1900
+ );
1658
1901
  }
1659
1902
  const headers = new Headers(init?.headers);
1660
1903
  headers.set("Authorization", `Bearer ${tokens.idToken}`);
@@ -1711,7 +1954,7 @@ async function initCommand(projectName, options = {}) {
1711
1954
  if (!validateThemeName(kebabName)) {
1712
1955
  return "Invalid project name. Use lowercase letters, numbers, and hyphens only.";
1713
1956
  }
1714
- if (fs3__default.default.existsSync(path8__default.default.join(process.cwd(), kebabName))) {
1957
+ if (fs3__default.default.existsSync(path10__default.default.join(process.cwd(), kebabName))) {
1715
1958
  return `Directory "${kebabName}" already exists`;
1716
1959
  }
1717
1960
  return true;
@@ -1722,14 +1965,14 @@ async function initCommand(projectName, options = {}) {
1722
1965
  } else {
1723
1966
  name = toKebabCase(projectName);
1724
1967
  }
1725
- const projectPath = path8__default.default.join(process.cwd(), name);
1968
+ const projectPath = path10__default.default.join(process.cwd(), name);
1726
1969
  if (fs3__default.default.existsSync(projectPath)) {
1727
1970
  exports.logger.error(`Directory "${name}" already exists.`);
1728
1971
  process.exit(1);
1729
1972
  }
1730
1973
  if (!options.yes) {
1731
1974
  try {
1732
- const apiUrl = getApiUrl();
1975
+ const apiUrl = getApiUrl(options.env ?? "dev");
1733
1976
  const controller = new AbortController();
1734
1977
  const timeout = setTimeout(() => controller.abort(), 3e3);
1735
1978
  const response = await fetch(
@@ -1838,7 +2081,7 @@ async function initCommand(projectName, options = {}) {
1838
2081
  description,
1839
2082
  author
1840
2083
  );
1841
- const mcpJsonPath = path8__default.default.join(projectPath, ".mcp.json");
2084
+ const mcpJsonPath = path10__default.default.join(projectPath, ".mcp.json");
1842
2085
  if (fs3__default.default.existsSync(mcpJsonPath)) {
1843
2086
  let mcpContent = fs3__default.default.readFileSync(mcpJsonPath, "utf-8");
1844
2087
  if (figmaApiKey) {
@@ -1918,7 +2161,7 @@ async function initCommand(projectName, options = {}) {
1918
2161
  }
1919
2162
  }
1920
2163
  async function renameThemeInFiles(projectPath, themeName, displayName, description, author) {
1921
- const configPath = path8__default.default.join(projectPath, "theme.config.ts");
2164
+ const configPath = path10__default.default.join(projectPath, "theme.config.ts");
1922
2165
  if (fs3__default.default.existsSync(configPath)) {
1923
2166
  let content = fs3__default.default.readFileSync(configPath, "utf-8");
1924
2167
  content = content.replace(
@@ -1931,7 +2174,7 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
1931
2174
  );
1932
2175
  fs3__default.default.writeFileSync(configPath, content, "utf-8");
1933
2176
  }
1934
- const pkgPath = path8__default.default.join(projectPath, "package.json");
2177
+ const pkgPath = path10__default.default.join(projectPath, "package.json");
1935
2178
  if (fs3__default.default.existsSync(pkgPath)) {
1936
2179
  let content = fs3__default.default.readFileSync(pkgPath, "utf-8");
1937
2180
  content = content.replace(
@@ -1953,10 +2196,10 @@ async function createSectionCommand(name, options) {
1953
2196
  ensureOneXProject();
1954
2197
  if (!options.theme) {
1955
2198
  const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
1956
- (f) => fs__default.default.existsSync(path8__default.default.join(process.cwd(), f))
2199
+ (f) => fs__default.default.existsSync(path10__default.default.join(process.cwd(), f))
1957
2200
  );
1958
2201
  if (isStandaloneTheme) {
1959
- options.theme = path8__default.default.basename(process.cwd());
2202
+ options.theme = path10__default.default.basename(process.cwd());
1960
2203
  }
1961
2204
  }
1962
2205
  const sectionName = toKebabCase(name);
@@ -2019,35 +2262,35 @@ async function createSectionCommand(name, options) {
2019
2262
  };
2020
2263
  exports.logger.startSpinner("Creating section files...");
2021
2264
  try {
2022
- const themePath = path8__default.default.join(getThemesDir(), themeName);
2023
- const sectionPath = path8__default.default.join(themePath, "sections", sectionName);
2265
+ const themePath = path10__default.default.join(getThemesDir(), themeName);
2266
+ const sectionPath = path10__default.default.join(themePath, "sections", sectionName);
2024
2267
  const schemaContent = generateSectionSchema(data);
2025
2268
  await writeFile(
2026
- path8__default.default.join(sectionPath, `${sectionName}.schema.ts`),
2269
+ path10__default.default.join(sectionPath, `${sectionName}.schema.ts`),
2027
2270
  schemaContent
2028
2271
  );
2029
2272
  if (createTemplate) {
2030
2273
  const templateContent = generateSectionTemplate(data);
2031
2274
  await writeFile(
2032
- path8__default.default.join(sectionPath, `${sectionName}-default.tsx`),
2275
+ path10__default.default.join(sectionPath, `${sectionName}-default.tsx`),
2033
2276
  templateContent
2034
2277
  );
2035
2278
  }
2036
2279
  const indexContent = generateSectionIndex(data, createTemplate);
2037
- await writeFile(path8__default.default.join(sectionPath, "index.ts"), indexContent);
2280
+ await writeFile(path10__default.default.join(sectionPath, "index.ts"), indexContent);
2038
2281
  exports.logger.stopSpinner(true, "Section files created successfully!");
2039
2282
  exports.logger.newLine();
2040
2283
  exports.logger.section("Next steps:");
2041
2284
  exports.logger.log(
2042
- ` 1. Edit schema: ${path8__default.default.relative(process.cwd(), path8__default.default.join(sectionPath, `${sectionName}.schema.ts`))}`
2285
+ ` 1. Edit schema: ${path10__default.default.relative(process.cwd(), path10__default.default.join(sectionPath, `${sectionName}.schema.ts`))}`
2043
2286
  );
2044
2287
  if (createTemplate) {
2045
2288
  exports.logger.log(
2046
- ` 2. Edit template: ${path8__default.default.relative(process.cwd(), path8__default.default.join(sectionPath, `${sectionName}-default.tsx`))}`
2289
+ ` 2. Edit template: ${path10__default.default.relative(process.cwd(), path10__default.default.join(sectionPath, `${sectionName}-default.tsx`))}`
2047
2290
  );
2048
2291
  }
2049
2292
  exports.logger.log(
2050
- ` 3. Add to theme manifest: ${path8__default.default.relative(process.cwd(), path8__default.default.join(themePath, "manifest.ts"))}`
2293
+ ` 3. Add to theme manifest: ${path10__default.default.relative(process.cwd(), path10__default.default.join(themePath, "manifest.ts"))}`
2051
2294
  );
2052
2295
  exports.logger.newLine();
2053
2296
  exports.logger.success("Section created successfully!");
@@ -2195,10 +2438,10 @@ async function createBlockCommand(name, options) {
2195
2438
  ensureOneXProject();
2196
2439
  if (!options.theme) {
2197
2440
  const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
2198
- (f) => fs__default.default.existsSync(path8__default.default.join(process.cwd(), f))
2441
+ (f) => fs__default.default.existsSync(path10__default.default.join(process.cwd(), f))
2199
2442
  );
2200
2443
  if (isStandaloneTheme) {
2201
- options.theme = path8__default.default.basename(process.cwd());
2444
+ options.theme = path10__default.default.basename(process.cwd());
2202
2445
  }
2203
2446
  }
2204
2447
  const blockName = toKebabCase(name);
@@ -2273,24 +2516,24 @@ async function createBlockCommand(name, options) {
2273
2516
  };
2274
2517
  exports.logger.startSpinner("Creating block files...");
2275
2518
  try {
2276
- const blockPath = scope === "shared" ? path8__default.default.join(getFeaturesDir(), "blocks", blockName) : path8__default.default.join(getThemesDir(), themeName, "blocks", blockName);
2519
+ const blockPath = scope === "shared" ? path10__default.default.join(getFeaturesDir(), "blocks", blockName) : path10__default.default.join(getThemesDir(), themeName, "blocks", blockName);
2277
2520
  const schemaContent = generateBlockSchema(data);
2278
2521
  await writeFile(
2279
- path8__default.default.join(blockPath, `${blockName}.schema.ts`),
2522
+ path10__default.default.join(blockPath, `${blockName}.schema.ts`),
2280
2523
  schemaContent
2281
2524
  );
2282
2525
  const componentContent = generateBlockComponent(data);
2283
- await writeFile(path8__default.default.join(blockPath, `${blockName}.tsx`), componentContent);
2526
+ await writeFile(path10__default.default.join(blockPath, `${blockName}.tsx`), componentContent);
2284
2527
  const indexContent = generateBlockIndex(data);
2285
- await writeFile(path8__default.default.join(blockPath, "index.ts"), indexContent);
2528
+ await writeFile(path10__default.default.join(blockPath, "index.ts"), indexContent);
2286
2529
  exports.logger.stopSpinner(true, "Block files created successfully!");
2287
2530
  exports.logger.newLine();
2288
2531
  exports.logger.section("Next steps:");
2289
2532
  exports.logger.log(
2290
- ` 1. Edit schema: ${path8__default.default.relative(process.cwd(), path8__default.default.join(blockPath, `${blockName}.schema.ts`))}`
2533
+ ` 1. Edit schema: ${path10__default.default.relative(process.cwd(), path10__default.default.join(blockPath, `${blockName}.schema.ts`))}`
2291
2534
  );
2292
2535
  exports.logger.log(
2293
- ` 2. Edit component: ${path8__default.default.relative(process.cwd(), path8__default.default.join(blockPath, `${blockName}.tsx`))}`
2536
+ ` 2. Edit component: ${path10__default.default.relative(process.cwd(), path10__default.default.join(blockPath, `${blockName}.tsx`))}`
2294
2537
  );
2295
2538
  exports.logger.log(
2296
2539
  ` 3. Register in block registry: src/lib/registry/block-registry.ts`
@@ -2468,31 +2711,31 @@ async function createComponentCommand(name, options) {
2468
2711
  };
2469
2712
  exports.logger.startSpinner("Creating component files...");
2470
2713
  try {
2471
- const componentPath = path8__default.default.join(
2714
+ const componentPath = path10__default.default.join(
2472
2715
  getFeaturesDir(),
2473
2716
  "components",
2474
2717
  componentName
2475
2718
  );
2476
2719
  const schemaContent = generateComponentSchema(data);
2477
2720
  await writeFile(
2478
- path8__default.default.join(componentPath, `${componentName}.schema.ts`),
2721
+ path10__default.default.join(componentPath, `${componentName}.schema.ts`),
2479
2722
  schemaContent
2480
2723
  );
2481
2724
  const componentContent = generateComponent(data);
2482
2725
  await writeFile(
2483
- path8__default.default.join(componentPath, `${componentName}.tsx`),
2726
+ path10__default.default.join(componentPath, `${componentName}.tsx`),
2484
2727
  componentContent
2485
2728
  );
2486
2729
  const indexContent = generateComponentIndex(data);
2487
- await writeFile(path8__default.default.join(componentPath, "index.ts"), indexContent);
2730
+ await writeFile(path10__default.default.join(componentPath, "index.ts"), indexContent);
2488
2731
  exports.logger.stopSpinner(true, "Component files created successfully!");
2489
2732
  exports.logger.newLine();
2490
2733
  exports.logger.section("Next steps:");
2491
2734
  exports.logger.log(
2492
- ` 1. Edit schema: ${path8__default.default.relative(process.cwd(), path8__default.default.join(componentPath, `${componentName}.schema.ts`))}`
2735
+ ` 1. Edit schema: ${path10__default.default.relative(process.cwd(), path10__default.default.join(componentPath, `${componentName}.schema.ts`))}`
2493
2736
  );
2494
2737
  exports.logger.log(
2495
- ` 2. Edit component: ${path8__default.default.relative(process.cwd(), path8__default.default.join(componentPath, `${componentName}.tsx`))}`
2738
+ ` 2. Edit component: ${path10__default.default.relative(process.cwd(), path10__default.default.join(componentPath, `${componentName}.tsx`))}`
2496
2739
  );
2497
2740
  exports.logger.log(
2498
2741
  ` 3. Register in component registry: src/lib/registry/component-registry.ts`
@@ -2649,13 +2892,13 @@ async function listSections(themeFilter) {
2649
2892
  return;
2650
2893
  }
2651
2894
  for (const theme of themes) {
2652
- const sectionsDir = path8__default.default.join(getThemesDir(), theme, "sections");
2895
+ const sectionsDir = path10__default.default.join(getThemesDir(), theme, "sections");
2653
2896
  if (!fs__default.default.existsSync(sectionsDir)) {
2654
2897
  continue;
2655
2898
  }
2656
2899
  const sections = fs__default.default.readdirSync(sectionsDir).filter((name) => {
2657
- const sectionPath = path8__default.default.join(sectionsDir, name);
2658
- return fs__default.default.statSync(sectionPath).isDirectory() && fs__default.default.existsSync(path8__default.default.join(sectionPath, "index.ts"));
2900
+ const sectionPath = path10__default.default.join(sectionsDir, name);
2901
+ return fs__default.default.statSync(sectionPath).isDirectory() && fs__default.default.existsSync(path10__default.default.join(sectionPath, "index.ts"));
2659
2902
  });
2660
2903
  if (sections.length > 0) {
2661
2904
  exports.logger.log(chalk4__default.default.cyan(`
@@ -2669,11 +2912,11 @@ async function listSections(themeFilter) {
2669
2912
  }
2670
2913
  async function listBlocks(themeFilter) {
2671
2914
  exports.logger.section("\u{1F9F1} Blocks");
2672
- const sharedBlocksDir = path8__default.default.join(getFeaturesDir(), "blocks");
2915
+ const sharedBlocksDir = path10__default.default.join(getFeaturesDir(), "blocks");
2673
2916
  if (fs__default.default.existsSync(sharedBlocksDir)) {
2674
2917
  const sharedBlocks = fs__default.default.readdirSync(sharedBlocksDir).filter((name) => {
2675
- const blockPath = path8__default.default.join(sharedBlocksDir, name);
2676
- return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path8__default.default.join(blockPath, "index.ts"));
2918
+ const blockPath = path10__default.default.join(sharedBlocksDir, name);
2919
+ return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path10__default.default.join(blockPath, "index.ts"));
2677
2920
  });
2678
2921
  if (sharedBlocks.length > 0) {
2679
2922
  exports.logger.log(chalk4__default.default.cyan("\n Shared:"));
@@ -2684,13 +2927,13 @@ async function listBlocks(themeFilter) {
2684
2927
  }
2685
2928
  const themes = themeFilter ? [themeFilter] : listThemes();
2686
2929
  for (const theme of themes) {
2687
- const blocksDir = path8__default.default.join(getThemesDir(), theme, "blocks");
2930
+ const blocksDir = path10__default.default.join(getThemesDir(), theme, "blocks");
2688
2931
  if (!fs__default.default.existsSync(blocksDir)) {
2689
2932
  continue;
2690
2933
  }
2691
2934
  const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => {
2692
- const blockPath = path8__default.default.join(blocksDir, name);
2693
- return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path8__default.default.join(blockPath, "index.ts"));
2935
+ const blockPath = path10__default.default.join(blocksDir, name);
2936
+ return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path10__default.default.join(blockPath, "index.ts"));
2694
2937
  });
2695
2938
  if (blocks.length > 0) {
2696
2939
  exports.logger.log(chalk4__default.default.cyan(`
@@ -2704,14 +2947,14 @@ async function listBlocks(themeFilter) {
2704
2947
  }
2705
2948
  async function listComponents() {
2706
2949
  exports.logger.section("\u2699\uFE0F Components");
2707
- const componentsDir = path8__default.default.join(getFeaturesDir(), "components");
2950
+ const componentsDir = path10__default.default.join(getFeaturesDir(), "components");
2708
2951
  if (!fs__default.default.existsSync(componentsDir)) {
2709
2952
  exports.logger.warning("No components directory found");
2710
2953
  return;
2711
2954
  }
2712
2955
  const components = fs__default.default.readdirSync(componentsDir).filter((name) => {
2713
- const componentPath = path8__default.default.join(componentsDir, name);
2714
- return fs__default.default.statSync(componentPath).isDirectory() && fs__default.default.existsSync(path8__default.default.join(componentPath, "index.ts"));
2956
+ const componentPath = path10__default.default.join(componentsDir, name);
2957
+ return fs__default.default.statSync(componentPath).isDirectory() && fs__default.default.existsSync(path10__default.default.join(componentPath, "index.ts"));
2715
2958
  });
2716
2959
  if (components.length === 0) {
2717
2960
  exports.logger.warning("No components found");
@@ -2732,11 +2975,11 @@ async function listThemesInfo() {
2732
2975
  }
2733
2976
  exports.logger.log("");
2734
2977
  for (const theme of themes) {
2735
- const themeDir = path8__default.default.join(getThemesDir(), theme);
2978
+ const themeDir = path10__default.default.join(getThemesDir(), theme);
2736
2979
  const candidates = ["theme.config.ts", "bundle-entry.ts", "manifest.ts"];
2737
2980
  let manifestContent = "";
2738
2981
  for (const candidate of candidates) {
2739
- const candidatePath = path8__default.default.join(themeDir, candidate);
2982
+ const candidatePath = path10__default.default.join(themeDir, candidate);
2740
2983
  if (fs__default.default.existsSync(candidatePath)) {
2741
2984
  manifestContent = fs__default.default.readFileSync(candidatePath, "utf-8");
2742
2985
  break;
@@ -2765,14 +3008,14 @@ async function buildCommand(options) {
2765
3008
  if (options.theme) {
2766
3009
  themeName = options.theme;
2767
3010
  try {
2768
- const workspaceThemePath = path8__default.default.join(getThemesDir(), themeName);
3011
+ const workspaceThemePath = path10__default.default.join(getThemesDir(), themeName);
2769
3012
  if (fs__default.default.existsSync(workspaceThemePath)) {
2770
3013
  themePath = workspaceThemePath;
2771
3014
  } else {
2772
- themePath = path8__default.default.join(process.cwd(), themeName);
3015
+ themePath = path10__default.default.join(process.cwd(), themeName);
2773
3016
  }
2774
3017
  } catch {
2775
- themePath = path8__default.default.join(process.cwd(), themeName);
3018
+ themePath = path10__default.default.join(process.cwd(), themeName);
2776
3019
  }
2777
3020
  if (!fs__default.default.existsSync(themePath)) {
2778
3021
  exports.logger.error(`Theme "${themeName}" not found.`);
@@ -2783,10 +3026,10 @@ async function buildCommand(options) {
2783
3026
  "theme.config.ts",
2784
3027
  "bundle-entry.ts",
2785
3028
  "manifest.ts"
2786
- ].some((f) => fs__default.default.existsSync(path8__default.default.join(process.cwd(), f)));
3029
+ ].some((f) => fs__default.default.existsSync(path10__default.default.join(process.cwd(), f)));
2787
3030
  if (isThemeDir) {
2788
3031
  themePath = process.cwd();
2789
- themeName = path8__default.default.basename(themePath);
3032
+ themeName = path10__default.default.basename(themePath);
2790
3033
  exports.logger.info(`Building current theme: ${themeName}`);
2791
3034
  } else {
2792
3035
  exports.logger.error(
@@ -2795,7 +3038,7 @@ async function buildCommand(options) {
2795
3038
  process.exit(1);
2796
3039
  }
2797
3040
  }
2798
- const packageJsonPath = path8__default.default.join(themePath, "package.json");
3041
+ const packageJsonPath = path10__default.default.join(themePath, "package.json");
2799
3042
  const hasPkgJson = fs__default.default.existsSync(packageJsonPath);
2800
3043
  if (!hasPkgJson) {
2801
3044
  exports.logger.warning(
@@ -2851,9 +3094,9 @@ async function buildCommand(options) {
2851
3094
  exports.logger.success("\u2713 Theme built successfully!");
2852
3095
  exports.logger.newLine();
2853
3096
  exports.logger.info(`Theme: ${themeName}`);
2854
- const distPath = path8__default.default.join(themePath, "dist");
3097
+ const distPath = path10__default.default.join(themePath, "dist");
2855
3098
  if (fs__default.default.existsSync(distPath)) {
2856
- exports.logger.log(`Output: ${path8__default.default.relative(process.cwd(), distPath)}`);
3099
+ exports.logger.log(`Output: ${path10__default.default.relative(process.cwd(), distPath)}`);
2857
3100
  const files = fs__default.default.readdirSync(distPath);
2858
3101
  exports.logger.log(`Files: ${files.length}`);
2859
3102
  }
@@ -2994,8 +3237,8 @@ async function downloadBundleZip(apiUrl, themeId, version) {
2994
3237
  async function createCompatibilityFiles(outputDir, manifest) {
2995
3238
  const entryFile = manifest.output?.entry || "bundle-entry.js";
2996
3239
  if (entryFile !== "bundle-entry.js" && entryFile.startsWith("bundle-entry-")) {
2997
- const hashedPath = path8__default.default.join(outputDir, entryFile);
2998
- const stablePath = path8__default.default.join(outputDir, "bundle-entry.js");
3240
+ const hashedPath = path10__default.default.join(outputDir, entryFile);
3241
+ const stablePath = path10__default.default.join(outputDir, "bundle-entry.js");
2999
3242
  if (await fs__default.default.pathExists(hashedPath)) {
3000
3243
  await fs__default.default.copy(hashedPath, stablePath);
3001
3244
  const mapPath = hashedPath + ".map";
@@ -3004,13 +3247,13 @@ async function createCompatibilityFiles(outputDir, manifest) {
3004
3247
  }
3005
3248
  }
3006
3249
  }
3007
- const sectionsRegistryPath = path8__default.default.join(outputDir, "sections-registry.js");
3250
+ const sectionsRegistryPath = path10__default.default.join(outputDir, "sections-registry.js");
3008
3251
  const content = `// Re-export all sections from bundle-entry
3009
3252
  // This file exists to maintain compatibility with the import path
3010
3253
  export * from './bundle-entry.js';
3011
3254
  `;
3012
3255
  await fs__default.default.writeFile(sectionsRegistryPath, content, "utf-8");
3013
- const pkgJsonPath = path8__default.default.join(outputDir, "package.json");
3256
+ const pkgJsonPath = path10__default.default.join(outputDir, "package.json");
3014
3257
  await fs__default.default.writeFile(pkgJsonPath, '{\n "type": "module"\n}\n', "utf-8");
3015
3258
  }
3016
3259
  function showDownloadFailureHelp(themeId, apiUrl) {
@@ -3041,9 +3284,7 @@ function showDownloadFailureHelp(themeId, apiUrl) {
3041
3284
  console.log();
3042
3285
  console.log(chalk4__default.default.white("2. Check API URL configuration:"));
3043
3286
  console.log(chalk4__default.default.gray(` Current API URL: ${apiUrl}`));
3044
- console.log(
3045
- chalk4__default.default.gray(" Override with NEXT_PUBLIC_API_URL or ONEXTHM_API_URL")
3046
- );
3287
+ console.log(chalk4__default.default.gray(" Override with ONEXTHM_API_URL env var if needed"));
3047
3288
  console.log();
3048
3289
  console.log(chalk4__default.default.white("3. Pin a specific version (CI/production):"));
3049
3290
  console.log(
@@ -3053,15 +3294,17 @@ function showDownloadFailureHelp(themeId, apiUrl) {
3053
3294
  }
3054
3295
  async function downloadCommand(options) {
3055
3296
  exports.logger.header("Download Theme");
3297
+ const env = options.env ?? "dev";
3298
+ const apiUrl = getApiUrl(env);
3299
+ exports.logger.info(`Environment: ${env} (${apiUrl})`);
3056
3300
  const spinner = ora__default.default("Initializing download...").start();
3057
- if (options.bucket || options.environment) {
3301
+ if (options.bucket) {
3058
3302
  spinner.stop();
3059
3303
  exports.logger.warning(
3060
- "--bucket and --environment are deprecated and ignored. Themes are now served via HTTP from the website-api Lambda."
3304
+ "--bucket is deprecated and ignored. Themes are now served via HTTP from the website-api Lambda."
3061
3305
  );
3062
3306
  spinner.start();
3063
3307
  }
3064
- const apiUrl = getApiUrl();
3065
3308
  try {
3066
3309
  const themeId = options.themeId || process.env.NEXT_PUBLIC_THEME_ID || process.env.THEME_ID;
3067
3310
  const requestedVersion = options.version || process.env.THEME_VERSION || "latest";
@@ -3109,7 +3352,7 @@ async function downloadCommand(options) {
3109
3352
  zip.extractAllTo(outputDir, true);
3110
3353
  const entries = zip.getEntries().filter((e) => !e.isDirectory);
3111
3354
  spinner.succeed(`Extracted ${entries.length} files to ${outputDir}`);
3112
- const manifestPath = path8__default.default.join(outputDir, "manifest.json");
3355
+ const manifestPath = path10__default.default.join(outputDir, "manifest.json");
3113
3356
  const manifest = await fs__default.default.readJson(manifestPath);
3114
3357
  await createCompatibilityFiles(outputDir, manifest);
3115
3358
  console.log();
@@ -3118,6 +3361,7 @@ async function downloadCommand(options) {
3118
3361
  console.log(
3119
3362
  chalk4__default.default.cyan(" Theme: ") + chalk4__default.default.white(`${themeId}@${resolvedVersion}`)
3120
3363
  );
3364
+ console.log(chalk4__default.default.cyan(" Env: ") + chalk4__default.default.white(env));
3121
3365
  console.log(chalk4__default.default.cyan(" Source: ") + chalk4__default.default.white(apiUrl));
3122
3366
  console.log(chalk4__default.default.cyan(" Output: ") + chalk4__default.default.white(outputDir));
3123
3367
  console.log(chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(entries.length));
@@ -3160,11 +3404,9 @@ async function resolveLatestVersion2(apiUrl, themeId) {
3160
3404
  }
3161
3405
  return latest;
3162
3406
  }
3163
- async function fetchSourceZip(apiUrl, themeId, version) {
3407
+ async function fetchSourceZip(apiUrl, themeId, version, env) {
3164
3408
  const url = `${apiUrl}/website-api/themes/${encodeURIComponent(themeId)}/source?version=${encodeURIComponent(version)}`;
3165
- const response = await authenticatedFetch(url, {
3166
- method: "GET"
3167
- });
3409
+ const response = await authenticatedFetch(url, { method: "GET" }, env);
3168
3410
  if (!response.ok) {
3169
3411
  if (response.status === 404) {
3170
3412
  throw new Error(
@@ -3173,7 +3415,7 @@ async function fetchSourceZip(apiUrl, themeId, version) {
3173
3415
  }
3174
3416
  if (response.status === 401 || response.status === 403) {
3175
3417
  throw new Error(
3176
- `Not authorized to download source for "${themeId}". Run \`onexthm login\` first.`
3418
+ `Not authorized to download source for "${themeId}". Run \`onexthm login --env ${env}\` first.`
3177
3419
  );
3178
3420
  }
3179
3421
  throw new Error(
@@ -3231,7 +3473,7 @@ async function renameTheme(themeDir, oldName, newName) {
3231
3473
  const oldPrefix = `${oldName}-`;
3232
3474
  const newPrefix = `${newName}-`;
3233
3475
  const newDisplayName = newName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
3234
- const pkgPath = path8__default.default.join(themeDir, "package.json");
3476
+ const pkgPath = path10__default.default.join(themeDir, "package.json");
3235
3477
  if (await fs__default.default.pathExists(pkgPath)) {
3236
3478
  const pkg = await fs__default.default.readJson(pkgPath);
3237
3479
  pkg.name = `@onex-themes/${newName}`;
@@ -3247,7 +3489,7 @@ async function renameTheme(themeDir, oldName, newName) {
3247
3489
  }
3248
3490
  await fs__default.default.writeJson(pkgPath, pkg, { spaces: 2 });
3249
3491
  }
3250
- const configPath = path8__default.default.join(themeDir, "theme.config.ts");
3492
+ const configPath = path10__default.default.join(themeDir, "theme.config.ts");
3251
3493
  if (await fs__default.default.pathExists(configPath)) {
3252
3494
  let content = await fs__default.default.readFile(configPath, "utf-8");
3253
3495
  content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
@@ -3257,7 +3499,7 @@ async function renameTheme(themeDir, oldName, newName) {
3257
3499
  );
3258
3500
  await fs__default.default.writeFile(configPath, content);
3259
3501
  }
3260
- const layoutPath = path8__default.default.join(themeDir, "theme.layout.ts");
3502
+ const layoutPath = path10__default.default.join(themeDir, "theme.layout.ts");
3261
3503
  if (await fs__default.default.pathExists(layoutPath)) {
3262
3504
  let content = await fs__default.default.readFile(layoutPath, "utf-8");
3263
3505
  content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
@@ -3270,7 +3512,7 @@ async function renameTheme(themeDir, oldName, newName) {
3270
3512
  const oldDisplayName = oldName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
3271
3513
  const tsFiles = await glob.glob("**/*.ts", { cwd: themeDir, nodir: true });
3272
3514
  for (const file of tsFiles) {
3273
- const filePath = path8__default.default.join(themeDir, file);
3515
+ const filePath = path10__default.default.join(themeDir, file);
3274
3516
  let content = await fs__default.default.readFile(filePath, "utf-8");
3275
3517
  const original = content;
3276
3518
  content = content.replace(
@@ -3292,14 +3534,19 @@ async function renameTheme(themeDir, oldName, newName) {
3292
3534
  }
3293
3535
  async function cloneCommand(themeName, options) {
3294
3536
  exports.logger.header("Clone Theme Source");
3295
- if (options.bucket || options.environment) {
3537
+ const env = options.env ?? "dev";
3538
+ const apiUrl = getApiUrl(env);
3539
+ exports.logger.info(`Environment: ${env} (${apiUrl})`);
3540
+ if (options.bucket) {
3296
3541
  exports.logger.warning(
3297
- "--bucket and --environment are deprecated and ignored. Source is now fetched via HTTP from the website-api Lambda."
3542
+ "--bucket is deprecated and ignored. Source is now fetched via HTTP from the website-api Lambda."
3298
3543
  );
3299
3544
  }
3300
- const tokens = await getValidTokens();
3545
+ const tokens = await getValidTokens(env);
3301
3546
  if (!tokens) {
3302
- exports.logger.error("Not logged in. Run: onexthm login");
3547
+ exports.logger.error(
3548
+ `Not logged in to ${env} environment. Run: onexthm login --env ${env}`
3549
+ );
3303
3550
  process.exit(1);
3304
3551
  }
3305
3552
  let newName = options.name;
@@ -3308,8 +3555,7 @@ async function cloneCommand(themeName, options) {
3308
3555
  }
3309
3556
  const spinner = ora__default.default("Initializing clone...").start();
3310
3557
  try {
3311
- const apiUrl = getApiUrl();
3312
- const outputDir = options.output || path8__default.default.resolve(process.cwd(), newName);
3558
+ const outputDir = options.output || path10__default.default.resolve(process.cwd(), newName);
3313
3559
  if (await fs__default.default.pathExists(outputDir)) {
3314
3560
  spinner.fail(chalk4__default.default.red(`Directory already exists: ${outputDir}`));
3315
3561
  exports.logger.info(
@@ -3328,7 +3574,7 @@ async function cloneCommand(themeName, options) {
3328
3574
  spinner.start(`Downloading source.zip for ${themeName}@${version}...`);
3329
3575
  let zipBuffer;
3330
3576
  try {
3331
- zipBuffer = await fetchSourceZip(apiUrl, themeName, version);
3577
+ zipBuffer = await fetchSourceZip(apiUrl, themeName, version, env);
3332
3578
  } catch (error) {
3333
3579
  spinner.fail(chalk4__default.default.red(error.message));
3334
3580
  console.log();
@@ -3355,20 +3601,20 @@ async function cloneCommand(themeName, options) {
3355
3601
  spinner.succeed(
3356
3602
  `Renamed theme: ${chalk4__default.default.gray(themeName)} \u2192 ${chalk4__default.default.cyan(newName)}`
3357
3603
  );
3358
- const envExamplePath = path8__default.default.join(outputDir, ".env.example");
3604
+ const envExamplePath = path10__default.default.join(outputDir, ".env.example");
3359
3605
  if (!await fs__default.default.pathExists(envExamplePath)) {
3360
3606
  await fs__default.default.writeFile(
3361
3607
  envExamplePath,
3362
3608
  [
3363
3609
  "# API Configuration (enables real data in preview)",
3364
3610
  "# Get your Company ID from the OneX dashboard",
3365
- "NEXT_PUBLIC_API_URL=https://platform-dev.onexeos.com",
3611
+ `NEXT_PUBLIC_API_URL=${apiUrl}`,
3366
3612
  "NEXT_PUBLIC_COMPANY_ID=",
3367
3613
  ""
3368
3614
  ].join("\n")
3369
3615
  );
3370
3616
  }
3371
- const mcpJsonPath = path8__default.default.join(outputDir, ".mcp.json");
3617
+ const mcpJsonPath = path10__default.default.join(outputDir, ".mcp.json");
3372
3618
  if (await fs__default.default.pathExists(mcpJsonPath)) {
3373
3619
  const { default: inquirerMod } = await import('inquirer');
3374
3620
  const { figmaApiKey } = await inquirerMod.prompt([
@@ -3393,7 +3639,7 @@ async function cloneCommand(themeName, options) {
3393
3639
  }
3394
3640
  if (options.install !== false) {
3395
3641
  const hasPkgJson = await fs__default.default.pathExists(
3396
- path8__default.default.join(outputDir, "package.json")
3642
+ path10__default.default.join(outputDir, "package.json")
3397
3643
  );
3398
3644
  if (hasPkgJson) {
3399
3645
  spinner.start("Installing dependencies...");
@@ -3415,12 +3661,13 @@ async function cloneCommand(themeName, options) {
3415
3661
  console.log(
3416
3662
  chalk4__default.default.cyan(" Source: ") + chalk4__default.default.gray(`${themeName}@${version}`)
3417
3663
  );
3664
+ console.log(chalk4__default.default.cyan(" Env: ") + chalk4__default.default.white(env));
3418
3665
  console.log(chalk4__default.default.cyan(" Theme: ") + chalk4__default.default.white(newName));
3419
3666
  console.log(chalk4__default.default.cyan(" Location: ") + chalk4__default.default.white(outputDir));
3420
3667
  console.log(chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(entries.length));
3421
3668
  console.log();
3422
3669
  console.log(chalk4__default.default.cyan("Next steps:"));
3423
- console.log(chalk4__default.default.gray(` cd ${path8__default.default.relative(process.cwd(), outputDir)}`));
3670
+ console.log(chalk4__default.default.gray(` cd ${path10__default.default.relative(process.cwd(), outputDir)}`));
3424
3671
  console.log(
3425
3672
  chalk4__default.default.gray(" cp .env.example .env # then add your Company ID")
3426
3673
  );