@onexapis/cli 1.1.65 → 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/README.md +1 -1
- package/dist/cli.js +1688 -801
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +1684 -797
- package/dist/cli.mjs.map +1 -1
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +784 -405
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +779 -400
- package/dist/index.mjs.map +1 -1
- package/dist/preview/preview-app.tsx +89 -7
- package/package.json +2 -2
- package/templates/default/package.json +5 -0
package/dist/index.js
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
var chalk4 = require('chalk');
|
|
4
4
|
var ora = require('ora');
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var fs7 = require('fs/promises');
|
|
8
|
-
var crypto = require('crypto');
|
|
5
|
+
var fs3 = require('fs');
|
|
6
|
+
var path12 = require('path');
|
|
9
7
|
var glob = require('glob');
|
|
8
|
+
var fs = require('fs-extra');
|
|
9
|
+
var crypto = require('crypto');
|
|
10
|
+
var fs10 = require('fs/promises');
|
|
11
|
+
var esbuild = require('esbuild');
|
|
10
12
|
var module$1 = require('module');
|
|
11
|
-
var fs3 = require('fs');
|
|
12
13
|
var child_process = require('child_process');
|
|
13
14
|
var inquirer = require('inquirer');
|
|
14
|
-
var fs = require('fs-extra');
|
|
15
15
|
var ejs = require('ejs');
|
|
16
16
|
var os = require('os');
|
|
17
17
|
var AdmZip = require('adm-zip');
|
|
@@ -39,13 +39,13 @@ function _interopNamespace(e) {
|
|
|
39
39
|
|
|
40
40
|
var chalk4__default = /*#__PURE__*/_interopDefault(chalk4);
|
|
41
41
|
var ora__default = /*#__PURE__*/_interopDefault(ora);
|
|
42
|
-
var esbuild__namespace = /*#__PURE__*/_interopNamespace(esbuild);
|
|
43
|
-
var path8__default = /*#__PURE__*/_interopDefault(path8);
|
|
44
|
-
var fs7__default = /*#__PURE__*/_interopDefault(fs7);
|
|
45
|
-
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
46
42
|
var fs3__default = /*#__PURE__*/_interopDefault(fs3);
|
|
47
|
-
var
|
|
43
|
+
var path12__default = /*#__PURE__*/_interopDefault(path12);
|
|
48
44
|
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
45
|
+
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
46
|
+
var fs10__default = /*#__PURE__*/_interopDefault(fs10);
|
|
47
|
+
var esbuild__namespace = /*#__PURE__*/_interopNamespace(esbuild);
|
|
48
|
+
var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
|
|
49
49
|
var ejs__default = /*#__PURE__*/_interopDefault(ejs);
|
|
50
50
|
var os__default = /*#__PURE__*/_interopDefault(os);
|
|
51
51
|
var AdmZip__default = /*#__PURE__*/_interopDefault(AdmZip);
|
|
@@ -121,6 +121,289 @@ 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
|
+
});
|
|
131
|
+
function sortedCopy(value) {
|
|
132
|
+
if (Array.isArray(value)) {
|
|
133
|
+
return value.map((v) => sortedCopy(v));
|
|
134
|
+
}
|
|
135
|
+
if (value && typeof value === "object") {
|
|
136
|
+
const sorted = {};
|
|
137
|
+
for (const key of Object.keys(value).sort()) {
|
|
138
|
+
sorted[key] = sortedCopy(value[key]);
|
|
139
|
+
}
|
|
140
|
+
return sorted;
|
|
141
|
+
}
|
|
142
|
+
return value;
|
|
143
|
+
}
|
|
144
|
+
function normalizeField(raw) {
|
|
145
|
+
const out = {
|
|
146
|
+
id: String(raw.id),
|
|
147
|
+
type: String(raw.type)
|
|
148
|
+
};
|
|
149
|
+
if (raw.required === true) out.required = true;
|
|
150
|
+
if (raw.default !== void 0) out.default = raw.default;
|
|
151
|
+
if (Array.isArray(raw.aliases) && raw.aliases.length > 0) {
|
|
152
|
+
out.aliases = [...raw.aliases].map(String).sort();
|
|
153
|
+
}
|
|
154
|
+
if (typeof raw.maxLength === "number") out.maxLength = raw.maxLength;
|
|
155
|
+
if (typeof raw.min === "number") out.min = raw.min;
|
|
156
|
+
if (typeof raw.max === "number") out.max = raw.max;
|
|
157
|
+
if (typeof raw.step === "number") out.step = raw.step;
|
|
158
|
+
if (Array.isArray(raw.accept)) {
|
|
159
|
+
out.accept = [...raw.accept].map(String).sort();
|
|
160
|
+
}
|
|
161
|
+
if (Array.isArray(raw.options)) {
|
|
162
|
+
out.options = raw.options.map((o) => String(o?.value ?? o)).sort();
|
|
163
|
+
}
|
|
164
|
+
return out;
|
|
165
|
+
}
|
|
166
|
+
function normalizeBlock(raw) {
|
|
167
|
+
return {
|
|
168
|
+
type: String(raw.type),
|
|
169
|
+
settings: Array.isArray(raw.settings) ? raw.settings.map(normalizeField).sort(sortFieldsById) : [],
|
|
170
|
+
defaults: raw.defaults && typeof raw.defaults === "object" ? sortedCopy(raw.defaults) : {},
|
|
171
|
+
...typeof raw.limit === "number" ? { limit: raw.limit } : {},
|
|
172
|
+
...typeof raw.min === "number" ? { min: raw.min } : {},
|
|
173
|
+
...raw.sortable === true ? { sortable: true } : {},
|
|
174
|
+
...raw.baseType ? { baseType: String(raw.baseType) } : {}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function normalizeTemplate(raw) {
|
|
178
|
+
const out = { id: String(raw.id) };
|
|
179
|
+
if (raw.isDefault === true) out.isDefault = true;
|
|
180
|
+
if (Array.isArray(raw.settings)) {
|
|
181
|
+
out.settings = raw.settings.map(normalizeField).sort(sortFieldsById);
|
|
182
|
+
}
|
|
183
|
+
if (raw.defaults && typeof raw.defaults === "object") {
|
|
184
|
+
out.defaults = sortedCopy(raw.defaults);
|
|
185
|
+
}
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
function sortFieldsById(a, b) {
|
|
189
|
+
return a.id.localeCompare(b.id);
|
|
190
|
+
}
|
|
191
|
+
function sortByType(a, b) {
|
|
192
|
+
return a.type.localeCompare(b.type);
|
|
193
|
+
}
|
|
194
|
+
function normalizeSection(raw) {
|
|
195
|
+
return {
|
|
196
|
+
type: String(raw.type),
|
|
197
|
+
settings: Array.isArray(raw.settings) ? raw.settings.map(normalizeField).sort(sortFieldsById) : [],
|
|
198
|
+
defaults: raw.defaults && typeof raw.defaults === "object" ? sortedCopy(raw.defaults) : {},
|
|
199
|
+
blocks: Array.isArray(raw.blocks) ? raw.blocks.map(normalizeBlock).sort(sortByType) : [],
|
|
200
|
+
templates: Array.isArray(raw.templates) ? raw.templates.map(normalizeTemplate).sort(sortFieldsById) : [],
|
|
201
|
+
dataRequirements: raw.dataRequirements && typeof raw.dataRequirements === "object" ? sortedCopy(raw.dataRequirements) : null,
|
|
202
|
+
...raw.global === true ? { global: true } : {},
|
|
203
|
+
...typeof raw.maxBlocks === "number" ? { maxBlocks: raw.maxBlocks } : {}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
async function extractSchemas(themePath) {
|
|
207
|
+
const { createJiti } = await import('jiti');
|
|
208
|
+
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)));
|
|
209
|
+
const schemaFiles = await glob.glob("sections/**/*.schema.ts", { cwd: themePath });
|
|
210
|
+
const sections = {};
|
|
211
|
+
for (const file of schemaFiles) {
|
|
212
|
+
try {
|
|
213
|
+
const mod = await jiti.import(path12__default.default.join(themePath, file));
|
|
214
|
+
const exports$1 = mod;
|
|
215
|
+
for (const value of Object.values(exports$1)) {
|
|
216
|
+
if (value && typeof value === "object" && typeof value.type === "string" && Array.isArray(value.settings)) {
|
|
217
|
+
const section = normalizeSection(value);
|
|
218
|
+
sections[section.type] = section;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
} catch {
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
const manifest = {
|
|
225
|
+
manifestVersion: 1,
|
|
226
|
+
sections: {}
|
|
227
|
+
};
|
|
228
|
+
for (const type of Object.keys(sections).sort()) {
|
|
229
|
+
manifest.sections[type] = sections[type];
|
|
230
|
+
}
|
|
231
|
+
return manifest;
|
|
232
|
+
}
|
|
233
|
+
function serializeManifest(manifest) {
|
|
234
|
+
return JSON.stringify(sortedCopy(manifest), null, 2);
|
|
235
|
+
}
|
|
236
|
+
var init_extract_schemas = __esm({
|
|
237
|
+
"src/utils/extract-schemas.ts"() {
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
function mimeFor(filename) {
|
|
241
|
+
const ext = path12__default.default.extname(filename).toLowerCase();
|
|
242
|
+
return MIME_MAP[ext] || "application/octet-stream";
|
|
243
|
+
}
|
|
244
|
+
async function sha256Prefix(absPath, len) {
|
|
245
|
+
const buf = await fs__default.default.readFile(absPath);
|
|
246
|
+
return crypto__default.default.createHash("sha256").update(buf).digest("hex").slice(0, len);
|
|
247
|
+
}
|
|
248
|
+
function insertHashIntoName(relPath, hash) {
|
|
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);
|
|
252
|
+
const stem = ext ? base.slice(0, -ext.length) : base;
|
|
253
|
+
const hashed = `${stem}-${hash}${ext}`;
|
|
254
|
+
return dir === "." ? hashed : `${dir}/${hashed}`;
|
|
255
|
+
}
|
|
256
|
+
async function scanThemeAssets(distDir) {
|
|
257
|
+
const assetsDir = path12__default.default.join(distDir, "theme-assets");
|
|
258
|
+
if (!await fs__default.default.pathExists(assetsDir)) return [];
|
|
259
|
+
const files = await glob.glob("**/*", {
|
|
260
|
+
cwd: assetsDir,
|
|
261
|
+
nodir: true,
|
|
262
|
+
dot: false
|
|
263
|
+
});
|
|
264
|
+
const results = [];
|
|
265
|
+
for (const rel of files) {
|
|
266
|
+
const absPath = path12__default.default.join(assetsDir, rel);
|
|
267
|
+
const stat = await fs__default.default.stat(absPath);
|
|
268
|
+
if (!stat.isFile()) continue;
|
|
269
|
+
const originalPath = rel.split(path12__default.default.sep).join("/");
|
|
270
|
+
const hash = await sha256Prefix(absPath, HASH_LEN);
|
|
271
|
+
const hashedPath = insertHashIntoName(originalPath, hash);
|
|
272
|
+
const contentType = mimeFor(rel);
|
|
273
|
+
results.push({
|
|
274
|
+
originalPath,
|
|
275
|
+
hashedPath,
|
|
276
|
+
hash,
|
|
277
|
+
size: stat.size,
|
|
278
|
+
contentType,
|
|
279
|
+
absPath
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
results.sort((a, b) => a.originalPath.localeCompare(b.originalPath));
|
|
283
|
+
return results;
|
|
284
|
+
}
|
|
285
|
+
var MIME_MAP, HASH_LEN;
|
|
286
|
+
var init_scan_theme_assets = __esm({
|
|
287
|
+
"src/utils/scan-theme-assets.ts"() {
|
|
288
|
+
MIME_MAP = {
|
|
289
|
+
".png": "image/png",
|
|
290
|
+
".jpg": "image/jpeg",
|
|
291
|
+
".jpeg": "image/jpeg",
|
|
292
|
+
".gif": "image/gif",
|
|
293
|
+
".webp": "image/webp",
|
|
294
|
+
".avif": "image/avif",
|
|
295
|
+
".svg": "image/svg+xml",
|
|
296
|
+
".ico": "image/x-icon",
|
|
297
|
+
".bmp": "image/bmp",
|
|
298
|
+
".woff": "font/woff",
|
|
299
|
+
".woff2": "font/woff2",
|
|
300
|
+
".ttf": "font/ttf",
|
|
301
|
+
".otf": "font/otf",
|
|
302
|
+
".eot": "application/vnd.ms-fontobject",
|
|
303
|
+
".mp4": "video/mp4",
|
|
304
|
+
".webm": "video/webm",
|
|
305
|
+
".mov": "video/quicktime",
|
|
306
|
+
".ogg": "video/ogg",
|
|
307
|
+
".json": "application/json"
|
|
308
|
+
};
|
|
309
|
+
HASH_LEN = 8;
|
|
310
|
+
}
|
|
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
|
+
});
|
|
124
407
|
|
|
125
408
|
// src/utils/compile-theme.ts
|
|
126
409
|
var compile_theme_exports = {};
|
|
@@ -136,8 +419,8 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
136
419
|
const tailwindcss = (await import('tailwindcss')).default;
|
|
137
420
|
const tailwindConfig = {
|
|
138
421
|
content: [
|
|
139
|
-
|
|
140
|
-
|
|
422
|
+
path12__default.default.join(themePath, "sections/**/*.{ts,tsx}"),
|
|
423
|
+
path12__default.default.join(themePath, "components/**/*.{ts,tsx}")
|
|
141
424
|
],
|
|
142
425
|
theme: { extend: {} },
|
|
143
426
|
plugins: []
|
|
@@ -147,7 +430,7 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
147
430
|
inputCSS,
|
|
148
431
|
{ from: void 0 }
|
|
149
432
|
);
|
|
150
|
-
await
|
|
433
|
+
await fs10__default.default.writeFile(path12__default.default.join(outDir, "bundle.css"), result.css);
|
|
151
434
|
exports.logger.info("Generated bundle.css");
|
|
152
435
|
} catch (err) {
|
|
153
436
|
exports.logger.warning(
|
|
@@ -158,12 +441,12 @@ async function generateThemeCSS(themePath, outDir) {
|
|
|
158
441
|
async function resolveNodeModulesFile(startDir, relativePath) {
|
|
159
442
|
let dir = startDir;
|
|
160
443
|
while (true) {
|
|
161
|
-
const candidate =
|
|
444
|
+
const candidate = path12__default.default.join(dir, "node_modules", relativePath);
|
|
162
445
|
try {
|
|
163
|
-
await
|
|
446
|
+
await fs10__default.default.access(candidate);
|
|
164
447
|
return candidate;
|
|
165
448
|
} catch {
|
|
166
|
-
const parent =
|
|
449
|
+
const parent = path12__default.default.dirname(dir);
|
|
167
450
|
if (parent === dir) break;
|
|
168
451
|
dir = parent;
|
|
169
452
|
}
|
|
@@ -187,7 +470,7 @@ async function scanImportsFromPackage(sourceDir, packageName) {
|
|
|
187
470
|
});
|
|
188
471
|
for (const file of sourceFiles) {
|
|
189
472
|
try {
|
|
190
|
-
const content = await
|
|
473
|
+
const content = await fs10__default.default.readFile(path12__default.default.join(sourceDir, file), "utf-8");
|
|
191
474
|
for (const match of content.matchAll(namespaceImportRegex)) {
|
|
192
475
|
const subpath = match[1] ? match[1].slice(1) : "";
|
|
193
476
|
if (!result[subpath]) result[subpath] = /* @__PURE__ */ new Set();
|
|
@@ -241,17 +524,17 @@ function createCoreGlobalPlugin(themePath) {
|
|
|
241
524
|
const distFileName = subpath ? `${subpath}.mjs` : "index.mjs";
|
|
242
525
|
let distPath = await resolveNodeModulesFile(
|
|
243
526
|
themePath,
|
|
244
|
-
|
|
527
|
+
path12__default.default.join("@onexapis", "core", "dist", distFileName)
|
|
245
528
|
);
|
|
246
529
|
if (!distPath) {
|
|
247
530
|
distPath = await resolveNodeModulesFile(
|
|
248
531
|
__dirname,
|
|
249
|
-
|
|
532
|
+
path12__default.default.join("@onexapis", "core", "dist", distFileName)
|
|
250
533
|
);
|
|
251
534
|
}
|
|
252
535
|
try {
|
|
253
536
|
if (!distPath) throw new Error("not found");
|
|
254
|
-
const distContent = await
|
|
537
|
+
const distContent = await fs10__default.default.readFile(distPath, "utf-8");
|
|
255
538
|
const exportMatches = distContent.matchAll(/export\s*\{([^}]+)\}/g);
|
|
256
539
|
for (const m of exportMatches) {
|
|
257
540
|
const names = m[1].split(",").map((n) => {
|
|
@@ -298,180 +581,6 @@ ${namedExportLines}
|
|
|
298
581
|
}
|
|
299
582
|
};
|
|
300
583
|
}
|
|
301
|
-
function createThemeDepsStubPlugin(themePath) {
|
|
302
|
-
return {
|
|
303
|
-
name: "theme-deps-stub",
|
|
304
|
-
setup(build2) {
|
|
305
|
-
const tryResolveOrStub = (filter, namespace) => {
|
|
306
|
-
build2.onResolve({ filter }, async (args) => {
|
|
307
|
-
if (args.pluginData?.skipStub) return void 0;
|
|
308
|
-
try {
|
|
309
|
-
const result = await build2.resolve(args.path, {
|
|
310
|
-
kind: args.kind,
|
|
311
|
-
resolveDir: args.resolveDir || themePath,
|
|
312
|
-
importer: args.importer,
|
|
313
|
-
namespace: "file",
|
|
314
|
-
pluginData: { skipStub: true }
|
|
315
|
-
});
|
|
316
|
-
if (!result.errors.length) return result;
|
|
317
|
-
} catch {
|
|
318
|
-
}
|
|
319
|
-
try {
|
|
320
|
-
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);
|
|
321
|
-
const resolved = req.resolve(args.path);
|
|
322
|
-
if (resolved) return { path: resolved, namespace: "file" };
|
|
323
|
-
} catch {
|
|
324
|
-
}
|
|
325
|
-
return { path: args.path, namespace };
|
|
326
|
-
});
|
|
327
|
-
};
|
|
328
|
-
tryResolveOrStub(/^next\//, "next-stub");
|
|
329
|
-
build2.onLoad({ filter: /.*/, namespace: "next-stub" }, (args) => {
|
|
330
|
-
const stubs = {
|
|
331
|
-
"next/image": `
|
|
332
|
-
import React from 'react';
|
|
333
|
-
const Image = React.forwardRef((props, ref) => {
|
|
334
|
-
const { src, alt, width, height, fill, priority, sizes, quality, placeholder, blurDataURL, onLoad, onError, style, className, ...rest } = props;
|
|
335
|
-
const imgSrc = typeof src === 'object' ? src.src : src;
|
|
336
|
-
const fillStyle = fill ? { position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: style?.objectFit || 'cover', display: 'block' } : {};
|
|
337
|
-
const mergedStyle = { ...fillStyle, ...style };
|
|
338
|
-
return React.createElement('img', {
|
|
339
|
-
ref, src: imgSrc, alt,
|
|
340
|
-
width: fill ? undefined : width, height: fill ? undefined : height,
|
|
341
|
-
loading: priority ? 'eager' : 'lazy',
|
|
342
|
-
style: Object.keys(mergedStyle).length > 0 ? mergedStyle : undefined,
|
|
343
|
-
className, onLoad, onError, ...rest,
|
|
344
|
-
});
|
|
345
|
-
});
|
|
346
|
-
export default Image;
|
|
347
|
-
`,
|
|
348
|
-
"next/link": `
|
|
349
|
-
import React from 'react';
|
|
350
|
-
const Link = ({ href, children, ...rest }) => React.createElement('a', { href, ...rest }, children);
|
|
351
|
-
export default Link;
|
|
352
|
-
`,
|
|
353
|
-
"next/navigation": `
|
|
354
|
-
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(){} }; }
|
|
355
|
-
export function usePathname() { return window.location.pathname; }
|
|
356
|
-
export function useSearchParams() { return new URLSearchParams(window.location.search); }
|
|
357
|
-
export function useParams() { return {}; }
|
|
358
|
-
export function redirect(url) { window.location.href = url; }
|
|
359
|
-
export function notFound() { throw new Error('Not Found'); }
|
|
360
|
-
`,
|
|
361
|
-
"next/headers": `
|
|
362
|
-
export function cookies() { return { get(){}, getAll(){ return []; }, set(){}, delete(){}, has(){ return false; } }; }
|
|
363
|
-
export function headers() { return new Headers(); }
|
|
364
|
-
`
|
|
365
|
-
};
|
|
366
|
-
return {
|
|
367
|
-
contents: stubs[args.path] || "export default {};",
|
|
368
|
-
loader: "jsx",
|
|
369
|
-
resolveDir: themePath
|
|
370
|
-
};
|
|
371
|
-
});
|
|
372
|
-
const lucideImports = /* @__PURE__ */ new Set();
|
|
373
|
-
let lucideThemeScanned = false;
|
|
374
|
-
tryResolveOrStub(/^lucide-react/, "lucide-stub");
|
|
375
|
-
build2.onLoad({ filter: /.*/, namespace: "lucide-stub" }, async () => {
|
|
376
|
-
if (!lucideThemeScanned) {
|
|
377
|
-
lucideThemeScanned = true;
|
|
378
|
-
try {
|
|
379
|
-
const scanned = await scanImportsFromPackage(
|
|
380
|
-
themePath,
|
|
381
|
-
"lucide-react"
|
|
382
|
-
);
|
|
383
|
-
for (const names of Object.values(scanned)) {
|
|
384
|
-
for (const name of names) lucideImports.add(name);
|
|
385
|
-
}
|
|
386
|
-
} catch {
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
const iconNames = [...lucideImports];
|
|
390
|
-
const exports$1 = iconNames.map((n) => `icon as ${n}`).join(", ");
|
|
391
|
-
return {
|
|
392
|
-
contents: `
|
|
393
|
-
const icon = (props) => null;
|
|
394
|
-
export { ${exports$1} };
|
|
395
|
-
export default new Proxy({}, { get: (_, name) => name === '__esModule' ? true : icon });
|
|
396
|
-
`.trim(),
|
|
397
|
-
loader: "jsx"
|
|
398
|
-
};
|
|
399
|
-
});
|
|
400
|
-
tryResolveOrStub(/^framer-motion/, "motion-stub");
|
|
401
|
-
build2.onLoad({ filter: /.*/, namespace: "motion-stub" }, () => ({
|
|
402
|
-
contents: `
|
|
403
|
-
import React from 'react';
|
|
404
|
-
const handler = { get: (_, name) => {
|
|
405
|
-
if (name === '__esModule') return true;
|
|
406
|
-
return React.forwardRef((props, ref) => React.createElement(name, { ...props, ref }));
|
|
407
|
-
}};
|
|
408
|
-
export const motion = new Proxy({}, handler);
|
|
409
|
-
export const AnimatePresence = ({ children }) => children || null;
|
|
410
|
-
export function useInView() { return true; }
|
|
411
|
-
export default { motion, AnimatePresence, useInView };
|
|
412
|
-
`.trim(),
|
|
413
|
-
loader: "jsx",
|
|
414
|
-
resolveDir: themePath
|
|
415
|
-
}));
|
|
416
|
-
tryResolveOrStub(/^sonner$/, "sonner-stub");
|
|
417
|
-
build2.onLoad({ filter: /.*/, namespace: "sonner-stub" }, () => ({
|
|
418
|
-
contents: `
|
|
419
|
-
export const toast = new Proxy(() => {}, { get: () => () => {} });
|
|
420
|
-
export const Toaster = () => null;
|
|
421
|
-
export default { toast, Toaster };
|
|
422
|
-
`.trim(),
|
|
423
|
-
loader: "jsx"
|
|
424
|
-
}));
|
|
425
|
-
tryResolveOrStub(/^react-hook-form$/, "rhf-stub");
|
|
426
|
-
build2.onLoad({ filter: /.*/, namespace: "rhf-stub" }, () => ({
|
|
427
|
-
contents: `
|
|
428
|
-
export function useForm() {
|
|
429
|
-
return {
|
|
430
|
-
register: () => ({}),
|
|
431
|
-
handleSubmit: (fn) => (e) => { e?.preventDefault?.(); fn({}); },
|
|
432
|
-
formState: { errors: {}, isSubmitting: false, isValid: true },
|
|
433
|
-
watch: () => undefined,
|
|
434
|
-
setValue: () => {},
|
|
435
|
-
reset: () => {},
|
|
436
|
-
control: {},
|
|
437
|
-
};
|
|
438
|
-
}
|
|
439
|
-
export function useController() { return { field: {}, fieldState: {} }; }
|
|
440
|
-
export function useFormContext() { return useForm(); }
|
|
441
|
-
`.trim(),
|
|
442
|
-
loader: "js"
|
|
443
|
-
}));
|
|
444
|
-
tryResolveOrStub(/^@hookform\/resolvers/, "hookform-resolvers-stub");
|
|
445
|
-
build2.onLoad(
|
|
446
|
-
{ filter: /.*/, namespace: "hookform-resolvers-stub" },
|
|
447
|
-
() => ({
|
|
448
|
-
contents: `export function zodResolver() { return () => ({ values: {}, errors: {} }); }`,
|
|
449
|
-
loader: "js"
|
|
450
|
-
})
|
|
451
|
-
);
|
|
452
|
-
tryResolveOrStub(/^next-intl$/, "next-intl-stub");
|
|
453
|
-
build2.onLoad({ filter: /.*/, namespace: "next-intl-stub" }, () => ({
|
|
454
|
-
contents: `
|
|
455
|
-
export function useTranslations(ns) {
|
|
456
|
-
return (key) => ns ? ns + '.' + key : key;
|
|
457
|
-
}
|
|
458
|
-
export function useLocale() { return 'en'; }
|
|
459
|
-
export function useMessages() { return {}; }
|
|
460
|
-
`.trim(),
|
|
461
|
-
loader: "js"
|
|
462
|
-
}));
|
|
463
|
-
tryResolveOrStub(/^zod$/, "zod-stub");
|
|
464
|
-
build2.onLoad({ filter: /.*/, namespace: "zod-stub" }, () => ({
|
|
465
|
-
contents: `
|
|
466
|
-
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 });
|
|
467
|
-
export const z = { string: schema, number: schema, boolean: schema, object: (s) => ({ ...schema(), shape: s }), array: schema, enum: schema, union: schema, literal: schema, infer: undefined };
|
|
468
|
-
export default z;
|
|
469
|
-
`.trim(),
|
|
470
|
-
loader: "js"
|
|
471
|
-
}));
|
|
472
|
-
}
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
584
|
async function generateThemeData(themePath, outputDir, themeId) {
|
|
476
585
|
const { createJiti } = await import('jiti');
|
|
477
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)));
|
|
@@ -480,7 +589,7 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
480
589
|
const pages = {};
|
|
481
590
|
for (const ext of [".ts", ".js"]) {
|
|
482
591
|
try {
|
|
483
|
-
const mod = await jiti.import(
|
|
592
|
+
const mod = await jiti.import(path12__default.default.join(themePath, `theme.config${ext}`));
|
|
484
593
|
themeConfig = mod.default || mod;
|
|
485
594
|
break;
|
|
486
595
|
} catch {
|
|
@@ -488,20 +597,20 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
488
597
|
}
|
|
489
598
|
for (const ext of [".ts", ".js"]) {
|
|
490
599
|
try {
|
|
491
|
-
const mod = await jiti.import(
|
|
600
|
+
const mod = await jiti.import(path12__default.default.join(themePath, `theme.layout${ext}`));
|
|
492
601
|
layoutConfig = mod.default || mod;
|
|
493
602
|
break;
|
|
494
603
|
} catch {
|
|
495
604
|
}
|
|
496
605
|
}
|
|
497
606
|
const schemas = {};
|
|
498
|
-
const sectionsDir =
|
|
607
|
+
const sectionsDir = path12__default.default.join(themePath, "sections");
|
|
499
608
|
try {
|
|
500
|
-
const sectionDirs = await
|
|
609
|
+
const sectionDirs = await fs10__default.default.readdir(sectionsDir);
|
|
501
610
|
for (const dir of sectionDirs) {
|
|
502
|
-
const schemaFile =
|
|
611
|
+
const schemaFile = path12__default.default.join(sectionsDir, dir, `${dir}.schema.ts`);
|
|
503
612
|
try {
|
|
504
|
-
await
|
|
613
|
+
await fs10__default.default.access(schemaFile);
|
|
505
614
|
const mod = await jiti.import(schemaFile);
|
|
506
615
|
for (const [key, value] of Object.entries(mod)) {
|
|
507
616
|
if (key.endsWith("Schema") && value && typeof value === "object" && value.type) {
|
|
@@ -513,14 +622,14 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
513
622
|
}
|
|
514
623
|
} catch {
|
|
515
624
|
}
|
|
516
|
-
const pagesDir =
|
|
625
|
+
const pagesDir = path12__default.default.join(themePath, "pages");
|
|
517
626
|
try {
|
|
518
|
-
const files = await
|
|
627
|
+
const files = await fs10__default.default.readdir(pagesDir);
|
|
519
628
|
for (const file of files) {
|
|
520
629
|
if (!file.match(/\.(ts|js)$/)) continue;
|
|
521
630
|
const name = file.replace(/\.(ts|js)$/, "");
|
|
522
631
|
try {
|
|
523
|
-
const mod = await jiti.import(
|
|
632
|
+
const mod = await jiti.import(path12__default.default.join(pagesDir, file));
|
|
524
633
|
const config = mod.default || mod;
|
|
525
634
|
const sections = (config.sections || []).map((section) => {
|
|
526
635
|
const schema = schemas[section.type];
|
|
@@ -548,8 +657,16 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
548
657
|
}
|
|
549
658
|
} catch {
|
|
550
659
|
}
|
|
551
|
-
|
|
552
|
-
|
|
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"),
|
|
553
670
|
JSON.stringify(
|
|
554
671
|
{
|
|
555
672
|
themeId,
|
|
@@ -572,22 +689,22 @@ async function generateThemeData(themePath, outputDir, themeId) {
|
|
|
572
689
|
exports.logger.info(`Generated theme-data.json (${Object.keys(pages).length} pages)`);
|
|
573
690
|
}
|
|
574
691
|
async function contentHashEntry(outputDir) {
|
|
575
|
-
const entryPath =
|
|
576
|
-
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");
|
|
577
694
|
let entryContent;
|
|
578
695
|
try {
|
|
579
|
-
entryContent = await
|
|
696
|
+
entryContent = await fs10__default.default.readFile(entryPath, "utf-8");
|
|
580
697
|
} catch {
|
|
581
|
-
const indexPath =
|
|
698
|
+
const indexPath = path12__default.default.join(outputDir, "index.js");
|
|
582
699
|
try {
|
|
583
|
-
entryContent = await
|
|
700
|
+
entryContent = await fs10__default.default.readFile(indexPath, "utf-8");
|
|
584
701
|
} catch {
|
|
585
702
|
exports.logger.warning("No entry file found in output, skipping content hash");
|
|
586
703
|
return;
|
|
587
704
|
}
|
|
588
705
|
const hash2 = crypto__default.default.createHash("sha256").update(entryContent).digest("hex").slice(0, 8);
|
|
589
706
|
const hashedName2 = `bundle-entry-${hash2}.js`;
|
|
590
|
-
const indexMapPath =
|
|
707
|
+
const indexMapPath = path12__default.default.join(outputDir, "index.js.map");
|
|
591
708
|
const hashedMapName2 = `bundle-entry-${hash2}.js.map`;
|
|
592
709
|
entryContent = entryContent.replace(
|
|
593
710
|
/\/\/# sourceMappingURL=index\.js\.map/,
|
|
@@ -595,18 +712,18 @@ async function contentHashEntry(outputDir) {
|
|
|
595
712
|
);
|
|
596
713
|
const oldFiles2 = await glob.glob("bundle-entry-*.js*", { cwd: outputDir });
|
|
597
714
|
for (const f of oldFiles2) {
|
|
598
|
-
await
|
|
715
|
+
await fs10__default.default.unlink(path12__default.default.join(outputDir, f));
|
|
599
716
|
}
|
|
600
|
-
await
|
|
601
|
-
await
|
|
717
|
+
await fs10__default.default.writeFile(path12__default.default.join(outputDir, hashedName2), entryContent);
|
|
718
|
+
await fs10__default.default.unlink(indexPath);
|
|
602
719
|
try {
|
|
603
|
-
await
|
|
720
|
+
await fs10__default.default.unlink(entryPath);
|
|
604
721
|
} catch {
|
|
605
722
|
}
|
|
606
|
-
await
|
|
723
|
+
await fs10__default.default.writeFile(entryPath, entryContent);
|
|
607
724
|
try {
|
|
608
|
-
await
|
|
609
|
-
await
|
|
725
|
+
await fs10__default.default.access(indexMapPath);
|
|
726
|
+
await fs10__default.default.rename(indexMapPath, path12__default.default.join(outputDir, hashedMapName2));
|
|
610
727
|
} catch {
|
|
611
728
|
}
|
|
612
729
|
exports.logger.info(`Entry hashed: ${hashedName2}`);
|
|
@@ -621,17 +738,17 @@ async function contentHashEntry(outputDir) {
|
|
|
621
738
|
);
|
|
622
739
|
const oldFiles = await glob.glob("bundle-entry-*.js*", { cwd: outputDir });
|
|
623
740
|
for (const f of oldFiles) {
|
|
624
|
-
await
|
|
741
|
+
await fs10__default.default.unlink(path12__default.default.join(outputDir, f));
|
|
625
742
|
}
|
|
626
|
-
await
|
|
743
|
+
await fs10__default.default.writeFile(path12__default.default.join(outputDir, hashedName), entryContent);
|
|
627
744
|
try {
|
|
628
|
-
await
|
|
745
|
+
await fs10__default.default.unlink(entryPath);
|
|
629
746
|
} catch {
|
|
630
747
|
}
|
|
631
|
-
await
|
|
748
|
+
await fs10__default.default.writeFile(entryPath, entryContent);
|
|
632
749
|
try {
|
|
633
|
-
await
|
|
634
|
-
await
|
|
750
|
+
await fs10__default.default.access(mapPath);
|
|
751
|
+
await fs10__default.default.rename(mapPath, path12__default.default.join(outputDir, hashedMapName));
|
|
635
752
|
} catch {
|
|
636
753
|
}
|
|
637
754
|
exports.logger.info(`Entry hashed: ${hashedName}`);
|
|
@@ -643,7 +760,7 @@ async function extractDataRequirements(themePath) {
|
|
|
643
760
|
const requirements = {};
|
|
644
761
|
for (const file of schemaFiles) {
|
|
645
762
|
try {
|
|
646
|
-
const mod = await jiti.import(
|
|
763
|
+
const mod = await jiti.import(path12__default.default.join(themePath, file));
|
|
647
764
|
const exports$1 = mod;
|
|
648
765
|
for (const value of Object.values(exports$1)) {
|
|
649
766
|
if (value && typeof value === "object" && typeof value.type === "string" && value.dataRequirements && typeof value.dataRequirements === "object") {
|
|
@@ -658,12 +775,105 @@ async function extractDataRequirements(themePath) {
|
|
|
658
775
|
}
|
|
659
776
|
return requirements;
|
|
660
777
|
}
|
|
778
|
+
async function writeGateManifests(themePath, outputDir) {
|
|
779
|
+
try {
|
|
780
|
+
const schemas = await extractSchemas(themePath);
|
|
781
|
+
await fs10__default.default.writeFile(
|
|
782
|
+
path12__default.default.join(outputDir, "schemas.json"),
|
|
783
|
+
serializeManifest(schemas)
|
|
784
|
+
);
|
|
785
|
+
exports.logger.info(
|
|
786
|
+
`Generated schemas.json (${Object.keys(schemas.sections).length} sections)`
|
|
787
|
+
);
|
|
788
|
+
} catch (err) {
|
|
789
|
+
exports.logger.warning(
|
|
790
|
+
`schemas.json not written: ${err instanceof Error ? err.message : String(err)}`
|
|
791
|
+
);
|
|
792
|
+
}
|
|
793
|
+
try {
|
|
794
|
+
const entries = await scanThemeAssets(outputDir);
|
|
795
|
+
const assets = entries.map((e) => ({
|
|
796
|
+
path: e.originalPath,
|
|
797
|
+
hash: e.hash,
|
|
798
|
+
size: e.size,
|
|
799
|
+
contentType: e.contentType
|
|
800
|
+
}));
|
|
801
|
+
await fs10__default.default.writeFile(
|
|
802
|
+
path12__default.default.join(outputDir, "asset-manifest.json"),
|
|
803
|
+
JSON.stringify({ manifestVersion: 1, assets }, null, 2)
|
|
804
|
+
);
|
|
805
|
+
exports.logger.info(`Generated asset-manifest.json (${assets.length} assets)`);
|
|
806
|
+
} catch (err) {
|
|
807
|
+
exports.logger.warning(
|
|
808
|
+
`asset-manifest.json not written: ${err instanceof Error ? err.message : String(err)}`
|
|
809
|
+
);
|
|
810
|
+
}
|
|
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
|
+
}
|
|
661
871
|
async function generateManifest(themeName, themePath, outputDir) {
|
|
662
872
|
let version = "1.0.0";
|
|
663
873
|
let themeId = themeName;
|
|
664
874
|
try {
|
|
665
|
-
const pkgContent = await
|
|
666
|
-
|
|
875
|
+
const pkgContent = await fs10__default.default.readFile(
|
|
876
|
+
path12__default.default.join(themePath, "package.json"),
|
|
667
877
|
"utf-8"
|
|
668
878
|
);
|
|
669
879
|
const pkg = JSON.parse(pkgContent);
|
|
@@ -681,7 +891,7 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
681
891
|
const dataRequirements = await extractDataRequirements(themePath);
|
|
682
892
|
let hasThemeConfig = false;
|
|
683
893
|
try {
|
|
684
|
-
await
|
|
894
|
+
await fs10__default.default.access(path12__default.default.join(themePath, "theme.config.ts"));
|
|
685
895
|
hasThemeConfig = true;
|
|
686
896
|
} catch {
|
|
687
897
|
}
|
|
@@ -722,24 +932,34 @@ async function generateManifest(themeName, themePath, outputDir) {
|
|
|
722
932
|
// Section data requirements for server-side prefetching (keyed by section type)
|
|
723
933
|
dataRequirements
|
|
724
934
|
};
|
|
725
|
-
await
|
|
726
|
-
|
|
935
|
+
await fs10__default.default.writeFile(
|
|
936
|
+
path12__default.default.join(outputDir, "manifest.json"),
|
|
727
937
|
JSON.stringify(manifest, null, 2)
|
|
728
938
|
);
|
|
729
939
|
}
|
|
730
940
|
async function compileStandaloneTheme(themePath, themeName) {
|
|
731
|
-
const outputDir =
|
|
732
|
-
const
|
|
733
|
-
|
|
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");
|
|
734
948
|
let entryPoint = indexEntry;
|
|
735
949
|
try {
|
|
736
|
-
await
|
|
950
|
+
await fs10__default.default.access(bundleEntry);
|
|
737
951
|
entryPoint = bundleEntry;
|
|
738
952
|
} catch {
|
|
739
953
|
}
|
|
740
|
-
const shimPath =
|
|
741
|
-
await
|
|
742
|
-
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);
|
|
743
963
|
const buildOptions = {
|
|
744
964
|
entryPoints: [entryPoint],
|
|
745
965
|
bundle: true,
|
|
@@ -751,12 +971,7 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
751
971
|
banner: {
|
|
752
972
|
js: '"use client";'
|
|
753
973
|
},
|
|
754
|
-
plugins
|
|
755
|
-
reactGlobalPlugin,
|
|
756
|
-
reactQueryGlobalPlugin,
|
|
757
|
-
createCoreGlobalPlugin(themePath),
|
|
758
|
-
createThemeDepsStubPlugin(themePath)
|
|
759
|
-
],
|
|
974
|
+
plugins,
|
|
760
975
|
external: [],
|
|
761
976
|
alias: {
|
|
762
977
|
events: "events/",
|
|
@@ -790,19 +1005,21 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
790
1005
|
try {
|
|
791
1006
|
const result = await esbuild__namespace.build(buildOptions);
|
|
792
1007
|
try {
|
|
793
|
-
await
|
|
1008
|
+
await fs10__default.default.unlink(shimPath);
|
|
794
1009
|
} catch {
|
|
795
1010
|
}
|
|
1011
|
+
await compileSections(themePath, outputDir);
|
|
796
1012
|
await contentHashEntry(outputDir);
|
|
797
|
-
const themeAssetsDir =
|
|
798
|
-
const distThemeAssets =
|
|
1013
|
+
const themeAssetsDir = path12__default.default.join(themePath, "assets");
|
|
1014
|
+
const distThemeAssets = path12__default.default.join(outputDir, "theme-assets");
|
|
799
1015
|
try {
|
|
800
|
-
await
|
|
801
|
-
await
|
|
1016
|
+
await fs10__default.default.access(themeAssetsDir);
|
|
1017
|
+
await fs10__default.default.cp(themeAssetsDir, distThemeAssets, { recursive: true });
|
|
802
1018
|
exports.logger.info("Copied static assets to dist/theme-assets/");
|
|
803
1019
|
} catch {
|
|
804
1020
|
}
|
|
805
1021
|
await generateManifest(themeName, themePath, outputDir);
|
|
1022
|
+
await writeGateManifests(themePath, outputDir);
|
|
806
1023
|
await generateThemeData(themePath, outputDir, themeName);
|
|
807
1024
|
await generateThemeCSS(themePath, outputDir);
|
|
808
1025
|
if (result.metafile) {
|
|
@@ -817,7 +1034,7 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
817
1034
|
return true;
|
|
818
1035
|
} catch (error) {
|
|
819
1036
|
try {
|
|
820
|
-
await
|
|
1037
|
+
await fs10__default.default.unlink(shimPath);
|
|
821
1038
|
} catch {
|
|
822
1039
|
}
|
|
823
1040
|
exports.logger.error(`esbuild compilation failed: ${error}`);
|
|
@@ -825,18 +1042,25 @@ async function compileStandaloneTheme(themePath, themeName) {
|
|
|
825
1042
|
}
|
|
826
1043
|
}
|
|
827
1044
|
async function compileStandaloneThemeDev(themePath, themeName) {
|
|
828
|
-
const outputDir =
|
|
829
|
-
const
|
|
830
|
-
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");
|
|
831
1049
|
let entryPoint = indexEntry;
|
|
832
1050
|
try {
|
|
833
|
-
await
|
|
1051
|
+
await fs10__default.default.access(bundleEntry);
|
|
834
1052
|
entryPoint = bundleEntry;
|
|
835
1053
|
} catch {
|
|
836
1054
|
}
|
|
837
|
-
const shimPath =
|
|
838
|
-
await
|
|
839
|
-
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);
|
|
840
1064
|
const buildOptions = {
|
|
841
1065
|
entryPoints: [entryPoint],
|
|
842
1066
|
bundle: true,
|
|
@@ -847,12 +1071,7 @@ async function compileStandaloneThemeDev(themePath, themeName) {
|
|
|
847
1071
|
banner: {
|
|
848
1072
|
js: '"use client";'
|
|
849
1073
|
},
|
|
850
|
-
plugins:
|
|
851
|
-
reactGlobalPlugin,
|
|
852
|
-
reactQueryGlobalPlugin,
|
|
853
|
-
createCoreGlobalPlugin(themePath),
|
|
854
|
-
createThemeDepsStubPlugin(themePath)
|
|
855
|
-
],
|
|
1074
|
+
plugins: devPlugins,
|
|
856
1075
|
external: [],
|
|
857
1076
|
alias: {
|
|
858
1077
|
events: "events/",
|
|
@@ -890,18 +1109,18 @@ async function compileStandaloneThemeDev(themePath, themeName) {
|
|
|
890
1109
|
return { context: context2, outputDir };
|
|
891
1110
|
}
|
|
892
1111
|
async function compilePreviewRuntime(themePath) {
|
|
893
|
-
const outputDir =
|
|
894
|
-
await
|
|
895
|
-
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");
|
|
896
1115
|
const locations = [
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
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")
|
|
900
1119
|
];
|
|
901
1120
|
let previewEntryPath = null;
|
|
902
1121
|
for (const loc of locations) {
|
|
903
1122
|
try {
|
|
904
|
-
await
|
|
1123
|
+
await fs10__default.default.access(loc);
|
|
905
1124
|
previewEntryPath = loc;
|
|
906
1125
|
break;
|
|
907
1126
|
} catch {
|
|
@@ -984,10 +1203,10 @@ ${locations.join("\n")}`
|
|
|
984
1203
|
if (!lucideScanned) {
|
|
985
1204
|
lucideScanned = true;
|
|
986
1205
|
const coreSrcCandidates = [
|
|
987
|
-
|
|
988
|
-
|
|
1206
|
+
path12__default.default.join(themePath, "node_modules", "@onexapis", "core", "src"),
|
|
1207
|
+
path12__default.default.join(themePath, "..", "..", "packages", "core", "src"),
|
|
989
1208
|
// monorepo sibling
|
|
990
|
-
|
|
1209
|
+
path12__default.default.join(
|
|
991
1210
|
__dirname,
|
|
992
1211
|
"..",
|
|
993
1212
|
"..",
|
|
@@ -1002,7 +1221,7 @@ ${locations.join("\n")}`
|
|
|
1002
1221
|
let coreSourceDir = null;
|
|
1003
1222
|
for (const candidate of coreSrcCandidates) {
|
|
1004
1223
|
try {
|
|
1005
|
-
await
|
|
1224
|
+
await fs10__default.default.access(candidate);
|
|
1006
1225
|
coreSourceDir = candidate;
|
|
1007
1226
|
break;
|
|
1008
1227
|
} catch {
|
|
@@ -1021,21 +1240,21 @@ ${locations.join("\n")}`
|
|
|
1021
1240
|
}
|
|
1022
1241
|
} else {
|
|
1023
1242
|
const coreDistCandidates = [
|
|
1024
|
-
|
|
1243
|
+
path12__default.default.join(themePath, "node_modules", "@onexapis", "core", "dist")
|
|
1025
1244
|
];
|
|
1026
1245
|
const resolvedDist = await resolveNodeModulesFile(
|
|
1027
1246
|
__dirname,
|
|
1028
|
-
|
|
1247
|
+
path12__default.default.join("@onexapis", "core", "dist")
|
|
1029
1248
|
);
|
|
1030
1249
|
if (resolvedDist) coreDistCandidates.push(resolvedDist);
|
|
1031
1250
|
for (const candidate of coreDistCandidates) {
|
|
1032
1251
|
try {
|
|
1033
|
-
await
|
|
1252
|
+
await fs10__default.default.access(candidate);
|
|
1034
1253
|
const mjsFiles = await glob.glob("*.mjs", { cwd: candidate });
|
|
1035
1254
|
const importRegex = /import\s*\{([^}]+)\}\s*from\s*["']lucide-react["']/g;
|
|
1036
1255
|
for (const file of mjsFiles) {
|
|
1037
|
-
const content = await
|
|
1038
|
-
|
|
1256
|
+
const content = await fs10__default.default.readFile(
|
|
1257
|
+
path12__default.default.join(candidate, file),
|
|
1039
1258
|
"utf-8"
|
|
1040
1259
|
);
|
|
1041
1260
|
for (const match of content.matchAll(importRegex)) {
|
|
@@ -1090,7 +1309,7 @@ export default new Proxy({}, { get: (_, name) => name === '__esModule' ? true :
|
|
|
1090
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);
|
|
1091
1310
|
const cjsPath = req.resolve("framer-motion");
|
|
1092
1311
|
const pkgDir = cjsPath.replace(/[/\\]dist[/\\].*$/, "");
|
|
1093
|
-
const esmEntry =
|
|
1312
|
+
const esmEntry = path12__default.default.join(pkgDir, "dist", "es", "index.mjs");
|
|
1094
1313
|
const { existsSync } = await import('fs');
|
|
1095
1314
|
if (existsSync(esmEntry)) {
|
|
1096
1315
|
return { path: esmEntry, namespace: "file" };
|
|
@@ -1189,8 +1408,8 @@ export function headers() { return new Headers(); }
|
|
|
1189
1408
|
});
|
|
1190
1409
|
}
|
|
1191
1410
|
};
|
|
1192
|
-
const shimPath =
|
|
1193
|
-
await
|
|
1411
|
+
const shimPath = path12__default.default.join(outputDir, ".process-shim-preview.js");
|
|
1412
|
+
await fs10__default.default.writeFile(shimPath, PROCESS_SHIM);
|
|
1194
1413
|
await esbuild__namespace.build({
|
|
1195
1414
|
entryPoints: [previewEntryPath],
|
|
1196
1415
|
bundle: true,
|
|
@@ -1225,15 +1444,19 @@ export function headers() { return new Headers(); }
|
|
|
1225
1444
|
}
|
|
1226
1445
|
});
|
|
1227
1446
|
try {
|
|
1228
|
-
await
|
|
1447
|
+
await fs10__default.default.unlink(shimPath);
|
|
1229
1448
|
} catch {
|
|
1230
1449
|
}
|
|
1231
1450
|
return outputPath;
|
|
1232
1451
|
}
|
|
1233
|
-
var PROCESS_SHIM, reactGlobalPlugin, reactQueryGlobalPlugin;
|
|
1452
|
+
var PROCESS_SHIM, reactGlobalPlugin, reactQueryGlobalPlugin, nextShimPlugin;
|
|
1234
1453
|
var init_compile_theme = __esm({
|
|
1235
1454
|
"src/utils/compile-theme.ts"() {
|
|
1236
1455
|
init_logger();
|
|
1456
|
+
init_extract_schemas();
|
|
1457
|
+
init_scan_theme_assets();
|
|
1458
|
+
init_detect_nextjs();
|
|
1459
|
+
init_nextjs_page_scanner();
|
|
1237
1460
|
PROCESS_SHIM = `
|
|
1238
1461
|
if (typeof process === "undefined") {
|
|
1239
1462
|
globalThis.process = {
|
|
@@ -1379,6 +1602,145 @@ export const {
|
|
|
1379
1602
|
}));
|
|
1380
1603
|
}
|
|
1381
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
|
+
};
|
|
1382
1744
|
}
|
|
1383
1745
|
});
|
|
1384
1746
|
|
|
@@ -1403,8 +1765,8 @@ function validateThemeName(name) {
|
|
|
1403
1765
|
return /^[a-z][a-z0-9-]*$/.test(name);
|
|
1404
1766
|
}
|
|
1405
1767
|
function pathExists(filePath) {
|
|
1406
|
-
const
|
|
1407
|
-
return
|
|
1768
|
+
const fs14 = __require("fs-extra");
|
|
1769
|
+
return fs14.existsSync(filePath);
|
|
1408
1770
|
}
|
|
1409
1771
|
function validateCategory(category) {
|
|
1410
1772
|
const validCategories = [
|
|
@@ -1445,18 +1807,18 @@ async function renderTemplate(templatePath, data) {
|
|
|
1445
1807
|
return ejs__default.default.render(template, data);
|
|
1446
1808
|
}
|
|
1447
1809
|
async function writeFile(filePath, content) {
|
|
1448
|
-
await fs__default.default.ensureDir(
|
|
1810
|
+
await fs__default.default.ensureDir(path12__default.default.dirname(filePath));
|
|
1449
1811
|
await fs__default.default.writeFile(filePath, content, "utf-8");
|
|
1450
1812
|
}
|
|
1451
1813
|
function getTemplatesDir() {
|
|
1452
1814
|
const locations = [
|
|
1453
|
-
|
|
1815
|
+
path12__default.default.join(__dirname, "../../templates"),
|
|
1454
1816
|
// Development
|
|
1455
|
-
|
|
1817
|
+
path12__default.default.join(__dirname, "../templates"),
|
|
1456
1818
|
// Production (dist/)
|
|
1457
|
-
|
|
1819
|
+
path12__default.default.join(process.cwd(), "templates"),
|
|
1458
1820
|
// Fallback
|
|
1459
|
-
|
|
1821
|
+
path12__default.default.join(process.cwd(), "packages/cli/templates")
|
|
1460
1822
|
// Monorepo
|
|
1461
1823
|
];
|
|
1462
1824
|
for (const location of locations) {
|
|
@@ -1468,7 +1830,7 @@ function getTemplatesDir() {
|
|
|
1468
1830
|
}
|
|
1469
1831
|
async function copyTemplate(templateName, targetDir, data) {
|
|
1470
1832
|
const templatesDir = getTemplatesDir();
|
|
1471
|
-
const templateDir =
|
|
1833
|
+
const templateDir = path12__default.default.join(templatesDir, templateName);
|
|
1472
1834
|
if (!fs__default.default.existsSync(templateDir)) {
|
|
1473
1835
|
throw new Error(
|
|
1474
1836
|
`Template "${templateName}" not found at ${templateDir}. Available templates: ${fs__default.default.readdirSync(templatesDir).join(", ")}`
|
|
@@ -1477,8 +1839,8 @@ async function copyTemplate(templateName, targetDir, data) {
|
|
|
1477
1839
|
await fs__default.default.ensureDir(targetDir);
|
|
1478
1840
|
const files = await fs__default.default.readdir(templateDir);
|
|
1479
1841
|
for (const file of files) {
|
|
1480
|
-
const templatePath =
|
|
1481
|
-
const targetPath =
|
|
1842
|
+
const templatePath = path12__default.default.join(templateDir, file);
|
|
1843
|
+
const targetPath = path12__default.default.join(targetDir, file);
|
|
1482
1844
|
const stat = await fs__default.default.stat(templatePath);
|
|
1483
1845
|
if (stat.isDirectory()) {
|
|
1484
1846
|
await copyTemplateDir(templatePath, targetPath, data);
|
|
@@ -1495,8 +1857,8 @@ async function copyTemplateDir(templateDir, targetDir, data) {
|
|
|
1495
1857
|
await fs__default.default.ensureDir(targetDir);
|
|
1496
1858
|
const files = await fs__default.default.readdir(templateDir);
|
|
1497
1859
|
for (const file of files) {
|
|
1498
|
-
const templatePath =
|
|
1499
|
-
const targetPath =
|
|
1860
|
+
const templatePath = path12__default.default.join(templateDir, file);
|
|
1861
|
+
const targetPath = path12__default.default.join(targetDir, file);
|
|
1500
1862
|
const stat = await fs__default.default.stat(templatePath);
|
|
1501
1863
|
if (stat.isDirectory()) {
|
|
1502
1864
|
await copyTemplateDir(templatePath, targetPath, data);
|
|
@@ -1511,32 +1873,32 @@ async function copyTemplateDir(templateDir, targetDir, data) {
|
|
|
1511
1873
|
}
|
|
1512
1874
|
function getProjectRoot() {
|
|
1513
1875
|
let currentDir = process.cwd();
|
|
1514
|
-
while (currentDir !==
|
|
1515
|
-
const packageJsonPath =
|
|
1876
|
+
while (currentDir !== path12__default.default.parse(currentDir).root) {
|
|
1877
|
+
const packageJsonPath = path12__default.default.join(currentDir, "package.json");
|
|
1516
1878
|
if (fs__default.default.existsSync(packageJsonPath)) {
|
|
1517
1879
|
const packageJson = fs__default.default.readJsonSync(packageJsonPath);
|
|
1518
|
-
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"))) {
|
|
1519
1881
|
return currentDir;
|
|
1520
1882
|
}
|
|
1521
1883
|
}
|
|
1522
|
-
currentDir =
|
|
1884
|
+
currentDir = path12__default.default.dirname(currentDir);
|
|
1523
1885
|
}
|
|
1524
1886
|
return process.cwd();
|
|
1525
1887
|
}
|
|
1526
1888
|
function getThemesDir() {
|
|
1527
1889
|
const root = getProjectRoot();
|
|
1528
|
-
if (fs__default.default.existsSync(
|
|
1529
|
-
return
|
|
1530
|
-
if (fs__default.default.existsSync(
|
|
1531
|
-
return
|
|
1532
|
-
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);
|
|
1533
1895
|
}
|
|
1534
1896
|
function getFeaturesDir() {
|
|
1535
|
-
return
|
|
1897
|
+
return path12__default.default.join(getProjectRoot(), "src/features");
|
|
1536
1898
|
}
|
|
1537
1899
|
function isOneXProject() {
|
|
1538
1900
|
const root = getProjectRoot();
|
|
1539
|
-
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"));
|
|
1540
1902
|
}
|
|
1541
1903
|
function ensureOneXProject() {
|
|
1542
1904
|
if (!isOneXProject()) {
|
|
@@ -1552,13 +1914,13 @@ function listThemes() {
|
|
|
1552
1914
|
return [];
|
|
1553
1915
|
}
|
|
1554
1916
|
return fs__default.default.readdirSync(themesDir).filter((name) => {
|
|
1555
|
-
const themePath =
|
|
1556
|
-
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")));
|
|
1557
1919
|
});
|
|
1558
1920
|
}
|
|
1559
1921
|
function themeExists(themeName) {
|
|
1560
|
-
const themePath =
|
|
1561
|
-
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")));
|
|
1562
1924
|
}
|
|
1563
1925
|
function detectPackageManager() {
|
|
1564
1926
|
const userAgent = process.env.npm_config_user_agent || "";
|
|
@@ -1566,9 +1928,9 @@ function detectPackageManager() {
|
|
|
1566
1928
|
if (userAgent.includes("yarn")) return "yarn";
|
|
1567
1929
|
if (userAgent.includes("bun")) return "bun";
|
|
1568
1930
|
const cwd = process.cwd();
|
|
1569
|
-
if (fs__default.default.existsSync(
|
|
1570
|
-
if (fs__default.default.existsSync(
|
|
1571
|
-
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";
|
|
1572
1934
|
return "npm";
|
|
1573
1935
|
}
|
|
1574
1936
|
async function installDependencies(projectPath, packageManager = "npm") {
|
|
@@ -1585,15 +1947,16 @@ async function installDependencies(projectPath, packageManager = "npm") {
|
|
|
1585
1947
|
}
|
|
1586
1948
|
});
|
|
1587
1949
|
}
|
|
1588
|
-
var AUTH_DIR =
|
|
1950
|
+
var AUTH_DIR = path12__default.default.join(os__default.default.homedir(), ".onexthm");
|
|
1589
1951
|
var ENV_URLS = {
|
|
1590
1952
|
dev: "https://platform-dev.onexeos.com",
|
|
1591
|
-
|
|
1953
|
+
staging: "https://platform-staging.onexeos.com",
|
|
1954
|
+
prod: "https://platform-apis.onexeos.com"
|
|
1592
1955
|
};
|
|
1593
1956
|
function getAuthFile(env = "dev") {
|
|
1594
|
-
const newFile =
|
|
1957
|
+
const newFile = path12__default.default.join(AUTH_DIR, `auth-${env}.json`);
|
|
1595
1958
|
if (env === "dev") {
|
|
1596
|
-
const legacyFile =
|
|
1959
|
+
const legacyFile = path12__default.default.join(AUTH_DIR, "auth.json");
|
|
1597
1960
|
if (fs__default.default.existsSync(legacyFile) && !fs__default.default.existsSync(newFile)) {
|
|
1598
1961
|
try {
|
|
1599
1962
|
fs__default.default.moveSync(legacyFile, newFile);
|
|
@@ -1720,7 +2083,7 @@ function decrypt(text, key) {
|
|
|
1720
2083
|
}
|
|
1721
2084
|
|
|
1722
2085
|
// src/commands/init.ts
|
|
1723
|
-
async function initCommand(projectName, options
|
|
2086
|
+
async function initCommand(projectName, options) {
|
|
1724
2087
|
exports.logger.header("Create New OneX Theme Project");
|
|
1725
2088
|
let name;
|
|
1726
2089
|
if (!projectName) {
|
|
@@ -1735,7 +2098,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1735
2098
|
if (!validateThemeName(kebabName)) {
|
|
1736
2099
|
return "Invalid project name. Use lowercase letters, numbers, and hyphens only.";
|
|
1737
2100
|
}
|
|
1738
|
-
if (fs3__default.default.existsSync(
|
|
2101
|
+
if (fs3__default.default.existsSync(path12__default.default.join(process.cwd(), kebabName))) {
|
|
1739
2102
|
return `Directory "${kebabName}" already exists`;
|
|
1740
2103
|
}
|
|
1741
2104
|
return true;
|
|
@@ -1746,14 +2109,14 @@ async function initCommand(projectName, options = {}) {
|
|
|
1746
2109
|
} else {
|
|
1747
2110
|
name = toKebabCase(projectName);
|
|
1748
2111
|
}
|
|
1749
|
-
const projectPath =
|
|
2112
|
+
const projectPath = path12__default.default.join(process.cwd(), name);
|
|
1750
2113
|
if (fs3__default.default.existsSync(projectPath)) {
|
|
1751
2114
|
exports.logger.error(`Directory "${name}" already exists.`);
|
|
1752
2115
|
process.exit(1);
|
|
1753
2116
|
}
|
|
1754
2117
|
if (!options.yes) {
|
|
1755
2118
|
try {
|
|
1756
|
-
const apiUrl = getApiUrl(options.env
|
|
2119
|
+
const apiUrl = getApiUrl(options.env);
|
|
1757
2120
|
const controller = new AbortController();
|
|
1758
2121
|
const timeout = setTimeout(() => controller.abort(), 3e3);
|
|
1759
2122
|
const response = await fetch(
|
|
@@ -1862,7 +2225,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1862
2225
|
description,
|
|
1863
2226
|
author
|
|
1864
2227
|
);
|
|
1865
|
-
const mcpJsonPath =
|
|
2228
|
+
const mcpJsonPath = path12__default.default.join(projectPath, ".mcp.json");
|
|
1866
2229
|
if (fs3__default.default.existsSync(mcpJsonPath)) {
|
|
1867
2230
|
let mcpContent = fs3__default.default.readFileSync(mcpJsonPath, "utf-8");
|
|
1868
2231
|
if (figmaApiKey) {
|
|
@@ -1942,7 +2305,7 @@ async function initCommand(projectName, options = {}) {
|
|
|
1942
2305
|
}
|
|
1943
2306
|
}
|
|
1944
2307
|
async function renameThemeInFiles(projectPath, themeName, displayName, description, author) {
|
|
1945
|
-
const configPath =
|
|
2308
|
+
const configPath = path12__default.default.join(projectPath, "theme.config.ts");
|
|
1946
2309
|
if (fs3__default.default.existsSync(configPath)) {
|
|
1947
2310
|
let content = fs3__default.default.readFileSync(configPath, "utf-8");
|
|
1948
2311
|
content = content.replace(
|
|
@@ -1955,7 +2318,7 @@ async function renameThemeInFiles(projectPath, themeName, displayName, descripti
|
|
|
1955
2318
|
);
|
|
1956
2319
|
fs3__default.default.writeFileSync(configPath, content, "utf-8");
|
|
1957
2320
|
}
|
|
1958
|
-
const pkgPath =
|
|
2321
|
+
const pkgPath = path12__default.default.join(projectPath, "package.json");
|
|
1959
2322
|
if (fs3__default.default.existsSync(pkgPath)) {
|
|
1960
2323
|
let content = fs3__default.default.readFileSync(pkgPath, "utf-8");
|
|
1961
2324
|
content = content.replace(
|
|
@@ -1977,10 +2340,10 @@ async function createSectionCommand(name, options) {
|
|
|
1977
2340
|
ensureOneXProject();
|
|
1978
2341
|
if (!options.theme) {
|
|
1979
2342
|
const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
|
|
1980
|
-
(f) => fs__default.default.existsSync(
|
|
2343
|
+
(f) => fs__default.default.existsSync(path12__default.default.join(process.cwd(), f))
|
|
1981
2344
|
);
|
|
1982
2345
|
if (isStandaloneTheme) {
|
|
1983
|
-
options.theme =
|
|
2346
|
+
options.theme = path12__default.default.basename(process.cwd());
|
|
1984
2347
|
}
|
|
1985
2348
|
}
|
|
1986
2349
|
const sectionName = toKebabCase(name);
|
|
@@ -2043,35 +2406,35 @@ async function createSectionCommand(name, options) {
|
|
|
2043
2406
|
};
|
|
2044
2407
|
exports.logger.startSpinner("Creating section files...");
|
|
2045
2408
|
try {
|
|
2046
|
-
const themePath =
|
|
2047
|
-
const sectionPath =
|
|
2409
|
+
const themePath = path12__default.default.join(getThemesDir(), themeName);
|
|
2410
|
+
const sectionPath = path12__default.default.join(themePath, "sections", sectionName);
|
|
2048
2411
|
const schemaContent = generateSectionSchema(data);
|
|
2049
2412
|
await writeFile(
|
|
2050
|
-
|
|
2413
|
+
path12__default.default.join(sectionPath, `${sectionName}.schema.ts`),
|
|
2051
2414
|
schemaContent
|
|
2052
2415
|
);
|
|
2053
2416
|
if (createTemplate) {
|
|
2054
2417
|
const templateContent = generateSectionTemplate(data);
|
|
2055
2418
|
await writeFile(
|
|
2056
|
-
|
|
2419
|
+
path12__default.default.join(sectionPath, `${sectionName}-default.tsx`),
|
|
2057
2420
|
templateContent
|
|
2058
2421
|
);
|
|
2059
2422
|
}
|
|
2060
2423
|
const indexContent = generateSectionIndex(data, createTemplate);
|
|
2061
|
-
await writeFile(
|
|
2424
|
+
await writeFile(path12__default.default.join(sectionPath, "index.ts"), indexContent);
|
|
2062
2425
|
exports.logger.stopSpinner(true, "Section files created successfully!");
|
|
2063
2426
|
exports.logger.newLine();
|
|
2064
2427
|
exports.logger.section("Next steps:");
|
|
2065
2428
|
exports.logger.log(
|
|
2066
|
-
` 1. Edit schema: ${
|
|
2429
|
+
` 1. Edit schema: ${path12__default.default.relative(process.cwd(), path12__default.default.join(sectionPath, `${sectionName}.schema.ts`))}`
|
|
2067
2430
|
);
|
|
2068
2431
|
if (createTemplate) {
|
|
2069
2432
|
exports.logger.log(
|
|
2070
|
-
` 2. Edit template: ${
|
|
2433
|
+
` 2. Edit template: ${path12__default.default.relative(process.cwd(), path12__default.default.join(sectionPath, `${sectionName}-default.tsx`))}`
|
|
2071
2434
|
);
|
|
2072
2435
|
}
|
|
2073
2436
|
exports.logger.log(
|
|
2074
|
-
` 3. Add to theme manifest: ${
|
|
2437
|
+
` 3. Add to theme manifest: ${path12__default.default.relative(process.cwd(), path12__default.default.join(themePath, "manifest.ts"))}`
|
|
2075
2438
|
);
|
|
2076
2439
|
exports.logger.newLine();
|
|
2077
2440
|
exports.logger.success("Section created successfully!");
|
|
@@ -2219,10 +2582,10 @@ async function createBlockCommand(name, options) {
|
|
|
2219
2582
|
ensureOneXProject();
|
|
2220
2583
|
if (!options.theme) {
|
|
2221
2584
|
const isStandaloneTheme = ["theme.config.ts", "bundle-entry.ts"].some(
|
|
2222
|
-
(f) => fs__default.default.existsSync(
|
|
2585
|
+
(f) => fs__default.default.existsSync(path12__default.default.join(process.cwd(), f))
|
|
2223
2586
|
);
|
|
2224
2587
|
if (isStandaloneTheme) {
|
|
2225
|
-
options.theme =
|
|
2588
|
+
options.theme = path12__default.default.basename(process.cwd());
|
|
2226
2589
|
}
|
|
2227
2590
|
}
|
|
2228
2591
|
const blockName = toKebabCase(name);
|
|
@@ -2297,24 +2660,24 @@ async function createBlockCommand(name, options) {
|
|
|
2297
2660
|
};
|
|
2298
2661
|
exports.logger.startSpinner("Creating block files...");
|
|
2299
2662
|
try {
|
|
2300
|
-
const blockPath = scope === "shared" ?
|
|
2663
|
+
const blockPath = scope === "shared" ? path12__default.default.join(getFeaturesDir(), "blocks", blockName) : path12__default.default.join(getThemesDir(), themeName, "blocks", blockName);
|
|
2301
2664
|
const schemaContent = generateBlockSchema(data);
|
|
2302
2665
|
await writeFile(
|
|
2303
|
-
|
|
2666
|
+
path12__default.default.join(blockPath, `${blockName}.schema.ts`),
|
|
2304
2667
|
schemaContent
|
|
2305
2668
|
);
|
|
2306
2669
|
const componentContent = generateBlockComponent(data);
|
|
2307
|
-
await writeFile(
|
|
2670
|
+
await writeFile(path12__default.default.join(blockPath, `${blockName}.tsx`), componentContent);
|
|
2308
2671
|
const indexContent = generateBlockIndex(data);
|
|
2309
|
-
await writeFile(
|
|
2672
|
+
await writeFile(path12__default.default.join(blockPath, "index.ts"), indexContent);
|
|
2310
2673
|
exports.logger.stopSpinner(true, "Block files created successfully!");
|
|
2311
2674
|
exports.logger.newLine();
|
|
2312
2675
|
exports.logger.section("Next steps:");
|
|
2313
2676
|
exports.logger.log(
|
|
2314
|
-
` 1. Edit schema: ${
|
|
2677
|
+
` 1. Edit schema: ${path12__default.default.relative(process.cwd(), path12__default.default.join(blockPath, `${blockName}.schema.ts`))}`
|
|
2315
2678
|
);
|
|
2316
2679
|
exports.logger.log(
|
|
2317
|
-
` 2. Edit component: ${
|
|
2680
|
+
` 2. Edit component: ${path12__default.default.relative(process.cwd(), path12__default.default.join(blockPath, `${blockName}.tsx`))}`
|
|
2318
2681
|
);
|
|
2319
2682
|
exports.logger.log(
|
|
2320
2683
|
` 3. Register in block registry: src/lib/registry/block-registry.ts`
|
|
@@ -2492,31 +2855,31 @@ async function createComponentCommand(name, options) {
|
|
|
2492
2855
|
};
|
|
2493
2856
|
exports.logger.startSpinner("Creating component files...");
|
|
2494
2857
|
try {
|
|
2495
|
-
const componentPath =
|
|
2858
|
+
const componentPath = path12__default.default.join(
|
|
2496
2859
|
getFeaturesDir(),
|
|
2497
2860
|
"components",
|
|
2498
2861
|
componentName
|
|
2499
2862
|
);
|
|
2500
2863
|
const schemaContent = generateComponentSchema(data);
|
|
2501
2864
|
await writeFile(
|
|
2502
|
-
|
|
2865
|
+
path12__default.default.join(componentPath, `${componentName}.schema.ts`),
|
|
2503
2866
|
schemaContent
|
|
2504
2867
|
);
|
|
2505
2868
|
const componentContent = generateComponent(data);
|
|
2506
2869
|
await writeFile(
|
|
2507
|
-
|
|
2870
|
+
path12__default.default.join(componentPath, `${componentName}.tsx`),
|
|
2508
2871
|
componentContent
|
|
2509
2872
|
);
|
|
2510
2873
|
const indexContent = generateComponentIndex(data);
|
|
2511
|
-
await writeFile(
|
|
2874
|
+
await writeFile(path12__default.default.join(componentPath, "index.ts"), indexContent);
|
|
2512
2875
|
exports.logger.stopSpinner(true, "Component files created successfully!");
|
|
2513
2876
|
exports.logger.newLine();
|
|
2514
2877
|
exports.logger.section("Next steps:");
|
|
2515
2878
|
exports.logger.log(
|
|
2516
|
-
` 1. Edit schema: ${
|
|
2879
|
+
` 1. Edit schema: ${path12__default.default.relative(process.cwd(), path12__default.default.join(componentPath, `${componentName}.schema.ts`))}`
|
|
2517
2880
|
);
|
|
2518
2881
|
exports.logger.log(
|
|
2519
|
-
` 2. Edit component: ${
|
|
2882
|
+
` 2. Edit component: ${path12__default.default.relative(process.cwd(), path12__default.default.join(componentPath, `${componentName}.tsx`))}`
|
|
2520
2883
|
);
|
|
2521
2884
|
exports.logger.log(
|
|
2522
2885
|
` 3. Register in component registry: src/lib/registry/component-registry.ts`
|
|
@@ -2673,13 +3036,13 @@ async function listSections(themeFilter) {
|
|
|
2673
3036
|
return;
|
|
2674
3037
|
}
|
|
2675
3038
|
for (const theme of themes) {
|
|
2676
|
-
const sectionsDir =
|
|
3039
|
+
const sectionsDir = path12__default.default.join(getThemesDir(), theme, "sections");
|
|
2677
3040
|
if (!fs__default.default.existsSync(sectionsDir)) {
|
|
2678
3041
|
continue;
|
|
2679
3042
|
}
|
|
2680
3043
|
const sections = fs__default.default.readdirSync(sectionsDir).filter((name) => {
|
|
2681
|
-
const sectionPath =
|
|
2682
|
-
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"));
|
|
2683
3046
|
});
|
|
2684
3047
|
if (sections.length > 0) {
|
|
2685
3048
|
exports.logger.log(chalk4__default.default.cyan(`
|
|
@@ -2693,11 +3056,11 @@ async function listSections(themeFilter) {
|
|
|
2693
3056
|
}
|
|
2694
3057
|
async function listBlocks(themeFilter) {
|
|
2695
3058
|
exports.logger.section("\u{1F9F1} Blocks");
|
|
2696
|
-
const sharedBlocksDir =
|
|
3059
|
+
const sharedBlocksDir = path12__default.default.join(getFeaturesDir(), "blocks");
|
|
2697
3060
|
if (fs__default.default.existsSync(sharedBlocksDir)) {
|
|
2698
3061
|
const sharedBlocks = fs__default.default.readdirSync(sharedBlocksDir).filter((name) => {
|
|
2699
|
-
const blockPath =
|
|
2700
|
-
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"));
|
|
2701
3064
|
});
|
|
2702
3065
|
if (sharedBlocks.length > 0) {
|
|
2703
3066
|
exports.logger.log(chalk4__default.default.cyan("\n Shared:"));
|
|
@@ -2708,13 +3071,13 @@ async function listBlocks(themeFilter) {
|
|
|
2708
3071
|
}
|
|
2709
3072
|
const themes = themeFilter ? [themeFilter] : listThemes();
|
|
2710
3073
|
for (const theme of themes) {
|
|
2711
|
-
const blocksDir =
|
|
3074
|
+
const blocksDir = path12__default.default.join(getThemesDir(), theme, "blocks");
|
|
2712
3075
|
if (!fs__default.default.existsSync(blocksDir)) {
|
|
2713
3076
|
continue;
|
|
2714
3077
|
}
|
|
2715
3078
|
const blocks = fs__default.default.readdirSync(blocksDir).filter((name) => {
|
|
2716
|
-
const blockPath =
|
|
2717
|
-
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"));
|
|
2718
3081
|
});
|
|
2719
3082
|
if (blocks.length > 0) {
|
|
2720
3083
|
exports.logger.log(chalk4__default.default.cyan(`
|
|
@@ -2728,14 +3091,14 @@ async function listBlocks(themeFilter) {
|
|
|
2728
3091
|
}
|
|
2729
3092
|
async function listComponents() {
|
|
2730
3093
|
exports.logger.section("\u2699\uFE0F Components");
|
|
2731
|
-
const componentsDir =
|
|
3094
|
+
const componentsDir = path12__default.default.join(getFeaturesDir(), "components");
|
|
2732
3095
|
if (!fs__default.default.existsSync(componentsDir)) {
|
|
2733
3096
|
exports.logger.warning("No components directory found");
|
|
2734
3097
|
return;
|
|
2735
3098
|
}
|
|
2736
3099
|
const components = fs__default.default.readdirSync(componentsDir).filter((name) => {
|
|
2737
|
-
const componentPath =
|
|
2738
|
-
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"));
|
|
2739
3102
|
});
|
|
2740
3103
|
if (components.length === 0) {
|
|
2741
3104
|
exports.logger.warning("No components found");
|
|
@@ -2756,11 +3119,11 @@ async function listThemesInfo() {
|
|
|
2756
3119
|
}
|
|
2757
3120
|
exports.logger.log("");
|
|
2758
3121
|
for (const theme of themes) {
|
|
2759
|
-
const themeDir =
|
|
3122
|
+
const themeDir = path12__default.default.join(getThemesDir(), theme);
|
|
2760
3123
|
const candidates = ["theme.config.ts", "bundle-entry.ts", "manifest.ts"];
|
|
2761
3124
|
let manifestContent = "";
|
|
2762
3125
|
for (const candidate of candidates) {
|
|
2763
|
-
const candidatePath =
|
|
3126
|
+
const candidatePath = path12__default.default.join(themeDir, candidate);
|
|
2764
3127
|
if (fs__default.default.existsSync(candidatePath)) {
|
|
2765
3128
|
manifestContent = fs__default.default.readFileSync(candidatePath, "utf-8");
|
|
2766
3129
|
break;
|
|
@@ -2782,6 +3145,7 @@ async function listThemesInfo() {
|
|
|
2782
3145
|
|
|
2783
3146
|
// src/commands/build.ts
|
|
2784
3147
|
init_logger();
|
|
3148
|
+
init_detect_nextjs();
|
|
2785
3149
|
async function buildCommand(options) {
|
|
2786
3150
|
exports.logger.header("Build Theme");
|
|
2787
3151
|
let themePath;
|
|
@@ -2789,14 +3153,14 @@ async function buildCommand(options) {
|
|
|
2789
3153
|
if (options.theme) {
|
|
2790
3154
|
themeName = options.theme;
|
|
2791
3155
|
try {
|
|
2792
|
-
const workspaceThemePath =
|
|
3156
|
+
const workspaceThemePath = path12__default.default.join(getThemesDir(), themeName);
|
|
2793
3157
|
if (fs__default.default.existsSync(workspaceThemePath)) {
|
|
2794
3158
|
themePath = workspaceThemePath;
|
|
2795
3159
|
} else {
|
|
2796
|
-
themePath =
|
|
3160
|
+
themePath = path12__default.default.join(process.cwd(), themeName);
|
|
2797
3161
|
}
|
|
2798
3162
|
} catch {
|
|
2799
|
-
themePath =
|
|
3163
|
+
themePath = path12__default.default.join(process.cwd(), themeName);
|
|
2800
3164
|
}
|
|
2801
3165
|
if (!fs__default.default.existsSync(themePath)) {
|
|
2802
3166
|
exports.logger.error(`Theme "${themeName}" not found.`);
|
|
@@ -2806,11 +3170,14 @@ async function buildCommand(options) {
|
|
|
2806
3170
|
const isThemeDir = [
|
|
2807
3171
|
"theme.config.ts",
|
|
2808
3172
|
"bundle-entry.ts",
|
|
2809
|
-
"manifest.ts"
|
|
2810
|
-
|
|
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)));
|
|
2811
3178
|
if (isThemeDir) {
|
|
2812
3179
|
themePath = process.cwd();
|
|
2813
|
-
themeName =
|
|
3180
|
+
themeName = path12__default.default.basename(themePath);
|
|
2814
3181
|
exports.logger.info(`Building current theme: ${themeName}`);
|
|
2815
3182
|
} else {
|
|
2816
3183
|
exports.logger.error(
|
|
@@ -2819,7 +3186,7 @@ async function buildCommand(options) {
|
|
|
2819
3186
|
process.exit(1);
|
|
2820
3187
|
}
|
|
2821
3188
|
}
|
|
2822
|
-
const packageJsonPath =
|
|
3189
|
+
const packageJsonPath = path12__default.default.join(themePath, "package.json");
|
|
2823
3190
|
const hasPkgJson = fs__default.default.existsSync(packageJsonPath);
|
|
2824
3191
|
if (!hasPkgJson) {
|
|
2825
3192
|
exports.logger.warning(
|
|
@@ -2835,30 +3202,42 @@ async function buildCommand(options) {
|
|
|
2835
3202
|
}
|
|
2836
3203
|
exports.logger.newLine();
|
|
2837
3204
|
exports.logger.section("Build Steps");
|
|
2838
|
-
exports.logger.startSpinner("Running type check...");
|
|
2839
|
-
const typeCheckSuccess = await runCommand("pnpm", ["type-check"], themePath);
|
|
2840
|
-
if (!typeCheckSuccess) {
|
|
2841
|
-
exports.logger.stopSpinner(false, "Type check failed");
|
|
2842
|
-
exports.logger.error("Fix type errors before building.");
|
|
2843
|
-
process.exit(1);
|
|
2844
|
-
}
|
|
2845
|
-
exports.logger.stopSpinner(true, "Type check passed");
|
|
2846
|
-
exports.logger.startSpinner("Running linter...");
|
|
2847
|
-
const lintSuccess = await runCommand("pnpm", ["lint"], themePath);
|
|
2848
|
-
if (!lintSuccess) {
|
|
2849
|
-
exports.logger.stopSpinner(false, "Lint failed");
|
|
2850
|
-
exports.logger.error("Fix lint errors before building.");
|
|
2851
|
-
process.exit(1);
|
|
2852
|
-
}
|
|
2853
|
-
exports.logger.stopSpinner(true, "Lint passed");
|
|
2854
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
|
+
}
|
|
2855
3233
|
const buildScript = pkgJson.scripts?.build || "";
|
|
2856
3234
|
const isRecursive = buildScript.includes("onexthm build") || buildScript.includes("onex build") || buildScript.includes("onex-cli build");
|
|
3235
|
+
const isNextjs = isNextjsProject(themePath);
|
|
2857
3236
|
exports.logger.startSpinner(
|
|
2858
3237
|
options.watch ? "Building (watch mode)..." : "Building..."
|
|
2859
3238
|
);
|
|
2860
3239
|
let buildSuccess;
|
|
2861
|
-
if (isRecursive) {
|
|
3240
|
+
if (isRecursive || isNextjs) {
|
|
2862
3241
|
const { compileStandaloneTheme: compileStandaloneTheme2 } = await Promise.resolve().then(() => (init_compile_theme(), compile_theme_exports));
|
|
2863
3242
|
buildSuccess = await compileStandaloneTheme2(themePath, themeName);
|
|
2864
3243
|
} else {
|
|
@@ -2875,9 +3254,9 @@ async function buildCommand(options) {
|
|
|
2875
3254
|
exports.logger.success("\u2713 Theme built successfully!");
|
|
2876
3255
|
exports.logger.newLine();
|
|
2877
3256
|
exports.logger.info(`Theme: ${themeName}`);
|
|
2878
|
-
const distPath =
|
|
3257
|
+
const distPath = path12__default.default.join(themePath, "dist");
|
|
2879
3258
|
if (fs__default.default.existsSync(distPath)) {
|
|
2880
|
-
exports.logger.log(`Output: ${
|
|
3259
|
+
exports.logger.log(`Output: ${path12__default.default.relative(process.cwd(), distPath)}`);
|
|
2881
3260
|
const files = fs__default.default.readdirSync(distPath);
|
|
2882
3261
|
exports.logger.log(`Files: ${files.length}`);
|
|
2883
3262
|
}
|
|
@@ -3018,8 +3397,8 @@ async function downloadBundleZip(apiUrl, themeId, version) {
|
|
|
3018
3397
|
async function createCompatibilityFiles(outputDir, manifest) {
|
|
3019
3398
|
const entryFile = manifest.output?.entry || "bundle-entry.js";
|
|
3020
3399
|
if (entryFile !== "bundle-entry.js" && entryFile.startsWith("bundle-entry-")) {
|
|
3021
|
-
const hashedPath =
|
|
3022
|
-
const stablePath =
|
|
3400
|
+
const hashedPath = path12__default.default.join(outputDir, entryFile);
|
|
3401
|
+
const stablePath = path12__default.default.join(outputDir, "bundle-entry.js");
|
|
3023
3402
|
if (await fs__default.default.pathExists(hashedPath)) {
|
|
3024
3403
|
await fs__default.default.copy(hashedPath, stablePath);
|
|
3025
3404
|
const mapPath = hashedPath + ".map";
|
|
@@ -3028,13 +3407,13 @@ async function createCompatibilityFiles(outputDir, manifest) {
|
|
|
3028
3407
|
}
|
|
3029
3408
|
}
|
|
3030
3409
|
}
|
|
3031
|
-
const sectionsRegistryPath =
|
|
3410
|
+
const sectionsRegistryPath = path12__default.default.join(outputDir, "sections-registry.js");
|
|
3032
3411
|
const content = `// Re-export all sections from bundle-entry
|
|
3033
3412
|
// This file exists to maintain compatibility with the import path
|
|
3034
3413
|
export * from './bundle-entry.js';
|
|
3035
3414
|
`;
|
|
3036
3415
|
await fs__default.default.writeFile(sectionsRegistryPath, content, "utf-8");
|
|
3037
|
-
const pkgJsonPath =
|
|
3416
|
+
const pkgJsonPath = path12__default.default.join(outputDir, "package.json");
|
|
3038
3417
|
await fs__default.default.writeFile(pkgJsonPath, '{\n "type": "module"\n}\n', "utf-8");
|
|
3039
3418
|
}
|
|
3040
3419
|
function showDownloadFailureHelp(themeId, apiUrl) {
|
|
@@ -3075,7 +3454,7 @@ function showDownloadFailureHelp(themeId, apiUrl) {
|
|
|
3075
3454
|
}
|
|
3076
3455
|
async function downloadCommand(options) {
|
|
3077
3456
|
exports.logger.header("Download Theme");
|
|
3078
|
-
const env = options.env
|
|
3457
|
+
const env = options.env;
|
|
3079
3458
|
const apiUrl = getApiUrl(env);
|
|
3080
3459
|
exports.logger.info(`Environment: ${env} (${apiUrl})`);
|
|
3081
3460
|
const spinner = ora__default.default("Initializing download...").start();
|
|
@@ -3133,7 +3512,7 @@ async function downloadCommand(options) {
|
|
|
3133
3512
|
zip.extractAllTo(outputDir, true);
|
|
3134
3513
|
const entries = zip.getEntries().filter((e) => !e.isDirectory);
|
|
3135
3514
|
spinner.succeed(`Extracted ${entries.length} files to ${outputDir}`);
|
|
3136
|
-
const manifestPath =
|
|
3515
|
+
const manifestPath = path12__default.default.join(outputDir, "manifest.json");
|
|
3137
3516
|
const manifest = await fs__default.default.readJson(manifestPath);
|
|
3138
3517
|
await createCompatibilityFiles(outputDir, manifest);
|
|
3139
3518
|
console.log();
|
|
@@ -3254,7 +3633,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3254
3633
|
const oldPrefix = `${oldName}-`;
|
|
3255
3634
|
const newPrefix = `${newName}-`;
|
|
3256
3635
|
const newDisplayName = newName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3257
|
-
const pkgPath =
|
|
3636
|
+
const pkgPath = path12__default.default.join(themeDir, "package.json");
|
|
3258
3637
|
if (await fs__default.default.pathExists(pkgPath)) {
|
|
3259
3638
|
const pkg = await fs__default.default.readJson(pkgPath);
|
|
3260
3639
|
pkg.name = `@onex-themes/${newName}`;
|
|
@@ -3270,7 +3649,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3270
3649
|
}
|
|
3271
3650
|
await fs__default.default.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
3272
3651
|
}
|
|
3273
|
-
const configPath =
|
|
3652
|
+
const configPath = path12__default.default.join(themeDir, "theme.config.ts");
|
|
3274
3653
|
if (await fs__default.default.pathExists(configPath)) {
|
|
3275
3654
|
let content = await fs__default.default.readFile(configPath, "utf-8");
|
|
3276
3655
|
content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
|
|
@@ -3280,7 +3659,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3280
3659
|
);
|
|
3281
3660
|
await fs__default.default.writeFile(configPath, content);
|
|
3282
3661
|
}
|
|
3283
|
-
const layoutPath =
|
|
3662
|
+
const layoutPath = path12__default.default.join(themeDir, "theme.layout.ts");
|
|
3284
3663
|
if (await fs__default.default.pathExists(layoutPath)) {
|
|
3285
3664
|
let content = await fs__default.default.readFile(layoutPath, "utf-8");
|
|
3286
3665
|
content = content.replace(/id:\s*"[^"]*"/, `id: "${newName}"`);
|
|
@@ -3293,7 +3672,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3293
3672
|
const oldDisplayName = oldName.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" ");
|
|
3294
3673
|
const tsFiles = await glob.glob("**/*.ts", { cwd: themeDir, nodir: true });
|
|
3295
3674
|
for (const file of tsFiles) {
|
|
3296
|
-
const filePath =
|
|
3675
|
+
const filePath = path12__default.default.join(themeDir, file);
|
|
3297
3676
|
let content = await fs__default.default.readFile(filePath, "utf-8");
|
|
3298
3677
|
const original = content;
|
|
3299
3678
|
content = content.replace(
|
|
@@ -3315,7 +3694,7 @@ async function renameTheme(themeDir, oldName, newName) {
|
|
|
3315
3694
|
}
|
|
3316
3695
|
async function cloneCommand(themeName, options) {
|
|
3317
3696
|
exports.logger.header("Clone Theme Source");
|
|
3318
|
-
const env = options.env
|
|
3697
|
+
const env = options.env;
|
|
3319
3698
|
const apiUrl = getApiUrl(env);
|
|
3320
3699
|
exports.logger.info(`Environment: ${env} (${apiUrl})`);
|
|
3321
3700
|
if (options.bucket) {
|
|
@@ -3336,7 +3715,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3336
3715
|
}
|
|
3337
3716
|
const spinner = ora__default.default("Initializing clone...").start();
|
|
3338
3717
|
try {
|
|
3339
|
-
const outputDir = options.output ||
|
|
3718
|
+
const outputDir = options.output || path12__default.default.resolve(process.cwd(), newName);
|
|
3340
3719
|
if (await fs__default.default.pathExists(outputDir)) {
|
|
3341
3720
|
spinner.fail(chalk4__default.default.red(`Directory already exists: ${outputDir}`));
|
|
3342
3721
|
exports.logger.info(
|
|
@@ -3382,7 +3761,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3382
3761
|
spinner.succeed(
|
|
3383
3762
|
`Renamed theme: ${chalk4__default.default.gray(themeName)} \u2192 ${chalk4__default.default.cyan(newName)}`
|
|
3384
3763
|
);
|
|
3385
|
-
const envExamplePath =
|
|
3764
|
+
const envExamplePath = path12__default.default.join(outputDir, ".env.example");
|
|
3386
3765
|
if (!await fs__default.default.pathExists(envExamplePath)) {
|
|
3387
3766
|
await fs__default.default.writeFile(
|
|
3388
3767
|
envExamplePath,
|
|
@@ -3395,7 +3774,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3395
3774
|
].join("\n")
|
|
3396
3775
|
);
|
|
3397
3776
|
}
|
|
3398
|
-
const mcpJsonPath =
|
|
3777
|
+
const mcpJsonPath = path12__default.default.join(outputDir, ".mcp.json");
|
|
3399
3778
|
if (await fs__default.default.pathExists(mcpJsonPath)) {
|
|
3400
3779
|
const { default: inquirerMod } = await import('inquirer');
|
|
3401
3780
|
const { figmaApiKey } = await inquirerMod.prompt([
|
|
@@ -3420,7 +3799,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3420
3799
|
}
|
|
3421
3800
|
if (options.install !== false) {
|
|
3422
3801
|
const hasPkgJson = await fs__default.default.pathExists(
|
|
3423
|
-
|
|
3802
|
+
path12__default.default.join(outputDir, "package.json")
|
|
3424
3803
|
);
|
|
3425
3804
|
if (hasPkgJson) {
|
|
3426
3805
|
spinner.start("Installing dependencies...");
|
|
@@ -3448,7 +3827,7 @@ async function cloneCommand(themeName, options) {
|
|
|
3448
3827
|
console.log(chalk4__default.default.cyan(" Files: ") + chalk4__default.default.white(entries.length));
|
|
3449
3828
|
console.log();
|
|
3450
3829
|
console.log(chalk4__default.default.cyan("Next steps:"));
|
|
3451
|
-
console.log(chalk4__default.default.gray(` cd ${
|
|
3830
|
+
console.log(chalk4__default.default.gray(` cd ${path12__default.default.relative(process.cwd(), outputDir)}`));
|
|
3452
3831
|
console.log(
|
|
3453
3832
|
chalk4__default.default.gray(" cp .env.example .env # then add your Company ID")
|
|
3454
3833
|
);
|