@onexapis/cli 1.1.66 → 1.1.70
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 +901 -695
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +898 -692
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +571 -411
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +568 -408
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/templates/default/package.json +5 -0
package/dist/index.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
var chalk4 = require('chalk');
|
|
4
4
|
var ora = require('ora');
|
|
5
|
-
var
|
|
5
|
+
var fs3 = require('fs');
|
|
6
|
+
var path12 = require('path');
|
|
6
7
|
var glob = require('glob');
|
|
7
8
|
var fs = require('fs-extra');
|
|
8
9
|
var crypto = require('crypto');
|
|
10
|
+
var fs10 = require('fs/promises');
|
|
9
11
|
var esbuild = require('esbuild');
|
|
10
|
-
var fs8 = require('fs/promises');
|
|
11
12
|
var module$1 = require('module');
|
|
12
|
-
var fs3 = require('fs');
|
|
13
13
|
var child_process = require('child_process');
|
|
14
14
|
var inquirer = require('inquirer');
|
|
15
15
|
var ejs = require('ejs');
|
|
@@ -39,12 +39,12 @@ function _interopNamespace(e) {
|
|
|
39
39
|
|
|
40
40
|
var chalk4__default = /*#__PURE__*/_interopDefault(chalk4);
|
|
41
41
|
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
42
|
-
var
|
|
42
|
+
var fs3__default = /*#__PURE__*/_interopDefault(fs3);
|
|
43
|
+
var path12__default = /*#__PURE__*/_interopDefault(path12);
|
|
43
44
|
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
44
45
|
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
46
|
+
var fs10__default = /*#__PURE__*/_interopDefault(fs10);
|
|
45
47
|
var esbuild__namespace = /*#__PURE__*/_interopNamespace(esbuild);
|
|
46
|
-
var fs8__default = /*#__PURE__*/_interopDefault(fs8);
|
|
47
|
-
var fs3__default = /*#__PURE__*/_interopDefault(fs3);
|
|
48
48
|
var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
|
|
49
49
|
var ejs__default = /*#__PURE__*/_interopDefault(ejs);
|
|
50
50
|
var os__default = /*#__PURE__*/_interopDefault(os);
|
|
@@ -121,6 +121,13 @@ var init_logger = __esm({
|
|
|
121
121
|
exports.logger = new exports.Logger();
|
|
122
122
|
}
|
|
123
123
|
});
|
|
124
|
+
function isNextjsProject(dir) {
|
|
125
|
+
return fs3__default.default.existsSync(path12__default.default.join(dir, "next.config.ts")) || fs3__default.default.existsSync(path12__default.default.join(dir, "next.config.js")) || fs3__default.default.existsSync(path12__default.default.join(dir, "next.config.mjs"));
|
|
126
|
+
}
|
|
127
|
+
var init_detect_nextjs = __esm({
|
|
128
|
+
"src/utils/detect-nextjs.ts"() {
|
|
129
|
+
}
|
|
130
|
+
});
|
|
124
131
|
function sortedCopy(value) {
|
|
125
132
|
if (Array.isArray(value)) {
|
|
126
133
|
return value.map((v) => sortedCopy(v));
|
|
@@ -203,7 +210,7 @@ async function extractSchemas(themePath) {
|
|
|
203
210
|
const sections = {};
|
|
204
211
|
for (const file of schemaFiles) {
|
|
205
212
|
try {
|
|
206
|
-
const mod = await jiti.import(
|
|
213
|
+
const mod = await jiti.import(path12__default.default.join(themePath, file));
|
|
207
214
|
const exports$1 = mod;
|
|
208
215
|
for (const value of Object.values(exports$1)) {
|
|
209
216
|
if (value && typeof value === "object" && typeof value.type === "string" && Array.isArray(value.settings)) {
|
|
@@ -231,7 +238,7 @@ var init_extract_schemas = __esm({
|
|
|
231
238
|
}
|
|
232
239
|
});
|
|
233
240
|
function mimeFor(filename) {
|
|
234
|
-
const ext =
|
|
241
|
+
const ext = path12__default.default.extname(filename).toLowerCase();
|
|
235
242
|
return MIME_MAP[ext] || "application/octet-stream";
|
|
236
243
|
}
|
|
237
244
|
async function sha256Prefix(absPath, len) {
|
|
@@ -239,15 +246,15 @@ async function sha256Prefix(absPath, len) {
|
|
|
239
246
|
return crypto__default.default.createHash("sha256").update(buf).digest("hex").slice(0, len);
|
|
240
247
|
}
|
|
241
248
|
function insertHashIntoName(relPath, hash) {
|
|
242
|
-
const dir =
|
|
243
|
-
const base =
|
|
244
|
-
const ext =
|
|
249
|
+
const dir = path12__default.default.posix.dirname(relPath);
|
|
250
|
+
const base = path12__default.default.posix.basename(relPath);
|
|
251
|
+
const ext = path12__default.default.posix.extname(base);
|
|
245
252
|
const stem = ext ? base.slice(0, -ext.length) : base;
|
|
246
253
|
const hashed = `${stem}-${hash}${ext}`;
|
|
247
254
|
return dir === "." ? hashed : `${dir}/${hashed}`;
|
|
248
255
|
}
|
|
249
256
|
async function scanThemeAssets(distDir) {
|
|
250
|
-
const assetsDir =
|
|
257
|
+
const assetsDir = path12__default.default.join(distDir, "theme-assets");
|
|
251
258
|
if (!await fs__default.default.pathExists(assetsDir)) return [];
|
|
252
259
|
const files = await glob.glob("**/*", {
|
|
253
260
|
cwd: assetsDir,
|
|
@@ -256,10 +263,10 @@ async function scanThemeAssets(distDir) {
|
|
|
256
263
|
});
|
|
257
264
|
const results = [];
|
|
258
265
|
for (const rel of files) {
|
|
259
|
-
const absPath =
|
|
266
|
+
const absPath = path12__default.default.join(assetsDir, rel);
|
|
260
267
|
const stat = await fs__default.default.stat(absPath);
|
|
261
268
|
if (!stat.isFile()) continue;
|
|
262
|
-
const originalPath = rel.split(
|
|
269
|
+
const originalPath = rel.split(path12__default.default.sep).join("/");
|
|
263
270
|
const hash = await sha256Prefix(absPath, HASH_LEN);
|
|
264
271
|
const hashedPath = insertHashIntoName(originalPath, hash);
|
|
265
272
|
const contentType = mimeFor(rel);
|
|
@@ -302,6 +309,101 @@ var init_scan_theme_assets = __esm({
|
|
|
302
309
|
HASH_LEN = 8;
|
|
303
310
|
}
|
|
304
311
|
});
|
|
312
|
+
async function scanAppDirectory(themePath) {
|
|
313
|
+
const appDir = path12__default.default.join(themePath, "app");
|
|
314
|
+
let pageFiles;
|
|
315
|
+
try {
|
|
316
|
+
pageFiles = await glob.glob("**/page.{tsx,ts,jsx,js}", { cwd: appDir });
|
|
317
|
+
} catch {
|
|
318
|
+
return [];
|
|
319
|
+
}
|
|
320
|
+
if (pageFiles.length === 0) return [];
|
|
321
|
+
const pages = [];
|
|
322
|
+
for (const pageFile of pageFiles) {
|
|
323
|
+
const routePath = deriveRoutePath(pageFile);
|
|
324
|
+
const absPageFile = path12__default.default.join(appDir, pageFile);
|
|
325
|
+
let source;
|
|
326
|
+
try {
|
|
327
|
+
source = await fs10__default.default.readFile(absPageFile, "utf-8");
|
|
328
|
+
} catch {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
const sections = await extractSectionsFromPage(source, themePath);
|
|
332
|
+
pages.push({
|
|
333
|
+
routePath,
|
|
334
|
+
sourceFile: path12__default.default.join("app", pageFile),
|
|
335
|
+
sections
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
return pages;
|
|
339
|
+
}
|
|
340
|
+
function deriveRoutePath(pageFile) {
|
|
341
|
+
const dir = path12__default.default.dirname(pageFile);
|
|
342
|
+
if (dir === ".") return "/";
|
|
343
|
+
return "/" + dir;
|
|
344
|
+
}
|
|
345
|
+
async function extractSectionsFromPage(source, themePath) {
|
|
346
|
+
const importRegex = /import\s+\w+\s+from\s+["'](@\/|\.\.?\/)(components\/[^"']+)["']/g;
|
|
347
|
+
const sections = [];
|
|
348
|
+
const seen = /* @__PURE__ */ new Set();
|
|
349
|
+
for (const match of source.matchAll(importRegex)) {
|
|
350
|
+
const rawImportPath = match[2];
|
|
351
|
+
const componentDir = path12__default.default.dirname(rawImportPath);
|
|
352
|
+
const absComponentDir = path12__default.default.join(themePath, componentDir);
|
|
353
|
+
if (seen.has(componentDir)) continue;
|
|
354
|
+
seen.add(componentDir);
|
|
355
|
+
const sectionJsonPath = path12__default.default.join(absComponentDir, "section.json");
|
|
356
|
+
let sectionJson;
|
|
357
|
+
try {
|
|
358
|
+
const raw = await fs10__default.default.readFile(sectionJsonPath, "utf-8");
|
|
359
|
+
sectionJson = JSON.parse(raw);
|
|
360
|
+
} catch {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
if (sectionJson.type !== "opaque-react") continue;
|
|
364
|
+
if (!sectionJson.entry) continue;
|
|
365
|
+
sections.push({
|
|
366
|
+
type: "opaque-react",
|
|
367
|
+
name: sectionJson.name ?? path12__default.default.basename(componentDir),
|
|
368
|
+
entry: path12__default.default.join(componentDir, sectionJson.entry),
|
|
369
|
+
componentDir
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
return sections;
|
|
373
|
+
}
|
|
374
|
+
function buildNextjsPagesMap(pages, themeId) {
|
|
375
|
+
const result = {};
|
|
376
|
+
for (const page of pages) {
|
|
377
|
+
const id = page.routePath === "/" ? "home" : page.routePath.replace(/\//g, "-").replace(/^-/, "");
|
|
378
|
+
const makeSectionType = (name) => `${themeId}-${name.toLowerCase().replace(/\s+/g, "-")}`;
|
|
379
|
+
result[id] = {
|
|
380
|
+
id,
|
|
381
|
+
name: id.charAt(0).toUpperCase() + id.slice(1),
|
|
382
|
+
path: page.routePath,
|
|
383
|
+
config: {
|
|
384
|
+
id,
|
|
385
|
+
path: page.routePath,
|
|
386
|
+
sections: page.sections.map((s, i) => ({
|
|
387
|
+
id: `${id}-section-${i}`,
|
|
388
|
+
type: makeSectionType(s.name),
|
|
389
|
+
sectionType: "opaque-react",
|
|
390
|
+
settings: {}
|
|
391
|
+
}))
|
|
392
|
+
},
|
|
393
|
+
sections: page.sections.map((s, i) => ({
|
|
394
|
+
id: `${id}-section-${i}`,
|
|
395
|
+
type: makeSectionType(s.name),
|
|
396
|
+
sectionType: "opaque-react",
|
|
397
|
+
settings: {}
|
|
398
|
+
}))
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
return result;
|
|
402
|
+
}
|
|
403
|
+
var init_nextjs_page_scanner = __esm({
|
|
404
|
+
"src/utils/nextjs-page-scanner.ts"() {
|
|
405
|
+
}
|
|
406
|
+
});
|
|
305
407
|
|
|
306
408
|
// src/utils/compile-theme.ts
|
|
307
409
|
var compile_theme_exports = {};
|
|
@@ -317,8 +419,8 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
317
419
|
const tailwindcss = (await import('tailwindcss')).default;
|
|
318
420
|
const tailwindConfig = {
|
|
319
421
|
content: [
|
|
320
|
-
|
|
321
|
-
|
|
422
|
+
path12__default.default.join(themePath, "sections/**/*.{ts,tsx}"),
|
|
423
|
+
path12__default.default.join(themePath, "components/**/*.{ts,tsx}")
|
|
322
424
|
],
|
|
323
425
|
theme: { extend: {} },
|
|
324
426
|
plugins: []
|
|
@@ -328,7 +430,7 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
328
430
|
inputCSS,
|
|
329
431
|
{ from: void 0 }
|
|
330
432
|
);
|
|
331
|
-
await
|
|
433
|
+
await fs10__default.default.writeFile(path12__default.default.join(outDir, "bundle.css"), result.css);
|
|
332
434
|
exports.logger.info("Generated bundle.css");
|
|
333
435
|
} catch (err) {
|
|
334
436
|
exports.logger.warning(
|
|
@@ -339,12 +441,12 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
339
441
|
async function resolveNodeModulesFile(startDir, relativePath) {
|
|
340
442
|
let dir = startDir;
|
|
341
443
|
while (true) {
|
|
342
|
-
const candidate =
|
|
444
|
+
const candidate = path12__default.default.join(dir, "node_modules", relativePath);
|
|
343
445
|
try {
|
|
344
|
-
await
|
|
446
|
+
await fs10__default.default.access(candidate);
|
|
345
447
|
return candidate;
|
|
346
448
|
} catch {
|
|
347
|
-
const parent =
|
|
449
|
+
const parent = path12__default.default.dirname(dir);
|
|
348
450
|
if (parent === dir) break;
|
|
349
451
|
dir = parent;
|
|
350
452
|
}
|
|
@@ -368,7 +470,7 @@ async function scanImportsFromPackage(sourceDir, packageName) {
|
|
|
368
470
|
});
|
|
369
471
|
for (const file of sourceFiles) {
|
|
370
472
|
try {
|
|
371
|
-
const content = await
|
|
473
|
+
const content = await fs10__default.default.readFile(path12__default.default.join(sourceDir, file), "utf-8");
|
|
372
474
|
for (const match of content.matchAll(namespaceImportRegex)) {
|
|
373
475
|
const subpath = match[1] ? match[1].slice(1) : "";
|
|
374
476
|
if (!result[subpath]) result[subpath] = /* @__PURE__ */ new Set();
|
|
@@ -422,17 +524,17 @@ function createCoreGlobalPlugin(themePath) {
|
|
|
422
524
|
const distFileName = subpath ? `${subpath}.mjs` : "index.mjs";
|
|
423
525
|
let distPath = await resolveNodeModulesFile(
|
|
424
526
|
themePath,
|
|
425
|
-
|
|
527
|
+
path12__default.default.join("@onexapis", "core", "dist", distFileName)
|
|
426
528
|
);
|
|
427
529
|
if (!distPath) {
|
|
428
530
|
distPath = await resolveNodeModulesFile(
|
|
429
531
|
__dirname,
|
|
430
|
-
|
|
532
|
+
path12__default.default.join("@onexapis", "core", "dist", distFileName)
|
|
431
533
|
);
|
|
432
534
|
}
|
|
433
535
|
try {
|
|
434
536
|
if (!distPath) throw new Error("not found");
|
|
435
|
-
const distContent = await
|
|
537
|
+
const distContent = await fs10__default.default.readFile(distPath, "utf-8");
|
|
436
538
|
const exportMatches = distContent.matchAll(/export\s*\{([^}]+)\}/g);
|
|
437
539
|
for (const m of exportMatches) {
|
|
438
540
|
const names = m[1].split(",").map((n) => {
|
|
@@ -479,180 +581,6 @@ ${namedExportLines}
|
|
|
479
581
|
}
|
|
480
582
|
};
|
|
481
583
|
}
|
|
482
|
-
function createThemeDepsStubPlugin(themePath) {
|
|
483
|
-
return {
|
|
484
|
-
name: "theme-deps-stub",
|
|
485
|
-
setup(build2) {
|
|
486
|
-
const tryResolveOrStub = (filter, namespace) => {
|
|
487
|
-
build2.onResolve({ filter }, async (args) => {
|
|
488
|
-
if (args.pluginData?.skipStub) return void 0;
|
|
489
|
-
try {
|
|
490
|
-
const result = await build2.resolve(args.path, {
|
|
491
|
-
kind: args.kind,
|
|
492
|
-
resolveDir: args.resolveDir || themePath,
|
|
493
|
-
importer: args.importer,
|
|
494
|
-
namespace: "file",
|
|
495
|
-
pluginData: { skipStub: true }
|
|
496
|
-
});
|
|
497
|
-
if (!result.errors.length) return result;
|
|
498
|
-
} catch {
|
|
499
|
-
}
|
|
500
|
-
try {
|
|
501
|
-
const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) || __filename);
|
|
502
|
-
const resolved = req.resolve(args.path);
|
|
503
|
-
if (resolved) return { path: resolved, namespace: "file" };
|
|
504
|
-
} catch {
|
|
505
|
-
}
|
|
506
|
-
return { path: args.path, namespace };
|
|
507
|
-
});
|
|
508
|
-
};
|
|
509
|
-
tryResolveOrStub(/^next\//, "next-stub");
|
|
510
|
-
build2.onLoad({ filter: /.*/, namespace: "next-stub" }, (args) => {
|
|
511
|
-
const stubs = {
|
|
512
|
-
"next/image": `
|
|
513
|
-
import React from 'react';
|
|
514
|
-
const Image = React.forwardRef((props, ref) => {
|
|
515
|
-
const { src, alt, width, height, fill, priority, sizes, quality, placeholder, blurDataURL, onLoad, onError, style, className, ...rest } = props;
|
|
516
|
-
const imgSrc = typeof src === 'object' ? src.src : src;
|
|
517
|
-
const fillStyle = fill ? { position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: style?.objectFit || 'cover', display: 'block' } : {};
|
|
518
|
-
const mergedStyle = { ...fillStyle, ...style };
|
|
519
|
-
return React.createElement('img', {
|
|
520
|
-
ref, src: imgSrc, alt,
|
|
521
|
-
width: fill ? undefined : width, height: fill ? undefined : height,
|
|
522
|
-
loading: priority ? 'eager' : 'lazy',
|
|
523
|
-
style: Object.keys(mergedStyle).length > 0 ? mergedStyle : undefined,
|
|
524
|
-
className, onLoad, onError, ...rest,
|
|
525
|
-
});
|
|
526
|
-
});
|
|
527
|
-
export default Image;
|
|
528
|
-
`,
|
|
529
|
-
"next/link": `
|
|
530
|
-
import React from 'react';
|
|
531
|
-
const Link = ({ href, children, ...rest }) => React.createElement('a', { href, ...rest }, children);
|
|
532
|
-
export default Link;
|
|
533
|
-
`,
|
|
534
|
-
"next/navigation": `
|
|
535
|
-
export function useRouter() { return { push(u){window.location.href=u}, replace(u){window.location.href=u}, back(){window.history.back()}, forward(){window.history.forward()}, refresh(){window.location.reload()}, prefetch(){} }; }
|
|
536
|
-
export function usePathname() { return window.location.pathname; }
|
|
537
|
-
export function useSearchParams() { return new URLSearchParams(window.location.search); }
|
|
538
|
-
export function useParams() { return {}; }
|
|
539
|
-
export function redirect(url) { window.location.href = url; }
|
|
540
|
-
export function notFound() { throw new Error('Not Found'); }
|
|
541
|
-
`,
|
|
542
|
-
"next/headers": `
|
|
543
|
-
export function cookies() { return { get(){}, getAll(){ return []; }, set(){}, delete(){}, has(){ return false; } }; }
|
|
544
|
-
export function headers() { return new Headers(); }
|
|
545
|
-
`
|
|
546
|
-
};
|
|
547
|
-
return {
|
|
548
|
-
contents: stubs[args.path] || "export default {};",
|
|
549
|
-
loader: "jsx",
|
|
550
|
-
resolveDir: themePath
|
|
551
|
-
};
|
|
552
|
-
});
|
|
553
|
-
const lucideImports = /* @__PURE__ */ new Set();
|
|
554
|
-
let lucideThemeScanned = false;
|
|
555
|
-
tryResolveOrStub(/^lucide-react/, "lucide-stub");
|
|
556
|
-
build2.onLoad({ filter: /.*/, namespace: "lucide-stub" }, async () => {
|
|
557
|
-
if (!lucideThemeScanned) {
|
|
558
|
-
lucideThemeScanned = true;
|
|
559
|
-
try {
|
|
560
|
-
const scanned = await scanImportsFromPackage(
|
|
561
|
-
themePath,
|
|
562
|
-
"lucide-react"
|
|
563
|
-
);
|
|
564
|
-
for (const names of Object.values(scanned)) {
|
|
565
|
-
for (const name of names) lucideImports.add(name);
|
|
566
|
-
}
|
|
567
|
-
} catch {
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
const iconNames = [...lucideImports];
|
|
571
|
-
const exports$1 = iconNames.map((n) => `icon as ${n}`).join(", ");
|
|
572
|
-
return {
|
|
573
|
-
contents: `
|
|
574
|
-
const icon = (props) => null;
|
|
575
|
-
export { ${exports$1} };
|
|
576
|
-
export default new Proxy({}, { get: (_, name) => name === '__esModule' ? true : icon });
|
|
577
|
-
`.trim(),
|
|
578
|
-
loader: "jsx"
|
|
579
|
-
};
|
|
580
|
-
});
|
|
581
|
-
tryResolveOrStub(/^framer-motion/, "motion-stub");
|
|
582
|
-
build2.onLoad({ filter: /.*/, namespace: "motion-stub" }, () => ({
|
|
583
|
-
contents: `
|
|
584
|
-
import React from 'react';
|
|
585
|
-
const handler = { get: (_, name) => {
|
|
586
|
-
if (name === '__esModule') return true;
|
|
587
|
-
return React.forwardRef((props, ref) => React.createElement(name, { ...props, ref }));
|
|
588
|
-
}};
|
|
589
|
-
export const motion = new Proxy({}, handler);
|
|
590
|
-
export const AnimatePresence = ({ children }) => children || null;
|
|
591
|
-
export function useInView() { return true; }
|
|
592
|
-
export default { motion, AnimatePresence, useInView };
|
|
593
|
-
`.trim(),
|
|
594
|
-
loader: "jsx",
|
|
595
|
-
resolveDir: themePath
|
|
596
|
-
}));
|
|
597
|
-
tryResolveOrStub(/^sonner$/, "sonner-stub");
|
|
598
|
-
build2.onLoad({ filter: /.*/, namespace: "sonner-stub" }, () => ({
|
|
599
|
-
contents: `
|
|
600
|
-
export const toast = new Proxy(() => {}, { get: () => () => {} });
|
|
601
|
-
export const Toaster = () => null;
|
|
602
|
-
export default { toast, Toaster };
|
|
603
|
-
`.trim(),
|
|
604
|
-
loader: "jsx"
|
|
605
|
-
}));
|
|
606
|
-
tryResolveOrStub(/^react-hook-form$/, "rhf-stub");
|
|
607
|
-
build2.onLoad({ filter: /.*/, namespace: "rhf-stub" }, () => ({
|
|
608
|
-
contents: `
|
|
609
|
-
export function useForm() {
|
|
610
|
-
return {
|
|
611
|
-
register: () => ({}),
|
|
612
|
-
handleSubmit: (fn) => (e) => { e?.preventDefault?.(); fn({}); },
|
|
613
|
-
formState: { errors: {}, isSubmitting: false, isValid: true },
|
|
614
|
-
watch: () => undefined,
|
|
615
|
-
setValue: () => {},
|
|
616
|
-
reset: () => {},
|
|
617
|
-
control: {},
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
export function useController() { return { field: {}, fieldState: {} }; }
|
|
621
|
-
export function useFormContext() { return useForm(); }
|
|
622
|
-
`.trim(),
|
|
623
|
-
loader: "js"
|
|
624
|
-
}));
|
|
625
|
-
tryResolveOrStub(/^@hookform\/resolvers/, "hookform-resolvers-stub");
|
|
626
|
-
build2.onLoad(
|
|
627
|
-
{ filter: /.*/, namespace: "hookform-resolvers-stub" },
|
|
628
|
-
() => ({
|
|
629
|
-
contents: `export function zodResolver() { return () => ({ values: {}, errors: {} }); }`,
|
|
630
|
-
loader: "js"
|
|
631
|
-
})
|
|
632
|
-
);
|
|
633
|
-
tryResolveOrStub(/^next-intl$/, "next-intl-stub");
|
|
634
|
-
build2.onLoad({ filter: /.*/, namespace: "next-intl-stub" }, () => ({
|
|
635
|
-
contents: `
|
|
636
|
-
export function useTranslations(ns) {
|
|
637
|
-
return (key) => ns ? ns + '.' + key : key;
|
|
638
|
-
}
|
|
639
|
-
export function useLocale() { return 'en'; }
|
|
640
|
-
export function useMessages() { return {}; }
|
|
641
|
-
`.trim(),
|
|
642
|
-
loader: "js"
|
|
643
|
-
}));
|
|
644
|
-
tryResolveOrStub(/^zod$/, "zod-stub");
|
|
645
|
-
build2.onLoad({ filter: /.*/, namespace: "zod-stub" }, () => ({
|
|
646
|
-
contents: `
|
|
647
|
-
const schema = () => ({ parse: (v) => v, safeParse: (v) => ({ success: true, data: v }), optional: schema, min: schema, max: schema, email: schema, url: schema, regex: schema, refine: schema, transform: schema });
|
|
648
|
-
export const z = { string: schema, number: schema, boolean: schema, object: (s) => ({ ...schema(), shape: s }), array: schema, enum: schema, union: schema, literal: schema, infer: undefined };
|
|
649
|
-
export default z;
|
|
650
|
-
`.trim(),
|
|
651
|
-
loader: "js"
|
|
652
|
-
}));
|
|
653
|
-
}
|
|
654
|
-
};
|
|
655
|
-
}
|
|
656
584
|
async function generateThemeData(themePath, outputDir, themeId) {
|
|
657
585
|
const { createJiti } = await import('jiti');
|
|
658
586
|
const jiti = createJiti((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)));
|
|
@@ -661,7 +589,7 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
661
589
|
const pages = {};
|
|
662
590
|
for (const ext of [".ts", ".js"]) {
|
|
663
591
|
try {
|
|
664
|
-
const mod = await jiti.import(
|
|
592
|
+
const mod = await jiti.import(path12__default.default.join(themePath, `theme.config${ext}`));
|
|
665
593
|
themeConfig = mod.default || mod;
|
|
666
594
|
break;
|
|
667
595
|
} catch {
|
|
@@ -669,20 +597,20 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
669
597
|
}
|
|
670
598
|
for (const ext of [".ts", ".js"]) {
|
|
671
599
|
try {
|
|
672
|
-
const mod = await jiti.import(
|
|
600
|
+
const mod = await jiti.import(path12__default.default.join(themePath, `theme.layout${ext}`));
|
|
673
601
|
layoutConfig = mod.default || mod;
|
|
674
602
|
break;
|
|
675
603
|
} catch {
|
|
676
604
|
}
|
|
677
605
|
}
|
|
678
606
|
const schemas = {};
|
|
679
|
-
const sectionsDir =
|
|
607
|
+
const sectionsDir = path12__default.default.join(themePath, "sections");
|
|
680
608
|
try {
|
|
681
|
-
const sectionDirs = await
|
|
609
|
+
const sectionDirs = await fs10__default.default.readdir(sectionsDir);
|
|
682
610
|
for (const dir of sectionDirs) {
|
|
683
|
-
const schemaFile =
|
|
611
|
+
const schemaFile = path12__default.default.join(sectionsDir, dir, `${dir}.schema.ts`);
|
|
684
612
|
try {
|
|
685
|
-
await
|
|
613
|
+
await fs10__default.default.access(schemaFile);
|
|
686
614
|
const mod = await jiti.import(schemaFile);
|
|
687
615
|
for (const [key, value] of Object.entries(mod)) {
|
|
688
616
|
if (key.endsWith("Schema") && value && typeof value === "object" && value.type) {
|
|
@@ -694,14 +622,14 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
694
622
|
}
|
|
695
623
|
} catch {
|
|
696
624
|
}
|
|
697
|
-
const pagesDir =
|
|
625
|
+
const pagesDir = path12__default.default.join(themePath, "pages");
|
|
698
626
|
try {
|
|
699
|
-
const files = await
|
|
627
|
+
const files = await fs10__default.default.readdir(pagesDir);
|
|
700
628
|
for (const file of files) {
|
|
701
629
|
if (!file.match(/\.(ts|js)$/)) continue;
|
|
702
630
|
const name = file.replace(/\.(ts|js)$/, "");
|
|
703
631
|
try {
|
|
704
|
-
const mod = await jiti.import(
|
|
632
|
+
const mod = await jiti.import(path12__default.default.join(pagesDir, file));
|
|
705
633
|
const config = mod.default || mod;
|
|
706
634
|
const sections = (config.sections || []).map((section) => {
|
|
707
635
|
const schema = schemas[section.type];
|
|
@@ -729,8 +657,16 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
729
657
|
}
|
|
730
658
|
} catch {
|
|
731
659
|
}
|
|
732
|
-
|
|
733
|
-
|
|
660
|
+
if (isNextjsProject(themePath)) {
|
|
661
|
+
const nextjsPages = await scanAppDirectory(themePath);
|
|
662
|
+
if (nextjsPages.length > 0) {
|
|
663
|
+
const nextjsPagesMap = buildNextjsPagesMap(nextjsPages, themeId);
|
|
664
|
+
Object.assign(pages, nextjsPagesMap);
|
|
665
|
+
exports.logger.info(`Scanned ${nextjsPages.length} Next.js app/ pages`);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
await fs10__default.default.writeFile(
|
|
669
|
+
path12__default.default.join(outputDir, "theme-data.json"),
|
|
734
670
|
JSON.stringify(
|
|
735
671
|
{
|
|
736
672
|
themeId,
|
|
@@ -753,22 +689,22 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
753
689
|
exports.logger.info(`Generated theme-data.json (${Object.keys(pages).length} pages)`);
|
|
754
690
|
}
|
|
755
691
|
async function contentHashEntry(outputDir) {
|
|
756
|
-
const entryPath =
|
|
757
|
-
const mapPath =
|
|
692
|
+
const entryPath = path12__default.default.join(outputDir, "bundle-entry.js");
|
|
693
|
+
const mapPath = path12__default.default.join(outputDir, "bundle-entry.js.map");
|
|
758
694
|
let entryContent;
|
|
759
695
|
try {
|
|
760
|
-
entryContent = await
|
|
696
|
+
entryContent = await fs10__default.default.readFile(entryPath, "utf-8");
|
|
761
697
|
} catch {
|
|
762
|
-
const indexPath =
|
|
698
|
+
const indexPath = path12__default.default.join(outputDir, "index.js");
|
|
763
699
|
try {
|
|
764
|
-
entryContent = await
|
|
700
|
+
entryContent = await fs10__default.default.readFile(indexPath, "utf-8");
|
|
765
701
|
} catch {
|
|
766
702
|
exports.logger.warning("No entry file found in output, skipping content hash");
|
|
767
703
|
return;
|
|
768
704
|
}
|
|
769
705
|
const hash2 = crypto__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
|
|
770
706
|
const hashedName2 = `bundle-entry-${hash2}.js`;
|
|
771
|
-
const indexMapPath =
|
|
707
|
+
const indexMapPath = path12__default.default.join(outputDir, "index.js.map");
|
|
772
708
|
const hashedMapName2 = `bundle-entry-${hash2}.js.map`;
|
|
773
709
|
entryContent = entryContent.replace(
|
|
774
710
|
/\/\/# sourceMappingURL=index\.js\.map/,
|
|
@@ -776,18 +712,18 @@ async function contentHashEntry(outputDir) {
|
|
|
776
712
|
);
|
|
777
713
|
const oldFiles2 = await glob.glob("bundle-entry-*.js*", { cwd: outputDir });
|
|
778
714
|
for (const f of oldFiles2) {
|
|
779
|
-
await
|
|
715
|
+
await fs10__default.default.unlink(path12__default.default.join(outputDir, f));
|
|
780
716
|
}
|
|
781
|
-
await
|
|
782
|
-
await
|
|
717
|
+
await fs10__default.default.writeFile(path12__default.default.join(outputDir, hashedName2), entryContent);
|
|
718
|
+
await fs10__default.default.unlink(indexPath);
|
|
783
719
|
try {
|
|
784
|
-
await
|
|
720
|
+
await fs10__default.default.unlink(entryPath);
|
|
785
721
|
} catch {
|
|
786
722
|
}
|
|
787
|
-
await
|
|
723
|
+
await fs10__default.default.writeFile(entryPath, entryContent);
|
|
788
724
|
try {
|
|
789
|
-
await
|
|
790
|
-
await
|
|
725
|
+
await fs10__default.default.access(indexMapPath);
|
|
726
|
+
await fs10__default.default.rename(indexMapPath, path12__default.default.join(outputDir, hashedMapName2));
|
|
791
727
|
} catch {
|
|
792
728
|
}
|
|
793
729
|
exports.logger.info(`Entry hashed: ${hashedName2}`);
|
|
@@ -802,17 +738,17 @@ async function contentHashEntry(outputDir) {
|
|
|
802
738
|
);
|
|
803
739
|
const oldFiles = await glob.glob("bundle-entry-*.js*", { cwd: outputDir });
|
|
804
740
|
for (const f of oldFiles) {
|
|
805
|
-
await
|
|
741
|
+
await fs10__default.default.unlink(path12__default.default.join(outputDir, f));
|
|
806
742
|
}
|
|
807
|
-
await
|
|
743
|
+
await fs10__default.default.writeFile(path12__default.default.join(outputDir, hashedName), entryContent);
|
|
808
744
|
try {
|
|
809
|
-
await
|
|
745
|
+
await fs10__default.default.unlink(entryPath);
|
|
810
746
|
} catch {
|
|
811
747
|
}
|
|
812
|
-
await
|
|
748
|
+
await fs10__default.default.writeFile(entryPath, entryContent);
|
|
813
749
|
try {
|
|
814
|
-
await
|
|
815
|
-
await
|
|
750
|
+
await fs10__default.default.access(mapPath);
|
|
751
|
+
await fs10__default.default.rename(mapPath, path12__default.default.join(outputDir, hashedMapName));
|
|
816
752
|
} catch {
|
|
817
753
|
}
|
|
818
754
|
exports.logger.info(`Entry hashed: ${hashedName}`);
|
|
@@ -824,7 +760,7 @@ async function extractDataRequirements(themePath) {
|
|
|
824
760
|
const requirements = {};
|
|
825
761
|
for (const file of schemaFiles) {
|
|
826
762
|
try {
|
|
827
|
-
const mod = await jiti.import(
|
|
763
|
+
const mod = await jiti.import(path12__default.default.join(themePath, file));
|
|
828
764
|
const exports$1 = mod;
|
|
829
765
|
for (const value of Object.values(exports$1)) {
|
|
830
766
|
if (value && typeof value === "object" && typeof value.type === "string" && value.dataRequirements && typeof value.dataRequirements === "object") {
|
|
@@ -842,8 +778,8 @@ async function extractDataRequirements(themePath) {
|
|
|
842
778
|
async function writeGateManifests(themePath, outputDir) {
|
|
843
779
|
try {
|
|
844
780
|
const schemas = await extractSchemas(themePath);
|
|
845
|
-
await
|
|
846
|
-
|
|
781
|
+
await fs10__default.default.writeFile(
|
|
782
|
+
path12__default.default.join(outputDir, "schemas.json"),
|
|
847
783
|
serializeManifest(schemas)
|
|
848
784
|
);
|
|
849
785
|
exports.logger.info(
|
|
@@ -862,8 +798,8 @@ async function writeGateManifests(themePath, outputDir) {
|
|
|
862
798
|
size: e.size,
|
|
863
799
|
contentType: e.contentType
|
|
864
800
|
}));
|
|
865
|
-
await
|
|
866
|
-
|
|
801
|
+
await fs10__default.default.writeFile(
|
|
802
|
+
path12__default.default.join(outputDir, "asset-manifest.json"),
|
|
867
803
|
JSON.stringify({ manifestVersion: 1, assets }, null, 2)
|
|
868
804
|
);
|
|
869
805
|
exports.logger.info(`Generated asset-manifest.json (${assets.length} assets)`);
|
|
@@ -873,12 +809,71 @@ async function writeGateManifests(themePath, outputDir) {
|
|
|
873
809
|
);
|
|
874
810
|
}
|
|
875
811
|
}
|
|
812
|
+
async function compileSections(themePath, outputDir) {
|
|
813
|
+
const sectionsDir = path12__default.default.join(themePath, "sections");
|
|
814
|
+
let sectionDirs;
|
|
815
|
+
try {
|
|
816
|
+
sectionDirs = await fs10__default.default.readdir(sectionsDir);
|
|
817
|
+
} catch {
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
for (const dirName of sectionDirs) {
|
|
821
|
+
const sectionSrc = path12__default.default.join(sectionsDir, dirName);
|
|
822
|
+
const sectionOut = path12__default.default.join(outputDir, "sections", dirName);
|
|
823
|
+
let section = null;
|
|
824
|
+
try {
|
|
825
|
+
const raw = await fs10__default.default.readFile(
|
|
826
|
+
path12__default.default.join(sectionSrc, "section.manifest.json"),
|
|
827
|
+
"utf-8"
|
|
828
|
+
);
|
|
829
|
+
section = JSON.parse(raw);
|
|
830
|
+
} catch {
|
|
831
|
+
continue;
|
|
832
|
+
}
|
|
833
|
+
switch (section.type) {
|
|
834
|
+
case "editable":
|
|
835
|
+
case "opaque-react":
|
|
836
|
+
break;
|
|
837
|
+
case "html": {
|
|
838
|
+
await fs10__default.default.mkdir(sectionOut, { recursive: true });
|
|
839
|
+
const htmlSrc = path12__default.default.join(sectionSrc, section.html);
|
|
840
|
+
let htmlContent = await fs10__default.default.readFile(htmlSrc, "utf-8");
|
|
841
|
+
htmlContent = htmlContent.replace(
|
|
842
|
+
/<script[^>]+src=["']https?:\/\/[^"']*["'][^>]*><\/script>/gi,
|
|
843
|
+
""
|
|
844
|
+
);
|
|
845
|
+
await fs10__default.default.writeFile(path12__default.default.join(sectionOut, path12__default.default.basename(section.html)), htmlContent);
|
|
846
|
+
if (section.css) {
|
|
847
|
+
await fs10__default.default.copyFile(
|
|
848
|
+
path12__default.default.join(sectionSrc, section.css),
|
|
849
|
+
path12__default.default.join(sectionOut, path12__default.default.basename(section.css))
|
|
850
|
+
);
|
|
851
|
+
}
|
|
852
|
+
break;
|
|
853
|
+
}
|
|
854
|
+
case "iframe":
|
|
855
|
+
break;
|
|
856
|
+
case "webcomponent": {
|
|
857
|
+
await fs10__default.default.mkdir(sectionOut, { recursive: true });
|
|
858
|
+
await fs10__default.default.copyFile(
|
|
859
|
+
path12__default.default.join(sectionSrc, section.bundle),
|
|
860
|
+
path12__default.default.join(sectionOut, path12__default.default.basename(section.bundle))
|
|
861
|
+
);
|
|
862
|
+
break;
|
|
863
|
+
}
|
|
864
|
+
default:
|
|
865
|
+
throw new Error(
|
|
866
|
+
`Unknown section type. Valid types: editable, opaque-react, html, iframe, webcomponent`
|
|
867
|
+
);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
876
871
|
async function generateManifest(themeName, themePath, outputDir) {
|
|
877
872
|
let version = "1.0.0";
|
|
878
873
|
let themeId = themeName;
|
|
879
874
|
try {
|
|
880
|
-
const pkgContent = await
|
|
881
|
-
|
|
875
|
+
const pkgContent = await fs10__default.default.readFile(
|
|
876
|
+
path12__default.default.join(themePath, "package.json"),
|
|
882
877
|
"utf-8"
|
|
883
878
|
);
|
|
884
879
|
const pkg = JSON.parse(pkgContent);
|
|
@@ -896,7 +891,7 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
896
891
|
const dataRequirements = await extractDataRequirements(themePath);
|
|
897
892
|
let hasThemeConfig = false;
|
|
898
893
|
try {
|
|
899
|
-
await
|
|
894
|
+
await fs10__default.default.access(path12__default.default.join(themePath, "theme.config.ts"));
|
|
900
895
|
hasThemeConfig = true;
|
|
901
896
|
} catch {
|
|
902
897
|
}
|
|
@@ -937,24 +932,34 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
937
932
|
// Section data requirements for server-side prefetching (keyed by section type)
|
|
938
933
|
dataRequirements
|
|
939
934
|
};
|
|
940
|
-
await
|
|
941
|
-
|
|
935
|
+
await fs10__default.default.writeFile(
|
|
936
|
+
path12__default.default.join(outputDir, "manifest.json"),
|
|
942
937
|
JSON.stringify(manifest, null, 2)
|
|
943
938
|
);
|
|
944
939
|
}
|
|
945
940
|
async function compileStandaloneTheme(themePath, themeName) {
|
|
946
|
-
const outputDir =
|
|
947
|
-
const
|
|
948
|
-
|
|
941
|
+
const outputDir = path12__default.default.join(themePath, "dist");
|
|
942
|
+
const isNextjs = isNextjsProject(themePath);
|
|
943
|
+
if (isNextjs) {
|
|
944
|
+
exports.logger.info("Detected Next.js project \u2014 using next/* shims");
|
|
945
|
+
}
|
|
946
|
+
const bundleEntry = path12__default.default.join(themePath, "bundle-entry.ts");
|
|
947
|
+
const indexEntry = path12__default.default.join(themePath, "index.ts");
|
|
949
948
|
let entryPoint = indexEntry;
|
|
950
949
|
try {
|
|
951
|
-
await
|
|
950
|
+
await fs10__default.default.access(bundleEntry);
|
|
952
951
|
entryPoint = bundleEntry;
|
|
953
952
|
} catch {
|
|
954
953
|
}
|
|
955
|
-
const shimPath =
|
|
956
|
-
await
|
|
957
|
-
await
|
|
954
|
+
const shimPath = path12__default.default.join(outputDir, ".process-shim.js");
|
|
955
|
+
await fs10__default.default.mkdir(outputDir, { recursive: true });
|
|
956
|
+
await fs10__default.default.writeFile(shimPath, PROCESS_SHIM);
|
|
957
|
+
const plugins = [
|
|
958
|
+
reactGlobalPlugin,
|
|
959
|
+
reactQueryGlobalPlugin,
|
|
960
|
+
createCoreGlobalPlugin(themePath)
|
|
961
|
+
];
|
|
962
|
+
if (isNextjs) plugins.unshift(nextShimPlugin);
|
|
958
963
|
const buildOptions = {
|
|
959
964
|
entryPoints: [entryPoint],
|
|
960
965
|
bundle: true,
|
|
@@ -966,12 +971,7 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
966
971
|
banner: {
|
|
967
972
|
js: '"use client";'
|
|
968
973
|
},
|
|
969
|
-
plugins
|
|
970
|
-
reactGlobalPlugin,
|
|
971
|
-
reactQueryGlobalPlugin,
|
|
972
|
-
createCoreGlobalPlugin(themePath),
|
|
973
|
-
createThemeDepsStubPlugin(themePath)
|
|
974
|
-
],
|
|
974
|
+
plugins,
|
|
975
975
|
external: [],
|
|
976
976
|
alias: {
|
|
977
977
|
events: "events/",
|
|
@@ -1005,15 +1005,16 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
1005
1005
|
try {
|
|
1006
1006
|
const result = await esbuild__namespace.build(buildOptions);
|
|
1007
1007
|
try {
|
|
1008
|
-
await
|
|
1008
|
+
await fs10__default.default.unlink(shimPath);
|
|
1009
1009
|
} catch {
|
|
1010
1010
|
}
|
|
1011
|
+
await compileSections(themePath, outputDir);
|
|
1011
1012
|
await contentHashEntry(outputDir);
|
|
1012
|
-
const themeAssetsDir =
|
|
1013
|
-
const distThemeAssets =
|
|
1013
|
+
const themeAssetsDir = path12__default.default.join(themePath, "assets");
|
|
1014
|
+
const distThemeAssets = path12__default.default.join(outputDir, "theme-assets");
|
|
1014
1015
|
try {
|
|
1015
|
-
await
|
|
1016
|
-
await
|
|
1016
|
+
await fs10__default.default.access(themeAssetsDir);
|
|
1017
|
+
await fs10__default.default.cp(themeAssetsDir, distThemeAssets, { recursive: true });
|
|
1017
1018
|
exports.logger.info("Copied static assets to dist/theme-assets/");
|
|
1018
1019
|
} catch {
|
|
1019
1020
|
}
|
|
@@ -1033,7 +1034,7 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
1033
1034
|
return true;
|
|
1034
1035
|
} catch (error) {
|
|
1035
1036
|
try {
|
|
1036
|
-
await
|
|
1037
|
+
await fs10__default.default.unlink(shimPath);
|
|
1037
1038
|
} catch {
|
|
1038
1039
|
}
|
|
1039
1040
|
exports.logger.error(`esbuild compilation failed: ${error}`);
|
|
@@ -1041,18 +1042,25 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
1041
1042
|
}
|
|
1042
1043
|
}
|
|
1043
1044
|
async function compileStandaloneThemeDev(themePath, themeName) {
|
|
1044
|
-
const outputDir =
|
|
1045
|
-
const
|
|
1046
|
-
const
|
|
1045
|
+
const outputDir = path12__default.default.join(themePath, "dist");
|
|
1046
|
+
const isNextjs = isNextjsProject(themePath);
|
|
1047
|
+
const bundleEntry = path12__default.default.join(themePath, "bundle-entry.ts");
|
|
1048
|
+
const indexEntry = path12__default.default.join(themePath, "index.ts");
|
|
1047
1049
|
let entryPoint = indexEntry;
|
|
1048
1050
|
try {
|
|
1049
|
-
await
|
|
1051
|
+
await fs10__default.default.access(bundleEntry);
|
|
1050
1052
|
entryPoint = bundleEntry;
|
|
1051
1053
|
} catch {
|
|
1052
1054
|
}
|
|
1053
|
-
const shimPath =
|
|
1054
|
-
await
|
|
1055
|
-
await
|
|
1055
|
+
const shimPath = path12__default.default.join(outputDir, ".process-shim.js");
|
|
1056
|
+
await fs10__default.default.mkdir(outputDir, { recursive: true });
|
|
1057
|
+
await fs10__default.default.writeFile(shimPath, PROCESS_SHIM);
|
|
1058
|
+
const devPlugins = [
|
|
1059
|
+
reactGlobalPlugin,
|
|
1060
|
+
reactQueryGlobalPlugin,
|
|
1061
|
+
createCoreGlobalPlugin(themePath)
|
|
1062
|
+
];
|
|
1063
|
+
if (isNextjs) devPlugins.unshift(nextShimPlugin);
|
|
1056
1064
|
const buildOptions = {
|
|
1057
1065
|
entryPoints: [entryPoint],
|
|
1058
1066
|
bundle: true,
|
|
@@ -1063,12 +1071,7 @@ async function compileStandaloneThemeDev(themePath, themeName) {
|
|
|
1063
1071
|
banner: {
|
|
1064
1072
|
js: '"use client";'
|
|
1065
1073
|
},
|
|
1066
|
-
plugins:
|
|
1067
|
-
reactGlobalPlugin,
|
|
1068
|
-
reactQueryGlobalPlugin,
|
|
1069
|
-
createCoreGlobalPlugin(themePath),
|
|
1070
|
-
createThemeDepsStubPlugin(themePath)
|
|
1071
|
-
],
|
|
1074
|
+
plugins: devPlugins,
|
|
1072
1075
|
external: [],
|
|
1073
1076
|
alias: {
|
|
1074
1077
|
events: "events/",
|
|
@@ -1106,18 +1109,18 @@ async function compileStandaloneThemeDev(themePath, themeName) {
|
|
|
1106
1109
|
return { context: context2, outputDir };
|
|
1107
1110
|
}
|
|
1108
1111
|
async function compilePreviewRuntime(themePath) {
|
|
1109
|
-
const outputDir =
|
|
1110
|
-
await
|
|
1111
|
-
const outputPath =
|
|
1112
|
+
const outputDir = path12__default.default.join(themePath, "dist");
|
|
1113
|
+
await fs10__default.default.mkdir(outputDir, { recursive: true });
|
|
1114
|
+
const outputPath = path12__default.default.join(outputDir, "preview-runtime.js");
|
|
1112
1115
|
const locations = [
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
+
path12__default.default.join(__dirname, "..", "preview", "preview-app.tsx"),
|
|
1117
|
+
path12__default.default.join(__dirname, "preview", "preview-app.tsx"),
|
|
1118
|
+
path12__default.default.join(__dirname, "..", "..", "src", "preview", "preview-app.tsx")
|
|
1116
1119
|
];
|
|
1117
1120
|
let previewEntryPath = null;
|
|
1118
1121
|
for (const loc of locations) {
|
|
1119
1122
|
try {
|
|
1120
|
-
await
|
|
1123
|
+
await fs10__default.default.access(loc);
|
|
1121
1124
|
previewEntryPath = loc;
|
|
1122
1125
|
break;
|
|
1123
1126
|
} catch {
|
|
@@ -1200,10 +1203,10 @@ ${locations.join("\n")}`
|
|
|
1200
1203
|
if (!lucideScanned) {
|
|
1201
1204
|
lucideScanned = true;
|
|
1202
1205
|
const coreSrcCandidates = [
|
|
1203
|
-
|
|
1204
|
-
|
|
1206
|
+
path12__default.default.join(themePath, "node_modules", "@onexapis", "core", "src"),
|
|
1207
|
+
path12__default.default.join(themePath, "..", "..", "packages", "core", "src"),
|
|
1205
1208
|
// monorepo sibling
|
|
1206
|
-
|
|
1209
|
+
path12__default.default.join(
|
|
1207
1210
|
__dirname,
|
|
1208
1211
|
"..",
|
|
1209
1212
|
"..",
|
|
@@ -1218,7 +1221,7 @@ ${locations.join("\n")}`
|
|
|
1218
1221
|
let coreSourceDir = null;
|
|
1219
1222
|
for (const candidate of coreSrcCandidates) {
|
|
1220
1223
|
try {
|
|
1221
|
-
await
|
|
1224
|
+
await fs10__default.default.access(candidate);
|
|
1222
1225
|
coreSourceDir = candidate;
|
|
1223
1226
|
break;
|
|
1224
1227
|
} catch {
|
|
@@ -1237,21 +1240,21 @@ ${locations.join("\n")}`
|
|
|
1237
1240
|
}
|
|
1238
1241
|
} else {
|
|
1239
1242
|
const coreDistCandidates = [
|
|
1240
|
-
|
|
1243
|
+
path12__default.default.join(themePath, "node_modules", "@onexapis", "core", "dist")
|
|
1241
1244
|
];
|
|
1242
1245
|
const resolvedDist = await resolveNodeModulesFile(
|
|
1243
1246
|
__dirname,
|
|
1244
|
-
|
|
1247
|
+
path12__default.default.join("@onexapis", "core", "dist")
|
|
1245
1248
|
);
|
|
1246
1249
|
if (resolvedDist) coreDistCandidates.push(resolvedDist);
|
|
1247
1250
|
for (const candidate of coreDistCandidates) {
|
|
1248
1251
|
try {
|
|
1249
|
-
await
|
|
1252
|
+
await fs10__default.default.access(candidate);
|
|
1250
1253
|
const mjsFiles = await glob.glob("*.mjs", { cwd: candidate });
|
|
1251
1254
|
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']lucide-react["']/g;
|
|
1252
1255
|
for (const file of mjsFiles) {
|
|
1253
|
-
const content = await
|
|
1254
|
-
|
|
1256
|
+
const content = await fs10__default.default.readFile(
|
|
1257
|
+
path12__default.default.join(candidate, file),
|
|
1255
1258
|
"utf-8"
|
|
1256
1259
|
);
|
|
1257
1260
|
for (const match of content.matchAll(importRegex)) {
|
|
@@ -1306,7 +1309,7 @@ export default new Proxy({}, { get: (_, name) => name === '__esModule' ? true :
|
|
|
1306
1309
|
const req = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) || __filename);
|
|
1307
1310
|
const cjsPath = req.resolve("framer-motion");
|
|
1308
1311
|
const pkgDir = cjsPath.replace(/[/\\]dist[/\\].*$/, "");
|
|
1309
|
-
const esmEntry =
|
|
1312
|
+
const esmEntry = path12__default.default.join(pkgDir, "dist", "es", "index.mjs");
|
|
1310
1313
|
const { existsSync } = await import('fs');
|
|
1311
1314
|
if (existsSync(esmEntry)) {
|
|
1312
1315
|
return { path: esmEntry, namespace: "file" };
|
|
@@ -1405,8 +1408,8 @@ export function headers() { return new Headers(); }
|
|
|
1405
1408
|
});
|
|
1406
1409
|
}
|
|
1407
1410
|
};
|
|
1408
|
-
const shimPath =
|
|
1409
|
-
await
|
|
1411
|
+
const shimPath = path12__default.default.join(outputDir, ".process-shim-preview.js");
|
|
1412
|
+
await fs10__default.default.writeFile(shimPath, PROCESS_SHIM);
|
|
1410
1413
|
await esbuild__namespace.build({
|
|
1411
1414
|
entryPoints: [previewEntryPath],
|
|
1412
1415
|
bundle: true,
|
|
@@ -1441,17 +1444,19 @@ export function headers() { return new Headers(); }
|
|
|
1441
1444
|
}
|
|
1442
1445
|
});
|
|
1443
1446
|
try {
|
|
1444
|
-
await
|
|
1447
|
+
await fs10__default.default.unlink(shimPath);
|
|
1445
1448
|
} catch {
|
|
1446
1449
|
}
|
|
1447
1450
|
return outputPath;
|
|
1448
1451
|
}
|
|
1449
|
-
var PROCESS_SHIM, reactGlobalPlugin, reactQueryGlobalPlugin;
|
|
1452
|
+
var PROCESS_SHIM, reactGlobalPlugin, reactQueryGlobalPlugin, nextShimPlugin;
|
|
1450
1453
|
var init_compile_theme = __esm({
|
|
1451
1454
|
"src/utils/compile-theme.ts"() {
|
|
1452
1455
|
init_logger();
|
|
1453
1456
|
init_extract_schemas();
|
|
1454
1457
|
init_scan_theme_assets();
|
|
1458
|
+
init_detect_nextjs();
|
|
1459
|
+
init_nextjs_page_scanner();
|
|
1455
1460
|
PROCESS_SHIM = `
|
|
1456
1461
|
if (typeof process === "undefined") {
|
|
1457
1462
|
globalThis.process = {
|
|
@@ -1597,6 +1602,145 @@ export const {
|
|
|
1597
1602
|
}));
|
|
1598
1603
|
}
|
|
1599
1604
|
};
|
|
1605
|
+
nextShimPlugin = {
|
|
1606
|
+
name: "next-shim",
|
|
1607
|
+
setup(build2) {
|
|
1608
|
+
for (const serverModule of ["next/headers", "next/server", "next/cache"]) {
|
|
1609
|
+
build2.onResolve({ filter: new RegExp(`^${serverModule.replace("/", "\\/")}`) }, (args) => ({
|
|
1610
|
+
path: args.path,
|
|
1611
|
+
namespace: "next-server-error"
|
|
1612
|
+
}));
|
|
1613
|
+
}
|
|
1614
|
+
build2.onLoad({ filter: /.*/, namespace: "next-server-error" }, (args) => ({
|
|
1615
|
+
errors: [
|
|
1616
|
+
{
|
|
1617
|
+
text: `"${args.path}" is server-only and cannot be used in a OneX theme bundle. Use client-side equivalents or remove the import.`
|
|
1618
|
+
}
|
|
1619
|
+
]
|
|
1620
|
+
}));
|
|
1621
|
+
build2.onResolve({ filter: /^next\/navigation$/ }, () => ({
|
|
1622
|
+
path: "next-navigation-shim",
|
|
1623
|
+
namespace: "next-shim"
|
|
1624
|
+
}));
|
|
1625
|
+
build2.onLoad({ filter: /^next-navigation-shim$/, namespace: "next-shim" }, () => ({
|
|
1626
|
+
contents: `
|
|
1627
|
+
export function usePathname() {
|
|
1628
|
+
if (typeof window === 'undefined') return '/';
|
|
1629
|
+
return window.location.pathname;
|
|
1630
|
+
}
|
|
1631
|
+
export function useSearchParams() {
|
|
1632
|
+
if (typeof window === 'undefined') return new URLSearchParams();
|
|
1633
|
+
return new URLSearchParams(window.location.search);
|
|
1634
|
+
}
|
|
1635
|
+
export function useParams() {
|
|
1636
|
+
if (typeof window === 'undefined') return {};
|
|
1637
|
+
return (globalThis.__ONEX_ROUTE_PARAMS__) ?? {};
|
|
1638
|
+
}
|
|
1639
|
+
export function useRouter() {
|
|
1640
|
+
return {
|
|
1641
|
+
push(url) { if (typeof window !== 'undefined') window.location.href = url; },
|
|
1642
|
+
replace(url) { if (typeof window !== 'undefined') window.location.replace(url); },
|
|
1643
|
+
back() { if (typeof window !== 'undefined') window.history.back(); },
|
|
1644
|
+
forward() { if (typeof window !== 'undefined') window.history.forward(); },
|
|
1645
|
+
refresh() { if (typeof window !== 'undefined') window.location.reload(); },
|
|
1646
|
+
prefetch() {},
|
|
1647
|
+
};
|
|
1648
|
+
}
|
|
1649
|
+
export function redirect(url) {
|
|
1650
|
+
if (typeof window !== 'undefined') window.location.href = url;
|
|
1651
|
+
throw new Error('redirect');
|
|
1652
|
+
}
|
|
1653
|
+
export function notFound() { throw new Error('not-found'); }
|
|
1654
|
+
`.trim(),
|
|
1655
|
+
loader: "js"
|
|
1656
|
+
}));
|
|
1657
|
+
build2.onResolve({ filter: /^next\/font\// }, () => ({
|
|
1658
|
+
path: "next-font-shim",
|
|
1659
|
+
namespace: "next-shim"
|
|
1660
|
+
}));
|
|
1661
|
+
build2.onLoad({ filter: /^next-font-shim$/, namespace: "next-shim" }, () => ({
|
|
1662
|
+
contents: `
|
|
1663
|
+
function makeFont(family) {
|
|
1664
|
+
return function(_opts) {
|
|
1665
|
+
return {
|
|
1666
|
+
className: '',
|
|
1667
|
+
style: { fontFamily: family + ', system-ui, sans-serif' },
|
|
1668
|
+
variable: '--font-' + family.toLowerCase().replace(/\\s+/g, '-'),
|
|
1669
|
+
};
|
|
1670
|
+
};
|
|
1671
|
+
}
|
|
1672
|
+
export const Inter = makeFont('Inter');
|
|
1673
|
+
export const Roboto = makeFont('Roboto');
|
|
1674
|
+
export const Open_Sans = makeFont('Open Sans');
|
|
1675
|
+
export const Lato = makeFont('Lato');
|
|
1676
|
+
export const Montserrat = makeFont('Montserrat');
|
|
1677
|
+
export const Poppins = makeFont('Poppins');
|
|
1678
|
+
export const Raleway = makeFont('Raleway');
|
|
1679
|
+
export const Nunito = makeFont('Nunito');
|
|
1680
|
+
export const Geist = makeFont('Geist');
|
|
1681
|
+
export const Geist_Mono = makeFont('Geist Mono');
|
|
1682
|
+
export const DM_Sans = makeFont('DM Sans');
|
|
1683
|
+
export const Plus_Jakarta_Sans = makeFont('Plus Jakarta Sans');
|
|
1684
|
+
export function localFont(_opts) {
|
|
1685
|
+
return { className: '', style: { fontFamily: 'system-ui, sans-serif' }, variable: '--font-local' };
|
|
1686
|
+
}
|
|
1687
|
+
`.trim(),
|
|
1688
|
+
loader: "js"
|
|
1689
|
+
}));
|
|
1690
|
+
build2.onResolve({ filter: /^next\/dynamic$/ }, () => ({
|
|
1691
|
+
path: "next-dynamic-shim",
|
|
1692
|
+
namespace: "next-shim"
|
|
1693
|
+
}));
|
|
1694
|
+
build2.onLoad({ filter: /^next-dynamic-shim$/, namespace: "next-shim" }, () => ({
|
|
1695
|
+
contents: `
|
|
1696
|
+
import { lazy, Suspense, createElement } from 'react';
|
|
1697
|
+
export default function dynamic(loader, opts) {
|
|
1698
|
+
const Lazy = lazy(loader);
|
|
1699
|
+
return function DynamicComponent(props) {
|
|
1700
|
+
return createElement(Suspense, { fallback: opts?.loading ? createElement(opts.loading) : null },
|
|
1701
|
+
createElement(Lazy, props));
|
|
1702
|
+
};
|
|
1703
|
+
}
|
|
1704
|
+
`.trim(),
|
|
1705
|
+
loader: "js"
|
|
1706
|
+
}));
|
|
1707
|
+
build2.onResolve({ filter: /^next\/image$/ }, () => ({
|
|
1708
|
+
path: "next-image-shim",
|
|
1709
|
+
namespace: "next-shim"
|
|
1710
|
+
}));
|
|
1711
|
+
build2.onLoad({ filter: /^next-image-shim$/, namespace: "next-shim" }, () => ({
|
|
1712
|
+
contents: `
|
|
1713
|
+
import { createElement } from 'react';
|
|
1714
|
+
export default function Image({ src, alt, width, height, style, className, ...rest }) {
|
|
1715
|
+
return createElement('img', { src, alt, width, height, style, className, ...rest });
|
|
1716
|
+
}
|
|
1717
|
+
`.trim(),
|
|
1718
|
+
loader: "js"
|
|
1719
|
+
}));
|
|
1720
|
+
build2.onResolve({ filter: /^next\/link$/ }, () => ({
|
|
1721
|
+
path: "next-link-shim",
|
|
1722
|
+
namespace: "next-shim"
|
|
1723
|
+
}));
|
|
1724
|
+
build2.onLoad({ filter: /^next-link-shim$/, namespace: "next-shim" }, () => ({
|
|
1725
|
+
contents: `
|
|
1726
|
+
import { createElement } from 'react';
|
|
1727
|
+
export default function Link({ href, children, className, style, ...rest }) {
|
|
1728
|
+
return createElement('a', { href, className, style, ...rest }, children);
|
|
1729
|
+
}
|
|
1730
|
+
`.trim(),
|
|
1731
|
+
loader: "js"
|
|
1732
|
+
}));
|
|
1733
|
+
build2.onResolve({ filter: /^next\// }, () => ({
|
|
1734
|
+
path: "next-noop-shim",
|
|
1735
|
+
namespace: "next-shim"
|
|
1736
|
+
}));
|
|
1737
|
+
build2.onLoad({ filter: /^next-noop-shim$/, namespace: "next-shim" }, () => ({
|
|
1738
|
+
contents: `export default {};
|
|
1739
|
+
`,
|
|
1740
|
+
loader: "js"
|
|
1741
|
+
}));
|
|
1742
|
+
}
|
|
1743
|
+
};
|
|
1600
1744
|
}
|
|
1601
1745
|
});
|
|
1602
1746
|
|
|
@@ -1621,8 +1765,8 @@ function validateThemeName(name) {
|
|
|
1621
1765
|
return /^[a-z][a-z0-9-]*$/.test(name);
|
|
1622
1766
|
}
|
|
1623
1767
|
function pathExists(filePath) {
|
|
1624
|
-
const
|
|
1625
|
-
return
|
|
1768
|
+
const fs14 = __require("fs-extra");
|
|
1769
|
+
return fs14.existsSync(filePath);
|
|
1626
1770
|
}
|
|
1627
1771
|
function validateCategory(category) {
|
|
1628
1772
|
const validCategories = [
|
|
@@ -1663,18 +1807,18 @@ async function renderTemplate(templatePath, data) {
|
|
|
1663
1807
|
return ejs__default.default.render(template, data);
|
|
1664
1808
|
}
|
|
1665
1809
|
async function writeFile(filePath, content) {
|
|
1666
|
-
await fs__default.default.ensureDir(
|
|
1810
|
+
await fs__default.default.ensureDir(path12__default.default.dirname(filePath));
|
|
1667
1811
|
await fs__default.default.writeFile(filePath, content, "utf-8");
|
|
1668
1812
|
}
|
|
1669
1813
|
function getTemplatesDir() {
|
|
1670
1814
|
const locations = [
|
|
1671
|
-
|
|
1815
|
+
path12__default.default.join(__dirname, "../../templates"),
|
|
1672
1816
|
// Development
|
|
1673
|
-
|
|
1817
|
+
path12__default.default.join(__dirname, "../templates"),
|
|
1674
1818
|
// Production (dist/)
|
|
1675
|
-
|
|
1819
|
+
path12__default.default.join(process.cwd(), "templates"),
|
|
1676
1820
|
// Fallback
|
|
1677
|
-
|
|
1821
|
+
path12__default.default.join(process.cwd(), "packages/cli/templates")
|
|
1678
1822
|
// Monorepo
|
|
1679
1823
|
];
|
|
1680
1824
|
for (const location of locations) {
|
|
@@ -1686,7 +1830,7 @@ function getTemplatesDir() {
|
|
|
1686
1830
|
}
|
|
1687
1831
|
async function copyTemplate(templateName, targetDir, data) {
|
|
1688
1832
|
const templatesDir = getTemplatesDir();
|
|
1689
|
-
const templateDir =
|
|
1833
|
+
const templateDir = path12__default.default.join(templatesDir, templateName);
|
|
1690
1834
|
if (!fs__default.default.existsSync(templateDir)) {
|
|
1691
1835
|
throw new Error(
|
|
1692
1836
|
`Template "${templateName}" not found at ${templateDir}. Available templates: ${fs__default.default.readdirSync(templatesDir).join(", ")}`
|
|
@@ -1695,8 +1839,8 @@ async function copyTemplate(templateName, targetDir, data) {
|
|
|
1695
1839
|
await fs__default.default.ensureDir(targetDir);
|
|
1696
1840
|
const files = await fs__default.default.readdir(templateDir);
|
|
1697
1841
|
for (const file of files) {
|
|
1698
|
-
const templatePath =
|
|
1699
|
-
const targetPath =
|
|
1842
|
+
const templatePath = path12__default.default.join(templateDir, file);
|
|
1843
|
+
const targetPath = path12__default.default.join(targetDir, file);
|
|
1700
1844
|
const stat = await fs__default.default.stat(templatePath);
|
|
1701
1845
|
if (stat.isDirectory()) {
|
|
1702
1846
|
await copyTemplateDir(templatePath, targetPath, data);
|
|
@@ -1713,8 +1857,8 @@ async function copyTemplateDir(templateDir, targetDir, data) {
|
|
|
1713
1857
|
await fs__default.default.ensureDir(targetDir);
|
|
1714
1858
|
const files = await fs__default.default.readdir(templateDir);
|
|
1715
1859
|
for (const file of files) {
|
|
1716
|
-
const templatePath =
|
|
1717
|
-
const targetPath =
|
|
1860
|
+
const templatePath = path12__default.default.join(templateDir, file);
|
|
1861
|
+
const targetPath = path12__default.default.join(targetDir, file);
|
|
1718
1862
|
const stat = await fs__default.default.stat(templatePath);
|
|
1719
1863
|
if (stat.isDirectory()) {
|
|
1720
1864
|
await copyTemplateDir(templatePath, targetPath, data);
|
|
@@ -1729,32 +1873,32 @@ async function copyTemplateDir(templateDir, targetDir, data) {
|
|
|
1729
1873
|
}
|
|
1730
1874
|
function getProjectRoot() {
|
|
1731
1875
|
let currentDir = process.cwd();
|
|
1732
|
-
while (currentDir !==
|
|
1733
|
-
const packageJsonPath =
|
|
1876
|
+
while (currentDir !== path12__default.default.parse(currentDir).root) {
|
|
1877
|
+
const packageJsonPath = path12__default.default.join(currentDir, "package.json");
|
|
1734
1878
|
if (fs__default.default.existsSync(packageJsonPath)) {
|
|
1735
1879
|
const packageJson = fs__default.default.readJsonSync(packageJsonPath);
|
|
1736
|
-
if (packageJson.workspaces || fs__default.default.existsSync(
|
|
1880
|
+
if (packageJson.workspaces || fs__default.default.existsSync(path12__default.default.join(currentDir, "src/themes")) || fs__default.default.existsSync(path12__default.default.join(currentDir, "themes"))) {
|
|
1737
1881
|
return currentDir;
|
|
1738
1882
|
}
|
|
1739
1883
|
}
|
|
1740
|
-
currentDir =
|
|
1884
|
+
currentDir = path12__default.default.dirname(currentDir);
|
|
1741
1885
|
}
|
|
1742
1886
|
return process.cwd();
|
|
1743
1887
|
}
|
|
1744
1888
|
function getThemesDir() {
|
|
1745
1889
|
const root = getProjectRoot();
|
|
1746
|
-
if (fs__default.default.existsSync(
|
|
1747
|
-
return
|
|
1748
|
-
if (fs__default.default.existsSync(
|
|
1749
|
-
return
|
|
1750
|
-
return
|
|
1890
|
+
if (fs__default.default.existsSync(path12__default.default.join(root, "themes")))
|
|
1891
|
+
return path12__default.default.join(root, "themes");
|
|
1892
|
+
if (fs__default.default.existsSync(path12__default.default.join(root, "src/themes")))
|
|
1893
|
+
return path12__default.default.join(root, "src/themes");
|
|
1894
|
+
return path12__default.default.dirname(root);
|
|
1751
1895
|
}
|
|
1752
1896
|
function getFeaturesDir() {
|
|
1753
|
-
return
|
|
1897
|
+
return path12__default.default.join(getProjectRoot(), "src/features");
|
|
1754
1898
|
}
|
|
1755
1899
|
function isOneXProject() {
|
|
1756
1900
|
const root = getProjectRoot();
|
|
1757
|
-
return fs__default.default.existsSync(
|
|
1901
|
+
return fs__default.default.existsSync(path12__default.default.join(root, "themes")) || fs__default.default.existsSync(path12__default.default.join(root, "src/themes")) || fs__default.default.existsSync(path12__default.default.join(root, "theme.config.ts")) || fs__default.default.existsSync(path12__default.default.join(root, "bundle-entry.ts"));
|
|
1758
1902
|
}
|
|
1759
1903
|
function ensureOneXProject() {
|
|
1760
1904
|
if (!isOneXProject()) {
|
|
@@ -1770,13 +1914,13 @@ function listThemes() {
|
|
|
1770
1914
|
return [];
|
|
1771
1915
|
}
|
|
1772
1916
|
return fs__default.default.readdirSync(themesDir).filter((name) => {
|
|
1773
|
-
const themePath =
|
|
1774
|
-
return fs__default.default.statSync(themePath).isDirectory() && (fs__default.default.existsSync(
|
|
1917
|
+
const themePath = path12__default.default.join(themesDir, name);
|
|
1918
|
+
return fs__default.default.statSync(themePath).isDirectory() && (fs__default.default.existsSync(path12__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path12__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path12__default.default.join(themePath, "manifest.ts")));
|
|
1775
1919
|
});
|
|
1776
1920
|
}
|
|
1777
1921
|
function themeExists(themeName) {
|
|
1778
|
-
const themePath =
|
|
1779
|
-
return fs__default.default.existsSync(themePath) && (fs__default.default.existsSync(
|
|
1922
|
+
const themePath = path12__default.default.join(getThemesDir(), themeName);
|
|
1923
|
+
return fs__default.default.existsSync(themePath) && (fs__default.default.existsSync(path12__default.default.join(themePath, "theme.config.ts")) || fs__default.default.existsSync(path12__default.default.join(themePath, "bundle-entry.ts")) || fs__default.default.existsSync(path12__default.default.join(themePath, "manifest.ts")));
|
|
1780
1924
|
}
|
|
1781
1925
|
function detectPackageManager() {
|
|
1782
1926
|
const userAgent = process.env.npm_config_user_agent || "";
|
|
@@ -1784,9 +1928,9 @@ function detectPackageManager() {
|
|
|
1784
1928
|
if (userAgent.includes("yarn")) return "yarn";
|
|
1785
1929
|
if (userAgent.includes("bun")) return "bun";
|
|
1786
1930
|
const cwd = process.cwd();
|
|
1787
|
-
if (fs__default.default.existsSync(
|
|
1788
|
-
if (fs__default.default.existsSync(
|
|
1789
|
-
if (fs__default.default.existsSync(
|
|
1931
|
+
if (fs__default.default.existsSync(path12__default.default.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
|
|
1932
|
+
if (fs__default.default.existsSync(path12__default.default.join(cwd, "yarn.lock"))) return "yarn";
|
|
1933
|
+
if (fs__default.default.existsSync(path12__default.default.join(cwd, "bun.lockb"))) return "bun";
|
|
1790
1934
|
return "npm";
|
|
1791
1935
|
}
|
|
1792
1936
|
async function installDependencies(projectPath, packageManager = "npm") {
|
|
@@ -1803,16 +1947,16 @@ async function installDependencies(projectPath, packageManager = "npm") {
|
|
|
1803
1947
|
}
|
|
1804
1948
|
});
|
|
1805
1949
|
}
|
|
1806
|
-
var AUTH_DIR =
|
|
1950
|
+
var AUTH_DIR = path12__default.default.join(os__default.default.homedir(), ".onexthm");
|
|
1807
1951
|
var ENV_URLS = {
|
|
1808
1952
|
dev: "https://platform-dev.onexeos.com",
|
|
1809
1953
|
staging: "https://platform-staging.onexeos.com",
|
|
1810
1954
|
prod: "https://platform-apis.onexeos.com"
|
|
1811
1955
|
};
|
|
1812
1956
|
function getAuthFile(env = "dev") {
|
|
1813
|
-
const newFile =
|
|
1957
|
+
const newFile = path12__default.default.join(AUTH_DIR, `auth-${env}.json`);
|
|
1814
1958
|
if (env === "dev") {
|
|
1815
|
-
const legacyFile =
|
|
1959
|
+
const legacyFile = path12__default.default.join(AUTH_DIR, "auth.json");
|
|
1816
1960
|
if (fs__default.default.existsSync(legacyFile) && !fs__default.default.existsSync(newFile)) {
|
|
1817
1961
|
try {
|
|
1818
1962
|
fs__default.default.moveSync(legacyFile, newFile);
|
|
@@ -1939,7 +2083,7 @@ function decrypt(text, key) {
|
|
|
1939
2083
|
}
|
|
1940
2084
|
|
|
1941
2085
|
// src/commands/init.ts
|
|
1942
|
-
async function initCommand(projectName, options
|
|
2086
|
+
async function initCommand(projectName, options) {
|
|
1943
2087
|
exports.logger.header("Create New OneX Theme Project");
|
|
1944
2088
|
let name;
|
|
1945
2089
|
if (!projectName) {
|
|
@@ -1954,7 +2098,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1954
2098
|
if (!validateThemeName(kebabName)) {
|
|
1955
2099
|
return "Invalid project name. Use lowercase letters, numbers, and hyphens only.";
|
|
1956
2100
|
}
|
|
1957
|
-
if (fs3__default.default.existsSync(
|
|
2101
|
+
if (fs3__default.default.existsSync(path12__default.default.join(process.cwd(), kebabName))) {
|
|
1958
2102
|
return `Directory "${kebabName}" already exists`;
|
|
1959
2103
|
}
|
|
1960
2104
|
return true;
|
|
@@ -1965,14 +2109,14 @@ async function initCommand(projectName, options = {}) {
|
|
|
1965
2109
|
} else {
|
|
1966
2110
|
name = toKebabCase(projectName);
|
|
1967
2111
|
}
|
|
1968
|
-
const projectPath =
|
|
2112
|
+
const projectPath = path12__default.default.join(process.cwd(), name);
|
|
1969
2113
|
if (fs3__default.default.existsSync(projectPath)) {
|
|
1970
2114
|
exports.logger.error(`Directory "${name}" already exists.`);
|
|
1971
2115
|
process.exit(1);
|
|
1972
2116
|
}
|
|
1973
2117
|
if (!options.yes) {
|
|
1974
2118
|
try {
|
|
1975
|
-
const apiUrl = getApiUrl(options.env
|
|
2119
|
+
const apiUrl = getApiUrl(options.env);
|
|
1976
2120
|
const controller = new AbortController();
|
|
1977
2121
|
const timeout = setTimeout(() => controller.abort(), 3e3);
|
|
1978
2122
|
const response = await fetch(
|
|
@@ -2081,7 +2225,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
2081
2225
|
description,
|
|
2082
2226
|
author
|
|
2083
2227
|
);
|
|
2084
|
-
const mcpJsonPath =
|
|
2228
|
+
const mcpJsonPath = path12__default.default.join(projectPath, ".mcp.json");
|
|
2085
2229
|
if (fs3__default.default.existsSync(mcpJsonPath)) {
|
|
2086
2230
|
let mcpContent = fs3__default.default.readFileSync(mcpJsonPath, "utf-8");
|
|
2087
2231
|
if (figmaApiKey) {
|
|
@@ -2161,7 +2305,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
2161
2305
|
}
|
|
2162
2306
|
}
|
|
2163
2307
|
async function renameThemeInFiles(projectPath, themeName, displayName, description, author) {
|
|
2164
|
-
const configPath =
|
|
2308
|
+
const configPath = path12__default.default.join(projectPath, "theme.config.ts");
|
|
2165
2309
|
if (fs3__default.default.existsSync(configPath)) {
|
|
2166
2310
|
let content = fs3__default.default.readFileSync(configPath, "utf-8");
|
|
2167
2311
|
content = content.replace(
|
|
@@ -2174,7 +2318,7 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
|
|
|
2174
2318
|
);
|
|
2175
2319
|
fs3__default.default.writeFileSync(configPath, content, "utf-8");
|
|
2176
2320
|
}
|
|
2177
|
-
const pkgPath =
|
|
2321
|
+
const pkgPath = path12__default.default.join(projectPath, "package.json");
|
|
2178
2322
|
if (fs3__default.default.existsSync(pkgPath)) {
|
|
2179
2323
|
let content = fs3__default.default.readFileSync(pkgPath, "utf-8");
|
|
2180
2324
|
content = content.replace(
|
|
@@ -2196,10 +2340,10 @@ async function createSectionCommand(name, options) {
|
|
|
2196
2340
|
ensureOneXProject();
|
|
2197
2341
|
if (!options.theme) {
|
|
2198
2342
|
const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
|
|
2199
|
-
(f) => fs__default.default.existsSync(
|
|
2343
|
+
(f) => fs__default.default.existsSync(path12__default.default.join(process.cwd(), f))
|
|
2200
2344
|
);
|
|
2201
2345
|
if (isStandaloneTheme) {
|
|
2202
|
-
options.theme =
|
|
2346
|
+
options.theme = path12__default.default.basename(process.cwd());
|
|
2203
2347
|
}
|
|
2204
2348
|
}
|
|
2205
2349
|
const sectionName = toKebabCase(name);
|
|
@@ -2262,35 +2406,35 @@ async function createSectionCommand(name, options) {
|
|
|
2262
2406
|
};
|
|
2263
2407
|
exports.logger.startSpinner("Creating section files...");
|
|
2264
2408
|
try {
|
|
2265
|
-
const themePath =
|
|
2266
|
-
const sectionPath =
|
|
2409
|
+
const themePath = path12__default.default.join(getThemesDir(), themeName);
|
|
2410
|
+
const sectionPath = path12__default.default.join(themePath, "sections", sectionName);
|
|
2267
2411
|
const schemaContent = generateSectionSchema(data);
|
|
2268
2412
|
await writeFile(
|
|
2269
|
-
|
|
2413
|
+
path12__default.default.join(sectionPath, `${sectionName}.schema.ts`),
|
|
2270
2414
|
schemaContent
|
|
2271
2415
|
);
|
|
2272
2416
|
if (createTemplate) {
|
|
2273
2417
|
const templateContent = generateSectionTemplate(data);
|
|
2274
2418
|
await writeFile(
|
|
2275
|
-
|
|
2419
|
+
path12__default.default.join(sectionPath, `${sectionName}-default.tsx`),
|
|
2276
2420
|
templateContent
|
|
2277
2421
|
);
|
|
2278
2422
|
}
|
|
2279
2423
|
const indexContent = generateSectionIndex(data, createTemplate);
|
|
2280
|
-
await writeFile(
|
|
2424
|
+
await writeFile(path12__default.default.join(sectionPath, "index.ts"), indexContent);
|
|
2281
2425
|
exports.logger.stopSpinner(true, "Section files created successfully!");
|
|
2282
2426
|
exports.logger.newLine();
|
|
2283
2427
|
exports.logger.section("Next steps:");
|
|
2284
2428
|
exports.logger.log(
|
|
2285
|
-
` 1. Edit schema: ${
|
|
2429
|
+
` 1. Edit schema: ${path12__default.default.relative(process.cwd(), path12__default.default.join(sectionPath, `${sectionName}.schema.ts`))}`
|
|
2286
2430
|
);
|
|
2287
2431
|
if (createTemplate) {
|
|
2288
2432
|
exports.logger.log(
|
|
2289
|
-
` 2. Edit template: ${
|
|
2433
|
+
` 2. Edit template: ${path12__default.default.relative(process.cwd(), path12__default.default.join(sectionPath, `${sectionName}-default.tsx`))}`
|
|
2290
2434
|
);
|
|
2291
2435
|
}
|
|
2292
2436
|
exports.logger.log(
|
|
2293
|
-
` 3. Add to theme manifest: ${
|
|
2437
|
+
` 3. Add to theme manifest: ${path12__default.default.relative(process.cwd(), path12__default.default.join(themePath, "manifest.ts"))}`
|
|
2294
2438
|
);
|
|
2295
2439
|
exports.logger.newLine();
|
|
2296
2440
|
exports.logger.success("Section created successfully!");
|
|
@@ -2438,10 +2582,10 @@ async function createBlockCommand(name, options) {
|
|
|
2438
2582
|
ensureOneXProject();
|
|
2439
2583
|
if (!options.theme) {
|
|
2440
2584
|
const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
|
|
2441
|
-
(f) => fs__default.default.existsSync(
|
|
2585
|
+
(f) => fs__default.default.existsSync(path12__default.default.join(process.cwd(), f))
|
|
2442
2586
|
);
|
|
2443
2587
|
if (isStandaloneTheme) {
|
|
2444
|
-
options.theme =
|
|
2588
|
+
options.theme = path12__default.default.basename(process.cwd());
|
|
2445
2589
|
}
|
|
2446
2590
|
}
|
|
2447
2591
|
const blockName = toKebabCase(name);
|
|
@@ -2516,24 +2660,24 @@ async function createBlockCommand(name, options) {
|
|
|
2516
2660
|
};
|
|
2517
2661
|
exports.logger.startSpinner("Creating block files...");
|
|
2518
2662
|
try {
|
|
2519
|
-
const blockPath = scope === "shared" ?
|
|
2663
|
+
const blockPath = scope === "shared" ? path12__default.default.join(getFeaturesDir(), "blocks", blockName) : path12__default.default.join(getThemesDir(), themeName, "blocks", blockName);
|
|
2520
2664
|
const schemaContent = generateBlockSchema(data);
|
|
2521
2665
|
await writeFile(
|
|
2522
|
-
|
|
2666
|
+
path12__default.default.join(blockPath, `${blockName}.schema.ts`),
|
|
2523
2667
|
schemaContent
|
|
2524
2668
|
);
|
|
2525
2669
|
const componentContent = generateBlockComponent(data);
|
|
2526
|
-
await writeFile(
|
|
2670
|
+
await writeFile(path12__default.default.join(blockPath, `${blockName}.tsx`), componentContent);
|
|
2527
2671
|
const indexContent = generateBlockIndex(data);
|
|
2528
|
-
await writeFile(
|
|
2672
|
+
await writeFile(path12__default.default.join(blockPath, "index.ts"), indexContent);
|
|
2529
2673
|
exports.logger.stopSpinner(true, "Block files created successfully!");
|
|
2530
2674
|
exports.logger.newLine();
|
|
2531
2675
|
exports.logger.section("Next steps:");
|
|
2532
2676
|
exports.logger.log(
|
|
2533
|
-
` 1. Edit schema: ${
|
|
2677
|
+
` 1. Edit schema: ${path12__default.default.relative(process.cwd(), path12__default.default.join(blockPath, `${blockName}.schema.ts`))}`
|
|
2534
2678
|
);
|
|
2535
2679
|
exports.logger.log(
|
|
2536
|
-
` 2. Edit component: ${
|
|
2680
|
+
` 2. Edit component: ${path12__default.default.relative(process.cwd(), path12__default.default.join(blockPath, `${blockName}.tsx`))}`
|
|
2537
2681
|
);
|
|
2538
2682
|
exports.logger.log(
|
|
2539
2683
|
` 3. Register in block registry: src/lib/registry/block-registry.ts`
|
|
@@ -2711,31 +2855,31 @@ async function createComponentCommand(name, options) {
|
|
|
2711
2855
|
};
|
|
2712
2856
|
exports.logger.startSpinner("Creating component files...");
|
|
2713
2857
|
try {
|
|
2714
|
-
const componentPath =
|
|
2858
|
+
const componentPath = path12__default.default.join(
|
|
2715
2859
|
getFeaturesDir(),
|
|
2716
2860
|
"components",
|
|
2717
2861
|
componentName
|
|
2718
2862
|
);
|
|
2719
2863
|
const schemaContent = generateComponentSchema(data);
|
|
2720
2864
|
await writeFile(
|
|
2721
|
-
|
|
2865
|
+
path12__default.default.join(componentPath, `${componentName}.schema.ts`),
|
|
2722
2866
|
schemaContent
|
|
2723
2867
|
);
|
|
2724
2868
|
const componentContent = generateComponent(data);
|
|
2725
2869
|
await writeFile(
|
|
2726
|
-
|
|
2870
|
+
path12__default.default.join(componentPath, `${componentName}.tsx`),
|
|
2727
2871
|
componentContent
|
|
2728
2872
|
);
|
|
2729
2873
|
const indexContent = generateComponentIndex(data);
|
|
2730
|
-
await writeFile(
|
|
2874
|
+
await writeFile(path12__default.default.join(componentPath, "index.ts"), indexContent);
|
|
2731
2875
|
exports.logger.stopSpinner(true, "Component files created successfully!");
|
|
2732
2876
|
exports.logger.newLine();
|
|
2733
2877
|
exports.logger.section("Next steps:");
|
|
2734
2878
|
exports.logger.log(
|
|
2735
|
-
` 1. Edit schema: ${
|
|
2879
|
+
` 1. Edit schema: ${path12__default.default.relative(process.cwd(), path12__default.default.join(componentPath, `${componentName}.schema.ts`))}`
|
|
2736
2880
|
);
|
|
2737
2881
|
exports.logger.log(
|
|
2738
|
-
` 2. Edit component: ${
|
|
2882
|
+
` 2. Edit component: ${path12__default.default.relative(process.cwd(), path12__default.default.join(componentPath, `${componentName}.tsx`))}`
|
|
2739
2883
|
);
|
|
2740
2884
|
exports.logger.log(
|
|
2741
2885
|
` 3. Register in component registry: src/lib/registry/component-registry.ts`
|
|
@@ -2892,13 +3036,13 @@ async function listSections(themeFilter) {
|
|
|
2892
3036
|
return;
|
|
2893
3037
|
}
|
|
2894
3038
|
for (const theme of themes) {
|
|
2895
|
-
const sectionsDir =
|
|
3039
|
+
const sectionsDir = path12__default.default.join(getThemesDir(), theme, "sections");
|
|
2896
3040
|
if (!fs__default.default.existsSync(sectionsDir)) {
|
|
2897
3041
|
continue;
|
|
2898
3042
|
}
|
|
2899
3043
|
const sections = fs__default.default.readdirSync(sectionsDir).filter((name) => {
|
|
2900
|
-
const sectionPath =
|
|
2901
|
-
return fs__default.default.statSync(sectionPath).isDirectory() && fs__default.default.existsSync(
|
|
3044
|
+
const sectionPath = path12__default.default.join(sectionsDir, name);
|
|
3045
|
+
return fs__default.default.statSync(sectionPath).isDirectory() && fs__default.default.existsSync(path12__default.default.join(sectionPath, "index.ts"));
|
|
2902
3046
|
});
|
|
2903
3047
|
if (sections.length > 0) {
|
|
2904
3048
|
exports.logger.log(chalk4__default.default.cyan(`
|
|
@@ -2912,11 +3056,11 @@ async function listSections(themeFilter) {
|
|
|
2912
3056
|
}
|
|
2913
3057
|
async function listBlocks(themeFilter) {
|
|
2914
3058
|
exports.logger.section("\u{1F9F1} Blocks");
|
|
2915
|
-
const sharedBlocksDir =
|
|
3059
|
+
const sharedBlocksDir = path12__default.default.join(getFeaturesDir(), "blocks");
|
|
2916
3060
|
if (fs__default.default.existsSync(sharedBlocksDir)) {
|
|
2917
3061
|
const sharedBlocks = fs__default.default.readdirSync(sharedBlocksDir).filter((name) => {
|
|
2918
|
-
const blockPath =
|
|
2919
|
-
return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(
|
|
3062
|
+
const blockPath = path12__default.default.join(sharedBlocksDir, name);
|
|
3063
|
+
return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path12__default.default.join(blockPath, "index.ts"));
|
|
2920
3064
|
});
|
|
2921
3065
|
if (sharedBlocks.length > 0) {
|
|
2922
3066
|
exports.logger.log(chalk4__default.default.cyan("\n Shared:"));
|
|
@@ -2927,13 +3071,13 @@ async function listBlocks(themeFilter) {
|
|
|
2927
3071
|
}
|
|
2928
3072
|
const themes = themeFilter ? [themeFilter] : listThemes();
|
|
2929
3073
|
for (const theme of themes) {
|
|
2930
|
-
const blocksDir =
|
|
3074
|
+
const blocksDir = path12__default.default.join(getThemesDir(), theme, "blocks");
|
|
2931
3075
|
if (!fs__default.default.existsSync(blocksDir)) {
|
|
2932
3076
|
continue;
|
|
2933
3077
|
}
|
|
2934
3078
|
const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => {
|
|
2935
|
-
const blockPath =
|
|
2936
|
-
return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(
|
|
3079
|
+
const blockPath = path12__default.default.join(blocksDir, name);
|
|
3080
|
+
return fs__default.default.statSync(blockPath).isDirectory() && fs__default.default.existsSync(path12__default.default.join(blockPath, "index.ts"));
|
|
2937
3081
|
});
|
|
2938
3082
|
if (blocks.length > 0) {
|
|
2939
3083
|
exports.logger.log(chalk4__default.default.cyan(`
|
|
@@ -2947,14 +3091,14 @@ async function listBlocks(themeFilter) {
|
|
|
2947
3091
|
}
|
|
2948
3092
|
async function listComponents() {
|
|
2949
3093
|
exports.logger.section("\u2699\uFE0F Components");
|
|
2950
|
-
const componentsDir =
|
|
3094
|
+
const componentsDir = path12__default.default.join(getFeaturesDir(), "components");
|
|
2951
3095
|
if (!fs__default.default.existsSync(componentsDir)) {
|
|
2952
3096
|
exports.logger.warning("No components directory found");
|
|
2953
3097
|
return;
|
|
2954
3098
|
}
|
|
2955
3099
|
const components = fs__default.default.readdirSync(componentsDir).filter((name) => {
|
|
2956
|
-
const componentPath =
|
|
2957
|
-
return fs__default.default.statSync(componentPath).isDirectory() && fs__default.default.existsSync(
|
|
3100
|
+
const componentPath = path12__default.default.join(componentsDir, name);
|
|
3101
|
+
return fs__default.default.statSync(componentPath).isDirectory() && fs__default.default.existsSync(path12__default.default.join(componentPath, "index.ts"));
|
|
2958
3102
|
});
|
|
2959
3103
|
if (components.length === 0) {
|
|
2960
3104
|
exports.logger.warning("No components found");
|
|
@@ -2975,11 +3119,11 @@ async function listThemesInfo() {
|
|
|
2975
3119
|
}
|
|
2976
3120
|
exports.logger.log("");
|
|
2977
3121
|
for (const theme of themes) {
|
|
2978
|
-
const themeDir =
|
|
3122
|
+
const themeDir = path12__default.default.join(getThemesDir(), theme);
|
|
2979
3123
|
const candidates = ["theme.config.ts", "bundle-entry.ts", "manifest.ts"];
|
|
2980
3124
|
let manifestContent = "";
|
|
2981
3125
|
for (const candidate of candidates) {
|
|
2982
|
-
const candidatePath =
|
|
3126
|
+
const candidatePath = path12__default.default.join(themeDir, candidate);
|
|
2983
3127
|
if (fs__default.default.existsSync(candidatePath)) {
|
|
2984
3128
|
manifestContent = fs__default.default.readFileSync(candidatePath, "utf-8");
|
|
2985
3129
|
break;
|
|
@@ -3001,6 +3145,7 @@ async function listThemesInfo() {
|
|
|
3001
3145
|
|
|
3002
3146
|
// src/commands/build.ts
|
|
3003
3147
|
init_logger();
|
|
3148
|
+
init_detect_nextjs();
|
|
3004
3149
|
async function buildCommand(options) {
|
|
3005
3150
|
exports.logger.header("Build Theme");
|
|
3006
3151
|
let themePath;
|
|
@@ -3008,14 +3153,14 @@ async function buildCommand(options) {
|
|
|
3008
3153
|
if (options.theme) {
|
|
3009
3154
|
themeName = options.theme;
|
|
3010
3155
|
try {
|
|
3011
|
-
const workspaceThemePath =
|
|
3156
|
+
const workspaceThemePath = path12__default.default.join(getThemesDir(), themeName);
|
|
3012
3157
|
if (fs__default.default.existsSync(workspaceThemePath)) {
|
|
3013
3158
|
themePath = workspaceThemePath;
|
|
3014
3159
|
} else {
|
|
3015
|
-
themePath =
|
|
3160
|
+
themePath = path12__default.default.join(process.cwd(), themeName);
|
|
3016
3161
|
}
|
|
3017
3162
|
} catch {
|
|
3018
|
-
themePath =
|
|
3163
|
+
themePath = path12__default.default.join(process.cwd(), themeName);
|
|
3019
3164
|
}
|
|
3020
3165
|
if (!fs__default.default.existsSync(themePath)) {
|
|
3021
3166
|
exports.logger.error(`Theme "${themeName}" not found.`);
|
|
@@ -3025,11 +3170,14 @@ async function buildCommand(options) {
|
|
|
3025
3170
|
const isThemeDir = [
|
|
3026
3171
|
"theme.config.ts",
|
|
3027
3172
|
"bundle-entry.ts",
|
|
3028
|
-
"manifest.ts"
|
|
3029
|
-
|
|
3173
|
+
"manifest.ts",
|
|
3174
|
+
"next.config.ts",
|
|
3175
|
+
"next.config.js",
|
|
3176
|
+
"next.config.mjs"
|
|
3177
|
+
].some((f) => fs__default.default.existsSync(path12__default.default.join(process.cwd(), f)));
|
|
3030
3178
|
if (isThemeDir) {
|
|
3031
3179
|
themePath = process.cwd();
|
|
3032
|
-
themeName =
|
|
3180
|
+
themeName = path12__default.default.basename(themePath);
|
|
3033
3181
|
exports.logger.info(`Building current theme: ${themeName}`);
|
|
3034
3182
|
} else {
|
|
3035
3183
|
exports.logger.error(
|
|
@@ -3038,7 +3186,7 @@ async function buildCommand(options) {
|
|
|
3038
3186
|
process.exit(1);
|
|
3039
3187
|
}
|
|
3040
3188
|
}
|
|
3041
|
-
const packageJsonPath =
|
|
3189
|
+
const packageJsonPath = path12__default.default.join(themePath, "package.json");
|
|
3042
3190
|
const hasPkgJson = fs__default.default.existsSync(packageJsonPath);
|
|
3043
3191
|
if (!hasPkgJson) {
|
|
3044
3192
|
exports.logger.warning(
|
|
@@ -3054,30 +3202,42 @@ async function buildCommand(options) {
|
|
|
3054
3202
|
}
|
|
3055
3203
|
exports.logger.newLine();
|
|
3056
3204
|
exports.logger.section("Build Steps");
|
|
3057
|
-
exports.logger.startSpinner("Running type check...");
|
|
3058
|
-
const typeCheckSuccess = await runCommand("pnpm", ["type-check"], themePath);
|
|
3059
|
-
if (!typeCheckSuccess) {
|
|
3060
|
-
exports.logger.stopSpinner(false, "Type check failed");
|
|
3061
|
-
exports.logger.error("Fix type errors before building.");
|
|
3062
|
-
process.exit(1);
|
|
3063
|
-
}
|
|
3064
|
-
exports.logger.stopSpinner(true, "Type check passed");
|
|
3065
|
-
exports.logger.startSpinner("Running linter...");
|
|
3066
|
-
const lintSuccess = await runCommand("pnpm", ["lint"], themePath);
|
|
3067
|
-
if (!lintSuccess) {
|
|
3068
|
-
exports.logger.stopSpinner(false, "Lint failed");
|
|
3069
|
-
exports.logger.error("Fix lint errors before building.");
|
|
3070
|
-
process.exit(1);
|
|
3071
|
-
}
|
|
3072
|
-
exports.logger.stopSpinner(true, "Lint passed");
|
|
3073
3205
|
const pkgJson = fs__default.default.readJsonSync(packageJsonPath);
|
|
3206
|
+
if (pkgJson.scripts?.["type-check"]) {
|
|
3207
|
+
exports.logger.startSpinner("Running type check...");
|
|
3208
|
+
const typeCheckSuccess = await runCommand("pnpm", ["type-check"], themePath);
|
|
3209
|
+
if (!typeCheckSuccess) {
|
|
3210
|
+
exports.logger.stopSpinner(false, "Type check failed");
|
|
3211
|
+
exports.logger.error("Fix type errors before building.");
|
|
3212
|
+
process.exit(1);
|
|
3213
|
+
}
|
|
3214
|
+
exports.logger.stopSpinner(true, "Type check passed");
|
|
3215
|
+
} else {
|
|
3216
|
+
exports.logger.info("Skipping type check (no type-check script in package.json)");
|
|
3217
|
+
}
|
|
3218
|
+
const isNextjsForLint = isNextjsProject(themePath);
|
|
3219
|
+
if (!isNextjsForLint && pkgJson.scripts?.lint) {
|
|
3220
|
+
exports.logger.startSpinner("Running linter...");
|
|
3221
|
+
const lintSuccess = await runCommand("pnpm", ["lint"], themePath);
|
|
3222
|
+
if (!lintSuccess) {
|
|
3223
|
+
exports.logger.stopSpinner(false, "Lint failed");
|
|
3224
|
+
exports.logger.error("Fix lint errors before building.");
|
|
3225
|
+
process.exit(1);
|
|
3226
|
+
}
|
|
3227
|
+
exports.logger.stopSpinner(true, "Lint passed");
|
|
3228
|
+
} else if (isNextjsForLint) {
|
|
3229
|
+
exports.logger.info("Skipping lint (Next.js project compiled via esbuild)");
|
|
3230
|
+
} else {
|
|
3231
|
+
exports.logger.info("Skipping lint (no lint script in package.json)");
|
|
3232
|
+
}
|
|
3074
3233
|
const buildScript = pkgJson.scripts?.build || "";
|
|
3075
3234
|
const isRecursive = buildScript.includes("onexthm build") || buildScript.includes("onex build") || buildScript.includes("onex-cli build");
|
|
3235
|
+
const isNextjs = isNextjsProject(themePath);
|
|
3076
3236
|
exports.logger.startSpinner(
|
|
3077
3237
|
options.watch ? "Building (watch mode)..." : "Building..."
|
|
3078
3238
|
);
|
|
3079
3239
|
let buildSuccess;
|
|
3080
|
-
if (isRecursive) {
|
|
3240
|
+
if (isRecursive || isNextjs) {
|
|
3081
3241
|
const { compileStandaloneTheme: compileStandaloneTheme2 } = await Promise.resolve().then(() => (init_compile_theme(), compile_theme_exports));
|
|
3082
3242
|
buildSuccess = await compileStandaloneTheme2(themePath, themeName);
|
|
3083
3243
|
} else {
|
|
@@ -3094,9 +3254,9 @@ async function buildCommand(options) {
|
|
|
3094
3254
|
exports.logger.success("\u2713 Theme built successfully!");
|
|
3095
3255
|
exports.logger.newLine();
|
|
3096
3256
|
exports.logger.info(`Theme: ${themeName}`);
|
|
3097
|
-
const distPath =
|
|
3257
|
+
const distPath = path12__default.default.join(themePath, "dist");
|
|
3098
3258
|
if (fs__default.default.existsSync(distPath)) {
|
|
3099
|
-
exports.logger.log(`Output: ${
|
|
3259
|
+
exports.logger.log(`Output: ${path12__default.default.relative(process.cwd(), distPath)}`);
|
|
3100
3260
|
const files = fs__default.default.readdirSync(distPath);
|
|
3101
3261
|
exports.logger.log(`Files: ${files.length}`);
|
|
3102
3262
|
}
|
|
@@ -3237,8 +3397,8 @@ async function downloadBundleZip(apiUrl, themeId, version) {
|
|
|
3237
3397
|
async function createCompatibilityFiles(outputDir, manifest) {
|
|
3238
3398
|
const entryFile = manifest.output?.entry || "bundle-entry.js";
|
|
3239
3399
|
if (entryFile !== "bundle-entry.js" && entryFile.startsWith("bundle-entry-")) {
|
|
3240
|
-
const hashedPath =
|
|
3241
|
-
const stablePath =
|
|
3400
|
+
const hashedPath = path12__default.default.join(outputDir, entryFile);
|
|
3401
|
+
const stablePath = path12__default.default.join(outputDir, "bundle-entry.js");
|
|
3242
3402
|
if (await fs__default.default.pathExists(hashedPath)) {
|
|
3243
3403
|
await fs__default.default.copy(hashedPath, stablePath);
|
|
3244
3404
|
const mapPath = hashedPath + ".map";
|
|
@@ -3247,13 +3407,13 @@ async function createCompatibilityFiles(outputDir, manifest) {
|
|
|
3247
3407
|
}
|
|
3248
3408
|
}
|
|
3249
3409
|
}
|
|
3250
|
-
const sectionsRegistryPath =
|
|
3410
|
+
const sectionsRegistryPath = path12__default.default.join(outputDir, "sections-registry.js");
|
|
3251
3411
|
const content = `// Re-export all sections from bundle-entry
|
|
3252
3412
|
// This file exists to maintain compatibility with the import path
|
|
3253
3413
|
export * from './bundle-entry.js';
|
|
3254
3414
|
`;
|
|
3255
3415
|
await fs__default.default.writeFile(sectionsRegistryPath, content, "utf-8");
|
|
3256
|
-
const pkgJsonPath =
|
|
3416
|
+
const pkgJsonPath = path12__default.default.join(outputDir, "package.json");
|
|
3257
3417
|
await fs__default.default.writeFile(pkgJsonPath, '{\n "type": "module"\n}\n', "utf-8");
|
|
3258
3418
|
}
|
|
3259
3419
|
function showDownloadFailureHelp(themeId, apiUrl) {
|
|
@@ -3294,7 +3454,7 @@ function showDownloadFailureHelp(themeId, apiUrl) {
|
|
|
3294
3454
|
}
|
|
3295
3455
|
async function downloadCommand(options) {
|
|
3296
3456
|
exports.logger.header("Download Theme");
|
|
3297
|
-
const env = options.env
|
|
3457
|
+
const env = options.env;
|
|
3298
3458
|
const apiUrl = getApiUrl(env);
|
|
3299
3459
|
exports.logger.info(`Environment: ${env} (${apiUrl})`);
|
|
3300
3460
|
const spinner = ora__default.default("Initializing download...").start();
|
|
@@ -3352,7 +3512,7 @@ async function downloadCommand(options) {
|
|
|
3352
3512
|
zip.extractAllTo(outputDir, true);
|
|
3353
3513
|
const entries = zip.getEntries().filter((e) => !e.isDirectory);
|
|
3354
3514
|
spinner.succeed(`Extracted ${entries.length} files to ${outputDir}`);
|
|
3355
|
-
const manifestPath =
|
|
3515
|
+
const manifestPath = path12__default.default.join(outputDir, "manifest.json");
|
|
3356
3516
|
const manifest = await fs__default.default.readJson(manifestPath);
|
|
3357
3517
|
await createCompatibilityFiles(outputDir, manifest);
|
|
3358
3518
|
console.log();
|
|
@@ -3473,7 +3633,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3473
3633
|
const oldPrefix = `${oldName}-`;
|
|
3474
3634
|
const newPrefix = `${newName}-`;
|
|
3475
3635
|
const newDisplayName = newName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3476
|
-
const pkgPath =
|
|
3636
|
+
const pkgPath = path12__default.default.join(themeDir, "package.json");
|
|
3477
3637
|
if (await fs__default.default.pathExists(pkgPath)) {
|
|
3478
3638
|
const pkg = await fs__default.default.readJson(pkgPath);
|
|
3479
3639
|
pkg.name = `@onex-themes/${newName}`;
|
|
@@ -3489,7 +3649,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3489
3649
|
}
|
|
3490
3650
|
await fs__default.default.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
3491
3651
|
}
|
|
3492
|
-
const configPath =
|
|
3652
|
+
const configPath = path12__default.default.join(themeDir, "theme.config.ts");
|
|
3493
3653
|
if (await fs__default.default.pathExists(configPath)) {
|
|
3494
3654
|
let content = await fs__default.default.readFile(configPath, "utf-8");
|
|
3495
3655
|
content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
|
|
@@ -3499,7 +3659,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3499
3659
|
);
|
|
3500
3660
|
await fs__default.default.writeFile(configPath, content);
|
|
3501
3661
|
}
|
|
3502
|
-
const layoutPath =
|
|
3662
|
+
const layoutPath = path12__default.default.join(themeDir, "theme.layout.ts");
|
|
3503
3663
|
if (await fs__default.default.pathExists(layoutPath)) {
|
|
3504
3664
|
let content = await fs__default.default.readFile(layoutPath, "utf-8");
|
|
3505
3665
|
content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
|
|
@@ -3512,7 +3672,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3512
3672
|
const oldDisplayName = oldName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3513
3673
|
const tsFiles = await glob.glob("**/*.ts", { cwd: themeDir, nodir: true });
|
|
3514
3674
|
for (const file of tsFiles) {
|
|
3515
|
-
const filePath =
|
|
3675
|
+
const filePath = path12__default.default.join(themeDir, file);
|
|
3516
3676
|
let content = await fs__default.default.readFile(filePath, "utf-8");
|
|
3517
3677
|
const original = content;
|
|
3518
3678
|
content = content.replace(
|
|
@@ -3534,7 +3694,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3534
3694
|
}
|
|
3535
3695
|
async function cloneCommand(themeName, options) {
|
|
3536
3696
|
exports.logger.header("Clone Theme Source");
|
|
3537
|
-
const env = options.env
|
|
3697
|
+
const env = options.env;
|
|
3538
3698
|
const apiUrl = getApiUrl(env);
|
|
3539
3699
|
exports.logger.info(`Environment: ${env} (${apiUrl})`);
|
|
3540
3700
|
if (options.bucket) {
|
|
@@ -3555,7 +3715,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3555
3715
|
}
|
|
3556
3716
|
const spinner = ora__default.default("Initializing clone...").start();
|
|
3557
3717
|
try {
|
|
3558
|
-
const outputDir = options.output ||
|
|
3718
|
+
const outputDir = options.output || path12__default.default.resolve(process.cwd(), newName);
|
|
3559
3719
|
if (await fs__default.default.pathExists(outputDir)) {
|
|
3560
3720
|
spinner.fail(chalk4__default.default.red(`Directory already exists: ${outputDir}`));
|
|
3561
3721
|
exports.logger.info(
|
|
@@ -3601,7 +3761,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3601
3761
|
spinner.succeed(
|
|
3602
3762
|
`Renamed theme: ${chalk4__default.default.gray(themeName)} \u2192 ${chalk4__default.default.cyan(newName)}`
|
|
3603
3763
|
);
|
|
3604
|
-
const envExamplePath =
|
|
3764
|
+
const envExamplePath = path12__default.default.join(outputDir, ".env.example");
|
|
3605
3765
|
if (!await fs__default.default.pathExists(envExamplePath)) {
|
|
3606
3766
|
await fs__default.default.writeFile(
|
|
3607
3767
|
envExamplePath,
|
|
@@ -3614,7 +3774,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3614
3774
|
].join("\n")
|
|
3615
3775
|
);
|
|
3616
3776
|
}
|
|
3617
|
-
const mcpJsonPath =
|
|
3777
|
+
const mcpJsonPath = path12__default.default.join(outputDir, ".mcp.json");
|
|
3618
3778
|
if (await fs__default.default.pathExists(mcpJsonPath)) {
|
|
3619
3779
|
const { default: inquirerMod } = await import('inquirer');
|
|
3620
3780
|
const { figmaApiKey } = await inquirerMod.prompt([
|
|
@@ -3639,7 +3799,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3639
3799
|
}
|
|
3640
3800
|
if (options.install !== false) {
|
|
3641
3801
|
const hasPkgJson = await fs__default.default.pathExists(
|
|
3642
|
-
|
|
3802
|
+
path12__default.default.join(outputDir, "package.json")
|
|
3643
3803
|
);
|
|
3644
3804
|
if (hasPkgJson) {
|
|
3645
3805
|
spinner.start("Installing dependencies...");
|
|
@@ -3667,7 +3827,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3667
3827
|
console.log(chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(entries.length));
|
|
3668
3828
|
console.log();
|
|
3669
3829
|
console.log(chalk4__default.default.cyan("Next steps:"));
|
|
3670
|
-
console.log(chalk4__default.default.gray(` cd ${
|
|
3830
|
+
console.log(chalk4__default.default.gray(` cd ${path12__default.default.relative(process.cwd(), outputDir)}`));
|
|
3671
3831
|
console.log(
|
|
3672
3832
|
chalk4__default.default.gray(" cp .env.example .env # then add your Company ID")
|
|
3673
3833
|
);
|