@onexapis/cli 1.0.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,11 +1,15 @@
1
1
  'use strict';
2
2
 
3
+ var chalk4 = require('chalk');
4
+ var ora = require('ora');
5
+ var esbuild = require('esbuild');
3
6
  var path = require('path');
7
+ var fs6 = require('fs/promises');
8
+ var crypto = require('crypto');
9
+ var glob = require('glob');
4
10
  var fs2 = require('fs');
5
11
  var child_process = require('child_process');
6
12
  var inquirer = require('inquirer');
7
- var chalk4 = require('chalk');
8
- var ora = require('ora');
9
13
  var fs = require('fs-extra');
10
14
  var ejs = require('ejs');
11
15
  var clientS3 = require('@aws-sdk/client-s3');
@@ -15,17 +19,40 @@ var AdmZip = require('adm-zip');
15
19
 
16
20
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
17
21
 
22
+ function _interopNamespace(e) {
23
+ if (e && e.__esModule) return e;
24
+ var n = Object.create(null);
25
+ if (e) {
26
+ Object.keys(e).forEach(function (k) {
27
+ if (k !== 'default') {
28
+ var d = Object.getOwnPropertyDescriptor(e, k);
29
+ Object.defineProperty(n, k, d.get ? d : {
30
+ enumerable: true,
31
+ get: function () { return e[k]; }
32
+ });
33
+ }
34
+ });
35
+ }
36
+ n.default = e;
37
+ return Object.freeze(n);
38
+ }
39
+
40
+ var chalk4__default = /*#__PURE__*/_interopDefault(chalk4);
41
+ var ora__default = /*#__PURE__*/_interopDefault(ora);
42
+ var esbuild__namespace = /*#__PURE__*/_interopNamespace(esbuild);
18
43
  var path__default = /*#__PURE__*/_interopDefault(path);
44
+ var fs6__default = /*#__PURE__*/_interopDefault(fs6);
45
+ var crypto__default = /*#__PURE__*/_interopDefault(crypto);
19
46
  var fs2__default = /*#__PURE__*/_interopDefault(fs2);
20
47
  var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
21
- var chalk4__default = /*#__PURE__*/_interopDefault(chalk4);
22
- var ora__default = /*#__PURE__*/_interopDefault(ora);
23
48
  var fs__default = /*#__PURE__*/_interopDefault(fs);
24
49
  var ejs__default = /*#__PURE__*/_interopDefault(ejs);
25
50
  var os__default = /*#__PURE__*/_interopDefault(os);
26
51
  var archiver__default = /*#__PURE__*/_interopDefault(archiver);
27
52
  var AdmZip__default = /*#__PURE__*/_interopDefault(AdmZip);
28
53
 
54
+ var __defProp = Object.defineProperty;
55
+ var __getOwnPropNames = Object.getOwnPropertyNames;
29
56
  var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : /* @__PURE__ */ Symbol.for("Symbol." + name);
30
57
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
31
58
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
@@ -33,58 +60,644 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
33
60
  if (typeof require !== "undefined") return require.apply(this, arguments);
34
61
  throw Error('Dynamic require of "' + x + '" is not supported');
35
62
  });
63
+ var __esm = (fn, res) => function __init() {
64
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
65
+ };
66
+ var __export = (target, all) => {
67
+ for (var name in all)
68
+ __defProp(target, name, { get: all[name], enumerable: true });
69
+ };
36
70
  var __forAwait = (obj, it, method) => (it = obj[__knownSymbol("asyncIterator")]) ? it.call(obj) : (obj = obj[__knownSymbol("iterator")](), it = {}, method = (key, fn) => (fn = obj[key]) && (it[key] = (arg) => new Promise((yes, no, done) => (arg = fn.call(obj, arg), done = arg.done, Promise.resolve(arg.value).then((value) => yes({ value, done }), no)))), method("next"), method("return"), it);
37
- var Logger = class {
38
- constructor() {
39
- this.spinner = null;
40
- }
41
- success(message) {
42
- console.log(chalk4__default.default.green("\u2713"), message);
43
- }
44
- error(message) {
45
- console.log(chalk4__default.default.red("\u2717"), message);
71
+ exports.Logger = void 0; exports.logger = void 0;
72
+ var init_logger = __esm({
73
+ "src/utils/logger.ts"() {
74
+ exports.Logger = class {
75
+ constructor() {
76
+ this.spinner = null;
77
+ }
78
+ success(message) {
79
+ console.log(chalk4__default.default.green("\u2713"), message);
80
+ }
81
+ error(message) {
82
+ console.log(chalk4__default.default.red("\u2717"), message);
83
+ }
84
+ warning(message) {
85
+ console.log(chalk4__default.default.yellow("\u26A0"), message);
86
+ }
87
+ info(message) {
88
+ console.log(chalk4__default.default.blue("\u2139"), message);
89
+ }
90
+ log(message) {
91
+ console.log(message);
92
+ }
93
+ startSpinner(message) {
94
+ this.spinner = ora__default.default(message).start();
95
+ }
96
+ stopSpinner(success = true, message) {
97
+ if (!this.spinner) return;
98
+ if (success) {
99
+ this.spinner.succeed(message);
100
+ } else {
101
+ this.spinner.fail(message);
102
+ }
103
+ this.spinner = null;
104
+ }
105
+ updateSpinner(message) {
106
+ if (this.spinner) {
107
+ this.spinner.text = message;
108
+ }
109
+ }
110
+ newLine() {
111
+ console.log();
112
+ }
113
+ header(message) {
114
+ console.log();
115
+ console.log(chalk4__default.default.bold.cyan(message));
116
+ console.log(chalk4__default.default.cyan("=".repeat(message.length)));
117
+ console.log();
118
+ }
119
+ section(message) {
120
+ console.log();
121
+ console.log(chalk4__default.default.bold(message));
122
+ }
123
+ };
124
+ exports.logger = new exports.Logger();
46
125
  }
47
- warning(message) {
48
- console.log(chalk4__default.default.yellow("\u26A0"), message);
126
+ });
127
+
128
+ // src/utils/compile-theme.ts
129
+ var compile_theme_exports = {};
130
+ __export(compile_theme_exports, {
131
+ compilePreviewRuntime: () => compilePreviewRuntime,
132
+ compileStandaloneTheme: () => compileStandaloneTheme,
133
+ compileStandaloneThemeDev: () => compileStandaloneThemeDev,
134
+ generateManifest: () => generateManifest2
135
+ });
136
+ async function resolveNodeModulesFile(startDir, relativePath) {
137
+ let dir = startDir;
138
+ while (true) {
139
+ const candidate = path__default.default.join(dir, "node_modules", relativePath);
140
+ try {
141
+ await fs6__default.default.access(candidate);
142
+ return candidate;
143
+ } catch (e) {
144
+ const parent = path__default.default.dirname(dir);
145
+ if (parent === dir) break;
146
+ dir = parent;
147
+ }
49
148
  }
50
- info(message) {
51
- console.log(chalk4__default.default.blue("\u2139"), message);
149
+ return null;
150
+ }
151
+ function createCoreGlobalPlugin(themePath) {
152
+ const exportsBySubpath = {};
153
+ return {
154
+ name: "core-global",
155
+ setup(build2) {
156
+ build2.onResolve({ filter: /^@onexapis\/core(\/.*)?$/ }, (args) => ({
157
+ path: args.path,
158
+ namespace: "core-global"
159
+ }));
160
+ build2.onLoad({ filter: /.*/, namespace: "core-global" }, async (args) => {
161
+ const match = args.path.match(/^@onexapis\/core(\/(.+))?$/);
162
+ const subpath = (match == null ? void 0 : match[2]) || "";
163
+ const moduleAccess = subpath ? `['${subpath}']` : "";
164
+ let namedExports = [];
165
+ const cacheKey = subpath || "__root__";
166
+ if (exportsBySubpath[cacheKey]) {
167
+ namedExports = exportsBySubpath[cacheKey];
168
+ } else {
169
+ const distFileName = subpath ? `${subpath}.mjs` : "index.mjs";
170
+ const distPath = await resolveNodeModulesFile(
171
+ themePath,
172
+ path__default.default.join("@onexapis", "core", "dist", distFileName)
173
+ );
174
+ try {
175
+ if (!distPath) throw new Error("not found");
176
+ const distContent = await fs6__default.default.readFile(distPath, "utf-8");
177
+ const exportMatches = distContent.matchAll(/export\s*\{([^}]+)\}/g);
178
+ for (const m of exportMatches) {
179
+ const names = m[1].split(",").map((n) => {
180
+ const parts = n.trim().split(/\s+as\s+/);
181
+ return (parts[1] || parts[0]).trim();
182
+ }).filter((n) => n.length > 0);
183
+ namedExports.push(...names);
184
+ }
185
+ namedExports = [...new Set(namedExports)];
186
+ } catch (e) {
187
+ }
188
+ exportsBySubpath[cacheKey] = namedExports;
189
+ }
190
+ const namedExportLines = namedExports.length > 0 ? `
191
+ export const {
192
+ ${namedExports.join(",\n ")}
193
+ } = _module;
194
+ ` : "";
195
+ return {
196
+ contents: `
197
+ if (!globalThis.__ONEX_CORE__) {
198
+ throw new Error('[Theme Bundle] @onexapis/core not initialized. Ensure globalThis.__ONEX_CORE__ is set before loading theme.');
199
+ }
200
+
201
+ const _module = globalThis.__ONEX_CORE__${moduleAccess};
202
+ if (!_module) {
203
+ const subpath = ${subpath ? `'${subpath}'` : "null"};
204
+ const modulePath = subpath ? '/' + subpath : '';
205
+ const moduleKey = subpath ? '["' + subpath + '"]' : '';
206
+ throw new Error('[Theme Bundle] @onexapis/core' + modulePath + ' not available in globalThis.__ONEX_CORE__' + moduleKey);
207
+ }
208
+
209
+ export default _module;
210
+ ${namedExportLines}
211
+ `.trim(),
212
+ loader: "js"
213
+ };
214
+ });
215
+ }
216
+ };
217
+ }
218
+ async function contentHashEntry(outputDir) {
219
+ const entryPath = path__default.default.join(outputDir, "bundle-entry.js");
220
+ const mapPath = path__default.default.join(outputDir, "bundle-entry.js.map");
221
+ const oldFiles = await glob.glob("bundle-entry-*.js*", { cwd: outputDir });
222
+ for (const f of oldFiles) {
223
+ await fs6__default.default.unlink(path__default.default.join(outputDir, f));
52
224
  }
53
- log(message) {
54
- console.log(message);
225
+ let entryContent;
226
+ try {
227
+ entryContent = await fs6__default.default.readFile(entryPath, "utf-8");
228
+ } catch (e) {
229
+ const indexPath = path__default.default.join(outputDir, "index.js");
230
+ try {
231
+ entryContent = await fs6__default.default.readFile(indexPath, "utf-8");
232
+ } catch (e2) {
233
+ exports.logger.warning("No entry file found in output, skipping content hash");
234
+ return;
235
+ }
236
+ const hash2 = crypto__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
237
+ const hashedName2 = `bundle-entry-${hash2}.js`;
238
+ const indexMapPath = path__default.default.join(outputDir, "index.js.map");
239
+ const hashedMapName2 = `bundle-entry-${hash2}.js.map`;
240
+ entryContent = entryContent.replace(
241
+ /\/\/# sourceMappingURL=index\.js\.map/,
242
+ `//# sourceMappingURL=${hashedMapName2}`
243
+ );
244
+ await fs6__default.default.writeFile(path__default.default.join(outputDir, hashedName2), entryContent);
245
+ await fs6__default.default.unlink(indexPath);
246
+ try {
247
+ await fs6__default.default.access(indexMapPath);
248
+ await fs6__default.default.rename(indexMapPath, path__default.default.join(outputDir, hashedMapName2));
249
+ } catch (e2) {
250
+ }
251
+ exports.logger.info(`Entry hashed: ${hashedName2}`);
252
+ return;
55
253
  }
56
- startSpinner(message) {
57
- this.spinner = ora__default.default(message).start();
254
+ const hash = crypto__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
255
+ const hashedName = `bundle-entry-${hash}.js`;
256
+ const hashedMapName = `bundle-entry-${hash}.js.map`;
257
+ entryContent = entryContent.replace(
258
+ /\/\/# sourceMappingURL=bundle-entry\.js\.map/,
259
+ `//# sourceMappingURL=${hashedMapName}`
260
+ );
261
+ await fs6__default.default.writeFile(path__default.default.join(outputDir, hashedName), entryContent);
262
+ await fs6__default.default.unlink(entryPath);
263
+ try {
264
+ await fs6__default.default.access(mapPath);
265
+ await fs6__default.default.rename(mapPath, path__default.default.join(outputDir, hashedMapName));
266
+ } catch (e) {
58
267
  }
59
- stopSpinner(success = true, message) {
60
- if (!this.spinner) return;
61
- if (success) {
62
- this.spinner.succeed(message);
63
- } else {
64
- this.spinner.fail(message);
268
+ exports.logger.info(`Entry hashed: ${hashedName}`);
269
+ }
270
+ async function generateManifest2(themeName, themePath, outputDir) {
271
+ let version = "1.0.0";
272
+ let themeId = themeName;
273
+ try {
274
+ const pkgContent = await fs6__default.default.readFile(
275
+ path__default.default.join(themePath, "package.json"),
276
+ "utf-8"
277
+ );
278
+ const pkg = JSON.parse(pkgContent);
279
+ version = pkg.version || version;
280
+ if (pkg.name) {
281
+ themeId = pkg.name.replace(/^@onex-themes\//, "");
65
282
  }
66
- this.spinner = null;
283
+ } catch (e) {
67
284
  }
68
- updateSpinner(message) {
69
- if (this.spinner) {
70
- this.spinner.text = message;
285
+ const [sectionFiles, blockFiles, schemaFiles] = await Promise.all([
286
+ glob.glob("sections/**/index.ts", { cwd: themePath }),
287
+ glob.glob("blocks/**/index.ts", { cwd: themePath }),
288
+ glob.glob("**/*.schema.ts", { cwd: themePath })
289
+ ]);
290
+ let hasThemeConfig = false;
291
+ try {
292
+ await fs6__default.default.access(path__default.default.join(themePath, "theme.config.ts"));
293
+ hasThemeConfig = true;
294
+ } catch (e) {
295
+ }
296
+ const allFiles = await glob.glob("**/*", { cwd: outputDir, nodir: true });
297
+ const jsFiles = allFiles.filter((f) => f.endsWith(".js"));
298
+ const cssFiles = allFiles.filter((f) => f.endsWith(".css"));
299
+ const entryFile = jsFiles.find((f) => f.includes("bundle-entry")) || "bundle-entry.js";
300
+ const manifest = {
301
+ themeId,
302
+ version,
303
+ name: themeId.charAt(0).toUpperCase() + themeId.slice(1),
304
+ compiledAt: (/* @__PURE__ */ new Date()).toISOString(),
305
+ format: "esm",
306
+ platform: "browser",
307
+ target: "es2020",
308
+ counts: {
309
+ sections: sectionFiles.length,
310
+ blocks: blockFiles.length,
311
+ schemas: schemaFiles.length
312
+ },
313
+ output: {
314
+ entry: entryFile,
315
+ chunks: jsFiles.filter((f) => f !== entryFile && !f.endsWith(".map")),
316
+ assets: allFiles.filter(
317
+ (f) => [".png", ".jpg", ".jpeg", ".svg", ".gif", ".webp"].some(
318
+ (ext) => f.endsWith(ext)
319
+ )
320
+ ),
321
+ stylesheets: cssFiles
322
+ },
323
+ external: ["react", "react-dom", "@onexapis/core"],
324
+ source: {
325
+ sections: sectionFiles,
326
+ blocks: blockFiles,
327
+ schemas: schemaFiles,
328
+ hasThemeConfig
329
+ }
330
+ };
331
+ await fs6__default.default.writeFile(
332
+ path__default.default.join(outputDir, "manifest.json"),
333
+ JSON.stringify(manifest, null, 2)
334
+ );
335
+ }
336
+ async function compileStandaloneTheme(themePath, themeName) {
337
+ const outputDir = path__default.default.join(themePath, "dist");
338
+ const bundleEntry = path__default.default.join(themePath, "bundle-entry.ts");
339
+ const indexEntry = path__default.default.join(themePath, "index.ts");
340
+ let entryPoint = indexEntry;
341
+ try {
342
+ await fs6__default.default.access(bundleEntry);
343
+ entryPoint = bundleEntry;
344
+ } catch (e) {
345
+ }
346
+ const shimPath = path__default.default.join(outputDir, ".process-shim.js");
347
+ await fs6__default.default.mkdir(outputDir, { recursive: true });
348
+ await fs6__default.default.writeFile(shimPath, PROCESS_SHIM);
349
+ const buildOptions = {
350
+ entryPoints: [entryPoint],
351
+ bundle: true,
352
+ platform: "browser",
353
+ format: "esm",
354
+ outdir: outputDir,
355
+ splitting: false,
356
+ chunkNames: "[name]-[hash]",
357
+ banner: {
358
+ js: '"use client";'
359
+ },
360
+ plugins: [reactGlobalPlugin, createCoreGlobalPlugin(themePath)],
361
+ external: [],
362
+ alias: {
363
+ events: "events/",
364
+ buffer: "buffer/"
365
+ },
366
+ inject: [shimPath],
367
+ define: {
368
+ "process.env.NODE_ENV": JSON.stringify("production"),
369
+ global: "globalThis"
370
+ },
371
+ minify: true,
372
+ sourcemap: true,
373
+ logLevel: "warning",
374
+ target: "es2020",
375
+ jsx: "automatic",
376
+ jsxImportSource: "react",
377
+ loader: {
378
+ ".tsx": "tsx",
379
+ ".ts": "ts",
380
+ ".jpg": "file",
381
+ ".jpeg": "file",
382
+ ".png": "file",
383
+ ".gif": "file",
384
+ ".svg": "file",
385
+ ".webp": "file"
386
+ },
387
+ assetNames: "assets/[name]-[hash]",
388
+ publicPath: "./",
389
+ metafile: true
390
+ };
391
+ try {
392
+ const result = await esbuild__namespace.build(buildOptions);
393
+ try {
394
+ await fs6__default.default.unlink(shimPath);
395
+ } catch (e) {
396
+ }
397
+ await contentHashEntry(outputDir);
398
+ await generateManifest2(themeName, themePath, outputDir);
399
+ if (result.metafile) {
400
+ const outputs = result.metafile.outputs;
401
+ let totalSize = 0;
402
+ for (const output of Object.values(outputs)) {
403
+ totalSize += output.bytes;
404
+ }
405
+ const totalKB = (totalSize / 1024).toFixed(2);
406
+ exports.logger.info(`Bundle size: ${totalKB} KB`);
407
+ }
408
+ return true;
409
+ } catch (error) {
410
+ try {
411
+ await fs6__default.default.unlink(shimPath);
412
+ } catch (e) {
71
413
  }
414
+ exports.logger.error(`esbuild compilation failed: ${error}`);
415
+ return false;
72
416
  }
73
- newLine() {
74
- console.log();
417
+ }
418
+ async function compileStandaloneThemeDev(themePath, themeName) {
419
+ const outputDir = path__default.default.join(themePath, "dist");
420
+ const bundleEntry = path__default.default.join(themePath, "bundle-entry.ts");
421
+ const indexEntry = path__default.default.join(themePath, "index.ts");
422
+ let entryPoint = indexEntry;
423
+ try {
424
+ await fs6__default.default.access(bundleEntry);
425
+ entryPoint = bundleEntry;
426
+ } catch (e) {
427
+ }
428
+ const shimPath = path__default.default.join(outputDir, ".process-shim.js");
429
+ await fs6__default.default.mkdir(outputDir, { recursive: true });
430
+ await fs6__default.default.writeFile(shimPath, PROCESS_SHIM);
431
+ const buildOptions = {
432
+ entryPoints: [entryPoint],
433
+ bundle: true,
434
+ platform: "browser",
435
+ format: "esm",
436
+ outdir: outputDir,
437
+ splitting: false,
438
+ banner: {
439
+ js: '"use client";'
440
+ },
441
+ plugins: [reactGlobalPlugin, createCoreGlobalPlugin(themePath)],
442
+ external: [],
443
+ alias: {
444
+ events: "events/",
445
+ buffer: "buffer/"
446
+ },
447
+ inject: [shimPath],
448
+ define: {
449
+ "process.env.NODE_ENV": JSON.stringify("development"),
450
+ global: "globalThis"
451
+ },
452
+ minify: false,
453
+ sourcemap: true,
454
+ logLevel: "warning",
455
+ target: "es2020",
456
+ jsx: "automatic",
457
+ jsxImportSource: "react",
458
+ loader: {
459
+ ".tsx": "tsx",
460
+ ".ts": "ts",
461
+ ".jpg": "file",
462
+ ".jpeg": "file",
463
+ ".png": "file",
464
+ ".gif": "file",
465
+ ".svg": "file",
466
+ ".webp": "file"
467
+ },
468
+ assetNames: "assets/[name]-[hash]",
469
+ publicPath: "./",
470
+ metafile: true
471
+ };
472
+ const context2 = await esbuild__namespace.context(buildOptions);
473
+ await context2.rebuild();
474
+ await generateManifest2(themeName, themePath, outputDir);
475
+ return { context: context2, outputDir };
476
+ }
477
+ async function compilePreviewRuntime(themePath) {
478
+ const outputDir = path__default.default.join(themePath, "dist");
479
+ await fs6__default.default.mkdir(outputDir, { recursive: true });
480
+ const outputPath = path__default.default.join(outputDir, "preview-runtime.js");
481
+ const locations = [
482
+ path__default.default.join(__dirname, "..", "preview", "preview-app.tsx"),
483
+ path__default.default.join(__dirname, "preview", "preview-app.tsx"),
484
+ path__default.default.join(__dirname, "..", "..", "src", "preview", "preview-app.tsx")
485
+ ];
486
+ let previewEntryPath = null;
487
+ for (const loc of locations) {
488
+ try {
489
+ await fs6__default.default.access(loc);
490
+ previewEntryPath = loc;
491
+ break;
492
+ } catch (e) {
493
+ }
75
494
  }
76
- header(message) {
77
- console.log();
78
- console.log(chalk4__default.default.bold.cyan(message));
79
- console.log(chalk4__default.default.cyan("=".repeat(message.length)));
80
- console.log();
495
+ if (!previewEntryPath) {
496
+ throw new Error(
497
+ `Preview app source not found. Searched:
498
+ ${locations.join("\n")}`
499
+ );
81
500
  }
82
- section(message) {
83
- console.log();
84
- console.log(chalk4__default.default.bold(message));
501
+ const serverStubPlugin = {
502
+ name: "server-stub",
503
+ setup(build2) {
504
+ build2.onResolve({ filter: /^server-only$/ }, () => ({
505
+ path: "server-only",
506
+ namespace: "server-stub"
507
+ }));
508
+ build2.onLoad({ filter: /.*/, namespace: "server-stub" }, () => ({
509
+ contents: "// server-only stub for browser",
510
+ loader: "js"
511
+ }));
512
+ const nodeBuiltins = [
513
+ "fs",
514
+ "fs/promises",
515
+ "path",
516
+ "os",
517
+ "crypto",
518
+ "stream",
519
+ "url",
520
+ "http",
521
+ "https",
522
+ "net",
523
+ "tls",
524
+ "child_process",
525
+ "util",
526
+ "events",
527
+ "buffer",
528
+ "querystring",
529
+ "zlib"
530
+ ];
531
+ for (const mod of nodeBuiltins) {
532
+ build2.onResolve({ filter: new RegExp(`^${mod.replace("/", "\\/")}$`) }, () => ({
533
+ path: mod,
534
+ namespace: "node-stub"
535
+ }));
536
+ }
537
+ build2.onLoad({ filter: /.*/, namespace: "node-stub" }, (args) => {
538
+ const stubs = {
539
+ events: "export class EventEmitter { on(){return this} off(){return this} emit(){return false} addListener(){return this} removeListener(){return this} } export default { EventEmitter };",
540
+ path: "export function join(){return ''} export function resolve(){return ''} export function dirname(){return ''} export function basename(){return ''} export function extname(){return ''} export default {};",
541
+ fs: "export const promises = {}; export function readFileSync(){return ''} export function existsSync(){return false} export default {};"
542
+ };
543
+ return {
544
+ contents: stubs[args.path] || "export default {};",
545
+ loader: "js"
546
+ };
547
+ });
548
+ }
549
+ };
550
+ await esbuild__namespace.build({
551
+ entryPoints: [previewEntryPath],
552
+ bundle: true,
553
+ platform: "browser",
554
+ format: "esm",
555
+ outfile: outputPath,
556
+ // Bundle React + core INTO the output (NOT externalized)
557
+ external: [],
558
+ plugins: [serverStubPlugin],
559
+ minify: false,
560
+ sourcemap: true,
561
+ target: "es2020",
562
+ jsx: "automatic",
563
+ jsxImportSource: "react",
564
+ define: {
565
+ "process.env.NODE_ENV": JSON.stringify("development"),
566
+ global: "globalThis"
567
+ },
568
+ loader: { ".tsx": "tsx", ".ts": "ts" },
569
+ // Force CJS resolution to avoid sideEffects:false dropping ESM chunk imports
570
+ conditions: ["require", "default"],
571
+ mainFields: ["main"],
572
+ logOverride: {
573
+ "ignored-bare-import": "silent"
574
+ }
575
+ });
576
+ return outputPath;
577
+ }
578
+ var PROCESS_SHIM, reactGlobalPlugin;
579
+ var init_compile_theme = __esm({
580
+ "src/utils/compile-theme.ts"() {
581
+ init_logger();
582
+ PROCESS_SHIM = `
583
+ if (typeof process === "undefined") {
584
+ globalThis.process = {
585
+ env: {},
586
+ browser: true,
587
+ };
588
+ }
589
+ `;
590
+ reactGlobalPlugin = {
591
+ name: "react-global",
592
+ setup(build2) {
593
+ build2.onResolve({ filter: /^react$/ }, () => ({
594
+ path: "react-external",
595
+ namespace: "react-global"
596
+ }));
597
+ build2.onResolve({ filter: /^react-dom$/ }, () => ({
598
+ path: "react-dom-external",
599
+ namespace: "react-global"
600
+ }));
601
+ build2.onResolve({ filter: /^react\/jsx-runtime$/ }, () => ({
602
+ path: "react-jsx-runtime-external",
603
+ namespace: "react-global"
604
+ }));
605
+ build2.onLoad({ filter: /.*/, namespace: "react-global" }, (args) => {
606
+ if (args.path === "react-external") {
607
+ return {
608
+ contents: `
609
+ if (!globalThis.__ONEX_REACT__) {
610
+ throw new Error('[Theme Bundle] React not initialized. Ensure globalThis.__ONEX_REACT__ is set before loading theme.');
611
+ }
612
+
613
+ const React = globalThis.__ONEX_REACT__;
614
+ export default React;
615
+
616
+ export const {
617
+ useState,
618
+ useEffect,
619
+ useContext,
620
+ useReducer,
621
+ useCallback,
622
+ useMemo,
623
+ useRef,
624
+ useImperativeHandle,
625
+ useLayoutEffect,
626
+ useDebugValue,
627
+ useDeferredValue,
628
+ useTransition,
629
+ useId,
630
+ useSyncExternalStore,
631
+ useInsertionEffect,
632
+ createContext,
633
+ forwardRef,
634
+ lazy,
635
+ memo,
636
+ startTransition,
637
+ createElement,
638
+ cloneElement,
639
+ isValidElement,
640
+ Children,
641
+ Fragment,
642
+ Profiler,
643
+ StrictMode,
644
+ Suspense,
645
+ Component,
646
+ PureComponent,
647
+ useActionState,
648
+ use,
649
+ } = React;
650
+ `.trim(),
651
+ loader: "js"
652
+ };
653
+ }
654
+ if (args.path === "react-dom-external") {
655
+ return {
656
+ contents: `
657
+ if (!globalThis.__ONEX_REACT_DOM__) {
658
+ throw new Error('[Theme Bundle] ReactDOM not initialized. Ensure globalThis.__ONEX_REACT_DOM__ is set before loading theme.');
659
+ }
660
+
661
+ const ReactDOM = globalThis.__ONEX_REACT_DOM__;
662
+ export default ReactDOM;
663
+
664
+ export const {
665
+ createRoot,
666
+ hydrateRoot,
667
+ flushSync,
668
+ createPortal,
669
+ findDOMNode,
670
+ render,
671
+ hydrate,
672
+ unmountComponentAtNode,
673
+ } = ReactDOM;
674
+ `.trim(),
675
+ loader: "js"
676
+ };
677
+ }
678
+ if (args.path === "react-jsx-runtime-external") {
679
+ return {
680
+ contents: `
681
+ if (!globalThis.__ONEX_JSX_RUNTIME__) {
682
+ throw new Error('[Theme Bundle] React JSX runtime not initialized. Ensure globalThis.__ONEX_JSX_RUNTIME__ is set before loading theme.');
683
+ }
684
+ const _jsxRuntime = globalThis.__ONEX_JSX_RUNTIME__;
685
+ export const jsx = _jsxRuntime.jsx;
686
+ export const jsxs = _jsxRuntime.jsxs;
687
+ export const Fragment = _jsxRuntime.Fragment;
688
+ `.trim(),
689
+ loader: "js"
690
+ };
691
+ }
692
+ return null;
693
+ });
694
+ }
695
+ };
85
696
  }
86
- };
87
- var logger = new Logger();
697
+ });
698
+
699
+ // src/commands/init.ts
700
+ init_logger();
88
701
 
89
702
  // src/utils/validators.ts
90
703
  function validateName(name) {
@@ -104,8 +717,8 @@ function validateThemeName(name) {
104
717
  return /^[a-z][a-z0-9-]*$/.test(name);
105
718
  }
106
719
  function pathExists(filePath) {
107
- const fs8 = __require("fs-extra");
108
- return fs8.existsSync(filePath);
720
+ const fs11 = __require("fs-extra");
721
+ return fs11.existsSync(filePath);
109
722
  }
110
723
  function validateCategory(category) {
111
724
  const validCategories = [
@@ -138,6 +751,9 @@ function getValidCategories() {
138
751
  "contact"
139
752
  ];
140
753
  }
754
+
755
+ // src/utils/file-helpers.ts
756
+ init_logger();
141
757
  async function renderTemplate(templatePath, data) {
142
758
  const template = await fs__default.default.readFile(templatePath, "utf-8");
143
759
  return ejs__default.default.render(template, data);
@@ -223,22 +839,22 @@ function getProjectRoot() {
223
839
  }
224
840
  function getThemesDir() {
225
841
  const root = getProjectRoot();
226
- const themesDir = path__default.default.join(root, "themes");
227
- if (fs__default.default.existsSync(themesDir)) {
228
- return themesDir;
229
- }
230
- return path__default.default.join(root, "src/themes");
842
+ if (fs__default.default.existsSync(path__default.default.join(root, "themes")))
843
+ return path__default.default.join(root, "themes");
844
+ if (fs__default.default.existsSync(path__default.default.join(root, "src/themes")))
845
+ return path__default.default.join(root, "src/themes");
846
+ return path__default.default.dirname(root);
231
847
  }
232
848
  function getFeaturesDir() {
233
849
  return path__default.default.join(getProjectRoot(), "src/features");
234
850
  }
235
851
  function isOneXProject() {
236
852
  const root = getProjectRoot();
237
- return fs__default.default.existsSync(path__default.default.join(root, "themes")) || fs__default.default.existsSync(path__default.default.join(root, "src/themes"));
853
+ return fs__default.default.existsSync(path__default.default.join(root, "themes")) || fs__default.default.existsSync(path__default.default.join(root, "src/themes")) || fs__default.default.existsSync(path__default.default.join(root, "theme.config.ts")) || fs__default.default.existsSync(path__default.default.join(root, "bundle-entry.ts"));
238
854
  }
239
855
  function ensureOneXProject() {
240
856
  if (!isOneXProject()) {
241
- logger.error(
857
+ exports.logger.error(
242
858
  "Not in a OneX project. Please run this command from a OneX project root."
243
859
  );
244
860
  process.exit(1);
@@ -286,7 +902,7 @@ async function installDependencies(projectPath, packageManager = "npm") {
286
902
 
287
903
  // src/commands/init.ts
288
904
  async function initCommand(projectName, options = {}) {
289
- logger.header("Create New OneX Theme Project");
905
+ exports.logger.header("Create New OneX Theme Project");
290
906
  let name;
291
907
  if (!projectName) {
292
908
  const { inputName } = await inquirer__default.default.prompt([
@@ -313,7 +929,7 @@ async function initCommand(projectName, options = {}) {
313
929
  }
314
930
  const projectPath = path__default.default.join(process.cwd(), name);
315
931
  if (fs2__default.default.existsSync(projectPath)) {
316
- logger.error(`Directory "${name}" already exists.`);
932
+ exports.logger.error(`Directory "${name}" already exists.`);
317
933
  process.exit(1);
318
934
  }
319
935
  let displayName;
@@ -370,7 +986,7 @@ async function initCommand(projectName, options = {}) {
370
986
  author,
371
987
  template
372
988
  };
373
- logger.startSpinner("Creating project structure...");
989
+ exports.logger.startSpinner("Creating project structure...");
374
990
  try {
375
991
  fs2__default.default.mkdirSync(projectPath, { recursive: true });
376
992
  await copyTemplate(template, projectPath, data);
@@ -406,9 +1022,9 @@ Add your theme-specific blocks here.
406
1022
  fs2__default.default.mkdirSync(pagesPath, { recursive: true });
407
1023
  const homePageContent = generateHomePage(data);
408
1024
  await writeFile(path__default.default.join(pagesPath, "home.ts"), homePageContent);
409
- logger.stopSpinner(true, "Project structure created!");
1025
+ exports.logger.stopSpinner(true, "Project structure created!");
410
1026
  if (options.git) {
411
- logger.startSpinner("Initializing git repository...");
1027
+ exports.logger.startSpinner("Initializing git repository...");
412
1028
  try {
413
1029
  child_process.execSync("git init", { cwd: projectPath, stdio: "ignore" });
414
1030
  child_process.execSync("git add .", { cwd: projectPath, stdio: "ignore" });
@@ -416,52 +1032,52 @@ Add your theme-specific blocks here.
416
1032
  cwd: projectPath,
417
1033
  stdio: "ignore"
418
1034
  });
419
- logger.stopSpinner(true, "Git repository initialized!");
1035
+ exports.logger.stopSpinner(true, "Git repository initialized!");
420
1036
  } catch (e) {
421
- logger.stopSpinner(false, "Failed to initialize git");
1037
+ exports.logger.stopSpinner(false, "Failed to initialize git");
422
1038
  }
423
1039
  }
424
1040
  if (!options.noInstall) {
425
- logger.newLine();
1041
+ exports.logger.newLine();
426
1042
  const packageManager = detectPackageManager();
427
- logger.startSpinner(`Installing dependencies with ${packageManager}...`);
1043
+ exports.logger.startSpinner(`Installing dependencies with ${packageManager}...`);
428
1044
  try {
429
1045
  await installDependencies(projectPath, packageManager);
430
- logger.stopSpinner(true, "Dependencies installed!");
1046
+ exports.logger.stopSpinner(true, "Dependencies installed!");
431
1047
  } catch (e) {
432
- logger.stopSpinner(false, "Failed to install dependencies");
433
- logger.info(
1048
+ exports.logger.stopSpinner(false, "Failed to install dependencies");
1049
+ exports.logger.info(
434
1050
  "You can install dependencies manually by running: cd " + name + " && npm install"
435
1051
  );
436
1052
  }
437
1053
  }
438
- logger.newLine();
439
- logger.section("Success! \u{1F389}");
440
- logger.newLine();
441
- logger.info(`Created OneX theme project at: ${projectPath}`);
442
- logger.newLine();
443
- logger.section("Next steps:");
444
- logger.log(` cd ${name}`);
1054
+ exports.logger.newLine();
1055
+ exports.logger.section("Success! \u{1F389}");
1056
+ exports.logger.newLine();
1057
+ exports.logger.info(`Created OneX theme project at: ${projectPath}`);
1058
+ exports.logger.newLine();
1059
+ exports.logger.section("Next steps:");
1060
+ exports.logger.log(` cd ${name}`);
445
1061
  if (options.noInstall) {
446
- logger.log(` npm install`);
447
- }
448
- logger.log(` npm run build # Build your theme`);
449
- logger.log(` npm run dev # Start development mode`);
450
- logger.newLine();
451
- logger.section("Theme structure:");
452
- logger.log(" src/manifest.ts - Theme manifest and exports");
453
- logger.log(
1062
+ exports.logger.log(` npm install`);
1063
+ }
1064
+ exports.logger.log(` npm run build # Build your theme`);
1065
+ exports.logger.log(` npm run dev # Start development mode`);
1066
+ exports.logger.newLine();
1067
+ exports.logger.section("Theme structure:");
1068
+ exports.logger.log(" src/manifest.ts - Theme manifest and exports");
1069
+ exports.logger.log(
454
1070
  " src/config.ts - Design tokens (colors, typography, etc.)"
455
1071
  );
456
- logger.log(" src/layout.ts - Header and footer configuration");
457
- logger.log(" src/sections/ - Custom sections for your theme");
458
- logger.log(" src/blocks/ - Reusable blocks");
459
- logger.log(" src/pages/ - Page configurations");
460
- logger.newLine();
461
- logger.success(`Happy theming! \u{1F3A8}`);
1072
+ exports.logger.log(" src/layout.ts - Header and footer configuration");
1073
+ exports.logger.log(" src/sections/ - Custom sections for your theme");
1074
+ exports.logger.log(" src/blocks/ - Reusable blocks");
1075
+ exports.logger.log(" src/pages/ - Page configurations");
1076
+ exports.logger.newLine();
1077
+ exports.logger.success(`Happy theming! \u{1F3A8}`);
462
1078
  } catch (error) {
463
- logger.stopSpinner(false, "Failed to create project");
464
- logger.error(
1079
+ exports.logger.stopSpinner(false, "Failed to create project");
1080
+ exports.logger.error(
465
1081
  error instanceof Error ? error.message : "Unknown error occurred"
466
1082
  );
467
1083
  if (fs2__default.default.existsSync(projectPath)) {
@@ -696,12 +1312,23 @@ export const homePageConfig: PageConfig = {
696
1312
  };
697
1313
  `;
698
1314
  }
1315
+
1316
+ // src/commands/create-section.ts
1317
+ init_logger();
699
1318
  async function createSectionCommand(name, options) {
700
- logger.header("Create New Section");
1319
+ exports.logger.header("Create New Section");
701
1320
  ensureOneXProject();
1321
+ if (!options.theme) {
1322
+ const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
1323
+ (f) => fs__default.default.existsSync(path__default.default.join(process.cwd(), f))
1324
+ );
1325
+ if (isStandaloneTheme) {
1326
+ options.theme = path__default.default.basename(process.cwd());
1327
+ }
1328
+ }
702
1329
  const sectionName = toKebabCase(name);
703
1330
  if (!validateName(sectionName)) {
704
- logger.error(
1331
+ exports.logger.error(
705
1332
  `Invalid section name: ${sectionName}. Use kebab-case (e.g., hero, featured-products)`
706
1333
  );
707
1334
  process.exit(1);
@@ -746,7 +1373,7 @@ async function createSectionCommand(name, options) {
746
1373
  const description = answers.description;
747
1374
  const createTemplate = answers.createTemplate;
748
1375
  if (!themeExists(themeName)) {
749
- logger.error(`Theme "${themeName}" does not exist.`);
1376
+ exports.logger.error(`Theme "${themeName}" does not exist.`);
750
1377
  process.exit(1);
751
1378
  }
752
1379
  const data = {
@@ -757,7 +1384,7 @@ async function createSectionCommand(name, options) {
757
1384
  displayName,
758
1385
  description
759
1386
  };
760
- logger.startSpinner("Creating section files...");
1387
+ exports.logger.startSpinner("Creating section files...");
761
1388
  try {
762
1389
  const themePath = path__default.default.join(getThemesDir(), themeName);
763
1390
  const sectionPath = path__default.default.join(themePath, "sections", sectionName);
@@ -775,25 +1402,25 @@ async function createSectionCommand(name, options) {
775
1402
  }
776
1403
  const indexContent = generateSectionIndex(data, createTemplate);
777
1404
  await writeFile(path__default.default.join(sectionPath, "index.ts"), indexContent);
778
- logger.stopSpinner(true, "Section files created successfully!");
779
- logger.newLine();
780
- logger.section("Next steps:");
781
- logger.log(
1405
+ exports.logger.stopSpinner(true, "Section files created successfully!");
1406
+ exports.logger.newLine();
1407
+ exports.logger.section("Next steps:");
1408
+ exports.logger.log(
782
1409
  ` 1. Edit schema: ${path__default.default.relative(process.cwd(), path__default.default.join(sectionPath, `${sectionName}.schema.ts`))}`
783
1410
  );
784
1411
  if (createTemplate) {
785
- logger.log(
1412
+ exports.logger.log(
786
1413
  ` 2. Edit template: ${path__default.default.relative(process.cwd(), path__default.default.join(sectionPath, `${sectionName}-default.tsx`))}`
787
1414
  );
788
1415
  }
789
- logger.log(
1416
+ exports.logger.log(
790
1417
  ` 3. Add to theme manifest: ${path__default.default.relative(process.cwd(), path__default.default.join(themePath, "manifest.ts"))}`
791
1418
  );
792
- logger.newLine();
793
- logger.success("Section created successfully!");
1419
+ exports.logger.newLine();
1420
+ exports.logger.success("Section created successfully!");
794
1421
  } catch (error) {
795
- logger.stopSpinner(false, "Failed to create section");
796
- logger.error(
1422
+ exports.logger.stopSpinner(false, "Failed to create section");
1423
+ exports.logger.error(
797
1424
  error instanceof Error ? error.message : "Unknown error occurred"
798
1425
  );
799
1426
  process.exit(1);
@@ -927,12 +1554,23 @@ export { ${data.sectionName}Schema } from "./${data.sectionName}.schema";
927
1554
  ${hasTemplate ? `export { ${data.sectionNamePascal}Default } from "./${data.sectionName}-default";` : ""}
928
1555
  `;
929
1556
  }
1557
+
1558
+ // src/commands/create-block.ts
1559
+ init_logger();
930
1560
  async function createBlockCommand(name, options) {
931
- logger.header("Create New Block");
1561
+ exports.logger.header("Create New Block");
932
1562
  ensureOneXProject();
1563
+ if (!options.theme) {
1564
+ const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
1565
+ (f) => fs__default.default.existsSync(path__default.default.join(process.cwd(), f))
1566
+ );
1567
+ if (isStandaloneTheme) {
1568
+ options.theme = path__default.default.basename(process.cwd());
1569
+ }
1570
+ }
933
1571
  const blockName = toKebabCase(name);
934
1572
  if (!validateName(blockName)) {
935
- logger.error(
1573
+ exports.logger.error(
936
1574
  `Invalid block name: ${blockName}. Use kebab-case (e.g., product-card, testimonial-item)`
937
1575
  );
938
1576
  process.exit(1);
@@ -987,7 +1625,7 @@ async function createBlockCommand(name, options) {
987
1625
  const hasComponents = answers.hasComponents;
988
1626
  const hasNestedBlocks = answers.hasNestedBlocks;
989
1627
  if (scope === "theme" && !themeExists(themeName)) {
990
- logger.error(`Theme "${themeName}" does not exist.`);
1628
+ exports.logger.error(`Theme "${themeName}" does not exist.`);
991
1629
  process.exit(1);
992
1630
  }
993
1631
  const data = {
@@ -1000,7 +1638,7 @@ async function createBlockCommand(name, options) {
1000
1638
  scope,
1001
1639
  themeName
1002
1640
  };
1003
- logger.startSpinner("Creating block files...");
1641
+ exports.logger.startSpinner("Creating block files...");
1004
1642
  try {
1005
1643
  const blockPath = scope === "shared" ? path__default.default.join(getFeaturesDir(), "blocks", blockName) : path__default.default.join(getThemesDir(), themeName, "blocks", blockName);
1006
1644
  const schemaContent = generateBlockSchema(data);
@@ -1012,23 +1650,23 @@ async function createBlockCommand(name, options) {
1012
1650
  await writeFile(path__default.default.join(blockPath, `${blockName}.tsx`), componentContent);
1013
1651
  const indexContent = generateBlockIndex(data);
1014
1652
  await writeFile(path__default.default.join(blockPath, "index.ts"), indexContent);
1015
- logger.stopSpinner(true, "Block files created successfully!");
1016
- logger.newLine();
1017
- logger.section("Next steps:");
1018
- logger.log(
1653
+ exports.logger.stopSpinner(true, "Block files created successfully!");
1654
+ exports.logger.newLine();
1655
+ exports.logger.section("Next steps:");
1656
+ exports.logger.log(
1019
1657
  ` 1. Edit schema: ${path__default.default.relative(process.cwd(), path__default.default.join(blockPath, `${blockName}.schema.ts`))}`
1020
1658
  );
1021
- logger.log(
1659
+ exports.logger.log(
1022
1660
  ` 2. Edit component: ${path__default.default.relative(process.cwd(), path__default.default.join(blockPath, `${blockName}.tsx`))}`
1023
1661
  );
1024
- logger.log(
1662
+ exports.logger.log(
1025
1663
  ` 3. Register in block registry: src/lib/registry/block-registry.ts`
1026
1664
  );
1027
- logger.newLine();
1028
- logger.success("Block created successfully!");
1665
+ exports.logger.newLine();
1666
+ exports.logger.success("Block created successfully!");
1029
1667
  } catch (error) {
1030
- logger.stopSpinner(false, "Failed to create block");
1031
- logger.error(
1668
+ exports.logger.stopSpinner(false, "Failed to create block");
1669
+ exports.logger.error(
1032
1670
  error instanceof Error ? error.message : "Unknown error occurred"
1033
1671
  );
1034
1672
  process.exit(1);
@@ -1143,12 +1781,15 @@ export { ${data.blockName}Definition } from "./${data.blockName}.schema";
1143
1781
  export { ${data.blockNamePascal} } from "./${data.blockName}";
1144
1782
  `;
1145
1783
  }
1784
+
1785
+ // src/commands/create-component.ts
1786
+ init_logger();
1146
1787
  async function createComponentCommand(name, options) {
1147
- logger.header("Create New Component");
1788
+ exports.logger.header("Create New Component");
1148
1789
  ensureOneXProject();
1149
1790
  const componentName = toKebabCase(name);
1150
1791
  if (!validateName(componentName)) {
1151
- logger.error(
1792
+ exports.logger.error(
1152
1793
  `Invalid component name: ${componentName}. Use kebab-case (e.g., button, icon-badge)`
1153
1794
  );
1154
1795
  process.exit(1);
@@ -1192,7 +1833,7 @@ async function createComponentCommand(name, options) {
1192
1833
  displayName,
1193
1834
  description
1194
1835
  };
1195
- logger.startSpinner("Creating component files...");
1836
+ exports.logger.startSpinner("Creating component files...");
1196
1837
  try {
1197
1838
  const componentPath = path__default.default.join(
1198
1839
  getFeaturesDir(),
@@ -1211,23 +1852,23 @@ async function createComponentCommand(name, options) {
1211
1852
  );
1212
1853
  const indexContent = generateComponentIndex(data);
1213
1854
  await writeFile(path__default.default.join(componentPath, "index.ts"), indexContent);
1214
- logger.stopSpinner(true, "Component files created successfully!");
1215
- logger.newLine();
1216
- logger.section("Next steps:");
1217
- logger.log(
1855
+ exports.logger.stopSpinner(true, "Component files created successfully!");
1856
+ exports.logger.newLine();
1857
+ exports.logger.section("Next steps:");
1858
+ exports.logger.log(
1218
1859
  ` 1. Edit schema: ${path__default.default.relative(process.cwd(), path__default.default.join(componentPath, `${componentName}.schema.ts`))}`
1219
1860
  );
1220
- logger.log(
1861
+ exports.logger.log(
1221
1862
  ` 2. Edit component: ${path__default.default.relative(process.cwd(), path__default.default.join(componentPath, `${componentName}.tsx`))}`
1222
1863
  );
1223
- logger.log(
1864
+ exports.logger.log(
1224
1865
  ` 3. Register in component registry: src/lib/registry/component-registry.ts`
1225
1866
  );
1226
- logger.newLine();
1227
- logger.success("Component created successfully!");
1867
+ exports.logger.newLine();
1868
+ exports.logger.success("Component created successfully!");
1228
1869
  } catch (error) {
1229
- logger.stopSpinner(false, "Failed to create component");
1230
- logger.error(
1870
+ exports.logger.stopSpinner(false, "Failed to create component");
1871
+ exports.logger.error(
1231
1872
  error instanceof Error ? error.message : "Unknown error occurred"
1232
1873
  );
1233
1874
  process.exit(1);
@@ -1347,8 +1988,11 @@ export { ${data.componentName}Definition } from "./${data.componentName}.schema"
1347
1988
  export { ${data.componentNamePascal} } from "./${data.componentName}";
1348
1989
  `;
1349
1990
  }
1991
+
1992
+ // src/commands/list.ts
1993
+ init_logger();
1350
1994
  async function listCommand(options) {
1351
- logger.header("OneX Project Inventory");
1995
+ exports.logger.header("OneX Project Inventory");
1352
1996
  ensureOneXProject();
1353
1997
  const showAll = !options.sections && !options.blocks && !options.components;
1354
1998
  if (showAll || options.sections) {
@@ -1365,10 +2009,10 @@ async function listCommand(options) {
1365
2009
  }
1366
2010
  }
1367
2011
  async function listSections(themeFilter) {
1368
- logger.section("\u{1F4C4} Sections");
2012
+ exports.logger.section("\u{1F4C4} Sections");
1369
2013
  const themes = themeFilter ? [themeFilter] : listThemes();
1370
2014
  if (themes.length === 0) {
1371
- logger.warning("No themes found");
2015
+ exports.logger.warning("No themes found");
1372
2016
  return;
1373
2017
  }
1374
2018
  for (const theme of themes) {
@@ -1381,17 +2025,17 @@ async function listSections(themeFilter) {
1381
2025
  return fs__default.default.statSync(sectionPath).isDirectory() && fs__default.default.existsSync(path__default.default.join(sectionPath, "index.ts"));
1382
2026
  });
1383
2027
  if (sections.length > 0) {
1384
- logger.log(chalk4__default.default.cyan(`
2028
+ exports.logger.log(chalk4__default.default.cyan(`
1385
2029
  ${theme}:`));
1386
2030
  sections.forEach((section) => {
1387
- logger.log(` \u2022 ${section}`);
2031
+ exports.logger.log(` \u2022 ${section}`);
1388
2032
  });
1389
2033
  }
1390
2034
  }
1391
- logger.newLine();
2035
+ exports.logger.newLine();
1392
2036
  }
1393
2037
  async function listBlocks(themeFilter) {
1394
- logger.section("\u{1F9F1} Blocks");
2038
+ exports.logger.section("\u{1F9F1} Blocks");
1395
2039
  const sharedBlocksDir = path__default.default.join(getFeaturesDir(), "blocks");
1396
2040
  if (fs__default.default.existsSync(sharedBlocksDir)) {
1397
2041
  const sharedBlocks = fs__default.default.readdirSync(sharedBlocksDir).filter((name) => {
@@ -1399,9 +2043,9 @@ async function listBlocks(themeFilter) {
1399
2043
  return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path__default.default.join(blockPath, "index.ts"));
1400
2044
  });
1401
2045
  if (sharedBlocks.length > 0) {
1402
- logger.log(chalk4__default.default.cyan("\n Shared:"));
2046
+ exports.logger.log(chalk4__default.default.cyan("\n Shared:"));
1403
2047
  sharedBlocks.forEach((block) => {
1404
- logger.log(` \u2022 ${block}`);
2048
+ exports.logger.log(` \u2022 ${block}`);
1405
2049
  });
1406
2050
  }
1407
2051
  }
@@ -1416,20 +2060,20 @@ async function listBlocks(themeFilter) {
1416
2060
  return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path__default.default.join(blockPath, "index.ts"));
1417
2061
  });
1418
2062
  if (blocks.length > 0) {
1419
- logger.log(chalk4__default.default.cyan(`
2063
+ exports.logger.log(chalk4__default.default.cyan(`
1420
2064
  ${theme}:`));
1421
2065
  blocks.forEach((block) => {
1422
- logger.log(` \u2022 ${block}`);
2066
+ exports.logger.log(` \u2022 ${block}`);
1423
2067
  });
1424
2068
  }
1425
2069
  }
1426
- logger.newLine();
2070
+ exports.logger.newLine();
1427
2071
  }
1428
2072
  async function listComponents() {
1429
- logger.section("\u2699\uFE0F Components");
2073
+ exports.logger.section("\u2699\uFE0F Components");
1430
2074
  const componentsDir = path__default.default.join(getFeaturesDir(), "components");
1431
2075
  if (!fs__default.default.existsSync(componentsDir)) {
1432
- logger.warning("No components directory found");
2076
+ exports.logger.warning("No components directory found");
1433
2077
  return;
1434
2078
  }
1435
2079
  const components = fs__default.default.readdirSync(componentsDir).filter((name) => {
@@ -1437,23 +2081,23 @@ async function listComponents() {
1437
2081
  return fs__default.default.statSync(componentPath).isDirectory() && fs__default.default.existsSync(path__default.default.join(componentPath, "index.ts"));
1438
2082
  });
1439
2083
  if (components.length === 0) {
1440
- logger.warning("No components found");
2084
+ exports.logger.warning("No components found");
1441
2085
  return;
1442
2086
  }
1443
- logger.log("");
2087
+ exports.logger.log("");
1444
2088
  components.forEach((component) => {
1445
- logger.log(` \u2022 ${component}`);
2089
+ exports.logger.log(` \u2022 ${component}`);
1446
2090
  });
1447
- logger.newLine();
2091
+ exports.logger.newLine();
1448
2092
  }
1449
2093
  async function listThemesInfo() {
1450
- logger.section("\u{1F3A8} Themes");
2094
+ exports.logger.section("\u{1F3A8} Themes");
1451
2095
  const themes = listThemes();
1452
2096
  if (themes.length === 0) {
1453
- logger.warning("No themes found");
2097
+ exports.logger.warning("No themes found");
1454
2098
  return;
1455
2099
  }
1456
- logger.log("");
2100
+ exports.logger.log("");
1457
2101
  for (const theme of themes) {
1458
2102
  const themeDir = path__default.default.join(getThemesDir(), theme);
1459
2103
  const candidates = ["theme.config.ts", "bundle-entry.ts", "manifest.ts"];
@@ -1471,15 +2115,19 @@ async function listThemesInfo() {
1471
2115
  const displayName = nameMatch ? nameMatch[1] : theme;
1472
2116
  const version = versionMatch ? versionMatch[1] : "unknown";
1473
2117
  const description = descMatch ? descMatch[1] : "";
1474
- logger.log(chalk4__default.default.cyan(` ${displayName}`) + chalk4__default.default.gray(` (v${version})`));
2118
+ exports.logger.log(chalk4__default.default.cyan(` ${displayName}`) + chalk4__default.default.gray(` (v${version})`));
1475
2119
  if (description) {
1476
- logger.log(chalk4__default.default.gray(` ${description}`));
2120
+ exports.logger.log(chalk4__default.default.gray(` ${description}`));
1477
2121
  }
1478
2122
  }
1479
- logger.newLine();
2123
+ exports.logger.newLine();
1480
2124
  }
2125
+
2126
+ // src/commands/build.ts
2127
+ init_logger();
1481
2128
  async function buildCommand(options) {
1482
- logger.header("Build Theme");
2129
+ var _a;
2130
+ exports.logger.header("Build Theme");
1483
2131
  let themePath;
1484
2132
  let themeName;
1485
2133
  if (options.theme) {
@@ -1495,17 +2143,21 @@ async function buildCommand(options) {
1495
2143
  themePath = path__default.default.join(process.cwd(), themeName);
1496
2144
  }
1497
2145
  if (!fs__default.default.existsSync(themePath)) {
1498
- logger.error(`Theme "${themeName}" not found.`);
2146
+ exports.logger.error(`Theme "${themeName}" not found.`);
1499
2147
  process.exit(1);
1500
2148
  }
1501
2149
  } else {
1502
- const manifestPath = path__default.default.join(process.cwd(), "manifest.ts");
1503
- if (fs__default.default.existsSync(manifestPath)) {
2150
+ const isThemeDir = [
2151
+ "theme.config.ts",
2152
+ "bundle-entry.ts",
2153
+ "manifest.ts"
2154
+ ].some((f) => fs__default.default.existsSync(path__default.default.join(process.cwd(), f)));
2155
+ if (isThemeDir) {
1504
2156
  themePath = process.cwd();
1505
2157
  themeName = path__default.default.basename(themePath);
1506
- logger.info(`Building current theme: ${themeName}`);
2158
+ exports.logger.info(`Building current theme: ${themeName}`);
1507
2159
  } else {
1508
- logger.error(
2160
+ exports.logger.error(
1509
2161
  "Not in a theme directory and no --theme specified. Run from theme root or use --theme flag."
1510
2162
  );
1511
2163
  process.exit(1);
@@ -1514,55 +2166,64 @@ async function buildCommand(options) {
1514
2166
  const packageJsonPath = path__default.default.join(themePath, "package.json");
1515
2167
  const hasPkgJson = fs__default.default.existsSync(packageJsonPath);
1516
2168
  if (!hasPkgJson) {
1517
- logger.warning(
2169
+ exports.logger.warning(
1518
2170
  "No package.json found in theme. Skipping build (themes in monorepo are built via turbo)."
1519
2171
  );
1520
- logger.newLine();
1521
- logger.info("To build all packages, run:");
1522
- logger.log(" pnpm turbo build");
1523
- logger.newLine();
1524
- logger.info("To build specific theme components:");
1525
- logger.log(" pnpm turbo build --filter=./src/themes/*");
2172
+ exports.logger.newLine();
2173
+ exports.logger.info("To build all packages, run:");
2174
+ exports.logger.log(" pnpm turbo build");
2175
+ exports.logger.newLine();
2176
+ exports.logger.info("To build specific theme components:");
2177
+ exports.logger.log(" pnpm turbo build --filter=./src/themes/*");
1526
2178
  return;
1527
2179
  }
1528
- logger.newLine();
1529
- logger.section("Build Steps");
1530
- logger.startSpinner("Running type check...");
2180
+ exports.logger.newLine();
2181
+ exports.logger.section("Build Steps");
2182
+ exports.logger.startSpinner("Running type check...");
1531
2183
  const typeCheckSuccess = await runCommand("pnpm", ["type-check"], themePath);
1532
2184
  if (!typeCheckSuccess) {
1533
- logger.stopSpinner(false, "Type check failed");
1534
- logger.error("Fix type errors before building.");
2185
+ exports.logger.stopSpinner(false, "Type check failed");
2186
+ exports.logger.error("Fix type errors before building.");
1535
2187
  process.exit(1);
1536
2188
  }
1537
- logger.stopSpinner(true, "Type check passed");
1538
- logger.startSpinner("Running linter...");
2189
+ exports.logger.stopSpinner(true, "Type check passed");
2190
+ exports.logger.startSpinner("Running linter...");
1539
2191
  const lintSuccess = await runCommand("pnpm", ["lint"], themePath);
1540
2192
  if (!lintSuccess) {
1541
- logger.stopSpinner(false, "Lint failed");
1542
- logger.error("Fix lint errors before building.");
2193
+ exports.logger.stopSpinner(false, "Lint failed");
2194
+ exports.logger.error("Fix lint errors before building.");
1543
2195
  process.exit(1);
1544
2196
  }
1545
- logger.stopSpinner(true, "Lint passed");
1546
- const buildArgs = options.watch ? ["build", "--watch"] : ["build"];
1547
- logger.startSpinner(
2197
+ exports.logger.stopSpinner(true, "Lint passed");
2198
+ const pkgJson = fs__default.default.readJsonSync(packageJsonPath);
2199
+ const buildScript = ((_a = pkgJson.scripts) == null ? void 0 : _a.build) || "";
2200
+ const isRecursive = buildScript.includes("onex build") || buildScript.includes("onex-cli build");
2201
+ exports.logger.startSpinner(
1548
2202
  options.watch ? "Building (watch mode)..." : "Building..."
1549
2203
  );
1550
- const buildSuccess = await runCommand("pnpm", buildArgs, themePath);
2204
+ let buildSuccess;
2205
+ if (isRecursive) {
2206
+ const { compileStandaloneTheme: compileStandaloneTheme2 } = await Promise.resolve().then(() => (init_compile_theme(), compile_theme_exports));
2207
+ buildSuccess = await compileStandaloneTheme2(themePath, themeName);
2208
+ } else {
2209
+ const buildArgs = options.watch ? ["build", "--watch"] : ["build"];
2210
+ buildSuccess = await runCommand("pnpm", buildArgs, themePath);
2211
+ }
1551
2212
  if (!buildSuccess && !options.watch) {
1552
- logger.stopSpinner(false, "Build failed");
2213
+ exports.logger.stopSpinner(false, "Build failed");
1553
2214
  process.exit(1);
1554
2215
  }
1555
2216
  if (!options.watch) {
1556
- logger.stopSpinner(true, "Build complete");
1557
- logger.newLine();
1558
- logger.success("\u2713 Theme built successfully!");
1559
- logger.newLine();
1560
- logger.info(`Theme: ${themeName}`);
2217
+ exports.logger.stopSpinner(true, "Build complete");
2218
+ exports.logger.newLine();
2219
+ exports.logger.success("\u2713 Theme built successfully!");
2220
+ exports.logger.newLine();
2221
+ exports.logger.info(`Theme: ${themeName}`);
1561
2222
  const distPath = path__default.default.join(themePath, "dist");
1562
2223
  if (fs__default.default.existsSync(distPath)) {
1563
- logger.log(`Output: ${path__default.default.relative(process.cwd(), distPath)}`);
2224
+ exports.logger.log(`Output: ${path__default.default.relative(process.cwd(), distPath)}`);
1564
2225
  const files = fs__default.default.readdirSync(distPath);
1565
- logger.log(`Files: ${files.length}`);
2226
+ exports.logger.log(`Files: ${files.length}`);
1566
2227
  }
1567
2228
  }
1568
2229
  }
@@ -1588,6 +2249,9 @@ function runCommand(command, args, cwd) {
1588
2249
  });
1589
2250
  });
1590
2251
  }
2252
+
2253
+ // src/commands/upload.ts
2254
+ init_logger();
1591
2255
  function getS3Client() {
1592
2256
  const adapterMode = (process.env.ADAPTER_MODE || "aws").trim().toLowerCase();
1593
2257
  if (adapterMode === "vps") {
@@ -1627,21 +2291,12 @@ function getBucketName(env) {
1627
2291
  return environment === "production" ? "onex-themes-prod" : "onex-themes-staging";
1628
2292
  }
1629
2293
  async function findCompiledThemeDir(themeId, version) {
1630
- const searchPaths = [
1631
- path__default.default.resolve(process.cwd(), "dist"),
1632
- path__default.default.resolve(
1633
- process.cwd(),
1634
- `../../apps/api-server/compiled-themes/${themeId}@${version}`
1635
- ),
1636
- path__default.default.resolve(
1637
- process.cwd(),
1638
- `../api-server/compiled-themes/${themeId}@${version}`
1639
- )
1640
- ];
2294
+ const searchPaths = [path__default.default.resolve(process.cwd(), "dist")];
1641
2295
  for (const dir of searchPaths) {
1642
2296
  if (await fs__default.default.pathExists(dir)) {
1643
- const manifestPath = path__default.default.join(dir, "manifest.json");
1644
- if (await fs__default.default.pathExists(manifestPath)) {
2297
+ const hasManifest = await fs__default.default.pathExists(path__default.default.join(dir, "manifest.json"));
2298
+ const hasThemeEntry = await fs__default.default.pathExists(path__default.default.join(dir, "bundle-entry.js")) || await fs__default.default.pathExists(path__default.default.join(dir, "theme.config.js")) || await fs__default.default.pathExists(path__default.default.join(dir, "index.js"));
2299
+ if (hasManifest || hasThemeEntry) {
1645
2300
  return dir;
1646
2301
  }
1647
2302
  }
@@ -1656,7 +2311,7 @@ async function readManifest() {
1656
2311
  const module = await import(manifestTsPath);
1657
2312
  return module.default || module;
1658
2313
  } catch (error) {
1659
- logger.warning("Failed to import manifest.ts, trying package.json");
2314
+ exports.logger.warning("Failed to import manifest.ts, trying package.json");
1660
2315
  }
1661
2316
  }
1662
2317
  const packageJsonPath = path__default.default.resolve(process.cwd(), "package.json");
@@ -1721,7 +2376,7 @@ async function updateLatestPointer(s3Client, bucket, themeId, version) {
1721
2376
  );
1722
2377
  }
1723
2378
  async function uploadCommand(options) {
1724
- logger.header("Upload Theme to S3");
2379
+ exports.logger.header("Upload Theme to S3");
1725
2380
  const spinner = ora__default.default("Preparing theme upload...").start();
1726
2381
  try {
1727
2382
  let themeId;
@@ -1744,13 +2399,8 @@ async function uploadCommand(options) {
1744
2399
  `Compiled theme not found for ${themeId}@${version}. Run 'onex build' first.`
1745
2400
  )
1746
2401
  );
1747
- logger.info(
1748
- chalk4__default.default.gray(
1749
- `Expected locations:
1750
- - ./dist/
1751
- - ../../apps/api-server/compiled-themes/${themeId}@${version}/`
1752
- )
1753
- );
2402
+ exports.logger.info(chalk4__default.default.gray(`Expected location:
2403
+ - ./dist/`));
1754
2404
  process.exit(1);
1755
2405
  }
1756
2406
  spinner.succeed(`Found compiled theme at: ${compiledDir}`);
@@ -1850,16 +2500,14 @@ async function uploadCommand(options) {
1850
2500
  await updateLatestPointer(s3Client, bucket, themeId, version);
1851
2501
  spinner.succeed("Updated latest.json pointer");
1852
2502
  console.log();
1853
- logger.success(chalk4__default.default.green.bold("Theme uploaded successfully!"));
2503
+ exports.logger.success(chalk4__default.default.green.bold("Theme uploaded successfully!"));
1854
2504
  console.log();
1855
2505
  console.log(
1856
2506
  chalk4__default.default.cyan(" Theme: ") + chalk4__default.default.white(`${themeId}@${version}`)
1857
2507
  );
1858
2508
  console.log(chalk4__default.default.cyan(" Bucket: ") + chalk4__default.default.white(bucket));
1859
2509
  console.log(
1860
- chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(
1861
- `bundle.zip${sourceUploaded ? " + source.zip" : ""}`
1862
- )
2510
+ chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(`bundle.zip${sourceUploaded ? " + source.zip" : ""}`)
1863
2511
  );
1864
2512
  console.log(
1865
2513
  chalk4__default.default.cyan(" Path: ") + chalk4__default.default.gray(`s3://${bucket}/themes/${themeId}/${version}/`)
@@ -1867,10 +2515,13 @@ async function uploadCommand(options) {
1867
2515
  console.log();
1868
2516
  } catch (error) {
1869
2517
  spinner.fail(chalk4__default.default.red(`Upload failed: ${error.message}`));
1870
- logger.error(error.stack || error.message);
2518
+ exports.logger.error(error.stack || error.message);
1871
2519
  process.exit(1);
1872
2520
  }
1873
2521
  }
2522
+
2523
+ // src/commands/download.ts
2524
+ init_logger();
1874
2525
  function getS3Client2() {
1875
2526
  const adapterMode = (process.env.ADAPTER_MODE || "aws").trim().toLowerCase();
1876
2527
  if (adapterMode === "vps") {
@@ -1989,7 +2640,7 @@ export * from './bundle-entry.js';
1989
2640
  }
1990
2641
  function showDownloadFailureHelp(themeId, bucket) {
1991
2642
  console.log();
1992
- logger.error(chalk4__default.default.red.bold("Theme download failed"));
2643
+ exports.logger.error(chalk4__default.default.red.bold("Theme download failed"));
1993
2644
  console.log();
1994
2645
  console.log(chalk4__default.default.yellow("Possible reasons:"));
1995
2646
  console.log(chalk4__default.default.gray(" 1. Theme not uploaded to S3 yet"));
@@ -2018,15 +2669,11 @@ function showDownloadFailureHelp(themeId, bucket) {
2018
2669
  );
2019
2670
  console.log();
2020
2671
  console.log(chalk4__default.default.white("4. Verify theme exists in S3:"));
2021
- console.log(
2022
- chalk4__default.default.gray(
2023
- ` aws s3 ls s3://${bucket}/themes/${themeId}/`
2024
- )
2025
- );
2672
+ console.log(chalk4__default.default.gray(` aws s3 ls s3://${bucket}/themes/${themeId}/`));
2026
2673
  console.log();
2027
2674
  }
2028
2675
  async function downloadCommand(options) {
2029
- logger.header("Download Theme from S3");
2676
+ exports.logger.header("Download Theme from S3");
2030
2677
  const spinner = ora__default.default("Initializing download...").start();
2031
2678
  try {
2032
2679
  const themeId = options.themeId || process.env.NEXT_PUBLIC_THEME_ID || process.env.THEME_ID;
@@ -2075,7 +2722,7 @@ async function downloadCommand(options) {
2075
2722
  const manifest = await fs__default.default.readJson(manifestPath);
2076
2723
  await createCompatibilityFiles(outputDir, manifest);
2077
2724
  console.log();
2078
- logger.success(chalk4__default.default.green.bold("Theme downloaded successfully!"));
2725
+ exports.logger.success(chalk4__default.default.green.bold("Theme downloaded successfully!"));
2079
2726
  console.log();
2080
2727
  console.log(
2081
2728
  chalk4__default.default.cyan(" Theme: ") + chalk4__default.default.white(`${themeId}@${resolvedVersion}`)
@@ -2091,13 +2738,16 @@ async function downloadCommand(options) {
2091
2738
  console.log();
2092
2739
  } catch (error) {
2093
2740
  spinner.fail(chalk4__default.default.red("Download failed"));
2094
- logger.error(error.message);
2741
+ exports.logger.error(error.message);
2095
2742
  const themeId = options.themeId || process.env.NEXT_PUBLIC_THEME_ID || "unknown";
2096
2743
  const bucket = options.bucket || getBucketName2(options.environment);
2097
2744
  showDownloadFailureHelp(themeId, bucket);
2098
2745
  process.exit(1);
2099
2746
  }
2100
2747
  }
2748
+
2749
+ // src/commands/clone.ts
2750
+ init_logger();
2101
2751
  function getS3Client3() {
2102
2752
  const adapterMode = (process.env.ADAPTER_MODE || "aws").trim().toLowerCase();
2103
2753
  if (adapterMode === "vps") {
@@ -2201,18 +2851,101 @@ function runInstall(cwd) {
2201
2851
  proc.on("error", () => resolve(false));
2202
2852
  });
2203
2853
  }
2854
+ async function promptThemeName(originalName) {
2855
+ const { default: inquirer5 } = await import('inquirer');
2856
+ const { themeName } = await inquirer5.prompt([
2857
+ {
2858
+ type: "input",
2859
+ name: "themeName",
2860
+ message: "New theme name (kebab-case):",
2861
+ default: `my-${originalName}`,
2862
+ validate: (input) => {
2863
+ if (!/^[a-z][a-z0-9-]*$/.test(input)) {
2864
+ return "Theme name must be kebab-case (lowercase letters, numbers, hyphens)";
2865
+ }
2866
+ if (input === originalName) {
2867
+ return `Name must differ from the original theme "${originalName}"`;
2868
+ }
2869
+ return true;
2870
+ }
2871
+ }
2872
+ ]);
2873
+ return themeName;
2874
+ }
2875
+ async function renameTheme(themeDir, oldName, newName) {
2876
+ const oldPrefix = `${oldName}-`;
2877
+ const newPrefix = `${newName}-`;
2878
+ const newDisplayName = newName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
2879
+ const pkgPath = path__default.default.join(themeDir, "package.json");
2880
+ if (await fs__default.default.pathExists(pkgPath)) {
2881
+ const pkg = await fs__default.default.readJson(pkgPath);
2882
+ pkg.name = `@onex-themes/${newName}`;
2883
+ if (pkg.description) {
2884
+ pkg.description = pkg.description.replace(
2885
+ new RegExp(oldName, "gi"),
2886
+ newDisplayName
2887
+ );
2888
+ }
2889
+ pkg.version = "1.0.0";
2890
+ await fs__default.default.writeJson(pkgPath, pkg, { spaces: 2 });
2891
+ }
2892
+ const configPath = path__default.default.join(themeDir, "theme.config.ts");
2893
+ if (await fs__default.default.pathExists(configPath)) {
2894
+ let content = await fs__default.default.readFile(configPath, "utf-8");
2895
+ content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
2896
+ content = content.replace(
2897
+ /name:\s*"[^"]*Theme"/,
2898
+ `name: "${newDisplayName} Theme"`
2899
+ );
2900
+ await fs__default.default.writeFile(configPath, content);
2901
+ }
2902
+ const layoutPath = path__default.default.join(themeDir, "theme.layout.ts");
2903
+ if (await fs__default.default.pathExists(layoutPath)) {
2904
+ let content = await fs__default.default.readFile(layoutPath, "utf-8");
2905
+ content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
2906
+ content = content.replace(
2907
+ /name:\s*"[^"]*Theme"/,
2908
+ `name: "${newDisplayName} Theme"`
2909
+ );
2910
+ await fs__default.default.writeFile(layoutPath, content);
2911
+ }
2912
+ const oldDisplayName = oldName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
2913
+ const tsFiles = await glob.glob("**/*.ts", { cwd: themeDir, nodir: true });
2914
+ for (const file of tsFiles) {
2915
+ const filePath = path__default.default.join(themeDir, file);
2916
+ let content = await fs__default.default.readFile(filePath, "utf-8");
2917
+ const original = content;
2918
+ content = content.replace(
2919
+ new RegExp(`"${oldPrefix}`, "g"),
2920
+ `"${newPrefix}`
2921
+ );
2922
+ content = content.replace(
2923
+ new RegExp(`themeId:\\s*"${oldName}"`, "g"),
2924
+ `themeId: "${newName}"`
2925
+ );
2926
+ content = content.replace(
2927
+ new RegExp(`${oldDisplayName} Theme`, "g"),
2928
+ `${newDisplayName} Theme`
2929
+ );
2930
+ if (content !== original) {
2931
+ await fs__default.default.writeFile(filePath, content);
2932
+ }
2933
+ }
2934
+ }
2204
2935
  async function cloneCommand(themeName, options) {
2205
- logger.header("Clone Theme Source");
2936
+ exports.logger.header("Clone Theme Source");
2937
+ let newName = options.name;
2938
+ if (!newName) {
2939
+ newName = await promptThemeName(themeName);
2940
+ }
2206
2941
  const spinner = ora__default.default("Initializing clone...").start();
2207
2942
  try {
2208
2943
  const bucket = options.bucket || getBucketName3(options.environment);
2209
- const outputDir = options.output || path__default.default.resolve(process.cwd(), themeName);
2944
+ const outputDir = options.output || path__default.default.resolve(process.cwd(), newName);
2210
2945
  const s3Client = getS3Client3();
2211
2946
  if (await fs__default.default.pathExists(outputDir)) {
2212
- spinner.fail(
2213
- chalk4__default.default.red(`Directory already exists: ${outputDir}`)
2214
- );
2215
- logger.info(
2947
+ spinner.fail(chalk4__default.default.red(`Directory already exists: ${outputDir}`));
2948
+ exports.logger.info(
2216
2949
  chalk4__default.default.gray(
2217
2950
  "Use -o to specify a different output directory, or remove the existing directory."
2218
2951
  )
@@ -2225,9 +2958,7 @@ async function cloneCommand(themeName, options) {
2225
2958
  version = await resolveLatestVersion2(s3Client, bucket, themeName);
2226
2959
  spinner.succeed(`Resolved latest version: ${chalk4__default.default.cyan(version)}`);
2227
2960
  }
2228
- spinner.start(
2229
- `Downloading source.zip for ${themeName}@${version}...`
2230
- );
2961
+ spinner.start(`Downloading source.zip for ${themeName}@${version}...`);
2231
2962
  const s3Key = `themes/${themeName}/${version}/source.zip`;
2232
2963
  let zipBuffer;
2233
2964
  try {
@@ -2245,9 +2976,7 @@ async function cloneCommand(themeName, options) {
2245
2976
  chalk4__default.default.yellow("The theme source may not have been uploaded yet.")
2246
2977
  );
2247
2978
  console.log(
2248
- chalk4__default.default.gray(
2249
- `Upload source with: onex upload --theme ${themeName}`
2250
- )
2979
+ chalk4__default.default.gray(`Upload source with: onex upload --theme ${themeName}`)
2251
2980
  );
2252
2981
  console.log();
2253
2982
  process.exit(1);
@@ -2260,6 +2989,13 @@ async function cloneCommand(themeName, options) {
2260
2989
  zip.extractAllTo(outputDir, true);
2261
2990
  const entries = zip.getEntries().filter((e) => !e.isDirectory);
2262
2991
  spinner.succeed(`Extracted ${entries.length} files`);
2992
+ spinner.start(
2993
+ `Renaming theme: ${chalk4__default.default.gray(themeName)} \u2192 ${chalk4__default.default.cyan(newName)}...`
2994
+ );
2995
+ await renameTheme(outputDir, themeName, newName);
2996
+ spinner.succeed(
2997
+ `Renamed theme: ${chalk4__default.default.gray(themeName)} \u2192 ${chalk4__default.default.cyan(newName)}`
2998
+ );
2263
2999
  if (options.install !== false) {
2264
3000
  const hasPkgJson = await fs__default.default.pathExists(
2265
3001
  path__default.default.join(outputDir, "package.json")
@@ -2279,18 +3015,17 @@ async function cloneCommand(themeName, options) {
2279
3015
  }
2280
3016
  }
2281
3017
  console.log();
2282
- logger.success(chalk4__default.default.green.bold("Theme cloned successfully!"));
3018
+ exports.logger.success(chalk4__default.default.green.bold("Theme cloned successfully!"));
2283
3019
  console.log();
2284
3020
  console.log(
2285
- chalk4__default.default.cyan(" Theme: ") + chalk4__default.default.white(`${themeName}@${version}`)
3021
+ chalk4__default.default.cyan(" Source: ") + chalk4__default.default.gray(`${themeName}@${version}`)
2286
3022
  );
3023
+ console.log(chalk4__default.default.cyan(" Theme: ") + chalk4__default.default.white(newName));
2287
3024
  console.log(chalk4__default.default.cyan(" Location: ") + chalk4__default.default.white(outputDir));
2288
3025
  console.log(chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(entries.length));
2289
3026
  console.log();
2290
3027
  console.log(chalk4__default.default.cyan("Next steps:"));
2291
- console.log(
2292
- chalk4__default.default.gray(` cd ${path__default.default.relative(process.cwd(), outputDir)}`)
2293
- );
3028
+ console.log(chalk4__default.default.gray(` cd ${path__default.default.relative(process.cwd(), outputDir)}`));
2294
3029
  if (options.install === false) {
2295
3030
  console.log(chalk4__default.default.gray(" pnpm install"));
2296
3031
  }
@@ -2298,12 +3033,14 @@ async function cloneCommand(themeName, options) {
2298
3033
  console.log();
2299
3034
  } catch (error) {
2300
3035
  spinner.fail(chalk4__default.default.red(`Clone failed: ${error.message}`));
2301
- logger.error(error.stack || error.message);
3036
+ exports.logger.error(error.stack || error.message);
2302
3037
  process.exit(1);
2303
3038
  }
2304
3039
  }
2305
3040
 
2306
- exports.Logger = Logger;
3041
+ // src/index.ts
3042
+ init_logger();
3043
+
2307
3044
  exports.buildCommand = buildCommand;
2308
3045
  exports.cloneCommand = cloneCommand;
2309
3046
  exports.copyTemplate = copyTemplate;
@@ -2322,7 +3059,6 @@ exports.installDependencies = installDependencies;
2322
3059
  exports.isOneXProject = isOneXProject;
2323
3060
  exports.listCommand = listCommand;
2324
3061
  exports.listThemes = listThemes;
2325
- exports.logger = logger;
2326
3062
  exports.pathExists = pathExists;
2327
3063
  exports.renderTemplate = renderTemplate;
2328
3064
  exports.themeExists = themeExists;