@salesforce/storefront-next-dev 0.2.0-alpha.2 → 0.3.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cartridge-services/index.d.ts.map +1 -1
- package/dist/cartridge-services/index.js +171 -50
- package/dist/cartridge-services/index.js.map +1 -1
- package/dist/commands/create-bundle.js +12 -11
- package/dist/commands/create-instructions.js +7 -5
- package/dist/commands/create-storefront.js +18 -22
- package/dist/commands/deploy-cartridge.js +67 -26
- package/dist/commands/dev.js +6 -4
- package/dist/commands/extensions/create.js +2 -0
- package/dist/commands/extensions/install.js +3 -7
- package/dist/commands/extensions/list.js +2 -0
- package/dist/commands/extensions/remove.js +3 -7
- package/dist/commands/generate-cartridge.js +23 -2
- package/dist/commands/preview.js +15 -10
- package/dist/commands/push.js +25 -19
- package/dist/commands/validate-cartridge.js +51 -0
- package/dist/config.js +74 -47
- package/dist/configs/react-router.config.d.ts.map +1 -1
- package/dist/configs/react-router.config.js +36 -0
- package/dist/configs/react-router.config.js.map +1 -1
- package/dist/dependency-utils.js +14 -16
- package/dist/entry/server.d.ts.map +1 -1
- package/dist/entry/server.js +221 -11
- package/dist/entry/server.js.map +1 -1
- package/dist/generate-cartridge.js +106 -50
- package/dist/index.d.ts +127 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1147 -167
- package/dist/index.js.map +1 -1
- package/dist/local-dev-setup.js +13 -13
- package/dist/logger/index.d.ts +20 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +69 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logger.js +79 -33
- package/dist/logger2.js +1 -0
- package/dist/manage-extensions.js +7 -13
- package/dist/mrt/ssr.mjs +60 -72
- package/dist/mrt/ssr.mjs.map +1 -1
- package/dist/mrt/streamingHandler.mjs +66 -78
- package/dist/mrt/streamingHandler.mjs.map +1 -1
- package/dist/react-router/Scripts.d.ts +1 -1
- package/dist/react-router/Scripts.d.ts.map +1 -1
- package/dist/react-router/Scripts.js +38 -2
- package/dist/react-router/Scripts.js.map +1 -1
- package/dist/server.js +296 -16
- package/dist/utils.js +4 -4
- package/dist/validate-cartridge.js +45 -0
- package/package.json +22 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/cartridge-services/generate-cartridge.ts"],"sourcesContent":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/cartridge-services/generate-cartridge.ts"],"sourcesContent":[],"mappings":";;AA80BA;;;AAIG,UA1Ec,uBAAA,CA0Ed;EAAO;;;;;;;;;;;;;;;;;;;;UAlDO,sBAAA;;;;;;iBA8CK,gBAAA,gEAGR,0BACX,QAAQ"}
|
|
@@ -6,7 +6,73 @@ import { existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
|
6
6
|
import { tmpdir } from "node:os";
|
|
7
7
|
import { randomUUID } from "node:crypto";
|
|
8
8
|
import { npmRunPathEnv } from "npm-run-path";
|
|
9
|
+
import chalk from "chalk";
|
|
9
10
|
|
|
11
|
+
//#region src/utils/logger.ts
|
|
12
|
+
const LEVEL_PRIORITY = {
|
|
13
|
+
error: 0,
|
|
14
|
+
warn: 1,
|
|
15
|
+
info: 2,
|
|
16
|
+
debug: 3
|
|
17
|
+
};
|
|
18
|
+
let overrideLevel;
|
|
19
|
+
/**
|
|
20
|
+
* Returns true when the `DEBUG` env var targets sfnext or is a general enable flag.
|
|
21
|
+
* Avoids accidentally enabling debug mode when DEBUG is set for unrelated libraries
|
|
22
|
+
* (e.g. `DEBUG=express:*`).
|
|
23
|
+
*/
|
|
24
|
+
function debugEnablesSfnext() {
|
|
25
|
+
const raw = process.env.DEBUG?.trim();
|
|
26
|
+
if (!raw) return false;
|
|
27
|
+
const normalized = raw.toLowerCase();
|
|
28
|
+
if ([
|
|
29
|
+
"1",
|
|
30
|
+
"true",
|
|
31
|
+
"yes",
|
|
32
|
+
"on"
|
|
33
|
+
].includes(normalized)) return true;
|
|
34
|
+
return raw.split(",").some((token) => {
|
|
35
|
+
const value = token.trim();
|
|
36
|
+
return value === "*" || value === "sfnext" || value === "sfnext:*";
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function resolveLevel() {
|
|
40
|
+
if (overrideLevel) return overrideLevel;
|
|
41
|
+
const envLevel = process.env.MRT_LOG_LEVEL ?? process.env.SFCC_LOG_LEVEL;
|
|
42
|
+
if (envLevel && envLevel in LEVEL_PRIORITY) return envLevel;
|
|
43
|
+
if (debugEnablesSfnext()) return "debug";
|
|
44
|
+
if (process.env.NODE_ENV === "production") return "warn";
|
|
45
|
+
return "info";
|
|
46
|
+
}
|
|
47
|
+
function shouldLog(level) {
|
|
48
|
+
return LEVEL_PRIORITY[level] <= LEVEL_PRIORITY[resolveLevel()];
|
|
49
|
+
}
|
|
50
|
+
const logger = {
|
|
51
|
+
error(msg, ...args) {
|
|
52
|
+
if (!shouldLog("error")) return;
|
|
53
|
+
console.error(chalk.red("[sfnext:error]"), msg, ...args);
|
|
54
|
+
},
|
|
55
|
+
warn(msg, ...args) {
|
|
56
|
+
if (!shouldLog("warn")) return;
|
|
57
|
+
console.warn(chalk.yellow("[sfnext:warn]"), msg, ...args);
|
|
58
|
+
},
|
|
59
|
+
info(msg, ...args) {
|
|
60
|
+
if (!shouldLog("info")) return;
|
|
61
|
+
console.log(chalk.cyan("[sfnext:info]"), msg, ...args);
|
|
62
|
+
},
|
|
63
|
+
debug(msg, ...args) {
|
|
64
|
+
if (!shouldLog("debug")) return;
|
|
65
|
+
console.log(chalk.gray("[sfnext:debug]"), msg, ...args);
|
|
66
|
+
},
|
|
67
|
+
setLevel(level) {
|
|
68
|
+
overrideLevel = level;
|
|
69
|
+
},
|
|
70
|
+
getLevel() {
|
|
71
|
+
return resolveLevel();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
//#endregion
|
|
10
76
|
//#region src/cartridge-services/react-router-config.ts
|
|
11
77
|
let isCliAvailable = null;
|
|
12
78
|
function checkReactRouterCli(projectDirectory) {
|
|
@@ -76,7 +142,7 @@ function filePathToRoute(filePath, projectRoot) {
|
|
|
76
142
|
const routeFileNormalized = routeFilePosix.replace(/^\.\//, "");
|
|
77
143
|
if (filePathPosix.endsWith(routeFileNormalized) || filePathPosix.endsWith(`/${routeFileNormalized}`)) return route.path;
|
|
78
144
|
}
|
|
79
|
-
|
|
145
|
+
logger.warn(`Could not find route for file: ${filePath}`);
|
|
80
146
|
return "/unknown";
|
|
81
147
|
}
|
|
82
148
|
/**
|
|
@@ -151,7 +217,7 @@ const TYPE_MAPPING = {
|
|
|
151
217
|
function resolveAttributeType(decoratorType, tsMorphType, fieldName) {
|
|
152
218
|
if (decoratorType) {
|
|
153
219
|
if (!VALID_ATTRIBUTE_TYPES.includes(decoratorType)) {
|
|
154
|
-
|
|
220
|
+
logger.error(`Invalid attribute type '${decoratorType}' for field '${fieldName || "unknown"}'. Valid types are: ${VALID_ATTRIBUTE_TYPES.join(", ")}`);
|
|
155
221
|
process.exit(1);
|
|
156
222
|
}
|
|
157
223
|
return decoratorType;
|
|
@@ -176,6 +242,30 @@ function getTypeFromTsMorph(property, _sourceFile) {
|
|
|
176
242
|
} catch {}
|
|
177
243
|
return "string";
|
|
178
244
|
}
|
|
245
|
+
/**
|
|
246
|
+
* Resolve a variable's initializer expression from the same source file,
|
|
247
|
+
* unwrapping `as const` type assertions.
|
|
248
|
+
*/
|
|
249
|
+
function resolveVariableInitializer(sourceFile, name) {
|
|
250
|
+
const varDecl = sourceFile.getVariableDeclaration(name);
|
|
251
|
+
if (!varDecl) return void 0;
|
|
252
|
+
let initializer = varDecl.getInitializer();
|
|
253
|
+
if (initializer && Node.isAsExpression(initializer)) initializer = initializer.getExpression();
|
|
254
|
+
return initializer;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Check whether an AST node is a type that `parseExpression` can resolve to a
|
|
258
|
+
* concrete JS value (as opposed to falling through to `getText()`).
|
|
259
|
+
*/
|
|
260
|
+
function isResolvableLiteral(node) {
|
|
261
|
+
return Node.isStringLiteral(node) || Node.isNumericLiteral(node) || Node.isTrueLiteral(node) || Node.isFalseLiteral(node) || Node.isObjectLiteralExpression(node) || Node.isArrayLiteralExpression(node);
|
|
262
|
+
}
|
|
263
|
+
var UnresolvedConstantReferenceError = class extends Error {
|
|
264
|
+
constructor(reference) {
|
|
265
|
+
super(`Cannot resolve constant reference '${reference}'. Ensure the variable is declared in the same file as a literal value.`);
|
|
266
|
+
this.name = "UnresolvedConstantReferenceError";
|
|
267
|
+
}
|
|
268
|
+
};
|
|
179
269
|
function parseExpression(expression) {
|
|
180
270
|
if (Node.isStringLiteral(expression)) return expression.getLiteralValue();
|
|
181
271
|
else if (Node.isNumericLiteral(expression)) return expression.getLiteralValue();
|
|
@@ -183,7 +273,26 @@ function parseExpression(expression) {
|
|
|
183
273
|
else if (Node.isFalseLiteral(expression)) return false;
|
|
184
274
|
else if (Node.isObjectLiteralExpression(expression)) return parseNestedObject(expression);
|
|
185
275
|
else if (Node.isArrayLiteralExpression(expression)) return parseArrayLiteral(expression);
|
|
186
|
-
else
|
|
276
|
+
else if (Node.isPropertyAccessExpression(expression)) {
|
|
277
|
+
const obj = expression.getExpression();
|
|
278
|
+
const propName = expression.getName();
|
|
279
|
+
if (Node.isIdentifier(obj)) {
|
|
280
|
+
const resolved = resolveVariableInitializer(expression.getSourceFile(), obj.getText());
|
|
281
|
+
if (resolved && Node.isObjectLiteralExpression(resolved)) {
|
|
282
|
+
const prop = resolved.getProperty(propName);
|
|
283
|
+
if (prop && Node.isPropertyAssignment(prop)) {
|
|
284
|
+
const propInit = prop.getInitializer();
|
|
285
|
+
if (propInit) return parseExpression(propInit);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
throw new UnresolvedConstantReferenceError(expression.getText());
|
|
289
|
+
}
|
|
290
|
+
return expression.getText();
|
|
291
|
+
} else if (Node.isIdentifier(expression)) {
|
|
292
|
+
const resolved = resolveVariableInitializer(expression.getSourceFile(), expression.getText());
|
|
293
|
+
if (resolved && isResolvableLiteral(resolved)) return parseExpression(resolved);
|
|
294
|
+
return expression.getText();
|
|
295
|
+
} else return expression.getText();
|
|
187
296
|
}
|
|
188
297
|
function parseNestedObject(objectLiteral) {
|
|
189
298
|
const result = {};
|
|
@@ -195,7 +304,7 @@ function parseNestedObject(objectLiteral) {
|
|
|
195
304
|
if (initializer) result[name] = parseExpression(initializer);
|
|
196
305
|
}
|
|
197
306
|
} catch (error) {
|
|
198
|
-
|
|
307
|
+
logger.warn(`Could not parse nested object: ${error.message}`);
|
|
199
308
|
return result;
|
|
200
309
|
}
|
|
201
310
|
return result;
|
|
@@ -206,7 +315,7 @@ function parseArrayLiteral(arrayLiteral) {
|
|
|
206
315
|
const elements = arrayLiteral.getElements();
|
|
207
316
|
for (const element of elements) result.push(parseExpression(element));
|
|
208
317
|
} catch (error) {
|
|
209
|
-
|
|
318
|
+
logger.warn(`Could not parse array literal: ${error.message}`);
|
|
210
319
|
}
|
|
211
320
|
return result;
|
|
212
321
|
}
|
|
@@ -239,7 +348,8 @@ function parseDecoratorArgs(decorator) {
|
|
|
239
348
|
}
|
|
240
349
|
return result;
|
|
241
350
|
} catch (error) {
|
|
242
|
-
|
|
351
|
+
if (error instanceof UnresolvedConstantReferenceError) throw error;
|
|
352
|
+
logger.warn(`Could not parse decorator arguments: ${error.message}`);
|
|
243
353
|
return result;
|
|
244
354
|
}
|
|
245
355
|
}
|
|
@@ -268,11 +378,15 @@ function extractAttributesFromSource(sourceFile, className) {
|
|
|
268
378
|
attributes.push(attribute);
|
|
269
379
|
}
|
|
270
380
|
} catch (error) {
|
|
271
|
-
|
|
381
|
+
if (error instanceof UnresolvedConstantReferenceError) throw error;
|
|
382
|
+
logger.warn(`Could not extract attributes from class ${className}: ${error.message}`);
|
|
272
383
|
}
|
|
273
384
|
return attributes;
|
|
274
385
|
}
|
|
275
|
-
function
|
|
386
|
+
function normalizeComponentTypeId(typeId, defaultGroup) {
|
|
387
|
+
return typeId.includes(".") ? typeId : `${defaultGroup}.${typeId}`;
|
|
388
|
+
}
|
|
389
|
+
function extractRegionDefinitionsFromSource(sourceFile, className, defaultComponentGroup = DEFAULT_COMPONENT_GROUP) {
|
|
276
390
|
const regionDefinitions = [];
|
|
277
391
|
try {
|
|
278
392
|
const classDeclaration = sourceFile.getClass(className);
|
|
@@ -291,8 +405,8 @@ function extractRegionDefinitionsFromSource(sourceFile, className) {
|
|
|
291
405
|
name: regionConfig.name || "Region"
|
|
292
406
|
};
|
|
293
407
|
if (regionConfig.componentTypes) regionDefinition.component_types = regionConfig.componentTypes;
|
|
294
|
-
if (Array.isArray(regionConfig.componentTypeInclusions)) regionDefinition.component_type_inclusions = regionConfig.componentTypeInclusions.map((incl) => ({ type_id: incl }));
|
|
295
|
-
if (Array.isArray(regionConfig.componentTypeExclusions)) regionDefinition.component_type_exclusions = regionConfig.componentTypeExclusions.map((excl) => ({ type_id: excl }));
|
|
408
|
+
if (Array.isArray(regionConfig.componentTypeInclusions)) regionDefinition.component_type_inclusions = regionConfig.componentTypeInclusions.map((incl) => ({ type_id: normalizeComponentTypeId(String(incl), defaultComponentGroup) }));
|
|
409
|
+
if (Array.isArray(regionConfig.componentTypeExclusions)) regionDefinition.component_type_exclusions = regionConfig.componentTypeExclusions.map((excl) => ({ type_id: normalizeComponentTypeId(String(excl), defaultComponentGroup) }));
|
|
296
410
|
if (regionConfig.maxComponents !== void 0) regionDefinition.max_components = regionConfig.maxComponents;
|
|
297
411
|
if (regionConfig.minComponents !== void 0) regionDefinition.min_components = regionConfig.minComponents;
|
|
298
412
|
if (regionConfig.allowMultiple !== void 0) regionDefinition.allow_multiple = regionConfig.allowMultiple;
|
|
@@ -303,7 +417,7 @@ function extractRegionDefinitionsFromSource(sourceFile, className) {
|
|
|
303
417
|
}
|
|
304
418
|
}
|
|
305
419
|
} catch (error) {
|
|
306
|
-
|
|
420
|
+
logger.warn(`Warning: Could not extract region definitions from class ${className}: ${error.message}`);
|
|
307
421
|
}
|
|
308
422
|
return regionDefinitions;
|
|
309
423
|
}
|
|
@@ -324,12 +438,13 @@ async function processComponentFile(filePath, _projectRoot) {
|
|
|
324
438
|
const className = classDeclaration.getName();
|
|
325
439
|
if (!className) continue;
|
|
326
440
|
const componentConfig = parseDecoratorArgs(componentDecorator);
|
|
441
|
+
const componentGroup = String(componentConfig.group || DEFAULT_COMPONENT_GROUP);
|
|
327
442
|
const attributes = extractAttributesFromSource(sourceFile, className);
|
|
328
|
-
const regionDefinitions = extractRegionDefinitionsFromSource(sourceFile, className);
|
|
443
|
+
const regionDefinitions = extractRegionDefinitionsFromSource(sourceFile, className, componentGroup);
|
|
329
444
|
const componentMetadata = {
|
|
330
445
|
typeId: componentConfig.id || className.toLowerCase(),
|
|
331
446
|
name: componentConfig.name || toHumanReadableName(className),
|
|
332
|
-
group:
|
|
447
|
+
group: componentGroup,
|
|
333
448
|
description: componentConfig.description || `Custom component: ${className}`,
|
|
334
449
|
regionDefinitions,
|
|
335
450
|
attributes
|
|
@@ -337,11 +452,13 @@ async function processComponentFile(filePath, _projectRoot) {
|
|
|
337
452
|
components.push(componentMetadata);
|
|
338
453
|
}
|
|
339
454
|
} catch (error) {
|
|
340
|
-
|
|
455
|
+
if (error instanceof UnresolvedConstantReferenceError) throw error;
|
|
456
|
+
logger.warn(`Could not process file ${filePath}:`, error.message);
|
|
341
457
|
}
|
|
342
458
|
return components;
|
|
343
459
|
} catch (error) {
|
|
344
|
-
|
|
460
|
+
if (error instanceof UnresolvedConstantReferenceError) throw error;
|
|
461
|
+
logger.warn(`Could not read file ${filePath}:`, error.message);
|
|
345
462
|
return [];
|
|
346
463
|
}
|
|
347
464
|
}
|
|
@@ -377,11 +494,11 @@ async function processPageTypeFile(filePath, projectRoot) {
|
|
|
377
494
|
pageTypes.push(pageTypeMetadata);
|
|
378
495
|
}
|
|
379
496
|
} catch (error) {
|
|
380
|
-
|
|
497
|
+
logger.warn(`Could not process file ${filePath}:`, error.message);
|
|
381
498
|
}
|
|
382
499
|
return pageTypes;
|
|
383
500
|
} catch (error) {
|
|
384
|
-
|
|
501
|
+
logger.warn(`Could not read file ${filePath}:`, error.message);
|
|
385
502
|
return [];
|
|
386
503
|
}
|
|
387
504
|
}
|
|
@@ -404,11 +521,11 @@ async function processAspectFile(filePath, _projectRoot) {
|
|
|
404
521
|
};
|
|
405
522
|
aspects.push(aspectMetadata);
|
|
406
523
|
} catch (parseError) {
|
|
407
|
-
|
|
524
|
+
logger.warn(`Could not parse JSON in file ${filePath}:`, parseError.message);
|
|
408
525
|
}
|
|
409
526
|
return aspects;
|
|
410
527
|
} catch (error) {
|
|
411
|
-
|
|
528
|
+
logger.warn(`Could not read file ${filePath}:`, error.message);
|
|
412
529
|
return [];
|
|
413
530
|
}
|
|
414
531
|
}
|
|
@@ -437,7 +554,7 @@ async function generateComponentCartridge(component, outputDir, dryRun = false)
|
|
|
437
554
|
await writeFile(outputPath, JSON.stringify(cartridgeData, null, 2));
|
|
438
555
|
}
|
|
439
556
|
const prefix = dryRun ? " - [DRY RUN]" : " -";
|
|
440
|
-
|
|
557
|
+
logger.debug(`${prefix} ${String(component.typeId)}: ${String(component.name)} (${String(component.attributes.length)} attributes) → ${fileName}.json`);
|
|
441
558
|
}
|
|
442
559
|
async function generatePageTypeCartridge(pageType, outputDir, dryRun = false) {
|
|
443
560
|
const fileName = toCamelCaseFileName(pageType.name);
|
|
@@ -460,7 +577,7 @@ async function generatePageTypeCartridge(pageType, outputDir, dryRun = false) {
|
|
|
460
577
|
await writeFile(outputPath, JSON.stringify(cartridgeData, null, 2));
|
|
461
578
|
}
|
|
462
579
|
const prefix = dryRun ? " - [DRY RUN]" : " -";
|
|
463
|
-
|
|
580
|
+
logger.debug(`${prefix} ${String(pageType.name)}: ${String(pageType.description)} (${String(pageType.attributes.length)} attributes) → ${fileName}.json`);
|
|
464
581
|
}
|
|
465
582
|
async function generateAspectCartridge(aspect, outputDir, dryRun = false) {
|
|
466
583
|
const fileName = toCamelCaseFileName(aspect.id);
|
|
@@ -476,7 +593,7 @@ async function generateAspectCartridge(aspect, outputDir, dryRun = false) {
|
|
|
476
593
|
await writeFile(outputPath, JSON.stringify(cartridgeData, null, 2));
|
|
477
594
|
}
|
|
478
595
|
const prefix = dryRun ? " - [DRY RUN]" : " -";
|
|
479
|
-
|
|
596
|
+
logger.debug(`${prefix} ${String(aspect.name)}: ${String(aspect.description)} (${String(aspect.attributeDefinitions.length)} attributes) → ${fileName}.json`);
|
|
480
597
|
}
|
|
481
598
|
/**
|
|
482
599
|
* Runs ESLint with --fix on the specified directory to format JSON files.
|
|
@@ -484,20 +601,20 @@ async function generateAspectCartridge(aspect, outputDir, dryRun = false) {
|
|
|
484
601
|
*/
|
|
485
602
|
function lintGeneratedFiles(metadataDir, projectRoot) {
|
|
486
603
|
try {
|
|
487
|
-
|
|
604
|
+
logger.debug("🔧 Running ESLint --fix on generated JSON files...");
|
|
488
605
|
execSync(`npx eslint "${metadataDir}/**/*.json" --fix --no-error-on-unmatched-pattern`, {
|
|
489
606
|
cwd: projectRoot,
|
|
490
607
|
stdio: "pipe",
|
|
491
608
|
encoding: "utf-8"
|
|
492
609
|
});
|
|
493
|
-
|
|
610
|
+
logger.debug("✅ JSON files formatted successfully");
|
|
494
611
|
} catch (error) {
|
|
495
612
|
const execError = error;
|
|
496
613
|
if (execError.status === 2) {
|
|
497
614
|
const errMsg = execError.stderr || execError.stdout || "Unknown error";
|
|
498
|
-
|
|
499
|
-
} else if (execError.stderr && execError.stderr.includes("error"))
|
|
500
|
-
else
|
|
615
|
+
logger.warn(`⚠️ Could not run ESLint --fix: ${errMsg}`);
|
|
616
|
+
} else if (execError.stderr && execError.stderr.includes("error")) logger.warn(`⚠️ Some linting issues could not be auto-fixed. Run ESLint manually to review.`);
|
|
617
|
+
else logger.debug("✅ JSON files formatted successfully");
|
|
501
618
|
}
|
|
502
619
|
}
|
|
503
620
|
async function generateMetadata(projectDirectory, metadataDirectory, options) {
|
|
@@ -505,9 +622,9 @@ async function generateMetadata(projectDirectory, metadataDirectory, options) {
|
|
|
505
622
|
const filePaths = options?.filePaths;
|
|
506
623
|
const isIncrementalMode = filePaths && filePaths.length > 0;
|
|
507
624
|
const dryRun = options?.dryRun || false;
|
|
508
|
-
if (dryRun)
|
|
509
|
-
else if (isIncrementalMode)
|
|
510
|
-
else
|
|
625
|
+
if (dryRun) logger.debug("🔍 [DRY RUN] Scanning for decorated components and page types...");
|
|
626
|
+
else if (isIncrementalMode) logger.debug(`🔍 Generating metadata for ${filePaths.length} specified file(s)...`);
|
|
627
|
+
else logger.debug("🔍 Generating metadata for decorated components and page types...");
|
|
511
628
|
const projectRoot = resolve(projectDirectory);
|
|
512
629
|
const srcDir = join(projectRoot, "src");
|
|
513
630
|
const metadataDir = resolve(metadataDirectory);
|
|
@@ -516,7 +633,7 @@ async function generateMetadata(projectDirectory, metadataDirectory, options) {
|
|
|
516
633
|
const aspectsOutputDir = join(metadataDir, "aspects");
|
|
517
634
|
if (!dryRun) {
|
|
518
635
|
if (!isIncrementalMode) {
|
|
519
|
-
|
|
636
|
+
logger.debug("🗑️ Cleaning existing output directories...");
|
|
520
637
|
for (const outputDir of [
|
|
521
638
|
componentsOutputDir,
|
|
522
639
|
pagesOutputDir,
|
|
@@ -526,12 +643,12 @@ async function generateMetadata(projectDirectory, metadataDirectory, options) {
|
|
|
526
643
|
recursive: true,
|
|
527
644
|
force: true
|
|
528
645
|
});
|
|
529
|
-
|
|
646
|
+
logger.debug(` - Deleted: ${outputDir}`);
|
|
530
647
|
} catch {
|
|
531
|
-
|
|
648
|
+
logger.debug(` - Directory not found (skipping): ${outputDir}`);
|
|
532
649
|
}
|
|
533
|
-
} else
|
|
534
|
-
|
|
650
|
+
} else logger.debug("📝 Incremental mode: existing cartridge files will be preserved/overwritten");
|
|
651
|
+
logger.debug("Creating output directories...");
|
|
535
652
|
for (const outputDir of [
|
|
536
653
|
componentsOutputDir,
|
|
537
654
|
pagesOutputDir,
|
|
@@ -542,16 +659,18 @@ async function generateMetadata(projectDirectory, metadataDirectory, options) {
|
|
|
542
659
|
try {
|
|
543
660
|
await access(outputDir);
|
|
544
661
|
} catch {
|
|
545
|
-
|
|
662
|
+
const err = error;
|
|
663
|
+
logger.error(`❌ Failed to create output directory ${outputDir}: ${err.message}`);
|
|
546
664
|
process.exit(1);
|
|
665
|
+
throw err;
|
|
547
666
|
}
|
|
548
667
|
}
|
|
549
|
-
} else if (isIncrementalMode)
|
|
550
|
-
else
|
|
668
|
+
} else if (isIncrementalMode) logger.debug(`📝 [DRY RUN] Would process ${filePaths.length} specific file(s)`);
|
|
669
|
+
else logger.debug("📝 [DRY RUN] Would clean and regenerate all metadata files");
|
|
551
670
|
let files = [];
|
|
552
671
|
if (isIncrementalMode && filePaths) {
|
|
553
672
|
files = filePaths.map((fp) => resolve(projectRoot, fp));
|
|
554
|
-
|
|
673
|
+
logger.debug(`📂 Processing ${files.length} specified file(s)...`);
|
|
555
674
|
} else {
|
|
556
675
|
const scanDirectory = async (dir) => {
|
|
557
676
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
@@ -576,7 +695,7 @@ async function generateMetadata(projectDirectory, metadataDirectory, options) {
|
|
|
576
695
|
allAspects.push(...aspects);
|
|
577
696
|
}
|
|
578
697
|
if (allComponents.length === 0 && allPageTypes.length === 0 && allAspects.length === 0) {
|
|
579
|
-
|
|
698
|
+
logger.info("⚠️ No decorated components, page types, or aspect files found.");
|
|
580
699
|
return {
|
|
581
700
|
componentsGenerated: 0,
|
|
582
701
|
pageTypesGenerated: 0,
|
|
@@ -585,22 +704,22 @@ async function generateMetadata(projectDirectory, metadataDirectory, options) {
|
|
|
585
704
|
};
|
|
586
705
|
}
|
|
587
706
|
if (allComponents.length > 0) {
|
|
588
|
-
|
|
707
|
+
logger.debug(`✅ Found ${allComponents.length} decorated component(s)`);
|
|
589
708
|
for (const component of allComponents) await generateComponentCartridge(component, componentsOutputDir, dryRun);
|
|
590
|
-
if (dryRun)
|
|
591
|
-
else
|
|
709
|
+
if (dryRun) logger.info(`[DRY RUN] Would generate ${allComponents.length} component metadata file(s)`);
|
|
710
|
+
else logger.info(`Generated ${allComponents.length} component metadata file(s)`);
|
|
592
711
|
}
|
|
593
712
|
if (allPageTypes.length > 0) {
|
|
594
|
-
|
|
713
|
+
logger.debug(`✅ Found ${allPageTypes.length} decorated page type(s)`);
|
|
595
714
|
for (const pageType of allPageTypes) await generatePageTypeCartridge(pageType, pagesOutputDir, dryRun);
|
|
596
|
-
if (dryRun)
|
|
597
|
-
else
|
|
715
|
+
if (dryRun) logger.info(`[DRY RUN] Would generate ${allPageTypes.length} page type metadata file(s)`);
|
|
716
|
+
else logger.info(`Generated ${allPageTypes.length} page type metadata file(s)`);
|
|
598
717
|
}
|
|
599
718
|
if (allAspects.length > 0) {
|
|
600
|
-
|
|
719
|
+
logger.debug(`✅ Found ${allAspects.length} decorated aspect(s)`);
|
|
601
720
|
for (const aspect of allAspects) await generateAspectCartridge(aspect, aspectsOutputDir, dryRun);
|
|
602
|
-
if (dryRun)
|
|
603
|
-
else
|
|
721
|
+
if (dryRun) logger.info(`[DRY RUN] Would generate ${allAspects.length} aspect metadata file(s)`);
|
|
722
|
+
else logger.info(`Generated ${allAspects.length} aspect metadata file(s)`);
|
|
604
723
|
}
|
|
605
724
|
const shouldLintFix = options?.lintFix !== false;
|
|
606
725
|
if (!dryRun && shouldLintFix && (allComponents.length > 0 || allPageTypes.length > 0 || allAspects.length > 0)) lintGeneratedFiles(metadataDir, projectRoot);
|
|
@@ -611,8 +730,10 @@ async function generateMetadata(projectDirectory, metadataDirectory, options) {
|
|
|
611
730
|
totalFiles: allComponents.length + allPageTypes.length + allAspects.length
|
|
612
731
|
};
|
|
613
732
|
} catch (error) {
|
|
614
|
-
|
|
733
|
+
const err = error;
|
|
734
|
+
logger.error("❌ Error:", err.message);
|
|
615
735
|
process.exit(1);
|
|
736
|
+
throw err;
|
|
616
737
|
}
|
|
617
738
|
}
|
|
618
739
|
|