@onexapis/cli 1.1.37 → 1.1.38
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/cli.js +688 -454
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +681 -449
- package/dist/cli.mjs.map +1 -1
- package/dist/index.js +343 -256
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +339 -253
- package/dist/index.mjs.map +1 -1
- package/dist/preview/preview-app.tsx +5 -13
- package/package.json +8 -4
- package/templates/default/bundle-entry.ts +0 -5
- package/templates/default/index.ts +1 -21
- package/templates/default/sections-registry.ts +0 -28
- package/templates/default/theme.layout.ts +2 -53
- package/templates/default/AUTH_AND_PROFILE.md +0 -167
- package/templates/default/LAYOUT.md +0 -195
- package/templates/default/hooks/index.ts +0 -26
- package/templates/default/hooks/use-forgot-password-form.ts +0 -90
- package/templates/default/hooks/use-login-form.ts +0 -102
- package/templates/default/hooks/use-profile-form.ts +0 -255
- package/templates/default/hooks/use-register-form.ts +0 -154
- package/templates/default/hooks/use-verify-code-form.ts +0 -224
- package/templates/default/pages/forgot-password.ts +0 -41
- package/templates/default/pages/login.ts +0 -41
- package/templates/default/pages/profile.ts +0 -39
- package/templates/default/pages/register.ts +0 -41
- package/templates/default/pages/verify-code.ts +0 -41
- package/templates/default/sections/auth-forgot-password/auth-forgot-password-default.tsx +0 -192
- package/templates/default/sections/auth-forgot-password/auth-forgot-password.schema.ts +0 -150
- package/templates/default/sections/auth-forgot-password/index.ts +0 -14
- package/templates/default/sections/auth-login/auth-login-default.tsx +0 -238
- package/templates/default/sections/auth-login/auth-login.schema.ts +0 -171
- package/templates/default/sections/auth-login/index.ts +0 -14
- package/templates/default/sections/auth-register/auth-register-default.tsx +0 -327
- package/templates/default/sections/auth-register/auth-register.schema.ts +0 -188
- package/templates/default/sections/auth-register/index.ts +0 -14
- package/templates/default/sections/auth-verify-code/auth-verify-code-default.tsx +0 -209
- package/templates/default/sections/auth-verify-code/auth-verify-code.schema.ts +0 -150
- package/templates/default/sections/auth-verify-code/index.ts +0 -14
- package/templates/default/sections/footer/footer-default.tsx +0 -214
- package/templates/default/sections/footer/footer.schema.ts +0 -170
- package/templates/default/sections/footer/index.ts +0 -14
- package/templates/default/sections/header/header-default.tsx +0 -322
- package/templates/default/sections/header/header.schema.ts +0 -168
- package/templates/default/sections/header/index.ts +0 -14
- package/templates/default/sections/profile/index.ts +0 -14
- package/templates/default/sections/profile/profile-default.tsx +0 -522
- package/templates/default/sections/profile/profile.schema.ts +0 -228
package/dist/cli.js
CHANGED
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
var chalk4 = require('chalk');
|
|
5
5
|
var ora = require('ora');
|
|
6
6
|
var esbuild = require('esbuild');
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var
|
|
7
|
+
var path10 = require('path');
|
|
8
|
+
var fs9 = require('fs/promises');
|
|
9
|
+
var crypto = require('crypto');
|
|
10
10
|
var glob = require('glob');
|
|
11
11
|
var module$1 = require('module');
|
|
12
|
-
var
|
|
12
|
+
var os = require('os');
|
|
13
13
|
var dotenv = require('dotenv');
|
|
14
14
|
var fs = require('fs-extra');
|
|
15
15
|
var ejs = require('ejs');
|
|
16
|
-
var
|
|
16
|
+
var spawn2 = require('cross-spawn');
|
|
17
17
|
var commander = require('commander');
|
|
18
|
-
var
|
|
18
|
+
var fs4 = require('fs');
|
|
19
19
|
var inquirer = require('inquirer');
|
|
20
20
|
var archiver = require('archiver');
|
|
21
21
|
var FormData = require('form-data');
|
|
@@ -25,6 +25,7 @@ var AdmZip = require('adm-zip');
|
|
|
25
25
|
var chokidar = require('chokidar');
|
|
26
26
|
var http = require('http');
|
|
27
27
|
var ws = require('ws');
|
|
28
|
+
var semver = require('semver');
|
|
28
29
|
|
|
29
30
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
30
31
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -50,14 +51,15 @@ function _interopNamespace(e) {
|
|
|
50
51
|
var chalk4__default = /*#__PURE__*/_interopDefault(chalk4);
|
|
51
52
|
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
52
53
|
var esbuild__namespace = /*#__PURE__*/_interopNamespace(esbuild);
|
|
53
|
-
var
|
|
54
|
-
var
|
|
55
|
-
var
|
|
56
|
-
var
|
|
54
|
+
var path10__default = /*#__PURE__*/_interopDefault(path10);
|
|
55
|
+
var fs9__default = /*#__PURE__*/_interopDefault(fs9);
|
|
56
|
+
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
57
|
+
var os__default = /*#__PURE__*/_interopDefault(os);
|
|
57
58
|
var dotenv__default = /*#__PURE__*/_interopDefault(dotenv);
|
|
58
59
|
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
59
60
|
var ejs__default = /*#__PURE__*/_interopDefault(ejs);
|
|
60
|
-
var
|
|
61
|
+
var spawn2__default = /*#__PURE__*/_interopDefault(spawn2);
|
|
62
|
+
var fs4__default = /*#__PURE__*/_interopDefault(fs4);
|
|
61
63
|
var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
|
|
62
64
|
var archiver__default = /*#__PURE__*/_interopDefault(archiver);
|
|
63
65
|
var FormData__default = /*#__PURE__*/_interopDefault(FormData);
|
|
@@ -65,6 +67,7 @@ var fetch2__default = /*#__PURE__*/_interopDefault(fetch2);
|
|
|
65
67
|
var AdmZip__default = /*#__PURE__*/_interopDefault(AdmZip);
|
|
66
68
|
var chokidar__default = /*#__PURE__*/_interopDefault(chokidar);
|
|
67
69
|
var http__default = /*#__PURE__*/_interopDefault(http);
|
|
70
|
+
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
68
71
|
|
|
69
72
|
var __defProp = Object.defineProperty;
|
|
70
73
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -146,8 +149,8 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
146
149
|
const tailwindcss = (await import('tailwindcss')).default;
|
|
147
150
|
const tailwindConfig = {
|
|
148
151
|
content: [
|
|
149
|
-
|
|
150
|
-
|
|
152
|
+
path10__default.default.join(themePath, "sections/**/*.{ts,tsx}"),
|
|
153
|
+
path10__default.default.join(themePath, "components/**/*.{ts,tsx}")
|
|
151
154
|
],
|
|
152
155
|
theme: { extend: {} },
|
|
153
156
|
plugins: []
|
|
@@ -157,7 +160,7 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
157
160
|
inputCSS,
|
|
158
161
|
{ from: void 0 }
|
|
159
162
|
);
|
|
160
|
-
await
|
|
163
|
+
await fs9__default.default.writeFile(path10__default.default.join(outDir, "bundle.css"), result.css);
|
|
161
164
|
logger.info("Generated bundle.css");
|
|
162
165
|
} catch (err) {
|
|
163
166
|
logger.warning(
|
|
@@ -168,12 +171,12 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
168
171
|
async function resolveNodeModulesFile(startDir, relativePath) {
|
|
169
172
|
let dir = startDir;
|
|
170
173
|
while (true) {
|
|
171
|
-
const candidate =
|
|
174
|
+
const candidate = path10__default.default.join(dir, "node_modules", relativePath);
|
|
172
175
|
try {
|
|
173
|
-
await
|
|
176
|
+
await fs9__default.default.access(candidate);
|
|
174
177
|
return candidate;
|
|
175
178
|
} catch {
|
|
176
|
-
const parent =
|
|
179
|
+
const parent = path10__default.default.dirname(dir);
|
|
177
180
|
if (parent === dir) break;
|
|
178
181
|
dir = parent;
|
|
179
182
|
}
|
|
@@ -197,7 +200,7 @@ async function scanImportsFromPackage(sourceDir, packageName) {
|
|
|
197
200
|
});
|
|
198
201
|
for (const file of sourceFiles) {
|
|
199
202
|
try {
|
|
200
|
-
const content = await
|
|
203
|
+
const content = await fs9__default.default.readFile(path10__default.default.join(sourceDir, file), "utf-8");
|
|
201
204
|
for (const match of content.matchAll(namespaceImportRegex)) {
|
|
202
205
|
const subpath = match[1] ? match[1].slice(1) : "";
|
|
203
206
|
if (!result[subpath]) result[subpath] = /* @__PURE__ */ new Set();
|
|
@@ -251,17 +254,17 @@ function createCoreGlobalPlugin(themePath) {
|
|
|
251
254
|
const distFileName = subpath ? `${subpath}.mjs` : "index.mjs";
|
|
252
255
|
let distPath = await resolveNodeModulesFile(
|
|
253
256
|
themePath,
|
|
254
|
-
|
|
257
|
+
path10__default.default.join("@onexapis", "core", "dist", distFileName)
|
|
255
258
|
);
|
|
256
259
|
if (!distPath) {
|
|
257
260
|
distPath = await resolveNodeModulesFile(
|
|
258
261
|
__dirname,
|
|
259
|
-
|
|
262
|
+
path10__default.default.join("@onexapis", "core", "dist", distFileName)
|
|
260
263
|
);
|
|
261
264
|
}
|
|
262
265
|
try {
|
|
263
266
|
if (!distPath) throw new Error("not found");
|
|
264
|
-
const distContent = await
|
|
267
|
+
const distContent = await fs9__default.default.readFile(distPath, "utf-8");
|
|
265
268
|
const exportMatches = distContent.matchAll(/export\s*\{([^}]+)\}/g);
|
|
266
269
|
for (const m of exportMatches) {
|
|
267
270
|
const names = m[1].split(",").map((n) => {
|
|
@@ -490,7 +493,7 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
490
493
|
const pages = {};
|
|
491
494
|
for (const ext of [".ts", ".js"]) {
|
|
492
495
|
try {
|
|
493
|
-
const mod = await jiti.import(
|
|
496
|
+
const mod = await jiti.import(path10__default.default.join(themePath, `theme.config${ext}`));
|
|
494
497
|
themeConfig = mod.default || mod;
|
|
495
498
|
break;
|
|
496
499
|
} catch {
|
|
@@ -498,20 +501,20 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
498
501
|
}
|
|
499
502
|
for (const ext of [".ts", ".js"]) {
|
|
500
503
|
try {
|
|
501
|
-
const mod = await jiti.import(
|
|
504
|
+
const mod = await jiti.import(path10__default.default.join(themePath, `theme.layout${ext}`));
|
|
502
505
|
layoutConfig = mod.default || mod;
|
|
503
506
|
break;
|
|
504
507
|
} catch {
|
|
505
508
|
}
|
|
506
509
|
}
|
|
507
510
|
const schemas = {};
|
|
508
|
-
const sectionsDir =
|
|
511
|
+
const sectionsDir = path10__default.default.join(themePath, "sections");
|
|
509
512
|
try {
|
|
510
|
-
const sectionDirs = await
|
|
513
|
+
const sectionDirs = await fs9__default.default.readdir(sectionsDir);
|
|
511
514
|
for (const dir of sectionDirs) {
|
|
512
|
-
const schemaFile =
|
|
515
|
+
const schemaFile = path10__default.default.join(sectionsDir, dir, `${dir}.schema.ts`);
|
|
513
516
|
try {
|
|
514
|
-
await
|
|
517
|
+
await fs9__default.default.access(schemaFile);
|
|
515
518
|
const mod = await jiti.import(schemaFile);
|
|
516
519
|
for (const [key, value] of Object.entries(mod)) {
|
|
517
520
|
if (key.endsWith("Schema") && value && typeof value === "object" && value.type) {
|
|
@@ -523,14 +526,14 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
523
526
|
}
|
|
524
527
|
} catch {
|
|
525
528
|
}
|
|
526
|
-
const pagesDir =
|
|
529
|
+
const pagesDir = path10__default.default.join(themePath, "pages");
|
|
527
530
|
try {
|
|
528
|
-
const files = await
|
|
531
|
+
const files = await fs9__default.default.readdir(pagesDir);
|
|
529
532
|
for (const file of files) {
|
|
530
533
|
if (!file.match(/\.(ts|js)$/)) continue;
|
|
531
534
|
const name = file.replace(/\.(ts|js)$/, "");
|
|
532
535
|
try {
|
|
533
|
-
const mod = await jiti.import(
|
|
536
|
+
const mod = await jiti.import(path10__default.default.join(pagesDir, file));
|
|
534
537
|
const config = mod.default || mod;
|
|
535
538
|
const sections = (config.sections || []).map((section) => {
|
|
536
539
|
const schema = schemas[section.type];
|
|
@@ -558,8 +561,8 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
558
561
|
}
|
|
559
562
|
} catch {
|
|
560
563
|
}
|
|
561
|
-
await
|
|
562
|
-
|
|
564
|
+
await fs9__default.default.writeFile(
|
|
565
|
+
path10__default.default.join(outputDir, "theme-data.json"),
|
|
563
566
|
JSON.stringify(
|
|
564
567
|
{
|
|
565
568
|
themeId,
|
|
@@ -582,53 +585,53 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
582
585
|
logger.info(`Generated theme-data.json (${Object.keys(pages).length} pages)`);
|
|
583
586
|
}
|
|
584
587
|
async function contentHashEntry(outputDir) {
|
|
585
|
-
const entryPath =
|
|
586
|
-
const mapPath =
|
|
588
|
+
const entryPath = path10__default.default.join(outputDir, "bundle-entry.js");
|
|
589
|
+
const mapPath = path10__default.default.join(outputDir, "bundle-entry.js.map");
|
|
587
590
|
const oldFiles = await glob.glob("bundle-entry-*.js*", { cwd: outputDir });
|
|
588
591
|
for (const f of oldFiles) {
|
|
589
|
-
await
|
|
592
|
+
await fs9__default.default.unlink(path10__default.default.join(outputDir, f));
|
|
590
593
|
}
|
|
591
594
|
let entryContent;
|
|
592
595
|
try {
|
|
593
|
-
entryContent = await
|
|
596
|
+
entryContent = await fs9__default.default.readFile(entryPath, "utf-8");
|
|
594
597
|
} catch {
|
|
595
|
-
const indexPath =
|
|
598
|
+
const indexPath = path10__default.default.join(outputDir, "index.js");
|
|
596
599
|
try {
|
|
597
|
-
entryContent = await
|
|
600
|
+
entryContent = await fs9__default.default.readFile(indexPath, "utf-8");
|
|
598
601
|
} catch {
|
|
599
602
|
logger.warning("No entry file found in output, skipping content hash");
|
|
600
603
|
return;
|
|
601
604
|
}
|
|
602
|
-
const hash2 =
|
|
605
|
+
const hash2 = crypto__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
|
|
603
606
|
const hashedName2 = `bundle-entry-${hash2}.js`;
|
|
604
|
-
const indexMapPath =
|
|
607
|
+
const indexMapPath = path10__default.default.join(outputDir, "index.js.map");
|
|
605
608
|
const hashedMapName2 = `bundle-entry-${hash2}.js.map`;
|
|
606
609
|
entryContent = entryContent.replace(
|
|
607
610
|
/\/\/# sourceMappingURL=index\.js\.map/,
|
|
608
611
|
`//# sourceMappingURL=${hashedMapName2}`
|
|
609
612
|
);
|
|
610
|
-
await
|
|
611
|
-
await
|
|
613
|
+
await fs9__default.default.writeFile(path10__default.default.join(outputDir, hashedName2), entryContent);
|
|
614
|
+
await fs9__default.default.unlink(indexPath);
|
|
612
615
|
try {
|
|
613
|
-
await
|
|
614
|
-
await
|
|
616
|
+
await fs9__default.default.access(indexMapPath);
|
|
617
|
+
await fs9__default.default.rename(indexMapPath, path10__default.default.join(outputDir, hashedMapName2));
|
|
615
618
|
} catch {
|
|
616
619
|
}
|
|
617
620
|
logger.info(`Entry hashed: ${hashedName2}`);
|
|
618
621
|
return;
|
|
619
622
|
}
|
|
620
|
-
const hash =
|
|
623
|
+
const hash = crypto__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
|
|
621
624
|
const hashedName = `bundle-entry-${hash}.js`;
|
|
622
625
|
const hashedMapName = `bundle-entry-${hash}.js.map`;
|
|
623
626
|
entryContent = entryContent.replace(
|
|
624
627
|
/\/\/# sourceMappingURL=bundle-entry\.js\.map/,
|
|
625
628
|
`//# sourceMappingURL=${hashedMapName}`
|
|
626
629
|
);
|
|
627
|
-
await
|
|
628
|
-
await
|
|
630
|
+
await fs9__default.default.writeFile(path10__default.default.join(outputDir, hashedName), entryContent);
|
|
631
|
+
await fs9__default.default.unlink(entryPath);
|
|
629
632
|
try {
|
|
630
|
-
await
|
|
631
|
-
await
|
|
633
|
+
await fs9__default.default.access(mapPath);
|
|
634
|
+
await fs9__default.default.rename(mapPath, path10__default.default.join(outputDir, hashedMapName));
|
|
632
635
|
} catch {
|
|
633
636
|
}
|
|
634
637
|
logger.info(`Entry hashed: ${hashedName}`);
|
|
@@ -640,7 +643,7 @@ async function extractDataRequirements(themePath) {
|
|
|
640
643
|
const requirements = {};
|
|
641
644
|
for (const file of schemaFiles) {
|
|
642
645
|
try {
|
|
643
|
-
const mod = await jiti.import(
|
|
646
|
+
const mod = await jiti.import(path10__default.default.join(themePath, file));
|
|
644
647
|
const exports$1 = mod;
|
|
645
648
|
for (const value of Object.values(exports$1)) {
|
|
646
649
|
if (value && typeof value === "object" && typeof value.type === "string" && value.dataRequirements && typeof value.dataRequirements === "object") {
|
|
@@ -659,8 +662,8 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
659
662
|
let version2 = "1.0.0";
|
|
660
663
|
let themeId = themeName;
|
|
661
664
|
try {
|
|
662
|
-
const pkgContent = await
|
|
663
|
-
|
|
665
|
+
const pkgContent = await fs9__default.default.readFile(
|
|
666
|
+
path10__default.default.join(themePath, "package.json"),
|
|
664
667
|
"utf-8"
|
|
665
668
|
);
|
|
666
669
|
const pkg = JSON.parse(pkgContent);
|
|
@@ -678,7 +681,7 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
678
681
|
const dataRequirements = await extractDataRequirements(themePath);
|
|
679
682
|
let hasThemeConfig = false;
|
|
680
683
|
try {
|
|
681
|
-
await
|
|
684
|
+
await fs9__default.default.access(path10__default.default.join(themePath, "theme.config.ts"));
|
|
682
685
|
hasThemeConfig = true;
|
|
683
686
|
} catch {
|
|
684
687
|
}
|
|
@@ -719,24 +722,24 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
719
722
|
// Section data requirements for server-side prefetching (keyed by section type)
|
|
720
723
|
dataRequirements
|
|
721
724
|
};
|
|
722
|
-
await
|
|
723
|
-
|
|
725
|
+
await fs9__default.default.writeFile(
|
|
726
|
+
path10__default.default.join(outputDir, "manifest.json"),
|
|
724
727
|
JSON.stringify(manifest, null, 2)
|
|
725
728
|
);
|
|
726
729
|
}
|
|
727
730
|
async function compileStandaloneTheme(themePath, themeName) {
|
|
728
|
-
const outputDir =
|
|
729
|
-
const bundleEntry =
|
|
730
|
-
const indexEntry =
|
|
731
|
+
const outputDir = path10__default.default.join(themePath, "dist");
|
|
732
|
+
const bundleEntry = path10__default.default.join(themePath, "bundle-entry.ts");
|
|
733
|
+
const indexEntry = path10__default.default.join(themePath, "index.ts");
|
|
731
734
|
let entryPoint = indexEntry;
|
|
732
735
|
try {
|
|
733
|
-
await
|
|
736
|
+
await fs9__default.default.access(bundleEntry);
|
|
734
737
|
entryPoint = bundleEntry;
|
|
735
738
|
} catch {
|
|
736
739
|
}
|
|
737
|
-
const shimPath =
|
|
738
|
-
await
|
|
739
|
-
await
|
|
740
|
+
const shimPath = path10__default.default.join(outputDir, ".process-shim.js");
|
|
741
|
+
await fs9__default.default.mkdir(outputDir, { recursive: true });
|
|
742
|
+
await fs9__default.default.writeFile(shimPath, PROCESS_SHIM);
|
|
740
743
|
const buildOptions = {
|
|
741
744
|
entryPoints: [entryPoint],
|
|
742
745
|
bundle: true,
|
|
@@ -786,7 +789,7 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
786
789
|
try {
|
|
787
790
|
const result = await esbuild__namespace.build(buildOptions);
|
|
788
791
|
try {
|
|
789
|
-
await
|
|
792
|
+
await fs9__default.default.unlink(shimPath);
|
|
790
793
|
} catch {
|
|
791
794
|
}
|
|
792
795
|
await contentHashEntry(outputDir);
|
|
@@ -805,7 +808,7 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
805
808
|
return true;
|
|
806
809
|
} catch (error) {
|
|
807
810
|
try {
|
|
808
|
-
await
|
|
811
|
+
await fs9__default.default.unlink(shimPath);
|
|
809
812
|
} catch {
|
|
810
813
|
}
|
|
811
814
|
logger.error(`esbuild compilation failed: ${error}`);
|
|
@@ -813,18 +816,18 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
813
816
|
}
|
|
814
817
|
}
|
|
815
818
|
async function compileStandaloneThemeDev(themePath, themeName) {
|
|
816
|
-
const outputDir =
|
|
817
|
-
const bundleEntry =
|
|
818
|
-
const indexEntry =
|
|
819
|
+
const outputDir = path10__default.default.join(themePath, "dist");
|
|
820
|
+
const bundleEntry = path10__default.default.join(themePath, "bundle-entry.ts");
|
|
821
|
+
const indexEntry = path10__default.default.join(themePath, "index.ts");
|
|
819
822
|
let entryPoint = indexEntry;
|
|
820
823
|
try {
|
|
821
|
-
await
|
|
824
|
+
await fs9__default.default.access(bundleEntry);
|
|
822
825
|
entryPoint = bundleEntry;
|
|
823
826
|
} catch {
|
|
824
827
|
}
|
|
825
|
-
const shimPath =
|
|
826
|
-
await
|
|
827
|
-
await
|
|
828
|
+
const shimPath = path10__default.default.join(outputDir, ".process-shim.js");
|
|
829
|
+
await fs9__default.default.mkdir(outputDir, { recursive: true });
|
|
830
|
+
await fs9__default.default.writeFile(shimPath, PROCESS_SHIM);
|
|
828
831
|
const buildOptions = {
|
|
829
832
|
entryPoints: [entryPoint],
|
|
830
833
|
bundle: true,
|
|
@@ -877,18 +880,18 @@ async function compileStandaloneThemeDev(themePath, themeName) {
|
|
|
877
880
|
return { context: context2, outputDir };
|
|
878
881
|
}
|
|
879
882
|
async function compilePreviewRuntime(themePath) {
|
|
880
|
-
const outputDir =
|
|
881
|
-
await
|
|
882
|
-
const outputPath =
|
|
883
|
+
const outputDir = path10__default.default.join(themePath, "dist");
|
|
884
|
+
await fs9__default.default.mkdir(outputDir, { recursive: true });
|
|
885
|
+
const outputPath = path10__default.default.join(outputDir, "preview-runtime.js");
|
|
883
886
|
const locations = [
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
+
path10__default.default.join(__dirname, "..", "preview", "preview-app.tsx"),
|
|
888
|
+
path10__default.default.join(__dirname, "preview", "preview-app.tsx"),
|
|
889
|
+
path10__default.default.join(__dirname, "..", "..", "src", "preview", "preview-app.tsx")
|
|
887
890
|
];
|
|
888
891
|
let previewEntryPath = null;
|
|
889
892
|
for (const loc of locations) {
|
|
890
893
|
try {
|
|
891
|
-
await
|
|
894
|
+
await fs9__default.default.access(loc);
|
|
892
895
|
previewEntryPath = loc;
|
|
893
896
|
break;
|
|
894
897
|
} catch {
|
|
@@ -971,10 +974,10 @@ ${locations.join("\n")}`
|
|
|
971
974
|
if (!lucideScanned) {
|
|
972
975
|
lucideScanned = true;
|
|
973
976
|
const coreSrcCandidates = [
|
|
974
|
-
|
|
975
|
-
|
|
977
|
+
path10__default.default.join(themePath, "node_modules", "@onexapis", "core", "src"),
|
|
978
|
+
path10__default.default.join(themePath, "..", "..", "packages", "core", "src"),
|
|
976
979
|
// monorepo sibling
|
|
977
|
-
|
|
980
|
+
path10__default.default.join(
|
|
978
981
|
__dirname,
|
|
979
982
|
"..",
|
|
980
983
|
"..",
|
|
@@ -989,7 +992,7 @@ ${locations.join("\n")}`
|
|
|
989
992
|
let coreSourceDir = null;
|
|
990
993
|
for (const candidate of coreSrcCandidates) {
|
|
991
994
|
try {
|
|
992
|
-
await
|
|
995
|
+
await fs9__default.default.access(candidate);
|
|
993
996
|
coreSourceDir = candidate;
|
|
994
997
|
break;
|
|
995
998
|
} catch {
|
|
@@ -1008,21 +1011,21 @@ ${locations.join("\n")}`
|
|
|
1008
1011
|
}
|
|
1009
1012
|
} else {
|
|
1010
1013
|
const coreDistCandidates = [
|
|
1011
|
-
|
|
1014
|
+
path10__default.default.join(themePath, "node_modules", "@onexapis", "core", "dist")
|
|
1012
1015
|
];
|
|
1013
1016
|
const resolvedDist = await resolveNodeModulesFile(
|
|
1014
1017
|
__dirname,
|
|
1015
|
-
|
|
1018
|
+
path10__default.default.join("@onexapis", "core", "dist")
|
|
1016
1019
|
);
|
|
1017
1020
|
if (resolvedDist) coreDistCandidates.push(resolvedDist);
|
|
1018
1021
|
for (const candidate of coreDistCandidates) {
|
|
1019
1022
|
try {
|
|
1020
|
-
await
|
|
1023
|
+
await fs9__default.default.access(candidate);
|
|
1021
1024
|
const mjsFiles = await glob.glob("*.mjs", { cwd: candidate });
|
|
1022
1025
|
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']lucide-react["']/g;
|
|
1023
1026
|
for (const file of mjsFiles) {
|
|
1024
|
-
const content = await
|
|
1025
|
-
|
|
1027
|
+
const content = await fs9__default.default.readFile(
|
|
1028
|
+
path10__default.default.join(candidate, file),
|
|
1026
1029
|
"utf-8"
|
|
1027
1030
|
);
|
|
1028
1031
|
for (const match of content.matchAll(importRegex)) {
|
|
@@ -1077,7 +1080,7 @@ export default new Proxy({}, { get: (_, name) => name === '__esModule' ? true :
|
|
|
1077
1080
|
const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)) || __filename);
|
|
1078
1081
|
const cjsPath = req.resolve("framer-motion");
|
|
1079
1082
|
const pkgDir = cjsPath.replace(/[/\\]dist[/\\].*$/, "");
|
|
1080
|
-
const esmEntry =
|
|
1083
|
+
const esmEntry = path10__default.default.join(pkgDir, "dist", "es", "index.mjs");
|
|
1081
1084
|
const { existsSync } = await import('fs');
|
|
1082
1085
|
if (existsSync(esmEntry)) {
|
|
1083
1086
|
return { path: esmEntry, namespace: "file" };
|
|
@@ -1176,8 +1179,8 @@ export function headers() { return new Headers(); }
|
|
|
1176
1179
|
});
|
|
1177
1180
|
}
|
|
1178
1181
|
};
|
|
1179
|
-
const shimPath =
|
|
1180
|
-
await
|
|
1182
|
+
const shimPath = path10__default.default.join(outputDir, ".process-shim-preview.js");
|
|
1183
|
+
await fs9__default.default.writeFile(shimPath, PROCESS_SHIM);
|
|
1181
1184
|
await esbuild__namespace.build({
|
|
1182
1185
|
entryPoints: [previewEntryPath],
|
|
1183
1186
|
bundle: true,
|
|
@@ -1212,7 +1215,7 @@ export function headers() { return new Headers(); }
|
|
|
1212
1215
|
}
|
|
1213
1216
|
});
|
|
1214
1217
|
try {
|
|
1215
|
-
await
|
|
1218
|
+
await fs9__default.default.unlink(shimPath);
|
|
1216
1219
|
} catch {
|
|
1217
1220
|
}
|
|
1218
1221
|
return outputPath;
|
|
@@ -1345,18 +1348,18 @@ async function renderTemplate(templatePath, data) {
|
|
|
1345
1348
|
return ejs__default.default.render(template, data);
|
|
1346
1349
|
}
|
|
1347
1350
|
async function writeFile(filePath, content) {
|
|
1348
|
-
await fs__default.default.ensureDir(
|
|
1351
|
+
await fs__default.default.ensureDir(path10__default.default.dirname(filePath));
|
|
1349
1352
|
await fs__default.default.writeFile(filePath, content, "utf-8");
|
|
1350
1353
|
}
|
|
1351
1354
|
function getTemplatesDir() {
|
|
1352
1355
|
const locations = [
|
|
1353
|
-
|
|
1356
|
+
path10__default.default.join(__dirname, "../../templates"),
|
|
1354
1357
|
// Development
|
|
1355
|
-
|
|
1358
|
+
path10__default.default.join(__dirname, "../templates"),
|
|
1356
1359
|
// Production (dist/)
|
|
1357
|
-
|
|
1360
|
+
path10__default.default.join(process.cwd(), "templates"),
|
|
1358
1361
|
// Fallback
|
|
1359
|
-
|
|
1362
|
+
path10__default.default.join(process.cwd(), "packages/cli/templates")
|
|
1360
1363
|
// Monorepo
|
|
1361
1364
|
];
|
|
1362
1365
|
for (const location of locations) {
|
|
@@ -1368,7 +1371,7 @@ function getTemplatesDir() {
|
|
|
1368
1371
|
}
|
|
1369
1372
|
async function copyTemplate(templateName, targetDir, data) {
|
|
1370
1373
|
const templatesDir = getTemplatesDir();
|
|
1371
|
-
const templateDir =
|
|
1374
|
+
const templateDir = path10__default.default.join(templatesDir, templateName);
|
|
1372
1375
|
if (!fs__default.default.existsSync(templateDir)) {
|
|
1373
1376
|
throw new Error(
|
|
1374
1377
|
`Template "${templateName}" not found at ${templateDir}. Available templates: ${fs__default.default.readdirSync(templatesDir).join(", ")}`
|
|
@@ -1377,8 +1380,8 @@ async function copyTemplate(templateName, targetDir, data) {
|
|
|
1377
1380
|
await fs__default.default.ensureDir(targetDir);
|
|
1378
1381
|
const files = await fs__default.default.readdir(templateDir);
|
|
1379
1382
|
for (const file of files) {
|
|
1380
|
-
const templatePath =
|
|
1381
|
-
const targetPath =
|
|
1383
|
+
const templatePath = path10__default.default.join(templateDir, file);
|
|
1384
|
+
const targetPath = path10__default.default.join(targetDir, file);
|
|
1382
1385
|
const stat = await fs__default.default.stat(templatePath);
|
|
1383
1386
|
if (stat.isDirectory()) {
|
|
1384
1387
|
await copyTemplateDir(templatePath, targetPath, data);
|
|
@@ -1395,8 +1398,8 @@ async function copyTemplateDir(templateDir, targetDir, data) {
|
|
|
1395
1398
|
await fs__default.default.ensureDir(targetDir);
|
|
1396
1399
|
const files = await fs__default.default.readdir(templateDir);
|
|
1397
1400
|
for (const file of files) {
|
|
1398
|
-
const templatePath =
|
|
1399
|
-
const targetPath =
|
|
1401
|
+
const templatePath = path10__default.default.join(templateDir, file);
|
|
1402
|
+
const targetPath = path10__default.default.join(targetDir, file);
|
|
1400
1403
|
const stat = await fs__default.default.stat(templatePath);
|
|
1401
1404
|
if (stat.isDirectory()) {
|
|
1402
1405
|
await copyTemplateDir(templatePath, targetPath, data);
|
|
@@ -1411,32 +1414,32 @@ async function copyTemplateDir(templateDir, targetDir, data) {
|
|
|
1411
1414
|
}
|
|
1412
1415
|
function getProjectRoot() {
|
|
1413
1416
|
let currentDir = process.cwd();
|
|
1414
|
-
while (currentDir !==
|
|
1415
|
-
const packageJsonPath =
|
|
1417
|
+
while (currentDir !== path10__default.default.parse(currentDir).root) {
|
|
1418
|
+
const packageJsonPath = path10__default.default.join(currentDir, "package.json");
|
|
1416
1419
|
if (fs__default.default.existsSync(packageJsonPath)) {
|
|
1417
1420
|
const packageJson = fs__default.default.readJsonSync(packageJsonPath);
|
|
1418
|
-
if (packageJson.workspaces || fs__default.default.existsSync(
|
|
1421
|
+
if (packageJson.workspaces || fs__default.default.existsSync(path10__default.default.join(currentDir, "src/themes")) || fs__default.default.existsSync(path10__default.default.join(currentDir, "themes"))) {
|
|
1419
1422
|
return currentDir;
|
|
1420
1423
|
}
|
|
1421
1424
|
}
|
|
1422
|
-
currentDir =
|
|
1425
|
+
currentDir = path10__default.default.dirname(currentDir);
|
|
1423
1426
|
}
|
|
1424
1427
|
return process.cwd();
|
|
1425
1428
|
}
|
|
1426
1429
|
function getThemesDir() {
|
|
1427
1430
|
const root = getProjectRoot();
|
|
1428
|
-
if (fs__default.default.existsSync(
|
|
1429
|
-
return
|
|
1430
|
-
if (fs__default.default.existsSync(
|
|
1431
|
-
return
|
|
1432
|
-
return
|
|
1431
|
+
if (fs__default.default.existsSync(path10__default.default.join(root, "themes")))
|
|
1432
|
+
return path10__default.default.join(root, "themes");
|
|
1433
|
+
if (fs__default.default.existsSync(path10__default.default.join(root, "src/themes")))
|
|
1434
|
+
return path10__default.default.join(root, "src/themes");
|
|
1435
|
+
return path10__default.default.dirname(root);
|
|
1433
1436
|
}
|
|
1434
1437
|
function getFeaturesDir() {
|
|
1435
|
-
return
|
|
1438
|
+
return path10__default.default.join(getProjectRoot(), "src/features");
|
|
1436
1439
|
}
|
|
1437
1440
|
function isOneXProject() {
|
|
1438
1441
|
const root = getProjectRoot();
|
|
1439
|
-
return fs__default.default.existsSync(
|
|
1442
|
+
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"));
|
|
1440
1443
|
}
|
|
1441
1444
|
function ensureOneXProject() {
|
|
1442
1445
|
if (!isOneXProject()) {
|
|
@@ -1452,13 +1455,13 @@ function listThemes() {
|
|
|
1452
1455
|
return [];
|
|
1453
1456
|
}
|
|
1454
1457
|
return fs__default.default.readdirSync(themesDir).filter((name) => {
|
|
1455
|
-
const themePath =
|
|
1456
|
-
return fs__default.default.statSync(themePath).isDirectory() && (fs__default.default.existsSync(
|
|
1458
|
+
const themePath = path10__default.default.join(themesDir, name);
|
|
1459
|
+
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")));
|
|
1457
1460
|
});
|
|
1458
1461
|
}
|
|
1459
1462
|
function themeExists(themeName) {
|
|
1460
|
-
const themePath =
|
|
1461
|
-
return fs__default.default.existsSync(themePath) && (fs__default.default.existsSync(
|
|
1463
|
+
const themePath = path10__default.default.join(getThemesDir(), themeName);
|
|
1464
|
+
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")));
|
|
1462
1465
|
}
|
|
1463
1466
|
function detectPackageManager() {
|
|
1464
1467
|
const userAgent = process.env.npm_config_user_agent || "";
|
|
@@ -1466,24 +1469,22 @@ function detectPackageManager() {
|
|
|
1466
1469
|
if (userAgent.includes("yarn")) return "yarn";
|
|
1467
1470
|
if (userAgent.includes("bun")) return "bun";
|
|
1468
1471
|
const cwd = process.cwd();
|
|
1469
|
-
if (fs__default.default.existsSync(
|
|
1470
|
-
if (fs__default.default.existsSync(
|
|
1471
|
-
if (fs__default.default.existsSync(
|
|
1472
|
+
if (fs__default.default.existsSync(path10__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
1473
|
+
if (fs__default.default.existsSync(path10__default.default.join(cwd, "yarn.lock"))) return "yarn";
|
|
1474
|
+
if (fs__default.default.existsSync(path10__default.default.join(cwd, "bun.lockb"))) return "bun";
|
|
1472
1475
|
return "npm";
|
|
1473
1476
|
}
|
|
1474
1477
|
async function installDependencies(projectPath, packageManager = "npm") {
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
cwd: projectPath,
|
|
1480
|
-
stdio: "inherit"
|
|
1481
|
-
});
|
|
1482
|
-
resolve();
|
|
1483
|
-
} catch (error) {
|
|
1484
|
-
reject(error);
|
|
1485
|
-
}
|
|
1478
|
+
const args = packageManager === "yarn" ? [] : ["install"];
|
|
1479
|
+
const result = spawn2__default.default.sync(packageManager, args, {
|
|
1480
|
+
cwd: projectPath,
|
|
1481
|
+
stdio: "inherit"
|
|
1486
1482
|
});
|
|
1483
|
+
if (result.status !== 0) {
|
|
1484
|
+
throw new Error(
|
|
1485
|
+
`${packageManager} install failed with exit code ${result.status}`
|
|
1486
|
+
);
|
|
1487
|
+
}
|
|
1487
1488
|
}
|
|
1488
1489
|
|
|
1489
1490
|
// src/commands/init.ts
|
|
@@ -1517,6 +1518,184 @@ function getValidCategories() {
|
|
|
1517
1518
|
"contact"
|
|
1518
1519
|
];
|
|
1519
1520
|
}
|
|
1521
|
+
var AUTH_DIR = path10__default.default.join(os__default.default.homedir(), ".onexthm");
|
|
1522
|
+
var AUTH_FILE = path10__default.default.join(AUTH_DIR, "auth.json");
|
|
1523
|
+
function getApiUrl() {
|
|
1524
|
+
return process.env.ONEXTHM_API_URL || process.env.NEXT_PUBLIC_API_URL || "https://platform-dev.onexeos.com";
|
|
1525
|
+
}
|
|
1526
|
+
async function saveAuthTokens(tokens) {
|
|
1527
|
+
await fs__default.default.ensureDir(AUTH_DIR);
|
|
1528
|
+
const key = getMachineKey();
|
|
1529
|
+
const data = JSON.stringify(tokens);
|
|
1530
|
+
const encrypted = encrypt(data, key);
|
|
1531
|
+
await fs__default.default.writeFile(AUTH_FILE, encrypted, "utf-8");
|
|
1532
|
+
}
|
|
1533
|
+
function loadAuthTokens() {
|
|
1534
|
+
try {
|
|
1535
|
+
if (!fs__default.default.existsSync(AUTH_FILE)) return null;
|
|
1536
|
+
const encrypted = fs__default.default.readFileSync(AUTH_FILE, "utf-8");
|
|
1537
|
+
const key = getMachineKey();
|
|
1538
|
+
const data = decrypt(encrypted, key);
|
|
1539
|
+
return JSON.parse(data);
|
|
1540
|
+
} catch {
|
|
1541
|
+
return null;
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1544
|
+
async function clearAuthTokens() {
|
|
1545
|
+
try {
|
|
1546
|
+
await fs__default.default.remove(AUTH_FILE);
|
|
1547
|
+
} catch {
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
function isTokenExpired(tokens) {
|
|
1551
|
+
return Date.now() / 1e3 > tokens.expiresAt - 60;
|
|
1552
|
+
}
|
|
1553
|
+
async function getValidTokens() {
|
|
1554
|
+
const tokens = loadAuthTokens();
|
|
1555
|
+
if (!tokens) return null;
|
|
1556
|
+
if (!isTokenExpired(tokens)) return tokens;
|
|
1557
|
+
try {
|
|
1558
|
+
const apiUrl = getApiUrl();
|
|
1559
|
+
const response = await fetch(`${apiUrl}/auth/refresh`, {
|
|
1560
|
+
method: "POST",
|
|
1561
|
+
headers: { "Content-Type": "application/json" },
|
|
1562
|
+
body: JSON.stringify({ refresh_token: tokens.refreshToken })
|
|
1563
|
+
});
|
|
1564
|
+
if (!response.ok) {
|
|
1565
|
+
await clearAuthTokens();
|
|
1566
|
+
return null;
|
|
1567
|
+
}
|
|
1568
|
+
const data = await response.json();
|
|
1569
|
+
const body = data.statusCode ? data.body : data;
|
|
1570
|
+
const refreshed = {
|
|
1571
|
+
...tokens,
|
|
1572
|
+
accessToken: body.AccessToken || tokens.accessToken,
|
|
1573
|
+
idToken: body.IdToken || tokens.idToken,
|
|
1574
|
+
expiresAt: Math.floor(Date.now() / 1e3) + (body.ExpiresIn || 3600)
|
|
1575
|
+
};
|
|
1576
|
+
await saveAuthTokens(refreshed);
|
|
1577
|
+
return refreshed;
|
|
1578
|
+
} catch {
|
|
1579
|
+
await clearAuthTokens();
|
|
1580
|
+
return null;
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
async function authenticatedFetch(url, init) {
|
|
1584
|
+
const tokens = await getValidTokens();
|
|
1585
|
+
if (!tokens) {
|
|
1586
|
+
throw new Error("Not logged in. Run: onexthm login");
|
|
1587
|
+
}
|
|
1588
|
+
const headers = new Headers(init?.headers);
|
|
1589
|
+
headers.set("Authorization", `Bearer ${tokens.idToken}`);
|
|
1590
|
+
headers.set("Content-Type", "application/json");
|
|
1591
|
+
return fetch(url, { ...init, headers });
|
|
1592
|
+
}
|
|
1593
|
+
function getMachineKey() {
|
|
1594
|
+
let seed;
|
|
1595
|
+
if (process.platform === "darwin") {
|
|
1596
|
+
seed = `onexthm:${os__default.default.hostname()}:${os__default.default.userInfo().username}`;
|
|
1597
|
+
} else if (process.platform === "linux") {
|
|
1598
|
+
try {
|
|
1599
|
+
seed = `onexthm:${fs__default.default.readFileSync("/etc/machine-id", "utf-8").trim()}`;
|
|
1600
|
+
} catch {
|
|
1601
|
+
seed = `onexthm:${os__default.default.hostname()}:${os__default.default.userInfo().username}`;
|
|
1602
|
+
}
|
|
1603
|
+
} else {
|
|
1604
|
+
seed = `onexthm:${os__default.default.hostname()}:${os__default.default.userInfo().username}`;
|
|
1605
|
+
}
|
|
1606
|
+
return crypto__default.default.createHash("sha256").update(seed).digest();
|
|
1607
|
+
}
|
|
1608
|
+
function encrypt(text, key) {
|
|
1609
|
+
const iv = crypto__default.default.randomBytes(16);
|
|
1610
|
+
const cipher = crypto__default.default.createCipheriv("aes-256-gcm", key, iv);
|
|
1611
|
+
let encrypted = cipher.update(text, "utf-8", "hex");
|
|
1612
|
+
encrypted += cipher.final("hex");
|
|
1613
|
+
const tag = cipher.getAuthTag();
|
|
1614
|
+
return `${iv.toString("hex")}:${tag.toString("hex")}:${encrypted}`;
|
|
1615
|
+
}
|
|
1616
|
+
function decrypt(text, key) {
|
|
1617
|
+
const [ivHex, tagHex, encrypted] = text.split(":");
|
|
1618
|
+
const iv = Buffer.from(ivHex, "hex");
|
|
1619
|
+
const tag = Buffer.from(tagHex, "hex");
|
|
1620
|
+
const decipher = crypto__default.default.createDecipheriv("aes-256-gcm", key, iv);
|
|
1621
|
+
decipher.setAuthTag(tag);
|
|
1622
|
+
let decrypted = decipher.update(encrypted, "hex", "utf-8");
|
|
1623
|
+
decrypted += decipher.final("utf-8");
|
|
1624
|
+
return decrypted;
|
|
1625
|
+
}
|
|
1626
|
+
function parseJwtClaims(idToken) {
|
|
1627
|
+
try {
|
|
1628
|
+
const payload = idToken.split(".")[1];
|
|
1629
|
+
const decoded = Buffer.from(payload, "base64url").toString("utf-8");
|
|
1630
|
+
return JSON.parse(decoded);
|
|
1631
|
+
} catch {
|
|
1632
|
+
return {};
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
function getNpxCommand() {
|
|
1636
|
+
return process.platform === "win32" ? "npx.cmd" : "npx";
|
|
1637
|
+
}
|
|
1638
|
+
function getDefaultMcpConfig() {
|
|
1639
|
+
return {
|
|
1640
|
+
mcpServers: {
|
|
1641
|
+
onexthm: {
|
|
1642
|
+
command: getNpxCommand(),
|
|
1643
|
+
args: ["-y", "@onexapis/theme-mcp"]
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
};
|
|
1647
|
+
}
|
|
1648
|
+
function ensureMcpJson(projectPath, figmaApiKey) {
|
|
1649
|
+
const mcpJsonPath = path10__default.default.join(projectPath, ".mcp.json");
|
|
1650
|
+
const npx = getNpxCommand();
|
|
1651
|
+
let mcpConfig;
|
|
1652
|
+
if (fs4__default.default.existsSync(mcpJsonPath)) {
|
|
1653
|
+
try {
|
|
1654
|
+
mcpConfig = JSON.parse(fs4__default.default.readFileSync(mcpJsonPath, "utf-8"));
|
|
1655
|
+
if (!mcpConfig.mcpServers) {
|
|
1656
|
+
mcpConfig.mcpServers = {};
|
|
1657
|
+
}
|
|
1658
|
+
} catch {
|
|
1659
|
+
mcpConfig = getDefaultMcpConfig();
|
|
1660
|
+
}
|
|
1661
|
+
} else {
|
|
1662
|
+
mcpConfig = getDefaultMcpConfig();
|
|
1663
|
+
}
|
|
1664
|
+
mcpConfig.mcpServers.onexthm = {
|
|
1665
|
+
command: npx,
|
|
1666
|
+
args: ["-y", "@onexapis/theme-mcp"]
|
|
1667
|
+
};
|
|
1668
|
+
if (figmaApiKey) {
|
|
1669
|
+
mcpConfig.mcpServers.figma = {
|
|
1670
|
+
command: npx,
|
|
1671
|
+
args: [
|
|
1672
|
+
"-y",
|
|
1673
|
+
"figma-developer-mcp",
|
|
1674
|
+
`--figma-api-key=${figmaApiKey}`,
|
|
1675
|
+
"--stdio"
|
|
1676
|
+
]
|
|
1677
|
+
};
|
|
1678
|
+
} else {
|
|
1679
|
+
delete mcpConfig.mcpServers.figma;
|
|
1680
|
+
}
|
|
1681
|
+
fs4__default.default.writeFileSync(mcpJsonPath, JSON.stringify(mcpConfig, null, 2) + "\n");
|
|
1682
|
+
ensureThemeMcpDependency(projectPath);
|
|
1683
|
+
}
|
|
1684
|
+
function ensureThemeMcpDependency(projectPath) {
|
|
1685
|
+
const pkgJsonPath = path10__default.default.join(projectPath, "package.json");
|
|
1686
|
+
if (!fs4__default.default.existsSync(pkgJsonPath)) return;
|
|
1687
|
+
try {
|
|
1688
|
+
const pkg = JSON.parse(fs4__default.default.readFileSync(pkgJsonPath, "utf-8"));
|
|
1689
|
+
if (!pkg.devDependencies) {
|
|
1690
|
+
pkg.devDependencies = {};
|
|
1691
|
+
}
|
|
1692
|
+
if (!pkg.devDependencies["@onexapis/theme-mcp"]) {
|
|
1693
|
+
pkg.devDependencies["@onexapis/theme-mcp"] = "^0.1.0";
|
|
1694
|
+
fs4__default.default.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
1695
|
+
}
|
|
1696
|
+
} catch {
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1520
1699
|
|
|
1521
1700
|
// src/commands/init.ts
|
|
1522
1701
|
async function initCommand(projectName, options = {}) {
|
|
@@ -1534,7 +1713,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1534
1713
|
if (!validateThemeName(kebabName)) {
|
|
1535
1714
|
return "Invalid project name. Use lowercase letters, numbers, and hyphens only.";
|
|
1536
1715
|
}
|
|
1537
|
-
if (
|
|
1716
|
+
if (fs4__default.default.existsSync(path10__default.default.join(process.cwd(), kebabName))) {
|
|
1538
1717
|
return `Directory "${kebabName}" already exists`;
|
|
1539
1718
|
}
|
|
1540
1719
|
return true;
|
|
@@ -1545,11 +1724,46 @@ async function initCommand(projectName, options = {}) {
|
|
|
1545
1724
|
} else {
|
|
1546
1725
|
name = toKebabCase(projectName);
|
|
1547
1726
|
}
|
|
1548
|
-
const projectPath =
|
|
1549
|
-
if (
|
|
1727
|
+
const projectPath = path10__default.default.join(process.cwd(), name);
|
|
1728
|
+
if (fs4__default.default.existsSync(projectPath)) {
|
|
1550
1729
|
logger.error(`Directory "${name}" already exists.`);
|
|
1551
1730
|
process.exit(1);
|
|
1552
1731
|
}
|
|
1732
|
+
if (!options.yes) {
|
|
1733
|
+
try {
|
|
1734
|
+
const apiUrl = getApiUrl();
|
|
1735
|
+
const controller = new AbortController();
|
|
1736
|
+
const timeout = setTimeout(() => controller.abort(), 3e3);
|
|
1737
|
+
const response = await fetch(
|
|
1738
|
+
`${apiUrl}/website-api/themes/${encodeURIComponent(name)}/exists`,
|
|
1739
|
+
{ signal: controller.signal }
|
|
1740
|
+
);
|
|
1741
|
+
clearTimeout(timeout);
|
|
1742
|
+
if (response.ok) {
|
|
1743
|
+
const data2 = await response.json();
|
|
1744
|
+
const body = data2.statusCode ? data2.body : data2;
|
|
1745
|
+
if (body.exists && body.owner === "other") {
|
|
1746
|
+
logger.warning(
|
|
1747
|
+
`Theme ID "${name}" is already registered by another developer.
|
|
1748
|
+
You can still create this locally, but publishing will fail.
|
|
1749
|
+
Consider using a different name.`
|
|
1750
|
+
);
|
|
1751
|
+
const { proceed } = await inquirer__default.default.prompt([
|
|
1752
|
+
{
|
|
1753
|
+
type: "confirm",
|
|
1754
|
+
name: "proceed",
|
|
1755
|
+
message: "Continue anyway?",
|
|
1756
|
+
default: false
|
|
1757
|
+
}
|
|
1758
|
+
]);
|
|
1759
|
+
if (!proceed) {
|
|
1760
|
+
process.exit(0);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1764
|
+
} catch {
|
|
1765
|
+
}
|
|
1766
|
+
}
|
|
1553
1767
|
let displayName;
|
|
1554
1768
|
let description;
|
|
1555
1769
|
let author;
|
|
@@ -1617,7 +1831,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1617
1831
|
}
|
|
1618
1832
|
logger.startSpinner("Creating project structure...");
|
|
1619
1833
|
try {
|
|
1620
|
-
|
|
1834
|
+
fs4__default.default.mkdirSync(projectPath, { recursive: true });
|
|
1621
1835
|
await copyTemplate(template, projectPath, data);
|
|
1622
1836
|
await renameThemeInFiles(
|
|
1623
1837
|
projectPath,
|
|
@@ -1626,28 +1840,14 @@ async function initCommand(projectName, options = {}) {
|
|
|
1626
1840
|
description,
|
|
1627
1841
|
author
|
|
1628
1842
|
);
|
|
1629
|
-
|
|
1630
|
-
if (fs2__default.default.existsSync(mcpJsonPath)) {
|
|
1631
|
-
let mcpContent = fs2__default.default.readFileSync(mcpJsonPath, "utf-8");
|
|
1632
|
-
if (figmaApiKey) {
|
|
1633
|
-
mcpContent = mcpContent.replace("__FIGMA_API_KEY__", figmaApiKey);
|
|
1634
|
-
} else {
|
|
1635
|
-
try {
|
|
1636
|
-
const mcpJson = JSON.parse(mcpContent);
|
|
1637
|
-
delete mcpJson.mcpServers.figma;
|
|
1638
|
-
mcpContent = JSON.stringify(mcpJson, null, 2) + "\n";
|
|
1639
|
-
} catch {
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
fs2__default.default.writeFileSync(mcpJsonPath, mcpContent, "utf-8");
|
|
1643
|
-
}
|
|
1843
|
+
ensureMcpJson(projectPath, figmaApiKey || void 0);
|
|
1644
1844
|
logger.stopSpinner(true, "Project structure created!");
|
|
1645
1845
|
if (options.git) {
|
|
1646
1846
|
logger.startSpinner("Initializing git repository...");
|
|
1647
1847
|
try {
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1848
|
+
spawn2__default.default.sync("git", ["init"], { cwd: projectPath, stdio: "ignore" });
|
|
1849
|
+
spawn2__default.default.sync("git", ["add", "."], { cwd: projectPath, stdio: "ignore" });
|
|
1850
|
+
spawn2__default.default.sync("git", ["commit", "-m", "Initial commit from onexthm init"], {
|
|
1651
1851
|
cwd: projectPath,
|
|
1652
1852
|
stdio: "ignore"
|
|
1653
1853
|
});
|
|
@@ -1699,16 +1899,16 @@ async function initCommand(projectName, options = {}) {
|
|
|
1699
1899
|
logger.error(
|
|
1700
1900
|
error instanceof Error ? error.message : "Unknown error occurred"
|
|
1701
1901
|
);
|
|
1702
|
-
if (
|
|
1703
|
-
|
|
1902
|
+
if (fs4__default.default.existsSync(projectPath)) {
|
|
1903
|
+
fs4__default.default.rmSync(projectPath, { recursive: true, force: true });
|
|
1704
1904
|
}
|
|
1705
1905
|
process.exit(1);
|
|
1706
1906
|
}
|
|
1707
1907
|
}
|
|
1708
1908
|
async function renameThemeInFiles(projectPath, themeName, displayName, description, author) {
|
|
1709
|
-
const configPath =
|
|
1710
|
-
if (
|
|
1711
|
-
let content =
|
|
1909
|
+
const configPath = path10__default.default.join(projectPath, "theme.config.ts");
|
|
1910
|
+
if (fs4__default.default.existsSync(configPath)) {
|
|
1911
|
+
let content = fs4__default.default.readFileSync(configPath, "utf-8");
|
|
1712
1912
|
content = content.replace(
|
|
1713
1913
|
/name: "My Simple Theme"/,
|
|
1714
1914
|
`name: "${displayName}"`
|
|
@@ -1717,11 +1917,11 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
|
|
|
1717
1917
|
/description: ".*?"/,
|
|
1718
1918
|
`description: "${description}"`
|
|
1719
1919
|
);
|
|
1720
|
-
|
|
1920
|
+
fs4__default.default.writeFileSync(configPath, content, "utf-8");
|
|
1721
1921
|
}
|
|
1722
|
-
const pkgPath =
|
|
1723
|
-
if (
|
|
1724
|
-
let content =
|
|
1922
|
+
const pkgPath = path10__default.default.join(projectPath, "package.json");
|
|
1923
|
+
if (fs4__default.default.existsSync(pkgPath)) {
|
|
1924
|
+
let content = fs4__default.default.readFileSync(pkgPath, "utf-8");
|
|
1725
1925
|
content = content.replace(
|
|
1726
1926
|
/@onex-themes\/my-simple/g,
|
|
1727
1927
|
`@onex-themes/${themeName}`
|
|
@@ -1730,7 +1930,7 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
|
|
|
1730
1930
|
/"description": ".*?"/,
|
|
1731
1931
|
`"description": "${description}"`
|
|
1732
1932
|
);
|
|
1733
|
-
|
|
1933
|
+
fs4__default.default.writeFileSync(pkgPath, content, "utf-8");
|
|
1734
1934
|
}
|
|
1735
1935
|
}
|
|
1736
1936
|
|
|
@@ -1741,10 +1941,10 @@ async function createSectionCommand(name, options) {
|
|
|
1741
1941
|
ensureOneXProject();
|
|
1742
1942
|
if (!options.theme) {
|
|
1743
1943
|
const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
|
|
1744
|
-
(f) => fs__default.default.existsSync(
|
|
1944
|
+
(f) => fs__default.default.existsSync(path10__default.default.join(process.cwd(), f))
|
|
1745
1945
|
);
|
|
1746
1946
|
if (isStandaloneTheme) {
|
|
1747
|
-
options.theme =
|
|
1947
|
+
options.theme = path10__default.default.basename(process.cwd());
|
|
1748
1948
|
}
|
|
1749
1949
|
}
|
|
1750
1950
|
const sectionName = toKebabCase(name);
|
|
@@ -1807,35 +2007,35 @@ async function createSectionCommand(name, options) {
|
|
|
1807
2007
|
};
|
|
1808
2008
|
logger.startSpinner("Creating section files...");
|
|
1809
2009
|
try {
|
|
1810
|
-
const themePath =
|
|
1811
|
-
const sectionPath =
|
|
2010
|
+
const themePath = path10__default.default.join(getThemesDir(), themeName);
|
|
2011
|
+
const sectionPath = path10__default.default.join(themePath, "sections", sectionName);
|
|
1812
2012
|
const schemaContent = generateSectionSchema(data);
|
|
1813
2013
|
await writeFile(
|
|
1814
|
-
|
|
2014
|
+
path10__default.default.join(sectionPath, `${sectionName}.schema.ts`),
|
|
1815
2015
|
schemaContent
|
|
1816
2016
|
);
|
|
1817
2017
|
if (createTemplate) {
|
|
1818
2018
|
const templateContent = generateSectionTemplate(data);
|
|
1819
2019
|
await writeFile(
|
|
1820
|
-
|
|
2020
|
+
path10__default.default.join(sectionPath, `${sectionName}-default.tsx`),
|
|
1821
2021
|
templateContent
|
|
1822
2022
|
);
|
|
1823
2023
|
}
|
|
1824
2024
|
const indexContent = generateSectionIndex(data, createTemplate);
|
|
1825
|
-
await writeFile(
|
|
2025
|
+
await writeFile(path10__default.default.join(sectionPath, "index.ts"), indexContent);
|
|
1826
2026
|
logger.stopSpinner(true, "Section files created successfully!");
|
|
1827
2027
|
logger.newLine();
|
|
1828
2028
|
logger.section("Next steps:");
|
|
1829
2029
|
logger.log(
|
|
1830
|
-
` 1. Edit schema: ${
|
|
2030
|
+
` 1. Edit schema: ${path10__default.default.relative(process.cwd(), path10__default.default.join(sectionPath, `${sectionName}.schema.ts`))}`
|
|
1831
2031
|
);
|
|
1832
2032
|
if (createTemplate) {
|
|
1833
2033
|
logger.log(
|
|
1834
|
-
` 2. Edit template: ${
|
|
2034
|
+
` 2. Edit template: ${path10__default.default.relative(process.cwd(), path10__default.default.join(sectionPath, `${sectionName}-default.tsx`))}`
|
|
1835
2035
|
);
|
|
1836
2036
|
}
|
|
1837
2037
|
logger.log(
|
|
1838
|
-
` 3. Add to theme manifest: ${
|
|
2038
|
+
` 3. Add to theme manifest: ${path10__default.default.relative(process.cwd(), path10__default.default.join(themePath, "manifest.ts"))}`
|
|
1839
2039
|
);
|
|
1840
2040
|
logger.newLine();
|
|
1841
2041
|
logger.success("Section created successfully!");
|
|
@@ -1983,10 +2183,10 @@ async function createBlockCommand(name, options) {
|
|
|
1983
2183
|
ensureOneXProject();
|
|
1984
2184
|
if (!options.theme) {
|
|
1985
2185
|
const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
|
|
1986
|
-
(f) => fs__default.default.existsSync(
|
|
2186
|
+
(f) => fs__default.default.existsSync(path10__default.default.join(process.cwd(), f))
|
|
1987
2187
|
);
|
|
1988
2188
|
if (isStandaloneTheme) {
|
|
1989
|
-
options.theme =
|
|
2189
|
+
options.theme = path10__default.default.basename(process.cwd());
|
|
1990
2190
|
}
|
|
1991
2191
|
}
|
|
1992
2192
|
const blockName = toKebabCase(name);
|
|
@@ -2061,24 +2261,24 @@ async function createBlockCommand(name, options) {
|
|
|
2061
2261
|
};
|
|
2062
2262
|
logger.startSpinner("Creating block files...");
|
|
2063
2263
|
try {
|
|
2064
|
-
const blockPath = scope === "shared" ?
|
|
2264
|
+
const blockPath = scope === "shared" ? path10__default.default.join(getFeaturesDir(), "blocks", blockName) : path10__default.default.join(getThemesDir(), themeName, "blocks", blockName);
|
|
2065
2265
|
const schemaContent = generateBlockSchema(data);
|
|
2066
2266
|
await writeFile(
|
|
2067
|
-
|
|
2267
|
+
path10__default.default.join(blockPath, `${blockName}.schema.ts`),
|
|
2068
2268
|
schemaContent
|
|
2069
2269
|
);
|
|
2070
2270
|
const componentContent = generateBlockComponent(data);
|
|
2071
|
-
await writeFile(
|
|
2271
|
+
await writeFile(path10__default.default.join(blockPath, `${blockName}.tsx`), componentContent);
|
|
2072
2272
|
const indexContent = generateBlockIndex(data);
|
|
2073
|
-
await writeFile(
|
|
2273
|
+
await writeFile(path10__default.default.join(blockPath, "index.ts"), indexContent);
|
|
2074
2274
|
logger.stopSpinner(true, "Block files created successfully!");
|
|
2075
2275
|
logger.newLine();
|
|
2076
2276
|
logger.section("Next steps:");
|
|
2077
2277
|
logger.log(
|
|
2078
|
-
` 1. Edit schema: ${
|
|
2278
|
+
` 1. Edit schema: ${path10__default.default.relative(process.cwd(), path10__default.default.join(blockPath, `${blockName}.schema.ts`))}`
|
|
2079
2279
|
);
|
|
2080
2280
|
logger.log(
|
|
2081
|
-
` 2. Edit component: ${
|
|
2281
|
+
` 2. Edit component: ${path10__default.default.relative(process.cwd(), path10__default.default.join(blockPath, `${blockName}.tsx`))}`
|
|
2082
2282
|
);
|
|
2083
2283
|
logger.log(
|
|
2084
2284
|
` 3. Register in block registry: src/lib/registry/block-registry.ts`
|
|
@@ -2256,31 +2456,31 @@ async function createComponentCommand(name, options) {
|
|
|
2256
2456
|
};
|
|
2257
2457
|
logger.startSpinner("Creating component files...");
|
|
2258
2458
|
try {
|
|
2259
|
-
const componentPath =
|
|
2459
|
+
const componentPath = path10__default.default.join(
|
|
2260
2460
|
getFeaturesDir(),
|
|
2261
2461
|
"components",
|
|
2262
2462
|
componentName
|
|
2263
2463
|
);
|
|
2264
2464
|
const schemaContent = generateComponentSchema(data);
|
|
2265
2465
|
await writeFile(
|
|
2266
|
-
|
|
2466
|
+
path10__default.default.join(componentPath, `${componentName}.schema.ts`),
|
|
2267
2467
|
schemaContent
|
|
2268
2468
|
);
|
|
2269
2469
|
const componentContent = generateComponent(data);
|
|
2270
2470
|
await writeFile(
|
|
2271
|
-
|
|
2471
|
+
path10__default.default.join(componentPath, `${componentName}.tsx`),
|
|
2272
2472
|
componentContent
|
|
2273
2473
|
);
|
|
2274
2474
|
const indexContent = generateComponentIndex(data);
|
|
2275
|
-
await writeFile(
|
|
2475
|
+
await writeFile(path10__default.default.join(componentPath, "index.ts"), indexContent);
|
|
2276
2476
|
logger.stopSpinner(true, "Component files created successfully!");
|
|
2277
2477
|
logger.newLine();
|
|
2278
2478
|
logger.section("Next steps:");
|
|
2279
2479
|
logger.log(
|
|
2280
|
-
` 1. Edit schema: ${
|
|
2480
|
+
` 1. Edit schema: ${path10__default.default.relative(process.cwd(), path10__default.default.join(componentPath, `${componentName}.schema.ts`))}`
|
|
2281
2481
|
);
|
|
2282
2482
|
logger.log(
|
|
2283
|
-
` 2. Edit component: ${
|
|
2483
|
+
` 2. Edit component: ${path10__default.default.relative(process.cwd(), path10__default.default.join(componentPath, `${componentName}.tsx`))}`
|
|
2284
2484
|
);
|
|
2285
2485
|
logger.log(
|
|
2286
2486
|
` 3. Register in component registry: src/lib/registry/component-registry.ts`
|
|
@@ -2437,13 +2637,13 @@ async function listSections(themeFilter) {
|
|
|
2437
2637
|
return;
|
|
2438
2638
|
}
|
|
2439
2639
|
for (const theme of themes) {
|
|
2440
|
-
const sectionsDir =
|
|
2640
|
+
const sectionsDir = path10__default.default.join(getThemesDir(), theme, "sections");
|
|
2441
2641
|
if (!fs__default.default.existsSync(sectionsDir)) {
|
|
2442
2642
|
continue;
|
|
2443
2643
|
}
|
|
2444
2644
|
const sections = fs__default.default.readdirSync(sectionsDir).filter((name) => {
|
|
2445
|
-
const sectionPath =
|
|
2446
|
-
return fs__default.default.statSync(sectionPath).isDirectory() && fs__default.default.existsSync(
|
|
2645
|
+
const sectionPath = path10__default.default.join(sectionsDir, name);
|
|
2646
|
+
return fs__default.default.statSync(sectionPath).isDirectory() && fs__default.default.existsSync(path10__default.default.join(sectionPath, "index.ts"));
|
|
2447
2647
|
});
|
|
2448
2648
|
if (sections.length > 0) {
|
|
2449
2649
|
logger.log(chalk4__default.default.cyan(`
|
|
@@ -2457,11 +2657,11 @@ async function listSections(themeFilter) {
|
|
|
2457
2657
|
}
|
|
2458
2658
|
async function listBlocks(themeFilter) {
|
|
2459
2659
|
logger.section("\u{1F9F1} Blocks");
|
|
2460
|
-
const sharedBlocksDir =
|
|
2660
|
+
const sharedBlocksDir = path10__default.default.join(getFeaturesDir(), "blocks");
|
|
2461
2661
|
if (fs__default.default.existsSync(sharedBlocksDir)) {
|
|
2462
2662
|
const sharedBlocks = fs__default.default.readdirSync(sharedBlocksDir).filter((name) => {
|
|
2463
|
-
const blockPath =
|
|
2464
|
-
return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(
|
|
2663
|
+
const blockPath = path10__default.default.join(sharedBlocksDir, name);
|
|
2664
|
+
return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path10__default.default.join(blockPath, "index.ts"));
|
|
2465
2665
|
});
|
|
2466
2666
|
if (sharedBlocks.length > 0) {
|
|
2467
2667
|
logger.log(chalk4__default.default.cyan("\n Shared:"));
|
|
@@ -2472,13 +2672,13 @@ async function listBlocks(themeFilter) {
|
|
|
2472
2672
|
}
|
|
2473
2673
|
const themes = themeFilter ? [themeFilter] : listThemes();
|
|
2474
2674
|
for (const theme of themes) {
|
|
2475
|
-
const blocksDir =
|
|
2675
|
+
const blocksDir = path10__default.default.join(getThemesDir(), theme, "blocks");
|
|
2476
2676
|
if (!fs__default.default.existsSync(blocksDir)) {
|
|
2477
2677
|
continue;
|
|
2478
2678
|
}
|
|
2479
2679
|
const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => {
|
|
2480
|
-
const blockPath =
|
|
2481
|
-
return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(
|
|
2680
|
+
const blockPath = path10__default.default.join(blocksDir, name);
|
|
2681
|
+
return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path10__default.default.join(blockPath, "index.ts"));
|
|
2482
2682
|
});
|
|
2483
2683
|
if (blocks.length > 0) {
|
|
2484
2684
|
logger.log(chalk4__default.default.cyan(`
|
|
@@ -2492,14 +2692,14 @@ async function listBlocks(themeFilter) {
|
|
|
2492
2692
|
}
|
|
2493
2693
|
async function listComponents() {
|
|
2494
2694
|
logger.section("\u2699\uFE0F Components");
|
|
2495
|
-
const componentsDir =
|
|
2695
|
+
const componentsDir = path10__default.default.join(getFeaturesDir(), "components");
|
|
2496
2696
|
if (!fs__default.default.existsSync(componentsDir)) {
|
|
2497
2697
|
logger.warning("No components directory found");
|
|
2498
2698
|
return;
|
|
2499
2699
|
}
|
|
2500
2700
|
const components = fs__default.default.readdirSync(componentsDir).filter((name) => {
|
|
2501
|
-
const componentPath =
|
|
2502
|
-
return fs__default.default.statSync(componentPath).isDirectory() && fs__default.default.existsSync(
|
|
2701
|
+
const componentPath = path10__default.default.join(componentsDir, name);
|
|
2702
|
+
return fs__default.default.statSync(componentPath).isDirectory() && fs__default.default.existsSync(path10__default.default.join(componentPath, "index.ts"));
|
|
2503
2703
|
});
|
|
2504
2704
|
if (components.length === 0) {
|
|
2505
2705
|
logger.warning("No components found");
|
|
@@ -2520,11 +2720,11 @@ async function listThemesInfo() {
|
|
|
2520
2720
|
}
|
|
2521
2721
|
logger.log("");
|
|
2522
2722
|
for (const theme of themes) {
|
|
2523
|
-
const themeDir =
|
|
2723
|
+
const themeDir = path10__default.default.join(getThemesDir(), theme);
|
|
2524
2724
|
const candidates = ["theme.config.ts", "bundle-entry.ts", "manifest.ts"];
|
|
2525
2725
|
let manifestContent = "";
|
|
2526
2726
|
for (const candidate of candidates) {
|
|
2527
|
-
const candidatePath =
|
|
2727
|
+
const candidatePath = path10__default.default.join(themeDir, candidate);
|
|
2528
2728
|
if (fs__default.default.existsSync(candidatePath)) {
|
|
2529
2729
|
manifestContent = fs__default.default.readFileSync(candidatePath, "utf-8");
|
|
2530
2730
|
break;
|
|
@@ -2562,9 +2762,9 @@ async function validateCommand(options) {
|
|
|
2562
2762
|
"theme.config.ts",
|
|
2563
2763
|
"bundle-entry.ts",
|
|
2564
2764
|
"manifest.ts"
|
|
2565
|
-
].some((f) => fs__default.default.existsSync(
|
|
2765
|
+
].some((f) => fs__default.default.existsSync(path10__default.default.join(process.cwd(), f)));
|
|
2566
2766
|
if (isThemeDir) {
|
|
2567
|
-
themeToValidate =
|
|
2767
|
+
themeToValidate = path10__default.default.basename(process.cwd());
|
|
2568
2768
|
logger.info(`Validating current theme: ${themeToValidate}`);
|
|
2569
2769
|
} else {
|
|
2570
2770
|
logger.error(
|
|
@@ -2573,11 +2773,11 @@ async function validateCommand(options) {
|
|
|
2573
2773
|
process.exit(1);
|
|
2574
2774
|
}
|
|
2575
2775
|
}
|
|
2576
|
-
const themePath =
|
|
2776
|
+
const themePath = path10__default.default.join(getThemesDir(), themeToValidate);
|
|
2577
2777
|
logger.startSpinner("Running validation checks...");
|
|
2578
2778
|
const entryFiles = ["manifest.ts", "theme.config.ts", "bundle-entry.ts"];
|
|
2579
2779
|
const foundEntry = entryFiles.find(
|
|
2580
|
-
(f) => fs__default.default.existsSync(
|
|
2780
|
+
(f) => fs__default.default.existsSync(path10__default.default.join(themePath, f))
|
|
2581
2781
|
);
|
|
2582
2782
|
if (!foundEntry) {
|
|
2583
2783
|
issues.push({
|
|
@@ -2587,7 +2787,7 @@ async function validateCommand(options) {
|
|
|
2587
2787
|
});
|
|
2588
2788
|
} else if (foundEntry === "manifest.ts") {
|
|
2589
2789
|
const manifestContent = fs__default.default.readFileSync(
|
|
2590
|
-
|
|
2790
|
+
path10__default.default.join(themePath, foundEntry),
|
|
2591
2791
|
"utf-8"
|
|
2592
2792
|
);
|
|
2593
2793
|
if (!manifestContent.includes("export const") && !manifestContent.includes("export default") && !manifestContent.includes("export interface")) {
|
|
@@ -2598,7 +2798,7 @@ async function validateCommand(options) {
|
|
|
2598
2798
|
});
|
|
2599
2799
|
}
|
|
2600
2800
|
}
|
|
2601
|
-
const configPath =
|
|
2801
|
+
const configPath = path10__default.default.join(themePath, "theme.config.ts");
|
|
2602
2802
|
if (!fs__default.default.existsSync(configPath)) {
|
|
2603
2803
|
issues.push({
|
|
2604
2804
|
type: "warning",
|
|
@@ -2606,7 +2806,7 @@ async function validateCommand(options) {
|
|
|
2606
2806
|
message: "Theme config file not found (recommended)"
|
|
2607
2807
|
});
|
|
2608
2808
|
}
|
|
2609
|
-
const indexPath =
|
|
2809
|
+
const indexPath = path10__default.default.join(themePath, "index.ts");
|
|
2610
2810
|
if (!fs__default.default.existsSync(indexPath)) {
|
|
2611
2811
|
issues.push({
|
|
2612
2812
|
type: "warning",
|
|
@@ -2614,7 +2814,7 @@ async function validateCommand(options) {
|
|
|
2614
2814
|
message: "Index file not found (recommended)"
|
|
2615
2815
|
});
|
|
2616
2816
|
}
|
|
2617
|
-
const sectionsDir =
|
|
2817
|
+
const sectionsDir = path10__default.default.join(themePath, "sections");
|
|
2618
2818
|
if (!fs__default.default.existsSync(sectionsDir)) {
|
|
2619
2819
|
issues.push({
|
|
2620
2820
|
type: "warning",
|
|
@@ -2623,16 +2823,16 @@ async function validateCommand(options) {
|
|
|
2623
2823
|
});
|
|
2624
2824
|
} else {
|
|
2625
2825
|
const sections = fs__default.default.readdirSync(sectionsDir).filter(
|
|
2626
|
-
(name) => fs__default.default.statSync(
|
|
2826
|
+
(name) => fs__default.default.statSync(path10__default.default.join(sectionsDir, name)).isDirectory()
|
|
2627
2827
|
);
|
|
2628
2828
|
for (const sectionName of sections) {
|
|
2629
|
-
const sectionPath =
|
|
2630
|
-
const schemaFile =
|
|
2631
|
-
const defaultTemplate =
|
|
2829
|
+
const sectionPath = path10__default.default.join(sectionsDir, sectionName);
|
|
2830
|
+
const schemaFile = path10__default.default.join(sectionPath, `${sectionName}.schema.ts`);
|
|
2831
|
+
const defaultTemplate = path10__default.default.join(
|
|
2632
2832
|
sectionPath,
|
|
2633
2833
|
`${sectionName}-default.tsx`
|
|
2634
2834
|
);
|
|
2635
|
-
const indexFile =
|
|
2835
|
+
const indexFile = path10__default.default.join(sectionPath, "index.ts");
|
|
2636
2836
|
if (!fs__default.default.existsSync(schemaFile)) {
|
|
2637
2837
|
issues.push({
|
|
2638
2838
|
type: "error",
|
|
@@ -2656,14 +2856,14 @@ async function validateCommand(options) {
|
|
|
2656
2856
|
}
|
|
2657
2857
|
}
|
|
2658
2858
|
}
|
|
2659
|
-
const blocksDir =
|
|
2859
|
+
const blocksDir = path10__default.default.join(themePath, "blocks");
|
|
2660
2860
|
if (fs__default.default.existsSync(blocksDir)) {
|
|
2661
|
-
const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => fs__default.default.statSync(
|
|
2861
|
+
const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => fs__default.default.statSync(path10__default.default.join(blocksDir, name)).isDirectory());
|
|
2662
2862
|
for (const blockName of blocks) {
|
|
2663
|
-
const blockPath =
|
|
2664
|
-
const schemaFile =
|
|
2665
|
-
const componentFile =
|
|
2666
|
-
const indexFile =
|
|
2863
|
+
const blockPath = path10__default.default.join(blocksDir, blockName);
|
|
2864
|
+
const schemaFile = path10__default.default.join(blockPath, `${blockName}.schema.ts`);
|
|
2865
|
+
const componentFile = path10__default.default.join(blockPath, `${blockName}.tsx`);
|
|
2866
|
+
const indexFile = path10__default.default.join(blockPath, "index.ts");
|
|
2667
2867
|
if (!fs__default.default.existsSync(schemaFile)) {
|
|
2668
2868
|
issues.push({
|
|
2669
2869
|
type: "error",
|
|
@@ -2689,13 +2889,13 @@ async function validateCommand(options) {
|
|
|
2689
2889
|
}
|
|
2690
2890
|
if (fs__default.default.existsSync(sectionsDir)) {
|
|
2691
2891
|
const sections = fs__default.default.readdirSync(sectionsDir).filter(
|
|
2692
|
-
(name) => fs__default.default.statSync(
|
|
2892
|
+
(name) => fs__default.default.statSync(path10__default.default.join(sectionsDir, name)).isDirectory()
|
|
2693
2893
|
);
|
|
2694
2894
|
for (const sectionName of sections) {
|
|
2695
|
-
const sectionPath =
|
|
2895
|
+
const sectionPath = path10__default.default.join(sectionsDir, sectionName);
|
|
2696
2896
|
const tsxFiles = fs__default.default.readdirSync(sectionPath).filter((f) => f.endsWith(".tsx") && !f.endsWith(".schema.ts"));
|
|
2697
2897
|
for (const tsxFile of tsxFiles) {
|
|
2698
|
-
const filePath =
|
|
2898
|
+
const filePath = path10__default.default.join(sectionPath, tsxFile);
|
|
2699
2899
|
const content = fs__default.default.readFileSync(filePath, "utf-8");
|
|
2700
2900
|
const relPath = `sections/${sectionName}/${tsxFile}`;
|
|
2701
2901
|
if (!content.includes('"use client"') && !content.includes("'use client'")) {
|
|
@@ -2743,23 +2943,46 @@ async function validateCommand(options) {
|
|
|
2743
2943
|
}
|
|
2744
2944
|
}
|
|
2745
2945
|
}
|
|
2746
|
-
const registryPath =
|
|
2747
|
-
const bundleEntryPath =
|
|
2946
|
+
const registryPath = path10__default.default.join(themePath, "sections-registry.ts");
|
|
2947
|
+
const bundleEntryPath = path10__default.default.join(themePath, "bundle-entry.ts");
|
|
2748
2948
|
const registryContent = fs__default.default.existsSync(registryPath) ? fs__default.default.readFileSync(registryPath, "utf-8") : fs__default.default.existsSync(bundleEntryPath) ? fs__default.default.readFileSync(bundleEntryPath, "utf-8") : "";
|
|
2749
2949
|
if (fs__default.default.existsSync(sectionsDir) && registryContent) {
|
|
2750
2950
|
const sections = fs__default.default.readdirSync(sectionsDir).filter(
|
|
2751
|
-
(name) => fs__default.default.statSync(
|
|
2951
|
+
(name) => fs__default.default.statSync(path10__default.default.join(sectionsDir, name)).isDirectory()
|
|
2752
2952
|
);
|
|
2753
2953
|
for (const sectionName of sections) {
|
|
2754
2954
|
if (!registryContent.includes(`sections/${sectionName}`) && !registryContent.includes(`"${sectionName}"`)) {
|
|
2755
2955
|
issues.push({
|
|
2756
|
-
type: "
|
|
2956
|
+
type: "error",
|
|
2757
2957
|
file: `sections/${sectionName}/`,
|
|
2758
|
-
message: "Section not
|
|
2958
|
+
message: "Section not exported in sections-registry.ts or bundle-entry.ts \u2014 will not be included in build"
|
|
2759
2959
|
});
|
|
2760
2960
|
}
|
|
2761
2961
|
}
|
|
2762
2962
|
}
|
|
2963
|
+
if (fs__default.default.existsSync(sectionsDir)) {
|
|
2964
|
+
const schemaTypes = await loadSchemaTypes(themePath, sectionsDir);
|
|
2965
|
+
for (const { folderName, schemaType } of schemaTypes) {
|
|
2966
|
+
if (schemaType && schemaType !== folderName) {
|
|
2967
|
+
issues.push({
|
|
2968
|
+
type: "error",
|
|
2969
|
+
file: `sections/${folderName}/${folderName}.schema.ts`,
|
|
2970
|
+
message: `Schema type "${schemaType}" doesn't match folder name "${folderName}". Rename folder to "${schemaType}/" or change schema type to "${folderName}".`
|
|
2971
|
+
});
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
const pagesDir = path10__default.default.join(themePath, "pages");
|
|
2975
|
+
if (fs__default.default.existsSync(pagesDir)) {
|
|
2976
|
+
const allSchemaTypeSet = new Set(
|
|
2977
|
+
schemaTypes.map((s) => s.schemaType || s.folderName)
|
|
2978
|
+
);
|
|
2979
|
+
const pageIssues = await validatePageSectionTypes(
|
|
2980
|
+
pagesDir,
|
|
2981
|
+
allSchemaTypeSet
|
|
2982
|
+
);
|
|
2983
|
+
issues.push(...pageIssues);
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2763
2986
|
logger.stopSpinner(true, "Validation complete");
|
|
2764
2987
|
const errors = issues.filter((i) => i.type === "error");
|
|
2765
2988
|
const warnings = issues.filter((i) => i.type === "warning");
|
|
@@ -2798,6 +3021,83 @@ async function validateCommand(options) {
|
|
|
2798
3021
|
}
|
|
2799
3022
|
}
|
|
2800
3023
|
}
|
|
3024
|
+
async function loadSchemaTypes(themePath, sectionsDir) {
|
|
3025
|
+
const results = [];
|
|
3026
|
+
const sections = fs__default.default.readdirSync(sectionsDir).filter((name) => fs__default.default.statSync(path10__default.default.join(sectionsDir, name)).isDirectory());
|
|
3027
|
+
for (const sectionName of sections) {
|
|
3028
|
+
const schemaFile = path10__default.default.join(
|
|
3029
|
+
sectionsDir,
|
|
3030
|
+
sectionName,
|
|
3031
|
+
`${sectionName}.schema.ts`
|
|
3032
|
+
);
|
|
3033
|
+
if (!fs__default.default.existsSync(schemaFile)) {
|
|
3034
|
+
results.push({ folderName: sectionName, schemaType: null });
|
|
3035
|
+
continue;
|
|
3036
|
+
}
|
|
3037
|
+
const content = fs__default.default.readFileSync(schemaFile, "utf-8");
|
|
3038
|
+
const typeMatch = content.match(/\btype:\s*["']([^"']+)["']/);
|
|
3039
|
+
results.push({
|
|
3040
|
+
folderName: sectionName,
|
|
3041
|
+
schemaType: typeMatch ? typeMatch[1] : null
|
|
3042
|
+
});
|
|
3043
|
+
}
|
|
3044
|
+
return results;
|
|
3045
|
+
}
|
|
3046
|
+
async function validatePageSectionTypes(pagesDir, validTypes) {
|
|
3047
|
+
const issues = [];
|
|
3048
|
+
const files = fs__default.default.readdirSync(pagesDir).filter((f) => f.match(/\.(ts|js)$/));
|
|
3049
|
+
for (const file of files) {
|
|
3050
|
+
const content = fs__default.default.readFileSync(path10__default.default.join(pagesDir, file), "utf-8");
|
|
3051
|
+
const pageName = file.replace(/\.(ts|js)$/, "");
|
|
3052
|
+
const typeMatches = content.matchAll(/\btype:\s*["']([^"']+)["']/g);
|
|
3053
|
+
for (const match of typeMatches) {
|
|
3054
|
+
const sectionType = match[1];
|
|
3055
|
+
if (isFieldType(sectionType)) continue;
|
|
3056
|
+
if (!validTypes.has(sectionType)) {
|
|
3057
|
+
issues.push({
|
|
3058
|
+
type: "error",
|
|
3059
|
+
file: `pages/${file}`,
|
|
3060
|
+
message: `Page "${pageName}" uses section type "${sectionType}" which doesn't exist in sections/`
|
|
3061
|
+
});
|
|
3062
|
+
}
|
|
3063
|
+
}
|
|
3064
|
+
}
|
|
3065
|
+
return issues;
|
|
3066
|
+
}
|
|
3067
|
+
var FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
3068
|
+
"text",
|
|
3069
|
+
"textarea",
|
|
3070
|
+
"richtext",
|
|
3071
|
+
"number",
|
|
3072
|
+
"range",
|
|
3073
|
+
"toggle",
|
|
3074
|
+
"switch",
|
|
3075
|
+
"select",
|
|
3076
|
+
"radio",
|
|
3077
|
+
"checkbox",
|
|
3078
|
+
"color",
|
|
3079
|
+
"image",
|
|
3080
|
+
"video",
|
|
3081
|
+
"url",
|
|
3082
|
+
"link",
|
|
3083
|
+
"icon",
|
|
3084
|
+
"date",
|
|
3085
|
+
"datetime",
|
|
3086
|
+
"collection",
|
|
3087
|
+
"product",
|
|
3088
|
+
"blog",
|
|
3089
|
+
"page",
|
|
3090
|
+
"html",
|
|
3091
|
+
"code",
|
|
3092
|
+
"json",
|
|
3093
|
+
"array",
|
|
3094
|
+
"object",
|
|
3095
|
+
"group",
|
|
3096
|
+
"section"
|
|
3097
|
+
]);
|
|
3098
|
+
function isFieldType(type) {
|
|
3099
|
+
return FIELD_TYPES.has(type);
|
|
3100
|
+
}
|
|
2801
3101
|
|
|
2802
3102
|
// src/commands/build.ts
|
|
2803
3103
|
init_logger();
|
|
@@ -2808,14 +3108,14 @@ async function buildCommand(options) {
|
|
|
2808
3108
|
if (options.theme) {
|
|
2809
3109
|
themeName = options.theme;
|
|
2810
3110
|
try {
|
|
2811
|
-
const workspaceThemePath =
|
|
3111
|
+
const workspaceThemePath = path10__default.default.join(getThemesDir(), themeName);
|
|
2812
3112
|
if (fs__default.default.existsSync(workspaceThemePath)) {
|
|
2813
3113
|
themePath = workspaceThemePath;
|
|
2814
3114
|
} else {
|
|
2815
|
-
themePath =
|
|
3115
|
+
themePath = path10__default.default.join(process.cwd(), themeName);
|
|
2816
3116
|
}
|
|
2817
3117
|
} catch {
|
|
2818
|
-
themePath =
|
|
3118
|
+
themePath = path10__default.default.join(process.cwd(), themeName);
|
|
2819
3119
|
}
|
|
2820
3120
|
if (!fs__default.default.existsSync(themePath)) {
|
|
2821
3121
|
logger.error(`Theme "${themeName}" not found.`);
|
|
@@ -2826,10 +3126,10 @@ async function buildCommand(options) {
|
|
|
2826
3126
|
"theme.config.ts",
|
|
2827
3127
|
"bundle-entry.ts",
|
|
2828
3128
|
"manifest.ts"
|
|
2829
|
-
].some((f) => fs__default.default.existsSync(
|
|
3129
|
+
].some((f) => fs__default.default.existsSync(path10__default.default.join(process.cwd(), f)));
|
|
2830
3130
|
if (isThemeDir) {
|
|
2831
3131
|
themePath = process.cwd();
|
|
2832
|
-
themeName =
|
|
3132
|
+
themeName = path10__default.default.basename(themePath);
|
|
2833
3133
|
logger.info(`Building current theme: ${themeName}`);
|
|
2834
3134
|
} else {
|
|
2835
3135
|
logger.error(
|
|
@@ -2838,7 +3138,7 @@ async function buildCommand(options) {
|
|
|
2838
3138
|
process.exit(1);
|
|
2839
3139
|
}
|
|
2840
3140
|
}
|
|
2841
|
-
const packageJsonPath =
|
|
3141
|
+
const packageJsonPath = path10__default.default.join(themePath, "package.json");
|
|
2842
3142
|
const hasPkgJson = fs__default.default.existsSync(packageJsonPath);
|
|
2843
3143
|
if (!hasPkgJson) {
|
|
2844
3144
|
logger.warning(
|
|
@@ -2894,9 +3194,9 @@ async function buildCommand(options) {
|
|
|
2894
3194
|
logger.success("\u2713 Theme built successfully!");
|
|
2895
3195
|
logger.newLine();
|
|
2896
3196
|
logger.info(`Theme: ${themeName}`);
|
|
2897
|
-
const distPath =
|
|
3197
|
+
const distPath = path10__default.default.join(themePath, "dist");
|
|
2898
3198
|
if (fs__default.default.existsSync(distPath)) {
|
|
2899
|
-
logger.log(`Output: ${
|
|
3199
|
+
logger.log(`Output: ${path10__default.default.relative(process.cwd(), distPath)}`);
|
|
2900
3200
|
const files = fs__default.default.readdirSync(distPath);
|
|
2901
3201
|
logger.log(`Files: ${files.length}`);
|
|
2902
3202
|
}
|
|
@@ -2904,17 +3204,17 @@ async function buildCommand(options) {
|
|
|
2904
3204
|
}
|
|
2905
3205
|
function runCommand(command, args, cwd) {
|
|
2906
3206
|
return new Promise((resolve) => {
|
|
2907
|
-
const proc =
|
|
3207
|
+
const proc = spawn2__default.default(command, args, {
|
|
2908
3208
|
cwd,
|
|
2909
3209
|
stdio: ["pipe", "pipe", "pipe"],
|
|
2910
3210
|
shell: true
|
|
2911
3211
|
});
|
|
2912
3212
|
let stdout = "";
|
|
2913
3213
|
let stderr = "";
|
|
2914
|
-
proc.stdout
|
|
3214
|
+
proc.stdout?.on("data", (data) => {
|
|
2915
3215
|
stdout += data.toString();
|
|
2916
3216
|
});
|
|
2917
|
-
proc.stderr
|
|
3217
|
+
proc.stderr?.on("data", (data) => {
|
|
2918
3218
|
stderr += data.toString();
|
|
2919
3219
|
});
|
|
2920
3220
|
proc.on("close", (code) => {
|
|
@@ -2952,7 +3252,7 @@ async function packageCommand(options) {
|
|
|
2952
3252
|
let themeName;
|
|
2953
3253
|
if (options.theme) {
|
|
2954
3254
|
themeName = options.theme;
|
|
2955
|
-
themePath =
|
|
3255
|
+
themePath = path10__default.default.join(getThemesDir(), themeName);
|
|
2956
3256
|
if (!fs__default.default.existsSync(themePath)) {
|
|
2957
3257
|
logger.error(`Theme "${themeName}" not found.`);
|
|
2958
3258
|
process.exit(1);
|
|
@@ -2962,10 +3262,10 @@ async function packageCommand(options) {
|
|
|
2962
3262
|
"theme.config.ts",
|
|
2963
3263
|
"bundle-entry.ts",
|
|
2964
3264
|
"manifest.ts"
|
|
2965
|
-
].some((f) => fs__default.default.existsSync(
|
|
3265
|
+
].some((f) => fs__default.default.existsSync(path10__default.default.join(process.cwd(), f)));
|
|
2966
3266
|
if (isThemeDir) {
|
|
2967
3267
|
themePath = process.cwd();
|
|
2968
|
-
themeName =
|
|
3268
|
+
themeName = path10__default.default.basename(themePath);
|
|
2969
3269
|
logger.info(`Packaging current theme: ${themeName}`);
|
|
2970
3270
|
} else {
|
|
2971
3271
|
logger.error(
|
|
@@ -2974,7 +3274,7 @@ async function packageCommand(options) {
|
|
|
2974
3274
|
process.exit(1);
|
|
2975
3275
|
}
|
|
2976
3276
|
}
|
|
2977
|
-
const packageJsonPath =
|
|
3277
|
+
const packageJsonPath = path10__default.default.join(themePath, "package.json");
|
|
2978
3278
|
let version2 = "1.0.0";
|
|
2979
3279
|
if (fs__default.default.existsSync(packageJsonPath)) {
|
|
2980
3280
|
const packageJson = await fs__default.default.readJson(packageJsonPath);
|
|
@@ -2984,7 +3284,7 @@ async function packageCommand(options) {
|
|
|
2984
3284
|
logger.info(`Theme: ${themeName}`);
|
|
2985
3285
|
logger.info(`Version: ${version2}`);
|
|
2986
3286
|
logger.newLine();
|
|
2987
|
-
const compiledThemePath =
|
|
3287
|
+
const compiledThemePath = path10__default.default.join(
|
|
2988
3288
|
process.cwd(),
|
|
2989
3289
|
"themes",
|
|
2990
3290
|
themeName,
|
|
@@ -3018,8 +3318,8 @@ async function packageCommand(options) {
|
|
|
3018
3318
|
logger.newLine();
|
|
3019
3319
|
logger.section("Step 2: Create Package");
|
|
3020
3320
|
const packageName = options.name || `${themeName}-${version2}`;
|
|
3021
|
-
const outputDir = options.output ||
|
|
3022
|
-
const outputPath =
|
|
3321
|
+
const outputDir = options.output || path10__default.default.join(process.cwd(), "dist");
|
|
3322
|
+
const outputPath = path10__default.default.join(outputDir, `${packageName}.zip`);
|
|
3023
3323
|
await fs__default.default.ensureDir(outputDir);
|
|
3024
3324
|
logger.startSpinner("Creating zip archive...");
|
|
3025
3325
|
try {
|
|
@@ -3032,11 +3332,11 @@ async function packageCommand(options) {
|
|
|
3032
3332
|
logger.newLine();
|
|
3033
3333
|
logger.info(`Package: ${packageName}.zip`);
|
|
3034
3334
|
logger.log(`Size: ${sizeMB} MB`);
|
|
3035
|
-
logger.log(`Location: ${
|
|
3335
|
+
logger.log(`Location: ${path10__default.default.relative(process.cwd(), outputPath)}`);
|
|
3036
3336
|
logger.newLine();
|
|
3037
3337
|
logger.section("Next steps:");
|
|
3038
3338
|
logger.log(
|
|
3039
|
-
` onexthm deploy --package ${
|
|
3339
|
+
` onexthm deploy --package ${path10__default.default.relative(process.cwd(), outputPath)}`
|
|
3040
3340
|
);
|
|
3041
3341
|
} catch (error) {
|
|
3042
3342
|
logger.stopSpinner(false, "Failed to create package");
|
|
@@ -3048,13 +3348,13 @@ async function packageCommand(options) {
|
|
|
3048
3348
|
}
|
|
3049
3349
|
function runCommand2(command, args) {
|
|
3050
3350
|
return new Promise((resolve) => {
|
|
3051
|
-
const proc =
|
|
3351
|
+
const proc = spawn2__default.default(command, args, {
|
|
3052
3352
|
cwd: process.cwd(),
|
|
3053
3353
|
stdio: "pipe",
|
|
3054
3354
|
shell: true
|
|
3055
3355
|
});
|
|
3056
3356
|
let hasError = false;
|
|
3057
|
-
proc.stderr
|
|
3357
|
+
proc.stderr?.on("data", (data) => {
|
|
3058
3358
|
const message = data.toString();
|
|
3059
3359
|
if (message.includes("error") || message.includes("Error") || message.includes("ERROR")) {
|
|
3060
3360
|
hasError = true;
|
|
@@ -3094,9 +3394,9 @@ async function deployCommand(options) {
|
|
|
3094
3394
|
ensureOneXProject();
|
|
3095
3395
|
let packagePath;
|
|
3096
3396
|
if (options.package) {
|
|
3097
|
-
packagePath =
|
|
3397
|
+
packagePath = path10__default.default.resolve(options.package);
|
|
3098
3398
|
} else if (options.theme) {
|
|
3099
|
-
const distDir =
|
|
3399
|
+
const distDir = path10__default.default.join(process.cwd(), "dist");
|
|
3100
3400
|
if (!fs__default.default.existsSync(distDir)) {
|
|
3101
3401
|
logger.error("No dist/ directory found. Run 'onexthm package' first.");
|
|
3102
3402
|
process.exit(1);
|
|
@@ -3111,7 +3411,7 @@ async function deployCommand(options) {
|
|
|
3111
3411
|
process.exit(1);
|
|
3112
3412
|
}
|
|
3113
3413
|
packageFiles.sort().reverse();
|
|
3114
|
-
packagePath =
|
|
3414
|
+
packagePath = path10__default.default.join(distDir, packageFiles[0]);
|
|
3115
3415
|
} else {
|
|
3116
3416
|
logger.error("Either --package or --theme must be specified.");
|
|
3117
3417
|
logger.info("Examples:");
|
|
@@ -3125,11 +3425,11 @@ async function deployCommand(options) {
|
|
|
3125
3425
|
}
|
|
3126
3426
|
const stats = await fs__default.default.stat(packagePath);
|
|
3127
3427
|
const sizeMB = (stats.size / 1024 / 1024).toFixed(2);
|
|
3128
|
-
const fileName =
|
|
3428
|
+
const fileName = path10__default.default.basename(packagePath);
|
|
3129
3429
|
logger.newLine();
|
|
3130
3430
|
logger.info(`Package: ${fileName}`);
|
|
3131
3431
|
logger.log(`Size: ${sizeMB} MB`);
|
|
3132
|
-
logger.log(`Path: ${
|
|
3432
|
+
logger.log(`Path: ${path10__default.default.relative(process.cwd(), packagePath)}`);
|
|
3133
3433
|
logger.newLine();
|
|
3134
3434
|
const apiUrl = options.apiUrl || process.env.ONEX_API_URL || "http://localhost:3001";
|
|
3135
3435
|
const uploadEndpoint = `${apiUrl}/website-api/themes/upload`;
|
|
@@ -3233,11 +3533,11 @@ function getBucketName(env) {
|
|
|
3233
3533
|
return environment === "production" ? "theme-s3-bucket" : "theme-s3-bucket";
|
|
3234
3534
|
}
|
|
3235
3535
|
async function findCompiledThemeDir(themeId, version2) {
|
|
3236
|
-
const searchPaths = [
|
|
3536
|
+
const searchPaths = [path10__default.default.resolve(process.cwd(), "dist")];
|
|
3237
3537
|
for (const dir of searchPaths) {
|
|
3238
3538
|
if (await fs__default.default.pathExists(dir)) {
|
|
3239
|
-
const hasManifest = await fs__default.default.pathExists(
|
|
3240
|
-
const hasThemeEntry = await fs__default.default.pathExists(
|
|
3539
|
+
const hasManifest = await fs__default.default.pathExists(path10__default.default.join(dir, "manifest.json"));
|
|
3540
|
+
const hasThemeEntry = await fs__default.default.pathExists(path10__default.default.join(dir, "bundle-entry.js")) || await fs__default.default.pathExists(path10__default.default.join(dir, "theme.config.js")) || await fs__default.default.pathExists(path10__default.default.join(dir, "index.js"));
|
|
3241
3541
|
if (hasManifest || hasThemeEntry) {
|
|
3242
3542
|
return dir;
|
|
3243
3543
|
}
|
|
@@ -3246,7 +3546,7 @@ async function findCompiledThemeDir(themeId, version2) {
|
|
|
3246
3546
|
return null;
|
|
3247
3547
|
}
|
|
3248
3548
|
async function readManifest() {
|
|
3249
|
-
const manifestTsPath =
|
|
3549
|
+
const manifestTsPath = path10__default.default.resolve(process.cwd(), "manifest.ts");
|
|
3250
3550
|
if (await fs__default.default.pathExists(manifestTsPath)) {
|
|
3251
3551
|
try {
|
|
3252
3552
|
const module = await import(manifestTsPath);
|
|
@@ -3255,7 +3555,7 @@ async function readManifest() {
|
|
|
3255
3555
|
logger.warning("Failed to import manifest.ts, trying package.json");
|
|
3256
3556
|
}
|
|
3257
3557
|
}
|
|
3258
|
-
const packageJsonPath =
|
|
3558
|
+
const packageJsonPath = path10__default.default.resolve(process.cwd(), "package.json");
|
|
3259
3559
|
if (await fs__default.default.pathExists(packageJsonPath)) {
|
|
3260
3560
|
const pkg = await fs__default.default.readJson(packageJsonPath);
|
|
3261
3561
|
return {
|
|
@@ -3289,13 +3589,13 @@ async function findSourceDir(themeId, explicitDir) {
|
|
|
3289
3589
|
}
|
|
3290
3590
|
const searchPaths = [
|
|
3291
3591
|
process.cwd(),
|
|
3292
|
-
|
|
3293
|
-
|
|
3592
|
+
path10__default.default.resolve(process.cwd(), `../../themes/${themeId}`),
|
|
3593
|
+
path10__default.default.resolve(process.cwd(), `../themes/${themeId}`)
|
|
3294
3594
|
];
|
|
3295
3595
|
const markers = ["theme.config.ts", "bundle-entry.ts"];
|
|
3296
3596
|
for (const dir of searchPaths) {
|
|
3297
3597
|
for (const marker of markers) {
|
|
3298
|
-
if (await fs__default.default.pathExists(
|
|
3598
|
+
if (await fs__default.default.pathExists(path10__default.default.join(dir, marker))) {
|
|
3299
3599
|
return dir;
|
|
3300
3600
|
}
|
|
3301
3601
|
}
|
|
@@ -3346,8 +3646,8 @@ async function uploadCommand(options) {
|
|
|
3346
3646
|
}
|
|
3347
3647
|
spinner.succeed(`Found compiled theme at: ${compiledDir}`);
|
|
3348
3648
|
spinner.start("Creating bundle.zip...");
|
|
3349
|
-
const tmpDir =
|
|
3350
|
-
const bundleZipPath =
|
|
3649
|
+
const tmpDir = os__default.default.tmpdir();
|
|
3650
|
+
const bundleZipPath = path10__default.default.join(tmpDir, `${themeId}-${version2}-bundle.zip`);
|
|
3351
3651
|
await createZipFromDir(compiledDir, bundleZipPath);
|
|
3352
3652
|
const bundleZipBuffer = await fs__default.default.readFile(bundleZipPath);
|
|
3353
3653
|
const bundleSizeMB = (bundleZipBuffer.length / 1024 / 1024).toFixed(2);
|
|
@@ -3401,7 +3701,7 @@ async function uploadCommand(options) {
|
|
|
3401
3701
|
if (sourceDir) {
|
|
3402
3702
|
spinner.succeed(`Found source at: ${sourceDir}`);
|
|
3403
3703
|
spinner.start("Creating source.zip...");
|
|
3404
|
-
const sourceZipPath =
|
|
3704
|
+
const sourceZipPath = path10__default.default.join(
|
|
3405
3705
|
tmpDir,
|
|
3406
3706
|
`${themeId}-${version2}-source.zip`
|
|
3407
3707
|
);
|
|
@@ -3535,8 +3835,8 @@ async function resolveLatestVersion(s3Client, bucket, themeId) {
|
|
|
3535
3835
|
async function createCompatibilityFiles(outputDir, manifest) {
|
|
3536
3836
|
const entryFile = manifest.output?.entry || "bundle-entry.js";
|
|
3537
3837
|
if (entryFile !== "bundle-entry.js" && entryFile.startsWith("bundle-entry-")) {
|
|
3538
|
-
const hashedPath =
|
|
3539
|
-
const stablePath =
|
|
3838
|
+
const hashedPath = path10__default.default.join(outputDir, entryFile);
|
|
3839
|
+
const stablePath = path10__default.default.join(outputDir, "bundle-entry.js");
|
|
3540
3840
|
if (await fs__default.default.pathExists(hashedPath)) {
|
|
3541
3841
|
await fs__default.default.copy(hashedPath, stablePath);
|
|
3542
3842
|
const mapPath = hashedPath + ".map";
|
|
@@ -3545,13 +3845,13 @@ async function createCompatibilityFiles(outputDir, manifest) {
|
|
|
3545
3845
|
}
|
|
3546
3846
|
}
|
|
3547
3847
|
}
|
|
3548
|
-
const sectionsRegistryPath =
|
|
3848
|
+
const sectionsRegistryPath = path10__default.default.join(outputDir, "sections-registry.js");
|
|
3549
3849
|
const content = `// Re-export all sections from bundle-entry
|
|
3550
3850
|
// This file exists to maintain compatibility with the import path
|
|
3551
3851
|
export * from './bundle-entry.js';
|
|
3552
3852
|
`;
|
|
3553
3853
|
await fs__default.default.writeFile(sectionsRegistryPath, content, "utf-8");
|
|
3554
|
-
const pkgJsonPath =
|
|
3854
|
+
const pkgJsonPath = path10__default.default.join(outputDir, "package.json");
|
|
3555
3855
|
await fs__default.default.writeFile(pkgJsonPath, '{\n "type": "module"\n}\n', "utf-8");
|
|
3556
3856
|
}
|
|
3557
3857
|
function showDownloadFailureHelp(themeId, bucket) {
|
|
@@ -3613,6 +3913,18 @@ async function downloadCommand(options) {
|
|
|
3613
3913
|
spinner.succeed(
|
|
3614
3914
|
`Resolved latest version: ${chalk4__default.default.cyan(resolvedVersion)}`
|
|
3615
3915
|
);
|
|
3916
|
+
const isCI = !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.VERCEL);
|
|
3917
|
+
if (isCI) {
|
|
3918
|
+
console.log(
|
|
3919
|
+
chalk4__default.default.yellow(
|
|
3920
|
+
`
|
|
3921
|
+
Warning: Resolved "latest" to ${resolvedVersion} in CI environment.
|
|
3922
|
+
For production builds, pin to a specific version:
|
|
3923
|
+
THEME_VERSION=${resolvedVersion}
|
|
3924
|
+
`
|
|
3925
|
+
)
|
|
3926
|
+
);
|
|
3927
|
+
}
|
|
3616
3928
|
}
|
|
3617
3929
|
spinner.start(
|
|
3618
3930
|
`Downloading bundle.zip for ${themeId}@${resolvedVersion}...`
|
|
@@ -3634,7 +3946,7 @@ async function downloadCommand(options) {
|
|
|
3634
3946
|
zip.extractAllTo(outputDir, true);
|
|
3635
3947
|
const entries = zip.getEntries().filter((e) => !e.isDirectory);
|
|
3636
3948
|
spinner.succeed(`Extracted ${entries.length} files to ${outputDir}`);
|
|
3637
|
-
const manifestPath =
|
|
3949
|
+
const manifestPath = path10__default.default.join(outputDir, "manifest.json");
|
|
3638
3950
|
const manifest = await fs__default.default.readJson(manifestPath);
|
|
3639
3951
|
await createCompatibilityFiles(outputDir, manifest);
|
|
3640
3952
|
console.log();
|
|
@@ -3734,10 +4046,9 @@ async function resolveLatestVersion2(s3Client, bucket, themeId) {
|
|
|
3734
4046
|
}
|
|
3735
4047
|
function runInstall(cwd) {
|
|
3736
4048
|
return new Promise((resolve) => {
|
|
3737
|
-
const proc =
|
|
4049
|
+
const proc = spawn2__default.default("pnpm", ["install"], {
|
|
3738
4050
|
cwd,
|
|
3739
|
-
stdio: "inherit"
|
|
3740
|
-
shell: true
|
|
4051
|
+
stdio: "inherit"
|
|
3741
4052
|
});
|
|
3742
4053
|
proc.on("close", (code) => resolve(code === 0));
|
|
3743
4054
|
proc.on("error", () => resolve(false));
|
|
@@ -3768,7 +4079,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3768
4079
|
const oldPrefix = `${oldName}-`;
|
|
3769
4080
|
const newPrefix = `${newName}-`;
|
|
3770
4081
|
const newDisplayName = newName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3771
|
-
const pkgPath =
|
|
4082
|
+
const pkgPath = path10__default.default.join(themeDir, "package.json");
|
|
3772
4083
|
if (await fs__default.default.pathExists(pkgPath)) {
|
|
3773
4084
|
const pkg = await fs__default.default.readJson(pkgPath);
|
|
3774
4085
|
pkg.name = `@onex-themes/${newName}`;
|
|
@@ -3784,7 +4095,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3784
4095
|
}
|
|
3785
4096
|
await fs__default.default.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
3786
4097
|
}
|
|
3787
|
-
const configPath =
|
|
4098
|
+
const configPath = path10__default.default.join(themeDir, "theme.config.ts");
|
|
3788
4099
|
if (await fs__default.default.pathExists(configPath)) {
|
|
3789
4100
|
let content = await fs__default.default.readFile(configPath, "utf-8");
|
|
3790
4101
|
content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
|
|
@@ -3794,7 +4105,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3794
4105
|
);
|
|
3795
4106
|
await fs__default.default.writeFile(configPath, content);
|
|
3796
4107
|
}
|
|
3797
|
-
const layoutPath =
|
|
4108
|
+
const layoutPath = path10__default.default.join(themeDir, "theme.layout.ts");
|
|
3798
4109
|
if (await fs__default.default.pathExists(layoutPath)) {
|
|
3799
4110
|
let content = await fs__default.default.readFile(layoutPath, "utf-8");
|
|
3800
4111
|
content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
|
|
@@ -3807,7 +4118,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3807
4118
|
const oldDisplayName = oldName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3808
4119
|
const tsFiles = await glob.glob("**/*.ts", { cwd: themeDir, nodir: true });
|
|
3809
4120
|
for (const file of tsFiles) {
|
|
3810
|
-
const filePath =
|
|
4121
|
+
const filePath = path10__default.default.join(themeDir, file);
|
|
3811
4122
|
let content = await fs__default.default.readFile(filePath, "utf-8");
|
|
3812
4123
|
const original = content;
|
|
3813
4124
|
content = content.replace(
|
|
@@ -3836,7 +4147,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3836
4147
|
const spinner = ora__default.default("Initializing clone...").start();
|
|
3837
4148
|
try {
|
|
3838
4149
|
const bucket = options.bucket || getBucketName3(options.environment);
|
|
3839
|
-
const outputDir = options.output ||
|
|
4150
|
+
const outputDir = options.output || path10__default.default.resolve(process.cwd(), newName);
|
|
3840
4151
|
const s3Client = getS3Client3();
|
|
3841
4152
|
if (await fs__default.default.pathExists(outputDir)) {
|
|
3842
4153
|
spinner.fail(chalk4__default.default.red(`Directory already exists: ${outputDir}`));
|
|
@@ -3891,7 +4202,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3891
4202
|
spinner.succeed(
|
|
3892
4203
|
`Renamed theme: ${chalk4__default.default.gray(themeName)} \u2192 ${chalk4__default.default.cyan(newName)}`
|
|
3893
4204
|
);
|
|
3894
|
-
const envExamplePath =
|
|
4205
|
+
const envExamplePath = path10__default.default.join(outputDir, ".env.example");
|
|
3895
4206
|
if (!await fs__default.default.pathExists(envExamplePath)) {
|
|
3896
4207
|
await fs__default.default.writeFile(
|
|
3897
4208
|
envExamplePath,
|
|
@@ -3904,32 +4215,18 @@ async function cloneCommand(themeName, options) {
|
|
|
3904
4215
|
].join("\n")
|
|
3905
4216
|
);
|
|
3906
4217
|
}
|
|
3907
|
-
const
|
|
3908
|
-
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
name: "figmaApiKey",
|
|
3914
|
-
message: "Figma API Key (optional, for Figma-to-code MCP \u2014 press Enter to skip):"
|
|
3915
|
-
}
|
|
3916
|
-
]);
|
|
3917
|
-
let mcpContent = await fs__default.default.readFile(mcpJsonPath, "utf-8");
|
|
3918
|
-
if (figmaApiKey) {
|
|
3919
|
-
mcpContent = mcpContent.replace("__FIGMA_API_KEY__", figmaApiKey);
|
|
3920
|
-
} else {
|
|
3921
|
-
try {
|
|
3922
|
-
const mcpJson = JSON.parse(mcpContent);
|
|
3923
|
-
delete mcpJson.mcpServers?.figma;
|
|
3924
|
-
mcpContent = JSON.stringify(mcpJson, null, 2) + "\n";
|
|
3925
|
-
} catch {
|
|
3926
|
-
}
|
|
4218
|
+
const { default: inquirerMod } = await import('inquirer');
|
|
4219
|
+
const { figmaApiKey } = await inquirerMod.prompt([
|
|
4220
|
+
{
|
|
4221
|
+
type: "password",
|
|
4222
|
+
name: "figmaApiKey",
|
|
4223
|
+
message: "Figma API Key (optional, for Figma-to-code MCP \u2014 press Enter to skip):"
|
|
3927
4224
|
}
|
|
3928
|
-
|
|
3929
|
-
|
|
4225
|
+
]);
|
|
4226
|
+
ensureMcpJson(outputDir, figmaApiKey || void 0);
|
|
3930
4227
|
if (options.install !== false) {
|
|
3931
4228
|
const hasPkgJson = await fs__default.default.pathExists(
|
|
3932
|
-
|
|
4229
|
+
path10__default.default.join(outputDir, "package.json")
|
|
3933
4230
|
);
|
|
3934
4231
|
if (hasPkgJson) {
|
|
3935
4232
|
spinner.start("Installing dependencies...");
|
|
@@ -3956,9 +4253,10 @@ async function cloneCommand(themeName, options) {
|
|
|
3956
4253
|
console.log(chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(entries.length));
|
|
3957
4254
|
console.log();
|
|
3958
4255
|
console.log(chalk4__default.default.cyan("Next steps:"));
|
|
3959
|
-
console.log(chalk4__default.default.gray(` cd ${
|
|
4256
|
+
console.log(chalk4__default.default.gray(` cd ${path10__default.default.relative(process.cwd(), outputDir)}`));
|
|
4257
|
+
const copyCmd = process.platform === "win32" ? "copy .env.example .env" : "cp .env.example .env";
|
|
3960
4258
|
console.log(
|
|
3961
|
-
chalk4__default.default.gray(
|
|
4259
|
+
chalk4__default.default.gray(` ${copyCmd} # then add your Company ID`)
|
|
3962
4260
|
);
|
|
3963
4261
|
if (options.install === false) {
|
|
3964
4262
|
console.log(chalk4__default.default.gray(" pnpm install"));
|
|
@@ -3991,7 +4289,7 @@ var MIME_TYPES = {
|
|
|
3991
4289
|
};
|
|
3992
4290
|
function createDevServer(options) {
|
|
3993
4291
|
const clients = /* @__PURE__ */ new Set();
|
|
3994
|
-
const themeDataPath =
|
|
4292
|
+
const themeDataPath = path10__default.default.join(options.distDir, "theme-data.json");
|
|
3995
4293
|
const server = http__default.default.createServer((req, res) => {
|
|
3996
4294
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
3997
4295
|
res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
|
|
@@ -4017,8 +4315,8 @@ function createDevServer(options) {
|
|
|
4017
4315
|
if (pathname.startsWith("/_assets/")) {
|
|
4018
4316
|
const parts = pathname.replace(/^\/_assets\//, "").split("/");
|
|
4019
4317
|
const assetSubpath = parts.slice(1).join("/");
|
|
4020
|
-
const assetPath =
|
|
4021
|
-
if (!assetPath.startsWith(
|
|
4318
|
+
const assetPath = path10__default.default.join(options.themePath, "assets", assetSubpath);
|
|
4319
|
+
if (!assetPath.startsWith(path10__default.default.join(options.themePath, "assets"))) {
|
|
4022
4320
|
res.writeHead(403);
|
|
4023
4321
|
res.end("Forbidden");
|
|
4024
4322
|
return;
|
|
@@ -4029,8 +4327,8 @@ function createDevServer(options) {
|
|
|
4029
4327
|
if (pathname.startsWith("/themes/")) {
|
|
4030
4328
|
const match = pathname.match(/^\/themes\/[^/]+\/assets\/(.+)/);
|
|
4031
4329
|
if (match) {
|
|
4032
|
-
const assetPath =
|
|
4033
|
-
if (!assetPath.startsWith(
|
|
4330
|
+
const assetPath = path10__default.default.join(options.themePath, "assets", match[1]);
|
|
4331
|
+
if (!assetPath.startsWith(path10__default.default.join(options.themePath, "assets"))) {
|
|
4034
4332
|
res.writeHead(403);
|
|
4035
4333
|
res.end("Forbidden");
|
|
4036
4334
|
return;
|
|
@@ -4044,26 +4342,26 @@ function createDevServer(options) {
|
|
|
4044
4342
|
const segments = subpath.split("/");
|
|
4045
4343
|
let assetPath;
|
|
4046
4344
|
if (segments[0] === options.themeName || segments[0] === options.themeName.replace(/^my-/, "")) {
|
|
4047
|
-
assetPath =
|
|
4345
|
+
assetPath = path10__default.default.join(
|
|
4048
4346
|
options.themePath,
|
|
4049
4347
|
"assets",
|
|
4050
4348
|
segments.slice(1).join("/")
|
|
4051
4349
|
);
|
|
4052
4350
|
} else {
|
|
4053
|
-
assetPath =
|
|
4351
|
+
assetPath = path10__default.default.join(options.themePath, "assets", subpath);
|
|
4054
4352
|
}
|
|
4055
|
-
if (assetPath.startsWith(
|
|
4353
|
+
if (assetPath.startsWith(path10__default.default.join(options.themePath, "assets")) && fs4__default.default.existsSync(assetPath)) {
|
|
4056
4354
|
serveFile(res, assetPath);
|
|
4057
4355
|
return;
|
|
4058
4356
|
}
|
|
4059
4357
|
}
|
|
4060
|
-
const filePath =
|
|
4358
|
+
const filePath = path10__default.default.join(options.distDir, pathname);
|
|
4061
4359
|
if (!filePath.startsWith(options.distDir)) {
|
|
4062
4360
|
res.writeHead(403);
|
|
4063
4361
|
res.end("Forbidden");
|
|
4064
4362
|
return;
|
|
4065
4363
|
}
|
|
4066
|
-
if (
|
|
4364
|
+
if (fs4__default.default.existsSync(filePath) && fs4__default.default.statSync(filePath).isFile()) {
|
|
4067
4365
|
serveFile(res, filePath);
|
|
4068
4366
|
} else {
|
|
4069
4367
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
@@ -4095,14 +4393,14 @@ function createDevServer(options) {
|
|
|
4095
4393
|
}
|
|
4096
4394
|
function serveFile(res, filePath) {
|
|
4097
4395
|
try {
|
|
4098
|
-
if (!
|
|
4396
|
+
if (!fs4__default.default.existsSync(filePath)) {
|
|
4099
4397
|
res.writeHead(404);
|
|
4100
4398
|
res.end("Not Found");
|
|
4101
4399
|
return;
|
|
4102
4400
|
}
|
|
4103
|
-
const ext =
|
|
4401
|
+
const ext = path10__default.default.extname(filePath);
|
|
4104
4402
|
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
4105
|
-
const content =
|
|
4403
|
+
const content = fs4__default.default.readFileSync(filePath);
|
|
4106
4404
|
res.writeHead(200, { "Content-Type": contentType });
|
|
4107
4405
|
res.end(content);
|
|
4108
4406
|
} catch {
|
|
@@ -4115,7 +4413,7 @@ function generatePreviewHTML(themeName, port, themeDataPath) {
|
|
|
4115
4413
|
let fontVarsCSS = "";
|
|
4116
4414
|
if (themeDataPath) {
|
|
4117
4415
|
try {
|
|
4118
|
-
const themeData = JSON.parse(
|
|
4416
|
+
const themeData = JSON.parse(fs4__default.default.readFileSync(themeDataPath, "utf-8"));
|
|
4119
4417
|
const typography = (themeData?.themeConfig || themeData?.theme?.config)?.typography?.fontFamily;
|
|
4120
4418
|
if (typography) {
|
|
4121
4419
|
const fontFamilies = /* @__PURE__ */ new Set();
|
|
@@ -4203,14 +4501,14 @@ async function devCommand(options) {
|
|
|
4203
4501
|
if (options.theme) {
|
|
4204
4502
|
themeName = options.theme;
|
|
4205
4503
|
try {
|
|
4206
|
-
const workspaceThemePath =
|
|
4504
|
+
const workspaceThemePath = path10__default.default.join(getThemesDir(), themeName);
|
|
4207
4505
|
if (fs__default.default.existsSync(workspaceThemePath)) {
|
|
4208
4506
|
themePath = workspaceThemePath;
|
|
4209
4507
|
} else {
|
|
4210
|
-
themePath =
|
|
4508
|
+
themePath = path10__default.default.join(process.cwd(), themeName);
|
|
4211
4509
|
}
|
|
4212
4510
|
} catch {
|
|
4213
|
-
themePath =
|
|
4511
|
+
themePath = path10__default.default.join(process.cwd(), themeName);
|
|
4214
4512
|
}
|
|
4215
4513
|
if (!fs__default.default.existsSync(themePath)) {
|
|
4216
4514
|
logger.error(`Theme "${themeName}" not found.`);
|
|
@@ -4221,10 +4519,10 @@ async function devCommand(options) {
|
|
|
4221
4519
|
"theme.config.ts",
|
|
4222
4520
|
"bundle-entry.ts",
|
|
4223
4521
|
"manifest.ts"
|
|
4224
|
-
].some((f) => fs__default.default.existsSync(
|
|
4522
|
+
].some((f) => fs__default.default.existsSync(path10__default.default.join(process.cwd(), f)));
|
|
4225
4523
|
if (isThemeDir) {
|
|
4226
4524
|
themePath = process.cwd();
|
|
4227
|
-
themeName =
|
|
4525
|
+
themeName = path10__default.default.basename(themePath);
|
|
4228
4526
|
} else {
|
|
4229
4527
|
logger.error(
|
|
4230
4528
|
"Not in a theme directory and no --theme specified. Run from theme root or use --theme flag."
|
|
@@ -4293,9 +4591,9 @@ async function devCommand(options) {
|
|
|
4293
4591
|
watcher.close();
|
|
4294
4592
|
await context2.dispose();
|
|
4295
4593
|
server.close();
|
|
4296
|
-
const shimPath =
|
|
4594
|
+
const shimPath = path10__default.default.join(outputDir, ".process-shim.js");
|
|
4297
4595
|
try {
|
|
4298
|
-
await
|
|
4596
|
+
await fs9__default.default.unlink(shimPath);
|
|
4299
4597
|
} catch {
|
|
4300
4598
|
}
|
|
4301
4599
|
process.exit(0);
|
|
@@ -4304,8 +4602,8 @@ async function devCommand(options) {
|
|
|
4304
4602
|
|
|
4305
4603
|
// src/commands/config.ts
|
|
4306
4604
|
init_logger();
|
|
4307
|
-
var CONFIG_DIR =
|
|
4308
|
-
var CONFIG_FILE =
|
|
4605
|
+
var CONFIG_DIR = path10__default.default.join(os__default.default.homedir(), ".onexthm");
|
|
4606
|
+
var CONFIG_FILE = path10__default.default.join(CONFIG_DIR, ".env");
|
|
4309
4607
|
var CONFIG_ENTRIES = [
|
|
4310
4608
|
{
|
|
4311
4609
|
key: "AWS_ACCESS_KEY_ID",
|
|
@@ -4447,122 +4745,6 @@ async function configCommand() {
|
|
|
4447
4745
|
|
|
4448
4746
|
// src/commands/login.ts
|
|
4449
4747
|
init_logger();
|
|
4450
|
-
var AUTH_DIR = path8__default.default.join(os3__default.default.homedir(), ".onexthm");
|
|
4451
|
-
var AUTH_FILE = path8__default.default.join(AUTH_DIR, "auth.json");
|
|
4452
|
-
function getApiUrl() {
|
|
4453
|
-
return process.env.ONEXTHM_API_URL || process.env.NEXT_PUBLIC_API_URL || "https://platform-dev.onexeos.com";
|
|
4454
|
-
}
|
|
4455
|
-
async function saveAuthTokens(tokens) {
|
|
4456
|
-
await fs__default.default.ensureDir(AUTH_DIR);
|
|
4457
|
-
const key = getMachineKey();
|
|
4458
|
-
const data = JSON.stringify(tokens);
|
|
4459
|
-
const encrypted = encrypt(data, key);
|
|
4460
|
-
await fs__default.default.writeFile(AUTH_FILE, encrypted, "utf-8");
|
|
4461
|
-
}
|
|
4462
|
-
function loadAuthTokens() {
|
|
4463
|
-
try {
|
|
4464
|
-
if (!fs__default.default.existsSync(AUTH_FILE)) return null;
|
|
4465
|
-
const encrypted = fs__default.default.readFileSync(AUTH_FILE, "utf-8");
|
|
4466
|
-
const key = getMachineKey();
|
|
4467
|
-
const data = decrypt(encrypted, key);
|
|
4468
|
-
return JSON.parse(data);
|
|
4469
|
-
} catch {
|
|
4470
|
-
return null;
|
|
4471
|
-
}
|
|
4472
|
-
}
|
|
4473
|
-
async function clearAuthTokens() {
|
|
4474
|
-
try {
|
|
4475
|
-
await fs__default.default.remove(AUTH_FILE);
|
|
4476
|
-
} catch {
|
|
4477
|
-
}
|
|
4478
|
-
}
|
|
4479
|
-
function isTokenExpired(tokens) {
|
|
4480
|
-
return Date.now() / 1e3 > tokens.expiresAt - 60;
|
|
4481
|
-
}
|
|
4482
|
-
async function getValidTokens() {
|
|
4483
|
-
const tokens = loadAuthTokens();
|
|
4484
|
-
if (!tokens) return null;
|
|
4485
|
-
if (!isTokenExpired(tokens)) return tokens;
|
|
4486
|
-
try {
|
|
4487
|
-
const apiUrl = getApiUrl();
|
|
4488
|
-
const response = await fetch(`${apiUrl}/auth/refresh`, {
|
|
4489
|
-
method: "POST",
|
|
4490
|
-
headers: { "Content-Type": "application/json" },
|
|
4491
|
-
body: JSON.stringify({ refresh_token: tokens.refreshToken })
|
|
4492
|
-
});
|
|
4493
|
-
if (!response.ok) {
|
|
4494
|
-
await clearAuthTokens();
|
|
4495
|
-
return null;
|
|
4496
|
-
}
|
|
4497
|
-
const data = await response.json();
|
|
4498
|
-
const body = data.statusCode ? data.body : data;
|
|
4499
|
-
const refreshed = {
|
|
4500
|
-
...tokens,
|
|
4501
|
-
accessToken: body.AccessToken || tokens.accessToken,
|
|
4502
|
-
idToken: body.IdToken || tokens.idToken,
|
|
4503
|
-
expiresAt: Math.floor(Date.now() / 1e3) + (body.ExpiresIn || 3600)
|
|
4504
|
-
};
|
|
4505
|
-
await saveAuthTokens(refreshed);
|
|
4506
|
-
return refreshed;
|
|
4507
|
-
} catch {
|
|
4508
|
-
await clearAuthTokens();
|
|
4509
|
-
return null;
|
|
4510
|
-
}
|
|
4511
|
-
}
|
|
4512
|
-
async function authenticatedFetch(url, init) {
|
|
4513
|
-
const tokens = await getValidTokens();
|
|
4514
|
-
if (!tokens) {
|
|
4515
|
-
throw new Error("Not logged in. Run: onexthm login");
|
|
4516
|
-
}
|
|
4517
|
-
const headers = new Headers(init?.headers);
|
|
4518
|
-
headers.set("Authorization", `Bearer ${tokens.idToken}`);
|
|
4519
|
-
headers.set("Content-Type", "application/json");
|
|
4520
|
-
return fetch(url, { ...init, headers });
|
|
4521
|
-
}
|
|
4522
|
-
function getMachineKey() {
|
|
4523
|
-
let seed;
|
|
4524
|
-
if (process.platform === "darwin") {
|
|
4525
|
-
seed = `onexthm:${os3__default.default.hostname()}:${os3__default.default.userInfo().username}`;
|
|
4526
|
-
} else if (process.platform === "linux") {
|
|
4527
|
-
try {
|
|
4528
|
-
seed = `onexthm:${fs__default.default.readFileSync("/etc/machine-id", "utf-8").trim()}`;
|
|
4529
|
-
} catch {
|
|
4530
|
-
seed = `onexthm:${os3__default.default.hostname()}:${os3__default.default.userInfo().username}`;
|
|
4531
|
-
}
|
|
4532
|
-
} else {
|
|
4533
|
-
seed = `onexthm:${os3__default.default.hostname()}:${os3__default.default.userInfo().username}`;
|
|
4534
|
-
}
|
|
4535
|
-
return crypto2__default.default.createHash("sha256").update(seed).digest();
|
|
4536
|
-
}
|
|
4537
|
-
function encrypt(text, key) {
|
|
4538
|
-
const iv = crypto2__default.default.randomBytes(16);
|
|
4539
|
-
const cipher = crypto2__default.default.createCipheriv("aes-256-gcm", key, iv);
|
|
4540
|
-
let encrypted = cipher.update(text, "utf-8", "hex");
|
|
4541
|
-
encrypted += cipher.final("hex");
|
|
4542
|
-
const tag = cipher.getAuthTag();
|
|
4543
|
-
return `${iv.toString("hex")}:${tag.toString("hex")}:${encrypted}`;
|
|
4544
|
-
}
|
|
4545
|
-
function decrypt(text, key) {
|
|
4546
|
-
const [ivHex, tagHex, encrypted] = text.split(":");
|
|
4547
|
-
const iv = Buffer.from(ivHex, "hex");
|
|
4548
|
-
const tag = Buffer.from(tagHex, "hex");
|
|
4549
|
-
const decipher = crypto2__default.default.createDecipheriv("aes-256-gcm", key, iv);
|
|
4550
|
-
decipher.setAuthTag(tag);
|
|
4551
|
-
let decrypted = decipher.update(encrypted, "hex", "utf-8");
|
|
4552
|
-
decrypted += decipher.final("utf-8");
|
|
4553
|
-
return decrypted;
|
|
4554
|
-
}
|
|
4555
|
-
function parseJwtClaims(idToken) {
|
|
4556
|
-
try {
|
|
4557
|
-
const payload = idToken.split(".")[1];
|
|
4558
|
-
const decoded = Buffer.from(payload, "base64url").toString("utf-8");
|
|
4559
|
-
return JSON.parse(decoded);
|
|
4560
|
-
} catch {
|
|
4561
|
-
return {};
|
|
4562
|
-
}
|
|
4563
|
-
}
|
|
4564
|
-
|
|
4565
|
-
// src/commands/login.ts
|
|
4566
4748
|
async function loginCommand() {
|
|
4567
4749
|
logger.header("OneX Theme Developer Login");
|
|
4568
4750
|
const existing = loadAuthTokens();
|
|
@@ -4688,13 +4870,13 @@ async function publishCommand(options) {
|
|
|
4688
4870
|
logger.info(`Logged in as: ${tokens.user.email}`);
|
|
4689
4871
|
let themePath;
|
|
4690
4872
|
if (options.theme) {
|
|
4691
|
-
themePath =
|
|
4873
|
+
themePath = path10__default.default.resolve(options.theme);
|
|
4692
4874
|
} else {
|
|
4693
4875
|
const isThemeDir = [
|
|
4694
4876
|
"theme.config.ts",
|
|
4695
4877
|
"bundle-entry.ts",
|
|
4696
4878
|
"manifest.ts"
|
|
4697
|
-
].some((f) => fs__default.default.existsSync(
|
|
4879
|
+
].some((f) => fs__default.default.existsSync(path10__default.default.join(process.cwd(), f)));
|
|
4698
4880
|
if (isThemeDir) {
|
|
4699
4881
|
themePath = process.cwd();
|
|
4700
4882
|
} else {
|
|
@@ -4704,14 +4886,31 @@ async function publishCommand(options) {
|
|
|
4704
4886
|
process.exit(1);
|
|
4705
4887
|
}
|
|
4706
4888
|
}
|
|
4707
|
-
const pkgPath =
|
|
4889
|
+
const pkgPath = path10__default.default.join(themePath, "package.json");
|
|
4708
4890
|
if (!fs__default.default.existsSync(pkgPath)) {
|
|
4709
4891
|
logger.error("No package.json found in theme directory");
|
|
4710
4892
|
process.exit(1);
|
|
4711
4893
|
}
|
|
4712
4894
|
const pkg = fs__default.default.readJsonSync(pkgPath);
|
|
4713
|
-
const themeId = pkg.name?.replace("@onex-themes/", "") ||
|
|
4895
|
+
const themeId = pkg.name?.replace("@onex-themes/", "") || path10__default.default.basename(themePath);
|
|
4896
|
+
if (options.bump) {
|
|
4897
|
+
const currentVersion = pkg.version || "1.0.0";
|
|
4898
|
+
const newVersion = semver__default.default.inc(currentVersion, options.bump);
|
|
4899
|
+
if (!newVersion) {
|
|
4900
|
+
logger.error(`Failed to bump version from ${currentVersion}`);
|
|
4901
|
+
process.exit(1);
|
|
4902
|
+
}
|
|
4903
|
+
pkg.version = newVersion;
|
|
4904
|
+
fs__default.default.writeJsonSync(pkgPath, pkg, { spaces: 2 });
|
|
4905
|
+
logger.info(`Bumped version: ${currentVersion} -> ${newVersion}`);
|
|
4906
|
+
}
|
|
4714
4907
|
const version2 = pkg.version || "1.0.0";
|
|
4908
|
+
if (!semver__default.default.valid(version2)) {
|
|
4909
|
+
logger.error(
|
|
4910
|
+
`Invalid version "${version2}" in package.json. Must be valid semver (e.g., 1.0.0)`
|
|
4911
|
+
);
|
|
4912
|
+
process.exit(1);
|
|
4913
|
+
}
|
|
4715
4914
|
logger.newLine();
|
|
4716
4915
|
logger.info(`Theme: ${themeId}`);
|
|
4717
4916
|
logger.info(`Version: ${version2}`);
|
|
@@ -4748,6 +4947,38 @@ async function publishCommand(options) {
|
|
|
4748
4947
|
logger.error(error instanceof Error ? error.message : "Connection failed");
|
|
4749
4948
|
process.exit(1);
|
|
4750
4949
|
}
|
|
4950
|
+
logger.startSpinner("Checking version availability...");
|
|
4951
|
+
try {
|
|
4952
|
+
const checkResponse = await authenticatedFetch(
|
|
4953
|
+
`${apiUrl}/website-api/themes/${encodeURIComponent(themeId)}/versions/${encodeURIComponent(version2)}/exists`,
|
|
4954
|
+
{ method: "GET" }
|
|
4955
|
+
);
|
|
4956
|
+
const checkData = await checkResponse.json();
|
|
4957
|
+
const checkBody = checkData.statusCode ? checkData.body : checkData;
|
|
4958
|
+
if (checkBody.exists) {
|
|
4959
|
+
logger.stopSpinner(false, "Version already published");
|
|
4960
|
+
const patchVer = semver__default.default.inc(version2, "patch") || "?";
|
|
4961
|
+
const minorVer = semver__default.default.inc(version2, "minor") || "?";
|
|
4962
|
+
const majorVer = semver__default.default.inc(version2, "major") || "?";
|
|
4963
|
+
logger.error(
|
|
4964
|
+
`
|
|
4965
|
+
Version ${version2} of "${themeId}" is already published and cannot be overwritten.
|
|
4966
|
+
|
|
4967
|
+
To publish a new version:
|
|
4968
|
+
1. Bump version in package.json (e.g., ${version2} -> ${patchVer})
|
|
4969
|
+
2. Run: onexthm publish
|
|
4970
|
+
|
|
4971
|
+
Or use the --bump flag:
|
|
4972
|
+
onexthm publish --bump patch (${version2} -> ${patchVer})
|
|
4973
|
+
onexthm publish --bump minor (${version2} -> ${minorVer})
|
|
4974
|
+
onexthm publish --bump major (${version2} -> ${majorVer})`
|
|
4975
|
+
);
|
|
4976
|
+
process.exit(1);
|
|
4977
|
+
}
|
|
4978
|
+
logger.stopSpinner(true, `Version ${version2} is available`);
|
|
4979
|
+
} catch (error) {
|
|
4980
|
+
logger.stopSpinner(true, "Version check skipped (endpoint not available)");
|
|
4981
|
+
}
|
|
4751
4982
|
logger.startSpinner("Building theme...");
|
|
4752
4983
|
try {
|
|
4753
4984
|
const { compileStandaloneTheme: compileStandaloneTheme2 } = await Promise.resolve().then(() => (init_compile_theme(), compile_theme_exports));
|
|
@@ -4793,13 +5024,13 @@ async function publishCommand(options) {
|
|
|
4793
5024
|
try {
|
|
4794
5025
|
const archiver3 = await import('archiver');
|
|
4795
5026
|
const { createWriteStream } = await import('fs');
|
|
4796
|
-
const distDir =
|
|
5027
|
+
const distDir = path10__default.default.join(themePath, "dist");
|
|
4797
5028
|
if (!fs__default.default.existsSync(distDir)) {
|
|
4798
5029
|
logger.stopSpinner(false, "No dist/ directory");
|
|
4799
5030
|
logger.error("Build the theme first: onexthm build");
|
|
4800
5031
|
process.exit(1);
|
|
4801
5032
|
}
|
|
4802
|
-
const bundleZipPath =
|
|
5033
|
+
const bundleZipPath = path10__default.default.join(themePath, "dist", "bundle.zip");
|
|
4803
5034
|
await createZip(distDir, bundleZipPath, [
|
|
4804
5035
|
"bundle.zip",
|
|
4805
5036
|
"source.zip",
|
|
@@ -4824,7 +5055,7 @@ async function publishCommand(options) {
|
|
|
4824
5055
|
}
|
|
4825
5056
|
logger.startSpinner("Uploading source...");
|
|
4826
5057
|
try {
|
|
4827
|
-
const sourceZipPath =
|
|
5058
|
+
const sourceZipPath = path10__default.default.join(themePath, "dist", "source.zip");
|
|
4828
5059
|
await createZip(themePath, sourceZipPath, [
|
|
4829
5060
|
"node_modules",
|
|
4830
5061
|
"dist",
|
|
@@ -4912,14 +5143,14 @@ async function createZip(sourceDir, outputPath, exclude) {
|
|
|
4912
5143
|
try {
|
|
4913
5144
|
const projectRoot = getProjectRoot();
|
|
4914
5145
|
dotenv__default.default.config({
|
|
4915
|
-
path:
|
|
5146
|
+
path: path10__default.default.join(projectRoot, ".env.local"),
|
|
4916
5147
|
quiet: true
|
|
4917
5148
|
});
|
|
4918
|
-
dotenv__default.default.config({ path:
|
|
5149
|
+
dotenv__default.default.config({ path: path10__default.default.join(projectRoot, ".env"), quiet: true });
|
|
4919
5150
|
} catch {
|
|
4920
5151
|
}
|
|
4921
5152
|
dotenv__default.default.config({
|
|
4922
|
-
path:
|
|
5153
|
+
path: path10__default.default.join(os__default.default.homedir(), ".onexthm", ".env"),
|
|
4923
5154
|
quiet: true
|
|
4924
5155
|
});
|
|
4925
5156
|
var require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)));
|
|
@@ -4979,7 +5210,10 @@ program.command("config").description("Configure OneX CLI credentials (AWS, API
|
|
|
4979
5210
|
program.command("login").description("Login to OneX platform").action(loginCommand);
|
|
4980
5211
|
program.command("logout").description("Logout from OneX platform").action(logoutCommand);
|
|
4981
5212
|
program.command("whoami").description("Show current logged-in developer").action(whoamiCommand);
|
|
4982
|
-
program.command("publish").description("Build, scan, and publish theme to marketplace (requires login)").option("-t, --theme <path>", "Theme directory path").
|
|
5213
|
+
program.command("publish").description("Build, scan, and publish theme to marketplace (requires login)").option("-t, --theme <path>", "Theme directory path").option(
|
|
5214
|
+
"--bump <type>",
|
|
5215
|
+
"Auto-bump version before publish (patch|minor|major)"
|
|
5216
|
+
).action(publishCommand);
|
|
4983
5217
|
program.configureOutput({
|
|
4984
5218
|
writeErr: (str) => process.stderr.write(chalk4__default.default.red(str))
|
|
4985
5219
|
});
|