@onexapis/cli 1.1.37 → 1.1.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +688 -454
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +681 -449
- package/dist/cli.mjs.map +1 -1
- package/dist/index.js +343 -256
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +339 -253
- package/dist/index.mjs.map +1 -1
- package/dist/preview/preview-app.tsx +5 -13
- package/package.json +8 -4
- package/templates/default/bundle-entry.ts +0 -5
- package/templates/default/index.ts +1 -21
- package/templates/default/sections-registry.ts +0 -28
- package/templates/default/theme.layout.ts +2 -53
- package/templates/default/AUTH_AND_PROFILE.md +0 -167
- package/templates/default/LAYOUT.md +0 -195
- package/templates/default/hooks/index.ts +0 -26
- package/templates/default/hooks/use-forgot-password-form.ts +0 -90
- package/templates/default/hooks/use-login-form.ts +0 -102
- package/templates/default/hooks/use-profile-form.ts +0 -255
- package/templates/default/hooks/use-register-form.ts +0 -154
- package/templates/default/hooks/use-verify-code-form.ts +0 -224
- package/templates/default/pages/forgot-password.ts +0 -41
- package/templates/default/pages/login.ts +0 -41
- package/templates/default/pages/profile.ts +0 -39
- package/templates/default/pages/register.ts +0 -41
- package/templates/default/pages/verify-code.ts +0 -41
- package/templates/default/sections/auth-forgot-password/auth-forgot-password-default.tsx +0 -192
- package/templates/default/sections/auth-forgot-password/auth-forgot-password.schema.ts +0 -150
- package/templates/default/sections/auth-forgot-password/index.ts +0 -14
- package/templates/default/sections/auth-login/auth-login-default.tsx +0 -238
- package/templates/default/sections/auth-login/auth-login.schema.ts +0 -171
- package/templates/default/sections/auth-login/index.ts +0 -14
- package/templates/default/sections/auth-register/auth-register-default.tsx +0 -327
- package/templates/default/sections/auth-register/auth-register.schema.ts +0 -188
- package/templates/default/sections/auth-register/index.ts +0 -14
- package/templates/default/sections/auth-verify-code/auth-verify-code-default.tsx +0 -209
- package/templates/default/sections/auth-verify-code/auth-verify-code.schema.ts +0 -150
- package/templates/default/sections/auth-verify-code/index.ts +0 -14
- package/templates/default/sections/footer/footer-default.tsx +0 -214
- package/templates/default/sections/footer/footer.schema.ts +0 -170
- package/templates/default/sections/footer/index.ts +0 -14
- package/templates/default/sections/header/header-default.tsx +0 -322
- package/templates/default/sections/header/header.schema.ts +0 -168
- package/templates/default/sections/header/index.ts +0 -14
- package/templates/default/sections/profile/index.ts +0 -14
- package/templates/default/sections/profile/profile-default.tsx +0 -522
- package/templates/default/sections/profile/profile.schema.ts +0 -228
package/dist/index.mjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import chalk4 from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
3
|
import * as esbuild from 'esbuild';
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import path9 from 'path';
|
|
5
|
+
import fs8 from 'fs/promises';
|
|
6
6
|
import crypto from 'crypto';
|
|
7
7
|
import { glob } from 'glob';
|
|
8
8
|
import { createRequire } from 'module';
|
|
9
|
-
import
|
|
10
|
-
import
|
|
9
|
+
import fs4 from 'fs';
|
|
10
|
+
import spawn2 from 'cross-spawn';
|
|
11
11
|
import inquirer from 'inquirer';
|
|
12
12
|
import fs from 'fs-extra';
|
|
13
13
|
import ejs from 'ejs';
|
|
14
|
-
import { PutObjectCommand, GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
|
15
14
|
import os from 'os';
|
|
15
|
+
import { PutObjectCommand, GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
|
16
16
|
import archiver from 'archiver';
|
|
17
17
|
import AdmZip from 'adm-zip';
|
|
18
18
|
|
|
@@ -102,8 +102,8 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
102
102
|
const tailwindcss = (await import('tailwindcss')).default;
|
|
103
103
|
const tailwindConfig = {
|
|
104
104
|
content: [
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
path9.join(themePath, "sections/**/*.{ts,tsx}"),
|
|
106
|
+
path9.join(themePath, "components/**/*.{ts,tsx}")
|
|
107
107
|
],
|
|
108
108
|
theme: { extend: {} },
|
|
109
109
|
plugins: []
|
|
@@ -113,7 +113,7 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
113
113
|
inputCSS,
|
|
114
114
|
{ from: void 0 }
|
|
115
115
|
);
|
|
116
|
-
await
|
|
116
|
+
await fs8.writeFile(path9.join(outDir, "bundle.css"), result.css);
|
|
117
117
|
logger.info("Generated bundle.css");
|
|
118
118
|
} catch (err) {
|
|
119
119
|
logger.warning(
|
|
@@ -124,12 +124,12 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
124
124
|
async function resolveNodeModulesFile(startDir, relativePath) {
|
|
125
125
|
let dir = startDir;
|
|
126
126
|
while (true) {
|
|
127
|
-
const candidate =
|
|
127
|
+
const candidate = path9.join(dir, "node_modules", relativePath);
|
|
128
128
|
try {
|
|
129
|
-
await
|
|
129
|
+
await fs8.access(candidate);
|
|
130
130
|
return candidate;
|
|
131
131
|
} catch {
|
|
132
|
-
const parent =
|
|
132
|
+
const parent = path9.dirname(dir);
|
|
133
133
|
if (parent === dir) break;
|
|
134
134
|
dir = parent;
|
|
135
135
|
}
|
|
@@ -153,7 +153,7 @@ async function scanImportsFromPackage(sourceDir, packageName) {
|
|
|
153
153
|
});
|
|
154
154
|
for (const file of sourceFiles) {
|
|
155
155
|
try {
|
|
156
|
-
const content = await
|
|
156
|
+
const content = await fs8.readFile(path9.join(sourceDir, file), "utf-8");
|
|
157
157
|
for (const match of content.matchAll(namespaceImportRegex)) {
|
|
158
158
|
const subpath = match[1] ? match[1].slice(1) : "";
|
|
159
159
|
if (!result[subpath]) result[subpath] = /* @__PURE__ */ new Set();
|
|
@@ -207,17 +207,17 @@ function createCoreGlobalPlugin(themePath) {
|
|
|
207
207
|
const distFileName = subpath ? `${subpath}.mjs` : "index.mjs";
|
|
208
208
|
let distPath = await resolveNodeModulesFile(
|
|
209
209
|
themePath,
|
|
210
|
-
|
|
210
|
+
path9.join("@onexapis", "core", "dist", distFileName)
|
|
211
211
|
);
|
|
212
212
|
if (!distPath) {
|
|
213
213
|
distPath = await resolveNodeModulesFile(
|
|
214
214
|
__dirname,
|
|
215
|
-
|
|
215
|
+
path9.join("@onexapis", "core", "dist", distFileName)
|
|
216
216
|
);
|
|
217
217
|
}
|
|
218
218
|
try {
|
|
219
219
|
if (!distPath) throw new Error("not found");
|
|
220
|
-
const distContent = await
|
|
220
|
+
const distContent = await fs8.readFile(distPath, "utf-8");
|
|
221
221
|
const exportMatches = distContent.matchAll(/export\s*\{([^}]+)\}/g);
|
|
222
222
|
for (const m of exportMatches) {
|
|
223
223
|
const names = m[1].split(",").map((n) => {
|
|
@@ -446,7 +446,7 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
446
446
|
const pages = {};
|
|
447
447
|
for (const ext of [".ts", ".js"]) {
|
|
448
448
|
try {
|
|
449
|
-
const mod = await jiti.import(
|
|
449
|
+
const mod = await jiti.import(path9.join(themePath, `theme.config${ext}`));
|
|
450
450
|
themeConfig = mod.default || mod;
|
|
451
451
|
break;
|
|
452
452
|
} catch {
|
|
@@ -454,20 +454,20 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
454
454
|
}
|
|
455
455
|
for (const ext of [".ts", ".js"]) {
|
|
456
456
|
try {
|
|
457
|
-
const mod = await jiti.import(
|
|
457
|
+
const mod = await jiti.import(path9.join(themePath, `theme.layout${ext}`));
|
|
458
458
|
layoutConfig = mod.default || mod;
|
|
459
459
|
break;
|
|
460
460
|
} catch {
|
|
461
461
|
}
|
|
462
462
|
}
|
|
463
463
|
const schemas = {};
|
|
464
|
-
const sectionsDir =
|
|
464
|
+
const sectionsDir = path9.join(themePath, "sections");
|
|
465
465
|
try {
|
|
466
|
-
const sectionDirs = await
|
|
466
|
+
const sectionDirs = await fs8.readdir(sectionsDir);
|
|
467
467
|
for (const dir of sectionDirs) {
|
|
468
|
-
const schemaFile =
|
|
468
|
+
const schemaFile = path9.join(sectionsDir, dir, `${dir}.schema.ts`);
|
|
469
469
|
try {
|
|
470
|
-
await
|
|
470
|
+
await fs8.access(schemaFile);
|
|
471
471
|
const mod = await jiti.import(schemaFile);
|
|
472
472
|
for (const [key, value] of Object.entries(mod)) {
|
|
473
473
|
if (key.endsWith("Schema") && value && typeof value === "object" && value.type) {
|
|
@@ -479,14 +479,14 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
479
479
|
}
|
|
480
480
|
} catch {
|
|
481
481
|
}
|
|
482
|
-
const pagesDir =
|
|
482
|
+
const pagesDir = path9.join(themePath, "pages");
|
|
483
483
|
try {
|
|
484
|
-
const files = await
|
|
484
|
+
const files = await fs8.readdir(pagesDir);
|
|
485
485
|
for (const file of files) {
|
|
486
486
|
if (!file.match(/\.(ts|js)$/)) continue;
|
|
487
487
|
const name = file.replace(/\.(ts|js)$/, "");
|
|
488
488
|
try {
|
|
489
|
-
const mod = await jiti.import(
|
|
489
|
+
const mod = await jiti.import(path9.join(pagesDir, file));
|
|
490
490
|
const config = mod.default || mod;
|
|
491
491
|
const sections = (config.sections || []).map((section) => {
|
|
492
492
|
const schema = schemas[section.type];
|
|
@@ -514,8 +514,8 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
514
514
|
}
|
|
515
515
|
} catch {
|
|
516
516
|
}
|
|
517
|
-
await
|
|
518
|
-
|
|
517
|
+
await fs8.writeFile(
|
|
518
|
+
path9.join(outputDir, "theme-data.json"),
|
|
519
519
|
JSON.stringify(
|
|
520
520
|
{
|
|
521
521
|
themeId,
|
|
@@ -538,36 +538,36 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
538
538
|
logger.info(`Generated theme-data.json (${Object.keys(pages).length} pages)`);
|
|
539
539
|
}
|
|
540
540
|
async function contentHashEntry(outputDir) {
|
|
541
|
-
const entryPath =
|
|
542
|
-
const mapPath =
|
|
541
|
+
const entryPath = path9.join(outputDir, "bundle-entry.js");
|
|
542
|
+
const mapPath = path9.join(outputDir, "bundle-entry.js.map");
|
|
543
543
|
const oldFiles = await glob("bundle-entry-*.js*", { cwd: outputDir });
|
|
544
544
|
for (const f of oldFiles) {
|
|
545
|
-
await
|
|
545
|
+
await fs8.unlink(path9.join(outputDir, f));
|
|
546
546
|
}
|
|
547
547
|
let entryContent;
|
|
548
548
|
try {
|
|
549
|
-
entryContent = await
|
|
549
|
+
entryContent = await fs8.readFile(entryPath, "utf-8");
|
|
550
550
|
} catch {
|
|
551
|
-
const indexPath =
|
|
551
|
+
const indexPath = path9.join(outputDir, "index.js");
|
|
552
552
|
try {
|
|
553
|
-
entryContent = await
|
|
553
|
+
entryContent = await fs8.readFile(indexPath, "utf-8");
|
|
554
554
|
} catch {
|
|
555
555
|
logger.warning("No entry file found in output, skipping content hash");
|
|
556
556
|
return;
|
|
557
557
|
}
|
|
558
558
|
const hash2 = crypto.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
|
|
559
559
|
const hashedName2 = `bundle-entry-${hash2}.js`;
|
|
560
|
-
const indexMapPath =
|
|
560
|
+
const indexMapPath = path9.join(outputDir, "index.js.map");
|
|
561
561
|
const hashedMapName2 = `bundle-entry-${hash2}.js.map`;
|
|
562
562
|
entryContent = entryContent.replace(
|
|
563
563
|
/\/\/# sourceMappingURL=index\.js\.map/,
|
|
564
564
|
`//# sourceMappingURL=${hashedMapName2}`
|
|
565
565
|
);
|
|
566
|
-
await
|
|
567
|
-
await
|
|
566
|
+
await fs8.writeFile(path9.join(outputDir, hashedName2), entryContent);
|
|
567
|
+
await fs8.unlink(indexPath);
|
|
568
568
|
try {
|
|
569
|
-
await
|
|
570
|
-
await
|
|
569
|
+
await fs8.access(indexMapPath);
|
|
570
|
+
await fs8.rename(indexMapPath, path9.join(outputDir, hashedMapName2));
|
|
571
571
|
} catch {
|
|
572
572
|
}
|
|
573
573
|
logger.info(`Entry hashed: ${hashedName2}`);
|
|
@@ -580,11 +580,11 @@ async function contentHashEntry(outputDir) {
|
|
|
580
580
|
/\/\/# sourceMappingURL=bundle-entry\.js\.map/,
|
|
581
581
|
`//# sourceMappingURL=${hashedMapName}`
|
|
582
582
|
);
|
|
583
|
-
await
|
|
584
|
-
await
|
|
583
|
+
await fs8.writeFile(path9.join(outputDir, hashedName), entryContent);
|
|
584
|
+
await fs8.unlink(entryPath);
|
|
585
585
|
try {
|
|
586
|
-
await
|
|
587
|
-
await
|
|
586
|
+
await fs8.access(mapPath);
|
|
587
|
+
await fs8.rename(mapPath, path9.join(outputDir, hashedMapName));
|
|
588
588
|
} catch {
|
|
589
589
|
}
|
|
590
590
|
logger.info(`Entry hashed: ${hashedName}`);
|
|
@@ -596,7 +596,7 @@ async function extractDataRequirements(themePath) {
|
|
|
596
596
|
const requirements = {};
|
|
597
597
|
for (const file of schemaFiles) {
|
|
598
598
|
try {
|
|
599
|
-
const mod = await jiti.import(
|
|
599
|
+
const mod = await jiti.import(path9.join(themePath, file));
|
|
600
600
|
const exports$1 = mod;
|
|
601
601
|
for (const value of Object.values(exports$1)) {
|
|
602
602
|
if (value && typeof value === "object" && typeof value.type === "string" && value.dataRequirements && typeof value.dataRequirements === "object") {
|
|
@@ -615,8 +615,8 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
615
615
|
let version = "1.0.0";
|
|
616
616
|
let themeId = themeName;
|
|
617
617
|
try {
|
|
618
|
-
const pkgContent = await
|
|
619
|
-
|
|
618
|
+
const pkgContent = await fs8.readFile(
|
|
619
|
+
path9.join(themePath, "package.json"),
|
|
620
620
|
"utf-8"
|
|
621
621
|
);
|
|
622
622
|
const pkg = JSON.parse(pkgContent);
|
|
@@ -634,7 +634,7 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
634
634
|
const dataRequirements = await extractDataRequirements(themePath);
|
|
635
635
|
let hasThemeConfig = false;
|
|
636
636
|
try {
|
|
637
|
-
await
|
|
637
|
+
await fs8.access(path9.join(themePath, "theme.config.ts"));
|
|
638
638
|
hasThemeConfig = true;
|
|
639
639
|
} catch {
|
|
640
640
|
}
|
|
@@ -675,24 +675,24 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
675
675
|
// Section data requirements for server-side prefetching (keyed by section type)
|
|
676
676
|
dataRequirements
|
|
677
677
|
};
|
|
678
|
-
await
|
|
679
|
-
|
|
678
|
+
await fs8.writeFile(
|
|
679
|
+
path9.join(outputDir, "manifest.json"),
|
|
680
680
|
JSON.stringify(manifest, null, 2)
|
|
681
681
|
);
|
|
682
682
|
}
|
|
683
683
|
async function compileStandaloneTheme(themePath, themeName) {
|
|
684
|
-
const outputDir =
|
|
685
|
-
const bundleEntry =
|
|
686
|
-
const indexEntry =
|
|
684
|
+
const outputDir = path9.join(themePath, "dist");
|
|
685
|
+
const bundleEntry = path9.join(themePath, "bundle-entry.ts");
|
|
686
|
+
const indexEntry = path9.join(themePath, "index.ts");
|
|
687
687
|
let entryPoint = indexEntry;
|
|
688
688
|
try {
|
|
689
|
-
await
|
|
689
|
+
await fs8.access(bundleEntry);
|
|
690
690
|
entryPoint = bundleEntry;
|
|
691
691
|
} catch {
|
|
692
692
|
}
|
|
693
|
-
const shimPath =
|
|
694
|
-
await
|
|
695
|
-
await
|
|
693
|
+
const shimPath = path9.join(outputDir, ".process-shim.js");
|
|
694
|
+
await fs8.mkdir(outputDir, { recursive: true });
|
|
695
|
+
await fs8.writeFile(shimPath, PROCESS_SHIM);
|
|
696
696
|
const buildOptions = {
|
|
697
697
|
entryPoints: [entryPoint],
|
|
698
698
|
bundle: true,
|
|
@@ -742,7 +742,7 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
742
742
|
try {
|
|
743
743
|
const result = await esbuild.build(buildOptions);
|
|
744
744
|
try {
|
|
745
|
-
await
|
|
745
|
+
await fs8.unlink(shimPath);
|
|
746
746
|
} catch {
|
|
747
747
|
}
|
|
748
748
|
await contentHashEntry(outputDir);
|
|
@@ -761,7 +761,7 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
761
761
|
return true;
|
|
762
762
|
} catch (error) {
|
|
763
763
|
try {
|
|
764
|
-
await
|
|
764
|
+
await fs8.unlink(shimPath);
|
|
765
765
|
} catch {
|
|
766
766
|
}
|
|
767
767
|
logger.error(`esbuild compilation failed: ${error}`);
|
|
@@ -769,18 +769,18 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
769
769
|
}
|
|
770
770
|
}
|
|
771
771
|
async function compileStandaloneThemeDev(themePath, themeName) {
|
|
772
|
-
const outputDir =
|
|
773
|
-
const bundleEntry =
|
|
774
|
-
const indexEntry =
|
|
772
|
+
const outputDir = path9.join(themePath, "dist");
|
|
773
|
+
const bundleEntry = path9.join(themePath, "bundle-entry.ts");
|
|
774
|
+
const indexEntry = path9.join(themePath, "index.ts");
|
|
775
775
|
let entryPoint = indexEntry;
|
|
776
776
|
try {
|
|
777
|
-
await
|
|
777
|
+
await fs8.access(bundleEntry);
|
|
778
778
|
entryPoint = bundleEntry;
|
|
779
779
|
} catch {
|
|
780
780
|
}
|
|
781
|
-
const shimPath =
|
|
782
|
-
await
|
|
783
|
-
await
|
|
781
|
+
const shimPath = path9.join(outputDir, ".process-shim.js");
|
|
782
|
+
await fs8.mkdir(outputDir, { recursive: true });
|
|
783
|
+
await fs8.writeFile(shimPath, PROCESS_SHIM);
|
|
784
784
|
const buildOptions = {
|
|
785
785
|
entryPoints: [entryPoint],
|
|
786
786
|
bundle: true,
|
|
@@ -833,18 +833,18 @@ async function compileStandaloneThemeDev(themePath, themeName) {
|
|
|
833
833
|
return { context: context2, outputDir };
|
|
834
834
|
}
|
|
835
835
|
async function compilePreviewRuntime(themePath) {
|
|
836
|
-
const outputDir =
|
|
837
|
-
await
|
|
838
|
-
const outputPath =
|
|
836
|
+
const outputDir = path9.join(themePath, "dist");
|
|
837
|
+
await fs8.mkdir(outputDir, { recursive: true });
|
|
838
|
+
const outputPath = path9.join(outputDir, "preview-runtime.js");
|
|
839
839
|
const locations = [
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
840
|
+
path9.join(__dirname, "..", "preview", "preview-app.tsx"),
|
|
841
|
+
path9.join(__dirname, "preview", "preview-app.tsx"),
|
|
842
|
+
path9.join(__dirname, "..", "..", "src", "preview", "preview-app.tsx")
|
|
843
843
|
];
|
|
844
844
|
let previewEntryPath = null;
|
|
845
845
|
for (const loc of locations) {
|
|
846
846
|
try {
|
|
847
|
-
await
|
|
847
|
+
await fs8.access(loc);
|
|
848
848
|
previewEntryPath = loc;
|
|
849
849
|
break;
|
|
850
850
|
} catch {
|
|
@@ -927,10 +927,10 @@ ${locations.join("\n")}`
|
|
|
927
927
|
if (!lucideScanned) {
|
|
928
928
|
lucideScanned = true;
|
|
929
929
|
const coreSrcCandidates = [
|
|
930
|
-
|
|
931
|
-
|
|
930
|
+
path9.join(themePath, "node_modules", "@onexapis", "core", "src"),
|
|
931
|
+
path9.join(themePath, "..", "..", "packages", "core", "src"),
|
|
932
932
|
// monorepo sibling
|
|
933
|
-
|
|
933
|
+
path9.join(
|
|
934
934
|
__dirname,
|
|
935
935
|
"..",
|
|
936
936
|
"..",
|
|
@@ -945,7 +945,7 @@ ${locations.join("\n")}`
|
|
|
945
945
|
let coreSourceDir = null;
|
|
946
946
|
for (const candidate of coreSrcCandidates) {
|
|
947
947
|
try {
|
|
948
|
-
await
|
|
948
|
+
await fs8.access(candidate);
|
|
949
949
|
coreSourceDir = candidate;
|
|
950
950
|
break;
|
|
951
951
|
} catch {
|
|
@@ -964,21 +964,21 @@ ${locations.join("\n")}`
|
|
|
964
964
|
}
|
|
965
965
|
} else {
|
|
966
966
|
const coreDistCandidates = [
|
|
967
|
-
|
|
967
|
+
path9.join(themePath, "node_modules", "@onexapis", "core", "dist")
|
|
968
968
|
];
|
|
969
969
|
const resolvedDist = await resolveNodeModulesFile(
|
|
970
970
|
__dirname,
|
|
971
|
-
|
|
971
|
+
path9.join("@onexapis", "core", "dist")
|
|
972
972
|
);
|
|
973
973
|
if (resolvedDist) coreDistCandidates.push(resolvedDist);
|
|
974
974
|
for (const candidate of coreDistCandidates) {
|
|
975
975
|
try {
|
|
976
|
-
await
|
|
976
|
+
await fs8.access(candidate);
|
|
977
977
|
const mjsFiles = await glob("*.mjs", { cwd: candidate });
|
|
978
978
|
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']lucide-react["']/g;
|
|
979
979
|
for (const file of mjsFiles) {
|
|
980
|
-
const content = await
|
|
981
|
-
|
|
980
|
+
const content = await fs8.readFile(
|
|
981
|
+
path9.join(candidate, file),
|
|
982
982
|
"utf-8"
|
|
983
983
|
);
|
|
984
984
|
for (const match of content.matchAll(importRegex)) {
|
|
@@ -1033,7 +1033,7 @@ export default new Proxy({}, { get: (_, name) => name === '__esModule' ? true :
|
|
|
1033
1033
|
const req = createRequire(import.meta.url || __filename);
|
|
1034
1034
|
const cjsPath = req.resolve("framer-motion");
|
|
1035
1035
|
const pkgDir = cjsPath.replace(/[/\\]dist[/\\].*$/, "");
|
|
1036
|
-
const esmEntry =
|
|
1036
|
+
const esmEntry = path9.join(pkgDir, "dist", "es", "index.mjs");
|
|
1037
1037
|
const { existsSync } = await import('fs');
|
|
1038
1038
|
if (existsSync(esmEntry)) {
|
|
1039
1039
|
return { path: esmEntry, namespace: "file" };
|
|
@@ -1132,8 +1132,8 @@ export function headers() { return new Headers(); }
|
|
|
1132
1132
|
});
|
|
1133
1133
|
}
|
|
1134
1134
|
};
|
|
1135
|
-
const shimPath =
|
|
1136
|
-
await
|
|
1135
|
+
const shimPath = path9.join(outputDir, ".process-shim-preview.js");
|
|
1136
|
+
await fs8.writeFile(shimPath, PROCESS_SHIM);
|
|
1137
1137
|
await esbuild.build({
|
|
1138
1138
|
entryPoints: [previewEntryPath],
|
|
1139
1139
|
bundle: true,
|
|
@@ -1168,7 +1168,7 @@ export function headers() { return new Headers(); }
|
|
|
1168
1168
|
}
|
|
1169
1169
|
});
|
|
1170
1170
|
try {
|
|
1171
|
-
await
|
|
1171
|
+
await fs8.unlink(shimPath);
|
|
1172
1172
|
} catch {
|
|
1173
1173
|
}
|
|
1174
1174
|
return outputPath;
|
|
@@ -1315,8 +1315,8 @@ function validateThemeName(name) {
|
|
|
1315
1315
|
return /^[a-z][a-z0-9-]*$/.test(name);
|
|
1316
1316
|
}
|
|
1317
1317
|
function pathExists(filePath) {
|
|
1318
|
-
const
|
|
1319
|
-
return
|
|
1318
|
+
const fs13 = __require("fs-extra");
|
|
1319
|
+
return fs13.existsSync(filePath);
|
|
1320
1320
|
}
|
|
1321
1321
|
function validateCategory(category) {
|
|
1322
1322
|
const validCategories = [
|
|
@@ -1357,18 +1357,18 @@ async function renderTemplate(templatePath, data) {
|
|
|
1357
1357
|
return ejs.render(template, data);
|
|
1358
1358
|
}
|
|
1359
1359
|
async function writeFile(filePath, content) {
|
|
1360
|
-
await fs.ensureDir(
|
|
1360
|
+
await fs.ensureDir(path9.dirname(filePath));
|
|
1361
1361
|
await fs.writeFile(filePath, content, "utf-8");
|
|
1362
1362
|
}
|
|
1363
1363
|
function getTemplatesDir() {
|
|
1364
1364
|
const locations = [
|
|
1365
|
-
|
|
1365
|
+
path9.join(__dirname, "../../templates"),
|
|
1366
1366
|
// Development
|
|
1367
|
-
|
|
1367
|
+
path9.join(__dirname, "../templates"),
|
|
1368
1368
|
// Production (dist/)
|
|
1369
|
-
|
|
1369
|
+
path9.join(process.cwd(), "templates"),
|
|
1370
1370
|
// Fallback
|
|
1371
|
-
|
|
1371
|
+
path9.join(process.cwd(), "packages/cli/templates")
|
|
1372
1372
|
// Monorepo
|
|
1373
1373
|
];
|
|
1374
1374
|
for (const location of locations) {
|
|
@@ -1380,7 +1380,7 @@ function getTemplatesDir() {
|
|
|
1380
1380
|
}
|
|
1381
1381
|
async function copyTemplate(templateName, targetDir, data) {
|
|
1382
1382
|
const templatesDir = getTemplatesDir();
|
|
1383
|
-
const templateDir =
|
|
1383
|
+
const templateDir = path9.join(templatesDir, templateName);
|
|
1384
1384
|
if (!fs.existsSync(templateDir)) {
|
|
1385
1385
|
throw new Error(
|
|
1386
1386
|
`Template "${templateName}" not found at ${templateDir}. Available templates: ${fs.readdirSync(templatesDir).join(", ")}`
|
|
@@ -1389,8 +1389,8 @@ async function copyTemplate(templateName, targetDir, data) {
|
|
|
1389
1389
|
await fs.ensureDir(targetDir);
|
|
1390
1390
|
const files = await fs.readdir(templateDir);
|
|
1391
1391
|
for (const file of files) {
|
|
1392
|
-
const templatePath =
|
|
1393
|
-
const targetPath =
|
|
1392
|
+
const templatePath = path9.join(templateDir, file);
|
|
1393
|
+
const targetPath = path9.join(targetDir, file);
|
|
1394
1394
|
const stat = await fs.stat(templatePath);
|
|
1395
1395
|
if (stat.isDirectory()) {
|
|
1396
1396
|
await copyTemplateDir(templatePath, targetPath, data);
|
|
@@ -1407,8 +1407,8 @@ async function copyTemplateDir(templateDir, targetDir, data) {
|
|
|
1407
1407
|
await fs.ensureDir(targetDir);
|
|
1408
1408
|
const files = await fs.readdir(templateDir);
|
|
1409
1409
|
for (const file of files) {
|
|
1410
|
-
const templatePath =
|
|
1411
|
-
const targetPath =
|
|
1410
|
+
const templatePath = path9.join(templateDir, file);
|
|
1411
|
+
const targetPath = path9.join(targetDir, file);
|
|
1412
1412
|
const stat = await fs.stat(templatePath);
|
|
1413
1413
|
if (stat.isDirectory()) {
|
|
1414
1414
|
await copyTemplateDir(templatePath, targetPath, data);
|
|
@@ -1423,32 +1423,32 @@ async function copyTemplateDir(templateDir, targetDir, data) {
|
|
|
1423
1423
|
}
|
|
1424
1424
|
function getProjectRoot() {
|
|
1425
1425
|
let currentDir = process.cwd();
|
|
1426
|
-
while (currentDir !==
|
|
1427
|
-
const packageJsonPath =
|
|
1426
|
+
while (currentDir !== path9.parse(currentDir).root) {
|
|
1427
|
+
const packageJsonPath = path9.join(currentDir, "package.json");
|
|
1428
1428
|
if (fs.existsSync(packageJsonPath)) {
|
|
1429
1429
|
const packageJson = fs.readJsonSync(packageJsonPath);
|
|
1430
|
-
if (packageJson.workspaces || fs.existsSync(
|
|
1430
|
+
if (packageJson.workspaces || fs.existsSync(path9.join(currentDir, "src/themes")) || fs.existsSync(path9.join(currentDir, "themes"))) {
|
|
1431
1431
|
return currentDir;
|
|
1432
1432
|
}
|
|
1433
1433
|
}
|
|
1434
|
-
currentDir =
|
|
1434
|
+
currentDir = path9.dirname(currentDir);
|
|
1435
1435
|
}
|
|
1436
1436
|
return process.cwd();
|
|
1437
1437
|
}
|
|
1438
1438
|
function getThemesDir() {
|
|
1439
1439
|
const root = getProjectRoot();
|
|
1440
|
-
if (fs.existsSync(
|
|
1441
|
-
return
|
|
1442
|
-
if (fs.existsSync(
|
|
1443
|
-
return
|
|
1444
|
-
return
|
|
1440
|
+
if (fs.existsSync(path9.join(root, "themes")))
|
|
1441
|
+
return path9.join(root, "themes");
|
|
1442
|
+
if (fs.existsSync(path9.join(root, "src/themes")))
|
|
1443
|
+
return path9.join(root, "src/themes");
|
|
1444
|
+
return path9.dirname(root);
|
|
1445
1445
|
}
|
|
1446
1446
|
function getFeaturesDir() {
|
|
1447
|
-
return
|
|
1447
|
+
return path9.join(getProjectRoot(), "src/features");
|
|
1448
1448
|
}
|
|
1449
1449
|
function isOneXProject() {
|
|
1450
1450
|
const root = getProjectRoot();
|
|
1451
|
-
return fs.existsSync(
|
|
1451
|
+
return fs.existsSync(path9.join(root, "themes")) || fs.existsSync(path9.join(root, "src/themes")) || fs.existsSync(path9.join(root, "theme.config.ts")) || fs.existsSync(path9.join(root, "bundle-entry.ts"));
|
|
1452
1452
|
}
|
|
1453
1453
|
function ensureOneXProject() {
|
|
1454
1454
|
if (!isOneXProject()) {
|
|
@@ -1464,13 +1464,13 @@ function listThemes() {
|
|
|
1464
1464
|
return [];
|
|
1465
1465
|
}
|
|
1466
1466
|
return fs.readdirSync(themesDir).filter((name) => {
|
|
1467
|
-
const themePath =
|
|
1468
|
-
return fs.statSync(themePath).isDirectory() && (fs.existsSync(
|
|
1467
|
+
const themePath = path9.join(themesDir, name);
|
|
1468
|
+
return fs.statSync(themePath).isDirectory() && (fs.existsSync(path9.join(themePath, "theme.config.ts")) || fs.existsSync(path9.join(themePath, "bundle-entry.ts")) || fs.existsSync(path9.join(themePath, "manifest.ts")));
|
|
1469
1469
|
});
|
|
1470
1470
|
}
|
|
1471
1471
|
function themeExists(themeName) {
|
|
1472
|
-
const themePath =
|
|
1473
|
-
return fs.existsSync(themePath) && (fs.existsSync(
|
|
1472
|
+
const themePath = path9.join(getThemesDir(), themeName);
|
|
1473
|
+
return fs.existsSync(themePath) && (fs.existsSync(path9.join(themePath, "theme.config.ts")) || fs.existsSync(path9.join(themePath, "bundle-entry.ts")) || fs.existsSync(path9.join(themePath, "manifest.ts")));
|
|
1474
1474
|
}
|
|
1475
1475
|
function detectPackageManager() {
|
|
1476
1476
|
const userAgent = process.env.npm_config_user_agent || "";
|
|
@@ -1478,24 +1478,91 @@ function detectPackageManager() {
|
|
|
1478
1478
|
if (userAgent.includes("yarn")) return "yarn";
|
|
1479
1479
|
if (userAgent.includes("bun")) return "bun";
|
|
1480
1480
|
const cwd = process.cwd();
|
|
1481
|
-
if (fs.existsSync(
|
|
1482
|
-
if (fs.existsSync(
|
|
1483
|
-
if (fs.existsSync(
|
|
1481
|
+
if (fs.existsSync(path9.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
1482
|
+
if (fs.existsSync(path9.join(cwd, "yarn.lock"))) return "yarn";
|
|
1483
|
+
if (fs.existsSync(path9.join(cwd, "bun.lockb"))) return "bun";
|
|
1484
1484
|
return "npm";
|
|
1485
1485
|
}
|
|
1486
1486
|
async function installDependencies(projectPath, packageManager = "npm") {
|
|
1487
|
-
|
|
1487
|
+
const args = packageManager === "yarn" ? [] : ["install"];
|
|
1488
|
+
const result = spawn2.sync(packageManager, args, {
|
|
1489
|
+
cwd: projectPath,
|
|
1490
|
+
stdio: "inherit"
|
|
1491
|
+
});
|
|
1492
|
+
if (result.status !== 0) {
|
|
1493
|
+
throw new Error(
|
|
1494
|
+
`${packageManager} install failed with exit code ${result.status}`
|
|
1495
|
+
);
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
var AUTH_DIR = path9.join(os.homedir(), ".onexthm");
|
|
1499
|
+
path9.join(AUTH_DIR, "auth.json");
|
|
1500
|
+
function getApiUrl() {
|
|
1501
|
+
return process.env.ONEXTHM_API_URL || process.env.NEXT_PUBLIC_API_URL || "https://platform-dev.onexeos.com";
|
|
1502
|
+
}
|
|
1503
|
+
function getNpxCommand() {
|
|
1504
|
+
return process.platform === "win32" ? "npx.cmd" : "npx";
|
|
1505
|
+
}
|
|
1506
|
+
function getDefaultMcpConfig() {
|
|
1507
|
+
return {
|
|
1508
|
+
mcpServers: {
|
|
1509
|
+
onexthm: {
|
|
1510
|
+
command: getNpxCommand(),
|
|
1511
|
+
args: ["-y", "@onexapis/theme-mcp"]
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
function ensureMcpJson(projectPath, figmaApiKey) {
|
|
1517
|
+
const mcpJsonPath = path9.join(projectPath, ".mcp.json");
|
|
1518
|
+
const npx = getNpxCommand();
|
|
1519
|
+
let mcpConfig;
|
|
1520
|
+
if (fs4.existsSync(mcpJsonPath)) {
|
|
1488
1521
|
try {
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
} catch (error) {
|
|
1496
|
-
reject(error);
|
|
1522
|
+
mcpConfig = JSON.parse(fs4.readFileSync(mcpJsonPath, "utf-8"));
|
|
1523
|
+
if (!mcpConfig.mcpServers) {
|
|
1524
|
+
mcpConfig.mcpServers = {};
|
|
1525
|
+
}
|
|
1526
|
+
} catch {
|
|
1527
|
+
mcpConfig = getDefaultMcpConfig();
|
|
1497
1528
|
}
|
|
1498
|
-
}
|
|
1529
|
+
} else {
|
|
1530
|
+
mcpConfig = getDefaultMcpConfig();
|
|
1531
|
+
}
|
|
1532
|
+
mcpConfig.mcpServers.onexthm = {
|
|
1533
|
+
command: npx,
|
|
1534
|
+
args: ["-y", "@onexapis/theme-mcp"]
|
|
1535
|
+
};
|
|
1536
|
+
if (figmaApiKey) {
|
|
1537
|
+
mcpConfig.mcpServers.figma = {
|
|
1538
|
+
command: npx,
|
|
1539
|
+
args: [
|
|
1540
|
+
"-y",
|
|
1541
|
+
"figma-developer-mcp",
|
|
1542
|
+
`--figma-api-key=${figmaApiKey}`,
|
|
1543
|
+
"--stdio"
|
|
1544
|
+
]
|
|
1545
|
+
};
|
|
1546
|
+
} else {
|
|
1547
|
+
delete mcpConfig.mcpServers.figma;
|
|
1548
|
+
}
|
|
1549
|
+
fs4.writeFileSync(mcpJsonPath, JSON.stringify(mcpConfig, null, 2) + "\n");
|
|
1550
|
+
ensureThemeMcpDependency(projectPath);
|
|
1551
|
+
}
|
|
1552
|
+
function ensureThemeMcpDependency(projectPath) {
|
|
1553
|
+
const pkgJsonPath = path9.join(projectPath, "package.json");
|
|
1554
|
+
if (!fs4.existsSync(pkgJsonPath)) return;
|
|
1555
|
+
try {
|
|
1556
|
+
const pkg = JSON.parse(fs4.readFileSync(pkgJsonPath, "utf-8"));
|
|
1557
|
+
if (!pkg.devDependencies) {
|
|
1558
|
+
pkg.devDependencies = {};
|
|
1559
|
+
}
|
|
1560
|
+
if (!pkg.devDependencies["@onexapis/theme-mcp"]) {
|
|
1561
|
+
pkg.devDependencies["@onexapis/theme-mcp"] = "^0.1.0";
|
|
1562
|
+
fs4.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
1563
|
+
}
|
|
1564
|
+
} catch {
|
|
1565
|
+
}
|
|
1499
1566
|
}
|
|
1500
1567
|
|
|
1501
1568
|
// src/commands/init.ts
|
|
@@ -1514,7 +1581,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1514
1581
|
if (!validateThemeName(kebabName)) {
|
|
1515
1582
|
return "Invalid project name. Use lowercase letters, numbers, and hyphens only.";
|
|
1516
1583
|
}
|
|
1517
|
-
if (
|
|
1584
|
+
if (fs4.existsSync(path9.join(process.cwd(), kebabName))) {
|
|
1518
1585
|
return `Directory "${kebabName}" already exists`;
|
|
1519
1586
|
}
|
|
1520
1587
|
return true;
|
|
@@ -1525,11 +1592,46 @@ async function initCommand(projectName, options = {}) {
|
|
|
1525
1592
|
} else {
|
|
1526
1593
|
name = toKebabCase(projectName);
|
|
1527
1594
|
}
|
|
1528
|
-
const projectPath =
|
|
1529
|
-
if (
|
|
1595
|
+
const projectPath = path9.join(process.cwd(), name);
|
|
1596
|
+
if (fs4.existsSync(projectPath)) {
|
|
1530
1597
|
logger.error(`Directory "${name}" already exists.`);
|
|
1531
1598
|
process.exit(1);
|
|
1532
1599
|
}
|
|
1600
|
+
if (!options.yes) {
|
|
1601
|
+
try {
|
|
1602
|
+
const apiUrl = getApiUrl();
|
|
1603
|
+
const controller = new AbortController();
|
|
1604
|
+
const timeout = setTimeout(() => controller.abort(), 3e3);
|
|
1605
|
+
const response = await fetch(
|
|
1606
|
+
`${apiUrl}/website-api/themes/${encodeURIComponent(name)}/exists`,
|
|
1607
|
+
{ signal: controller.signal }
|
|
1608
|
+
);
|
|
1609
|
+
clearTimeout(timeout);
|
|
1610
|
+
if (response.ok) {
|
|
1611
|
+
const data2 = await response.json();
|
|
1612
|
+
const body = data2.statusCode ? data2.body : data2;
|
|
1613
|
+
if (body.exists && body.owner === "other") {
|
|
1614
|
+
logger.warning(
|
|
1615
|
+
`Theme ID "${name}" is already registered by another developer.
|
|
1616
|
+
You can still create this locally, but publishing will fail.
|
|
1617
|
+
Consider using a different name.`
|
|
1618
|
+
);
|
|
1619
|
+
const { proceed } = await inquirer.prompt([
|
|
1620
|
+
{
|
|
1621
|
+
type: "confirm",
|
|
1622
|
+
name: "proceed",
|
|
1623
|
+
message: "Continue anyway?",
|
|
1624
|
+
default: false
|
|
1625
|
+
}
|
|
1626
|
+
]);
|
|
1627
|
+
if (!proceed) {
|
|
1628
|
+
process.exit(0);
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
}
|
|
1632
|
+
} catch {
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1533
1635
|
let displayName;
|
|
1534
1636
|
let description;
|
|
1535
1637
|
let author;
|
|
@@ -1597,7 +1699,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1597
1699
|
}
|
|
1598
1700
|
logger.startSpinner("Creating project structure...");
|
|
1599
1701
|
try {
|
|
1600
|
-
|
|
1702
|
+
fs4.mkdirSync(projectPath, { recursive: true });
|
|
1601
1703
|
await copyTemplate(template, projectPath, data);
|
|
1602
1704
|
await renameThemeInFiles(
|
|
1603
1705
|
projectPath,
|
|
@@ -1606,28 +1708,14 @@ async function initCommand(projectName, options = {}) {
|
|
|
1606
1708
|
description,
|
|
1607
1709
|
author
|
|
1608
1710
|
);
|
|
1609
|
-
|
|
1610
|
-
if (fs2.existsSync(mcpJsonPath)) {
|
|
1611
|
-
let mcpContent = fs2.readFileSync(mcpJsonPath, "utf-8");
|
|
1612
|
-
if (figmaApiKey) {
|
|
1613
|
-
mcpContent = mcpContent.replace("__FIGMA_API_KEY__", figmaApiKey);
|
|
1614
|
-
} else {
|
|
1615
|
-
try {
|
|
1616
|
-
const mcpJson = JSON.parse(mcpContent);
|
|
1617
|
-
delete mcpJson.mcpServers.figma;
|
|
1618
|
-
mcpContent = JSON.stringify(mcpJson, null, 2) + "\n";
|
|
1619
|
-
} catch {
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
|
-
fs2.writeFileSync(mcpJsonPath, mcpContent, "utf-8");
|
|
1623
|
-
}
|
|
1711
|
+
ensureMcpJson(projectPath, figmaApiKey || void 0);
|
|
1624
1712
|
logger.stopSpinner(true, "Project structure created!");
|
|
1625
1713
|
if (options.git) {
|
|
1626
1714
|
logger.startSpinner("Initializing git repository...");
|
|
1627
1715
|
try {
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1716
|
+
spawn2.sync("git", ["init"], { cwd: projectPath, stdio: "ignore" });
|
|
1717
|
+
spawn2.sync("git", ["add", "."], { cwd: projectPath, stdio: "ignore" });
|
|
1718
|
+
spawn2.sync("git", ["commit", "-m", "Initial commit from onexthm init"], {
|
|
1631
1719
|
cwd: projectPath,
|
|
1632
1720
|
stdio: "ignore"
|
|
1633
1721
|
});
|
|
@@ -1679,16 +1767,16 @@ async function initCommand(projectName, options = {}) {
|
|
|
1679
1767
|
logger.error(
|
|
1680
1768
|
error instanceof Error ? error.message : "Unknown error occurred"
|
|
1681
1769
|
);
|
|
1682
|
-
if (
|
|
1683
|
-
|
|
1770
|
+
if (fs4.existsSync(projectPath)) {
|
|
1771
|
+
fs4.rmSync(projectPath, { recursive: true, force: true });
|
|
1684
1772
|
}
|
|
1685
1773
|
process.exit(1);
|
|
1686
1774
|
}
|
|
1687
1775
|
}
|
|
1688
1776
|
async function renameThemeInFiles(projectPath, themeName, displayName, description, author) {
|
|
1689
|
-
const configPath =
|
|
1690
|
-
if (
|
|
1691
|
-
let content =
|
|
1777
|
+
const configPath = path9.join(projectPath, "theme.config.ts");
|
|
1778
|
+
if (fs4.existsSync(configPath)) {
|
|
1779
|
+
let content = fs4.readFileSync(configPath, "utf-8");
|
|
1692
1780
|
content = content.replace(
|
|
1693
1781
|
/name: "My Simple Theme"/,
|
|
1694
1782
|
`name: "${displayName}"`
|
|
@@ -1697,11 +1785,11 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
|
|
|
1697
1785
|
/description: ".*?"/,
|
|
1698
1786
|
`description: "${description}"`
|
|
1699
1787
|
);
|
|
1700
|
-
|
|
1788
|
+
fs4.writeFileSync(configPath, content, "utf-8");
|
|
1701
1789
|
}
|
|
1702
|
-
const pkgPath =
|
|
1703
|
-
if (
|
|
1704
|
-
let content =
|
|
1790
|
+
const pkgPath = path9.join(projectPath, "package.json");
|
|
1791
|
+
if (fs4.existsSync(pkgPath)) {
|
|
1792
|
+
let content = fs4.readFileSync(pkgPath, "utf-8");
|
|
1705
1793
|
content = content.replace(
|
|
1706
1794
|
/@onex-themes\/my-simple/g,
|
|
1707
1795
|
`@onex-themes/${themeName}`
|
|
@@ -1710,7 +1798,7 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
|
|
|
1710
1798
|
/"description": ".*?"/,
|
|
1711
1799
|
`"description": "${description}"`
|
|
1712
1800
|
);
|
|
1713
|
-
|
|
1801
|
+
fs4.writeFileSync(pkgPath, content, "utf-8");
|
|
1714
1802
|
}
|
|
1715
1803
|
}
|
|
1716
1804
|
|
|
@@ -1721,10 +1809,10 @@ async function createSectionCommand(name, options) {
|
|
|
1721
1809
|
ensureOneXProject();
|
|
1722
1810
|
if (!options.theme) {
|
|
1723
1811
|
const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
|
|
1724
|
-
(f) => fs.existsSync(
|
|
1812
|
+
(f) => fs.existsSync(path9.join(process.cwd(), f))
|
|
1725
1813
|
);
|
|
1726
1814
|
if (isStandaloneTheme) {
|
|
1727
|
-
options.theme =
|
|
1815
|
+
options.theme = path9.basename(process.cwd());
|
|
1728
1816
|
}
|
|
1729
1817
|
}
|
|
1730
1818
|
const sectionName = toKebabCase(name);
|
|
@@ -1787,35 +1875,35 @@ async function createSectionCommand(name, options) {
|
|
|
1787
1875
|
};
|
|
1788
1876
|
logger.startSpinner("Creating section files...");
|
|
1789
1877
|
try {
|
|
1790
|
-
const themePath =
|
|
1791
|
-
const sectionPath =
|
|
1878
|
+
const themePath = path9.join(getThemesDir(), themeName);
|
|
1879
|
+
const sectionPath = path9.join(themePath, "sections", sectionName);
|
|
1792
1880
|
const schemaContent = generateSectionSchema(data);
|
|
1793
1881
|
await writeFile(
|
|
1794
|
-
|
|
1882
|
+
path9.join(sectionPath, `${sectionName}.schema.ts`),
|
|
1795
1883
|
schemaContent
|
|
1796
1884
|
);
|
|
1797
1885
|
if (createTemplate) {
|
|
1798
1886
|
const templateContent = generateSectionTemplate(data);
|
|
1799
1887
|
await writeFile(
|
|
1800
|
-
|
|
1888
|
+
path9.join(sectionPath, `${sectionName}-default.tsx`),
|
|
1801
1889
|
templateContent
|
|
1802
1890
|
);
|
|
1803
1891
|
}
|
|
1804
1892
|
const indexContent = generateSectionIndex(data, createTemplate);
|
|
1805
|
-
await writeFile(
|
|
1893
|
+
await writeFile(path9.join(sectionPath, "index.ts"), indexContent);
|
|
1806
1894
|
logger.stopSpinner(true, "Section files created successfully!");
|
|
1807
1895
|
logger.newLine();
|
|
1808
1896
|
logger.section("Next steps:");
|
|
1809
1897
|
logger.log(
|
|
1810
|
-
` 1. Edit schema: ${
|
|
1898
|
+
` 1. Edit schema: ${path9.relative(process.cwd(), path9.join(sectionPath, `${sectionName}.schema.ts`))}`
|
|
1811
1899
|
);
|
|
1812
1900
|
if (createTemplate) {
|
|
1813
1901
|
logger.log(
|
|
1814
|
-
` 2. Edit template: ${
|
|
1902
|
+
` 2. Edit template: ${path9.relative(process.cwd(), path9.join(sectionPath, `${sectionName}-default.tsx`))}`
|
|
1815
1903
|
);
|
|
1816
1904
|
}
|
|
1817
1905
|
logger.log(
|
|
1818
|
-
` 3. Add to theme manifest: ${
|
|
1906
|
+
` 3. Add to theme manifest: ${path9.relative(process.cwd(), path9.join(themePath, "manifest.ts"))}`
|
|
1819
1907
|
);
|
|
1820
1908
|
logger.newLine();
|
|
1821
1909
|
logger.success("Section created successfully!");
|
|
@@ -1963,10 +2051,10 @@ async function createBlockCommand(name, options) {
|
|
|
1963
2051
|
ensureOneXProject();
|
|
1964
2052
|
if (!options.theme) {
|
|
1965
2053
|
const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
|
|
1966
|
-
(f) => fs.existsSync(
|
|
2054
|
+
(f) => fs.existsSync(path9.join(process.cwd(), f))
|
|
1967
2055
|
);
|
|
1968
2056
|
if (isStandaloneTheme) {
|
|
1969
|
-
options.theme =
|
|
2057
|
+
options.theme = path9.basename(process.cwd());
|
|
1970
2058
|
}
|
|
1971
2059
|
}
|
|
1972
2060
|
const blockName = toKebabCase(name);
|
|
@@ -2041,24 +2129,24 @@ async function createBlockCommand(name, options) {
|
|
|
2041
2129
|
};
|
|
2042
2130
|
logger.startSpinner("Creating block files...");
|
|
2043
2131
|
try {
|
|
2044
|
-
const blockPath = scope === "shared" ?
|
|
2132
|
+
const blockPath = scope === "shared" ? path9.join(getFeaturesDir(), "blocks", blockName) : path9.join(getThemesDir(), themeName, "blocks", blockName);
|
|
2045
2133
|
const schemaContent = generateBlockSchema(data);
|
|
2046
2134
|
await writeFile(
|
|
2047
|
-
|
|
2135
|
+
path9.join(blockPath, `${blockName}.schema.ts`),
|
|
2048
2136
|
schemaContent
|
|
2049
2137
|
);
|
|
2050
2138
|
const componentContent = generateBlockComponent(data);
|
|
2051
|
-
await writeFile(
|
|
2139
|
+
await writeFile(path9.join(blockPath, `${blockName}.tsx`), componentContent);
|
|
2052
2140
|
const indexContent = generateBlockIndex(data);
|
|
2053
|
-
await writeFile(
|
|
2141
|
+
await writeFile(path9.join(blockPath, "index.ts"), indexContent);
|
|
2054
2142
|
logger.stopSpinner(true, "Block files created successfully!");
|
|
2055
2143
|
logger.newLine();
|
|
2056
2144
|
logger.section("Next steps:");
|
|
2057
2145
|
logger.log(
|
|
2058
|
-
` 1. Edit schema: ${
|
|
2146
|
+
` 1. Edit schema: ${path9.relative(process.cwd(), path9.join(blockPath, `${blockName}.schema.ts`))}`
|
|
2059
2147
|
);
|
|
2060
2148
|
logger.log(
|
|
2061
|
-
` 2. Edit component: ${
|
|
2149
|
+
` 2. Edit component: ${path9.relative(process.cwd(), path9.join(blockPath, `${blockName}.tsx`))}`
|
|
2062
2150
|
);
|
|
2063
2151
|
logger.log(
|
|
2064
2152
|
` 3. Register in block registry: src/lib/registry/block-registry.ts`
|
|
@@ -2236,31 +2324,31 @@ async function createComponentCommand(name, options) {
|
|
|
2236
2324
|
};
|
|
2237
2325
|
logger.startSpinner("Creating component files...");
|
|
2238
2326
|
try {
|
|
2239
|
-
const componentPath =
|
|
2327
|
+
const componentPath = path9.join(
|
|
2240
2328
|
getFeaturesDir(),
|
|
2241
2329
|
"components",
|
|
2242
2330
|
componentName
|
|
2243
2331
|
);
|
|
2244
2332
|
const schemaContent = generateComponentSchema(data);
|
|
2245
2333
|
await writeFile(
|
|
2246
|
-
|
|
2334
|
+
path9.join(componentPath, `${componentName}.schema.ts`),
|
|
2247
2335
|
schemaContent
|
|
2248
2336
|
);
|
|
2249
2337
|
const componentContent = generateComponent(data);
|
|
2250
2338
|
await writeFile(
|
|
2251
|
-
|
|
2339
|
+
path9.join(componentPath, `${componentName}.tsx`),
|
|
2252
2340
|
componentContent
|
|
2253
2341
|
);
|
|
2254
2342
|
const indexContent = generateComponentIndex(data);
|
|
2255
|
-
await writeFile(
|
|
2343
|
+
await writeFile(path9.join(componentPath, "index.ts"), indexContent);
|
|
2256
2344
|
logger.stopSpinner(true, "Component files created successfully!");
|
|
2257
2345
|
logger.newLine();
|
|
2258
2346
|
logger.section("Next steps:");
|
|
2259
2347
|
logger.log(
|
|
2260
|
-
` 1. Edit schema: ${
|
|
2348
|
+
` 1. Edit schema: ${path9.relative(process.cwd(), path9.join(componentPath, `${componentName}.schema.ts`))}`
|
|
2261
2349
|
);
|
|
2262
2350
|
logger.log(
|
|
2263
|
-
` 2. Edit component: ${
|
|
2351
|
+
` 2. Edit component: ${path9.relative(process.cwd(), path9.join(componentPath, `${componentName}.tsx`))}`
|
|
2264
2352
|
);
|
|
2265
2353
|
logger.log(
|
|
2266
2354
|
` 3. Register in component registry: src/lib/registry/component-registry.ts`
|
|
@@ -2417,13 +2505,13 @@ async function listSections(themeFilter) {
|
|
|
2417
2505
|
return;
|
|
2418
2506
|
}
|
|
2419
2507
|
for (const theme of themes) {
|
|
2420
|
-
const sectionsDir =
|
|
2508
|
+
const sectionsDir = path9.join(getThemesDir(), theme, "sections");
|
|
2421
2509
|
if (!fs.existsSync(sectionsDir)) {
|
|
2422
2510
|
continue;
|
|
2423
2511
|
}
|
|
2424
2512
|
const sections = fs.readdirSync(sectionsDir).filter((name) => {
|
|
2425
|
-
const sectionPath =
|
|
2426
|
-
return fs.statSync(sectionPath).isDirectory() && fs.existsSync(
|
|
2513
|
+
const sectionPath = path9.join(sectionsDir, name);
|
|
2514
|
+
return fs.statSync(sectionPath).isDirectory() && fs.existsSync(path9.join(sectionPath, "index.ts"));
|
|
2427
2515
|
});
|
|
2428
2516
|
if (sections.length > 0) {
|
|
2429
2517
|
logger.log(chalk4.cyan(`
|
|
@@ -2437,11 +2525,11 @@ async function listSections(themeFilter) {
|
|
|
2437
2525
|
}
|
|
2438
2526
|
async function listBlocks(themeFilter) {
|
|
2439
2527
|
logger.section("\u{1F9F1} Blocks");
|
|
2440
|
-
const sharedBlocksDir =
|
|
2528
|
+
const sharedBlocksDir = path9.join(getFeaturesDir(), "blocks");
|
|
2441
2529
|
if (fs.existsSync(sharedBlocksDir)) {
|
|
2442
2530
|
const sharedBlocks = fs.readdirSync(sharedBlocksDir).filter((name) => {
|
|
2443
|
-
const blockPath =
|
|
2444
|
-
return fs.statSync(blockPath).isDirectory() && fs.existsSync(
|
|
2531
|
+
const blockPath = path9.join(sharedBlocksDir, name);
|
|
2532
|
+
return fs.statSync(blockPath).isDirectory() && fs.existsSync(path9.join(blockPath, "index.ts"));
|
|
2445
2533
|
});
|
|
2446
2534
|
if (sharedBlocks.length > 0) {
|
|
2447
2535
|
logger.log(chalk4.cyan("\n Shared:"));
|
|
@@ -2452,13 +2540,13 @@ async function listBlocks(themeFilter) {
|
|
|
2452
2540
|
}
|
|
2453
2541
|
const themes = themeFilter ? [themeFilter] : listThemes();
|
|
2454
2542
|
for (const theme of themes) {
|
|
2455
|
-
const blocksDir =
|
|
2543
|
+
const blocksDir = path9.join(getThemesDir(), theme, "blocks");
|
|
2456
2544
|
if (!fs.existsSync(blocksDir)) {
|
|
2457
2545
|
continue;
|
|
2458
2546
|
}
|
|
2459
2547
|
const blocks = fs.readdirSync(blocksDir).filter((name) => {
|
|
2460
|
-
const blockPath =
|
|
2461
|
-
return fs.statSync(blockPath).isDirectory() && fs.existsSync(
|
|
2548
|
+
const blockPath = path9.join(blocksDir, name);
|
|
2549
|
+
return fs.statSync(blockPath).isDirectory() && fs.existsSync(path9.join(blockPath, "index.ts"));
|
|
2462
2550
|
});
|
|
2463
2551
|
if (blocks.length > 0) {
|
|
2464
2552
|
logger.log(chalk4.cyan(`
|
|
@@ -2472,14 +2560,14 @@ async function listBlocks(themeFilter) {
|
|
|
2472
2560
|
}
|
|
2473
2561
|
async function listComponents() {
|
|
2474
2562
|
logger.section("\u2699\uFE0F Components");
|
|
2475
|
-
const componentsDir =
|
|
2563
|
+
const componentsDir = path9.join(getFeaturesDir(), "components");
|
|
2476
2564
|
if (!fs.existsSync(componentsDir)) {
|
|
2477
2565
|
logger.warning("No components directory found");
|
|
2478
2566
|
return;
|
|
2479
2567
|
}
|
|
2480
2568
|
const components = fs.readdirSync(componentsDir).filter((name) => {
|
|
2481
|
-
const componentPath =
|
|
2482
|
-
return fs.statSync(componentPath).isDirectory() && fs.existsSync(
|
|
2569
|
+
const componentPath = path9.join(componentsDir, name);
|
|
2570
|
+
return fs.statSync(componentPath).isDirectory() && fs.existsSync(path9.join(componentPath, "index.ts"));
|
|
2483
2571
|
});
|
|
2484
2572
|
if (components.length === 0) {
|
|
2485
2573
|
logger.warning("No components found");
|
|
@@ -2500,11 +2588,11 @@ async function listThemesInfo() {
|
|
|
2500
2588
|
}
|
|
2501
2589
|
logger.log("");
|
|
2502
2590
|
for (const theme of themes) {
|
|
2503
|
-
const themeDir =
|
|
2591
|
+
const themeDir = path9.join(getThemesDir(), theme);
|
|
2504
2592
|
const candidates = ["theme.config.ts", "bundle-entry.ts", "manifest.ts"];
|
|
2505
2593
|
let manifestContent = "";
|
|
2506
2594
|
for (const candidate of candidates) {
|
|
2507
|
-
const candidatePath =
|
|
2595
|
+
const candidatePath = path9.join(themeDir, candidate);
|
|
2508
2596
|
if (fs.existsSync(candidatePath)) {
|
|
2509
2597
|
manifestContent = fs.readFileSync(candidatePath, "utf-8");
|
|
2510
2598
|
break;
|
|
@@ -2533,14 +2621,14 @@ async function buildCommand(options) {
|
|
|
2533
2621
|
if (options.theme) {
|
|
2534
2622
|
themeName = options.theme;
|
|
2535
2623
|
try {
|
|
2536
|
-
const workspaceThemePath =
|
|
2624
|
+
const workspaceThemePath = path9.join(getThemesDir(), themeName);
|
|
2537
2625
|
if (fs.existsSync(workspaceThemePath)) {
|
|
2538
2626
|
themePath = workspaceThemePath;
|
|
2539
2627
|
} else {
|
|
2540
|
-
themePath =
|
|
2628
|
+
themePath = path9.join(process.cwd(), themeName);
|
|
2541
2629
|
}
|
|
2542
2630
|
} catch {
|
|
2543
|
-
themePath =
|
|
2631
|
+
themePath = path9.join(process.cwd(), themeName);
|
|
2544
2632
|
}
|
|
2545
2633
|
if (!fs.existsSync(themePath)) {
|
|
2546
2634
|
logger.error(`Theme "${themeName}" not found.`);
|
|
@@ -2551,10 +2639,10 @@ async function buildCommand(options) {
|
|
|
2551
2639
|
"theme.config.ts",
|
|
2552
2640
|
"bundle-entry.ts",
|
|
2553
2641
|
"manifest.ts"
|
|
2554
|
-
].some((f) => fs.existsSync(
|
|
2642
|
+
].some((f) => fs.existsSync(path9.join(process.cwd(), f)));
|
|
2555
2643
|
if (isThemeDir) {
|
|
2556
2644
|
themePath = process.cwd();
|
|
2557
|
-
themeName =
|
|
2645
|
+
themeName = path9.basename(themePath);
|
|
2558
2646
|
logger.info(`Building current theme: ${themeName}`);
|
|
2559
2647
|
} else {
|
|
2560
2648
|
logger.error(
|
|
@@ -2563,7 +2651,7 @@ async function buildCommand(options) {
|
|
|
2563
2651
|
process.exit(1);
|
|
2564
2652
|
}
|
|
2565
2653
|
}
|
|
2566
|
-
const packageJsonPath =
|
|
2654
|
+
const packageJsonPath = path9.join(themePath, "package.json");
|
|
2567
2655
|
const hasPkgJson = fs.existsSync(packageJsonPath);
|
|
2568
2656
|
if (!hasPkgJson) {
|
|
2569
2657
|
logger.warning(
|
|
@@ -2619,9 +2707,9 @@ async function buildCommand(options) {
|
|
|
2619
2707
|
logger.success("\u2713 Theme built successfully!");
|
|
2620
2708
|
logger.newLine();
|
|
2621
2709
|
logger.info(`Theme: ${themeName}`);
|
|
2622
|
-
const distPath =
|
|
2710
|
+
const distPath = path9.join(themePath, "dist");
|
|
2623
2711
|
if (fs.existsSync(distPath)) {
|
|
2624
|
-
logger.log(`Output: ${
|
|
2712
|
+
logger.log(`Output: ${path9.relative(process.cwd(), distPath)}`);
|
|
2625
2713
|
const files = fs.readdirSync(distPath);
|
|
2626
2714
|
logger.log(`Files: ${files.length}`);
|
|
2627
2715
|
}
|
|
@@ -2629,17 +2717,17 @@ async function buildCommand(options) {
|
|
|
2629
2717
|
}
|
|
2630
2718
|
function runCommand(command, args, cwd) {
|
|
2631
2719
|
return new Promise((resolve) => {
|
|
2632
|
-
const proc =
|
|
2720
|
+
const proc = spawn2(command, args, {
|
|
2633
2721
|
cwd,
|
|
2634
2722
|
stdio: ["pipe", "pipe", "pipe"],
|
|
2635
2723
|
shell: true
|
|
2636
2724
|
});
|
|
2637
2725
|
let stdout = "";
|
|
2638
2726
|
let stderr = "";
|
|
2639
|
-
proc.stdout
|
|
2727
|
+
proc.stdout?.on("data", (data) => {
|
|
2640
2728
|
stdout += data.toString();
|
|
2641
2729
|
});
|
|
2642
|
-
proc.stderr
|
|
2730
|
+
proc.stderr?.on("data", (data) => {
|
|
2643
2731
|
stderr += data.toString();
|
|
2644
2732
|
});
|
|
2645
2733
|
proc.on("close", (code) => {
|
|
@@ -2709,11 +2797,11 @@ function getBucketName(env) {
|
|
|
2709
2797
|
return environment === "production" ? "theme-s3-bucket" : "theme-s3-bucket";
|
|
2710
2798
|
}
|
|
2711
2799
|
async function findCompiledThemeDir(themeId, version) {
|
|
2712
|
-
const searchPaths = [
|
|
2800
|
+
const searchPaths = [path9.resolve(process.cwd(), "dist")];
|
|
2713
2801
|
for (const dir of searchPaths) {
|
|
2714
2802
|
if (await fs.pathExists(dir)) {
|
|
2715
|
-
const hasManifest = await fs.pathExists(
|
|
2716
|
-
const hasThemeEntry = await fs.pathExists(
|
|
2803
|
+
const hasManifest = await fs.pathExists(path9.join(dir, "manifest.json"));
|
|
2804
|
+
const hasThemeEntry = await fs.pathExists(path9.join(dir, "bundle-entry.js")) || await fs.pathExists(path9.join(dir, "theme.config.js")) || await fs.pathExists(path9.join(dir, "index.js"));
|
|
2717
2805
|
if (hasManifest || hasThemeEntry) {
|
|
2718
2806
|
return dir;
|
|
2719
2807
|
}
|
|
@@ -2722,7 +2810,7 @@ async function findCompiledThemeDir(themeId, version) {
|
|
|
2722
2810
|
return null;
|
|
2723
2811
|
}
|
|
2724
2812
|
async function readManifest() {
|
|
2725
|
-
const manifestTsPath =
|
|
2813
|
+
const manifestTsPath = path9.resolve(process.cwd(), "manifest.ts");
|
|
2726
2814
|
if (await fs.pathExists(manifestTsPath)) {
|
|
2727
2815
|
try {
|
|
2728
2816
|
const module = await import(manifestTsPath);
|
|
@@ -2731,7 +2819,7 @@ async function readManifest() {
|
|
|
2731
2819
|
logger.warning("Failed to import manifest.ts, trying package.json");
|
|
2732
2820
|
}
|
|
2733
2821
|
}
|
|
2734
|
-
const packageJsonPath =
|
|
2822
|
+
const packageJsonPath = path9.resolve(process.cwd(), "package.json");
|
|
2735
2823
|
if (await fs.pathExists(packageJsonPath)) {
|
|
2736
2824
|
const pkg = await fs.readJson(packageJsonPath);
|
|
2737
2825
|
return {
|
|
@@ -2765,13 +2853,13 @@ async function findSourceDir(themeId, explicitDir) {
|
|
|
2765
2853
|
}
|
|
2766
2854
|
const searchPaths = [
|
|
2767
2855
|
process.cwd(),
|
|
2768
|
-
|
|
2769
|
-
|
|
2856
|
+
path9.resolve(process.cwd(), `../../themes/${themeId}`),
|
|
2857
|
+
path9.resolve(process.cwd(), `../themes/${themeId}`)
|
|
2770
2858
|
];
|
|
2771
2859
|
const markers = ["theme.config.ts", "bundle-entry.ts"];
|
|
2772
2860
|
for (const dir of searchPaths) {
|
|
2773
2861
|
for (const marker of markers) {
|
|
2774
|
-
if (await fs.pathExists(
|
|
2862
|
+
if (await fs.pathExists(path9.join(dir, marker))) {
|
|
2775
2863
|
return dir;
|
|
2776
2864
|
}
|
|
2777
2865
|
}
|
|
@@ -2823,7 +2911,7 @@ async function uploadCommand(options) {
|
|
|
2823
2911
|
spinner.succeed(`Found compiled theme at: ${compiledDir}`);
|
|
2824
2912
|
spinner.start("Creating bundle.zip...");
|
|
2825
2913
|
const tmpDir = os.tmpdir();
|
|
2826
|
-
const bundleZipPath =
|
|
2914
|
+
const bundleZipPath = path9.join(tmpDir, `${themeId}-${version}-bundle.zip`);
|
|
2827
2915
|
await createZipFromDir(compiledDir, bundleZipPath);
|
|
2828
2916
|
const bundleZipBuffer = await fs.readFile(bundleZipPath);
|
|
2829
2917
|
const bundleSizeMB = (bundleZipBuffer.length / 1024 / 1024).toFixed(2);
|
|
@@ -2877,7 +2965,7 @@ async function uploadCommand(options) {
|
|
|
2877
2965
|
if (sourceDir) {
|
|
2878
2966
|
spinner.succeed(`Found source at: ${sourceDir}`);
|
|
2879
2967
|
spinner.start("Creating source.zip...");
|
|
2880
|
-
const sourceZipPath =
|
|
2968
|
+
const sourceZipPath = path9.join(
|
|
2881
2969
|
tmpDir,
|
|
2882
2970
|
`${themeId}-${version}-source.zip`
|
|
2883
2971
|
);
|
|
@@ -3011,8 +3099,8 @@ async function resolveLatestVersion(s3Client, bucket, themeId) {
|
|
|
3011
3099
|
async function createCompatibilityFiles(outputDir, manifest) {
|
|
3012
3100
|
const entryFile = manifest.output?.entry || "bundle-entry.js";
|
|
3013
3101
|
if (entryFile !== "bundle-entry.js" && entryFile.startsWith("bundle-entry-")) {
|
|
3014
|
-
const hashedPath =
|
|
3015
|
-
const stablePath =
|
|
3102
|
+
const hashedPath = path9.join(outputDir, entryFile);
|
|
3103
|
+
const stablePath = path9.join(outputDir, "bundle-entry.js");
|
|
3016
3104
|
if (await fs.pathExists(hashedPath)) {
|
|
3017
3105
|
await fs.copy(hashedPath, stablePath);
|
|
3018
3106
|
const mapPath = hashedPath + ".map";
|
|
@@ -3021,13 +3109,13 @@ async function createCompatibilityFiles(outputDir, manifest) {
|
|
|
3021
3109
|
}
|
|
3022
3110
|
}
|
|
3023
3111
|
}
|
|
3024
|
-
const sectionsRegistryPath =
|
|
3112
|
+
const sectionsRegistryPath = path9.join(outputDir, "sections-registry.js");
|
|
3025
3113
|
const content = `// Re-export all sections from bundle-entry
|
|
3026
3114
|
// This file exists to maintain compatibility with the import path
|
|
3027
3115
|
export * from './bundle-entry.js';
|
|
3028
3116
|
`;
|
|
3029
3117
|
await fs.writeFile(sectionsRegistryPath, content, "utf-8");
|
|
3030
|
-
const pkgJsonPath =
|
|
3118
|
+
const pkgJsonPath = path9.join(outputDir, "package.json");
|
|
3031
3119
|
await fs.writeFile(pkgJsonPath, '{\n "type": "module"\n}\n', "utf-8");
|
|
3032
3120
|
}
|
|
3033
3121
|
function showDownloadFailureHelp(themeId, bucket) {
|
|
@@ -3089,6 +3177,18 @@ async function downloadCommand(options) {
|
|
|
3089
3177
|
spinner.succeed(
|
|
3090
3178
|
`Resolved latest version: ${chalk4.cyan(resolvedVersion)}`
|
|
3091
3179
|
);
|
|
3180
|
+
const isCI = !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.VERCEL);
|
|
3181
|
+
if (isCI) {
|
|
3182
|
+
console.log(
|
|
3183
|
+
chalk4.yellow(
|
|
3184
|
+
`
|
|
3185
|
+
Warning: Resolved "latest" to ${resolvedVersion} in CI environment.
|
|
3186
|
+
For production builds, pin to a specific version:
|
|
3187
|
+
THEME_VERSION=${resolvedVersion}
|
|
3188
|
+
`
|
|
3189
|
+
)
|
|
3190
|
+
);
|
|
3191
|
+
}
|
|
3092
3192
|
}
|
|
3093
3193
|
spinner.start(
|
|
3094
3194
|
`Downloading bundle.zip for ${themeId}@${resolvedVersion}...`
|
|
@@ -3110,7 +3210,7 @@ async function downloadCommand(options) {
|
|
|
3110
3210
|
zip.extractAllTo(outputDir, true);
|
|
3111
3211
|
const entries = zip.getEntries().filter((e) => !e.isDirectory);
|
|
3112
3212
|
spinner.succeed(`Extracted ${entries.length} files to ${outputDir}`);
|
|
3113
|
-
const manifestPath =
|
|
3213
|
+
const manifestPath = path9.join(outputDir, "manifest.json");
|
|
3114
3214
|
const manifest = await fs.readJson(manifestPath);
|
|
3115
3215
|
await createCompatibilityFiles(outputDir, manifest);
|
|
3116
3216
|
console.log();
|
|
@@ -3210,10 +3310,9 @@ async function resolveLatestVersion2(s3Client, bucket, themeId) {
|
|
|
3210
3310
|
}
|
|
3211
3311
|
function runInstall(cwd) {
|
|
3212
3312
|
return new Promise((resolve) => {
|
|
3213
|
-
const proc =
|
|
3313
|
+
const proc = spawn2("pnpm", ["install"], {
|
|
3214
3314
|
cwd,
|
|
3215
|
-
stdio: "inherit"
|
|
3216
|
-
shell: true
|
|
3315
|
+
stdio: "inherit"
|
|
3217
3316
|
});
|
|
3218
3317
|
proc.on("close", (code) => resolve(code === 0));
|
|
3219
3318
|
proc.on("error", () => resolve(false));
|
|
@@ -3244,7 +3343,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3244
3343
|
const oldPrefix = `${oldName}-`;
|
|
3245
3344
|
const newPrefix = `${newName}-`;
|
|
3246
3345
|
const newDisplayName = newName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3247
|
-
const pkgPath =
|
|
3346
|
+
const pkgPath = path9.join(themeDir, "package.json");
|
|
3248
3347
|
if (await fs.pathExists(pkgPath)) {
|
|
3249
3348
|
const pkg = await fs.readJson(pkgPath);
|
|
3250
3349
|
pkg.name = `@onex-themes/${newName}`;
|
|
@@ -3260,7 +3359,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3260
3359
|
}
|
|
3261
3360
|
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
3262
3361
|
}
|
|
3263
|
-
const configPath =
|
|
3362
|
+
const configPath = path9.join(themeDir, "theme.config.ts");
|
|
3264
3363
|
if (await fs.pathExists(configPath)) {
|
|
3265
3364
|
let content = await fs.readFile(configPath, "utf-8");
|
|
3266
3365
|
content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
|
|
@@ -3270,7 +3369,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3270
3369
|
);
|
|
3271
3370
|
await fs.writeFile(configPath, content);
|
|
3272
3371
|
}
|
|
3273
|
-
const layoutPath =
|
|
3372
|
+
const layoutPath = path9.join(themeDir, "theme.layout.ts");
|
|
3274
3373
|
if (await fs.pathExists(layoutPath)) {
|
|
3275
3374
|
let content = await fs.readFile(layoutPath, "utf-8");
|
|
3276
3375
|
content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
|
|
@@ -3283,7 +3382,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3283
3382
|
const oldDisplayName = oldName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3284
3383
|
const tsFiles = await glob("**/*.ts", { cwd: themeDir, nodir: true });
|
|
3285
3384
|
for (const file of tsFiles) {
|
|
3286
|
-
const filePath =
|
|
3385
|
+
const filePath = path9.join(themeDir, file);
|
|
3287
3386
|
let content = await fs.readFile(filePath, "utf-8");
|
|
3288
3387
|
const original = content;
|
|
3289
3388
|
content = content.replace(
|
|
@@ -3312,7 +3411,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3312
3411
|
const spinner = ora("Initializing clone...").start();
|
|
3313
3412
|
try {
|
|
3314
3413
|
const bucket = options.bucket || getBucketName3(options.environment);
|
|
3315
|
-
const outputDir = options.output ||
|
|
3414
|
+
const outputDir = options.output || path9.resolve(process.cwd(), newName);
|
|
3316
3415
|
const s3Client = getS3Client3();
|
|
3317
3416
|
if (await fs.pathExists(outputDir)) {
|
|
3318
3417
|
spinner.fail(chalk4.red(`Directory already exists: ${outputDir}`));
|
|
@@ -3367,7 +3466,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3367
3466
|
spinner.succeed(
|
|
3368
3467
|
`Renamed theme: ${chalk4.gray(themeName)} \u2192 ${chalk4.cyan(newName)}`
|
|
3369
3468
|
);
|
|
3370
|
-
const envExamplePath =
|
|
3469
|
+
const envExamplePath = path9.join(outputDir, ".env.example");
|
|
3371
3470
|
if (!await fs.pathExists(envExamplePath)) {
|
|
3372
3471
|
await fs.writeFile(
|
|
3373
3472
|
envExamplePath,
|
|
@@ -3380,32 +3479,18 @@ async function cloneCommand(themeName, options) {
|
|
|
3380
3479
|
].join("\n")
|
|
3381
3480
|
);
|
|
3382
3481
|
}
|
|
3383
|
-
const
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
name: "figmaApiKey",
|
|
3390
|
-
message: "Figma API Key (optional, for Figma-to-code MCP \u2014 press Enter to skip):"
|
|
3391
|
-
}
|
|
3392
|
-
]);
|
|
3393
|
-
let mcpContent = await fs.readFile(mcpJsonPath, "utf-8");
|
|
3394
|
-
if (figmaApiKey) {
|
|
3395
|
-
mcpContent = mcpContent.replace("__FIGMA_API_KEY__", figmaApiKey);
|
|
3396
|
-
} else {
|
|
3397
|
-
try {
|
|
3398
|
-
const mcpJson = JSON.parse(mcpContent);
|
|
3399
|
-
delete mcpJson.mcpServers?.figma;
|
|
3400
|
-
mcpContent = JSON.stringify(mcpJson, null, 2) + "\n";
|
|
3401
|
-
} catch {
|
|
3402
|
-
}
|
|
3482
|
+
const { default: inquirerMod } = await import('inquirer');
|
|
3483
|
+
const { figmaApiKey } = await inquirerMod.prompt([
|
|
3484
|
+
{
|
|
3485
|
+
type: "password",
|
|
3486
|
+
name: "figmaApiKey",
|
|
3487
|
+
message: "Figma API Key (optional, for Figma-to-code MCP \u2014 press Enter to skip):"
|
|
3403
3488
|
}
|
|
3404
|
-
|
|
3405
|
-
|
|
3489
|
+
]);
|
|
3490
|
+
ensureMcpJson(outputDir, figmaApiKey || void 0);
|
|
3406
3491
|
if (options.install !== false) {
|
|
3407
3492
|
const hasPkgJson = await fs.pathExists(
|
|
3408
|
-
|
|
3493
|
+
path9.join(outputDir, "package.json")
|
|
3409
3494
|
);
|
|
3410
3495
|
if (hasPkgJson) {
|
|
3411
3496
|
spinner.start("Installing dependencies...");
|
|
@@ -3432,9 +3517,10 @@ async function cloneCommand(themeName, options) {
|
|
|
3432
3517
|
console.log(chalk4.cyan(" Files: ") + chalk4.white(entries.length));
|
|
3433
3518
|
console.log();
|
|
3434
3519
|
console.log(chalk4.cyan("Next steps:"));
|
|
3435
|
-
console.log(chalk4.gray(` cd ${
|
|
3520
|
+
console.log(chalk4.gray(` cd ${path9.relative(process.cwd(), outputDir)}`));
|
|
3521
|
+
const copyCmd = process.platform === "win32" ? "copy .env.example .env" : "cp .env.example .env";
|
|
3436
3522
|
console.log(
|
|
3437
|
-
chalk4.gray(
|
|
3523
|
+
chalk4.gray(` ${copyCmd} # then add your Company ID`)
|
|
3438
3524
|
);
|
|
3439
3525
|
if (options.install === false) {
|
|
3440
3526
|
console.log(chalk4.gray(" pnpm install"));
|