@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.
Files changed (49) hide show
  1. package/dist/cartridge-services/index.d.ts.map +1 -1
  2. package/dist/cartridge-services/index.js +171 -50
  3. package/dist/cartridge-services/index.js.map +1 -1
  4. package/dist/commands/create-bundle.js +12 -11
  5. package/dist/commands/create-instructions.js +7 -5
  6. package/dist/commands/create-storefront.js +18 -22
  7. package/dist/commands/deploy-cartridge.js +67 -26
  8. package/dist/commands/dev.js +6 -4
  9. package/dist/commands/extensions/create.js +2 -0
  10. package/dist/commands/extensions/install.js +3 -7
  11. package/dist/commands/extensions/list.js +2 -0
  12. package/dist/commands/extensions/remove.js +3 -7
  13. package/dist/commands/generate-cartridge.js +23 -2
  14. package/dist/commands/preview.js +15 -10
  15. package/dist/commands/push.js +25 -19
  16. package/dist/commands/validate-cartridge.js +51 -0
  17. package/dist/config.js +74 -47
  18. package/dist/configs/react-router.config.d.ts.map +1 -1
  19. package/dist/configs/react-router.config.js +36 -0
  20. package/dist/configs/react-router.config.js.map +1 -1
  21. package/dist/dependency-utils.js +14 -16
  22. package/dist/entry/server.d.ts.map +1 -1
  23. package/dist/entry/server.js +221 -11
  24. package/dist/entry/server.js.map +1 -1
  25. package/dist/generate-cartridge.js +106 -50
  26. package/dist/index.d.ts +127 -13
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +1147 -167
  29. package/dist/index.js.map +1 -1
  30. package/dist/local-dev-setup.js +13 -13
  31. package/dist/logger/index.d.ts +20 -0
  32. package/dist/logger/index.d.ts.map +1 -0
  33. package/dist/logger/index.js +69 -0
  34. package/dist/logger/index.js.map +1 -0
  35. package/dist/logger.js +79 -33
  36. package/dist/logger2.js +1 -0
  37. package/dist/manage-extensions.js +7 -13
  38. package/dist/mrt/ssr.mjs +60 -72
  39. package/dist/mrt/ssr.mjs.map +1 -1
  40. package/dist/mrt/streamingHandler.mjs +66 -78
  41. package/dist/mrt/streamingHandler.mjs.map +1 -1
  42. package/dist/react-router/Scripts.d.ts +1 -1
  43. package/dist/react-router/Scripts.d.ts.map +1 -1
  44. package/dist/react-router/Scripts.js +38 -2
  45. package/dist/react-router/Scripts.js.map +1 -1
  46. package/dist/server.js +296 -16
  47. package/dist/utils.js +4 -4
  48. package/dist/validate-cartridge.js +45 -0
  49. package/package.json +22 -5
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/cartridge-services/generate-cartridge.ts"],"sourcesContent":[],"mappings":";;AA8vBA;;;AAIG,UA1Ec,uBAAA,CA0Ed;EAAO;;;;;;;;;;;;;;;;;;;;UAlDO,sBAAA;;;;;;iBA8CK,gBAAA,gEAGR,0BACX,QAAQ"}
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
- console.warn(`Warning: Could not find route for file: ${filePath}`);
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
- console.error(`Error: Invalid attribute type '${decoratorType}' for field '${fieldName || "unknown"}'. Valid types are: ${VALID_ATTRIBUTE_TYPES.join(", ")}`);
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 return expression.getText();
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
- console.warn(`Warning: Could not parse nested object: ${error.message}`);
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
- console.warn(`Warning: Could not parse array literal: ${error.message}`);
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
- console.warn(`Warning: Could not parse decorator arguments: ${error.message}`);
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
- console.warn(`Warning: Could not extract attributes from class ${className}: ${error.message}`);
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 extractRegionDefinitionsFromSource(sourceFile, className) {
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
- console.warn(`Warning: Could not extract region definitions from class ${className}: ${error.message}`);
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: componentConfig.group || DEFAULT_COMPONENT_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
- console.warn(`Warning: Could not process file ${filePath}:`, error.message);
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
- console.warn(`Warning: Could not read file ${filePath}:`, error.message);
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
- console.warn(`Warning: Could not process file ${filePath}:`, error.message);
497
+ logger.warn(`Could not process file ${filePath}:`, error.message);
381
498
  }
382
499
  return pageTypes;
383
500
  } catch (error) {
384
- console.warn(`Warning: Could not read file ${filePath}:`, error.message);
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
- console.warn(`Warning: Could not parse JSON in file ${filePath}:`, parseError.message);
524
+ logger.warn(`Could not parse JSON in file ${filePath}:`, parseError.message);
408
525
  }
409
526
  return aspects;
410
527
  } catch (error) {
411
- console.warn(`Warning: Could not read file ${filePath}:`, error.message);
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
- console.log(`${prefix} ${String(component.typeId)}: ${String(component.name)} (${String(component.attributes.length)} attributes) → ${fileName}.json`);
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
- console.log(`${prefix} ${String(pageType.name)}: ${String(pageType.description)} (${String(pageType.attributes.length)} attributes) → ${fileName}.json`);
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
- console.log(`${prefix} ${String(aspect.name)}: ${String(aspect.description)} (${String(aspect.attributeDefinitions.length)} attributes) → ${fileName}.json`);
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
- console.log("🔧 Running ESLint --fix on generated JSON files...");
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
- console.log("✅ JSON files formatted successfully");
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
- console.warn(`⚠️ Warning: Could not run ESLint --fix: ${errMsg}`);
499
- } else if (execError.stderr && execError.stderr.includes("error")) console.warn(`⚠️ Warning: Some linting issues could not be auto-fixed. Run ESLint manually to review.`);
500
- else console.log("✅ JSON files formatted successfully");
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) console.log("🔍 [DRY RUN] Scanning for decorated components and page types...");
509
- else if (isIncrementalMode) console.log(`🔍 Generating metadata for ${filePaths.length} specified file(s)...`);
510
- else console.log("🔍 Generating metadata for decorated components and page types...");
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
- console.log("🗑️ Cleaning existing output directories...");
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
- console.log(` - Deleted: ${outputDir}`);
646
+ logger.debug(` - Deleted: ${outputDir}`);
530
647
  } catch {
531
- console.log(` - Directory not found (skipping): ${outputDir}`);
648
+ logger.debug(` - Directory not found (skipping): ${outputDir}`);
532
649
  }
533
- } else console.log("📝 Incremental mode: existing cartridge files will be preserved/overwritten");
534
- console.log("📁 Creating output directories...");
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
- console.error(`❌ Error: Failed to create output directory ${outputDir}: ${error.message}`);
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) console.log(`📝 [DRY RUN] Would process ${filePaths.length} specific file(s)`);
550
- else console.log("📝 [DRY RUN] Would clean and regenerate all metadata files");
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
- console.log(`📂 Processing ${files.length} specified file(s)...`);
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
- console.log("⚠️ No decorated components, page types, or aspect files found.");
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
- console.log(`✅ Found ${allComponents.length} decorated component(s):`);
707
+ logger.debug(`✅ Found ${allComponents.length} decorated component(s)`);
589
708
  for (const component of allComponents) await generateComponentCartridge(component, componentsOutputDir, dryRun);
590
- if (dryRun) console.log(`📄 [DRY RUN] Would generate ${allComponents.length} component metadata file(s) in: ${componentsOutputDir}`);
591
- else console.log(`📄 Generated ${allComponents.length} component metadata file(s) in: ${componentsOutputDir}`);
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
- console.log(`✅ Found ${allPageTypes.length} decorated page type(s):`);
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) console.log(`📄 [DRY RUN] Would generate ${allPageTypes.length} page type metadata file(s) in: ${pagesOutputDir}`);
597
- else console.log(`📄 Generated ${allPageTypes.length} page type metadata file(s) in: ${pagesOutputDir}`);
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
- console.log(`✅ Found ${allAspects.length} decorated aspect(s):`);
719
+ logger.debug(`✅ Found ${allAspects.length} decorated aspect(s)`);
601
720
  for (const aspect of allAspects) await generateAspectCartridge(aspect, aspectsOutputDir, dryRun);
602
- if (dryRun) console.log(`📄 [DRY RUN] Would generate ${allAspects.length} aspect metadata file(s) in: ${aspectsOutputDir}`);
603
- else console.log(`📄 Generated ${allAspects.length} aspect metadata file(s) in: ${aspectsOutputDir}`);
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
- console.error("❌ Error:", error.message);
733
+ const err = error;
734
+ logger.error("❌ Error:", err.message);
615
735
  process.exit(1);
736
+ throw err;
616
737
  }
617
738
  }
618
739