@onexapis/cli 1.1.37 → 1.1.39
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 +639 -401
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +633 -396
- package/dist/cli.mjs.map +1 -1
- package/dist/index.js +255 -203
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +252 -200
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -4
- package/templates/default/CLAUDE.md +334 -1
- package/templates/default/esbuild.config.js +20 -0
- package/templates/default/pages/about.ts +2 -2
- package/templates/default/pages/forgot-password.ts +1 -3
- package/templates/default/pages/home.ts +4 -4
- package/templates/default/pages/login.ts +1 -3
- package/templates/default/pages/profile.ts +2 -2
- package/templates/default/pages/register.ts +1 -3
- package/templates/default/pages/showcase.ts +7 -7
- package/templates/default/pages/verify-code.ts +1 -3
- package/templates/default/sections/about/about.schema.ts +1 -1
- package/templates/default/sections/auth-forgot-password/auth-forgot-password.schema.ts +1 -1
- package/templates/default/sections/auth-login/auth-login.schema.ts +1 -1
- package/templates/default/sections/auth-register/auth-register.schema.ts +1 -1
- package/templates/default/sections/auth-verify-code/auth-verify-code.schema.ts +1 -1
- package/templates/default/sections/cta/cta.schema.ts +1 -1
- package/templates/default/sections/features/features.schema.ts +1 -1
- package/templates/default/sections/footer/footer.schema.ts +1 -1
- package/templates/default/sections/gallery/gallery.schema.ts +1 -1
- package/templates/default/sections/header/header.schema.ts +1 -1
- package/templates/default/sections/hero/hero.schema.ts +1 -1
- package/templates/default/sections/profile/profile.schema.ts +1 -1
- package/templates/default/sections/stats/stats.schema.ts +1 -1
- package/templates/default/sections/testimonials/testimonials.schema.ts +1 -1
- package/templates/default/theme.layout.ts +18 -0
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 path9 = require('path');
|
|
8
|
+
var fs8 = 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
16
|
var child_process = require('child_process');
|
|
17
17
|
var commander = require('commander');
|
|
18
|
-
var
|
|
18
|
+
var fs3 = 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,14 @@ 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 path9__default = /*#__PURE__*/_interopDefault(path9);
|
|
55
|
+
var fs8__default = /*#__PURE__*/_interopDefault(fs8);
|
|
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 fs3__default = /*#__PURE__*/_interopDefault(fs3);
|
|
61
62
|
var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
|
|
62
63
|
var archiver__default = /*#__PURE__*/_interopDefault(archiver);
|
|
63
64
|
var FormData__default = /*#__PURE__*/_interopDefault(FormData);
|
|
@@ -65,6 +66,7 @@ var fetch2__default = /*#__PURE__*/_interopDefault(fetch2);
|
|
|
65
66
|
var AdmZip__default = /*#__PURE__*/_interopDefault(AdmZip);
|
|
66
67
|
var chokidar__default = /*#__PURE__*/_interopDefault(chokidar);
|
|
67
68
|
var http__default = /*#__PURE__*/_interopDefault(http);
|
|
69
|
+
var semver__default = /*#__PURE__*/_interopDefault(semver);
|
|
68
70
|
|
|
69
71
|
var __defProp = Object.defineProperty;
|
|
70
72
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
@@ -146,8 +148,8 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
146
148
|
const tailwindcss = (await import('tailwindcss')).default;
|
|
147
149
|
const tailwindConfig = {
|
|
148
150
|
content: [
|
|
149
|
-
|
|
150
|
-
|
|
151
|
+
path9__default.default.join(themePath, "sections/**/*.{ts,tsx}"),
|
|
152
|
+
path9__default.default.join(themePath, "components/**/*.{ts,tsx}")
|
|
151
153
|
],
|
|
152
154
|
theme: { extend: {} },
|
|
153
155
|
plugins: []
|
|
@@ -157,7 +159,7 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
157
159
|
inputCSS,
|
|
158
160
|
{ from: void 0 }
|
|
159
161
|
);
|
|
160
|
-
await
|
|
162
|
+
await fs8__default.default.writeFile(path9__default.default.join(outDir, "bundle.css"), result.css);
|
|
161
163
|
logger.info("Generated bundle.css");
|
|
162
164
|
} catch (err) {
|
|
163
165
|
logger.warning(
|
|
@@ -168,12 +170,12 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
168
170
|
async function resolveNodeModulesFile(startDir, relativePath) {
|
|
169
171
|
let dir = startDir;
|
|
170
172
|
while (true) {
|
|
171
|
-
const candidate =
|
|
173
|
+
const candidate = path9__default.default.join(dir, "node_modules", relativePath);
|
|
172
174
|
try {
|
|
173
|
-
await
|
|
175
|
+
await fs8__default.default.access(candidate);
|
|
174
176
|
return candidate;
|
|
175
177
|
} catch {
|
|
176
|
-
const parent =
|
|
178
|
+
const parent = path9__default.default.dirname(dir);
|
|
177
179
|
if (parent === dir) break;
|
|
178
180
|
dir = parent;
|
|
179
181
|
}
|
|
@@ -197,7 +199,7 @@ async function scanImportsFromPackage(sourceDir, packageName) {
|
|
|
197
199
|
});
|
|
198
200
|
for (const file of sourceFiles) {
|
|
199
201
|
try {
|
|
200
|
-
const content = await
|
|
202
|
+
const content = await fs8__default.default.readFile(path9__default.default.join(sourceDir, file), "utf-8");
|
|
201
203
|
for (const match of content.matchAll(namespaceImportRegex)) {
|
|
202
204
|
const subpath = match[1] ? match[1].slice(1) : "";
|
|
203
205
|
if (!result[subpath]) result[subpath] = /* @__PURE__ */ new Set();
|
|
@@ -251,17 +253,17 @@ function createCoreGlobalPlugin(themePath) {
|
|
|
251
253
|
const distFileName = subpath ? `${subpath}.mjs` : "index.mjs";
|
|
252
254
|
let distPath = await resolveNodeModulesFile(
|
|
253
255
|
themePath,
|
|
254
|
-
|
|
256
|
+
path9__default.default.join("@onexapis", "core", "dist", distFileName)
|
|
255
257
|
);
|
|
256
258
|
if (!distPath) {
|
|
257
259
|
distPath = await resolveNodeModulesFile(
|
|
258
260
|
__dirname,
|
|
259
|
-
|
|
261
|
+
path9__default.default.join("@onexapis", "core", "dist", distFileName)
|
|
260
262
|
);
|
|
261
263
|
}
|
|
262
264
|
try {
|
|
263
265
|
if (!distPath) throw new Error("not found");
|
|
264
|
-
const distContent = await
|
|
266
|
+
const distContent = await fs8__default.default.readFile(distPath, "utf-8");
|
|
265
267
|
const exportMatches = distContent.matchAll(/export\s*\{([^}]+)\}/g);
|
|
266
268
|
for (const m of exportMatches) {
|
|
267
269
|
const names = m[1].split(",").map((n) => {
|
|
@@ -490,7 +492,7 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
490
492
|
const pages = {};
|
|
491
493
|
for (const ext of [".ts", ".js"]) {
|
|
492
494
|
try {
|
|
493
|
-
const mod = await jiti.import(
|
|
495
|
+
const mod = await jiti.import(path9__default.default.join(themePath, `theme.config${ext}`));
|
|
494
496
|
themeConfig = mod.default || mod;
|
|
495
497
|
break;
|
|
496
498
|
} catch {
|
|
@@ -498,20 +500,20 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
498
500
|
}
|
|
499
501
|
for (const ext of [".ts", ".js"]) {
|
|
500
502
|
try {
|
|
501
|
-
const mod = await jiti.import(
|
|
503
|
+
const mod = await jiti.import(path9__default.default.join(themePath, `theme.layout${ext}`));
|
|
502
504
|
layoutConfig = mod.default || mod;
|
|
503
505
|
break;
|
|
504
506
|
} catch {
|
|
505
507
|
}
|
|
506
508
|
}
|
|
507
509
|
const schemas = {};
|
|
508
|
-
const sectionsDir =
|
|
510
|
+
const sectionsDir = path9__default.default.join(themePath, "sections");
|
|
509
511
|
try {
|
|
510
|
-
const sectionDirs = await
|
|
512
|
+
const sectionDirs = await fs8__default.default.readdir(sectionsDir);
|
|
511
513
|
for (const dir of sectionDirs) {
|
|
512
|
-
const schemaFile =
|
|
514
|
+
const schemaFile = path9__default.default.join(sectionsDir, dir, `${dir}.schema.ts`);
|
|
513
515
|
try {
|
|
514
|
-
await
|
|
516
|
+
await fs8__default.default.access(schemaFile);
|
|
515
517
|
const mod = await jiti.import(schemaFile);
|
|
516
518
|
for (const [key, value] of Object.entries(mod)) {
|
|
517
519
|
if (key.endsWith("Schema") && value && typeof value === "object" && value.type) {
|
|
@@ -523,14 +525,14 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
523
525
|
}
|
|
524
526
|
} catch {
|
|
525
527
|
}
|
|
526
|
-
const pagesDir =
|
|
528
|
+
const pagesDir = path9__default.default.join(themePath, "pages");
|
|
527
529
|
try {
|
|
528
|
-
const files = await
|
|
530
|
+
const files = await fs8__default.default.readdir(pagesDir);
|
|
529
531
|
for (const file of files) {
|
|
530
532
|
if (!file.match(/\.(ts|js)$/)) continue;
|
|
531
533
|
const name = file.replace(/\.(ts|js)$/, "");
|
|
532
534
|
try {
|
|
533
|
-
const mod = await jiti.import(
|
|
535
|
+
const mod = await jiti.import(path9__default.default.join(pagesDir, file));
|
|
534
536
|
const config = mod.default || mod;
|
|
535
537
|
const sections = (config.sections || []).map((section) => {
|
|
536
538
|
const schema = schemas[section.type];
|
|
@@ -558,8 +560,8 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
558
560
|
}
|
|
559
561
|
} catch {
|
|
560
562
|
}
|
|
561
|
-
await
|
|
562
|
-
|
|
563
|
+
await fs8__default.default.writeFile(
|
|
564
|
+
path9__default.default.join(outputDir, "theme-data.json"),
|
|
563
565
|
JSON.stringify(
|
|
564
566
|
{
|
|
565
567
|
themeId,
|
|
@@ -582,53 +584,53 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
582
584
|
logger.info(`Generated theme-data.json (${Object.keys(pages).length} pages)`);
|
|
583
585
|
}
|
|
584
586
|
async function contentHashEntry(outputDir) {
|
|
585
|
-
const entryPath =
|
|
586
|
-
const mapPath =
|
|
587
|
+
const entryPath = path9__default.default.join(outputDir, "bundle-entry.js");
|
|
588
|
+
const mapPath = path9__default.default.join(outputDir, "bundle-entry.js.map");
|
|
587
589
|
const oldFiles = await glob.glob("bundle-entry-*.js*", { cwd: outputDir });
|
|
588
590
|
for (const f of oldFiles) {
|
|
589
|
-
await
|
|
591
|
+
await fs8__default.default.unlink(path9__default.default.join(outputDir, f));
|
|
590
592
|
}
|
|
591
593
|
let entryContent;
|
|
592
594
|
try {
|
|
593
|
-
entryContent = await
|
|
595
|
+
entryContent = await fs8__default.default.readFile(entryPath, "utf-8");
|
|
594
596
|
} catch {
|
|
595
|
-
const indexPath =
|
|
597
|
+
const indexPath = path9__default.default.join(outputDir, "index.js");
|
|
596
598
|
try {
|
|
597
|
-
entryContent = await
|
|
599
|
+
entryContent = await fs8__default.default.readFile(indexPath, "utf-8");
|
|
598
600
|
} catch {
|
|
599
601
|
logger.warning("No entry file found in output, skipping content hash");
|
|
600
602
|
return;
|
|
601
603
|
}
|
|
602
|
-
const hash2 =
|
|
604
|
+
const hash2 = crypto__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
|
|
603
605
|
const hashedName2 = `bundle-entry-${hash2}.js`;
|
|
604
|
-
const indexMapPath =
|
|
606
|
+
const indexMapPath = path9__default.default.join(outputDir, "index.js.map");
|
|
605
607
|
const hashedMapName2 = `bundle-entry-${hash2}.js.map`;
|
|
606
608
|
entryContent = entryContent.replace(
|
|
607
609
|
/\/\/# sourceMappingURL=index\.js\.map/,
|
|
608
610
|
`//# sourceMappingURL=${hashedMapName2}`
|
|
609
611
|
);
|
|
610
|
-
await
|
|
611
|
-
await
|
|
612
|
+
await fs8__default.default.writeFile(path9__default.default.join(outputDir, hashedName2), entryContent);
|
|
613
|
+
await fs8__default.default.unlink(indexPath);
|
|
612
614
|
try {
|
|
613
|
-
await
|
|
614
|
-
await
|
|
615
|
+
await fs8__default.default.access(indexMapPath);
|
|
616
|
+
await fs8__default.default.rename(indexMapPath, path9__default.default.join(outputDir, hashedMapName2));
|
|
615
617
|
} catch {
|
|
616
618
|
}
|
|
617
619
|
logger.info(`Entry hashed: ${hashedName2}`);
|
|
618
620
|
return;
|
|
619
621
|
}
|
|
620
|
-
const hash =
|
|
622
|
+
const hash = crypto__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
|
|
621
623
|
const hashedName = `bundle-entry-${hash}.js`;
|
|
622
624
|
const hashedMapName = `bundle-entry-${hash}.js.map`;
|
|
623
625
|
entryContent = entryContent.replace(
|
|
624
626
|
/\/\/# sourceMappingURL=bundle-entry\.js\.map/,
|
|
625
627
|
`//# sourceMappingURL=${hashedMapName}`
|
|
626
628
|
);
|
|
627
|
-
await
|
|
628
|
-
await
|
|
629
|
+
await fs8__default.default.writeFile(path9__default.default.join(outputDir, hashedName), entryContent);
|
|
630
|
+
await fs8__default.default.unlink(entryPath);
|
|
629
631
|
try {
|
|
630
|
-
await
|
|
631
|
-
await
|
|
632
|
+
await fs8__default.default.access(mapPath);
|
|
633
|
+
await fs8__default.default.rename(mapPath, path9__default.default.join(outputDir, hashedMapName));
|
|
632
634
|
} catch {
|
|
633
635
|
}
|
|
634
636
|
logger.info(`Entry hashed: ${hashedName}`);
|
|
@@ -640,7 +642,7 @@ async function extractDataRequirements(themePath) {
|
|
|
640
642
|
const requirements = {};
|
|
641
643
|
for (const file of schemaFiles) {
|
|
642
644
|
try {
|
|
643
|
-
const mod = await jiti.import(
|
|
645
|
+
const mod = await jiti.import(path9__default.default.join(themePath, file));
|
|
644
646
|
const exports$1 = mod;
|
|
645
647
|
for (const value of Object.values(exports$1)) {
|
|
646
648
|
if (value && typeof value === "object" && typeof value.type === "string" && value.dataRequirements && typeof value.dataRequirements === "object") {
|
|
@@ -659,8 +661,8 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
659
661
|
let version2 = "1.0.0";
|
|
660
662
|
let themeId = themeName;
|
|
661
663
|
try {
|
|
662
|
-
const pkgContent = await
|
|
663
|
-
|
|
664
|
+
const pkgContent = await fs8__default.default.readFile(
|
|
665
|
+
path9__default.default.join(themePath, "package.json"),
|
|
664
666
|
"utf-8"
|
|
665
667
|
);
|
|
666
668
|
const pkg = JSON.parse(pkgContent);
|
|
@@ -678,7 +680,7 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
678
680
|
const dataRequirements = await extractDataRequirements(themePath);
|
|
679
681
|
let hasThemeConfig = false;
|
|
680
682
|
try {
|
|
681
|
-
await
|
|
683
|
+
await fs8__default.default.access(path9__default.default.join(themePath, "theme.config.ts"));
|
|
682
684
|
hasThemeConfig = true;
|
|
683
685
|
} catch {
|
|
684
686
|
}
|
|
@@ -719,24 +721,24 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
719
721
|
// Section data requirements for server-side prefetching (keyed by section type)
|
|
720
722
|
dataRequirements
|
|
721
723
|
};
|
|
722
|
-
await
|
|
723
|
-
|
|
724
|
+
await fs8__default.default.writeFile(
|
|
725
|
+
path9__default.default.join(outputDir, "manifest.json"),
|
|
724
726
|
JSON.stringify(manifest, null, 2)
|
|
725
727
|
);
|
|
726
728
|
}
|
|
727
729
|
async function compileStandaloneTheme(themePath, themeName) {
|
|
728
|
-
const outputDir =
|
|
729
|
-
const bundleEntry =
|
|
730
|
-
const indexEntry =
|
|
730
|
+
const outputDir = path9__default.default.join(themePath, "dist");
|
|
731
|
+
const bundleEntry = path9__default.default.join(themePath, "bundle-entry.ts");
|
|
732
|
+
const indexEntry = path9__default.default.join(themePath, "index.ts");
|
|
731
733
|
let entryPoint = indexEntry;
|
|
732
734
|
try {
|
|
733
|
-
await
|
|
735
|
+
await fs8__default.default.access(bundleEntry);
|
|
734
736
|
entryPoint = bundleEntry;
|
|
735
737
|
} catch {
|
|
736
738
|
}
|
|
737
|
-
const shimPath =
|
|
738
|
-
await
|
|
739
|
-
await
|
|
739
|
+
const shimPath = path9__default.default.join(outputDir, ".process-shim.js");
|
|
740
|
+
await fs8__default.default.mkdir(outputDir, { recursive: true });
|
|
741
|
+
await fs8__default.default.writeFile(shimPath, PROCESS_SHIM);
|
|
740
742
|
const buildOptions = {
|
|
741
743
|
entryPoints: [entryPoint],
|
|
742
744
|
bundle: true,
|
|
@@ -786,7 +788,7 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
786
788
|
try {
|
|
787
789
|
const result = await esbuild__namespace.build(buildOptions);
|
|
788
790
|
try {
|
|
789
|
-
await
|
|
791
|
+
await fs8__default.default.unlink(shimPath);
|
|
790
792
|
} catch {
|
|
791
793
|
}
|
|
792
794
|
await contentHashEntry(outputDir);
|
|
@@ -805,7 +807,7 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
805
807
|
return true;
|
|
806
808
|
} catch (error) {
|
|
807
809
|
try {
|
|
808
|
-
await
|
|
810
|
+
await fs8__default.default.unlink(shimPath);
|
|
809
811
|
} catch {
|
|
810
812
|
}
|
|
811
813
|
logger.error(`esbuild compilation failed: ${error}`);
|
|
@@ -813,18 +815,18 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
813
815
|
}
|
|
814
816
|
}
|
|
815
817
|
async function compileStandaloneThemeDev(themePath, themeName) {
|
|
816
|
-
const outputDir =
|
|
817
|
-
const bundleEntry =
|
|
818
|
-
const indexEntry =
|
|
818
|
+
const outputDir = path9__default.default.join(themePath, "dist");
|
|
819
|
+
const bundleEntry = path9__default.default.join(themePath, "bundle-entry.ts");
|
|
820
|
+
const indexEntry = path9__default.default.join(themePath, "index.ts");
|
|
819
821
|
let entryPoint = indexEntry;
|
|
820
822
|
try {
|
|
821
|
-
await
|
|
823
|
+
await fs8__default.default.access(bundleEntry);
|
|
822
824
|
entryPoint = bundleEntry;
|
|
823
825
|
} catch {
|
|
824
826
|
}
|
|
825
|
-
const shimPath =
|
|
826
|
-
await
|
|
827
|
-
await
|
|
827
|
+
const shimPath = path9__default.default.join(outputDir, ".process-shim.js");
|
|
828
|
+
await fs8__default.default.mkdir(outputDir, { recursive: true });
|
|
829
|
+
await fs8__default.default.writeFile(shimPath, PROCESS_SHIM);
|
|
828
830
|
const buildOptions = {
|
|
829
831
|
entryPoints: [entryPoint],
|
|
830
832
|
bundle: true,
|
|
@@ -877,18 +879,18 @@ async function compileStandaloneThemeDev(themePath, themeName) {
|
|
|
877
879
|
return { context: context2, outputDir };
|
|
878
880
|
}
|
|
879
881
|
async function compilePreviewRuntime(themePath) {
|
|
880
|
-
const outputDir =
|
|
881
|
-
await
|
|
882
|
-
const outputPath =
|
|
882
|
+
const outputDir = path9__default.default.join(themePath, "dist");
|
|
883
|
+
await fs8__default.default.mkdir(outputDir, { recursive: true });
|
|
884
|
+
const outputPath = path9__default.default.join(outputDir, "preview-runtime.js");
|
|
883
885
|
const locations = [
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
886
|
+
path9__default.default.join(__dirname, "..", "preview", "preview-app.tsx"),
|
|
887
|
+
path9__default.default.join(__dirname, "preview", "preview-app.tsx"),
|
|
888
|
+
path9__default.default.join(__dirname, "..", "..", "src", "preview", "preview-app.tsx")
|
|
887
889
|
];
|
|
888
890
|
let previewEntryPath = null;
|
|
889
891
|
for (const loc of locations) {
|
|
890
892
|
try {
|
|
891
|
-
await
|
|
893
|
+
await fs8__default.default.access(loc);
|
|
892
894
|
previewEntryPath = loc;
|
|
893
895
|
break;
|
|
894
896
|
} catch {
|
|
@@ -971,10 +973,10 @@ ${locations.join("\n")}`
|
|
|
971
973
|
if (!lucideScanned) {
|
|
972
974
|
lucideScanned = true;
|
|
973
975
|
const coreSrcCandidates = [
|
|
974
|
-
|
|
975
|
-
|
|
976
|
+
path9__default.default.join(themePath, "node_modules", "@onexapis", "core", "src"),
|
|
977
|
+
path9__default.default.join(themePath, "..", "..", "packages", "core", "src"),
|
|
976
978
|
// monorepo sibling
|
|
977
|
-
|
|
979
|
+
path9__default.default.join(
|
|
978
980
|
__dirname,
|
|
979
981
|
"..",
|
|
980
982
|
"..",
|
|
@@ -989,7 +991,7 @@ ${locations.join("\n")}`
|
|
|
989
991
|
let coreSourceDir = null;
|
|
990
992
|
for (const candidate of coreSrcCandidates) {
|
|
991
993
|
try {
|
|
992
|
-
await
|
|
994
|
+
await fs8__default.default.access(candidate);
|
|
993
995
|
coreSourceDir = candidate;
|
|
994
996
|
break;
|
|
995
997
|
} catch {
|
|
@@ -1008,21 +1010,21 @@ ${locations.join("\n")}`
|
|
|
1008
1010
|
}
|
|
1009
1011
|
} else {
|
|
1010
1012
|
const coreDistCandidates = [
|
|
1011
|
-
|
|
1013
|
+
path9__default.default.join(themePath, "node_modules", "@onexapis", "core", "dist")
|
|
1012
1014
|
];
|
|
1013
1015
|
const resolvedDist = await resolveNodeModulesFile(
|
|
1014
1016
|
__dirname,
|
|
1015
|
-
|
|
1017
|
+
path9__default.default.join("@onexapis", "core", "dist")
|
|
1016
1018
|
);
|
|
1017
1019
|
if (resolvedDist) coreDistCandidates.push(resolvedDist);
|
|
1018
1020
|
for (const candidate of coreDistCandidates) {
|
|
1019
1021
|
try {
|
|
1020
|
-
await
|
|
1022
|
+
await fs8__default.default.access(candidate);
|
|
1021
1023
|
const mjsFiles = await glob.glob("*.mjs", { cwd: candidate });
|
|
1022
1024
|
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']lucide-react["']/g;
|
|
1023
1025
|
for (const file of mjsFiles) {
|
|
1024
|
-
const content = await
|
|
1025
|
-
|
|
1026
|
+
const content = await fs8__default.default.readFile(
|
|
1027
|
+
path9__default.default.join(candidate, file),
|
|
1026
1028
|
"utf-8"
|
|
1027
1029
|
);
|
|
1028
1030
|
for (const match of content.matchAll(importRegex)) {
|
|
@@ -1077,7 +1079,7 @@ export default new Proxy({}, { get: (_, name) => name === '__esModule' ? true :
|
|
|
1077
1079
|
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
1080
|
const cjsPath = req.resolve("framer-motion");
|
|
1079
1081
|
const pkgDir = cjsPath.replace(/[/\\]dist[/\\].*$/, "");
|
|
1080
|
-
const esmEntry =
|
|
1082
|
+
const esmEntry = path9__default.default.join(pkgDir, "dist", "es", "index.mjs");
|
|
1081
1083
|
const { existsSync } = await import('fs');
|
|
1082
1084
|
if (existsSync(esmEntry)) {
|
|
1083
1085
|
return { path: esmEntry, namespace: "file" };
|
|
@@ -1176,8 +1178,8 @@ export function headers() { return new Headers(); }
|
|
|
1176
1178
|
});
|
|
1177
1179
|
}
|
|
1178
1180
|
};
|
|
1179
|
-
const shimPath =
|
|
1180
|
-
await
|
|
1181
|
+
const shimPath = path9__default.default.join(outputDir, ".process-shim-preview.js");
|
|
1182
|
+
await fs8__default.default.writeFile(shimPath, PROCESS_SHIM);
|
|
1181
1183
|
await esbuild__namespace.build({
|
|
1182
1184
|
entryPoints: [previewEntryPath],
|
|
1183
1185
|
bundle: true,
|
|
@@ -1212,7 +1214,7 @@ export function headers() { return new Headers(); }
|
|
|
1212
1214
|
}
|
|
1213
1215
|
});
|
|
1214
1216
|
try {
|
|
1215
|
-
await
|
|
1217
|
+
await fs8__default.default.unlink(shimPath);
|
|
1216
1218
|
} catch {
|
|
1217
1219
|
}
|
|
1218
1220
|
return outputPath;
|
|
@@ -1345,18 +1347,18 @@ async function renderTemplate(templatePath, data) {
|
|
|
1345
1347
|
return ejs__default.default.render(template, data);
|
|
1346
1348
|
}
|
|
1347
1349
|
async function writeFile(filePath, content) {
|
|
1348
|
-
await fs__default.default.ensureDir(
|
|
1350
|
+
await fs__default.default.ensureDir(path9__default.default.dirname(filePath));
|
|
1349
1351
|
await fs__default.default.writeFile(filePath, content, "utf-8");
|
|
1350
1352
|
}
|
|
1351
1353
|
function getTemplatesDir() {
|
|
1352
1354
|
const locations = [
|
|
1353
|
-
|
|
1355
|
+
path9__default.default.join(__dirname, "../../templates"),
|
|
1354
1356
|
// Development
|
|
1355
|
-
|
|
1357
|
+
path9__default.default.join(__dirname, "../templates"),
|
|
1356
1358
|
// Production (dist/)
|
|
1357
|
-
|
|
1359
|
+
path9__default.default.join(process.cwd(), "templates"),
|
|
1358
1360
|
// Fallback
|
|
1359
|
-
|
|
1361
|
+
path9__default.default.join(process.cwd(), "packages/cli/templates")
|
|
1360
1362
|
// Monorepo
|
|
1361
1363
|
];
|
|
1362
1364
|
for (const location of locations) {
|
|
@@ -1368,7 +1370,7 @@ function getTemplatesDir() {
|
|
|
1368
1370
|
}
|
|
1369
1371
|
async function copyTemplate(templateName, targetDir, data) {
|
|
1370
1372
|
const templatesDir = getTemplatesDir();
|
|
1371
|
-
const templateDir =
|
|
1373
|
+
const templateDir = path9__default.default.join(templatesDir, templateName);
|
|
1372
1374
|
if (!fs__default.default.existsSync(templateDir)) {
|
|
1373
1375
|
throw new Error(
|
|
1374
1376
|
`Template "${templateName}" not found at ${templateDir}. Available templates: ${fs__default.default.readdirSync(templatesDir).join(", ")}`
|
|
@@ -1377,8 +1379,8 @@ async function copyTemplate(templateName, targetDir, data) {
|
|
|
1377
1379
|
await fs__default.default.ensureDir(targetDir);
|
|
1378
1380
|
const files = await fs__default.default.readdir(templateDir);
|
|
1379
1381
|
for (const file of files) {
|
|
1380
|
-
const templatePath =
|
|
1381
|
-
const targetPath =
|
|
1382
|
+
const templatePath = path9__default.default.join(templateDir, file);
|
|
1383
|
+
const targetPath = path9__default.default.join(targetDir, file);
|
|
1382
1384
|
const stat = await fs__default.default.stat(templatePath);
|
|
1383
1385
|
if (stat.isDirectory()) {
|
|
1384
1386
|
await copyTemplateDir(templatePath, targetPath, data);
|
|
@@ -1395,8 +1397,8 @@ async function copyTemplateDir(templateDir, targetDir, data) {
|
|
|
1395
1397
|
await fs__default.default.ensureDir(targetDir);
|
|
1396
1398
|
const files = await fs__default.default.readdir(templateDir);
|
|
1397
1399
|
for (const file of files) {
|
|
1398
|
-
const templatePath =
|
|
1399
|
-
const targetPath =
|
|
1400
|
+
const templatePath = path9__default.default.join(templateDir, file);
|
|
1401
|
+
const targetPath = path9__default.default.join(targetDir, file);
|
|
1400
1402
|
const stat = await fs__default.default.stat(templatePath);
|
|
1401
1403
|
if (stat.isDirectory()) {
|
|
1402
1404
|
await copyTemplateDir(templatePath, targetPath, data);
|
|
@@ -1411,32 +1413,32 @@ async function copyTemplateDir(templateDir, targetDir, data) {
|
|
|
1411
1413
|
}
|
|
1412
1414
|
function getProjectRoot() {
|
|
1413
1415
|
let currentDir = process.cwd();
|
|
1414
|
-
while (currentDir !==
|
|
1415
|
-
const packageJsonPath =
|
|
1416
|
+
while (currentDir !== path9__default.default.parse(currentDir).root) {
|
|
1417
|
+
const packageJsonPath = path9__default.default.join(currentDir, "package.json");
|
|
1416
1418
|
if (fs__default.default.existsSync(packageJsonPath)) {
|
|
1417
1419
|
const packageJson = fs__default.default.readJsonSync(packageJsonPath);
|
|
1418
|
-
if (packageJson.workspaces || fs__default.default.existsSync(
|
|
1420
|
+
if (packageJson.workspaces || fs__default.default.existsSync(path9__default.default.join(currentDir, "src/themes")) || fs__default.default.existsSync(path9__default.default.join(currentDir, "themes"))) {
|
|
1419
1421
|
return currentDir;
|
|
1420
1422
|
}
|
|
1421
1423
|
}
|
|
1422
|
-
currentDir =
|
|
1424
|
+
currentDir = path9__default.default.dirname(currentDir);
|
|
1423
1425
|
}
|
|
1424
1426
|
return process.cwd();
|
|
1425
1427
|
}
|
|
1426
1428
|
function getThemesDir() {
|
|
1427
1429
|
const root = getProjectRoot();
|
|
1428
|
-
if (fs__default.default.existsSync(
|
|
1429
|
-
return
|
|
1430
|
-
if (fs__default.default.existsSync(
|
|
1431
|
-
return
|
|
1432
|
-
return
|
|
1430
|
+
if (fs__default.default.existsSync(path9__default.default.join(root, "themes")))
|
|
1431
|
+
return path9__default.default.join(root, "themes");
|
|
1432
|
+
if (fs__default.default.existsSync(path9__default.default.join(root, "src/themes")))
|
|
1433
|
+
return path9__default.default.join(root, "src/themes");
|
|
1434
|
+
return path9__default.default.dirname(root);
|
|
1433
1435
|
}
|
|
1434
1436
|
function getFeaturesDir() {
|
|
1435
|
-
return
|
|
1437
|
+
return path9__default.default.join(getProjectRoot(), "src/features");
|
|
1436
1438
|
}
|
|
1437
1439
|
function isOneXProject() {
|
|
1438
1440
|
const root = getProjectRoot();
|
|
1439
|
-
return fs__default.default.existsSync(
|
|
1441
|
+
return fs__default.default.existsSync(path9__default.default.join(root, "themes")) || fs__default.default.existsSync(path9__default.default.join(root, "src/themes")) || fs__default.default.existsSync(path9__default.default.join(root, "theme.config.ts")) || fs__default.default.existsSync(path9__default.default.join(root, "bundle-entry.ts"));
|
|
1440
1442
|
}
|
|
1441
1443
|
function ensureOneXProject() {
|
|
1442
1444
|
if (!isOneXProject()) {
|
|
@@ -1452,13 +1454,13 @@ function listThemes() {
|
|
|
1452
1454
|
return [];
|
|
1453
1455
|
}
|
|
1454
1456
|
return fs__default.default.readdirSync(themesDir).filter((name) => {
|
|
1455
|
-
const themePath =
|
|
1456
|
-
return fs__default.default.statSync(themePath).isDirectory() && (fs__default.default.existsSync(
|
|
1457
|
+
const themePath = path9__default.default.join(themesDir, name);
|
|
1458
|
+
return fs__default.default.statSync(themePath).isDirectory() && (fs__default.default.existsSync(path9__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path9__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path9__default.default.join(themePath, "manifest.ts")));
|
|
1457
1459
|
});
|
|
1458
1460
|
}
|
|
1459
1461
|
function themeExists(themeName) {
|
|
1460
|
-
const themePath =
|
|
1461
|
-
return fs__default.default.existsSync(themePath) && (fs__default.default.existsSync(
|
|
1462
|
+
const themePath = path9__default.default.join(getThemesDir(), themeName);
|
|
1463
|
+
return fs__default.default.existsSync(themePath) && (fs__default.default.existsSync(path9__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path9__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path9__default.default.join(themePath, "manifest.ts")));
|
|
1462
1464
|
}
|
|
1463
1465
|
function detectPackageManager() {
|
|
1464
1466
|
const userAgent = process.env.npm_config_user_agent || "";
|
|
@@ -1466,9 +1468,9 @@ function detectPackageManager() {
|
|
|
1466
1468
|
if (userAgent.includes("yarn")) return "yarn";
|
|
1467
1469
|
if (userAgent.includes("bun")) return "bun";
|
|
1468
1470
|
const cwd = process.cwd();
|
|
1469
|
-
if (fs__default.default.existsSync(
|
|
1470
|
-
if (fs__default.default.existsSync(
|
|
1471
|
-
if (fs__default.default.existsSync(
|
|
1471
|
+
if (fs__default.default.existsSync(path9__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
1472
|
+
if (fs__default.default.existsSync(path9__default.default.join(cwd, "yarn.lock"))) return "yarn";
|
|
1473
|
+
if (fs__default.default.existsSync(path9__default.default.join(cwd, "bun.lockb"))) return "bun";
|
|
1472
1474
|
return "npm";
|
|
1473
1475
|
}
|
|
1474
1476
|
async function installDependencies(projectPath, packageManager = "npm") {
|
|
@@ -1517,6 +1519,120 @@ function getValidCategories() {
|
|
|
1517
1519
|
"contact"
|
|
1518
1520
|
];
|
|
1519
1521
|
}
|
|
1522
|
+
var AUTH_DIR = path9__default.default.join(os__default.default.homedir(), ".onexthm");
|
|
1523
|
+
var AUTH_FILE = path9__default.default.join(AUTH_DIR, "auth.json");
|
|
1524
|
+
function getApiUrl() {
|
|
1525
|
+
return process.env.ONEXTHM_API_URL || process.env.NEXT_PUBLIC_API_URL || "https://platform-dev.onexeos.com";
|
|
1526
|
+
}
|
|
1527
|
+
async function saveAuthTokens(tokens) {
|
|
1528
|
+
await fs__default.default.ensureDir(AUTH_DIR);
|
|
1529
|
+
const key = getMachineKey();
|
|
1530
|
+
const data = JSON.stringify(tokens);
|
|
1531
|
+
const encrypted = encrypt(data, key);
|
|
1532
|
+
await fs__default.default.writeFile(AUTH_FILE, encrypted, "utf-8");
|
|
1533
|
+
}
|
|
1534
|
+
function loadAuthTokens() {
|
|
1535
|
+
try {
|
|
1536
|
+
if (!fs__default.default.existsSync(AUTH_FILE)) return null;
|
|
1537
|
+
const encrypted = fs__default.default.readFileSync(AUTH_FILE, "utf-8");
|
|
1538
|
+
const key = getMachineKey();
|
|
1539
|
+
const data = decrypt(encrypted, key);
|
|
1540
|
+
return JSON.parse(data);
|
|
1541
|
+
} catch {
|
|
1542
|
+
return null;
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
async function clearAuthTokens() {
|
|
1546
|
+
try {
|
|
1547
|
+
await fs__default.default.remove(AUTH_FILE);
|
|
1548
|
+
} catch {
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
function isTokenExpired(tokens) {
|
|
1552
|
+
return Date.now() / 1e3 > tokens.expiresAt - 60;
|
|
1553
|
+
}
|
|
1554
|
+
async function getValidTokens() {
|
|
1555
|
+
const tokens = loadAuthTokens();
|
|
1556
|
+
if (!tokens) return null;
|
|
1557
|
+
if (!isTokenExpired(tokens)) return tokens;
|
|
1558
|
+
try {
|
|
1559
|
+
const apiUrl = getApiUrl();
|
|
1560
|
+
const response = await fetch(`${apiUrl}/auth/refresh`, {
|
|
1561
|
+
method: "POST",
|
|
1562
|
+
headers: { "Content-Type": "application/json" },
|
|
1563
|
+
body: JSON.stringify({ refresh_token: tokens.refreshToken })
|
|
1564
|
+
});
|
|
1565
|
+
if (!response.ok) {
|
|
1566
|
+
await clearAuthTokens();
|
|
1567
|
+
return null;
|
|
1568
|
+
}
|
|
1569
|
+
const data = await response.json();
|
|
1570
|
+
const body = data.statusCode ? data.body : data;
|
|
1571
|
+
const refreshed = {
|
|
1572
|
+
...tokens,
|
|
1573
|
+
accessToken: body.AccessToken || tokens.accessToken,
|
|
1574
|
+
idToken: body.IdToken || tokens.idToken,
|
|
1575
|
+
expiresAt: Math.floor(Date.now() / 1e3) + (body.ExpiresIn || 3600)
|
|
1576
|
+
};
|
|
1577
|
+
await saveAuthTokens(refreshed);
|
|
1578
|
+
return refreshed;
|
|
1579
|
+
} catch {
|
|
1580
|
+
await clearAuthTokens();
|
|
1581
|
+
return null;
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
async function authenticatedFetch(url, init) {
|
|
1585
|
+
const tokens = await getValidTokens();
|
|
1586
|
+
if (!tokens) {
|
|
1587
|
+
throw new Error("Not logged in. Run: onexthm login");
|
|
1588
|
+
}
|
|
1589
|
+
const headers = new Headers(init?.headers);
|
|
1590
|
+
headers.set("Authorization", `Bearer ${tokens.idToken}`);
|
|
1591
|
+
headers.set("Content-Type", "application/json");
|
|
1592
|
+
return fetch(url, { ...init, headers });
|
|
1593
|
+
}
|
|
1594
|
+
function getMachineKey() {
|
|
1595
|
+
let seed;
|
|
1596
|
+
if (process.platform === "darwin") {
|
|
1597
|
+
seed = `onexthm:${os__default.default.hostname()}:${os__default.default.userInfo().username}`;
|
|
1598
|
+
} else if (process.platform === "linux") {
|
|
1599
|
+
try {
|
|
1600
|
+
seed = `onexthm:${fs__default.default.readFileSync("/etc/machine-id", "utf-8").trim()}`;
|
|
1601
|
+
} catch {
|
|
1602
|
+
seed = `onexthm:${os__default.default.hostname()}:${os__default.default.userInfo().username}`;
|
|
1603
|
+
}
|
|
1604
|
+
} else {
|
|
1605
|
+
seed = `onexthm:${os__default.default.hostname()}:${os__default.default.userInfo().username}`;
|
|
1606
|
+
}
|
|
1607
|
+
return crypto__default.default.createHash("sha256").update(seed).digest();
|
|
1608
|
+
}
|
|
1609
|
+
function encrypt(text, key) {
|
|
1610
|
+
const iv = crypto__default.default.randomBytes(16);
|
|
1611
|
+
const cipher = crypto__default.default.createCipheriv("aes-256-gcm", key, iv);
|
|
1612
|
+
let encrypted = cipher.update(text, "utf-8", "hex");
|
|
1613
|
+
encrypted += cipher.final("hex");
|
|
1614
|
+
const tag = cipher.getAuthTag();
|
|
1615
|
+
return `${iv.toString("hex")}:${tag.toString("hex")}:${encrypted}`;
|
|
1616
|
+
}
|
|
1617
|
+
function decrypt(text, key) {
|
|
1618
|
+
const [ivHex, tagHex, encrypted] = text.split(":");
|
|
1619
|
+
const iv = Buffer.from(ivHex, "hex");
|
|
1620
|
+
const tag = Buffer.from(tagHex, "hex");
|
|
1621
|
+
const decipher = crypto__default.default.createDecipheriv("aes-256-gcm", key, iv);
|
|
1622
|
+
decipher.setAuthTag(tag);
|
|
1623
|
+
let decrypted = decipher.update(encrypted, "hex", "utf-8");
|
|
1624
|
+
decrypted += decipher.final("utf-8");
|
|
1625
|
+
return decrypted;
|
|
1626
|
+
}
|
|
1627
|
+
function parseJwtClaims(idToken) {
|
|
1628
|
+
try {
|
|
1629
|
+
const payload = idToken.split(".")[1];
|
|
1630
|
+
const decoded = Buffer.from(payload, "base64url").toString("utf-8");
|
|
1631
|
+
return JSON.parse(decoded);
|
|
1632
|
+
} catch {
|
|
1633
|
+
return {};
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1520
1636
|
|
|
1521
1637
|
// src/commands/init.ts
|
|
1522
1638
|
async function initCommand(projectName, options = {}) {
|
|
@@ -1534,7 +1650,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1534
1650
|
if (!validateThemeName(kebabName)) {
|
|
1535
1651
|
return "Invalid project name. Use lowercase letters, numbers, and hyphens only.";
|
|
1536
1652
|
}
|
|
1537
|
-
if (
|
|
1653
|
+
if (fs3__default.default.existsSync(path9__default.default.join(process.cwd(), kebabName))) {
|
|
1538
1654
|
return `Directory "${kebabName}" already exists`;
|
|
1539
1655
|
}
|
|
1540
1656
|
return true;
|
|
@@ -1545,11 +1661,46 @@ async function initCommand(projectName, options = {}) {
|
|
|
1545
1661
|
} else {
|
|
1546
1662
|
name = toKebabCase(projectName);
|
|
1547
1663
|
}
|
|
1548
|
-
const projectPath =
|
|
1549
|
-
if (
|
|
1664
|
+
const projectPath = path9__default.default.join(process.cwd(), name);
|
|
1665
|
+
if (fs3__default.default.existsSync(projectPath)) {
|
|
1550
1666
|
logger.error(`Directory "${name}" already exists.`);
|
|
1551
1667
|
process.exit(1);
|
|
1552
1668
|
}
|
|
1669
|
+
if (!options.yes) {
|
|
1670
|
+
try {
|
|
1671
|
+
const apiUrl = getApiUrl();
|
|
1672
|
+
const controller = new AbortController();
|
|
1673
|
+
const timeout = setTimeout(() => controller.abort(), 3e3);
|
|
1674
|
+
const response = await fetch(
|
|
1675
|
+
`${apiUrl}/website-api/themes/${encodeURIComponent(name)}/exists`,
|
|
1676
|
+
{ signal: controller.signal }
|
|
1677
|
+
);
|
|
1678
|
+
clearTimeout(timeout);
|
|
1679
|
+
if (response.ok) {
|
|
1680
|
+
const data2 = await response.json();
|
|
1681
|
+
const body = data2.statusCode ? data2.body : data2;
|
|
1682
|
+
if (body.exists && body.owner === "other") {
|
|
1683
|
+
logger.warning(
|
|
1684
|
+
`Theme ID "${name}" is already registered by another developer.
|
|
1685
|
+
You can still create this locally, but publishing will fail.
|
|
1686
|
+
Consider using a different name.`
|
|
1687
|
+
);
|
|
1688
|
+
const { proceed } = await inquirer__default.default.prompt([
|
|
1689
|
+
{
|
|
1690
|
+
type: "confirm",
|
|
1691
|
+
name: "proceed",
|
|
1692
|
+
message: "Continue anyway?",
|
|
1693
|
+
default: false
|
|
1694
|
+
}
|
|
1695
|
+
]);
|
|
1696
|
+
if (!proceed) {
|
|
1697
|
+
process.exit(0);
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
}
|
|
1701
|
+
} catch {
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1553
1704
|
let displayName;
|
|
1554
1705
|
let description;
|
|
1555
1706
|
let author;
|
|
@@ -1617,7 +1768,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1617
1768
|
}
|
|
1618
1769
|
logger.startSpinner("Creating project structure...");
|
|
1619
1770
|
try {
|
|
1620
|
-
|
|
1771
|
+
fs3__default.default.mkdirSync(projectPath, { recursive: true });
|
|
1621
1772
|
await copyTemplate(template, projectPath, data);
|
|
1622
1773
|
await renameThemeInFiles(
|
|
1623
1774
|
projectPath,
|
|
@@ -1626,9 +1777,9 @@ async function initCommand(projectName, options = {}) {
|
|
|
1626
1777
|
description,
|
|
1627
1778
|
author
|
|
1628
1779
|
);
|
|
1629
|
-
const mcpJsonPath =
|
|
1630
|
-
if (
|
|
1631
|
-
let mcpContent =
|
|
1780
|
+
const mcpJsonPath = path9__default.default.join(projectPath, ".mcp.json");
|
|
1781
|
+
if (fs3__default.default.existsSync(mcpJsonPath)) {
|
|
1782
|
+
let mcpContent = fs3__default.default.readFileSync(mcpJsonPath, "utf-8");
|
|
1632
1783
|
if (figmaApiKey) {
|
|
1633
1784
|
mcpContent = mcpContent.replace("__FIGMA_API_KEY__", figmaApiKey);
|
|
1634
1785
|
} else {
|
|
@@ -1639,7 +1790,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1639
1790
|
} catch {
|
|
1640
1791
|
}
|
|
1641
1792
|
}
|
|
1642
|
-
|
|
1793
|
+
fs3__default.default.writeFileSync(mcpJsonPath, mcpContent, "utf-8");
|
|
1643
1794
|
}
|
|
1644
1795
|
logger.stopSpinner(true, "Project structure created!");
|
|
1645
1796
|
if (options.git) {
|
|
@@ -1699,16 +1850,16 @@ async function initCommand(projectName, options = {}) {
|
|
|
1699
1850
|
logger.error(
|
|
1700
1851
|
error instanceof Error ? error.message : "Unknown error occurred"
|
|
1701
1852
|
);
|
|
1702
|
-
if (
|
|
1703
|
-
|
|
1853
|
+
if (fs3__default.default.existsSync(projectPath)) {
|
|
1854
|
+
fs3__default.default.rmSync(projectPath, { recursive: true, force: true });
|
|
1704
1855
|
}
|
|
1705
1856
|
process.exit(1);
|
|
1706
1857
|
}
|
|
1707
1858
|
}
|
|
1708
1859
|
async function renameThemeInFiles(projectPath, themeName, displayName, description, author) {
|
|
1709
|
-
const configPath =
|
|
1710
|
-
if (
|
|
1711
|
-
let content =
|
|
1860
|
+
const configPath = path9__default.default.join(projectPath, "theme.config.ts");
|
|
1861
|
+
if (fs3__default.default.existsSync(configPath)) {
|
|
1862
|
+
let content = fs3__default.default.readFileSync(configPath, "utf-8");
|
|
1712
1863
|
content = content.replace(
|
|
1713
1864
|
/name: "My Simple Theme"/,
|
|
1714
1865
|
`name: "${displayName}"`
|
|
@@ -1717,11 +1868,11 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
|
|
|
1717
1868
|
/description: ".*?"/,
|
|
1718
1869
|
`description: "${description}"`
|
|
1719
1870
|
);
|
|
1720
|
-
|
|
1871
|
+
fs3__default.default.writeFileSync(configPath, content, "utf-8");
|
|
1721
1872
|
}
|
|
1722
|
-
const pkgPath =
|
|
1723
|
-
if (
|
|
1724
|
-
let content =
|
|
1873
|
+
const pkgPath = path9__default.default.join(projectPath, "package.json");
|
|
1874
|
+
if (fs3__default.default.existsSync(pkgPath)) {
|
|
1875
|
+
let content = fs3__default.default.readFileSync(pkgPath, "utf-8");
|
|
1725
1876
|
content = content.replace(
|
|
1726
1877
|
/@onex-themes\/my-simple/g,
|
|
1727
1878
|
`@onex-themes/${themeName}`
|
|
@@ -1730,7 +1881,7 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
|
|
|
1730
1881
|
/"description": ".*?"/,
|
|
1731
1882
|
`"description": "${description}"`
|
|
1732
1883
|
);
|
|
1733
|
-
|
|
1884
|
+
fs3__default.default.writeFileSync(pkgPath, content, "utf-8");
|
|
1734
1885
|
}
|
|
1735
1886
|
}
|
|
1736
1887
|
|
|
@@ -1741,10 +1892,10 @@ async function createSectionCommand(name, options) {
|
|
|
1741
1892
|
ensureOneXProject();
|
|
1742
1893
|
if (!options.theme) {
|
|
1743
1894
|
const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
|
|
1744
|
-
(f) => fs__default.default.existsSync(
|
|
1895
|
+
(f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f))
|
|
1745
1896
|
);
|
|
1746
1897
|
if (isStandaloneTheme) {
|
|
1747
|
-
options.theme =
|
|
1898
|
+
options.theme = path9__default.default.basename(process.cwd());
|
|
1748
1899
|
}
|
|
1749
1900
|
}
|
|
1750
1901
|
const sectionName = toKebabCase(name);
|
|
@@ -1807,35 +1958,35 @@ async function createSectionCommand(name, options) {
|
|
|
1807
1958
|
};
|
|
1808
1959
|
logger.startSpinner("Creating section files...");
|
|
1809
1960
|
try {
|
|
1810
|
-
const themePath =
|
|
1811
|
-
const sectionPath =
|
|
1961
|
+
const themePath = path9__default.default.join(getThemesDir(), themeName);
|
|
1962
|
+
const sectionPath = path9__default.default.join(themePath, "sections", sectionName);
|
|
1812
1963
|
const schemaContent = generateSectionSchema(data);
|
|
1813
1964
|
await writeFile(
|
|
1814
|
-
|
|
1965
|
+
path9__default.default.join(sectionPath, `${sectionName}.schema.ts`),
|
|
1815
1966
|
schemaContent
|
|
1816
1967
|
);
|
|
1817
1968
|
if (createTemplate) {
|
|
1818
1969
|
const templateContent = generateSectionTemplate(data);
|
|
1819
1970
|
await writeFile(
|
|
1820
|
-
|
|
1971
|
+
path9__default.default.join(sectionPath, `${sectionName}-default.tsx`),
|
|
1821
1972
|
templateContent
|
|
1822
1973
|
);
|
|
1823
1974
|
}
|
|
1824
1975
|
const indexContent = generateSectionIndex(data, createTemplate);
|
|
1825
|
-
await writeFile(
|
|
1976
|
+
await writeFile(path9__default.default.join(sectionPath, "index.ts"), indexContent);
|
|
1826
1977
|
logger.stopSpinner(true, "Section files created successfully!");
|
|
1827
1978
|
logger.newLine();
|
|
1828
1979
|
logger.section("Next steps:");
|
|
1829
1980
|
logger.log(
|
|
1830
|
-
` 1. Edit schema: ${
|
|
1981
|
+
` 1. Edit schema: ${path9__default.default.relative(process.cwd(), path9__default.default.join(sectionPath, `${sectionName}.schema.ts`))}`
|
|
1831
1982
|
);
|
|
1832
1983
|
if (createTemplate) {
|
|
1833
1984
|
logger.log(
|
|
1834
|
-
` 2. Edit template: ${
|
|
1985
|
+
` 2. Edit template: ${path9__default.default.relative(process.cwd(), path9__default.default.join(sectionPath, `${sectionName}-default.tsx`))}`
|
|
1835
1986
|
);
|
|
1836
1987
|
}
|
|
1837
1988
|
logger.log(
|
|
1838
|
-
` 3. Add to theme manifest: ${
|
|
1989
|
+
` 3. Add to theme manifest: ${path9__default.default.relative(process.cwd(), path9__default.default.join(themePath, "manifest.ts"))}`
|
|
1839
1990
|
);
|
|
1840
1991
|
logger.newLine();
|
|
1841
1992
|
logger.success("Section created successfully!");
|
|
@@ -1983,10 +2134,10 @@ async function createBlockCommand(name, options) {
|
|
|
1983
2134
|
ensureOneXProject();
|
|
1984
2135
|
if (!options.theme) {
|
|
1985
2136
|
const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
|
|
1986
|
-
(f) => fs__default.default.existsSync(
|
|
2137
|
+
(f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f))
|
|
1987
2138
|
);
|
|
1988
2139
|
if (isStandaloneTheme) {
|
|
1989
|
-
options.theme =
|
|
2140
|
+
options.theme = path9__default.default.basename(process.cwd());
|
|
1990
2141
|
}
|
|
1991
2142
|
}
|
|
1992
2143
|
const blockName = toKebabCase(name);
|
|
@@ -2061,24 +2212,24 @@ async function createBlockCommand(name, options) {
|
|
|
2061
2212
|
};
|
|
2062
2213
|
logger.startSpinner("Creating block files...");
|
|
2063
2214
|
try {
|
|
2064
|
-
const blockPath = scope === "shared" ?
|
|
2215
|
+
const blockPath = scope === "shared" ? path9__default.default.join(getFeaturesDir(), "blocks", blockName) : path9__default.default.join(getThemesDir(), themeName, "blocks", blockName);
|
|
2065
2216
|
const schemaContent = generateBlockSchema(data);
|
|
2066
2217
|
await writeFile(
|
|
2067
|
-
|
|
2218
|
+
path9__default.default.join(blockPath, `${blockName}.schema.ts`),
|
|
2068
2219
|
schemaContent
|
|
2069
2220
|
);
|
|
2070
2221
|
const componentContent = generateBlockComponent(data);
|
|
2071
|
-
await writeFile(
|
|
2222
|
+
await writeFile(path9__default.default.join(blockPath, `${blockName}.tsx`), componentContent);
|
|
2072
2223
|
const indexContent = generateBlockIndex(data);
|
|
2073
|
-
await writeFile(
|
|
2224
|
+
await writeFile(path9__default.default.join(blockPath, "index.ts"), indexContent);
|
|
2074
2225
|
logger.stopSpinner(true, "Block files created successfully!");
|
|
2075
2226
|
logger.newLine();
|
|
2076
2227
|
logger.section("Next steps:");
|
|
2077
2228
|
logger.log(
|
|
2078
|
-
` 1. Edit schema: ${
|
|
2229
|
+
` 1. Edit schema: ${path9__default.default.relative(process.cwd(), path9__default.default.join(blockPath, `${blockName}.schema.ts`))}`
|
|
2079
2230
|
);
|
|
2080
2231
|
logger.log(
|
|
2081
|
-
` 2. Edit component: ${
|
|
2232
|
+
` 2. Edit component: ${path9__default.default.relative(process.cwd(), path9__default.default.join(blockPath, `${blockName}.tsx`))}`
|
|
2082
2233
|
);
|
|
2083
2234
|
logger.log(
|
|
2084
2235
|
` 3. Register in block registry: src/lib/registry/block-registry.ts`
|
|
@@ -2256,31 +2407,31 @@ async function createComponentCommand(name, options) {
|
|
|
2256
2407
|
};
|
|
2257
2408
|
logger.startSpinner("Creating component files...");
|
|
2258
2409
|
try {
|
|
2259
|
-
const componentPath =
|
|
2410
|
+
const componentPath = path9__default.default.join(
|
|
2260
2411
|
getFeaturesDir(),
|
|
2261
2412
|
"components",
|
|
2262
2413
|
componentName
|
|
2263
2414
|
);
|
|
2264
2415
|
const schemaContent = generateComponentSchema(data);
|
|
2265
2416
|
await writeFile(
|
|
2266
|
-
|
|
2417
|
+
path9__default.default.join(componentPath, `${componentName}.schema.ts`),
|
|
2267
2418
|
schemaContent
|
|
2268
2419
|
);
|
|
2269
2420
|
const componentContent = generateComponent(data);
|
|
2270
2421
|
await writeFile(
|
|
2271
|
-
|
|
2422
|
+
path9__default.default.join(componentPath, `${componentName}.tsx`),
|
|
2272
2423
|
componentContent
|
|
2273
2424
|
);
|
|
2274
2425
|
const indexContent = generateComponentIndex(data);
|
|
2275
|
-
await writeFile(
|
|
2426
|
+
await writeFile(path9__default.default.join(componentPath, "index.ts"), indexContent);
|
|
2276
2427
|
logger.stopSpinner(true, "Component files created successfully!");
|
|
2277
2428
|
logger.newLine();
|
|
2278
2429
|
logger.section("Next steps:");
|
|
2279
2430
|
logger.log(
|
|
2280
|
-
` 1. Edit schema: ${
|
|
2431
|
+
` 1. Edit schema: ${path9__default.default.relative(process.cwd(), path9__default.default.join(componentPath, `${componentName}.schema.ts`))}`
|
|
2281
2432
|
);
|
|
2282
2433
|
logger.log(
|
|
2283
|
-
` 2. Edit component: ${
|
|
2434
|
+
` 2. Edit component: ${path9__default.default.relative(process.cwd(), path9__default.default.join(componentPath, `${componentName}.tsx`))}`
|
|
2284
2435
|
);
|
|
2285
2436
|
logger.log(
|
|
2286
2437
|
` 3. Register in component registry: src/lib/registry/component-registry.ts`
|
|
@@ -2437,13 +2588,13 @@ async function listSections(themeFilter) {
|
|
|
2437
2588
|
return;
|
|
2438
2589
|
}
|
|
2439
2590
|
for (const theme of themes) {
|
|
2440
|
-
const sectionsDir =
|
|
2591
|
+
const sectionsDir = path9__default.default.join(getThemesDir(), theme, "sections");
|
|
2441
2592
|
if (!fs__default.default.existsSync(sectionsDir)) {
|
|
2442
2593
|
continue;
|
|
2443
2594
|
}
|
|
2444
2595
|
const sections = fs__default.default.readdirSync(sectionsDir).filter((name) => {
|
|
2445
|
-
const sectionPath =
|
|
2446
|
-
return fs__default.default.statSync(sectionPath).isDirectory() && fs__default.default.existsSync(
|
|
2596
|
+
const sectionPath = path9__default.default.join(sectionsDir, name);
|
|
2597
|
+
return fs__default.default.statSync(sectionPath).isDirectory() && fs__default.default.existsSync(path9__default.default.join(sectionPath, "index.ts"));
|
|
2447
2598
|
});
|
|
2448
2599
|
if (sections.length > 0) {
|
|
2449
2600
|
logger.log(chalk4__default.default.cyan(`
|
|
@@ -2457,11 +2608,11 @@ async function listSections(themeFilter) {
|
|
|
2457
2608
|
}
|
|
2458
2609
|
async function listBlocks(themeFilter) {
|
|
2459
2610
|
logger.section("\u{1F9F1} Blocks");
|
|
2460
|
-
const sharedBlocksDir =
|
|
2611
|
+
const sharedBlocksDir = path9__default.default.join(getFeaturesDir(), "blocks");
|
|
2461
2612
|
if (fs__default.default.existsSync(sharedBlocksDir)) {
|
|
2462
2613
|
const sharedBlocks = fs__default.default.readdirSync(sharedBlocksDir).filter((name) => {
|
|
2463
|
-
const blockPath =
|
|
2464
|
-
return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(
|
|
2614
|
+
const blockPath = path9__default.default.join(sharedBlocksDir, name);
|
|
2615
|
+
return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path9__default.default.join(blockPath, "index.ts"));
|
|
2465
2616
|
});
|
|
2466
2617
|
if (sharedBlocks.length > 0) {
|
|
2467
2618
|
logger.log(chalk4__default.default.cyan("\n Shared:"));
|
|
@@ -2472,13 +2623,13 @@ async function listBlocks(themeFilter) {
|
|
|
2472
2623
|
}
|
|
2473
2624
|
const themes = themeFilter ? [themeFilter] : listThemes();
|
|
2474
2625
|
for (const theme of themes) {
|
|
2475
|
-
const blocksDir =
|
|
2626
|
+
const blocksDir = path9__default.default.join(getThemesDir(), theme, "blocks");
|
|
2476
2627
|
if (!fs__default.default.existsSync(blocksDir)) {
|
|
2477
2628
|
continue;
|
|
2478
2629
|
}
|
|
2479
2630
|
const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => {
|
|
2480
|
-
const blockPath =
|
|
2481
|
-
return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(
|
|
2631
|
+
const blockPath = path9__default.default.join(blocksDir, name);
|
|
2632
|
+
return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path9__default.default.join(blockPath, "index.ts"));
|
|
2482
2633
|
});
|
|
2483
2634
|
if (blocks.length > 0) {
|
|
2484
2635
|
logger.log(chalk4__default.default.cyan(`
|
|
@@ -2492,14 +2643,14 @@ async function listBlocks(themeFilter) {
|
|
|
2492
2643
|
}
|
|
2493
2644
|
async function listComponents() {
|
|
2494
2645
|
logger.section("\u2699\uFE0F Components");
|
|
2495
|
-
const componentsDir =
|
|
2646
|
+
const componentsDir = path9__default.default.join(getFeaturesDir(), "components");
|
|
2496
2647
|
if (!fs__default.default.existsSync(componentsDir)) {
|
|
2497
2648
|
logger.warning("No components directory found");
|
|
2498
2649
|
return;
|
|
2499
2650
|
}
|
|
2500
2651
|
const components = fs__default.default.readdirSync(componentsDir).filter((name) => {
|
|
2501
|
-
const componentPath =
|
|
2502
|
-
return fs__default.default.statSync(componentPath).isDirectory() && fs__default.default.existsSync(
|
|
2652
|
+
const componentPath = path9__default.default.join(componentsDir, name);
|
|
2653
|
+
return fs__default.default.statSync(componentPath).isDirectory() && fs__default.default.existsSync(path9__default.default.join(componentPath, "index.ts"));
|
|
2503
2654
|
});
|
|
2504
2655
|
if (components.length === 0) {
|
|
2505
2656
|
logger.warning("No components found");
|
|
@@ -2520,11 +2671,11 @@ async function listThemesInfo() {
|
|
|
2520
2671
|
}
|
|
2521
2672
|
logger.log("");
|
|
2522
2673
|
for (const theme of themes) {
|
|
2523
|
-
const themeDir =
|
|
2674
|
+
const themeDir = path9__default.default.join(getThemesDir(), theme);
|
|
2524
2675
|
const candidates = ["theme.config.ts", "bundle-entry.ts", "manifest.ts"];
|
|
2525
2676
|
let manifestContent = "";
|
|
2526
2677
|
for (const candidate of candidates) {
|
|
2527
|
-
const candidatePath =
|
|
2678
|
+
const candidatePath = path9__default.default.join(themeDir, candidate);
|
|
2528
2679
|
if (fs__default.default.existsSync(candidatePath)) {
|
|
2529
2680
|
manifestContent = fs__default.default.readFileSync(candidatePath, "utf-8");
|
|
2530
2681
|
break;
|
|
@@ -2562,9 +2713,9 @@ async function validateCommand(options) {
|
|
|
2562
2713
|
"theme.config.ts",
|
|
2563
2714
|
"bundle-entry.ts",
|
|
2564
2715
|
"manifest.ts"
|
|
2565
|
-
].some((f) => fs__default.default.existsSync(
|
|
2716
|
+
].some((f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f)));
|
|
2566
2717
|
if (isThemeDir) {
|
|
2567
|
-
themeToValidate =
|
|
2718
|
+
themeToValidate = path9__default.default.basename(process.cwd());
|
|
2568
2719
|
logger.info(`Validating current theme: ${themeToValidate}`);
|
|
2569
2720
|
} else {
|
|
2570
2721
|
logger.error(
|
|
@@ -2573,11 +2724,11 @@ async function validateCommand(options) {
|
|
|
2573
2724
|
process.exit(1);
|
|
2574
2725
|
}
|
|
2575
2726
|
}
|
|
2576
|
-
const themePath =
|
|
2727
|
+
const themePath = path9__default.default.join(getThemesDir(), themeToValidate);
|
|
2577
2728
|
logger.startSpinner("Running validation checks...");
|
|
2578
2729
|
const entryFiles = ["manifest.ts", "theme.config.ts", "bundle-entry.ts"];
|
|
2579
2730
|
const foundEntry = entryFiles.find(
|
|
2580
|
-
(f) => fs__default.default.existsSync(
|
|
2731
|
+
(f) => fs__default.default.existsSync(path9__default.default.join(themePath, f))
|
|
2581
2732
|
);
|
|
2582
2733
|
if (!foundEntry) {
|
|
2583
2734
|
issues.push({
|
|
@@ -2587,7 +2738,7 @@ async function validateCommand(options) {
|
|
|
2587
2738
|
});
|
|
2588
2739
|
} else if (foundEntry === "manifest.ts") {
|
|
2589
2740
|
const manifestContent = fs__default.default.readFileSync(
|
|
2590
|
-
|
|
2741
|
+
path9__default.default.join(themePath, foundEntry),
|
|
2591
2742
|
"utf-8"
|
|
2592
2743
|
);
|
|
2593
2744
|
if (!manifestContent.includes("export const") && !manifestContent.includes("export default") && !manifestContent.includes("export interface")) {
|
|
@@ -2598,7 +2749,7 @@ async function validateCommand(options) {
|
|
|
2598
2749
|
});
|
|
2599
2750
|
}
|
|
2600
2751
|
}
|
|
2601
|
-
const configPath =
|
|
2752
|
+
const configPath = path9__default.default.join(themePath, "theme.config.ts");
|
|
2602
2753
|
if (!fs__default.default.existsSync(configPath)) {
|
|
2603
2754
|
issues.push({
|
|
2604
2755
|
type: "warning",
|
|
@@ -2606,7 +2757,7 @@ async function validateCommand(options) {
|
|
|
2606
2757
|
message: "Theme config file not found (recommended)"
|
|
2607
2758
|
});
|
|
2608
2759
|
}
|
|
2609
|
-
const indexPath =
|
|
2760
|
+
const indexPath = path9__default.default.join(themePath, "index.ts");
|
|
2610
2761
|
if (!fs__default.default.existsSync(indexPath)) {
|
|
2611
2762
|
issues.push({
|
|
2612
2763
|
type: "warning",
|
|
@@ -2614,7 +2765,7 @@ async function validateCommand(options) {
|
|
|
2614
2765
|
message: "Index file not found (recommended)"
|
|
2615
2766
|
});
|
|
2616
2767
|
}
|
|
2617
|
-
const sectionsDir =
|
|
2768
|
+
const sectionsDir = path9__default.default.join(themePath, "sections");
|
|
2618
2769
|
if (!fs__default.default.existsSync(sectionsDir)) {
|
|
2619
2770
|
issues.push({
|
|
2620
2771
|
type: "warning",
|
|
@@ -2623,16 +2774,16 @@ async function validateCommand(options) {
|
|
|
2623
2774
|
});
|
|
2624
2775
|
} else {
|
|
2625
2776
|
const sections = fs__default.default.readdirSync(sectionsDir).filter(
|
|
2626
|
-
(name) => fs__default.default.statSync(
|
|
2777
|
+
(name) => fs__default.default.statSync(path9__default.default.join(sectionsDir, name)).isDirectory()
|
|
2627
2778
|
);
|
|
2628
2779
|
for (const sectionName of sections) {
|
|
2629
|
-
const sectionPath =
|
|
2630
|
-
const schemaFile =
|
|
2631
|
-
const defaultTemplate =
|
|
2780
|
+
const sectionPath = path9__default.default.join(sectionsDir, sectionName);
|
|
2781
|
+
const schemaFile = path9__default.default.join(sectionPath, `${sectionName}.schema.ts`);
|
|
2782
|
+
const defaultTemplate = path9__default.default.join(
|
|
2632
2783
|
sectionPath,
|
|
2633
2784
|
`${sectionName}-default.tsx`
|
|
2634
2785
|
);
|
|
2635
|
-
const indexFile =
|
|
2786
|
+
const indexFile = path9__default.default.join(sectionPath, "index.ts");
|
|
2636
2787
|
if (!fs__default.default.existsSync(schemaFile)) {
|
|
2637
2788
|
issues.push({
|
|
2638
2789
|
type: "error",
|
|
@@ -2656,14 +2807,14 @@ async function validateCommand(options) {
|
|
|
2656
2807
|
}
|
|
2657
2808
|
}
|
|
2658
2809
|
}
|
|
2659
|
-
const blocksDir =
|
|
2810
|
+
const blocksDir = path9__default.default.join(themePath, "blocks");
|
|
2660
2811
|
if (fs__default.default.existsSync(blocksDir)) {
|
|
2661
|
-
const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => fs__default.default.statSync(
|
|
2812
|
+
const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => fs__default.default.statSync(path9__default.default.join(blocksDir, name)).isDirectory());
|
|
2662
2813
|
for (const blockName of blocks) {
|
|
2663
|
-
const blockPath =
|
|
2664
|
-
const schemaFile =
|
|
2665
|
-
const componentFile =
|
|
2666
|
-
const indexFile =
|
|
2814
|
+
const blockPath = path9__default.default.join(blocksDir, blockName);
|
|
2815
|
+
const schemaFile = path9__default.default.join(blockPath, `${blockName}.schema.ts`);
|
|
2816
|
+
const componentFile = path9__default.default.join(blockPath, `${blockName}.tsx`);
|
|
2817
|
+
const indexFile = path9__default.default.join(blockPath, "index.ts");
|
|
2667
2818
|
if (!fs__default.default.existsSync(schemaFile)) {
|
|
2668
2819
|
issues.push({
|
|
2669
2820
|
type: "error",
|
|
@@ -2689,13 +2840,13 @@ async function validateCommand(options) {
|
|
|
2689
2840
|
}
|
|
2690
2841
|
if (fs__default.default.existsSync(sectionsDir)) {
|
|
2691
2842
|
const sections = fs__default.default.readdirSync(sectionsDir).filter(
|
|
2692
|
-
(name) => fs__default.default.statSync(
|
|
2843
|
+
(name) => fs__default.default.statSync(path9__default.default.join(sectionsDir, name)).isDirectory()
|
|
2693
2844
|
);
|
|
2694
2845
|
for (const sectionName of sections) {
|
|
2695
|
-
const sectionPath =
|
|
2846
|
+
const sectionPath = path9__default.default.join(sectionsDir, sectionName);
|
|
2696
2847
|
const tsxFiles = fs__default.default.readdirSync(sectionPath).filter((f) => f.endsWith(".tsx") && !f.endsWith(".schema.ts"));
|
|
2697
2848
|
for (const tsxFile of tsxFiles) {
|
|
2698
|
-
const filePath =
|
|
2849
|
+
const filePath = path9__default.default.join(sectionPath, tsxFile);
|
|
2699
2850
|
const content = fs__default.default.readFileSync(filePath, "utf-8");
|
|
2700
2851
|
const relPath = `sections/${sectionName}/${tsxFile}`;
|
|
2701
2852
|
if (!content.includes('"use client"') && !content.includes("'use client'")) {
|
|
@@ -2743,23 +2894,46 @@ async function validateCommand(options) {
|
|
|
2743
2894
|
}
|
|
2744
2895
|
}
|
|
2745
2896
|
}
|
|
2746
|
-
const registryPath =
|
|
2747
|
-
const bundleEntryPath =
|
|
2897
|
+
const registryPath = path9__default.default.join(themePath, "sections-registry.ts");
|
|
2898
|
+
const bundleEntryPath = path9__default.default.join(themePath, "bundle-entry.ts");
|
|
2748
2899
|
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
2900
|
if (fs__default.default.existsSync(sectionsDir) && registryContent) {
|
|
2750
2901
|
const sections = fs__default.default.readdirSync(sectionsDir).filter(
|
|
2751
|
-
(name) => fs__default.default.statSync(
|
|
2902
|
+
(name) => fs__default.default.statSync(path9__default.default.join(sectionsDir, name)).isDirectory()
|
|
2752
2903
|
);
|
|
2753
2904
|
for (const sectionName of sections) {
|
|
2754
2905
|
if (!registryContent.includes(`sections/${sectionName}`) && !registryContent.includes(`"${sectionName}"`)) {
|
|
2755
2906
|
issues.push({
|
|
2756
|
-
type: "
|
|
2907
|
+
type: "error",
|
|
2757
2908
|
file: `sections/${sectionName}/`,
|
|
2758
|
-
message: "Section not
|
|
2909
|
+
message: "Section not exported in sections-registry.ts or bundle-entry.ts \u2014 will not be included in build"
|
|
2759
2910
|
});
|
|
2760
2911
|
}
|
|
2761
2912
|
}
|
|
2762
2913
|
}
|
|
2914
|
+
if (fs__default.default.existsSync(sectionsDir)) {
|
|
2915
|
+
const schemaTypes = await loadSchemaTypes(themePath, sectionsDir);
|
|
2916
|
+
for (const { folderName, schemaType } of schemaTypes) {
|
|
2917
|
+
if (schemaType && schemaType !== folderName) {
|
|
2918
|
+
issues.push({
|
|
2919
|
+
type: "error",
|
|
2920
|
+
file: `sections/${folderName}/${folderName}.schema.ts`,
|
|
2921
|
+
message: `Schema type "${schemaType}" doesn't match folder name "${folderName}". Rename folder to "${schemaType}/" or change schema type to "${folderName}".`
|
|
2922
|
+
});
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
const pagesDir = path9__default.default.join(themePath, "pages");
|
|
2926
|
+
if (fs__default.default.existsSync(pagesDir)) {
|
|
2927
|
+
const allSchemaTypeSet = new Set(
|
|
2928
|
+
schemaTypes.map((s) => s.schemaType || s.folderName)
|
|
2929
|
+
);
|
|
2930
|
+
const pageIssues = await validatePageSectionTypes(
|
|
2931
|
+
pagesDir,
|
|
2932
|
+
allSchemaTypeSet
|
|
2933
|
+
);
|
|
2934
|
+
issues.push(...pageIssues);
|
|
2935
|
+
}
|
|
2936
|
+
}
|
|
2763
2937
|
logger.stopSpinner(true, "Validation complete");
|
|
2764
2938
|
const errors = issues.filter((i) => i.type === "error");
|
|
2765
2939
|
const warnings = issues.filter((i) => i.type === "warning");
|
|
@@ -2798,6 +2972,116 @@ async function validateCommand(options) {
|
|
|
2798
2972
|
}
|
|
2799
2973
|
}
|
|
2800
2974
|
}
|
|
2975
|
+
async function loadSchemaTypes(themePath, sectionsDir) {
|
|
2976
|
+
const results = [];
|
|
2977
|
+
const sections = fs__default.default.readdirSync(sectionsDir).filter((name) => fs__default.default.statSync(path9__default.default.join(sectionsDir, name)).isDirectory());
|
|
2978
|
+
for (const sectionName of sections) {
|
|
2979
|
+
const schemaFile = path9__default.default.join(
|
|
2980
|
+
sectionsDir,
|
|
2981
|
+
sectionName,
|
|
2982
|
+
`${sectionName}.schema.ts`
|
|
2983
|
+
);
|
|
2984
|
+
if (!fs__default.default.existsSync(schemaFile)) {
|
|
2985
|
+
results.push({ folderName: sectionName, schemaType: null });
|
|
2986
|
+
continue;
|
|
2987
|
+
}
|
|
2988
|
+
const content = fs__default.default.readFileSync(schemaFile, "utf-8");
|
|
2989
|
+
let schemaType = null;
|
|
2990
|
+
const schemaExportMatch = content.match(
|
|
2991
|
+
/:\s*SectionSchema\s*=\s*\{[\s\S]*?\btype:\s*["']([^"']+)["']/
|
|
2992
|
+
);
|
|
2993
|
+
if (schemaExportMatch) {
|
|
2994
|
+
schemaType = schemaExportMatch[1];
|
|
2995
|
+
} else {
|
|
2996
|
+
const allTypeMatches = [
|
|
2997
|
+
...content.matchAll(/\btype:\s*["']([^"']+)["']/g)
|
|
2998
|
+
];
|
|
2999
|
+
for (const m of allTypeMatches) {
|
|
3000
|
+
if (!FIELD_TYPES.has(m[1])) {
|
|
3001
|
+
schemaType = m[1];
|
|
3002
|
+
break;
|
|
3003
|
+
}
|
|
3004
|
+
}
|
|
3005
|
+
}
|
|
3006
|
+
results.push({
|
|
3007
|
+
folderName: sectionName,
|
|
3008
|
+
schemaType
|
|
3009
|
+
});
|
|
3010
|
+
}
|
|
3011
|
+
return results;
|
|
3012
|
+
}
|
|
3013
|
+
async function validatePageSectionTypes(pagesDir, validTypes) {
|
|
3014
|
+
const issues = [];
|
|
3015
|
+
const files = fs__default.default.readdirSync(pagesDir).filter((f) => f.match(/\.(ts|js)$/));
|
|
3016
|
+
for (const file of files) {
|
|
3017
|
+
const content = fs__default.default.readFileSync(path9__default.default.join(pagesDir, file), "utf-8");
|
|
3018
|
+
const pageName = file.replace(/\.(ts|js)$/, "");
|
|
3019
|
+
const sectionsMatch = content.match(/\bsections:\s*\[/);
|
|
3020
|
+
if (!sectionsMatch || sectionsMatch.index === void 0) continue;
|
|
3021
|
+
const startIdx = sectionsMatch.index + sectionsMatch[0].length;
|
|
3022
|
+
let depth = 1;
|
|
3023
|
+
let endIdx = startIdx;
|
|
3024
|
+
for (let i = startIdx; i < content.length && depth > 0; i++) {
|
|
3025
|
+
if (content[i] === "[") depth++;
|
|
3026
|
+
else if (content[i] === "]") depth--;
|
|
3027
|
+
endIdx = i;
|
|
3028
|
+
}
|
|
3029
|
+
const sectionsBlock = content.slice(startIdx, endIdx);
|
|
3030
|
+
const typeMatches = sectionsBlock.matchAll(/\btype:\s*["']([^"']+)["']/g);
|
|
3031
|
+
for (const match of typeMatches) {
|
|
3032
|
+
const sectionType = match[1];
|
|
3033
|
+
if (!validTypes.has(sectionType)) {
|
|
3034
|
+
issues.push({
|
|
3035
|
+
type: "error",
|
|
3036
|
+
file: `pages/${file}`,
|
|
3037
|
+
message: `Page "${pageName}" uses section type "${sectionType}" which doesn't exist in sections/`
|
|
3038
|
+
});
|
|
3039
|
+
}
|
|
3040
|
+
}
|
|
3041
|
+
}
|
|
3042
|
+
return issues;
|
|
3043
|
+
}
|
|
3044
|
+
var FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
3045
|
+
"text",
|
|
3046
|
+
"textarea",
|
|
3047
|
+
"richtext",
|
|
3048
|
+
"number",
|
|
3049
|
+
"range",
|
|
3050
|
+
"toggle",
|
|
3051
|
+
"switch",
|
|
3052
|
+
"select",
|
|
3053
|
+
"radio",
|
|
3054
|
+
"checkbox",
|
|
3055
|
+
"color",
|
|
3056
|
+
"image",
|
|
3057
|
+
"video",
|
|
3058
|
+
"url",
|
|
3059
|
+
"link",
|
|
3060
|
+
"icon",
|
|
3061
|
+
"date",
|
|
3062
|
+
"datetime",
|
|
3063
|
+
"collection",
|
|
3064
|
+
"product",
|
|
3065
|
+
"blog",
|
|
3066
|
+
"page",
|
|
3067
|
+
"html",
|
|
3068
|
+
"code",
|
|
3069
|
+
"json",
|
|
3070
|
+
"array",
|
|
3071
|
+
"object",
|
|
3072
|
+
"group",
|
|
3073
|
+
"section",
|
|
3074
|
+
"boolean",
|
|
3075
|
+
"color_token",
|
|
3076
|
+
"color_background",
|
|
3077
|
+
"image_picker",
|
|
3078
|
+
"video_url",
|
|
3079
|
+
"font",
|
|
3080
|
+
"font_picker",
|
|
3081
|
+
"text_alignment",
|
|
3082
|
+
"inline_richtext",
|
|
3083
|
+
"repeater"
|
|
3084
|
+
]);
|
|
2801
3085
|
|
|
2802
3086
|
// src/commands/build.ts
|
|
2803
3087
|
init_logger();
|
|
@@ -2808,14 +3092,14 @@ async function buildCommand(options) {
|
|
|
2808
3092
|
if (options.theme) {
|
|
2809
3093
|
themeName = options.theme;
|
|
2810
3094
|
try {
|
|
2811
|
-
const workspaceThemePath =
|
|
3095
|
+
const workspaceThemePath = path9__default.default.join(getThemesDir(), themeName);
|
|
2812
3096
|
if (fs__default.default.existsSync(workspaceThemePath)) {
|
|
2813
3097
|
themePath = workspaceThemePath;
|
|
2814
3098
|
} else {
|
|
2815
|
-
themePath =
|
|
3099
|
+
themePath = path9__default.default.join(process.cwd(), themeName);
|
|
2816
3100
|
}
|
|
2817
3101
|
} catch {
|
|
2818
|
-
themePath =
|
|
3102
|
+
themePath = path9__default.default.join(process.cwd(), themeName);
|
|
2819
3103
|
}
|
|
2820
3104
|
if (!fs__default.default.existsSync(themePath)) {
|
|
2821
3105
|
logger.error(`Theme "${themeName}" not found.`);
|
|
@@ -2826,10 +3110,10 @@ async function buildCommand(options) {
|
|
|
2826
3110
|
"theme.config.ts",
|
|
2827
3111
|
"bundle-entry.ts",
|
|
2828
3112
|
"manifest.ts"
|
|
2829
|
-
].some((f) => fs__default.default.existsSync(
|
|
3113
|
+
].some((f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f)));
|
|
2830
3114
|
if (isThemeDir) {
|
|
2831
3115
|
themePath = process.cwd();
|
|
2832
|
-
themeName =
|
|
3116
|
+
themeName = path9__default.default.basename(themePath);
|
|
2833
3117
|
logger.info(`Building current theme: ${themeName}`);
|
|
2834
3118
|
} else {
|
|
2835
3119
|
logger.error(
|
|
@@ -2838,7 +3122,7 @@ async function buildCommand(options) {
|
|
|
2838
3122
|
process.exit(1);
|
|
2839
3123
|
}
|
|
2840
3124
|
}
|
|
2841
|
-
const packageJsonPath =
|
|
3125
|
+
const packageJsonPath = path9__default.default.join(themePath, "package.json");
|
|
2842
3126
|
const hasPkgJson = fs__default.default.existsSync(packageJsonPath);
|
|
2843
3127
|
if (!hasPkgJson) {
|
|
2844
3128
|
logger.warning(
|
|
@@ -2894,9 +3178,9 @@ async function buildCommand(options) {
|
|
|
2894
3178
|
logger.success("\u2713 Theme built successfully!");
|
|
2895
3179
|
logger.newLine();
|
|
2896
3180
|
logger.info(`Theme: ${themeName}`);
|
|
2897
|
-
const distPath =
|
|
3181
|
+
const distPath = path9__default.default.join(themePath, "dist");
|
|
2898
3182
|
if (fs__default.default.existsSync(distPath)) {
|
|
2899
|
-
logger.log(`Output: ${
|
|
3183
|
+
logger.log(`Output: ${path9__default.default.relative(process.cwd(), distPath)}`);
|
|
2900
3184
|
const files = fs__default.default.readdirSync(distPath);
|
|
2901
3185
|
logger.log(`Files: ${files.length}`);
|
|
2902
3186
|
}
|
|
@@ -2952,7 +3236,7 @@ async function packageCommand(options) {
|
|
|
2952
3236
|
let themeName;
|
|
2953
3237
|
if (options.theme) {
|
|
2954
3238
|
themeName = options.theme;
|
|
2955
|
-
themePath =
|
|
3239
|
+
themePath = path9__default.default.join(getThemesDir(), themeName);
|
|
2956
3240
|
if (!fs__default.default.existsSync(themePath)) {
|
|
2957
3241
|
logger.error(`Theme "${themeName}" not found.`);
|
|
2958
3242
|
process.exit(1);
|
|
@@ -2962,10 +3246,10 @@ async function packageCommand(options) {
|
|
|
2962
3246
|
"theme.config.ts",
|
|
2963
3247
|
"bundle-entry.ts",
|
|
2964
3248
|
"manifest.ts"
|
|
2965
|
-
].some((f) => fs__default.default.existsSync(
|
|
3249
|
+
].some((f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f)));
|
|
2966
3250
|
if (isThemeDir) {
|
|
2967
3251
|
themePath = process.cwd();
|
|
2968
|
-
themeName =
|
|
3252
|
+
themeName = path9__default.default.basename(themePath);
|
|
2969
3253
|
logger.info(`Packaging current theme: ${themeName}`);
|
|
2970
3254
|
} else {
|
|
2971
3255
|
logger.error(
|
|
@@ -2974,7 +3258,7 @@ async function packageCommand(options) {
|
|
|
2974
3258
|
process.exit(1);
|
|
2975
3259
|
}
|
|
2976
3260
|
}
|
|
2977
|
-
const packageJsonPath =
|
|
3261
|
+
const packageJsonPath = path9__default.default.join(themePath, "package.json");
|
|
2978
3262
|
let version2 = "1.0.0";
|
|
2979
3263
|
if (fs__default.default.existsSync(packageJsonPath)) {
|
|
2980
3264
|
const packageJson = await fs__default.default.readJson(packageJsonPath);
|
|
@@ -2984,7 +3268,7 @@ async function packageCommand(options) {
|
|
|
2984
3268
|
logger.info(`Theme: ${themeName}`);
|
|
2985
3269
|
logger.info(`Version: ${version2}`);
|
|
2986
3270
|
logger.newLine();
|
|
2987
|
-
const compiledThemePath =
|
|
3271
|
+
const compiledThemePath = path9__default.default.join(
|
|
2988
3272
|
process.cwd(),
|
|
2989
3273
|
"themes",
|
|
2990
3274
|
themeName,
|
|
@@ -3018,8 +3302,8 @@ async function packageCommand(options) {
|
|
|
3018
3302
|
logger.newLine();
|
|
3019
3303
|
logger.section("Step 2: Create Package");
|
|
3020
3304
|
const packageName = options.name || `${themeName}-${version2}`;
|
|
3021
|
-
const outputDir = options.output ||
|
|
3022
|
-
const outputPath =
|
|
3305
|
+
const outputDir = options.output || path9__default.default.join(process.cwd(), "dist");
|
|
3306
|
+
const outputPath = path9__default.default.join(outputDir, `${packageName}.zip`);
|
|
3023
3307
|
await fs__default.default.ensureDir(outputDir);
|
|
3024
3308
|
logger.startSpinner("Creating zip archive...");
|
|
3025
3309
|
try {
|
|
@@ -3032,11 +3316,11 @@ async function packageCommand(options) {
|
|
|
3032
3316
|
logger.newLine();
|
|
3033
3317
|
logger.info(`Package: ${packageName}.zip`);
|
|
3034
3318
|
logger.log(`Size: ${sizeMB} MB`);
|
|
3035
|
-
logger.log(`Location: ${
|
|
3319
|
+
logger.log(`Location: ${path9__default.default.relative(process.cwd(), outputPath)}`);
|
|
3036
3320
|
logger.newLine();
|
|
3037
3321
|
logger.section("Next steps:");
|
|
3038
3322
|
logger.log(
|
|
3039
|
-
` onexthm deploy --package ${
|
|
3323
|
+
` onexthm deploy --package ${path9__default.default.relative(process.cwd(), outputPath)}`
|
|
3040
3324
|
);
|
|
3041
3325
|
} catch (error) {
|
|
3042
3326
|
logger.stopSpinner(false, "Failed to create package");
|
|
@@ -3094,9 +3378,9 @@ async function deployCommand(options) {
|
|
|
3094
3378
|
ensureOneXProject();
|
|
3095
3379
|
let packagePath;
|
|
3096
3380
|
if (options.package) {
|
|
3097
|
-
packagePath =
|
|
3381
|
+
packagePath = path9__default.default.resolve(options.package);
|
|
3098
3382
|
} else if (options.theme) {
|
|
3099
|
-
const distDir =
|
|
3383
|
+
const distDir = path9__default.default.join(process.cwd(), "dist");
|
|
3100
3384
|
if (!fs__default.default.existsSync(distDir)) {
|
|
3101
3385
|
logger.error("No dist/ directory found. Run 'onexthm package' first.");
|
|
3102
3386
|
process.exit(1);
|
|
@@ -3111,7 +3395,7 @@ async function deployCommand(options) {
|
|
|
3111
3395
|
process.exit(1);
|
|
3112
3396
|
}
|
|
3113
3397
|
packageFiles.sort().reverse();
|
|
3114
|
-
packagePath =
|
|
3398
|
+
packagePath = path9__default.default.join(distDir, packageFiles[0]);
|
|
3115
3399
|
} else {
|
|
3116
3400
|
logger.error("Either --package or --theme must be specified.");
|
|
3117
3401
|
logger.info("Examples:");
|
|
@@ -3125,11 +3409,11 @@ async function deployCommand(options) {
|
|
|
3125
3409
|
}
|
|
3126
3410
|
const stats = await fs__default.default.stat(packagePath);
|
|
3127
3411
|
const sizeMB = (stats.size / 1024 / 1024).toFixed(2);
|
|
3128
|
-
const fileName =
|
|
3412
|
+
const fileName = path9__default.default.basename(packagePath);
|
|
3129
3413
|
logger.newLine();
|
|
3130
3414
|
logger.info(`Package: ${fileName}`);
|
|
3131
3415
|
logger.log(`Size: ${sizeMB} MB`);
|
|
3132
|
-
logger.log(`Path: ${
|
|
3416
|
+
logger.log(`Path: ${path9__default.default.relative(process.cwd(), packagePath)}`);
|
|
3133
3417
|
logger.newLine();
|
|
3134
3418
|
const apiUrl = options.apiUrl || process.env.ONEX_API_URL || "http://localhost:3001";
|
|
3135
3419
|
const uploadEndpoint = `${apiUrl}/website-api/themes/upload`;
|
|
@@ -3233,11 +3517,11 @@ function getBucketName(env) {
|
|
|
3233
3517
|
return environment === "production" ? "theme-s3-bucket" : "theme-s3-bucket";
|
|
3234
3518
|
}
|
|
3235
3519
|
async function findCompiledThemeDir(themeId, version2) {
|
|
3236
|
-
const searchPaths = [
|
|
3520
|
+
const searchPaths = [path9__default.default.resolve(process.cwd(), "dist")];
|
|
3237
3521
|
for (const dir of searchPaths) {
|
|
3238
3522
|
if (await fs__default.default.pathExists(dir)) {
|
|
3239
|
-
const hasManifest = await fs__default.default.pathExists(
|
|
3240
|
-
const hasThemeEntry = await fs__default.default.pathExists(
|
|
3523
|
+
const hasManifest = await fs__default.default.pathExists(path9__default.default.join(dir, "manifest.json"));
|
|
3524
|
+
const hasThemeEntry = await fs__default.default.pathExists(path9__default.default.join(dir, "bundle-entry.js")) || await fs__default.default.pathExists(path9__default.default.join(dir, "theme.config.js")) || await fs__default.default.pathExists(path9__default.default.join(dir, "index.js"));
|
|
3241
3525
|
if (hasManifest || hasThemeEntry) {
|
|
3242
3526
|
return dir;
|
|
3243
3527
|
}
|
|
@@ -3246,7 +3530,7 @@ async function findCompiledThemeDir(themeId, version2) {
|
|
|
3246
3530
|
return null;
|
|
3247
3531
|
}
|
|
3248
3532
|
async function readManifest() {
|
|
3249
|
-
const manifestTsPath =
|
|
3533
|
+
const manifestTsPath = path9__default.default.resolve(process.cwd(), "manifest.ts");
|
|
3250
3534
|
if (await fs__default.default.pathExists(manifestTsPath)) {
|
|
3251
3535
|
try {
|
|
3252
3536
|
const module = await import(manifestTsPath);
|
|
@@ -3255,7 +3539,7 @@ async function readManifest() {
|
|
|
3255
3539
|
logger.warning("Failed to import manifest.ts, trying package.json");
|
|
3256
3540
|
}
|
|
3257
3541
|
}
|
|
3258
|
-
const packageJsonPath =
|
|
3542
|
+
const packageJsonPath = path9__default.default.resolve(process.cwd(), "package.json");
|
|
3259
3543
|
if (await fs__default.default.pathExists(packageJsonPath)) {
|
|
3260
3544
|
const pkg = await fs__default.default.readJson(packageJsonPath);
|
|
3261
3545
|
return {
|
|
@@ -3289,13 +3573,13 @@ async function findSourceDir(themeId, explicitDir) {
|
|
|
3289
3573
|
}
|
|
3290
3574
|
const searchPaths = [
|
|
3291
3575
|
process.cwd(),
|
|
3292
|
-
|
|
3293
|
-
|
|
3576
|
+
path9__default.default.resolve(process.cwd(), `../../themes/${themeId}`),
|
|
3577
|
+
path9__default.default.resolve(process.cwd(), `../themes/${themeId}`)
|
|
3294
3578
|
];
|
|
3295
3579
|
const markers = ["theme.config.ts", "bundle-entry.ts"];
|
|
3296
3580
|
for (const dir of searchPaths) {
|
|
3297
3581
|
for (const marker of markers) {
|
|
3298
|
-
if (await fs__default.default.pathExists(
|
|
3582
|
+
if (await fs__default.default.pathExists(path9__default.default.join(dir, marker))) {
|
|
3299
3583
|
return dir;
|
|
3300
3584
|
}
|
|
3301
3585
|
}
|
|
@@ -3346,8 +3630,8 @@ async function uploadCommand(options) {
|
|
|
3346
3630
|
}
|
|
3347
3631
|
spinner.succeed(`Found compiled theme at: ${compiledDir}`);
|
|
3348
3632
|
spinner.start("Creating bundle.zip...");
|
|
3349
|
-
const tmpDir =
|
|
3350
|
-
const bundleZipPath =
|
|
3633
|
+
const tmpDir = os__default.default.tmpdir();
|
|
3634
|
+
const bundleZipPath = path9__default.default.join(tmpDir, `${themeId}-${version2}-bundle.zip`);
|
|
3351
3635
|
await createZipFromDir(compiledDir, bundleZipPath);
|
|
3352
3636
|
const bundleZipBuffer = await fs__default.default.readFile(bundleZipPath);
|
|
3353
3637
|
const bundleSizeMB = (bundleZipBuffer.length / 1024 / 1024).toFixed(2);
|
|
@@ -3401,7 +3685,7 @@ async function uploadCommand(options) {
|
|
|
3401
3685
|
if (sourceDir) {
|
|
3402
3686
|
spinner.succeed(`Found source at: ${sourceDir}`);
|
|
3403
3687
|
spinner.start("Creating source.zip...");
|
|
3404
|
-
const sourceZipPath =
|
|
3688
|
+
const sourceZipPath = path9__default.default.join(
|
|
3405
3689
|
tmpDir,
|
|
3406
3690
|
`${themeId}-${version2}-source.zip`
|
|
3407
3691
|
);
|
|
@@ -3535,8 +3819,8 @@ async function resolveLatestVersion(s3Client, bucket, themeId) {
|
|
|
3535
3819
|
async function createCompatibilityFiles(outputDir, manifest) {
|
|
3536
3820
|
const entryFile = manifest.output?.entry || "bundle-entry.js";
|
|
3537
3821
|
if (entryFile !== "bundle-entry.js" && entryFile.startsWith("bundle-entry-")) {
|
|
3538
|
-
const hashedPath =
|
|
3539
|
-
const stablePath =
|
|
3822
|
+
const hashedPath = path9__default.default.join(outputDir, entryFile);
|
|
3823
|
+
const stablePath = path9__default.default.join(outputDir, "bundle-entry.js");
|
|
3540
3824
|
if (await fs__default.default.pathExists(hashedPath)) {
|
|
3541
3825
|
await fs__default.default.copy(hashedPath, stablePath);
|
|
3542
3826
|
const mapPath = hashedPath + ".map";
|
|
@@ -3545,13 +3829,13 @@ async function createCompatibilityFiles(outputDir, manifest) {
|
|
|
3545
3829
|
}
|
|
3546
3830
|
}
|
|
3547
3831
|
}
|
|
3548
|
-
const sectionsRegistryPath =
|
|
3832
|
+
const sectionsRegistryPath = path9__default.default.join(outputDir, "sections-registry.js");
|
|
3549
3833
|
const content = `// Re-export all sections from bundle-entry
|
|
3550
3834
|
// This file exists to maintain compatibility with the import path
|
|
3551
3835
|
export * from './bundle-entry.js';
|
|
3552
3836
|
`;
|
|
3553
3837
|
await fs__default.default.writeFile(sectionsRegistryPath, content, "utf-8");
|
|
3554
|
-
const pkgJsonPath =
|
|
3838
|
+
const pkgJsonPath = path9__default.default.join(outputDir, "package.json");
|
|
3555
3839
|
await fs__default.default.writeFile(pkgJsonPath, '{\n "type": "module"\n}\n', "utf-8");
|
|
3556
3840
|
}
|
|
3557
3841
|
function showDownloadFailureHelp(themeId, bucket) {
|
|
@@ -3613,6 +3897,18 @@ async function downloadCommand(options) {
|
|
|
3613
3897
|
spinner.succeed(
|
|
3614
3898
|
`Resolved latest version: ${chalk4__default.default.cyan(resolvedVersion)}`
|
|
3615
3899
|
);
|
|
3900
|
+
const isCI = !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.VERCEL);
|
|
3901
|
+
if (isCI) {
|
|
3902
|
+
console.log(
|
|
3903
|
+
chalk4__default.default.yellow(
|
|
3904
|
+
`
|
|
3905
|
+
Warning: Resolved "latest" to ${resolvedVersion} in CI environment.
|
|
3906
|
+
For production builds, pin to a specific version:
|
|
3907
|
+
THEME_VERSION=${resolvedVersion}
|
|
3908
|
+
`
|
|
3909
|
+
)
|
|
3910
|
+
);
|
|
3911
|
+
}
|
|
3616
3912
|
}
|
|
3617
3913
|
spinner.start(
|
|
3618
3914
|
`Downloading bundle.zip for ${themeId}@${resolvedVersion}...`
|
|
@@ -3634,7 +3930,7 @@ async function downloadCommand(options) {
|
|
|
3634
3930
|
zip.extractAllTo(outputDir, true);
|
|
3635
3931
|
const entries = zip.getEntries().filter((e) => !e.isDirectory);
|
|
3636
3932
|
spinner.succeed(`Extracted ${entries.length} files to ${outputDir}`);
|
|
3637
|
-
const manifestPath =
|
|
3933
|
+
const manifestPath = path9__default.default.join(outputDir, "manifest.json");
|
|
3638
3934
|
const manifest = await fs__default.default.readJson(manifestPath);
|
|
3639
3935
|
await createCompatibilityFiles(outputDir, manifest);
|
|
3640
3936
|
console.log();
|
|
@@ -3768,7 +4064,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3768
4064
|
const oldPrefix = `${oldName}-`;
|
|
3769
4065
|
const newPrefix = `${newName}-`;
|
|
3770
4066
|
const newDisplayName = newName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3771
|
-
const pkgPath =
|
|
4067
|
+
const pkgPath = path9__default.default.join(themeDir, "package.json");
|
|
3772
4068
|
if (await fs__default.default.pathExists(pkgPath)) {
|
|
3773
4069
|
const pkg = await fs__default.default.readJson(pkgPath);
|
|
3774
4070
|
pkg.name = `@onex-themes/${newName}`;
|
|
@@ -3784,7 +4080,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3784
4080
|
}
|
|
3785
4081
|
await fs__default.default.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
3786
4082
|
}
|
|
3787
|
-
const configPath =
|
|
4083
|
+
const configPath = path9__default.default.join(themeDir, "theme.config.ts");
|
|
3788
4084
|
if (await fs__default.default.pathExists(configPath)) {
|
|
3789
4085
|
let content = await fs__default.default.readFile(configPath, "utf-8");
|
|
3790
4086
|
content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
|
|
@@ -3794,7 +4090,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3794
4090
|
);
|
|
3795
4091
|
await fs__default.default.writeFile(configPath, content);
|
|
3796
4092
|
}
|
|
3797
|
-
const layoutPath =
|
|
4093
|
+
const layoutPath = path9__default.default.join(themeDir, "theme.layout.ts");
|
|
3798
4094
|
if (await fs__default.default.pathExists(layoutPath)) {
|
|
3799
4095
|
let content = await fs__default.default.readFile(layoutPath, "utf-8");
|
|
3800
4096
|
content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
|
|
@@ -3807,7 +4103,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3807
4103
|
const oldDisplayName = oldName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3808
4104
|
const tsFiles = await glob.glob("**/*.ts", { cwd: themeDir, nodir: true });
|
|
3809
4105
|
for (const file of tsFiles) {
|
|
3810
|
-
const filePath =
|
|
4106
|
+
const filePath = path9__default.default.join(themeDir, file);
|
|
3811
4107
|
let content = await fs__default.default.readFile(filePath, "utf-8");
|
|
3812
4108
|
const original = content;
|
|
3813
4109
|
content = content.replace(
|
|
@@ -3836,7 +4132,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3836
4132
|
const spinner = ora__default.default("Initializing clone...").start();
|
|
3837
4133
|
try {
|
|
3838
4134
|
const bucket = options.bucket || getBucketName3(options.environment);
|
|
3839
|
-
const outputDir = options.output ||
|
|
4135
|
+
const outputDir = options.output || path9__default.default.resolve(process.cwd(), newName);
|
|
3840
4136
|
const s3Client = getS3Client3();
|
|
3841
4137
|
if (await fs__default.default.pathExists(outputDir)) {
|
|
3842
4138
|
spinner.fail(chalk4__default.default.red(`Directory already exists: ${outputDir}`));
|
|
@@ -3891,7 +4187,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3891
4187
|
spinner.succeed(
|
|
3892
4188
|
`Renamed theme: ${chalk4__default.default.gray(themeName)} \u2192 ${chalk4__default.default.cyan(newName)}`
|
|
3893
4189
|
);
|
|
3894
|
-
const envExamplePath =
|
|
4190
|
+
const envExamplePath = path9__default.default.join(outputDir, ".env.example");
|
|
3895
4191
|
if (!await fs__default.default.pathExists(envExamplePath)) {
|
|
3896
4192
|
await fs__default.default.writeFile(
|
|
3897
4193
|
envExamplePath,
|
|
@@ -3904,7 +4200,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3904
4200
|
].join("\n")
|
|
3905
4201
|
);
|
|
3906
4202
|
}
|
|
3907
|
-
const mcpJsonPath =
|
|
4203
|
+
const mcpJsonPath = path9__default.default.join(outputDir, ".mcp.json");
|
|
3908
4204
|
if (await fs__default.default.pathExists(mcpJsonPath)) {
|
|
3909
4205
|
const { default: inquirerMod } = await import('inquirer');
|
|
3910
4206
|
const { figmaApiKey } = await inquirerMod.prompt([
|
|
@@ -3929,7 +4225,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3929
4225
|
}
|
|
3930
4226
|
if (options.install !== false) {
|
|
3931
4227
|
const hasPkgJson = await fs__default.default.pathExists(
|
|
3932
|
-
|
|
4228
|
+
path9__default.default.join(outputDir, "package.json")
|
|
3933
4229
|
);
|
|
3934
4230
|
if (hasPkgJson) {
|
|
3935
4231
|
spinner.start("Installing dependencies...");
|
|
@@ -3956,7 +4252,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3956
4252
|
console.log(chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(entries.length));
|
|
3957
4253
|
console.log();
|
|
3958
4254
|
console.log(chalk4__default.default.cyan("Next steps:"));
|
|
3959
|
-
console.log(chalk4__default.default.gray(` cd ${
|
|
4255
|
+
console.log(chalk4__default.default.gray(` cd ${path9__default.default.relative(process.cwd(), outputDir)}`));
|
|
3960
4256
|
console.log(
|
|
3961
4257
|
chalk4__default.default.gray(" cp .env.example .env # then add your Company ID")
|
|
3962
4258
|
);
|
|
@@ -3991,7 +4287,7 @@ var MIME_TYPES = {
|
|
|
3991
4287
|
};
|
|
3992
4288
|
function createDevServer(options) {
|
|
3993
4289
|
const clients = /* @__PURE__ */ new Set();
|
|
3994
|
-
const themeDataPath =
|
|
4290
|
+
const themeDataPath = path9__default.default.join(options.distDir, "theme-data.json");
|
|
3995
4291
|
const server = http__default.default.createServer((req, res) => {
|
|
3996
4292
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
3997
4293
|
res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
|
|
@@ -4017,8 +4313,8 @@ function createDevServer(options) {
|
|
|
4017
4313
|
if (pathname.startsWith("/_assets/")) {
|
|
4018
4314
|
const parts = pathname.replace(/^\/_assets\//, "").split("/");
|
|
4019
4315
|
const assetSubpath = parts.slice(1).join("/");
|
|
4020
|
-
const assetPath =
|
|
4021
|
-
if (!assetPath.startsWith(
|
|
4316
|
+
const assetPath = path9__default.default.join(options.themePath, "assets", assetSubpath);
|
|
4317
|
+
if (!assetPath.startsWith(path9__default.default.join(options.themePath, "assets"))) {
|
|
4022
4318
|
res.writeHead(403);
|
|
4023
4319
|
res.end("Forbidden");
|
|
4024
4320
|
return;
|
|
@@ -4029,8 +4325,8 @@ function createDevServer(options) {
|
|
|
4029
4325
|
if (pathname.startsWith("/themes/")) {
|
|
4030
4326
|
const match = pathname.match(/^\/themes\/[^/]+\/assets\/(.+)/);
|
|
4031
4327
|
if (match) {
|
|
4032
|
-
const assetPath =
|
|
4033
|
-
if (!assetPath.startsWith(
|
|
4328
|
+
const assetPath = path9__default.default.join(options.themePath, "assets", match[1]);
|
|
4329
|
+
if (!assetPath.startsWith(path9__default.default.join(options.themePath, "assets"))) {
|
|
4034
4330
|
res.writeHead(403);
|
|
4035
4331
|
res.end("Forbidden");
|
|
4036
4332
|
return;
|
|
@@ -4044,26 +4340,26 @@ function createDevServer(options) {
|
|
|
4044
4340
|
const segments = subpath.split("/");
|
|
4045
4341
|
let assetPath;
|
|
4046
4342
|
if (segments[0] === options.themeName || segments[0] === options.themeName.replace(/^my-/, "")) {
|
|
4047
|
-
assetPath =
|
|
4343
|
+
assetPath = path9__default.default.join(
|
|
4048
4344
|
options.themePath,
|
|
4049
4345
|
"assets",
|
|
4050
4346
|
segments.slice(1).join("/")
|
|
4051
4347
|
);
|
|
4052
4348
|
} else {
|
|
4053
|
-
assetPath =
|
|
4349
|
+
assetPath = path9__default.default.join(options.themePath, "assets", subpath);
|
|
4054
4350
|
}
|
|
4055
|
-
if (assetPath.startsWith(
|
|
4351
|
+
if (assetPath.startsWith(path9__default.default.join(options.themePath, "assets")) && fs3__default.default.existsSync(assetPath)) {
|
|
4056
4352
|
serveFile(res, assetPath);
|
|
4057
4353
|
return;
|
|
4058
4354
|
}
|
|
4059
4355
|
}
|
|
4060
|
-
const filePath =
|
|
4356
|
+
const filePath = path9__default.default.join(options.distDir, pathname);
|
|
4061
4357
|
if (!filePath.startsWith(options.distDir)) {
|
|
4062
4358
|
res.writeHead(403);
|
|
4063
4359
|
res.end("Forbidden");
|
|
4064
4360
|
return;
|
|
4065
4361
|
}
|
|
4066
|
-
if (
|
|
4362
|
+
if (fs3__default.default.existsSync(filePath) && fs3__default.default.statSync(filePath).isFile()) {
|
|
4067
4363
|
serveFile(res, filePath);
|
|
4068
4364
|
} else {
|
|
4069
4365
|
res.writeHead(200, { "Content-Type": "text/html" });
|
|
@@ -4095,14 +4391,14 @@ function createDevServer(options) {
|
|
|
4095
4391
|
}
|
|
4096
4392
|
function serveFile(res, filePath) {
|
|
4097
4393
|
try {
|
|
4098
|
-
if (!
|
|
4394
|
+
if (!fs3__default.default.existsSync(filePath)) {
|
|
4099
4395
|
res.writeHead(404);
|
|
4100
4396
|
res.end("Not Found");
|
|
4101
4397
|
return;
|
|
4102
4398
|
}
|
|
4103
|
-
const ext =
|
|
4399
|
+
const ext = path9__default.default.extname(filePath);
|
|
4104
4400
|
const contentType = MIME_TYPES[ext] || "application/octet-stream";
|
|
4105
|
-
const content =
|
|
4401
|
+
const content = fs3__default.default.readFileSync(filePath);
|
|
4106
4402
|
res.writeHead(200, { "Content-Type": contentType });
|
|
4107
4403
|
res.end(content);
|
|
4108
4404
|
} catch {
|
|
@@ -4115,7 +4411,7 @@ function generatePreviewHTML(themeName, port, themeDataPath) {
|
|
|
4115
4411
|
let fontVarsCSS = "";
|
|
4116
4412
|
if (themeDataPath) {
|
|
4117
4413
|
try {
|
|
4118
|
-
const themeData = JSON.parse(
|
|
4414
|
+
const themeData = JSON.parse(fs3__default.default.readFileSync(themeDataPath, "utf-8"));
|
|
4119
4415
|
const typography = (themeData?.themeConfig || themeData?.theme?.config)?.typography?.fontFamily;
|
|
4120
4416
|
if (typography) {
|
|
4121
4417
|
const fontFamilies = /* @__PURE__ */ new Set();
|
|
@@ -4203,14 +4499,14 @@ async function devCommand(options) {
|
|
|
4203
4499
|
if (options.theme) {
|
|
4204
4500
|
themeName = options.theme;
|
|
4205
4501
|
try {
|
|
4206
|
-
const workspaceThemePath =
|
|
4502
|
+
const workspaceThemePath = path9__default.default.join(getThemesDir(), themeName);
|
|
4207
4503
|
if (fs__default.default.existsSync(workspaceThemePath)) {
|
|
4208
4504
|
themePath = workspaceThemePath;
|
|
4209
4505
|
} else {
|
|
4210
|
-
themePath =
|
|
4506
|
+
themePath = path9__default.default.join(process.cwd(), themeName);
|
|
4211
4507
|
}
|
|
4212
4508
|
} catch {
|
|
4213
|
-
themePath =
|
|
4509
|
+
themePath = path9__default.default.join(process.cwd(), themeName);
|
|
4214
4510
|
}
|
|
4215
4511
|
if (!fs__default.default.existsSync(themePath)) {
|
|
4216
4512
|
logger.error(`Theme "${themeName}" not found.`);
|
|
@@ -4221,10 +4517,10 @@ async function devCommand(options) {
|
|
|
4221
4517
|
"theme.config.ts",
|
|
4222
4518
|
"bundle-entry.ts",
|
|
4223
4519
|
"manifest.ts"
|
|
4224
|
-
].some((f) => fs__default.default.existsSync(
|
|
4520
|
+
].some((f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f)));
|
|
4225
4521
|
if (isThemeDir) {
|
|
4226
4522
|
themePath = process.cwd();
|
|
4227
|
-
themeName =
|
|
4523
|
+
themeName = path9__default.default.basename(themePath);
|
|
4228
4524
|
} else {
|
|
4229
4525
|
logger.error(
|
|
4230
4526
|
"Not in a theme directory and no --theme specified. Run from theme root or use --theme flag."
|
|
@@ -4293,9 +4589,9 @@ async function devCommand(options) {
|
|
|
4293
4589
|
watcher.close();
|
|
4294
4590
|
await context2.dispose();
|
|
4295
4591
|
server.close();
|
|
4296
|
-
const shimPath =
|
|
4592
|
+
const shimPath = path9__default.default.join(outputDir, ".process-shim.js");
|
|
4297
4593
|
try {
|
|
4298
|
-
await
|
|
4594
|
+
await fs8__default.default.unlink(shimPath);
|
|
4299
4595
|
} catch {
|
|
4300
4596
|
}
|
|
4301
4597
|
process.exit(0);
|
|
@@ -4304,8 +4600,8 @@ async function devCommand(options) {
|
|
|
4304
4600
|
|
|
4305
4601
|
// src/commands/config.ts
|
|
4306
4602
|
init_logger();
|
|
4307
|
-
var CONFIG_DIR =
|
|
4308
|
-
var CONFIG_FILE =
|
|
4603
|
+
var CONFIG_DIR = path9__default.default.join(os__default.default.homedir(), ".onexthm");
|
|
4604
|
+
var CONFIG_FILE = path9__default.default.join(CONFIG_DIR, ".env");
|
|
4309
4605
|
var CONFIG_ENTRIES = [
|
|
4310
4606
|
{
|
|
4311
4607
|
key: "AWS_ACCESS_KEY_ID",
|
|
@@ -4447,122 +4743,6 @@ async function configCommand() {
|
|
|
4447
4743
|
|
|
4448
4744
|
// src/commands/login.ts
|
|
4449
4745
|
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
4746
|
async function loginCommand() {
|
|
4567
4747
|
logger.header("OneX Theme Developer Login");
|
|
4568
4748
|
const existing = loadAuthTokens();
|
|
@@ -4688,13 +4868,13 @@ async function publishCommand(options) {
|
|
|
4688
4868
|
logger.info(`Logged in as: ${tokens.user.email}`);
|
|
4689
4869
|
let themePath;
|
|
4690
4870
|
if (options.theme) {
|
|
4691
|
-
themePath =
|
|
4871
|
+
themePath = path9__default.default.resolve(options.theme);
|
|
4692
4872
|
} else {
|
|
4693
4873
|
const isThemeDir = [
|
|
4694
4874
|
"theme.config.ts",
|
|
4695
4875
|
"bundle-entry.ts",
|
|
4696
4876
|
"manifest.ts"
|
|
4697
|
-
].some((f) => fs__default.default.existsSync(
|
|
4877
|
+
].some((f) => fs__default.default.existsSync(path9__default.default.join(process.cwd(), f)));
|
|
4698
4878
|
if (isThemeDir) {
|
|
4699
4879
|
themePath = process.cwd();
|
|
4700
4880
|
} else {
|
|
@@ -4704,14 +4884,31 @@ async function publishCommand(options) {
|
|
|
4704
4884
|
process.exit(1);
|
|
4705
4885
|
}
|
|
4706
4886
|
}
|
|
4707
|
-
const pkgPath =
|
|
4887
|
+
const pkgPath = path9__default.default.join(themePath, "package.json");
|
|
4708
4888
|
if (!fs__default.default.existsSync(pkgPath)) {
|
|
4709
4889
|
logger.error("No package.json found in theme directory");
|
|
4710
4890
|
process.exit(1);
|
|
4711
4891
|
}
|
|
4712
4892
|
const pkg = fs__default.default.readJsonSync(pkgPath);
|
|
4713
|
-
const themeId = pkg.name?.replace("@onex-themes/", "") ||
|
|
4893
|
+
const themeId = pkg.name?.replace("@onex-themes/", "") || path9__default.default.basename(themePath);
|
|
4894
|
+
if (options.bump) {
|
|
4895
|
+
const currentVersion = pkg.version || "1.0.0";
|
|
4896
|
+
const newVersion = semver__default.default.inc(currentVersion, options.bump);
|
|
4897
|
+
if (!newVersion) {
|
|
4898
|
+
logger.error(`Failed to bump version from ${currentVersion}`);
|
|
4899
|
+
process.exit(1);
|
|
4900
|
+
}
|
|
4901
|
+
pkg.version = newVersion;
|
|
4902
|
+
fs__default.default.writeJsonSync(pkgPath, pkg, { spaces: 2 });
|
|
4903
|
+
logger.info(`Bumped version: ${currentVersion} -> ${newVersion}`);
|
|
4904
|
+
}
|
|
4714
4905
|
const version2 = pkg.version || "1.0.0";
|
|
4906
|
+
if (!semver__default.default.valid(version2)) {
|
|
4907
|
+
logger.error(
|
|
4908
|
+
`Invalid version "${version2}" in package.json. Must be valid semver (e.g., 1.0.0)`
|
|
4909
|
+
);
|
|
4910
|
+
process.exit(1);
|
|
4911
|
+
}
|
|
4715
4912
|
logger.newLine();
|
|
4716
4913
|
logger.info(`Theme: ${themeId}`);
|
|
4717
4914
|
logger.info(`Version: ${version2}`);
|
|
@@ -4748,6 +4945,38 @@ async function publishCommand(options) {
|
|
|
4748
4945
|
logger.error(error instanceof Error ? error.message : "Connection failed");
|
|
4749
4946
|
process.exit(1);
|
|
4750
4947
|
}
|
|
4948
|
+
logger.startSpinner("Checking version availability...");
|
|
4949
|
+
try {
|
|
4950
|
+
const checkResponse = await authenticatedFetch(
|
|
4951
|
+
`${apiUrl}/website-api/themes/${encodeURIComponent(themeId)}/versions/${encodeURIComponent(version2)}/exists`,
|
|
4952
|
+
{ method: "GET" }
|
|
4953
|
+
);
|
|
4954
|
+
const checkData = await checkResponse.json();
|
|
4955
|
+
const checkBody = checkData.statusCode ? checkData.body : checkData;
|
|
4956
|
+
if (checkBody.exists) {
|
|
4957
|
+
logger.stopSpinner(false, "Version already published");
|
|
4958
|
+
const patchVer = semver__default.default.inc(version2, "patch") || "?";
|
|
4959
|
+
const minorVer = semver__default.default.inc(version2, "minor") || "?";
|
|
4960
|
+
const majorVer = semver__default.default.inc(version2, "major") || "?";
|
|
4961
|
+
logger.error(
|
|
4962
|
+
`
|
|
4963
|
+
Version ${version2} of "${themeId}" is already published and cannot be overwritten.
|
|
4964
|
+
|
|
4965
|
+
To publish a new version:
|
|
4966
|
+
1. Bump version in package.json (e.g., ${version2} -> ${patchVer})
|
|
4967
|
+
2. Run: onexthm publish
|
|
4968
|
+
|
|
4969
|
+
Or use the --bump flag:
|
|
4970
|
+
onexthm publish --bump patch (${version2} -> ${patchVer})
|
|
4971
|
+
onexthm publish --bump minor (${version2} -> ${minorVer})
|
|
4972
|
+
onexthm publish --bump major (${version2} -> ${majorVer})`
|
|
4973
|
+
);
|
|
4974
|
+
process.exit(1);
|
|
4975
|
+
}
|
|
4976
|
+
logger.stopSpinner(true, `Version ${version2} is available`);
|
|
4977
|
+
} catch (error) {
|
|
4978
|
+
logger.stopSpinner(true, "Version check skipped (endpoint not available)");
|
|
4979
|
+
}
|
|
4751
4980
|
logger.startSpinner("Building theme...");
|
|
4752
4981
|
try {
|
|
4753
4982
|
const { compileStandaloneTheme: compileStandaloneTheme2 } = await Promise.resolve().then(() => (init_compile_theme(), compile_theme_exports));
|
|
@@ -4793,13 +5022,13 @@ async function publishCommand(options) {
|
|
|
4793
5022
|
try {
|
|
4794
5023
|
const archiver3 = await import('archiver');
|
|
4795
5024
|
const { createWriteStream } = await import('fs');
|
|
4796
|
-
const distDir =
|
|
5025
|
+
const distDir = path9__default.default.join(themePath, "dist");
|
|
4797
5026
|
if (!fs__default.default.existsSync(distDir)) {
|
|
4798
5027
|
logger.stopSpinner(false, "No dist/ directory");
|
|
4799
5028
|
logger.error("Build the theme first: onexthm build");
|
|
4800
5029
|
process.exit(1);
|
|
4801
5030
|
}
|
|
4802
|
-
const bundleZipPath =
|
|
5031
|
+
const bundleZipPath = path9__default.default.join(themePath, "dist", "bundle.zip");
|
|
4803
5032
|
await createZip(distDir, bundleZipPath, [
|
|
4804
5033
|
"bundle.zip",
|
|
4805
5034
|
"source.zip",
|
|
@@ -4824,7 +5053,7 @@ async function publishCommand(options) {
|
|
|
4824
5053
|
}
|
|
4825
5054
|
logger.startSpinner("Uploading source...");
|
|
4826
5055
|
try {
|
|
4827
|
-
const sourceZipPath =
|
|
5056
|
+
const sourceZipPath = path9__default.default.join(themePath, "dist", "source.zip");
|
|
4828
5057
|
await createZip(themePath, sourceZipPath, [
|
|
4829
5058
|
"node_modules",
|
|
4830
5059
|
"dist",
|
|
@@ -4909,17 +5138,23 @@ async function createZip(sourceDir, outputPath, exclude) {
|
|
|
4909
5138
|
}
|
|
4910
5139
|
|
|
4911
5140
|
// src/cli.ts
|
|
5141
|
+
dotenv__default.default.config({
|
|
5142
|
+
path: path9__default.default.join(process.cwd(), ".env.local"),
|
|
5143
|
+
override: true
|
|
5144
|
+
});
|
|
5145
|
+
dotenv__default.default.config({ path: path9__default.default.join(process.cwd(), ".env") });
|
|
4912
5146
|
try {
|
|
4913
5147
|
const projectRoot = getProjectRoot();
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
5148
|
+
if (path9__default.default.resolve(projectRoot) !== path9__default.default.resolve(process.cwd())) {
|
|
5149
|
+
dotenv__default.default.config({
|
|
5150
|
+
path: path9__default.default.join(projectRoot, ".env.local")
|
|
5151
|
+
});
|
|
5152
|
+
dotenv__default.default.config({ path: path9__default.default.join(projectRoot, ".env") });
|
|
5153
|
+
}
|
|
4919
5154
|
} catch {
|
|
4920
5155
|
}
|
|
4921
5156
|
dotenv__default.default.config({
|
|
4922
|
-
path:
|
|
5157
|
+
path: path9__default.default.join(os__default.default.homedir(), ".onexthm", ".env"),
|
|
4923
5158
|
quiet: true
|
|
4924
5159
|
});
|
|
4925
5160
|
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 +5214,10 @@ program.command("config").description("Configure OneX CLI credentials (AWS, API
|
|
|
4979
5214
|
program.command("login").description("Login to OneX platform").action(loginCommand);
|
|
4980
5215
|
program.command("logout").description("Logout from OneX platform").action(logoutCommand);
|
|
4981
5216
|
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").
|
|
5217
|
+
program.command("publish").description("Build, scan, and publish theme to marketplace (requires login)").option("-t, --theme <path>", "Theme directory path").option(
|
|
5218
|
+
"--bump <type>",
|
|
5219
|
+
"Auto-bump version before publish (patch|minor|major)"
|
|
5220
|
+
).action(publishCommand);
|
|
4983
5221
|
program.configureOutput({
|
|
4984
5222
|
writeErr: (str) => process.stderr.write(chalk4__default.default.red(str))
|
|
4985
5223
|
});
|