@solid-stack/mason 1.0.34 → 1.0.35

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/bin.cjs CHANGED
@@ -218,37 +218,6 @@ function getConfiguredSharedDir(projectRoot, flags) {
218
218
  }
219
219
  return path26__default.default.join(projectRoot, "shared");
220
220
  }
221
- function loadLintConfig(projectRoot) {
222
- const configPath = path26__default.default.join(projectRoot, "mason-lint.config.json");
223
- if (fs17__default.default.existsSync(configPath)) {
224
- try {
225
- return JSON.parse(fs17__default.default.readFileSync(configPath, "utf-8"));
226
- } catch {
227
- }
228
- }
229
- return {};
230
- }
231
- function getResolvedLintPaths(projectRoot, config) {
232
- const masonConfig = loadMasonConfig(projectRoot);
233
- const configuredFeatures = config.paths?.features ?? masonConfig?.paths?.features;
234
- const configuredShared = config.paths?.shared ?? masonConfig?.paths?.shared;
235
- const configuredErrors = config.paths?.errors;
236
- const resolveBase = (configuredPath, defaultSrc, defaultRoot) => {
237
- if (configuredPath !== void 0) {
238
- return path26__default.default.resolve(projectRoot, configuredPath);
239
- }
240
- const srcPath = path26__default.default.join(projectRoot, defaultSrc);
241
- if (fs17__default.default.existsSync(srcPath)) return srcPath;
242
- const rootPath = path26__default.default.join(projectRoot, defaultRoot);
243
- if (fs17__default.default.existsSync(rootPath)) return rootPath;
244
- return srcPath;
245
- };
246
- return {
247
- featuresBase: resolveBase(configuredFeatures, "src/features", "features"),
248
- sharedBase: resolveBase(configuredShared, "src/shared", "shared"),
249
- errorsBase: resolveBase(configuredErrors, "src/errors", "errors")
250
- };
251
- }
252
221
 
253
222
  // src/utils/project.ts
254
223
  function findProjectRoot(startDir = process.cwd()) {
@@ -4934,19 +4903,43 @@ function scanDirFiles(dir, projectRoot) {
4934
4903
  }
4935
4904
  return files;
4936
4905
  }
4906
+ function resolveLintEnvironment(projectRoot) {
4907
+ const config = loadMasonConfig(projectRoot);
4908
+ const resolveDir = (configured, defaultSrc, defaultRoot) => {
4909
+ if (configured !== void 0) {
4910
+ return path26__default.default.resolve(projectRoot, configured);
4911
+ }
4912
+ const srcPath = path26__default.default.join(projectRoot, defaultSrc);
4913
+ if (fs17__default.default.existsSync(srcPath)) return srcPath;
4914
+ const rootPath = path26__default.default.join(projectRoot, defaultRoot);
4915
+ if (fs17__default.default.existsSync(rootPath)) return rootPath;
4916
+ return srcPath;
4917
+ };
4918
+ const featuresBase = resolveDir(config?.paths?.features, "src/features", "features");
4919
+ const sharedBase = resolveDir(config?.paths?.shared, "src/shared", "shared");
4920
+ const errorsBase = resolveDir(config?.paths?.errors, "src/errors", "errors");
4921
+ const defaultBaseErrorRelative = config?.paths?.errors ? path26__default.default.join(config.paths.errors, "AppError.ts") : fs17__default.default.existsSync(path26__default.default.join(projectRoot, "src/errors")) ? "src/errors/AppError.ts" : fs17__default.default.existsSync(path26__default.default.join(projectRoot, "errors")) ? "errors/AppError.ts" : "src/errors/AppError.ts";
4922
+ const baseErrorAbs = path26__default.default.resolve(
4923
+ projectRoot,
4924
+ config?.paths?.baseError || defaultBaseErrorRelative
4925
+ );
4926
+ return { featuresBase, sharedBase, errorsBase, baseErrorAbs };
4927
+ }
4937
4928
  function classifyFile(fullPathAbs, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs) {
4938
4929
  if (!sharedBaseAbs || !errorsBaseAbs) {
4939
- const paths = getResolvedLintPaths(featuresBaseAbs, loadLintConfig(featuresBaseAbs));
4940
- featuresBaseAbs = paths.featuresBase;
4941
- sharedBaseAbs = paths.sharedBase;
4942
- errorsBaseAbs = paths.errorsBase;
4930
+ const env = resolveLintEnvironment(featuresBaseAbs);
4931
+ featuresBaseAbs = env.featuresBase;
4932
+ sharedBaseAbs = env.sharedBase;
4933
+ errorsBaseAbs = env.errorsBase;
4943
4934
  }
4944
4935
  const normFullPath = path26__default.default.resolve(fullPathAbs);
4945
4936
  const normErrorsBase = path26__default.default.resolve(errorsBaseAbs);
4946
4937
  const normSharedBase = path26__default.default.resolve(sharedBaseAbs);
4947
4938
  const normFeaturesBase = path26__default.default.resolve(featuresBaseAbs);
4948
- const relErrors = path26__default.default.relative(normErrorsBase, normFullPath).replace(/\\/g, "/");
4949
- if (!relErrors.startsWith("..") && !path26__default.default.isAbsolute(relErrors)) {
4939
+ const isUnder = (base, target) => {
4940
+ return target === base || target.startsWith(base + path26__default.default.sep);
4941
+ };
4942
+ if (isUnder(normErrorsBase, normFullPath)) {
4950
4943
  return {
4951
4944
  moduleType: "error",
4952
4945
  moduleName: "global-errors",
@@ -4954,26 +4947,26 @@ function classifyFile(fullPathAbs, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs
4954
4947
  layer: "domain"
4955
4948
  };
4956
4949
  }
4957
- const relShared = path26__default.default.relative(normSharedBase, normFullPath).replace(/\\/g, "/");
4958
- if (!relShared.startsWith("..") && !path26__default.default.isAbsolute(relShared)) {
4959
- const parts = relShared.split("/").filter(Boolean);
4950
+ if (isUnder(normSharedBase, normFullPath)) {
4951
+ const rel = path26__default.default.relative(normSharedBase, normFullPath).replace(/\\/g, "/");
4952
+ const parts = rel.split("/").filter(Boolean);
4960
4953
  if (parts.length >= 1) {
4961
4954
  const moduleName = parts[0];
4962
- const rest = parts.slice(1).join("/");
4955
+ const subfolder = parts[1];
4963
4956
  let layer = "root";
4964
- if (rest.startsWith("domain/") || rest === "domain" || rest.startsWith("errors/") || rest === "errors") {
4957
+ if (subfolder === "domain" || subfolder === "errors") {
4965
4958
  layer = "domain";
4966
- } else if (rest.startsWith("ports/") || rest === "ports") {
4959
+ } else if (subfolder === "ports") {
4967
4960
  layer = "ports";
4968
- } else if (rest.startsWith("infrastructure/") || rest === "infrastructure") {
4961
+ } else if (subfolder === "infrastructure") {
4969
4962
  layer = "infrastructure";
4970
4963
  }
4971
4964
  return { moduleType: "shared", moduleName, feature: moduleName, layer };
4972
4965
  }
4973
4966
  }
4974
- const relFeatures = path26__default.default.relative(normFeaturesBase, normFullPath).replace(/\\/g, "/");
4975
- if (!relFeatures.startsWith("..") && !path26__default.default.isAbsolute(relFeatures)) {
4976
- const parts = relFeatures.split("/").filter(Boolean);
4967
+ if (isUnder(normFeaturesBase, normFullPath)) {
4968
+ const rel = path26__default.default.relative(normFeaturesBase, normFullPath).replace(/\\/g, "/");
4969
+ const parts = rel.split("/").filter(Boolean);
4977
4970
  if (parts.length >= 2) {
4978
4971
  const moduleName = parts[0];
4979
4972
  const subfolder = parts[1];
@@ -4986,7 +4979,7 @@ function classifyFile(fullPathAbs, featuresBaseAbs, sharedBaseAbs, errorsBaseAbs
4986
4979
  layer = "services";
4987
4980
  } else if (subfolder === "infrastructure") {
4988
4981
  layer = "infrastructure";
4989
- } else if (subfolder === "pxExpress" || subfolder === "presentation" || subfolder === "handlers" || subfolder.startsWith("px")) {
4982
+ } else if (subfolder.startsWith("px") || subfolder === "presentation" || subfolder === "handlers" || subfolder === "transformers") {
4990
4983
  layer = "presentation";
4991
4984
  }
4992
4985
  return { moduleType: "feature", moduleName, feature: moduleName, layer };
@@ -5015,10 +5008,10 @@ function classifyTarget(specifier, sourceFileAbs, projectRoot, featuresBaseAbs,
5015
5008
  return { isExternal: true, isDiFramework: false };
5016
5009
  }
5017
5010
  if (!featuresBaseAbs || !sharedBaseAbs || !errorsBaseAbs) {
5018
- const paths = getResolvedLintPaths(projectRoot, loadLintConfig(projectRoot));
5019
- featuresBaseAbs = featuresBaseAbs || paths.featuresBase;
5020
- sharedBaseAbs = sharedBaseAbs || paths.sharedBase;
5021
- errorsBaseAbs = errorsBaseAbs || paths.errorsBase;
5011
+ const env = resolveLintEnvironment(projectRoot);
5012
+ featuresBaseAbs = featuresBaseAbs || env.featuresBase;
5013
+ sharedBaseAbs = sharedBaseAbs || env.sharedBase;
5014
+ errorsBaseAbs = errorsBaseAbs || env.errorsBase;
5022
5015
  }
5023
5016
  const isGlobalConfig = specifier === "@configs" || specifier.startsWith("@configs/") || specifier === "@/configs" || specifier.startsWith("@/configs/") || specifier === "~/configs" || specifier.startsWith("~/configs/") || specifier === "configs" || specifier.startsWith("configs/");
5024
5017
  let targetAbs = null;
@@ -5659,24 +5652,21 @@ function lintCodebase(options = {}) {
5659
5652
  const startTime = Date.now();
5660
5653
  const projectRoot = options.projectRoot || findProjectRoot(options.targetDir || process.cwd());
5661
5654
  const failFast = !options.complete;
5662
- const lintConfig = loadLintConfig(projectRoot);
5663
- const { featuresBase, sharedBase, errorsBase } = getResolvedLintPaths(projectRoot, lintConfig);
5655
+ const { featuresBase, sharedBase, errorsBase, baseErrorAbs } = resolveLintEnvironment(projectRoot);
5664
5656
  const missingFoundations = [];
5665
5657
  if (!fs17__default.default.existsSync(featuresBase)) missingFoundations.push("features/");
5666
5658
  if (!fs17__default.default.existsSync(sharedBase)) missingFoundations.push("shared/");
5667
5659
  if (!fs17__default.default.existsSync(errorsBase)) missingFoundations.push("errors/");
5668
5660
  if (missingFoundations.length > 0) {
5669
5661
  throw new DependencyRuleError(
5670
- `Project Structure Violation: Missing required foundational directories: ${missingFoundations.join(", ")}. Every project must contain 'features/', 'shared/', and 'errors/'.`,
5662
+ `Project Structure Violation: Missing required foundational directories: ${missingFoundations.join(", ")}. Every architecture must contain 'features/', 'shared/', and 'errors/'.`,
5671
5663
  [],
5672
5664
  true
5673
5665
  );
5674
5666
  }
5675
- const baseErrorRelative = lintConfig.baseErrorPath || path26__default.default.relative(projectRoot, path26__default.default.join(errorsBase, "AppError.ts")).replace(/\\/g, "/");
5676
- const baseErrorAbs = path26__default.default.resolve(projectRoot, baseErrorRelative);
5677
5667
  if (!fs17__default.default.existsSync(baseErrorAbs)) {
5678
5668
  throw new DependencyRuleError(
5679
- `Project Structure Violation: Base error class not found at '${baseErrorRelative}'. Create this file or update 'baseErrorPath' in mason-lint.config.json.`,
5669
+ `Project Structure Violation: Base error class not found at '${path26__default.default.relative(projectRoot, baseErrorAbs).replace(/\\/g, "/")}'. Configure paths.baseError in mason.config.json.`,
5680
5670
  [],
5681
5671
  true
5682
5672
  );
@@ -5754,7 +5744,7 @@ Code: ${v.code}`;
5754
5744
  code: lineCode,
5755
5745
  ruleId: "E3_PLAIN_ERROR_THROW",
5756
5746
  severity: "error",
5757
- advice: `Throwing plain 'Error' is prohibited. You must throw '${baseErrorClassName}' or a domain-specific error class that inherits from it.`,
5747
+ advice: `Throwing plain 'Error' is prohibited. You must throw '${baseErrorClassName}' or a custom error class that inherits from it.`,
5758
5748
  fixExample: {
5759
5749
  bad: lineCode,
5760
5750
  good: `throw new ${baseErrorClassName}("Something went wrong");`
@@ -5784,7 +5774,7 @@ Code: ${v.code}`;
5784
5774
  code: lineCode,
5785
5775
  ruleId: "E4_MISSING_INHERITANCE",
5786
5776
  severity: "error",
5787
- advice: `Error class '${className}' must extend '${baseErrorClassName}' (or another class that derives from it).`,
5777
+ advice: `Error class '${className}' must extend '${baseErrorClassName}'.`,
5788
5778
  fixExample: {
5789
5779
  bad: lineCode,
5790
5780
  good: `export class ${className} extends ${baseErrorClassName} { ... }`
@@ -5801,7 +5791,7 @@ Code: ${v.code}`;
5801
5791
  code: lineCode,
5802
5792
  ruleId: "E5_NATIVE_ERROR_INHERITANCE",
5803
5793
  severity: "error",
5804
- advice: `Error class '${className}' extends the native 'Error'. It must extend your base error class ('${baseErrorClassName}').`,
5794
+ advice: `Error class '${className}' extends native 'Error'. It must extend your configured base error class ('${baseErrorClassName}').`,
5805
5795
  fixExample: {
5806
5796
  bad: lineCode,
5807
5797
  good: `export class ${className} extends ${baseErrorClassName} { ... }`