@onexapis/cli 1.1.16 → 1.1.18
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/README.md +117 -51
- package/bin/onexthm.js +4 -0
- package/dist/cli.js +750 -328
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +747 -325
- package/dist/cli.mjs.map +1 -1
- package/dist/index.js +162 -299
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +162 -299
- package/dist/index.mjs.map +1 -1
- package/dist/preview/preview-app.tsx +175 -53
- package/package.json +14 -12
- package/templates/default/.env.example +1 -1
- package/templates/default/.mcp.json +8 -0
- package/templates/default/CLAUDE.md +941 -0
- package/templates/default/bundle-entry.ts +18 -0
- package/templates/default/index.ts +26 -0
- package/templates/default/package.json +37 -0
- package/templates/default/pages/about.ts +66 -0
- package/templates/default/pages/home.ts +93 -0
- package/templates/default/pages/showcase.ts +146 -0
- package/templates/default/sections/about/about-default.tsx +237 -0
- package/templates/default/sections/about/about.schema.ts +259 -0
- package/templates/default/sections/about/index.ts +15 -0
- package/templates/default/sections/cta/cta-default.tsx +180 -0
- package/templates/default/sections/cta/cta.schema.ts +210 -0
- package/templates/default/sections/cta/index.ts +11 -0
- package/templates/default/sections/features/features-default.tsx +154 -0
- package/templates/default/sections/features/features.schema.ts +330 -0
- package/templates/default/sections/features/index.ts +11 -0
- package/templates/default/sections/gallery/gallery-default.tsx +134 -0
- package/templates/default/sections/gallery/gallery.schema.ts +397 -0
- package/templates/default/sections/gallery/index.ts +11 -0
- package/templates/default/sections/hero/hero-default.tsx +212 -0
- package/templates/default/sections/hero/hero.schema.ts +273 -0
- package/templates/default/sections/hero/index.ts +15 -0
- package/templates/default/sections/stats/index.ts +11 -0
- package/templates/default/sections/stats/stats-default.tsx +103 -0
- package/templates/default/sections/stats/stats.schema.ts +266 -0
- package/templates/default/sections/testimonials/index.ts +11 -0
- package/templates/default/sections/testimonials/testimonials-default.tsx +130 -0
- package/templates/default/sections/testimonials/testimonials.schema.ts +371 -0
- package/templates/default/sections-registry.ts +32 -0
- package/templates/default/theme.config.ts +107 -0
- package/templates/default/theme.layout.ts +21 -0
- package/templates/default/tsconfig.json +16 -7
- package/templates/default/README.md.ejs +0 -129
- package/templates/default/esbuild.config.js +0 -81
- package/templates/default/package.json.ejs +0 -31
- package/templates/default/src/config.ts.ejs +0 -98
- package/templates/default/src/index.ts.ejs +0 -11
- package/templates/default/src/layout.ts +0 -23
- package/templates/default/src/manifest.ts.ejs +0 -47
- package/templates/default/src/pages/home.ts.ejs +0 -37
- package/templates/default/src/sections/footer/footer-default.tsx +0 -28
- package/templates/default/src/sections/footer/footer.schema.ts +0 -45
- package/templates/default/src/sections/footer/index.ts +0 -2
- package/templates/default/src/sections/header/header-default.tsx +0 -61
- package/templates/default/src/sections/header/header.schema.ts +0 -46
- package/templates/default/src/sections/header/index.ts +0 -2
- package/templates/default/src/sections/hero/hero-default.tsx +0 -52
- package/templates/default/src/sections/hero/hero.schema.ts +0 -52
- package/templates/default/src/sections/hero/index.ts +0 -2
package/dist/index.mjs
CHANGED
|
@@ -5,6 +5,7 @@ import path7 from 'path';
|
|
|
5
5
|
import fs6 from 'fs/promises';
|
|
6
6
|
import crypto from 'crypto';
|
|
7
7
|
import { glob } from 'glob';
|
|
8
|
+
import { createRequire } from 'module';
|
|
8
9
|
import fs2 from 'fs';
|
|
9
10
|
import { execSync, spawn } from 'child_process';
|
|
10
11
|
import inquirer from 'inquirer';
|
|
@@ -93,7 +94,7 @@ __export(compile_theme_exports, {
|
|
|
93
94
|
compilePreviewRuntime: () => compilePreviewRuntime,
|
|
94
95
|
compileStandaloneTheme: () => compileStandaloneTheme,
|
|
95
96
|
compileStandaloneThemeDev: () => compileStandaloneThemeDev,
|
|
96
|
-
generateManifest: () =>
|
|
97
|
+
generateManifest: () => generateManifest
|
|
97
98
|
});
|
|
98
99
|
async function resolveNodeModulesFile(startDir, relativePath) {
|
|
99
100
|
let dir = startDir;
|
|
@@ -240,6 +241,12 @@ function createThemeDepsStubPlugin(themePath) {
|
|
|
240
241
|
if (!result.errors.length) return result;
|
|
241
242
|
} catch {
|
|
242
243
|
}
|
|
244
|
+
try {
|
|
245
|
+
const req = createRequire(import.meta.url || __filename);
|
|
246
|
+
const resolved = req.resolve(args.path);
|
|
247
|
+
if (resolved) return { path: resolved, namespace: "file" };
|
|
248
|
+
} catch {
|
|
249
|
+
}
|
|
243
250
|
return { path: args.path, namespace };
|
|
244
251
|
});
|
|
245
252
|
};
|
|
@@ -248,11 +255,19 @@ function createThemeDepsStubPlugin(themePath) {
|
|
|
248
255
|
const stubs = {
|
|
249
256
|
"next/image": `
|
|
250
257
|
import React from 'react';
|
|
251
|
-
const Image = (props) => {
|
|
252
|
-
const { src, alt, width, height, fill, priority, ...rest } = props;
|
|
258
|
+
const Image = React.forwardRef((props, ref) => {
|
|
259
|
+
const { src, alt, width, height, fill, priority, sizes, quality, placeholder, blurDataURL, onLoad, onError, style, className, ...rest } = props;
|
|
253
260
|
const imgSrc = typeof src === 'object' ? src.src : src;
|
|
254
|
-
|
|
255
|
-
};
|
|
261
|
+
const fillStyle = fill ? { position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: style?.objectFit || 'cover', display: 'block' } : {};
|
|
262
|
+
const mergedStyle = { ...fillStyle, ...style };
|
|
263
|
+
return React.createElement('img', {
|
|
264
|
+
ref, src: imgSrc, alt,
|
|
265
|
+
width: fill ? undefined : width, height: fill ? undefined : height,
|
|
266
|
+
loading: priority ? 'eager' : 'lazy',
|
|
267
|
+
style: Object.keys(mergedStyle).length > 0 ? mergedStyle : undefined,
|
|
268
|
+
className, onLoad, onError, ...rest,
|
|
269
|
+
});
|
|
270
|
+
});
|
|
256
271
|
export default Image;
|
|
257
272
|
`,
|
|
258
273
|
"next/link": `
|
|
@@ -286,7 +301,10 @@ export function headers() { return new Headers(); }
|
|
|
286
301
|
if (!lucideThemeScanned) {
|
|
287
302
|
lucideThemeScanned = true;
|
|
288
303
|
try {
|
|
289
|
-
const scanned = await scanImportsFromPackage(
|
|
304
|
+
const scanned = await scanImportsFromPackage(
|
|
305
|
+
themePath,
|
|
306
|
+
"lucide-react"
|
|
307
|
+
);
|
|
290
308
|
for (const names of Object.values(scanned)) {
|
|
291
309
|
for (const name of names) lucideImports.add(name);
|
|
292
310
|
}
|
|
@@ -349,10 +367,13 @@ export function useFormContext() { return useForm(); }
|
|
|
349
367
|
loader: "js"
|
|
350
368
|
}));
|
|
351
369
|
tryResolveOrStub(/^@hookform\/resolvers/, "hookform-resolvers-stub");
|
|
352
|
-
build2.onLoad(
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
370
|
+
build2.onLoad(
|
|
371
|
+
{ filter: /.*/, namespace: "hookform-resolvers-stub" },
|
|
372
|
+
() => ({
|
|
373
|
+
contents: `export function zodResolver() { return () => ({ values: {}, errors: {} }); }`,
|
|
374
|
+
loader: "js"
|
|
375
|
+
})
|
|
376
|
+
);
|
|
356
377
|
tryResolveOrStub(/^next-intl$/, "next-intl-stub");
|
|
357
378
|
build2.onLoad({ filter: /.*/, namespace: "next-intl-stub" }, () => ({
|
|
358
379
|
contents: `
|
|
@@ -517,7 +538,7 @@ async function extractDataRequirements(themePath) {
|
|
|
517
538
|
}
|
|
518
539
|
return requirements;
|
|
519
540
|
}
|
|
520
|
-
async function
|
|
541
|
+
async function generateManifest(themeName, themePath, outputDir) {
|
|
521
542
|
let version = "1.0.0";
|
|
522
543
|
let themeId = themeName;
|
|
523
544
|
try {
|
|
@@ -610,7 +631,11 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
610
631
|
banner: {
|
|
611
632
|
js: '"use client";'
|
|
612
633
|
},
|
|
613
|
-
plugins: [
|
|
634
|
+
plugins: [
|
|
635
|
+
reactGlobalPlugin,
|
|
636
|
+
createCoreGlobalPlugin(themePath),
|
|
637
|
+
createThemeDepsStubPlugin(themePath)
|
|
638
|
+
],
|
|
614
639
|
external: [],
|
|
615
640
|
alias: {
|
|
616
641
|
events: "events/",
|
|
@@ -648,7 +673,7 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
648
673
|
} catch {
|
|
649
674
|
}
|
|
650
675
|
await contentHashEntry(outputDir);
|
|
651
|
-
await
|
|
676
|
+
await generateManifest(themeName, themePath, outputDir);
|
|
652
677
|
await generateThemeData(themePath, outputDir, themeName);
|
|
653
678
|
if (result.metafile) {
|
|
654
679
|
const outputs = result.metafile.outputs;
|
|
@@ -692,7 +717,11 @@ async function compileStandaloneThemeDev(themePath, themeName) {
|
|
|
692
717
|
banner: {
|
|
693
718
|
js: '"use client";'
|
|
694
719
|
},
|
|
695
|
-
plugins: [
|
|
720
|
+
plugins: [
|
|
721
|
+
reactGlobalPlugin,
|
|
722
|
+
createCoreGlobalPlugin(themePath),
|
|
723
|
+
createThemeDepsStubPlugin(themePath)
|
|
724
|
+
],
|
|
696
725
|
external: [],
|
|
697
726
|
alias: {
|
|
698
727
|
events: "events/",
|
|
@@ -725,7 +754,7 @@ async function compileStandaloneThemeDev(themePath, themeName) {
|
|
|
725
754
|
};
|
|
726
755
|
const context2 = await esbuild.context(buildOptions);
|
|
727
756
|
await context2.rebuild();
|
|
728
|
-
await
|
|
757
|
+
await generateManifest(themeName, themePath, outputDir);
|
|
729
758
|
await generateThemeData(themePath, outputDir, themeName);
|
|
730
759
|
return { context: context2, outputDir };
|
|
731
760
|
}
|
|
@@ -827,7 +856,16 @@ ${locations.join("\n")}`
|
|
|
827
856
|
path7.join(themePath, "node_modules", "@onexapis", "core", "src"),
|
|
828
857
|
path7.join(themePath, "..", "..", "packages", "core", "src"),
|
|
829
858
|
// monorepo sibling
|
|
830
|
-
path7.join(
|
|
859
|
+
path7.join(
|
|
860
|
+
__dirname,
|
|
861
|
+
"..",
|
|
862
|
+
"..",
|
|
863
|
+
"..",
|
|
864
|
+
"..",
|
|
865
|
+
"packages",
|
|
866
|
+
"core",
|
|
867
|
+
"src"
|
|
868
|
+
)
|
|
831
869
|
// from CLI src
|
|
832
870
|
];
|
|
833
871
|
let coreSourceDir = null;
|
|
@@ -841,7 +879,10 @@ ${locations.join("\n")}`
|
|
|
841
879
|
}
|
|
842
880
|
if (coreSourceDir) {
|
|
843
881
|
try {
|
|
844
|
-
const scanned = await scanImportsFromPackage(
|
|
882
|
+
const scanned = await scanImportsFromPackage(
|
|
883
|
+
coreSourceDir,
|
|
884
|
+
"lucide-react"
|
|
885
|
+
);
|
|
845
886
|
for (const names of Object.values(scanned)) {
|
|
846
887
|
for (const name of names) lucideIconNames.add(name);
|
|
847
888
|
}
|
|
@@ -862,7 +903,10 @@ ${locations.join("\n")}`
|
|
|
862
903
|
const mjsFiles = await glob("*.mjs", { cwd: candidate });
|
|
863
904
|
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']lucide-react["']/g;
|
|
864
905
|
for (const file of mjsFiles) {
|
|
865
|
-
const content = await fs6.readFile(
|
|
906
|
+
const content = await fs6.readFile(
|
|
907
|
+
path7.join(candidate, file),
|
|
908
|
+
"utf-8"
|
|
909
|
+
);
|
|
866
910
|
for (const match of content.matchAll(importRegex)) {
|
|
867
911
|
for (const name of match[1].split(",")) {
|
|
868
912
|
const original = name.trim().split(/\s+as\s+/)[0].trim();
|
|
@@ -878,7 +922,10 @@ ${locations.join("\n")}`
|
|
|
878
922
|
}
|
|
879
923
|
}
|
|
880
924
|
try {
|
|
881
|
-
const scanned = await scanImportsFromPackage(
|
|
925
|
+
const scanned = await scanImportsFromPackage(
|
|
926
|
+
themePath,
|
|
927
|
+
"lucide-react"
|
|
928
|
+
);
|
|
882
929
|
for (const names of Object.values(scanned)) {
|
|
883
930
|
for (const name of names) lucideIconNames.add(name);
|
|
884
931
|
}
|
|
@@ -908,14 +955,39 @@ export default new Proxy({}, { get: (_, name) => name === '__esModule' ? true :
|
|
|
908
955
|
if (!result.errors.length) return result;
|
|
909
956
|
} catch {
|
|
910
957
|
}
|
|
958
|
+
try {
|
|
959
|
+
const req = createRequire(import.meta.url || __filename);
|
|
960
|
+
const cjsPath = req.resolve("framer-motion");
|
|
961
|
+
const pkgDir = cjsPath.replace(/[/\\]dist[/\\].*$/, "");
|
|
962
|
+
const esmEntry = path7.join(pkgDir, "dist", "es", "index.mjs");
|
|
963
|
+
const { existsSync } = await import('fs');
|
|
964
|
+
if (existsSync(esmEntry)) {
|
|
965
|
+
return { path: esmEntry, namespace: "file" };
|
|
966
|
+
}
|
|
967
|
+
return { path: cjsPath, namespace: "file" };
|
|
968
|
+
} catch {
|
|
969
|
+
}
|
|
911
970
|
return { path: args.path, namespace: "motion-stub" };
|
|
912
971
|
});
|
|
913
972
|
build2.onLoad({ filter: /.*/, namespace: "motion-stub" }, () => ({
|
|
914
973
|
contents: `
|
|
915
|
-
|
|
916
|
-
const
|
|
974
|
+
import React from 'react';
|
|
975
|
+
const MotionComponent = React.forwardRef((props, ref) => {
|
|
976
|
+
const { initial, animate, exit, variants, transition, whileInView, whileHover, whileTap, viewport, onAnimationComplete, layout, layoutId, style, className, ...rest } = props;
|
|
977
|
+
return React.createElement(rest.as || 'div', { ref, style, className, ...rest }, rest.children);
|
|
978
|
+
});
|
|
979
|
+
const handler = { get: (_, name) => {
|
|
980
|
+
if (name === '__esModule') return true;
|
|
981
|
+
if (name === 'create') return () => new Proxy({}, handler);
|
|
982
|
+
return MotionComponent;
|
|
983
|
+
}};
|
|
917
984
|
export const motion = new Proxy({}, handler);
|
|
918
|
-
export const AnimatePresence =
|
|
985
|
+
export const AnimatePresence = (props) => props.children || null;
|
|
986
|
+
export const useInView = () => true;
|
|
987
|
+
export const useAnimation = () => ({ start: () => {}, stop: () => {}, set: () => {} });
|
|
988
|
+
export const useMotionValue = (v) => ({ get: () => v, set: () => {}, onChange: () => () => {} });
|
|
989
|
+
export const useTransform = (v) => v;
|
|
990
|
+
export const useScroll = () => ({ scrollY: { get: () => 0, onChange: () => () => {} }, scrollYProgress: { get: () => 0, onChange: () => () => {} } });
|
|
919
991
|
export default { motion, AnimatePresence };
|
|
920
992
|
`.trim(),
|
|
921
993
|
loader: "jsx"
|
|
@@ -938,12 +1010,26 @@ export default { motion, AnimatePresence };
|
|
|
938
1010
|
build2.onLoad({ filter: /.*/, namespace: "next-stub" }, (args) => {
|
|
939
1011
|
const stubs = {
|
|
940
1012
|
"next/image": `
|
|
941
|
-
const Image = (props) => {
|
|
942
|
-
const { src, alt, width, height, fill, priority, ...rest } = props;
|
|
943
|
-
const imgSrc = typeof src === 'object' ? src.src : src;
|
|
944
|
-
return React.createElement('img', { src: imgSrc, alt, width: fill ? undefined : width, height: fill ? undefined : height, loading: priority ? 'eager' : 'lazy', ...rest });
|
|
945
|
-
};
|
|
946
1013
|
import React from 'react';
|
|
1014
|
+
const Image = React.forwardRef((props, ref) => {
|
|
1015
|
+
const { src, alt, width, height, fill, priority, sizes, quality, placeholder, blurDataURL, onLoad, onError, style, className, ...rest } = props;
|
|
1016
|
+
const imgSrc = typeof src === 'object' ? src.src : src;
|
|
1017
|
+
const fillStyle = fill ? { position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: style?.objectFit || 'cover', display: 'block' } : {};
|
|
1018
|
+
const mergedStyle = { ...fillStyle, ...style };
|
|
1019
|
+
return React.createElement('img', {
|
|
1020
|
+
ref,
|
|
1021
|
+
src: imgSrc,
|
|
1022
|
+
alt,
|
|
1023
|
+
width: fill ? undefined : width,
|
|
1024
|
+
height: fill ? undefined : height,
|
|
1025
|
+
loading: priority ? 'eager' : 'lazy',
|
|
1026
|
+
style: Object.keys(mergedStyle).length > 0 ? mergedStyle : undefined,
|
|
1027
|
+
className,
|
|
1028
|
+
onLoad,
|
|
1029
|
+
onError,
|
|
1030
|
+
...rest,
|
|
1031
|
+
});
|
|
1032
|
+
});
|
|
947
1033
|
export default Image;
|
|
948
1034
|
`,
|
|
949
1035
|
"next/link": `
|
|
@@ -1428,45 +1514,20 @@ async function initCommand(projectName, options = {}) {
|
|
|
1428
1514
|
try {
|
|
1429
1515
|
fs2.mkdirSync(projectPath, { recursive: true });
|
|
1430
1516
|
await copyTemplate(template, projectPath, data);
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
const layoutContent = generateThemeLayout(data);
|
|
1438
|
-
await writeFile(path7.join(srcPath, "layout.ts"), layoutContent);
|
|
1439
|
-
const indexContent = generateThemeIndex(data);
|
|
1440
|
-
await writeFile(path7.join(srcPath, "index.ts"), indexContent);
|
|
1441
|
-
const sectionsPath = path7.join(srcPath, "sections");
|
|
1442
|
-
fs2.mkdirSync(sectionsPath, { recursive: true });
|
|
1443
|
-
await writeFile(
|
|
1444
|
-
path7.join(sectionsPath, "README.md"),
|
|
1445
|
-
`# ${displayName} Sections
|
|
1446
|
-
|
|
1447
|
-
Add your theme-specific sections here.
|
|
1448
|
-
`
|
|
1449
|
-
);
|
|
1450
|
-
const blocksPath = path7.join(srcPath, "blocks");
|
|
1451
|
-
fs2.mkdirSync(blocksPath, { recursive: true });
|
|
1452
|
-
await writeFile(
|
|
1453
|
-
path7.join(blocksPath, "README.md"),
|
|
1454
|
-
`# ${displayName} Blocks
|
|
1455
|
-
|
|
1456
|
-
Add your theme-specific blocks here.
|
|
1457
|
-
`
|
|
1517
|
+
await renameThemeInFiles(
|
|
1518
|
+
projectPath,
|
|
1519
|
+
name,
|
|
1520
|
+
displayName,
|
|
1521
|
+
description,
|
|
1522
|
+
author
|
|
1458
1523
|
);
|
|
1459
|
-
const pagesPath = path7.join(srcPath, "pages");
|
|
1460
|
-
fs2.mkdirSync(pagesPath, { recursive: true });
|
|
1461
|
-
const homePageContent = generateHomePage(data);
|
|
1462
|
-
await writeFile(path7.join(pagesPath, "home.ts"), homePageContent);
|
|
1463
1524
|
logger.stopSpinner(true, "Project structure created!");
|
|
1464
1525
|
if (options.git) {
|
|
1465
1526
|
logger.startSpinner("Initializing git repository...");
|
|
1466
1527
|
try {
|
|
1467
1528
|
execSync("git init", { cwd: projectPath, stdio: "ignore" });
|
|
1468
1529
|
execSync("git add .", { cwd: projectPath, stdio: "ignore" });
|
|
1469
|
-
execSync('git commit -m "Initial commit from
|
|
1530
|
+
execSync('git commit -m "Initial commit from onexthm init"', {
|
|
1470
1531
|
cwd: projectPath,
|
|
1471
1532
|
stdio: "ignore"
|
|
1472
1533
|
});
|
|
@@ -1503,14 +1564,14 @@ Add your theme-specific blocks here.
|
|
|
1503
1564
|
logger.log(` npm run dev # Start development mode`);
|
|
1504
1565
|
logger.newLine();
|
|
1505
1566
|
logger.section("Theme structure:");
|
|
1506
|
-
logger.log("
|
|
1567
|
+
logger.log(" bundle-entry.ts - Theme manifest and exports");
|
|
1507
1568
|
logger.log(
|
|
1508
|
-
"
|
|
1569
|
+
" theme.config.ts - Design tokens (colors, typography, etc.)"
|
|
1509
1570
|
);
|
|
1510
|
-
logger.log("
|
|
1511
|
-
logger.log("
|
|
1512
|
-
logger.log("
|
|
1513
|
-
logger.log("
|
|
1571
|
+
logger.log(" theme.layout.ts - Header and footer configuration");
|
|
1572
|
+
logger.log(" sections/ - Custom sections for your theme");
|
|
1573
|
+
logger.log(" pages/ - Page configurations");
|
|
1574
|
+
logger.log(" CLAUDE.md - AI assistant context");
|
|
1514
1575
|
logger.newLine();
|
|
1515
1576
|
logger.success(`Happy theming! \u{1F3A8}`);
|
|
1516
1577
|
} catch (error) {
|
|
@@ -1524,231 +1585,33 @@ Add your theme-specific blocks here.
|
|
|
1524
1585
|
process.exit(1);
|
|
1525
1586
|
}
|
|
1526
1587
|
}
|
|
1527
|
-
function
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
// Example: productCard: () => import("./blocks/product-card").then((m) => m.productCardDefinition),
|
|
1555
|
-
},
|
|
1556
|
-
|
|
1557
|
-
// Default pages
|
|
1558
|
-
pages: {
|
|
1559
|
-
home: () => import("./pages/home").then((m) => m.homePageConfig),
|
|
1560
|
-
},
|
|
1561
|
-
|
|
1562
|
-
// Supported page types
|
|
1563
|
-
supportedPageTypes: ["home", "about", "contact", "custom"],
|
|
1564
|
-
|
|
1565
|
-
// Preview image (optional)
|
|
1566
|
-
preview: undefined,
|
|
1567
|
-
|
|
1568
|
-
// Tags for categorization (optional)
|
|
1569
|
-
tags: ["custom"],
|
|
1570
|
-
};
|
|
1571
|
-
|
|
1572
|
-
export default manifest;
|
|
1573
|
-
`;
|
|
1574
|
-
}
|
|
1575
|
-
function generateThemeConfig(data) {
|
|
1576
|
-
return `import type { ThemeConfig } from "@onexapis/core";
|
|
1577
|
-
|
|
1578
|
-
/**
|
|
1579
|
-
* ${data.displayName} Theme Configuration
|
|
1580
|
-
* Design tokens: colors, typography, spacing, etc.
|
|
1581
|
-
*/
|
|
1582
|
-
export const themeConfig: ThemeConfig = {
|
|
1583
|
-
// Color palette
|
|
1584
|
-
colors: {
|
|
1585
|
-
primary: {
|
|
1586
|
-
50: "#eff6ff",
|
|
1587
|
-
100: "#dbeafe",
|
|
1588
|
-
200: "#bfdbfe",
|
|
1589
|
-
300: "#93c5fd",
|
|
1590
|
-
400: "#60a5fa",
|
|
1591
|
-
500: "#3b82f6",
|
|
1592
|
-
600: "#2563eb",
|
|
1593
|
-
700: "#1d4ed8",
|
|
1594
|
-
800: "#1e40af",
|
|
1595
|
-
900: "#1e3a8a",
|
|
1596
|
-
},
|
|
1597
|
-
secondary: {
|
|
1598
|
-
50: "#f8fafc",
|
|
1599
|
-
100: "#f1f5f9",
|
|
1600
|
-
200: "#e2e8f0",
|
|
1601
|
-
300: "#cbd5e1",
|
|
1602
|
-
400: "#94a3b8",
|
|
1603
|
-
500: "#64748b",
|
|
1604
|
-
600: "#475569",
|
|
1605
|
-
700: "#334155",
|
|
1606
|
-
800: "#1e293b",
|
|
1607
|
-
900: "#0f172a",
|
|
1608
|
-
},
|
|
1609
|
-
accent: {
|
|
1610
|
-
50: "#fdf4ff",
|
|
1611
|
-
100: "#fae8ff",
|
|
1612
|
-
200: "#f5d0fe",
|
|
1613
|
-
300: "#f0abfc",
|
|
1614
|
-
400: "#e879f9",
|
|
1615
|
-
500: "#d946ef",
|
|
1616
|
-
600: "#c026d3",
|
|
1617
|
-
700: "#a21caf",
|
|
1618
|
-
800: "#86198f",
|
|
1619
|
-
900: "#701a75",
|
|
1620
|
-
},
|
|
1621
|
-
},
|
|
1622
|
-
|
|
1623
|
-
// Typography
|
|
1624
|
-
typography: {
|
|
1625
|
-
fontFamily: {
|
|
1626
|
-
sans: ["Inter", "system-ui", "sans-serif"],
|
|
1627
|
-
serif: ["Georgia", "serif"],
|
|
1628
|
-
mono: ["Monaco", "monospace"],
|
|
1629
|
-
},
|
|
1630
|
-
fontSize: {
|
|
1631
|
-
xs: "0.75rem",
|
|
1632
|
-
sm: "0.875rem",
|
|
1633
|
-
base: "1rem",
|
|
1634
|
-
lg: "1.125rem",
|
|
1635
|
-
xl: "1.25rem",
|
|
1636
|
-
"2xl": "1.5rem",
|
|
1637
|
-
"3xl": "1.875rem",
|
|
1638
|
-
"4xl": "2.25rem",
|
|
1639
|
-
"5xl": "3rem",
|
|
1640
|
-
},
|
|
1641
|
-
},
|
|
1642
|
-
|
|
1643
|
-
// Spacing
|
|
1644
|
-
spacing: {
|
|
1645
|
-
xs: "0.5rem",
|
|
1646
|
-
sm: "1rem",
|
|
1647
|
-
md: "1.5rem",
|
|
1648
|
-
lg: "2rem",
|
|
1649
|
-
xl: "3rem",
|
|
1650
|
-
"2xl": "4rem",
|
|
1651
|
-
"3xl": "6rem",
|
|
1652
|
-
"4xl": "8rem",
|
|
1653
|
-
},
|
|
1654
|
-
|
|
1655
|
-
// Border radius
|
|
1656
|
-
borderRadius: {
|
|
1657
|
-
none: "0",
|
|
1658
|
-
sm: "0.125rem",
|
|
1659
|
-
md: "0.375rem",
|
|
1660
|
-
lg: "0.5rem",
|
|
1661
|
-
xl: "0.75rem",
|
|
1662
|
-
full: "9999px",
|
|
1663
|
-
},
|
|
1664
|
-
|
|
1665
|
-
// Breakpoints
|
|
1666
|
-
breakpoints: {
|
|
1667
|
-
sm: "640px",
|
|
1668
|
-
md: "768px",
|
|
1669
|
-
lg: "1024px",
|
|
1670
|
-
xl: "1280px",
|
|
1671
|
-
"2xl": "1536px",
|
|
1672
|
-
},
|
|
1673
|
-
};
|
|
1674
|
-
`;
|
|
1675
|
-
}
|
|
1676
|
-
function generateThemeLayout(data) {
|
|
1677
|
-
return `import type { ThemeLayoutConfig } from "@onexapis/core";
|
|
1678
|
-
|
|
1679
|
-
/**
|
|
1680
|
-
* ${data.themeName} Theme Layout
|
|
1681
|
-
* Define header and footer sections
|
|
1682
|
-
*/
|
|
1683
|
-
export const themeLayout: ThemeLayoutConfig = {
|
|
1684
|
-
// Header section configuration
|
|
1685
|
-
header: undefined,
|
|
1686
|
-
// Example:
|
|
1687
|
-
// header: {
|
|
1688
|
-
// type: "header",
|
|
1689
|
-
// template: "default",
|
|
1690
|
-
// enabled: true,
|
|
1691
|
-
// settings: {},
|
|
1692
|
-
// },
|
|
1693
|
-
|
|
1694
|
-
// Footer section configuration
|
|
1695
|
-
footer: undefined,
|
|
1696
|
-
// Example:
|
|
1697
|
-
// footer: {
|
|
1698
|
-
// type: "footer",
|
|
1699
|
-
// template: "default",
|
|
1700
|
-
// enabled: true,
|
|
1701
|
-
// settings: {},
|
|
1702
|
-
// },
|
|
1703
|
-
};
|
|
1704
|
-
`;
|
|
1705
|
-
}
|
|
1706
|
-
function generateThemeIndex(data) {
|
|
1707
|
-
return `/**
|
|
1708
|
-
* ${data.themeNamePascal} Theme
|
|
1709
|
-
*/
|
|
1710
|
-
|
|
1711
|
-
export { manifest as ${data.themeNamePascal}Manifest } from "./manifest";
|
|
1712
|
-
export { themeConfig as ${data.themeNamePascal}Config } from "./config";
|
|
1713
|
-
export { themeLayout as ${data.themeNamePascal}Layout } from "./layout";
|
|
1714
|
-
`;
|
|
1715
|
-
}
|
|
1716
|
-
function generateHomePage(data) {
|
|
1717
|
-
return `import type { PageConfig } from "@onexapis/core";
|
|
1718
|
-
|
|
1719
|
-
/**
|
|
1720
|
-
* Home Page Configuration
|
|
1721
|
-
*/
|
|
1722
|
-
export const homePageConfig: PageConfig = {
|
|
1723
|
-
type: "home",
|
|
1724
|
-
title: "${data.displayName}",
|
|
1725
|
-
description: "Welcome to ${data.displayName}",
|
|
1726
|
-
|
|
1727
|
-
// SEO metadata
|
|
1728
|
-
seo: {
|
|
1729
|
-
title: "${data.displayName} - Home",
|
|
1730
|
-
description: "Welcome to ${data.displayName}",
|
|
1731
|
-
keywords: [],
|
|
1732
|
-
ogImage: undefined,
|
|
1733
|
-
},
|
|
1734
|
-
|
|
1735
|
-
// Page sections
|
|
1736
|
-
sections: [
|
|
1737
|
-
// Add your sections here
|
|
1738
|
-
// Example:
|
|
1739
|
-
// {
|
|
1740
|
-
// id: "hero-1",
|
|
1741
|
-
// type: "hero",
|
|
1742
|
-
// template: "default",
|
|
1743
|
-
// order: 0,
|
|
1744
|
-
// enabled: true,
|
|
1745
|
-
// settings: {},
|
|
1746
|
-
// components: [],
|
|
1747
|
-
// blocks: [],
|
|
1748
|
-
// },
|
|
1749
|
-
],
|
|
1750
|
-
};
|
|
1751
|
-
`;
|
|
1588
|
+
async function renameThemeInFiles(projectPath, themeName, displayName, description, author) {
|
|
1589
|
+
const configPath = path7.join(projectPath, "theme.config.ts");
|
|
1590
|
+
if (fs2.existsSync(configPath)) {
|
|
1591
|
+
let content = fs2.readFileSync(configPath, "utf-8");
|
|
1592
|
+
content = content.replace(
|
|
1593
|
+
/name: "My Simple Theme"/,
|
|
1594
|
+
`name: "${displayName}"`
|
|
1595
|
+
);
|
|
1596
|
+
content = content.replace(
|
|
1597
|
+
/description: ".*?"/,
|
|
1598
|
+
`description: "${description}"`
|
|
1599
|
+
);
|
|
1600
|
+
fs2.writeFileSync(configPath, content, "utf-8");
|
|
1601
|
+
}
|
|
1602
|
+
const pkgPath = path7.join(projectPath, "package.json");
|
|
1603
|
+
if (fs2.existsSync(pkgPath)) {
|
|
1604
|
+
let content = fs2.readFileSync(pkgPath, "utf-8");
|
|
1605
|
+
content = content.replace(
|
|
1606
|
+
/@onex-themes\/my-simple/g,
|
|
1607
|
+
`@onex-themes/${themeName}`
|
|
1608
|
+
);
|
|
1609
|
+
content = content.replace(
|
|
1610
|
+
/"description": ".*?"/,
|
|
1611
|
+
`"description": "${description}"`
|
|
1612
|
+
);
|
|
1613
|
+
fs2.writeFileSync(pkgPath, content, "utf-8");
|
|
1614
|
+
}
|
|
1752
1615
|
}
|
|
1753
1616
|
|
|
1754
1617
|
// src/commands/create-section.ts
|
|
@@ -2634,7 +2497,7 @@ async function buildCommand(options) {
|
|
|
2634
2497
|
logger.stopSpinner(true, "Lint passed");
|
|
2635
2498
|
const pkgJson = fs.readJsonSync(packageJsonPath);
|
|
2636
2499
|
const buildScript = pkgJson.scripts?.build || "";
|
|
2637
|
-
const isRecursive = buildScript.includes("
|
|
2500
|
+
const isRecursive = buildScript.includes("onexthm build") || buildScript.includes("onex-cli build");
|
|
2638
2501
|
logger.startSpinner(
|
|
2639
2502
|
options.watch ? "Building (watch mode)..." : "Building..."
|
|
2640
2503
|
);
|
|
@@ -2725,7 +2588,7 @@ function getBucketName(env) {
|
|
|
2725
2588
|
return process.env.BUCKET_NAME;
|
|
2726
2589
|
}
|
|
2727
2590
|
const environment = env || process.env.ENVIRONMENT || "staging";
|
|
2728
|
-
return environment === "production" ? "
|
|
2591
|
+
return environment === "production" ? "theme-s3-bucket" : "theme-s3-bucket";
|
|
2729
2592
|
}
|
|
2730
2593
|
async function findCompiledThemeDir(themeId, version) {
|
|
2731
2594
|
const searchPaths = [path7.resolve(process.cwd(), "dist")];
|
|
@@ -2832,7 +2695,7 @@ async function uploadCommand(options) {
|
|
|
2832
2695
|
if (!compiledDir) {
|
|
2833
2696
|
spinner.fail(
|
|
2834
2697
|
chalk4.red(
|
|
2835
|
-
`Compiled theme not found for ${themeId}@${version}. Run '
|
|
2698
|
+
`Compiled theme not found for ${themeId}@${version}. Run 'onexthm build' first.`
|
|
2836
2699
|
)
|
|
2837
2700
|
);
|
|
2838
2701
|
logger.info(chalk4.gray(`Expected location:
|
|
@@ -2994,7 +2857,7 @@ function getBucketName2(env) {
|
|
|
2994
2857
|
return process.env.BUCKET_NAME;
|
|
2995
2858
|
}
|
|
2996
2859
|
const environment = env || process.env.ENVIRONMENT || "staging";
|
|
2997
|
-
return environment === "production" ? "
|
|
2860
|
+
return environment === "production" ? "theme-s3-bucket" : "theme-s3-bucket";
|
|
2998
2861
|
}
|
|
2999
2862
|
async function streamToString(stream) {
|
|
3000
2863
|
const chunks = [];
|
|
@@ -3064,7 +2927,7 @@ function showDownloadFailureHelp(themeId, bucket) {
|
|
|
3064
2927
|
console.log(chalk4.white("1. Compile and upload the theme:"));
|
|
3065
2928
|
console.log(chalk4.gray(` cd themes/${themeId}`));
|
|
3066
2929
|
console.log(chalk4.gray(" pnpm build"));
|
|
3067
|
-
console.log(chalk4.gray("
|
|
2930
|
+
console.log(chalk4.gray(" onexthm upload"));
|
|
3068
2931
|
console.log();
|
|
3069
2932
|
console.log(chalk4.white("2. Verify AWS credentials are set:"));
|
|
3070
2933
|
console.log(
|
|
@@ -3195,7 +3058,7 @@ function getBucketName3(env) {
|
|
|
3195
3058
|
return process.env.BUCKET_NAME;
|
|
3196
3059
|
}
|
|
3197
3060
|
const environment = env || process.env.ENVIRONMENT || "staging";
|
|
3198
|
-
return environment === "production" ? "
|
|
3061
|
+
return environment === "production" ? "theme-s3-bucket" : "theme-s3-bucket";
|
|
3199
3062
|
}
|
|
3200
3063
|
async function streamToString2(stream) {
|
|
3201
3064
|
const chunks = [];
|
|
@@ -3366,7 +3229,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3366
3229
|
chalk4.yellow("The theme source may not have been uploaded yet.")
|
|
3367
3230
|
);
|
|
3368
3231
|
console.log(
|
|
3369
|
-
chalk4.gray(`Upload source with:
|
|
3232
|
+
chalk4.gray(`Upload source with: onexthm upload --theme ${themeName}`)
|
|
3370
3233
|
);
|
|
3371
3234
|
console.log();
|
|
3372
3235
|
process.exit(1);
|
|
@@ -3393,7 +3256,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3393
3256
|
[
|
|
3394
3257
|
"# API Configuration (enables real data in preview)",
|
|
3395
3258
|
"# Get your Company ID from the OneX dashboard",
|
|
3396
|
-
"NEXT_PUBLIC_API_URL=https://
|
|
3259
|
+
"NEXT_PUBLIC_API_URL=https://platform-dev.onexeos.com",
|
|
3397
3260
|
"NEXT_PUBLIC_COMPANY_ID=",
|
|
3398
3261
|
""
|
|
3399
3262
|
].join("\n")
|
|
@@ -3435,7 +3298,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3435
3298
|
if (options.install === false) {
|
|
3436
3299
|
console.log(chalk4.gray(" pnpm install"));
|
|
3437
3300
|
}
|
|
3438
|
-
console.log(chalk4.gray("
|
|
3301
|
+
console.log(chalk4.gray(" onexthm build"));
|
|
3439
3302
|
console.log();
|
|
3440
3303
|
} catch (error) {
|
|
3441
3304
|
spinner.fail(chalk4.red(`Clone failed: ${error.message}`));
|