@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/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 path8 from 'path';
|
|
5
|
+
import fs7 from 'fs/promises';
|
|
6
6
|
import crypto from 'crypto';
|
|
7
7
|
import { glob } from 'glob';
|
|
8
8
|
import { createRequire } from 'module';
|
|
9
|
-
import
|
|
9
|
+
import fs3 from 'fs';
|
|
10
10
|
import { execSync, spawn } from 'child_process';
|
|
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
|
+
path8.join(themePath, "sections/**/*.{ts,tsx}"),
|
|
106
|
+
path8.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 fs7.writeFile(path8.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 = path8.join(dir, "node_modules", relativePath);
|
|
128
128
|
try {
|
|
129
|
-
await
|
|
129
|
+
await fs7.access(candidate);
|
|
130
130
|
return candidate;
|
|
131
131
|
} catch {
|
|
132
|
-
const parent =
|
|
132
|
+
const parent = path8.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 fs7.readFile(path8.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
|
+
path8.join("@onexapis", "core", "dist", distFileName)
|
|
211
211
|
);
|
|
212
212
|
if (!distPath) {
|
|
213
213
|
distPath = await resolveNodeModulesFile(
|
|
214
214
|
__dirname,
|
|
215
|
-
|
|
215
|
+
path8.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 fs7.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(path8.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(path8.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 = path8.join(themePath, "sections");
|
|
465
465
|
try {
|
|
466
|
-
const sectionDirs = await
|
|
466
|
+
const sectionDirs = await fs7.readdir(sectionsDir);
|
|
467
467
|
for (const dir of sectionDirs) {
|
|
468
|
-
const schemaFile =
|
|
468
|
+
const schemaFile = path8.join(sectionsDir, dir, `${dir}.schema.ts`);
|
|
469
469
|
try {
|
|
470
|
-
await
|
|
470
|
+
await fs7.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 = path8.join(themePath, "pages");
|
|
483
483
|
try {
|
|
484
|
-
const files = await
|
|
484
|
+
const files = await fs7.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(path8.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 fs7.writeFile(
|
|
518
|
+
path8.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 = path8.join(outputDir, "bundle-entry.js");
|
|
542
|
+
const mapPath = path8.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 fs7.unlink(path8.join(outputDir, f));
|
|
546
546
|
}
|
|
547
547
|
let entryContent;
|
|
548
548
|
try {
|
|
549
|
-
entryContent = await
|
|
549
|
+
entryContent = await fs7.readFile(entryPath, "utf-8");
|
|
550
550
|
} catch {
|
|
551
|
-
const indexPath =
|
|
551
|
+
const indexPath = path8.join(outputDir, "index.js");
|
|
552
552
|
try {
|
|
553
|
-
entryContent = await
|
|
553
|
+
entryContent = await fs7.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 = path8.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 fs7.writeFile(path8.join(outputDir, hashedName2), entryContent);
|
|
567
|
+
await fs7.unlink(indexPath);
|
|
568
568
|
try {
|
|
569
|
-
await
|
|
570
|
-
await
|
|
569
|
+
await fs7.access(indexMapPath);
|
|
570
|
+
await fs7.rename(indexMapPath, path8.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 fs7.writeFile(path8.join(outputDir, hashedName), entryContent);
|
|
584
|
+
await fs7.unlink(entryPath);
|
|
585
585
|
try {
|
|
586
|
-
await
|
|
587
|
-
await
|
|
586
|
+
await fs7.access(mapPath);
|
|
587
|
+
await fs7.rename(mapPath, path8.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(path8.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 fs7.readFile(
|
|
619
|
+
path8.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 fs7.access(path8.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 fs7.writeFile(
|
|
679
|
+
path8.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 = path8.join(themePath, "dist");
|
|
685
|
+
const bundleEntry = path8.join(themePath, "bundle-entry.ts");
|
|
686
|
+
const indexEntry = path8.join(themePath, "index.ts");
|
|
687
687
|
let entryPoint = indexEntry;
|
|
688
688
|
try {
|
|
689
|
-
await
|
|
689
|
+
await fs7.access(bundleEntry);
|
|
690
690
|
entryPoint = bundleEntry;
|
|
691
691
|
} catch {
|
|
692
692
|
}
|
|
693
|
-
const shimPath =
|
|
694
|
-
await
|
|
695
|
-
await
|
|
693
|
+
const shimPath = path8.join(outputDir, ".process-shim.js");
|
|
694
|
+
await fs7.mkdir(outputDir, { recursive: true });
|
|
695
|
+
await fs7.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 fs7.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 fs7.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 = path8.join(themePath, "dist");
|
|
773
|
+
const bundleEntry = path8.join(themePath, "bundle-entry.ts");
|
|
774
|
+
const indexEntry = path8.join(themePath, "index.ts");
|
|
775
775
|
let entryPoint = indexEntry;
|
|
776
776
|
try {
|
|
777
|
-
await
|
|
777
|
+
await fs7.access(bundleEntry);
|
|
778
778
|
entryPoint = bundleEntry;
|
|
779
779
|
} catch {
|
|
780
780
|
}
|
|
781
|
-
const shimPath =
|
|
782
|
-
await
|
|
783
|
-
await
|
|
781
|
+
const shimPath = path8.join(outputDir, ".process-shim.js");
|
|
782
|
+
await fs7.mkdir(outputDir, { recursive: true });
|
|
783
|
+
await fs7.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 = path8.join(themePath, "dist");
|
|
837
|
+
await fs7.mkdir(outputDir, { recursive: true });
|
|
838
|
+
const outputPath = path8.join(outputDir, "preview-runtime.js");
|
|
839
839
|
const locations = [
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
840
|
+
path8.join(__dirname, "..", "preview", "preview-app.tsx"),
|
|
841
|
+
path8.join(__dirname, "preview", "preview-app.tsx"),
|
|
842
|
+
path8.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 fs7.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
|
+
path8.join(themePath, "node_modules", "@onexapis", "core", "src"),
|
|
931
|
+
path8.join(themePath, "..", "..", "packages", "core", "src"),
|
|
932
932
|
// monorepo sibling
|
|
933
|
-
|
|
933
|
+
path8.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 fs7.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
|
+
path8.join(themePath, "node_modules", "@onexapis", "core", "dist")
|
|
968
968
|
];
|
|
969
969
|
const resolvedDist = await resolveNodeModulesFile(
|
|
970
970
|
__dirname,
|
|
971
|
-
|
|
971
|
+
path8.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 fs7.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 fs7.readFile(
|
|
981
|
+
path8.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 = path8.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 = path8.join(outputDir, ".process-shim-preview.js");
|
|
1136
|
+
await fs7.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 fs7.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 fs12 = __require("fs-extra");
|
|
1319
|
+
return fs12.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(path8.dirname(filePath));
|
|
1361
1361
|
await fs.writeFile(filePath, content, "utf-8");
|
|
1362
1362
|
}
|
|
1363
1363
|
function getTemplatesDir() {
|
|
1364
1364
|
const locations = [
|
|
1365
|
-
|
|
1365
|
+
path8.join(__dirname, "../../templates"),
|
|
1366
1366
|
// Development
|
|
1367
|
-
|
|
1367
|
+
path8.join(__dirname, "../templates"),
|
|
1368
1368
|
// Production (dist/)
|
|
1369
|
-
|
|
1369
|
+
path8.join(process.cwd(), "templates"),
|
|
1370
1370
|
// Fallback
|
|
1371
|
-
|
|
1371
|
+
path8.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 = path8.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 = path8.join(templateDir, file);
|
|
1393
|
+
const targetPath = path8.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 = path8.join(templateDir, file);
|
|
1411
|
+
const targetPath = path8.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 !== path8.parse(currentDir).root) {
|
|
1427
|
+
const packageJsonPath = path8.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(path8.join(currentDir, "src/themes")) || fs.existsSync(path8.join(currentDir, "themes"))) {
|
|
1431
1431
|
return currentDir;
|
|
1432
1432
|
}
|
|
1433
1433
|
}
|
|
1434
|
-
currentDir =
|
|
1434
|
+
currentDir = path8.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(path8.join(root, "themes")))
|
|
1441
|
+
return path8.join(root, "themes");
|
|
1442
|
+
if (fs.existsSync(path8.join(root, "src/themes")))
|
|
1443
|
+
return path8.join(root, "src/themes");
|
|
1444
|
+
return path8.dirname(root);
|
|
1445
1445
|
}
|
|
1446
1446
|
function getFeaturesDir() {
|
|
1447
|
-
return
|
|
1447
|
+
return path8.join(getProjectRoot(), "src/features");
|
|
1448
1448
|
}
|
|
1449
1449
|
function isOneXProject() {
|
|
1450
1450
|
const root = getProjectRoot();
|
|
1451
|
-
return fs.existsSync(
|
|
1451
|
+
return fs.existsSync(path8.join(root, "themes")) || fs.existsSync(path8.join(root, "src/themes")) || fs.existsSync(path8.join(root, "theme.config.ts")) || fs.existsSync(path8.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 = path8.join(themesDir, name);
|
|
1468
|
+
return fs.statSync(themePath).isDirectory() && (fs.existsSync(path8.join(themePath, "theme.config.ts")) || fs.existsSync(path8.join(themePath, "bundle-entry.ts")) || fs.existsSync(path8.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 = path8.join(getThemesDir(), themeName);
|
|
1473
|
+
return fs.existsSync(themePath) && (fs.existsSync(path8.join(themePath, "theme.config.ts")) || fs.existsSync(path8.join(themePath, "bundle-entry.ts")) || fs.existsSync(path8.join(themePath, "manifest.ts")));
|
|
1474
1474
|
}
|
|
1475
1475
|
function detectPackageManager() {
|
|
1476
1476
|
const userAgent = process.env.npm_config_user_agent || "";
|
|
@@ -1478,9 +1478,9 @@ 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(path8.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
1482
|
+
if (fs.existsSync(path8.join(cwd, "yarn.lock"))) return "yarn";
|
|
1483
|
+
if (fs.existsSync(path8.join(cwd, "bun.lockb"))) return "bun";
|
|
1484
1484
|
return "npm";
|
|
1485
1485
|
}
|
|
1486
1486
|
async function installDependencies(projectPath, packageManager = "npm") {
|
|
@@ -1497,6 +1497,11 @@ async function installDependencies(projectPath, packageManager = "npm") {
|
|
|
1497
1497
|
}
|
|
1498
1498
|
});
|
|
1499
1499
|
}
|
|
1500
|
+
var AUTH_DIR = path8.join(os.homedir(), ".onexthm");
|
|
1501
|
+
path8.join(AUTH_DIR, "auth.json");
|
|
1502
|
+
function getApiUrl() {
|
|
1503
|
+
return process.env.ONEXTHM_API_URL || process.env.NEXT_PUBLIC_API_URL || "https://platform-dev.onexeos.com";
|
|
1504
|
+
}
|
|
1500
1505
|
|
|
1501
1506
|
// src/commands/init.ts
|
|
1502
1507
|
async function initCommand(projectName, options = {}) {
|
|
@@ -1514,7 +1519,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1514
1519
|
if (!validateThemeName(kebabName)) {
|
|
1515
1520
|
return "Invalid project name. Use lowercase letters, numbers, and hyphens only.";
|
|
1516
1521
|
}
|
|
1517
|
-
if (
|
|
1522
|
+
if (fs3.existsSync(path8.join(process.cwd(), kebabName))) {
|
|
1518
1523
|
return `Directory "${kebabName}" already exists`;
|
|
1519
1524
|
}
|
|
1520
1525
|
return true;
|
|
@@ -1525,11 +1530,46 @@ async function initCommand(projectName, options = {}) {
|
|
|
1525
1530
|
} else {
|
|
1526
1531
|
name = toKebabCase(projectName);
|
|
1527
1532
|
}
|
|
1528
|
-
const projectPath =
|
|
1529
|
-
if (
|
|
1533
|
+
const projectPath = path8.join(process.cwd(), name);
|
|
1534
|
+
if (fs3.existsSync(projectPath)) {
|
|
1530
1535
|
logger.error(`Directory "${name}" already exists.`);
|
|
1531
1536
|
process.exit(1);
|
|
1532
1537
|
}
|
|
1538
|
+
if (!options.yes) {
|
|
1539
|
+
try {
|
|
1540
|
+
const apiUrl = getApiUrl();
|
|
1541
|
+
const controller = new AbortController();
|
|
1542
|
+
const timeout = setTimeout(() => controller.abort(), 3e3);
|
|
1543
|
+
const response = await fetch(
|
|
1544
|
+
`${apiUrl}/website-api/themes/${encodeURIComponent(name)}/exists`,
|
|
1545
|
+
{ signal: controller.signal }
|
|
1546
|
+
);
|
|
1547
|
+
clearTimeout(timeout);
|
|
1548
|
+
if (response.ok) {
|
|
1549
|
+
const data2 = await response.json();
|
|
1550
|
+
const body = data2.statusCode ? data2.body : data2;
|
|
1551
|
+
if (body.exists && body.owner === "other") {
|
|
1552
|
+
logger.warning(
|
|
1553
|
+
`Theme ID "${name}" is already registered by another developer.
|
|
1554
|
+
You can still create this locally, but publishing will fail.
|
|
1555
|
+
Consider using a different name.`
|
|
1556
|
+
);
|
|
1557
|
+
const { proceed } = await inquirer.prompt([
|
|
1558
|
+
{
|
|
1559
|
+
type: "confirm",
|
|
1560
|
+
name: "proceed",
|
|
1561
|
+
message: "Continue anyway?",
|
|
1562
|
+
default: false
|
|
1563
|
+
}
|
|
1564
|
+
]);
|
|
1565
|
+
if (!proceed) {
|
|
1566
|
+
process.exit(0);
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
}
|
|
1570
|
+
} catch {
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1533
1573
|
let displayName;
|
|
1534
1574
|
let description;
|
|
1535
1575
|
let author;
|
|
@@ -1597,7 +1637,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1597
1637
|
}
|
|
1598
1638
|
logger.startSpinner("Creating project structure...");
|
|
1599
1639
|
try {
|
|
1600
|
-
|
|
1640
|
+
fs3.mkdirSync(projectPath, { recursive: true });
|
|
1601
1641
|
await copyTemplate(template, projectPath, data);
|
|
1602
1642
|
await renameThemeInFiles(
|
|
1603
1643
|
projectPath,
|
|
@@ -1606,9 +1646,9 @@ async function initCommand(projectName, options = {}) {
|
|
|
1606
1646
|
description,
|
|
1607
1647
|
author
|
|
1608
1648
|
);
|
|
1609
|
-
const mcpJsonPath =
|
|
1610
|
-
if (
|
|
1611
|
-
let mcpContent =
|
|
1649
|
+
const mcpJsonPath = path8.join(projectPath, ".mcp.json");
|
|
1650
|
+
if (fs3.existsSync(mcpJsonPath)) {
|
|
1651
|
+
let mcpContent = fs3.readFileSync(mcpJsonPath, "utf-8");
|
|
1612
1652
|
if (figmaApiKey) {
|
|
1613
1653
|
mcpContent = mcpContent.replace("__FIGMA_API_KEY__", figmaApiKey);
|
|
1614
1654
|
} else {
|
|
@@ -1619,7 +1659,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1619
1659
|
} catch {
|
|
1620
1660
|
}
|
|
1621
1661
|
}
|
|
1622
|
-
|
|
1662
|
+
fs3.writeFileSync(mcpJsonPath, mcpContent, "utf-8");
|
|
1623
1663
|
}
|
|
1624
1664
|
logger.stopSpinner(true, "Project structure created!");
|
|
1625
1665
|
if (options.git) {
|
|
@@ -1679,16 +1719,16 @@ async function initCommand(projectName, options = {}) {
|
|
|
1679
1719
|
logger.error(
|
|
1680
1720
|
error instanceof Error ? error.message : "Unknown error occurred"
|
|
1681
1721
|
);
|
|
1682
|
-
if (
|
|
1683
|
-
|
|
1722
|
+
if (fs3.existsSync(projectPath)) {
|
|
1723
|
+
fs3.rmSync(projectPath, { recursive: true, force: true });
|
|
1684
1724
|
}
|
|
1685
1725
|
process.exit(1);
|
|
1686
1726
|
}
|
|
1687
1727
|
}
|
|
1688
1728
|
async function renameThemeInFiles(projectPath, themeName, displayName, description, author) {
|
|
1689
|
-
const configPath =
|
|
1690
|
-
if (
|
|
1691
|
-
let content =
|
|
1729
|
+
const configPath = path8.join(projectPath, "theme.config.ts");
|
|
1730
|
+
if (fs3.existsSync(configPath)) {
|
|
1731
|
+
let content = fs3.readFileSync(configPath, "utf-8");
|
|
1692
1732
|
content = content.replace(
|
|
1693
1733
|
/name: "My Simple Theme"/,
|
|
1694
1734
|
`name: "${displayName}"`
|
|
@@ -1697,11 +1737,11 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
|
|
|
1697
1737
|
/description: ".*?"/,
|
|
1698
1738
|
`description: "${description}"`
|
|
1699
1739
|
);
|
|
1700
|
-
|
|
1740
|
+
fs3.writeFileSync(configPath, content, "utf-8");
|
|
1701
1741
|
}
|
|
1702
|
-
const pkgPath =
|
|
1703
|
-
if (
|
|
1704
|
-
let content =
|
|
1742
|
+
const pkgPath = path8.join(projectPath, "package.json");
|
|
1743
|
+
if (fs3.existsSync(pkgPath)) {
|
|
1744
|
+
let content = fs3.readFileSync(pkgPath, "utf-8");
|
|
1705
1745
|
content = content.replace(
|
|
1706
1746
|
/@onex-themes\/my-simple/g,
|
|
1707
1747
|
`@onex-themes/${themeName}`
|
|
@@ -1710,7 +1750,7 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
|
|
|
1710
1750
|
/"description": ".*?"/,
|
|
1711
1751
|
`"description": "${description}"`
|
|
1712
1752
|
);
|
|
1713
|
-
|
|
1753
|
+
fs3.writeFileSync(pkgPath, content, "utf-8");
|
|
1714
1754
|
}
|
|
1715
1755
|
}
|
|
1716
1756
|
|
|
@@ -1721,10 +1761,10 @@ async function createSectionCommand(name, options) {
|
|
|
1721
1761
|
ensureOneXProject();
|
|
1722
1762
|
if (!options.theme) {
|
|
1723
1763
|
const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
|
|
1724
|
-
(f) => fs.existsSync(
|
|
1764
|
+
(f) => fs.existsSync(path8.join(process.cwd(), f))
|
|
1725
1765
|
);
|
|
1726
1766
|
if (isStandaloneTheme) {
|
|
1727
|
-
options.theme =
|
|
1767
|
+
options.theme = path8.basename(process.cwd());
|
|
1728
1768
|
}
|
|
1729
1769
|
}
|
|
1730
1770
|
const sectionName = toKebabCase(name);
|
|
@@ -1787,35 +1827,35 @@ async function createSectionCommand(name, options) {
|
|
|
1787
1827
|
};
|
|
1788
1828
|
logger.startSpinner("Creating section files...");
|
|
1789
1829
|
try {
|
|
1790
|
-
const themePath =
|
|
1791
|
-
const sectionPath =
|
|
1830
|
+
const themePath = path8.join(getThemesDir(), themeName);
|
|
1831
|
+
const sectionPath = path8.join(themePath, "sections", sectionName);
|
|
1792
1832
|
const schemaContent = generateSectionSchema(data);
|
|
1793
1833
|
await writeFile(
|
|
1794
|
-
|
|
1834
|
+
path8.join(sectionPath, `${sectionName}.schema.ts`),
|
|
1795
1835
|
schemaContent
|
|
1796
1836
|
);
|
|
1797
1837
|
if (createTemplate) {
|
|
1798
1838
|
const templateContent = generateSectionTemplate(data);
|
|
1799
1839
|
await writeFile(
|
|
1800
|
-
|
|
1840
|
+
path8.join(sectionPath, `${sectionName}-default.tsx`),
|
|
1801
1841
|
templateContent
|
|
1802
1842
|
);
|
|
1803
1843
|
}
|
|
1804
1844
|
const indexContent = generateSectionIndex(data, createTemplate);
|
|
1805
|
-
await writeFile(
|
|
1845
|
+
await writeFile(path8.join(sectionPath, "index.ts"), indexContent);
|
|
1806
1846
|
logger.stopSpinner(true, "Section files created successfully!");
|
|
1807
1847
|
logger.newLine();
|
|
1808
1848
|
logger.section("Next steps:");
|
|
1809
1849
|
logger.log(
|
|
1810
|
-
` 1. Edit schema: ${
|
|
1850
|
+
` 1. Edit schema: ${path8.relative(process.cwd(), path8.join(sectionPath, `${sectionName}.schema.ts`))}`
|
|
1811
1851
|
);
|
|
1812
1852
|
if (createTemplate) {
|
|
1813
1853
|
logger.log(
|
|
1814
|
-
` 2. Edit template: ${
|
|
1854
|
+
` 2. Edit template: ${path8.relative(process.cwd(), path8.join(sectionPath, `${sectionName}-default.tsx`))}`
|
|
1815
1855
|
);
|
|
1816
1856
|
}
|
|
1817
1857
|
logger.log(
|
|
1818
|
-
` 3. Add to theme manifest: ${
|
|
1858
|
+
` 3. Add to theme manifest: ${path8.relative(process.cwd(), path8.join(themePath, "manifest.ts"))}`
|
|
1819
1859
|
);
|
|
1820
1860
|
logger.newLine();
|
|
1821
1861
|
logger.success("Section created successfully!");
|
|
@@ -1963,10 +2003,10 @@ async function createBlockCommand(name, options) {
|
|
|
1963
2003
|
ensureOneXProject();
|
|
1964
2004
|
if (!options.theme) {
|
|
1965
2005
|
const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
|
|
1966
|
-
(f) => fs.existsSync(
|
|
2006
|
+
(f) => fs.existsSync(path8.join(process.cwd(), f))
|
|
1967
2007
|
);
|
|
1968
2008
|
if (isStandaloneTheme) {
|
|
1969
|
-
options.theme =
|
|
2009
|
+
options.theme = path8.basename(process.cwd());
|
|
1970
2010
|
}
|
|
1971
2011
|
}
|
|
1972
2012
|
const blockName = toKebabCase(name);
|
|
@@ -2041,24 +2081,24 @@ async function createBlockCommand(name, options) {
|
|
|
2041
2081
|
};
|
|
2042
2082
|
logger.startSpinner("Creating block files...");
|
|
2043
2083
|
try {
|
|
2044
|
-
const blockPath = scope === "shared" ?
|
|
2084
|
+
const blockPath = scope === "shared" ? path8.join(getFeaturesDir(), "blocks", blockName) : path8.join(getThemesDir(), themeName, "blocks", blockName);
|
|
2045
2085
|
const schemaContent = generateBlockSchema(data);
|
|
2046
2086
|
await writeFile(
|
|
2047
|
-
|
|
2087
|
+
path8.join(blockPath, `${blockName}.schema.ts`),
|
|
2048
2088
|
schemaContent
|
|
2049
2089
|
);
|
|
2050
2090
|
const componentContent = generateBlockComponent(data);
|
|
2051
|
-
await writeFile(
|
|
2091
|
+
await writeFile(path8.join(blockPath, `${blockName}.tsx`), componentContent);
|
|
2052
2092
|
const indexContent = generateBlockIndex(data);
|
|
2053
|
-
await writeFile(
|
|
2093
|
+
await writeFile(path8.join(blockPath, "index.ts"), indexContent);
|
|
2054
2094
|
logger.stopSpinner(true, "Block files created successfully!");
|
|
2055
2095
|
logger.newLine();
|
|
2056
2096
|
logger.section("Next steps:");
|
|
2057
2097
|
logger.log(
|
|
2058
|
-
` 1. Edit schema: ${
|
|
2098
|
+
` 1. Edit schema: ${path8.relative(process.cwd(), path8.join(blockPath, `${blockName}.schema.ts`))}`
|
|
2059
2099
|
);
|
|
2060
2100
|
logger.log(
|
|
2061
|
-
` 2. Edit component: ${
|
|
2101
|
+
` 2. Edit component: ${path8.relative(process.cwd(), path8.join(blockPath, `${blockName}.tsx`))}`
|
|
2062
2102
|
);
|
|
2063
2103
|
logger.log(
|
|
2064
2104
|
` 3. Register in block registry: src/lib/registry/block-registry.ts`
|
|
@@ -2236,31 +2276,31 @@ async function createComponentCommand(name, options) {
|
|
|
2236
2276
|
};
|
|
2237
2277
|
logger.startSpinner("Creating component files...");
|
|
2238
2278
|
try {
|
|
2239
|
-
const componentPath =
|
|
2279
|
+
const componentPath = path8.join(
|
|
2240
2280
|
getFeaturesDir(),
|
|
2241
2281
|
"components",
|
|
2242
2282
|
componentName
|
|
2243
2283
|
);
|
|
2244
2284
|
const schemaContent = generateComponentSchema(data);
|
|
2245
2285
|
await writeFile(
|
|
2246
|
-
|
|
2286
|
+
path8.join(componentPath, `${componentName}.schema.ts`),
|
|
2247
2287
|
schemaContent
|
|
2248
2288
|
);
|
|
2249
2289
|
const componentContent = generateComponent(data);
|
|
2250
2290
|
await writeFile(
|
|
2251
|
-
|
|
2291
|
+
path8.join(componentPath, `${componentName}.tsx`),
|
|
2252
2292
|
componentContent
|
|
2253
2293
|
);
|
|
2254
2294
|
const indexContent = generateComponentIndex(data);
|
|
2255
|
-
await writeFile(
|
|
2295
|
+
await writeFile(path8.join(componentPath, "index.ts"), indexContent);
|
|
2256
2296
|
logger.stopSpinner(true, "Component files created successfully!");
|
|
2257
2297
|
logger.newLine();
|
|
2258
2298
|
logger.section("Next steps:");
|
|
2259
2299
|
logger.log(
|
|
2260
|
-
` 1. Edit schema: ${
|
|
2300
|
+
` 1. Edit schema: ${path8.relative(process.cwd(), path8.join(componentPath, `${componentName}.schema.ts`))}`
|
|
2261
2301
|
);
|
|
2262
2302
|
logger.log(
|
|
2263
|
-
` 2. Edit component: ${
|
|
2303
|
+
` 2. Edit component: ${path8.relative(process.cwd(), path8.join(componentPath, `${componentName}.tsx`))}`
|
|
2264
2304
|
);
|
|
2265
2305
|
logger.log(
|
|
2266
2306
|
` 3. Register in component registry: src/lib/registry/component-registry.ts`
|
|
@@ -2417,13 +2457,13 @@ async function listSections(themeFilter) {
|
|
|
2417
2457
|
return;
|
|
2418
2458
|
}
|
|
2419
2459
|
for (const theme of themes) {
|
|
2420
|
-
const sectionsDir =
|
|
2460
|
+
const sectionsDir = path8.join(getThemesDir(), theme, "sections");
|
|
2421
2461
|
if (!fs.existsSync(sectionsDir)) {
|
|
2422
2462
|
continue;
|
|
2423
2463
|
}
|
|
2424
2464
|
const sections = fs.readdirSync(sectionsDir).filter((name) => {
|
|
2425
|
-
const sectionPath =
|
|
2426
|
-
return fs.statSync(sectionPath).isDirectory() && fs.existsSync(
|
|
2465
|
+
const sectionPath = path8.join(sectionsDir, name);
|
|
2466
|
+
return fs.statSync(sectionPath).isDirectory() && fs.existsSync(path8.join(sectionPath, "index.ts"));
|
|
2427
2467
|
});
|
|
2428
2468
|
if (sections.length > 0) {
|
|
2429
2469
|
logger.log(chalk4.cyan(`
|
|
@@ -2437,11 +2477,11 @@ async function listSections(themeFilter) {
|
|
|
2437
2477
|
}
|
|
2438
2478
|
async function listBlocks(themeFilter) {
|
|
2439
2479
|
logger.section("\u{1F9F1} Blocks");
|
|
2440
|
-
const sharedBlocksDir =
|
|
2480
|
+
const sharedBlocksDir = path8.join(getFeaturesDir(), "blocks");
|
|
2441
2481
|
if (fs.existsSync(sharedBlocksDir)) {
|
|
2442
2482
|
const sharedBlocks = fs.readdirSync(sharedBlocksDir).filter((name) => {
|
|
2443
|
-
const blockPath =
|
|
2444
|
-
return fs.statSync(blockPath).isDirectory() && fs.existsSync(
|
|
2483
|
+
const blockPath = path8.join(sharedBlocksDir, name);
|
|
2484
|
+
return fs.statSync(blockPath).isDirectory() && fs.existsSync(path8.join(blockPath, "index.ts"));
|
|
2445
2485
|
});
|
|
2446
2486
|
if (sharedBlocks.length > 0) {
|
|
2447
2487
|
logger.log(chalk4.cyan("\n Shared:"));
|
|
@@ -2452,13 +2492,13 @@ async function listBlocks(themeFilter) {
|
|
|
2452
2492
|
}
|
|
2453
2493
|
const themes = themeFilter ? [themeFilter] : listThemes();
|
|
2454
2494
|
for (const theme of themes) {
|
|
2455
|
-
const blocksDir =
|
|
2495
|
+
const blocksDir = path8.join(getThemesDir(), theme, "blocks");
|
|
2456
2496
|
if (!fs.existsSync(blocksDir)) {
|
|
2457
2497
|
continue;
|
|
2458
2498
|
}
|
|
2459
2499
|
const blocks = fs.readdirSync(blocksDir).filter((name) => {
|
|
2460
|
-
const blockPath =
|
|
2461
|
-
return fs.statSync(blockPath).isDirectory() && fs.existsSync(
|
|
2500
|
+
const blockPath = path8.join(blocksDir, name);
|
|
2501
|
+
return fs.statSync(blockPath).isDirectory() && fs.existsSync(path8.join(blockPath, "index.ts"));
|
|
2462
2502
|
});
|
|
2463
2503
|
if (blocks.length > 0) {
|
|
2464
2504
|
logger.log(chalk4.cyan(`
|
|
@@ -2472,14 +2512,14 @@ async function listBlocks(themeFilter) {
|
|
|
2472
2512
|
}
|
|
2473
2513
|
async function listComponents() {
|
|
2474
2514
|
logger.section("\u2699\uFE0F Components");
|
|
2475
|
-
const componentsDir =
|
|
2515
|
+
const componentsDir = path8.join(getFeaturesDir(), "components");
|
|
2476
2516
|
if (!fs.existsSync(componentsDir)) {
|
|
2477
2517
|
logger.warning("No components directory found");
|
|
2478
2518
|
return;
|
|
2479
2519
|
}
|
|
2480
2520
|
const components = fs.readdirSync(componentsDir).filter((name) => {
|
|
2481
|
-
const componentPath =
|
|
2482
|
-
return fs.statSync(componentPath).isDirectory() && fs.existsSync(
|
|
2521
|
+
const componentPath = path8.join(componentsDir, name);
|
|
2522
|
+
return fs.statSync(componentPath).isDirectory() && fs.existsSync(path8.join(componentPath, "index.ts"));
|
|
2483
2523
|
});
|
|
2484
2524
|
if (components.length === 0) {
|
|
2485
2525
|
logger.warning("No components found");
|
|
@@ -2500,11 +2540,11 @@ async function listThemesInfo() {
|
|
|
2500
2540
|
}
|
|
2501
2541
|
logger.log("");
|
|
2502
2542
|
for (const theme of themes) {
|
|
2503
|
-
const themeDir =
|
|
2543
|
+
const themeDir = path8.join(getThemesDir(), theme);
|
|
2504
2544
|
const candidates = ["theme.config.ts", "bundle-entry.ts", "manifest.ts"];
|
|
2505
2545
|
let manifestContent = "";
|
|
2506
2546
|
for (const candidate of candidates) {
|
|
2507
|
-
const candidatePath =
|
|
2547
|
+
const candidatePath = path8.join(themeDir, candidate);
|
|
2508
2548
|
if (fs.existsSync(candidatePath)) {
|
|
2509
2549
|
manifestContent = fs.readFileSync(candidatePath, "utf-8");
|
|
2510
2550
|
break;
|
|
@@ -2533,14 +2573,14 @@ async function buildCommand(options) {
|
|
|
2533
2573
|
if (options.theme) {
|
|
2534
2574
|
themeName = options.theme;
|
|
2535
2575
|
try {
|
|
2536
|
-
const workspaceThemePath =
|
|
2576
|
+
const workspaceThemePath = path8.join(getThemesDir(), themeName);
|
|
2537
2577
|
if (fs.existsSync(workspaceThemePath)) {
|
|
2538
2578
|
themePath = workspaceThemePath;
|
|
2539
2579
|
} else {
|
|
2540
|
-
themePath =
|
|
2580
|
+
themePath = path8.join(process.cwd(), themeName);
|
|
2541
2581
|
}
|
|
2542
2582
|
} catch {
|
|
2543
|
-
themePath =
|
|
2583
|
+
themePath = path8.join(process.cwd(), themeName);
|
|
2544
2584
|
}
|
|
2545
2585
|
if (!fs.existsSync(themePath)) {
|
|
2546
2586
|
logger.error(`Theme "${themeName}" not found.`);
|
|
@@ -2551,10 +2591,10 @@ async function buildCommand(options) {
|
|
|
2551
2591
|
"theme.config.ts",
|
|
2552
2592
|
"bundle-entry.ts",
|
|
2553
2593
|
"manifest.ts"
|
|
2554
|
-
].some((f) => fs.existsSync(
|
|
2594
|
+
].some((f) => fs.existsSync(path8.join(process.cwd(), f)));
|
|
2555
2595
|
if (isThemeDir) {
|
|
2556
2596
|
themePath = process.cwd();
|
|
2557
|
-
themeName =
|
|
2597
|
+
themeName = path8.basename(themePath);
|
|
2558
2598
|
logger.info(`Building current theme: ${themeName}`);
|
|
2559
2599
|
} else {
|
|
2560
2600
|
logger.error(
|
|
@@ -2563,7 +2603,7 @@ async function buildCommand(options) {
|
|
|
2563
2603
|
process.exit(1);
|
|
2564
2604
|
}
|
|
2565
2605
|
}
|
|
2566
|
-
const packageJsonPath =
|
|
2606
|
+
const packageJsonPath = path8.join(themePath, "package.json");
|
|
2567
2607
|
const hasPkgJson = fs.existsSync(packageJsonPath);
|
|
2568
2608
|
if (!hasPkgJson) {
|
|
2569
2609
|
logger.warning(
|
|
@@ -2619,9 +2659,9 @@ async function buildCommand(options) {
|
|
|
2619
2659
|
logger.success("\u2713 Theme built successfully!");
|
|
2620
2660
|
logger.newLine();
|
|
2621
2661
|
logger.info(`Theme: ${themeName}`);
|
|
2622
|
-
const distPath =
|
|
2662
|
+
const distPath = path8.join(themePath, "dist");
|
|
2623
2663
|
if (fs.existsSync(distPath)) {
|
|
2624
|
-
logger.log(`Output: ${
|
|
2664
|
+
logger.log(`Output: ${path8.relative(process.cwd(), distPath)}`);
|
|
2625
2665
|
const files = fs.readdirSync(distPath);
|
|
2626
2666
|
logger.log(`Files: ${files.length}`);
|
|
2627
2667
|
}
|
|
@@ -2709,11 +2749,11 @@ function getBucketName(env) {
|
|
|
2709
2749
|
return environment === "production" ? "theme-s3-bucket" : "theme-s3-bucket";
|
|
2710
2750
|
}
|
|
2711
2751
|
async function findCompiledThemeDir(themeId, version) {
|
|
2712
|
-
const searchPaths = [
|
|
2752
|
+
const searchPaths = [path8.resolve(process.cwd(), "dist")];
|
|
2713
2753
|
for (const dir of searchPaths) {
|
|
2714
2754
|
if (await fs.pathExists(dir)) {
|
|
2715
|
-
const hasManifest = await fs.pathExists(
|
|
2716
|
-
const hasThemeEntry = await fs.pathExists(
|
|
2755
|
+
const hasManifest = await fs.pathExists(path8.join(dir, "manifest.json"));
|
|
2756
|
+
const hasThemeEntry = await fs.pathExists(path8.join(dir, "bundle-entry.js")) || await fs.pathExists(path8.join(dir, "theme.config.js")) || await fs.pathExists(path8.join(dir, "index.js"));
|
|
2717
2757
|
if (hasManifest || hasThemeEntry) {
|
|
2718
2758
|
return dir;
|
|
2719
2759
|
}
|
|
@@ -2722,7 +2762,7 @@ async function findCompiledThemeDir(themeId, version) {
|
|
|
2722
2762
|
return null;
|
|
2723
2763
|
}
|
|
2724
2764
|
async function readManifest() {
|
|
2725
|
-
const manifestTsPath =
|
|
2765
|
+
const manifestTsPath = path8.resolve(process.cwd(), "manifest.ts");
|
|
2726
2766
|
if (await fs.pathExists(manifestTsPath)) {
|
|
2727
2767
|
try {
|
|
2728
2768
|
const module = await import(manifestTsPath);
|
|
@@ -2731,7 +2771,7 @@ async function readManifest() {
|
|
|
2731
2771
|
logger.warning("Failed to import manifest.ts, trying package.json");
|
|
2732
2772
|
}
|
|
2733
2773
|
}
|
|
2734
|
-
const packageJsonPath =
|
|
2774
|
+
const packageJsonPath = path8.resolve(process.cwd(), "package.json");
|
|
2735
2775
|
if (await fs.pathExists(packageJsonPath)) {
|
|
2736
2776
|
const pkg = await fs.readJson(packageJsonPath);
|
|
2737
2777
|
return {
|
|
@@ -2765,13 +2805,13 @@ async function findSourceDir(themeId, explicitDir) {
|
|
|
2765
2805
|
}
|
|
2766
2806
|
const searchPaths = [
|
|
2767
2807
|
process.cwd(),
|
|
2768
|
-
|
|
2769
|
-
|
|
2808
|
+
path8.resolve(process.cwd(), `../../themes/${themeId}`),
|
|
2809
|
+
path8.resolve(process.cwd(), `../themes/${themeId}`)
|
|
2770
2810
|
];
|
|
2771
2811
|
const markers = ["theme.config.ts", "bundle-entry.ts"];
|
|
2772
2812
|
for (const dir of searchPaths) {
|
|
2773
2813
|
for (const marker of markers) {
|
|
2774
|
-
if (await fs.pathExists(
|
|
2814
|
+
if (await fs.pathExists(path8.join(dir, marker))) {
|
|
2775
2815
|
return dir;
|
|
2776
2816
|
}
|
|
2777
2817
|
}
|
|
@@ -2823,7 +2863,7 @@ async function uploadCommand(options) {
|
|
|
2823
2863
|
spinner.succeed(`Found compiled theme at: ${compiledDir}`);
|
|
2824
2864
|
spinner.start("Creating bundle.zip...");
|
|
2825
2865
|
const tmpDir = os.tmpdir();
|
|
2826
|
-
const bundleZipPath =
|
|
2866
|
+
const bundleZipPath = path8.join(tmpDir, `${themeId}-${version}-bundle.zip`);
|
|
2827
2867
|
await createZipFromDir(compiledDir, bundleZipPath);
|
|
2828
2868
|
const bundleZipBuffer = await fs.readFile(bundleZipPath);
|
|
2829
2869
|
const bundleSizeMB = (bundleZipBuffer.length / 1024 / 1024).toFixed(2);
|
|
@@ -2877,7 +2917,7 @@ async function uploadCommand(options) {
|
|
|
2877
2917
|
if (sourceDir) {
|
|
2878
2918
|
spinner.succeed(`Found source at: ${sourceDir}`);
|
|
2879
2919
|
spinner.start("Creating source.zip...");
|
|
2880
|
-
const sourceZipPath =
|
|
2920
|
+
const sourceZipPath = path8.join(
|
|
2881
2921
|
tmpDir,
|
|
2882
2922
|
`${themeId}-${version}-source.zip`
|
|
2883
2923
|
);
|
|
@@ -3011,8 +3051,8 @@ async function resolveLatestVersion(s3Client, bucket, themeId) {
|
|
|
3011
3051
|
async function createCompatibilityFiles(outputDir, manifest) {
|
|
3012
3052
|
const entryFile = manifest.output?.entry || "bundle-entry.js";
|
|
3013
3053
|
if (entryFile !== "bundle-entry.js" && entryFile.startsWith("bundle-entry-")) {
|
|
3014
|
-
const hashedPath =
|
|
3015
|
-
const stablePath =
|
|
3054
|
+
const hashedPath = path8.join(outputDir, entryFile);
|
|
3055
|
+
const stablePath = path8.join(outputDir, "bundle-entry.js");
|
|
3016
3056
|
if (await fs.pathExists(hashedPath)) {
|
|
3017
3057
|
await fs.copy(hashedPath, stablePath);
|
|
3018
3058
|
const mapPath = hashedPath + ".map";
|
|
@@ -3021,13 +3061,13 @@ async function createCompatibilityFiles(outputDir, manifest) {
|
|
|
3021
3061
|
}
|
|
3022
3062
|
}
|
|
3023
3063
|
}
|
|
3024
|
-
const sectionsRegistryPath =
|
|
3064
|
+
const sectionsRegistryPath = path8.join(outputDir, "sections-registry.js");
|
|
3025
3065
|
const content = `// Re-export all sections from bundle-entry
|
|
3026
3066
|
// This file exists to maintain compatibility with the import path
|
|
3027
3067
|
export * from './bundle-entry.js';
|
|
3028
3068
|
`;
|
|
3029
3069
|
await fs.writeFile(sectionsRegistryPath, content, "utf-8");
|
|
3030
|
-
const pkgJsonPath =
|
|
3070
|
+
const pkgJsonPath = path8.join(outputDir, "package.json");
|
|
3031
3071
|
await fs.writeFile(pkgJsonPath, '{\n "type": "module"\n}\n', "utf-8");
|
|
3032
3072
|
}
|
|
3033
3073
|
function showDownloadFailureHelp(themeId, bucket) {
|
|
@@ -3089,6 +3129,18 @@ async function downloadCommand(options) {
|
|
|
3089
3129
|
spinner.succeed(
|
|
3090
3130
|
`Resolved latest version: ${chalk4.cyan(resolvedVersion)}`
|
|
3091
3131
|
);
|
|
3132
|
+
const isCI = !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.VERCEL);
|
|
3133
|
+
if (isCI) {
|
|
3134
|
+
console.log(
|
|
3135
|
+
chalk4.yellow(
|
|
3136
|
+
`
|
|
3137
|
+
Warning: Resolved "latest" to ${resolvedVersion} in CI environment.
|
|
3138
|
+
For production builds, pin to a specific version:
|
|
3139
|
+
THEME_VERSION=${resolvedVersion}
|
|
3140
|
+
`
|
|
3141
|
+
)
|
|
3142
|
+
);
|
|
3143
|
+
}
|
|
3092
3144
|
}
|
|
3093
3145
|
spinner.start(
|
|
3094
3146
|
`Downloading bundle.zip for ${themeId}@${resolvedVersion}...`
|
|
@@ -3110,7 +3162,7 @@ async function downloadCommand(options) {
|
|
|
3110
3162
|
zip.extractAllTo(outputDir, true);
|
|
3111
3163
|
const entries = zip.getEntries().filter((e) => !e.isDirectory);
|
|
3112
3164
|
spinner.succeed(`Extracted ${entries.length} files to ${outputDir}`);
|
|
3113
|
-
const manifestPath =
|
|
3165
|
+
const manifestPath = path8.join(outputDir, "manifest.json");
|
|
3114
3166
|
const manifest = await fs.readJson(manifestPath);
|
|
3115
3167
|
await createCompatibilityFiles(outputDir, manifest);
|
|
3116
3168
|
console.log();
|
|
@@ -3244,7 +3296,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3244
3296
|
const oldPrefix = `${oldName}-`;
|
|
3245
3297
|
const newPrefix = `${newName}-`;
|
|
3246
3298
|
const newDisplayName = newName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3247
|
-
const pkgPath =
|
|
3299
|
+
const pkgPath = path8.join(themeDir, "package.json");
|
|
3248
3300
|
if (await fs.pathExists(pkgPath)) {
|
|
3249
3301
|
const pkg = await fs.readJson(pkgPath);
|
|
3250
3302
|
pkg.name = `@onex-themes/${newName}`;
|
|
@@ -3260,7 +3312,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3260
3312
|
}
|
|
3261
3313
|
await fs.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
3262
3314
|
}
|
|
3263
|
-
const configPath =
|
|
3315
|
+
const configPath = path8.join(themeDir, "theme.config.ts");
|
|
3264
3316
|
if (await fs.pathExists(configPath)) {
|
|
3265
3317
|
let content = await fs.readFile(configPath, "utf-8");
|
|
3266
3318
|
content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
|
|
@@ -3270,7 +3322,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3270
3322
|
);
|
|
3271
3323
|
await fs.writeFile(configPath, content);
|
|
3272
3324
|
}
|
|
3273
|
-
const layoutPath =
|
|
3325
|
+
const layoutPath = path8.join(themeDir, "theme.layout.ts");
|
|
3274
3326
|
if (await fs.pathExists(layoutPath)) {
|
|
3275
3327
|
let content = await fs.readFile(layoutPath, "utf-8");
|
|
3276
3328
|
content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
|
|
@@ -3283,7 +3335,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3283
3335
|
const oldDisplayName = oldName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3284
3336
|
const tsFiles = await glob("**/*.ts", { cwd: themeDir, nodir: true });
|
|
3285
3337
|
for (const file of tsFiles) {
|
|
3286
|
-
const filePath =
|
|
3338
|
+
const filePath = path8.join(themeDir, file);
|
|
3287
3339
|
let content = await fs.readFile(filePath, "utf-8");
|
|
3288
3340
|
const original = content;
|
|
3289
3341
|
content = content.replace(
|
|
@@ -3312,7 +3364,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3312
3364
|
const spinner = ora("Initializing clone...").start();
|
|
3313
3365
|
try {
|
|
3314
3366
|
const bucket = options.bucket || getBucketName3(options.environment);
|
|
3315
|
-
const outputDir = options.output ||
|
|
3367
|
+
const outputDir = options.output || path8.resolve(process.cwd(), newName);
|
|
3316
3368
|
const s3Client = getS3Client3();
|
|
3317
3369
|
if (await fs.pathExists(outputDir)) {
|
|
3318
3370
|
spinner.fail(chalk4.red(`Directory already exists: ${outputDir}`));
|
|
@@ -3367,7 +3419,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3367
3419
|
spinner.succeed(
|
|
3368
3420
|
`Renamed theme: ${chalk4.gray(themeName)} \u2192 ${chalk4.cyan(newName)}`
|
|
3369
3421
|
);
|
|
3370
|
-
const envExamplePath =
|
|
3422
|
+
const envExamplePath = path8.join(outputDir, ".env.example");
|
|
3371
3423
|
if (!await fs.pathExists(envExamplePath)) {
|
|
3372
3424
|
await fs.writeFile(
|
|
3373
3425
|
envExamplePath,
|
|
@@ -3380,7 +3432,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3380
3432
|
].join("\n")
|
|
3381
3433
|
);
|
|
3382
3434
|
}
|
|
3383
|
-
const mcpJsonPath =
|
|
3435
|
+
const mcpJsonPath = path8.join(outputDir, ".mcp.json");
|
|
3384
3436
|
if (await fs.pathExists(mcpJsonPath)) {
|
|
3385
3437
|
const { default: inquirerMod } = await import('inquirer');
|
|
3386
3438
|
const { figmaApiKey } = await inquirerMod.prompt([
|
|
@@ -3405,7 +3457,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3405
3457
|
}
|
|
3406
3458
|
if (options.install !== false) {
|
|
3407
3459
|
const hasPkgJson = await fs.pathExists(
|
|
3408
|
-
|
|
3460
|
+
path8.join(outputDir, "package.json")
|
|
3409
3461
|
);
|
|
3410
3462
|
if (hasPkgJson) {
|
|
3411
3463
|
spinner.start("Installing dependencies...");
|
|
@@ -3432,7 +3484,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3432
3484
|
console.log(chalk4.cyan(" Files: ") + chalk4.white(entries.length));
|
|
3433
3485
|
console.log();
|
|
3434
3486
|
console.log(chalk4.cyan("Next steps:"));
|
|
3435
|
-
console.log(chalk4.gray(` cd ${
|
|
3487
|
+
console.log(chalk4.gray(` cd ${path8.relative(process.cwd(), outputDir)}`));
|
|
3436
3488
|
console.log(
|
|
3437
3489
|
chalk4.gray(" cp .env.example .env # then add your Company ID")
|
|
3438
3490
|
);
|