@solid-stack/mason 1.0.35 → 1.0.36

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.
@@ -1 +1 @@
1
- {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/commands/lint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG5E,wBAAgB,eAAe,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAsBpD;AAED,wBAAsB,UAAU,CAAC,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA0EtF"}
1
+ {"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../src/commands/lint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAe,WAAW,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAG5E,wBAAgB,eAAe,CAAC,CAAC,EAAE,SAAS,GAAG,MAAM,CAsBpD;AAED,wBAAsB,UAAU,CAAC,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA4EtF"}
@@ -78,5 +78,14 @@ export interface ClassMethodInfo {
78
78
  export declare function extractClassMethods(content: string, className: string): ClassMethodInfo[] | null;
79
79
  export declare function checkUseCaseShape(featureName: string, filePath: string, relativePath: string, content: string, addViolation: (v: Violation) => void): void;
80
80
  export declare function checkServiceShape(featureName: string, filePath: string, relativePath: string, content: string, addViolation: (v: Violation) => void): void;
81
+ export interface RegistryModuleErrorInfo {
82
+ errorsDir: string;
83
+ hasErrorsDir: boolean;
84
+ baseErrorFileAbs?: string | undefined;
85
+ baseErrorClassName?: string | undefined;
86
+ baseErrorExtendsName?: string | undefined;
87
+ baseErrorRawClassCode?: string | undefined;
88
+ }
89
+ export declare function resolveRegistryModuleError(modDir: string, modName: string): RegistryModuleErrorInfo;
81
90
  export declare function lintCodebase(options?: LintOptions): LintSummary;
82
91
  //# sourceMappingURL=lintEngine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lintEngine.d.ts","sourceRoot":"","sources":["../../src/core/lintEngine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lintEngine.d.ts","sourceRoot":"","sources":["../../src/core/lintEngine.ts"],"names":[],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -5688,42 +5688,108 @@ private ${m.name}(...) { ... }`
5688
5688
  }
5689
5689
  }
5690
5690
  }
5691
+ function resolveRegistryModuleError(modDir, modName) {
5692
+ const errorsDir = path26__default.default.join(modDir, "errors");
5693
+ if (!fs17__default.default.existsSync(errorsDir) || !fs17__default.default.statSync(errorsDir).isDirectory()) {
5694
+ return { errorsDir, hasErrorsDir: false };
5695
+ }
5696
+ const entries = fs17__default.default.readdirSync(errorsDir);
5697
+ const errorFiles = entries.filter((f) => f.endsWith(".ts") || f.endsWith(".js"));
5698
+ const nameNormalized = modName.toLowerCase().replace(/[-_]/g, "");
5699
+ const singularNormalized = toSingular(modName).toLowerCase().replace(/[-_]/g, "");
5700
+ let baseErrorFileName = errorFiles.find((f) => {
5701
+ const baseNoExt = f.replace(/\.(ts|js)$/, "").toLowerCase().replace(/[-_]/g, "");
5702
+ return baseNoExt === `${nameNormalized}error` || baseNoExt === `${singularNormalized}error` || baseNoExt === `${nameNormalized}errors` || baseNoExt === `${singularNormalized}errors`;
5703
+ });
5704
+ if (!baseErrorFileName) {
5705
+ return { errorsDir, hasErrorsDir: true };
5706
+ }
5707
+ const baseErrorFileAbs = path26__default.default.join(errorsDir, baseErrorFileName);
5708
+ const content = fs17__default.default.readFileSync(baseErrorFileAbs, "utf-8");
5709
+ const classRegex = /(?:export\s+(?:default\s+)?)?(?:abstract\s+)?class\s+([A-Za-z0-9_]+)(?:<[^>]+>)?(?:\s+extends\s+([A-Za-z0-9_]+))?/g;
5710
+ let match;
5711
+ const classes = [];
5712
+ while ((match = classRegex.exec(content)) !== null) {
5713
+ classes.push({
5714
+ name: match[1],
5715
+ extendsName: match[2],
5716
+ raw: match[0]
5717
+ });
5718
+ }
5719
+ const expectedNames = [
5720
+ `${toPascalCase(modName)}Error`,
5721
+ `${toPascalCase(toSingular(modName))}Error`,
5722
+ `${toPascalCase(modName)}Errors`,
5723
+ `${toPascalCase(toSingular(modName))}Errors`
5724
+ ].map((n) => n.toLowerCase());
5725
+ const targetClass = classes.find((c) => expectedNames.includes(c.name.toLowerCase())) || classes.find((c) => c.raw.includes("export")) || classes[0];
5726
+ return {
5727
+ errorsDir,
5728
+ hasErrorsDir: true,
5729
+ baseErrorFileAbs,
5730
+ baseErrorClassName: targetClass ? targetClass.name : void 0,
5731
+ baseErrorExtendsName: targetClass ? targetClass.extendsName : void 0,
5732
+ baseErrorRawClassCode: targetClass ? targetClass.raw : void 0
5733
+ };
5734
+ }
5691
5735
  function lintCodebase(options = {}) {
5692
5736
  const startTime = Date.now();
5693
5737
  const projectRoot = options.projectRoot || findProjectRoot(options.targetDir || process.cwd());
5694
5738
  const failFast = !options.complete;
5739
+ const effectiveMode = options.mode || getEffectiveMode(projectRoot, options.registry !== void 0 ? { registry: options.registry } : void 0);
5740
+ const isRegistryMode = effectiveMode === "registry";
5695
5741
  const { featuresBase, sharedBase, errorsBase, baseErrorAbs } = resolveLintEnvironment(projectRoot);
5696
- const missingFoundations = [];
5697
- if (!fs17__default.default.existsSync(featuresBase)) missingFoundations.push("features/");
5698
- if (!fs17__default.default.existsSync(sharedBase)) missingFoundations.push("shared/");
5699
- if (!fs17__default.default.existsSync(errorsBase)) missingFoundations.push("errors/");
5700
- if (missingFoundations.length > 0) {
5701
- throw new DependencyRuleError(
5702
- `Project Structure Violation: Missing required foundational directories: ${missingFoundations.join(", ")}. Every architecture must contain 'features/', 'shared/', and 'errors/'.`,
5703
- [],
5704
- true
5705
- );
5742
+ if (!isRegistryMode) {
5743
+ const missingFoundations = [];
5744
+ if (!fs17__default.default.existsSync(featuresBase)) missingFoundations.push("features/");
5745
+ if (!fs17__default.default.existsSync(sharedBase)) missingFoundations.push("shared/");
5746
+ if (!fs17__default.default.existsSync(errorsBase)) missingFoundations.push("errors/");
5747
+ if (missingFoundations.length > 0) {
5748
+ throw new DependencyRuleError(
5749
+ `Project Structure Violation: Missing required foundational directories: ${missingFoundations.join(", ")}. Every architecture must contain 'features/', 'shared/', and 'errors/'.`,
5750
+ [],
5751
+ true
5752
+ );
5753
+ }
5754
+ if (!fs17__default.default.existsSync(baseErrorAbs)) {
5755
+ throw new DependencyRuleError(
5756
+ `Project Structure Violation: Base error class not found at '${path26__default.default.relative(projectRoot, baseErrorAbs).replace(/\\/g, "/")}'. Configure paths.baseError in mason.config.json.`,
5757
+ [],
5758
+ true
5759
+ );
5760
+ }
5761
+ } else {
5762
+ if (!fs17__default.default.existsSync(featuresBase) && !fs17__default.default.existsSync(sharedBase)) {
5763
+ throw new DependencyRuleError(
5764
+ `Project Structure Violation: Missing required foundational directories: features/ or shared/. A registry must contain 'features/' or 'shared/'.`,
5765
+ [],
5766
+ true
5767
+ );
5768
+ }
5706
5769
  }
5707
- if (!fs17__default.default.existsSync(baseErrorAbs)) {
5708
- throw new DependencyRuleError(
5709
- `Project Structure Violation: Base error class not found at '${path26__default.default.relative(projectRoot, baseErrorAbs).replace(/\\/g, "/")}'. Configure paths.baseError in mason.config.json.`,
5710
- [],
5711
- true
5770
+ let baseErrorClassName = "AppError";
5771
+ if (!isRegistryMode && fs17__default.default.existsSync(baseErrorAbs)) {
5772
+ const baseErrorContent = fs17__default.default.readFileSync(baseErrorAbs, "utf-8");
5773
+ const baseClassMatch = baseErrorContent.match(
5774
+ /(?:export\s+(?:default\s+)?)?(?:abstract\s+)?class\s+([A-Za-z0-9_]+)/
5712
5775
  );
5776
+ baseErrorClassName = baseClassMatch ? baseClassMatch[1] : "AppError";
5713
5777
  }
5714
- const baseErrorContent = fs17__default.default.readFileSync(baseErrorAbs, "utf-8");
5715
- const baseClassMatch = baseErrorContent.match(
5716
- /(?:export\s+(?:default\s+)?)?(?:abstract\s+)?class\s+([A-Za-z0-9_]+)/
5717
- );
5718
- const baseErrorClassName = baseClassMatch ? baseClassMatch[1] : "AppError";
5719
5778
  const features = discoverAllFeatures(featuresBase, [sharedBase, errorsBase]);
5720
5779
  const sharedModules = discoverAllShared(sharedBase, [featuresBase, errorsBase]);
5721
- const errorModule = { name: "global-errors", dir: errorsBase, type: "error" };
5722
5780
  const allModules = [
5723
5781
  ...features.map((f) => ({ ...f, type: "feature" })),
5724
- ...sharedModules.map((s) => ({ ...s, type: "shared" })),
5725
- errorModule
5782
+ ...sharedModules.map((s) => ({ ...s, type: "shared" }))
5726
5783
  ];
5784
+ if (!isRegistryMode) {
5785
+ const errorModule = { name: "global-errors", dir: errorsBase, type: "error" };
5786
+ allModules.push(errorModule);
5787
+ } else if (fs17__default.default.existsSync(errorsBase)) {
5788
+ const errorFiles = scanDirFiles(errorsBase, projectRoot);
5789
+ if (errorFiles.length > 0) {
5790
+ allModules.push({ name: "global-errors", dir: errorsBase, type: "error" });
5791
+ }
5792
+ }
5727
5793
  const graph = new FeatureDependencyGraph();
5728
5794
  const allViolations = [];
5729
5795
  const results = [];
@@ -5757,6 +5823,77 @@ Code: ${v.code}`;
5757
5823
  }
5758
5824
  for (const mod of allModules) {
5759
5825
  const modResult = results.find((r) => r.featureName === mod.name);
5826
+ let modBaseErrorClass = baseErrorClassName;
5827
+ let modBaseErrorAbs = !isRegistryMode ? baseErrorAbs : void 0;
5828
+ if (isRegistryMode && (mod.type === "feature" || mod.type === "shared")) {
5829
+ const errorInfo = resolveRegistryModuleError(mod.dir, mod.name);
5830
+ if (!errorInfo.hasErrorsDir) {
5831
+ addViolation({
5832
+ feature: mod.name,
5833
+ layer: "domain",
5834
+ file: mod.dir,
5835
+ relativePath: path26__default.default.relative(projectRoot, errorInfo.errorsDir).replace(/\\/g, "/"),
5836
+ line: 1,
5837
+ category: "Project Structure Violation",
5838
+ code: `Missing errors/ directory in registry ${mod.type} '${mod.name}'`,
5839
+ ruleId: "REG_ERRORS_DIR_REQUIRED",
5840
+ severity: "error",
5841
+ advice: `Registry ${mod.type} '${mod.name}' must implement its own 'errors/' directory at '${path26__default.default.relative(projectRoot, errorInfo.errorsDir).replace(/\\/g, "/")}'.`,
5842
+ fixExample: {
5843
+ bad: "// Missing errors directory",
5844
+ good: `mkdir -p ${path26__default.default.relative(projectRoot, errorInfo.errorsDir).replace(/\\/g, "/")}`
5845
+ }
5846
+ });
5847
+ } else if (!errorInfo.baseErrorFileAbs) {
5848
+ const expectedFileName = `${toPascalCase(mod.name)}Error.ts`;
5849
+ const expectedRel = path26__default.default.relative(projectRoot, path26__default.default.join(errorInfo.errorsDir, expectedFileName)).replace(/\\/g, "/");
5850
+ addViolation({
5851
+ feature: mod.name,
5852
+ layer: "domain",
5853
+ file: errorInfo.errorsDir,
5854
+ relativePath: expectedRel,
5855
+ line: 1,
5856
+ category: "Project Structure Violation",
5857
+ code: `Missing base error file in '${mod.name}/errors'`,
5858
+ ruleId: "REG_BASE_ERROR_REQUIRED",
5859
+ severity: "error",
5860
+ advice: `Registry ${mod.type} '${mod.name}' must have a base error file at '${expectedRel}'.`,
5861
+ fixExample: {
5862
+ bad: "// Missing base error file",
5863
+ good: `export class ${toPascalCase(mod.name)}Error extends Error {
5864
+ constructor(message: string) {
5865
+ super(message);
5866
+ }
5867
+ }`
5868
+ }
5869
+ });
5870
+ } else {
5871
+ modBaseErrorAbs = errorInfo.baseErrorFileAbs;
5872
+ modBaseErrorClass = errorInfo.baseErrorClassName || `${toPascalCase(mod.name)}Error`;
5873
+ if (!errorInfo.baseErrorClassName || errorInfo.baseErrorExtendsName !== "Error") {
5874
+ addViolation({
5875
+ feature: mod.name,
5876
+ layer: "domain",
5877
+ file: errorInfo.baseErrorFileAbs,
5878
+ relativePath: path26__default.default.relative(projectRoot, errorInfo.baseErrorFileAbs).replace(/\\/g, "/"),
5879
+ line: 1,
5880
+ category: "Error Inheritance Violation",
5881
+ code: errorInfo.baseErrorRawClassCode || `class ${modBaseErrorClass}`,
5882
+ ruleId: "REG_BASE_ERROR_MUST_EXTEND_ERROR",
5883
+ severity: "error",
5884
+ advice: `Registry ${mod.type} base error class '${modBaseErrorClass}' in '${mod.name}' must extend native 'Error'.`,
5885
+ fixExample: {
5886
+ bad: errorInfo.baseErrorRawClassCode || `class ${modBaseErrorClass}`,
5887
+ good: `export class ${modBaseErrorClass} extends Error {
5888
+ constructor(message: string) {
5889
+ super(message);
5890
+ }
5891
+ }`
5892
+ }
5893
+ });
5894
+ }
5895
+ }
5896
+ }
5760
5897
  const allFiles = scanDirFiles(mod.dir, projectRoot);
5761
5898
  modResult.scannedFilesCount = allFiles.length;
5762
5899
  for (const file of allFiles) {
@@ -5784,15 +5921,15 @@ Code: ${v.code}`;
5784
5921
  code: lineCode,
5785
5922
  ruleId: "E3_PLAIN_ERROR_THROW",
5786
5923
  severity: "error",
5787
- advice: `Throwing plain 'Error' is prohibited. You must throw '${baseErrorClassName}' or a custom error class that inherits from it.`,
5924
+ advice: isRegistryMode ? `Throwing plain 'Error' is prohibited in registry ${mod.type} '${mod.name}'. You must throw '${modBaseErrorClass}' or a class that inherits from it.` : `Throwing plain 'Error' is prohibited. You must throw '${modBaseErrorClass}' or a custom error class that inherits from it.`,
5788
5925
  fixExample: {
5789
5926
  bad: lineCode,
5790
- good: `throw new ${baseErrorClassName}("Something went wrong");`
5927
+ good: `throw new ${modBaseErrorClass}("Something went wrong");`
5791
5928
  }
5792
5929
  });
5793
5930
  }
5794
5931
  const isErrorFile = relPath.includes("/errors/") || relPath.startsWith("errors/") || relPath.startsWith("src/errors/") || moduleType === "error" || baseName.endsWith("Error.ts") || baseName.endsWith("Errors.ts") || baseName.endsWith("Error.js") || baseName.endsWith("Errors.js");
5795
- const isBaseErrorFile = path26__default.default.resolve(file) === path26__default.default.resolve(baseErrorAbs);
5932
+ const isBaseErrorFile = modBaseErrorAbs ? path26__default.default.resolve(file) === path26__default.default.resolve(modBaseErrorAbs) : !isRegistryMode && path26__default.default.resolve(file) === path26__default.default.resolve(baseErrorAbs);
5796
5933
  if (isErrorFile && !isBaseErrorFile) {
5797
5934
  const classRegex = /(?:export\s+(?:default\s+)?)?(?:abstract\s+)?class\s+([A-Za-z0-9_]+)(?:<[^>]+>)?(?:\s+extends\s+([A-Za-z0-9_]+))?/g;
5798
5935
  let classMatch;
@@ -5814,10 +5951,10 @@ Code: ${v.code}`;
5814
5951
  code: lineCode,
5815
5952
  ruleId: "E4_MISSING_INHERITANCE",
5816
5953
  severity: "error",
5817
- advice: `Error class '${className}' must extend '${baseErrorClassName}'.`,
5954
+ advice: isRegistryMode ? `Error class '${className}' in registry ${mod.type} '${mod.name}' must extend '${modBaseErrorClass}'.` : `Error class '${className}' must extend '${modBaseErrorClass}'.`,
5818
5955
  fixExample: {
5819
5956
  bad: lineCode,
5820
- good: `export class ${className} extends ${baseErrorClassName} { ... }`
5957
+ good: `export class ${className} extends ${modBaseErrorClass} { ... }`
5821
5958
  }
5822
5959
  });
5823
5960
  } else if (extendsName === "Error") {
@@ -5831,10 +5968,10 @@ Code: ${v.code}`;
5831
5968
  code: lineCode,
5832
5969
  ruleId: "E5_NATIVE_ERROR_INHERITANCE",
5833
5970
  severity: "error",
5834
- advice: `Error class '${className}' extends native 'Error'. It must extend your configured base error class ('${baseErrorClassName}').`,
5971
+ advice: isRegistryMode ? `Error class '${className}' extends native 'Error'. In registry ${mod.type} '${mod.name}', it must extend your base error class ('${modBaseErrorClass}').` : `Error class '${className}' extends native 'Error'. It must extend your configured base error class ('${modBaseErrorClass}').`,
5835
5972
  fixExample: {
5836
5973
  bad: lineCode,
5837
- good: `export class ${className} extends ${baseErrorClassName} { ... }`
5974
+ good: `export class ${className} extends ${modBaseErrorClass} { ... }`
5838
5975
  }
5839
5976
  });
5840
5977
  }
@@ -6594,7 +6731,9 @@ async function handleLint(flags = {}) {
6594
6731
  targetDir: flags.targetDir || flags.target,
6595
6732
  projectRoot: flags.projectRoot,
6596
6733
  fixHint: flags.fixHint !== false,
6597
- throwOnError: false
6734
+ throwOnError: false,
6735
+ mode: flags.mode || (flags.registry ? "registry" : void 0),
6736
+ registry: Boolean(flags.registry)
6598
6737
  };
6599
6738
  try {
6600
6739
  const summary = lintCodebase(options);