@archest/jest 1.0.1 → 1.0.2

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/index.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`@archest/core`)):typeof define==`function`&&define.amd?define([`exports`,`@archest/core`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.JestArch={},e._archest_core))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function n(){expect.extend({toPass(e){let n;n=e?.data&&e.data.type===`LayeredArchitecture`?(0,t.checkLayeredArchitecture)(e.data):e;let{pass:r,message:i}=n;return{pass:this.isNot?!r:r,message:r?()=>`Expected rule not to pass`:()=>i()}},toResideInFolder(e,n){let r;if(e.type===`ClassLocator`)r=(0,t.classCheckResideInFolder)(e,n,!!this.isNot);else throw Error(`toResideInFolder matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toHaveModifier(e,n){let r;if(e.type===`ClassLocator`)r=(0,t.classCheckHaveModifier)(e,n,!!this.isNot);else if(e.type===`FunctionLocator`)r=(0,t.functionCheckHaveModifier)(e,n,!!this.isNot);else throw Error(`toHaveModifier matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toExtendClass(e,n){let r;if(e.type===`ClassLocator`)r=(0,t.classCheckExtendClass)(e,n,!!this.isNot);else throw Error(`toExtendClass matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toImplementInterface(e,n){let r;if(e.type===`ClassLocator`)r=(0,t.classCheckImplementInterface)(e,n,!!this.isNot);else throw Error(`toImplementInterface matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toHaveExplicitReturnType(e){let n;if(e.type===`FunctionLocator`)n=(0,t.functionCheckHaveExplicitReturnType)(e,!!this.isNot);else throw Error(`toHaveExplicitReturnType matcher does not support ${e.type}`);return{pass:this.isNot?!n.pass:n.pass,message:n.message}},toBeReadonly(e){let n;if(e.type===`PropertyLocator`)n=(0,t.propertyCheckBeReadonly)(e,!!this.isNot);else throw Error(`toBeReadonly matcher does not support ${e.type}`);return{pass:this.isNot?!n.pass:n.pass,message:n.message}},toDependOnFilesInFolder(e,n){let r;if(e.type===`FileLocator`)r=(0,t.checkDependOnFilesInFolder)(e,n,!!this.isNot);else throw Error(`toDependOnFilesInFolder matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toDependOnExternalModule(e,n){let r;if(e.type===`FileLocator`)r=(0,t.checkDependOnExternalModule)(e,n,!!this.isNot);else throw Error(`toDependOnExternalModule matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toBeFreeOfCycles(e){let n;if(e.type===`FileLocator`)n=(0,t.fileCheckBeFreeOfCycles)(e,!!this.isNot);else if(e.type===`SliceLocator`)n=(0,t.sliceCheckBeFreeOfCycles)(e,!!this.isNot);else throw Error(`toBeFreeOfCycles matcher does not support ${e.type}`);return{pass:this.isNot?!n.pass:n.pass,message:n.message}},toMatchNamePattern(e,n){let r;if(e.type===`FileLocator`)r=(0,t.fileCheckMatchNamePattern)(e,n,!!this.isNot);else if(e.type===`ClassLocator`)r=(0,t.classCheckMatchNamePattern)(e,n,!!this.isNot);else if(e.type===`FunctionLocator`)r=(0,t.functionCheckMatchNamePattern)(e,n,!!this.isNot);else throw Error(`toMatchNamePattern matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toHaveMaxCyclomaticComplexity(e,n){let r;if(e.type===`FileLocator`)r=(0,t.fileCheckHaveMaxCyclomaticComplexity)(e,n,!!this.isNot);else if(e.type===`ClassLocator`)r=(0,t.classCheckHaveMaxCyclomaticComplexity)(e,n,!!this.isNot);else if(e.type===`FunctionLocator`)r=(0,t.functionCheckHaveMaxCyclomaticComplexity)(e,n,!!this.isNot);else throw Error(`toHaveMaxCyclomaticComplexity matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toHaveMinMaintainabilityIndex(e,n){let r;if(e.type===`FileLocator`)r=(0,t.fileCheckHaveMinMaintainabilityIndex)(e,n,!!this.isNot);else if(e.type===`FunctionLocator`)r=(0,t.functionCheckHaveMinMaintainabilityIndex)(e,n,!!this.isNot);else throw Error(`toHaveMinMaintainabilityIndex matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toHaveMaxDistanceFromMainSequence(e,n){let r;if(e.type===`SliceLocator`)r=(0,t.sliceCheckHaveMaxDistanceFromMainSequence)(e,n,!!this.isNot);else throw Error(`toHaveMaxDistanceFromMainSequence matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toHaveNameMatchingFileName(e){let n;if(e.type===`FunctionLocator`)n=(0,t.functionCheckHaveNameMatchingFileName)(e,!!this.isNot);else if(e.type===`ClassLocator`)n=(0,t.classCheckHaveNameMatchingFileName)(e,!!this.isNot);else throw Error(`toHaveNameMatchingFileName matcher does not support ${e.type}`);return{pass:this.isNot?!n.pass:n.pass,message:n.message}},toHaveMaxExportedFunctions(e,n){let r;if(e.type===`FileLocator`)r=(0,t.fileCheckHaveMaxExportedFunctions)(e,n,!!this.isNot);else throw Error(`toHaveMaxExportedFunctions matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}}})}Object.defineProperty(e,`parseProject`,{enumerable:!0,get:function(){return t.parseProject}}),e.setupMatchers=n});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("@archest/core")):typeof define==`function`&&define.amd?define([`exports`,`@archest/core`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.JestArch={},e._archest_core))})(this,function(e,t){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function n(){expect.extend({toPass(e){let n;n=e?.data&&e.data.type===`LayeredArchitecture`?(0,t.checkLayeredArchitecture)(e.data):e;let{pass:r,message:i}=n;return{pass:this.isNot?!r:r,message:r?()=>`Expected rule not to pass`:()=>i()}},toResideInFolder(e,n){let r;if(e.type===`ClassLocator`)r=(0,t.classCheckResideInFolder)(e,n,!!this.isNot);else throw Error(`toResideInFolder matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toHaveModifier(e,n){let r;if(e.type===`ClassLocator`)r=(0,t.classCheckHaveModifier)(e,n,!!this.isNot);else if(e.type===`FunctionLocator`)r=(0,t.functionCheckHaveModifier)(e,n,!!this.isNot);else throw Error(`toHaveModifier matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toExtendClass(e,n){let r;if(e.type===`ClassLocator`)r=(0,t.classCheckExtendClass)(e,n,!!this.isNot);else throw Error(`toExtendClass matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toImplementInterface(e,n){let r;if(e.type===`ClassLocator`)r=(0,t.classCheckImplementInterface)(e,n,!!this.isNot);else throw Error(`toImplementInterface matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toHaveExplicitReturnType(e){let n;if(e.type===`FunctionLocator`)n=(0,t.functionCheckHaveExplicitReturnType)(e,!!this.isNot);else throw Error(`toHaveExplicitReturnType matcher does not support ${e.type}`);return{pass:this.isNot?!n.pass:n.pass,message:n.message}},toBeReadonly(e){let n;if(e.type===`PropertyLocator`)n=(0,t.propertyCheckBeReadonly)(e,!!this.isNot);else throw Error(`toBeReadonly matcher does not support ${e.type}`);return{pass:this.isNot?!n.pass:n.pass,message:n.message}},toDependOnFilesInFolder(e,n){let r;if(e.type===`FileLocator`)r=(0,t.checkDependOnFilesInFolder)(e,n,!!this.isNot);else throw Error(`toDependOnFilesInFolder matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toDependOnExternalModule(e,n){let r;if(e.type===`FileLocator`)r=(0,t.checkDependOnExternalModule)(e,n,!!this.isNot);else throw Error(`toDependOnExternalModule matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toBeFreeOfCycles(e){let n;if(e.type===`FileLocator`)n=(0,t.fileCheckBeFreeOfCycles)(e,!!this.isNot);else if(e.type===`SliceLocator`)n=(0,t.sliceCheckBeFreeOfCycles)(e,!!this.isNot);else throw Error(`toBeFreeOfCycles matcher does not support ${e.type}`);return{pass:this.isNot?!n.pass:n.pass,message:n.message}},toMatchNamePattern(e,n){let r;if(e.type===`FileLocator`)r=(0,t.fileCheckMatchNamePattern)(e,n,!!this.isNot);else if(e.type===`ClassLocator`)r=(0,t.classCheckMatchNamePattern)(e,n,!!this.isNot);else if(e.type===`FunctionLocator`)r=(0,t.functionCheckMatchNamePattern)(e,n,!!this.isNot);else throw Error(`toMatchNamePattern matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toHaveMaxCyclomaticComplexity(e,n){let r;if(e.type===`FileLocator`)r=(0,t.fileCheckHaveMaxCyclomaticComplexity)(e,n,!!this.isNot);else if(e.type===`ClassLocator`)r=(0,t.classCheckHaveMaxCyclomaticComplexity)(e,n,!!this.isNot);else if(e.type===`FunctionLocator`)r=(0,t.functionCheckHaveMaxCyclomaticComplexity)(e,n,!!this.isNot);else throw Error(`toHaveMaxCyclomaticComplexity matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toHaveMinMaintainabilityIndex(e,n){let r;if(e.type===`FileLocator`)r=(0,t.fileCheckHaveMinMaintainabilityIndex)(e,n,!!this.isNot);else if(e.type===`FunctionLocator`)r=(0,t.functionCheckHaveMinMaintainabilityIndex)(e,n,!!this.isNot);else throw Error(`toHaveMinMaintainabilityIndex matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toHaveMaxDistanceFromMainSequence(e,n){let r;if(e.type===`SliceLocator`)r=(0,t.sliceCheckHaveMaxDistanceFromMainSequence)(e,n,!!this.isNot);else throw Error(`toHaveMaxDistanceFromMainSequence matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}},toHaveNameMatchingFileName(e){let n;if(e.type===`FunctionLocator`)n=(0,t.functionCheckHaveNameMatchingFileName)(e,!!this.isNot);else if(e.type===`ClassLocator`)n=(0,t.classCheckHaveNameMatchingFileName)(e,!!this.isNot);else throw Error(`toHaveNameMatchingFileName matcher does not support ${e.type}`);return{pass:this.isNot?!n.pass:n.pass,message:n.message}},toHaveMaxExportedFunctions(e,n){let r;if(e.type===`FileLocator`)r=(0,t.fileCheckHaveMaxExportedFunctions)(e,n,!!this.isNot);else throw Error(`toHaveMaxExportedFunctions matcher does not support ${e.type}`);return{pass:this.isNot?!r.pass:r.pass,message:r.message}}})}Object.defineProperty(e,"parseProject",{enumerable:!0,get:function(){return t.parseProject}}),e.setupMatchers=n});
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/matchers/index.ts"],"sourcesContent":["/// <reference types=\"jest\" />\nimport {\n checkDependOnExternalModule,\n checkDependOnFilesInFolder,\n checkLayeredArchitecture,\n classCheckExtendClass,\n classCheckHaveMaxCyclomaticComplexity,\n classCheckHaveModifier,\n classCheckHaveNameMatchingFileName,\n classCheckImplementInterface,\n classCheckMatchNamePattern,\n classCheckResideInFolder,\n fileCheckBeFreeOfCycles,\n fileCheckHaveMaxCyclomaticComplexity,\n fileCheckHaveMaxExportedFunctions,\n fileCheckHaveMinMaintainabilityIndex,\n fileCheckMatchNamePattern,\n functionCheckHaveExplicitReturnType,\n functionCheckHaveMaxCyclomaticComplexity,\n functionCheckHaveMinMaintainabilityIndex,\n functionCheckHaveModifier,\n functionCheckHaveNameMatchingFileName,\n functionCheckMatchNamePattern,\n type LocatorData,\n propertyCheckBeReadonly,\n type RuleResult,\n sliceCheckBeFreeOfCycles,\n sliceCheckHaveMaxDistanceFromMainSequence,\n} from '@archest/core';\nimport type { ArchestMatchers } from './models';\n\nexport * from './models';\n\n/**\n * Registers all Archest custom matchers (e.g., `toResideInFolder`, `toHaveModifier`)\n * with the global Vitest `expect` instance.\n *\n * This function must be called exactly once before any architectural tests are run.\n * The standard way to do this is to add it to a Vitest setup file.\n *\n * @example\n * ```typescript\n * // test/setup.ts\n * import { setupMatchers } from '@archest/jest';\n * setupMatchers();\n * ```\n */\nexport function setupMatchers() {\n expect.extend({\n // biome-ignore lint/suspicious/noExplicitAny: Matcher signature\n toPass(received: any) {\n let result: RuleResult;\n\n if (received?.data && received.data.type === 'LayeredArchitecture') {\n result = checkLayeredArchitecture(received.data);\n } else {\n result = received as RuleResult;\n }\n\n const { pass, message } = result;\n return {\n pass: this.isNot ? !pass : pass,\n message: pass ? () => 'Expected rule not to pass' : () => message(),\n };\n },\n\n toResideInFolder(received: LocatorData, folder: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckResideInFolder(received, folder, !!this.isNot);\n } else {\n throw new Error(\n `toResideInFolder matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveModifier(received: LocatorData, modifier: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckHaveModifier(received, modifier, !!this.isNot);\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckHaveModifier(received, modifier, !!this.isNot);\n } else {\n throw new Error(\n `toHaveModifier matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toExtendClass(received: LocatorData, className: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckExtendClass(received, className, !!this.isNot);\n } else {\n throw new Error(\n `toExtendClass matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toImplementInterface(received: LocatorData, interfaceName: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckImplementInterface(\n received,\n interfaceName,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toImplementInterface matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveExplicitReturnType(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'FunctionLocator') {\n result = functionCheckHaveExplicitReturnType(received, !!this.isNot);\n } else {\n throw new Error(\n `toHaveExplicitReturnType matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toBeReadonly(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'PropertyLocator') {\n result = propertyCheckBeReadonly(received, !!this.isNot);\n } else {\n throw new Error(\n `toBeReadonly matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toDependOnFilesInFolder(received: LocatorData, folder: string) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = checkDependOnFilesInFolder(received, folder, !!this.isNot);\n } else {\n throw new Error(\n `toDependOnFilesInFolder matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toDependOnExternalModule(\n received: LocatorData,\n moduleName: string | RegExp,\n ) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = checkDependOnExternalModule(\n received,\n moduleName,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toDependOnExternalModule matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toBeFreeOfCycles(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckBeFreeOfCycles(received, !!this.isNot);\n } else if (received.type === 'SliceLocator') {\n result = sliceCheckBeFreeOfCycles(received, !!this.isNot);\n } else {\n throw new Error(\n `toBeFreeOfCycles matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toMatchNamePattern(received: LocatorData, pattern: string | RegExp) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckMatchNamePattern(received, pattern, !!this.isNot);\n } else if (received.type === 'ClassLocator') {\n result = classCheckMatchNamePattern(received, pattern, !!this.isNot);\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckMatchNamePattern(received, pattern, !!this.isNot);\n } else {\n throw new Error(\n `toMatchNamePattern matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMaxCyclomaticComplexity(received: LocatorData, max: number) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckHaveMaxCyclomaticComplexity(\n received,\n max,\n !!this.isNot,\n );\n } else if (received.type === 'ClassLocator') {\n result = classCheckHaveMaxCyclomaticComplexity(\n received,\n max,\n !!this.isNot,\n );\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckHaveMaxCyclomaticComplexity(\n received,\n max,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toHaveMaxCyclomaticComplexity matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMinMaintainabilityIndex(received: LocatorData, min: number) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckHaveMinMaintainabilityIndex(\n received,\n min,\n !!this.isNot,\n );\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckHaveMinMaintainabilityIndex(\n received,\n min,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toHaveMinMaintainabilityIndex matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMaxDistanceFromMainSequence(received: LocatorData, max: number) {\n let result: RuleResult;\n if (received.type === 'SliceLocator') {\n result = sliceCheckHaveMaxDistanceFromMainSequence(\n received,\n max,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toHaveMaxDistanceFromMainSequence matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveNameMatchingFileName(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'FunctionLocator') {\n result = functionCheckHaveNameMatchingFileName(received, !!this.isNot);\n } else if (received.type === 'ClassLocator') {\n result = classCheckHaveNameMatchingFileName(received, !!this.isNot);\n } else {\n throw new Error(\n `toHaveNameMatchingFileName matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMaxExportedFunctions(received: LocatorData, max: number) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckHaveMaxExportedFunctions(received, max, !!this.isNot);\n } else {\n throw new Error(\n `toHaveMaxExportedFunctions matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n });\n}\n\ndeclare global {\n namespace jest {\n interface Matchers<R> extends ArchestMatchers<R> {}\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/matchers/index.ts"],"sourcesContent":["/// <reference types=\"jest\" />\nimport {\n checkDependOnExternalModule,\n checkDependOnFilesInFolder,\n checkLayeredArchitecture,\n classCheckExtendClass,\n classCheckHaveMaxCyclomaticComplexity,\n classCheckHaveModifier,\n classCheckHaveNameMatchingFileName,\n classCheckImplementInterface,\n classCheckMatchNamePattern,\n classCheckResideInFolder,\n fileCheckBeFreeOfCycles,\n fileCheckHaveMaxCyclomaticComplexity,\n fileCheckHaveMaxExportedFunctions,\n fileCheckHaveMinMaintainabilityIndex,\n fileCheckMatchNamePattern,\n functionCheckHaveExplicitReturnType,\n functionCheckHaveMaxCyclomaticComplexity,\n functionCheckHaveMinMaintainabilityIndex,\n functionCheckHaveModifier,\n functionCheckHaveNameMatchingFileName,\n functionCheckMatchNamePattern,\n type LocatorData,\n propertyCheckBeReadonly,\n type RuleResult,\n sliceCheckBeFreeOfCycles,\n sliceCheckHaveMaxDistanceFromMainSequence,\n} from '@archest/core';\nimport type { ArchestMatchers } from './models';\n\nexport * from './models';\n\n/**\n * Registers all Archest custom matchers (e.g., `toResideInFolder`, `toHaveModifier`)\n * with the global Vitest `expect` instance.\n *\n * This function must be called exactly once before any architectural tests are run.\n * The standard way to do this is to add it to a Vitest setup file.\n *\n * @example\n * ```typescript\n * // test/setup.ts\n * import { setupMatchers } from '@archest/jest';\n * setupMatchers();\n * ```\n */\nexport function setupMatchers() {\n expect.extend({\n // biome-ignore lint/suspicious/noExplicitAny: Matcher signature\n toPass(received: any) {\n let result: RuleResult;\n\n if (received?.data && received.data.type === 'LayeredArchitecture') {\n result = checkLayeredArchitecture(received.data);\n } else {\n result = received as RuleResult;\n }\n\n const { pass, message } = result;\n return {\n pass: this.isNot ? !pass : pass,\n message: pass ? () => 'Expected rule not to pass' : () => message(),\n };\n },\n\n toResideInFolder(received: LocatorData, folder: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckResideInFolder(received, folder, !!this.isNot);\n } else {\n throw new Error(\n `toResideInFolder matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveModifier(received: LocatorData, modifier: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckHaveModifier(received, modifier, !!this.isNot);\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckHaveModifier(received, modifier, !!this.isNot);\n } else {\n throw new Error(\n `toHaveModifier matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toExtendClass(received: LocatorData, className: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckExtendClass(received, className, !!this.isNot);\n } else {\n throw new Error(\n `toExtendClass matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toImplementInterface(received: LocatorData, interfaceName: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckImplementInterface(\n received,\n interfaceName,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toImplementInterface matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveExplicitReturnType(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'FunctionLocator') {\n result = functionCheckHaveExplicitReturnType(received, !!this.isNot);\n } else {\n throw new Error(\n `toHaveExplicitReturnType matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toBeReadonly(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'PropertyLocator') {\n result = propertyCheckBeReadonly(received, !!this.isNot);\n } else {\n throw new Error(\n `toBeReadonly matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toDependOnFilesInFolder(received: LocatorData, folder: string) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = checkDependOnFilesInFolder(received, folder, !!this.isNot);\n } else {\n throw new Error(\n `toDependOnFilesInFolder matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toDependOnExternalModule(\n received: LocatorData,\n moduleName: string | RegExp,\n ) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = checkDependOnExternalModule(\n received,\n moduleName,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toDependOnExternalModule matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toBeFreeOfCycles(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckBeFreeOfCycles(received, !!this.isNot);\n } else if (received.type === 'SliceLocator') {\n result = sliceCheckBeFreeOfCycles(received, !!this.isNot);\n } else {\n throw new Error(\n `toBeFreeOfCycles matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toMatchNamePattern(received: LocatorData, pattern: string | RegExp) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckMatchNamePattern(received, pattern, !!this.isNot);\n } else if (received.type === 'ClassLocator') {\n result = classCheckMatchNamePattern(received, pattern, !!this.isNot);\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckMatchNamePattern(received, pattern, !!this.isNot);\n } else {\n throw new Error(\n `toMatchNamePattern matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMaxCyclomaticComplexity(received: LocatorData, max: number) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckHaveMaxCyclomaticComplexity(\n received,\n max,\n !!this.isNot,\n );\n } else if (received.type === 'ClassLocator') {\n result = classCheckHaveMaxCyclomaticComplexity(\n received,\n max,\n !!this.isNot,\n );\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckHaveMaxCyclomaticComplexity(\n received,\n max,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toHaveMaxCyclomaticComplexity matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMinMaintainabilityIndex(received: LocatorData, min: number) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckHaveMinMaintainabilityIndex(\n received,\n min,\n !!this.isNot,\n );\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckHaveMinMaintainabilityIndex(\n received,\n min,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toHaveMinMaintainabilityIndex matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMaxDistanceFromMainSequence(received: LocatorData, max: number) {\n let result: RuleResult;\n if (received.type === 'SliceLocator') {\n result = sliceCheckHaveMaxDistanceFromMainSequence(\n received,\n max,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toHaveMaxDistanceFromMainSequence matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveNameMatchingFileName(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'FunctionLocator') {\n result = functionCheckHaveNameMatchingFileName(received, !!this.isNot);\n } else if (received.type === 'ClassLocator') {\n result = classCheckHaveNameMatchingFileName(received, !!this.isNot);\n } else {\n throw new Error(\n `toHaveNameMatchingFileName matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMaxExportedFunctions(received: LocatorData, max: number) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckHaveMaxExportedFunctions(received, max, !!this.isNot);\n } else {\n throw new Error(\n `toHaveMaxExportedFunctions matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n });\n}\n\ndeclare global {\n namespace jest {\n interface Matchers<R> extends ArchestMatchers<R> {}\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/matchers/index.ts"],"sourcesContent":["/// <reference types=\"jest\" />\nimport {\n checkDependOnExternalModule,\n checkDependOnFilesInFolder,\n checkLayeredArchitecture,\n classCheckExtendClass,\n classCheckHaveMaxCyclomaticComplexity,\n classCheckHaveModifier,\n classCheckHaveNameMatchingFileName,\n classCheckImplementInterface,\n classCheckMatchNamePattern,\n classCheckResideInFolder,\n fileCheckBeFreeOfCycles,\n fileCheckHaveMaxCyclomaticComplexity,\n fileCheckHaveMaxExportedFunctions,\n fileCheckHaveMinMaintainabilityIndex,\n fileCheckMatchNamePattern,\n functionCheckHaveExplicitReturnType,\n functionCheckHaveMaxCyclomaticComplexity,\n functionCheckHaveMinMaintainabilityIndex,\n functionCheckHaveModifier,\n functionCheckHaveNameMatchingFileName,\n functionCheckMatchNamePattern,\n type LocatorData,\n propertyCheckBeReadonly,\n type RuleResult,\n sliceCheckBeFreeOfCycles,\n sliceCheckHaveMaxDistanceFromMainSequence,\n} from '@archest/core';\nimport type { ArchestMatchers } from './models';\n\nexport * from './models';\n\n/**\n * Registers all Archest custom matchers (e.g., `toResideInFolder`, `toHaveModifier`)\n * with the global Vitest `expect` instance.\n *\n * This function must be called exactly once before any architectural tests are run.\n * The standard way to do this is to add it to a Vitest setup file.\n *\n * @example\n * ```typescript\n * // test/setup.ts\n * import { setupMatchers } from '@archest/jest';\n * setupMatchers();\n * ```\n */\nexport function setupMatchers() {\n expect.extend({\n // biome-ignore lint/suspicious/noExplicitAny: Matcher signature\n toPass(received: any) {\n let result: RuleResult;\n\n if (received?.data && received.data.type === 'LayeredArchitecture') {\n result = checkLayeredArchitecture(received.data);\n } else {\n result = received as RuleResult;\n }\n\n const { pass, message } = result;\n return {\n pass: this.isNot ? !pass : pass,\n message: pass ? () => 'Expected rule not to pass' : () => message(),\n };\n },\n\n toResideInFolder(received: LocatorData, folder: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckResideInFolder(received, folder, !!this.isNot);\n } else {\n throw new Error(\n `toResideInFolder matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveModifier(received: LocatorData, modifier: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckHaveModifier(received, modifier, !!this.isNot);\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckHaveModifier(received, modifier, !!this.isNot);\n } else {\n throw new Error(\n `toHaveModifier matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toExtendClass(received: LocatorData, className: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckExtendClass(received, className, !!this.isNot);\n } else {\n throw new Error(\n `toExtendClass matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toImplementInterface(received: LocatorData, interfaceName: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckImplementInterface(\n received,\n interfaceName,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toImplementInterface matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveExplicitReturnType(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'FunctionLocator') {\n result = functionCheckHaveExplicitReturnType(received, !!this.isNot);\n } else {\n throw new Error(\n `toHaveExplicitReturnType matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toBeReadonly(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'PropertyLocator') {\n result = propertyCheckBeReadonly(received, !!this.isNot);\n } else {\n throw new Error(\n `toBeReadonly matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toDependOnFilesInFolder(received: LocatorData, folder: string) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = checkDependOnFilesInFolder(received, folder, !!this.isNot);\n } else {\n throw new Error(\n `toDependOnFilesInFolder matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toDependOnExternalModule(\n received: LocatorData,\n moduleName: string | RegExp,\n ) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = checkDependOnExternalModule(\n received,\n moduleName,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toDependOnExternalModule matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toBeFreeOfCycles(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckBeFreeOfCycles(received, !!this.isNot);\n } else if (received.type === 'SliceLocator') {\n result = sliceCheckBeFreeOfCycles(received, !!this.isNot);\n } else {\n throw new Error(\n `toBeFreeOfCycles matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toMatchNamePattern(received: LocatorData, pattern: string | RegExp) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckMatchNamePattern(received, pattern, !!this.isNot);\n } else if (received.type === 'ClassLocator') {\n result = classCheckMatchNamePattern(received, pattern, !!this.isNot);\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckMatchNamePattern(received, pattern, !!this.isNot);\n } else {\n throw new Error(\n `toMatchNamePattern matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMaxCyclomaticComplexity(received: LocatorData, max: number) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckHaveMaxCyclomaticComplexity(\n received,\n max,\n !!this.isNot,\n );\n } else if (received.type === 'ClassLocator') {\n result = classCheckHaveMaxCyclomaticComplexity(\n received,\n max,\n !!this.isNot,\n );\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckHaveMaxCyclomaticComplexity(\n received,\n max,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toHaveMaxCyclomaticComplexity matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMinMaintainabilityIndex(received: LocatorData, min: number) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckHaveMinMaintainabilityIndex(\n received,\n min,\n !!this.isNot,\n );\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckHaveMinMaintainabilityIndex(\n received,\n min,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toHaveMinMaintainabilityIndex matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMaxDistanceFromMainSequence(received: LocatorData, max: number) {\n let result: RuleResult;\n if (received.type === 'SliceLocator') {\n result = sliceCheckHaveMaxDistanceFromMainSequence(\n received,\n max,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toHaveMaxDistanceFromMainSequence matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveNameMatchingFileName(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'FunctionLocator') {\n result = functionCheckHaveNameMatchingFileName(received, !!this.isNot);\n } else if (received.type === 'ClassLocator') {\n result = classCheckHaveNameMatchingFileName(received, !!this.isNot);\n } else {\n throw new Error(\n `toHaveNameMatchingFileName matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMaxExportedFunctions(received: LocatorData, max: number) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckHaveMaxExportedFunctions(received, max, !!this.isNot);\n } else {\n throw new Error(\n `toHaveMaxExportedFunctions matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n });\n}\n\ndeclare global {\n namespace jest {\n interface Matchers<R> extends ArchestMatchers<R> {}\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/matchers/index.ts"],"sourcesContent":["/// <reference types=\"jest\" />\nimport {\n checkDependOnExternalModule,\n checkDependOnFilesInFolder,\n checkLayeredArchitecture,\n classCheckExtendClass,\n classCheckHaveMaxCyclomaticComplexity,\n classCheckHaveModifier,\n classCheckHaveNameMatchingFileName,\n classCheckImplementInterface,\n classCheckMatchNamePattern,\n classCheckResideInFolder,\n fileCheckBeFreeOfCycles,\n fileCheckHaveMaxCyclomaticComplexity,\n fileCheckHaveMaxExportedFunctions,\n fileCheckHaveMinMaintainabilityIndex,\n fileCheckMatchNamePattern,\n functionCheckHaveExplicitReturnType,\n functionCheckHaveMaxCyclomaticComplexity,\n functionCheckHaveMinMaintainabilityIndex,\n functionCheckHaveModifier,\n functionCheckHaveNameMatchingFileName,\n functionCheckMatchNamePattern,\n type LocatorData,\n propertyCheckBeReadonly,\n type RuleResult,\n sliceCheckBeFreeOfCycles,\n sliceCheckHaveMaxDistanceFromMainSequence,\n} from '@archest/core';\nimport type { ArchestMatchers } from './models';\n\nexport * from './models';\n\n/**\n * Registers all Archest custom matchers (e.g., `toResideInFolder`, `toHaveModifier`)\n * with the global Vitest `expect` instance.\n *\n * This function must be called exactly once before any architectural tests are run.\n * The standard way to do this is to add it to a Vitest setup file.\n *\n * @example\n * ```typescript\n * // test/setup.ts\n * import { setupMatchers } from '@archest/jest';\n * setupMatchers();\n * ```\n */\nexport function setupMatchers() {\n expect.extend({\n // biome-ignore lint/suspicious/noExplicitAny: Matcher signature\n toPass(received: any) {\n let result: RuleResult;\n\n if (received?.data && received.data.type === 'LayeredArchitecture') {\n result = checkLayeredArchitecture(received.data);\n } else {\n result = received as RuleResult;\n }\n\n const { pass, message } = result;\n return {\n pass: this.isNot ? !pass : pass,\n message: pass ? () => 'Expected rule not to pass' : () => message(),\n };\n },\n\n toResideInFolder(received: LocatorData, folder: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckResideInFolder(received, folder, !!this.isNot);\n } else {\n throw new Error(\n `toResideInFolder matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveModifier(received: LocatorData, modifier: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckHaveModifier(received, modifier, !!this.isNot);\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckHaveModifier(received, modifier, !!this.isNot);\n } else {\n throw new Error(\n `toHaveModifier matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toExtendClass(received: LocatorData, className: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckExtendClass(received, className, !!this.isNot);\n } else {\n throw new Error(\n `toExtendClass matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toImplementInterface(received: LocatorData, interfaceName: string) {\n let result: RuleResult;\n if (received.type === 'ClassLocator') {\n result = classCheckImplementInterface(\n received,\n interfaceName,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toImplementInterface matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveExplicitReturnType(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'FunctionLocator') {\n result = functionCheckHaveExplicitReturnType(received, !!this.isNot);\n } else {\n throw new Error(\n `toHaveExplicitReturnType matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toBeReadonly(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'PropertyLocator') {\n result = propertyCheckBeReadonly(received, !!this.isNot);\n } else {\n throw new Error(\n `toBeReadonly matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toDependOnFilesInFolder(received: LocatorData, folder: string) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = checkDependOnFilesInFolder(received, folder, !!this.isNot);\n } else {\n throw new Error(\n `toDependOnFilesInFolder matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toDependOnExternalModule(\n received: LocatorData,\n moduleName: string | RegExp,\n ) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = checkDependOnExternalModule(\n received,\n moduleName,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toDependOnExternalModule matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toBeFreeOfCycles(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckBeFreeOfCycles(received, !!this.isNot);\n } else if (received.type === 'SliceLocator') {\n result = sliceCheckBeFreeOfCycles(received, !!this.isNot);\n } else {\n throw new Error(\n `toBeFreeOfCycles matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toMatchNamePattern(received: LocatorData, pattern: string | RegExp) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckMatchNamePattern(received, pattern, !!this.isNot);\n } else if (received.type === 'ClassLocator') {\n result = classCheckMatchNamePattern(received, pattern, !!this.isNot);\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckMatchNamePattern(received, pattern, !!this.isNot);\n } else {\n throw new Error(\n `toMatchNamePattern matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMaxCyclomaticComplexity(received: LocatorData, max: number) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckHaveMaxCyclomaticComplexity(\n received,\n max,\n !!this.isNot,\n );\n } else if (received.type === 'ClassLocator') {\n result = classCheckHaveMaxCyclomaticComplexity(\n received,\n max,\n !!this.isNot,\n );\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckHaveMaxCyclomaticComplexity(\n received,\n max,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toHaveMaxCyclomaticComplexity matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMinMaintainabilityIndex(received: LocatorData, min: number) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckHaveMinMaintainabilityIndex(\n received,\n min,\n !!this.isNot,\n );\n } else if (received.type === 'FunctionLocator') {\n result = functionCheckHaveMinMaintainabilityIndex(\n received,\n min,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toHaveMinMaintainabilityIndex matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMaxDistanceFromMainSequence(received: LocatorData, max: number) {\n let result: RuleResult;\n if (received.type === 'SliceLocator') {\n result = sliceCheckHaveMaxDistanceFromMainSequence(\n received,\n max,\n !!this.isNot,\n );\n } else {\n throw new Error(\n `toHaveMaxDistanceFromMainSequence matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveNameMatchingFileName(received: LocatorData) {\n let result: RuleResult;\n if (received.type === 'FunctionLocator') {\n result = functionCheckHaveNameMatchingFileName(received, !!this.isNot);\n } else if (received.type === 'ClassLocator') {\n result = classCheckHaveNameMatchingFileName(received, !!this.isNot);\n } else {\n throw new Error(\n `toHaveNameMatchingFileName matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n\n toHaveMaxExportedFunctions(received: LocatorData, max: number) {\n let result: RuleResult;\n if (received.type === 'FileLocator') {\n result = fileCheckHaveMaxExportedFunctions(received, max, !!this.isNot);\n } else {\n throw new Error(\n `toHaveMaxExportedFunctions matcher does not support ${received.type}`,\n );\n }\n return {\n pass: this.isNot ? !result.pass : result.pass,\n message: result.message,\n };\n },\n });\n}\n\ndeclare global {\n namespace jest {\n interface Matchers<R> extends ArchestMatchers<R> {}\n }\n}\n"],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  * This interface extends Vitest's `Assertion` interface to provide fluent assertions
5
5
  * on your codebase's architectural structure.
6
6
  */
7
- export interface ArchestMatchers<R = unknown> {
7
+ export interface ArchestMatchers<_R = unknown> {
8
8
  /**
9
9
  * Asserts that the evaluated architectural rule passes.
10
10
  * Primarily used for complex rules like LayeredArchitecture.
@@ -1,2 +1,2 @@
1
1
  import { FileData, ProjectData } from '../dto';
2
- export declare function getFileDependencies(sourceFile: FileData, projectData: ProjectData): string[];
2
+ export declare function getFileDependencies(sourceFile: FileData, _projectData: ProjectData): string[];
@@ -1,11 +1,11 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require(`node:path`),require(`@archest/core-rust`),require(`typescript`)):typeof define==`function`&&define.amd?define([`exports`,`node:path`,`@archest/core-rust`,`typescript`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.VitestArch={},e.node_path,e._archest_core_rust,e.typescript))})(this,function(e,t,n,r){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var i=Object.create,a=Object.defineProperty,o=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,c=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty,u=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=s(t),c=0,u=i.length,d;c<u;c++)d=i[c],!l.call(e,d)&&d!==n&&a(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(r=o(t,d))||r.enumerable});return e},d=(e,t,n)=>(n=e==null?{}:i(c(e)),u(t||!e||!e.__esModule?a(n,`default`,{value:e,enumerable:!0}):n,e));t=d(t),r=d(r);function f(e,t,n){let r=[];for(let i of e.classes){let e=i.name||`Anonymous`,a=!1;i.extends===t&&(a=!0),n&&a?r.push(`Class ${e} extends ${t}, but it shouldn't.`):!n&&!a&&r.push(`Class ${e} does not extend ${t}, but it should.`)}return{pass:r.length===0,message:()=>r.join(`
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("node:path"),require("@archest/core-rust"),require("typescript")):typeof define==`function`&&define.amd?define([`exports`,`node:path`,`@archest/core-rust`,`typescript`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.VitestArch={},e.node_path,e._archest_core_rust,e.typescript))})(this,function(e,t,n,r){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var i=Object.create,a=Object.defineProperty,o=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,c=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty,u=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=s(t),c=0,u=i.length,d;c<u;c++)d=i[c],!l.call(e,d)&&d!==n&&a(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(r=o(t,d))||r.enumerable});return e},d=(e,t,n)=>(n=e==null?{}:i(c(e)),u(t||!e||!e.__esModule?a(n,`default`,{value:e,enumerable:!0}):n,e));t=d(t),r=d(r);function f(e,t,n){let r=[];for(let i of e.classes){let e=i.name||`Anonymous`,a=!1;i.extends===t&&(a=!0),n&&a?r.push(`Class ${e} extends ${t}, but it shouldn't.`):!n&&!a&&r.push(`Class ${e} does not extend ${t}, but it should.`)}return{pass:r.length===0,message:()=>r.join(`
2
2
  `)}}function p(e,t,n){let r=[];for(let i of e){let{passes:e,failMessage:a,failNotMessage:o}=n(i);t&&e?o&&r.push(o):!t&&!e&&a&&r.push(a)}return{pass:r.length===0,message:()=>r.join(`
3
3
  `)}}function m(e,t,n,r,i,a){return p(e,a,e=>{let a=t(e),o=n(e),s=o>i,c=`${r} ${a||`Anonymous`}`;return{passes:!s,failMessage:`${c} has a total cyclomatic complexity of ${o}, which exceeds the maximum of ${i}.`,failNotMessage:`${c} has a total cyclomatic complexity of ${o}, which exceeds the maximum of ${i}, but it shouldn't.`}})}function h(e,t,n){return m(e.classes,e=>e.name,e=>e.cyclomatic_complexity||0,`Class`,t,n)}function g(e,t,n,r,i){return p(e,i,e=>{let i=t(e),a=!1;switch(r){case`export`:a=!!e.is_exported;break;case`default`:a=!!e.is_default;break;case`abstract`:a=!!e.is_abstract;break;case`async`:a=!!e.is_async;break;case`readonly`:a=!!e.is_readonly;break;default:throw Error(`Modifier ${r} is not fully supported.`)}let o=`${n} ${i||`Anonymous`}`;return{passes:a,failMessage:`${o} does not have modifier ${r}, but it should.`,failNotMessage:`${o} has modifier ${r}, but it shouldn't.`}})}function _(e,t,n){return g(e.classes,e=>e.name,`Class`,t,n)}function v(e,n,r,i){return p(e,i,e=>{let i=n(e);if(!e._filePath)return{passes:!0,failMessage:``,failNotMessage:``};let a=t.basename(e._filePath,t.extname(e._filePath)),o=i===a,s=`${r} ${i||`Anonymous`}`;return{passes:o,failMessage:`${s} does not have a name matching its filename ${a}, but it should.`,failNotMessage:`${s} has a name matching its filename ${a}, but it shouldn't.`}})}function y(e,t){return v(e.classes,e=>e.name,`Class`,t)}function b(e,t,n){let r=[];for(let i of e.classes){let e=i.name||`Anonymous`,a=!1;i.implements.includes(t)&&(a=!0),n&&a?r.push(`Class ${e} implements ${t}, but it shouldn't.`):!n&&!a&&r.push(`Class ${e} does not implement ${t}, but it should.`)}return{pass:r.length===0,message:()=>r.join(`
4
4
  `)}}function x(e,t,n,r,i){let a=typeof r==`string`?new RegExp(r):r;return p(e,i,e=>{let i=t(e),o=i?a.test(i):!1,s=`${n} ${i||`Anonymous`}`;return{passes:o,failMessage:`${s} does not match pattern ${r}, but it should.`,failNotMessage:`${s} matches pattern ${r}, but it shouldn't.`}})}function ee(e,t,n){return x(e.classes,e=>e.name,`Class`,t,n)}function S(e,t,n){let r=[];for(let i of e.classes){let e=i.name||`Anonymous Class`,a=i._filePath,o=a.includes(`/${t}/`)||a.includes(`\\${t}\\`);n&&o?r.push(`Class ${e} resides in ${t}, but it shouldn't.`):!n&&!o&&r.push(`Class ${e} does not reside in ${t}, but it should.`)}return{pass:r.length===0,message:()=>r.join(`
5
- `)}}function C(e,t,n){let r=e;if(n?.inFolder&&(r=r.filter(e=>e._filePath.includes(`/${n.inFolder}/`)||e._filePath.includes(`\\${n.inFolder}\\`))),n?.matchNamePattern){let e=typeof n.matchNamePattern==`string`?new RegExp(n.matchNamePattern):n.matchNamePattern;r=r.filter(t=>t.name&&e.test(t.name))}return n?.withDecorator&&(r=r.filter(e=>e.decorators.includes(n.withDecorator))),n?.extending&&(r=r.filter(e=>e.extends===n.extending)),n?.implementing&&(r=r.filter(e=>e.implements.includes(n.implementing))),n?.havingModifier&&(r=r.filter(e=>{switch(n.havingModifier){case`export`:return e.is_exported;case`default`:return e.is_default;case`abstract`:return e.is_abstract;default:throw Error(`Modifier ${n.havingModifier} is not fully supported.`)}})),{type:`ClassLocator`,classes:r,projectData:t}}function w(e,t,n){let r=[],i=typeof t==`string`?new RegExp(t):t;for(let a of e.files){let e=(a.external_dependencies||[]).some(e=>i.test(e));n&&e?r.push(`${a.path} incorrectly depends on external module '${t}'`):!n&&!e&&r.push(`${a.path} does not depend on external module '${t}'`)}return{pass:r.length===0,message:()=>r.join(`
5
+ `)}}function C(e,t,n){let r=e;if(n?.inFolder&&(r=r.filter(e=>e._filePath.includes(`/${n.inFolder}/`)||e._filePath.includes(`\\${n.inFolder}\\`))),n?.matchNamePattern){let e=typeof n.matchNamePattern==`string`?new RegExp(n.matchNamePattern):n.matchNamePattern;r=r.filter(t=>t.name&&e.test(t.name))}if(n?.withDecorator){let e=n.withDecorator;r=r.filter(t=>t.decorators.includes(e))}if(n?.extending&&(r=r.filter(e=>e.extends===n.extending)),n?.implementing){let e=n.implementing;r=r.filter(t=>t.implements.includes(e))}return n?.havingModifier&&(r=r.filter(e=>{switch(n.havingModifier){case`export`:return e.is_exported;case`default`:return e.is_default;case`abstract`:return e.is_abstract;default:throw Error(`Modifier ${n.havingModifier} is not fully supported.`)}})),{type:`ClassLocator`,classes:r,projectData:t}}function w(e,t,n){let r=[],i=typeof t==`string`?new RegExp(t):t;for(let a of e.files){let e=(a.external_dependencies||[]).some(e=>i.test(e));n&&e?r.push(`${a.path} incorrectly depends on external module '${t}'`):!n&&!e&&r.push(`${a.path} does not depend on external module '${t}'`)}return{pass:r.length===0,message:()=>r.join(`
6
6
  `)}}function T(e,t){return e.dependencies||[]}function E(e,t,n){let r=[];for(let i of e.files){let a=T(i,e.projectData).some(e=>e.includes(`/${t}/`)||e.includes(`\\${t}\\`));n&&a?r.push(`File ${i.path} depends on files in ${t}, but it shouldn't.`):!n&&!a&&r.push(`File ${i.path} does not depend on files in ${t}, but it should.`)}return{pass:r.length===0,message:()=>r.join(`
7
7
  `)}}function D(e,t){let n=e.files.map(e=>e.path),r=e.archestProject;if(!r)return{pass:!0,message:()=>`Mock pass: archestProject not in registry`};let i=r.checkFileCycles(n,!!t);return{pass:i.pass,message:()=>i.message}}function O(e,t,n){return m(e.files,e=>e.path,e=>{let t=0;for(let n of e.functions)t+=n.cyclomatic_complexity||0;for(let n of e.classes)t+=n.cyclomatic_complexity||0;return t},`File`,t,n)}function k(e,t,n){let r=[];for(let i of e.files){let e=i.functions.filter(e=>e.is_exported).length,a=e>t;n&&a?r.push(`File ${i.path} has ${e} exported functions, which exceeds the maximum of ${t}, but it shouldn't.`):!n&&a&&r.push(`File ${i.path} has ${e} exported functions, which exceeds the maximum of ${t}.`)}return{pass:n?r.length>0:r.length===0,message:()=>r.join(`
8
- `)||(n?`Expected some files to exceed maximum exported functions, but none did.`:``)}}function A(e,t,n,r,i,a){return p(e,a,e=>{let a=t(e),o=n(e),s=o<i,c=`${r} ${a||`Anonymous`}`;return{passes:!s,failMessage:`${c} has a maintainability index of ${o.toFixed(2)}, which falls below the minimum of ${i}.`,failNotMessage:`${c} has a maintainability index of ${o.toFixed(2)}, which falls below the minimum of ${i}, but it shouldn't.`}})}function te(e,t,n){return A(e.files,e=>e.path,e=>e.functions.length>0&&e.functions[0].maintainability_index||100,`File`,t,n)}function ne(e,t,n){return x(e.files,e=>e.path,`File`,t,n)}function j(e,t,n,r){let i=e;if(r?.inFolder&&(i=i.filter(e=>e.path.includes(`/${r.inFolder}/`)||e.path.includes(`\\${r.inFolder}\\`))),r?.matchNamePattern){let e=typeof r.matchNamePattern==`string`?new RegExp(r.matchNamePattern):r.matchNamePattern;i=i.filter(t=>e.test(t.path))}let a={type:`FileLocator`,files:i,projectData:t};return n&&Object.defineProperty(a,`archestProject`,{value:n,enumerable:!1}),a}function M(e,t){let n=[];for(let r of e.functions){let e=r.name||`Anonymous Function`,i=r.has_explicit_return_type;t&&i?n.push(`Function ${e} has an explicit return type, but it shouldn't.`):!t&&!i&&n.push(`Function ${e} does not have an explicit return type, but it should.`)}return{pass:n.length===0,message:()=>n.join(`
8
+ `)||(n?`Expected some files to exceed maximum exported functions, but none did.`:``)}}function A(e,t,n,r,i,a){return p(e,a,e=>{let a=t(e),o=n(e),s=o<i,c=`${r} ${a||`Anonymous`}`;return{passes:!s,failMessage:`${c} has a maintainability index of ${o.toFixed(2)}, which falls below the minimum of ${i}.`,failNotMessage:`${c} has a maintainability index of ${o.toFixed(2)}, which falls below the minimum of ${i}, but it shouldn't.`}})}function te(e,t,n){return A(e.files,e=>e.path,e=>e.functions.length>0&&e.functions[0].maintainability_index||100,`File`,t,n)}function ne(e,t,n){return x(e.files,e=>e.path,`File`,t,n)}function j(e,t,n,r){let i=e;if(r?.inFolder&&(i=i.filter(e=>e.path.includes(`/${r.inFolder}/`)||e.path.includes(`\\${r.inFolder}\\`))),r?.matchNamePattern){let e=typeof r.matchNamePattern==`string`?new RegExp(r.matchNamePattern):r.matchNamePattern;i=i.filter(t=>e.test(t.path))}let a={type:`FileLocator`,files:i,projectData:t};return n&&Object.defineProperty(a,"archestProject",{value:n,enumerable:!1}),a}function M(e,t){let n=[];for(let r of e.functions){let e=r.name||`Anonymous Function`,i=r.has_explicit_return_type;t&&i?n.push(`Function ${e} has an explicit return type, but it shouldn't.`):!t&&!i&&n.push(`Function ${e} does not have an explicit return type, but it should.`)}return{pass:n.length===0,message:()=>n.join(`
9
9
  `)}}function N(e,t,n){return m(e.functions,e=>e.name,e=>e.cyclomatic_complexity||0,`Function`,t,n)}function P(e,t,n){return A(e.functions,e=>e.name,e=>e.maintainability_index||100,`Function`,t,n)}function F(e,t,n){return g(e.functions,e=>e.name,`Function`,t,n)}function I(e,t){return v(e.functions,e=>e.name,`Function`,t)}function L(e,t,n){return x(e.functions,e=>e.name,`Function`,t,n)}function R(e,t,n){let r=e;if(n?.inFolder&&(r=r.filter(e=>e._filePath.includes(`/${n.inFolder}/`)||e._filePath.includes(`\\${n.inFolder}\\`))),n?.matchNamePattern){let e=typeof n.matchNamePattern==`string`?new RegExp(n.matchNamePattern):n.matchNamePattern;r=r.filter(t=>t.name&&e.test(t.name))}return n?.isTopLevel&&(r=r.filter(e=>e.is_top_level)),{type:`FunctionLocator`,functions:r,projectData:t}}function z(e){let t=[];for(let n of e.assertions)t.push(...n(e.files));return{pass:t.length===0,message:()=>t.join(`
10
10
  `)}}function B(e,t){return{type:`LayeredArchitecture`,files:e,layers:new Map,assertions:[],projectData:t}}function V(e,t,n){return e.layers.set(t,n),e}function H(e,t){return e.dependencies||[]}function U(e,t){if(!e.layers.has(t))throw Error(`Layer ${t} is not defined`);return e.assertions.push(n=>{let r=[],i=e.layers.get(t);for(let a of n){let n=a.path;!n.includes(`/${i}/`)&&!n.includes(`\\${i}\\`)&&H(a,e.projectData).some(e=>e.includes(`/${i}/`)||e.includes(`\\${i}\\`))&&r.push(`File ${n} accesses layer ${t} but it shouldn't.`)}return r}),e}function W(e,t,n){if(!e.layers.has(t))throw Error(`Layer ${t} is not defined`);return e.assertions.push(r=>{let i=[],a=e.layers.get(t),o=n.map(t=>e.layers.get(t));for(let s of r){let r=s.path,c=o.some(e=>r.includes(`/${e}/`)||r.includes(`\\${e}\\`));!r.includes(`/${a}/`)&&!r.includes(`\\${a}\\`)&&!c&&H(s,e.projectData).some(e=>e.includes(`/${a}/`)||e.includes(`\\${a}\\`))&&i.push(`File ${r} accesses layer ${t} but only ${n.join(`, `)} are allowed.`)}return i}),e}function G(e,t,n){let r=e;if(n?.inFolder&&(r=r.filter(e=>e._filePath.includes(`/${n.inFolder}/`)||e._filePath.includes(`\\${n.inFolder}\\`))),n?.matchNamePattern){let e=typeof n.matchNamePattern==`string`?new RegExp(n.matchNamePattern):n.matchNamePattern;r=r.filter(t=>e.test(t.name))}return{type:`PropertyLocator`,properties:r,projectData:t}}function K(e,t,n){let r=n.replace(/[.+?^${}()|[\]\\]/g,`\\$&`).replace(/\*/g,`([^/\\\\]+)`),i=new RegExp(r),a=new Set,o=new Map;for(let t of e){let e=t.path.match(i);if(e?.[1]){let n=e[1];a.add(n),o.has(n)||o.set(n,[]),o.get(n)?.push(t)}}return{type:`SliceLocator`,slicePattern:i,sliceIds:a,sliceFiles:o,projectData:t}}function q(e={}){let i=e.tsConfigFilePath||r.findConfigFile(process.cwd(),r.sys.fileExists,`tsconfig.json`);if(!i)throw Error(`Could not find tsconfig.json`);let a=(0,t.dirname)(i),o=r.readConfigFile(i,r.sys.readFile);e.include&&(o.config.include=e.include),e.exclude&&(o.config.exclude=e.exclude);let s=r.parseJsonConfigFileContent(o.config,r.sys,a,void 0,i,void 0,[{extension:`.vue`,isMixedContent:!0,scriptKind:r.ScriptKind.TS},{extension:`.svelte`,isMixedContent:!0,scriptKind:r.ScriptKind.TS}]),c=n.ArchestProject.parse(s.fileNames),l=JSON.parse(c.getProjectData());return{projectData:l,getFiles:e=>j(l.files,l,c,e),getClasses:e=>C(l.files.flatMap(e=>e.classes.map(t=>({...t,_filePath:e.path}))),l,e),layeredArchitecture:()=>{let e=B(l.files,l),t={layer:(n,r)=>(e=V(e,n,r),t),whereLayer:n=>({shouldNotBeAccessedByAnyLayer:()=>(e=U(e,n),t),shouldOnlyBeAccessedBy:(...r)=>(e=W(e,n,r),t)}),check:()=>z(e),get data(){return e}};return t},getFunctions:e=>R(l.files.flatMap(e=>e.functions.map(t=>({...t,_filePath:e.path}))),l,e),getProperties:e=>G(l.files.flatMap(e=>e.properties.map(t=>({...t,_filePath:e.path}))),l,e),getSlices:e=>K(l.files,l,e)}}function J(e,t){let n=[];for(let r of e.properties){let e=r.name||`Anonymous Property`,i=r.is_readonly;t&&i?n.push(`Property ${e} is readonly, but it shouldn't be.`):!t&&!i&&n.push(`Property ${e} is not readonly, but it should be.`)}return{pass:n.length===0,message:()=>n.join(`
11
11
  `)}}function Y(e,t){let n=new Map;for(let t of e.sliceIds)n.set(t,new Set);for(let[t,r]of e.sliceFiles.entries())for(let i of r)if(i.dependencies)for(let r of i.dependencies){let i=r.match(e.slicePattern);if(i?.[1]){let r=i[1];r!==t&&e.sliceIds.has(r)&&n.get(t)?.add(r)}}let r=new Set,i=new Set,a=[],o=(e,t)=>{r.add(e),i.add(e);for(let s of n.get(e)||[])if(!r.has(s)){if(o(s,[...t,s]))return!0}else if(i.has(s))return a.push(`Cycle detected between slices: ${t.join(` -> `)} -> ${s}`),!0;return i.delete(e),!1};for(let t of e.sliceIds)r.has(t)||o(t,[t]);return t?{pass:a.length>0,message:()=>a.length>0?``:`Expected cycles between slices but found none.`}:{pass:a.length===0,message:()=>a.join(`
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/classes/classCheckExtendClass.ts","../src/utils/ruleBuilder.ts","../src/shared/sharedCheckHaveMaxCyclomaticComplexity.ts","../src/classes/classCheckHaveMaxCyclomaticComplexity.ts","../src/shared/sharedCheckHaveModifier.ts","../src/classes/classCheckHaveModifier.ts","../src/shared/sharedCheckHaveNameMatchingFileName.ts","../src/classes/classCheckHaveNameMatchingFileName.ts","../src/classes/classCheckImplementInterface.ts","../src/shared/sharedCheckMatchNamePattern.ts","../src/classes/classCheckMatchNamePattern.ts","../src/classes/classCheckResideInFolder.ts","../src/classes/locateClasses.ts","../src/files/checkDependOnExternalModule.ts","../src/files/getFileDependencies.ts","../src/files/checkDependOnFilesInFolder.ts","../src/files/fileCheckBeFreeOfCycles.ts","../src/files/fileCheckHaveMaxCyclomaticComplexity.ts","../src/files/fileCheckHaveMaxExportedFunctions.ts","../src/shared/sharedCheckHaveMinMaintainabilityIndex.ts","../src/files/fileCheckHaveMinMaintainabilityIndex.ts","../src/files/fileCheckMatchNamePattern.ts","../src/files/locateFiles.ts","../src/functions/functionCheckHaveExplicitReturnType.ts","../src/functions/functionCheckHaveMaxCyclomaticComplexity.ts","../src/functions/functionCheckHaveMinMaintainabilityIndex.ts","../src/functions/functionCheckHaveModifier.ts","../src/functions/functionCheckHaveNameMatchingFileName.ts","../src/functions/functionCheckMatchNamePattern.ts","../src/functions/locateFunctions.ts","../src/layers/checkLayeredArchitecture.ts","../src/layers/createLayeredArchitecture.ts","../src/layers/layer.ts","../src/layers/getLayerDependencies.ts","../src/layers/layerShouldNotBeAccessedByAnyLayer.ts","../src/layers/layerShouldOnlyBeAccessedBy.ts","../src/properties/locateProperties.ts","../src/slices/locateSlices.ts","../src/project/parseProject.ts","../src/properties/propertyCheckBeReadonly.ts","../src/slices/sliceCheckBeFreeOfCycles.ts","../src/slices/sliceCheckHaveMaxDistanceFromMainSequence.ts","../src/testUtils.ts"],"sourcesContent":["import type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckExtendClass(\n locator: ClassLocatorData,\n className: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const c of locator.classes) {\n const name = c.name || 'Anonymous';\n let matches = false;\n if (c.extends === className) {\n matches = true;\n }\n if (isNot && matches) {\n violations.push(`Class ${name} extends ${className}, but it shouldn't.`);\n } else if (!isNot && !matches) {\n violations.push(\n `Class ${name} does not extend ${className}, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { RuleResult } from '../types';\n\nexport function ruleBuilder<T>(\n items: T[],\n isNot: boolean,\n evaluate: (item: T) => {\n passes: boolean;\n failMessage: string;\n failNotMessage: string;\n },\n): RuleResult {\n const violations: string[] = [];\n\n for (const item of items) {\n const { passes, failMessage, failNotMessage } = evaluate(item);\n\n if (isNot && passes) {\n if (failNotMessage) violations.push(failNotMessage);\n } else if (!isNot && !passes) {\n if (failMessage) violations.push(failMessage);\n }\n }\n\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveMaxCyclomaticComplexity<T>(\n items: T[],\n getName: (item: T) => string | undefined | null,\n getComplexity: (item: T) => number,\n label: string,\n max: number,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n const complexity = getComplexity(item);\n const exceeds = complexity > max;\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes: !exceeds,\n failMessage: `${desc} has a total cyclomatic complexity of ${complexity}, which exceeds the maximum of ${max}.`,\n failNotMessage: `${desc} has a total cyclomatic complexity of ${complexity}, which exceeds the maximum of ${max}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveMaxCyclomaticComplexity } from '../shared/sharedCheckHaveMaxCyclomaticComplexity';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckHaveMaxCyclomaticComplexity(\n locator: ClassLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMaxCyclomaticComplexity(\n locator.classes,\n (c) => c.name,\n (c) => c.cyclomatic_complexity || 0,\n 'Class',\n max,\n isNot,\n );\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveModifier<\n T extends {\n is_exported?: boolean;\n is_default?: boolean;\n is_abstract?: boolean;\n is_async?: boolean;\n is_readonly?: boolean;\n },\n>(\n items: T[],\n getName: (item: T) => string | null | undefined,\n label: string,\n modifierStr: string,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n let passes = false;\n switch (modifierStr) {\n case 'export':\n passes = !!item.is_exported;\n break;\n case 'default':\n passes = !!item.is_default;\n break;\n case 'abstract':\n passes = !!item.is_abstract;\n break;\n case 'async':\n passes = !!item.is_async;\n break;\n case 'readonly':\n passes = !!item.is_readonly;\n break;\n default:\n throw new Error(`Modifier ${modifierStr} is not fully supported.`);\n }\n\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes,\n failMessage: `${desc} does not have modifier ${modifierStr}, but it should.`,\n failNotMessage: `${desc} has modifier ${modifierStr}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveModifier } from '../shared/sharedCheckHaveModifier';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckHaveModifier(\n locator: ClassLocatorData,\n modifierStr: string,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveModifier(\n locator.classes,\n (c) => c.name,\n 'Class',\n modifierStr,\n isNot,\n );\n}\n","import * as path from 'node:path';\nimport { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveNameMatchingFileName<\n T extends { _filePath: string },\n>(\n items: T[],\n getName: (item: T) => string | null | undefined,\n label: string,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n\n if (!item._filePath) {\n return { passes: true, failMessage: '', failNotMessage: '' };\n }\n\n const basename = path.basename(\n item._filePath,\n path.extname(item._filePath),\n );\n const passes = name === basename;\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes,\n failMessage: `${desc} does not have a name matching its filename ${basename}, but it should.`,\n failNotMessage: `${desc} has a name matching its filename ${basename}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveNameMatchingFileName } from '../shared/sharedCheckHaveNameMatchingFileName';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckHaveNameMatchingFileName(\n locator: ClassLocatorData,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveNameMatchingFileName(\n locator.classes,\n (c) => c.name,\n 'Class',\n isNot,\n );\n}\n","import type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckImplementInterface(\n locator: ClassLocatorData,\n interfaceName: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const c of locator.classes) {\n const name = c.name || 'Anonymous';\n let matches = false;\n if (c.implements.includes(interfaceName)) {\n matches = true;\n }\n if (isNot && matches) {\n violations.push(\n `Class ${name} implements ${interfaceName}, but it shouldn't.`,\n );\n } else if (!isNot && !matches) {\n violations.push(\n `Class ${name} does not implement ${interfaceName}, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckMatchNamePattern<T>(\n items: T[],\n getName: (item: T) => string | undefined | null,\n label: string,\n pattern: string | RegExp,\n isNot: boolean,\n) {\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n const passes = name ? regex.test(name) : false;\n const desc = `${label} ${name || 'Anonymous'}`;\n return {\n passes,\n failMessage: `${desc} does not match pattern ${pattern}, but it should.`,\n failNotMessage: `${desc} matches pattern ${pattern}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckMatchNamePattern } from '../shared/sharedCheckMatchNamePattern';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckMatchNamePattern(\n locator: ClassLocatorData,\n pattern: string | RegExp,\n isNot: boolean,\n): RuleResult {\n return sharedCheckMatchNamePattern(\n locator.classes,\n (c) => c.name,\n 'Class',\n pattern,\n isNot,\n );\n}\n","import type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckResideInFolder(\n locator: ClassLocatorData,\n targetFolder: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const c of locator.classes) {\n const className = c.name || 'Anonymous Class';\n const filePath = c._filePath;\n const inTargetFolder =\n filePath.includes(`/${targetFolder}/`) ||\n filePath.includes(`\\\\${targetFolder}\\\\`);\n\n if (isNot && inTargetFolder) {\n violations.push(\n `Class ${className} resides in ${targetFolder}, but it shouldn't.`,\n );\n } else if (!isNot && !inTargetFolder) {\n violations.push(\n `Class ${className} does not reside in ${targetFolder}, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { ClassData, ProjectData } from '../dto';\nimport type { ClassLocatorData, ClassQueryOptions } from './types';\n\nexport function locateClasses(\n classes: (ClassData & { _filePath: string })[],\n projectData: ProjectData,\n options?: ClassQueryOptions,\n): ClassLocatorData {\n let filtered = classes;\n\n if (options?.inFolder) {\n filtered = filtered.filter((c) => {\n return (\n c._filePath.includes(`/${options.inFolder}/`) ||\n c._filePath.includes(`\\\\${options.inFolder}\\\\`)\n );\n });\n }\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((c) => {\n return c.name && regex.test(c.name);\n });\n }\n if (options?.withDecorator) {\n filtered = filtered.filter((c) => {\n return c.decorators.includes(options.withDecorator!);\n });\n }\n if (options?.extending) {\n filtered = filtered.filter((c) => {\n return c.extends === options.extending;\n });\n }\n if (options?.implementing) {\n filtered = filtered.filter((c) => {\n return c.implements.includes(options.implementing!);\n });\n }\n if (options?.havingModifier) {\n filtered = filtered.filter((c) => {\n switch (options.havingModifier) {\n case 'export':\n return c.is_exported;\n case 'default':\n return c.is_default;\n case 'abstract':\n return c.is_abstract;\n default:\n throw new Error(\n `Modifier ${options.havingModifier} is not fully supported.`,\n );\n }\n });\n }\n\n return {\n type: 'ClassLocator',\n classes: filtered,\n projectData,\n };\n}\n","import type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function checkDependOnExternalModule(\n locator: FileLocatorData,\n moduleName: string | RegExp,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n\n const regex =\n typeof moduleName === 'string' ? new RegExp(moduleName) : moduleName;\n\n for (const file of locator.files) {\n const deps = file.external_dependencies || [];\n const dependsOnModule = deps.some((dep) => regex.test(dep));\n\n if (isNot && dependsOnModule) {\n violations.push(\n `${file.path} incorrectly depends on external module '${moduleName}'`,\n );\n } else if (!isNot && !dependsOnModule) {\n violations.push(\n `${file.path} does not depend on external module '${moduleName}'`,\n );\n }\n }\n\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { FileData, ProjectData } from '../dto';\n\nexport function getFileDependencies(\n sourceFile: FileData,\n projectData: ProjectData,\n): string[] {\n return sourceFile.dependencies || [];\n}\n","import type { RuleResult } from '../types';\nimport { getFileDependencies } from './getFileDependencies';\nimport type { FileLocatorData } from './types';\n\nexport function checkDependOnFilesInFolder(\n locator: FileLocatorData,\n targetFolder: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n\n for (const file of locator.files) {\n const dependencies = getFileDependencies(file, locator.projectData);\n\n const dependsOnTarget = dependencies.some(\n (depPath) =>\n depPath.includes(`/${targetFolder}/`) ||\n depPath.includes(`\\\\${targetFolder}\\\\`),\n );\n\n if (isNot && dependsOnTarget) {\n violations.push(\n `File ${file.path} depends on files in ${targetFolder}, but it shouldn't.`,\n );\n } else if (!isNot && !dependsOnTarget) {\n violations.push(\n `File ${file.path} does not depend on files in ${targetFolder}, but it should.`,\n );\n }\n }\n\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { RuleResult } from '../types';\nimport { getFileDependencies } from './getFileDependencies';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckBeFreeOfCycles(\n locator: FileLocatorData,\n isNot: boolean,\n): RuleResult {\n const targetFiles = locator.files.map((f) => f.path);\n\n const archestProject = locator.archestProject;\n if (!archestProject) {\n // Fallback for mocked tests or if registry is missing\n return {\n pass: true,\n message: () => 'Mock pass: archestProject not in registry',\n };\n }\n\n const result = archestProject.checkFileCycles(targetFiles, !!isNot);\n\n return {\n pass: result.pass,\n message: () => result.message,\n };\n}\n","import { sharedCheckHaveMaxCyclomaticComplexity } from '../shared/sharedCheckHaveMaxCyclomaticComplexity';\nimport type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckHaveMaxCyclomaticComplexity(\n locator: FileLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMaxCyclomaticComplexity(\n locator.files,\n (f) => f.path,\n (file) => {\n let complexity = 0;\n for (const func of file.functions) {\n complexity += func.cyclomatic_complexity || 0;\n }\n for (const cls of file.classes) {\n complexity += cls.cyclomatic_complexity || 0;\n }\n return complexity;\n },\n 'File',\n max,\n isNot,\n );\n}\n","import type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckHaveMaxExportedFunctions(\n locator: FileLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const file of locator.files) {\n const exportedFuncCount = file.functions.filter(\n (f) => f.is_exported,\n ).length;\n\n const exceeds = exportedFuncCount > max;\n\n if (isNot && exceeds) {\n violations.push(\n `File ${file.path} has ${exportedFuncCount} exported functions, which exceeds the maximum of ${max}, but it shouldn't.`,\n );\n } else if (!isNot && exceeds) {\n violations.push(\n `File ${file.path} has ${exportedFuncCount} exported functions, which exceeds the maximum of ${max}.`,\n );\n }\n }\n return {\n pass: isNot ? violations.length > 0 : violations.length === 0,\n message: () =>\n violations.join('\\n') ||\n (isNot\n ? 'Expected some files to exceed maximum exported functions, but none did.'\n : ''),\n };\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveMinMaintainabilityIndex<T>(\n items: T[],\n getName: (item: T) => string | undefined | null,\n getMi: (item: T) => number,\n label: string,\n min: number,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n const mi = getMi(item);\n const fallsBelow = mi < min;\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes: !fallsBelow,\n failMessage: `${desc} has a maintainability index of ${mi.toFixed(2)}, which falls below the minimum of ${min}.`,\n failNotMessage: `${desc} has a maintainability index of ${mi.toFixed(2)}, which falls below the minimum of ${min}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveMinMaintainabilityIndex } from '../shared/sharedCheckHaveMinMaintainabilityIndex';\nimport type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckHaveMinMaintainabilityIndex(\n locator: FileLocatorData,\n min: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMinMaintainabilityIndex(\n locator.files,\n (f) => f.path,\n (file) => {\n if (file.functions.length > 0) {\n return file.functions[0].maintainability_index || 100;\n }\n return 100;\n },\n 'File',\n min,\n isNot,\n );\n}\n","import { sharedCheckMatchNamePattern } from '../shared/sharedCheckMatchNamePattern';\nimport type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckMatchNamePattern(\n locator: FileLocatorData,\n pattern: string | RegExp,\n isNot: boolean,\n): RuleResult {\n return sharedCheckMatchNamePattern(\n locator.files,\n (f) => f.path,\n 'File',\n pattern,\n isNot,\n );\n}\n","import type { ArchestProject } from '@archest/core-rust';\nimport type { FileData, ProjectData } from '../dto';\nimport type { FileLocatorData, FileQueryOptions } from './types';\n\nexport function locateFiles(\n sourceFiles: FileData[],\n projectData: ProjectData,\n archestProject?: ArchestProject,\n options?: FileQueryOptions,\n): FileLocatorData {\n let filtered = sourceFiles;\n\n if (options?.inFolder) {\n filtered = filtered.filter(\n (file) =>\n file.path.includes(`/${options.inFolder}/`) ||\n file.path.includes(`\\\\${options.inFolder}\\\\`),\n );\n }\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((file) => regex.test(file.path));\n }\n\n const result: FileLocatorData = {\n type: 'FileLocator',\n files: filtered,\n projectData,\n };\n\n if (archestProject) {\n Object.defineProperty(result, 'archestProject', {\n value: archestProject,\n enumerable: false,\n });\n }\n\n return result;\n}\n","import type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveExplicitReturnType(\n locator: FunctionLocatorData,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const f of locator.functions) {\n const name = f.name || 'Anonymous Function';\n const hasType = f.has_explicit_return_type;\n\n if (isNot && hasType) {\n violations.push(\n `Function ${name} has an explicit return type, but it shouldn't.`,\n );\n } else if (!isNot && !hasType) {\n violations.push(\n `Function ${name} does not have an explicit return type, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import { sharedCheckHaveMaxCyclomaticComplexity } from '../shared/sharedCheckHaveMaxCyclomaticComplexity';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveMaxCyclomaticComplexity(\n locator: FunctionLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMaxCyclomaticComplexity(\n locator.functions,\n (f) => f.name,\n (f) => f.cyclomatic_complexity || 0,\n 'Function',\n max,\n isNot,\n );\n}\n","import { sharedCheckHaveMinMaintainabilityIndex } from '../shared/sharedCheckHaveMinMaintainabilityIndex';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveMinMaintainabilityIndex(\n locator: FunctionLocatorData,\n min: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMinMaintainabilityIndex(\n locator.functions,\n (f) => f.name,\n (f) => f.maintainability_index || 100,\n 'Function',\n min,\n isNot,\n );\n}\n","import { sharedCheckHaveModifier } from '../shared/sharedCheckHaveModifier';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveModifier(\n locator: FunctionLocatorData,\n modifierStr: string,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveModifier(\n locator.functions,\n (f) => f.name,\n 'Function',\n modifierStr,\n isNot,\n );\n}\n","import { sharedCheckHaveNameMatchingFileName } from '../shared/sharedCheckHaveNameMatchingFileName';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveNameMatchingFileName(\n locator: FunctionLocatorData,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveNameMatchingFileName(\n locator.functions,\n (f) => f.name,\n 'Function',\n isNot,\n );\n}\n","import { sharedCheckMatchNamePattern } from '../shared/sharedCheckMatchNamePattern';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckMatchNamePattern(\n locator: FunctionLocatorData,\n pattern: string | RegExp,\n isNot: boolean,\n): RuleResult {\n return sharedCheckMatchNamePattern(\n locator.functions,\n (f) => f.name,\n 'Function',\n pattern,\n isNot,\n );\n}\n","import type { FunctionData, ProjectData } from '../dto';\nimport type { FunctionLocatorData, FunctionQueryOptions } from './types';\n\nexport function locateFunctions(\n functions: (FunctionData & { _filePath: string })[],\n projectData: ProjectData,\n options?: FunctionQueryOptions,\n): FunctionLocatorData {\n let filtered = functions;\n\n if (options?.inFolder) {\n filtered = filtered.filter((f) => {\n return (\n f._filePath.includes(`/${options.inFolder}/`) ||\n f._filePath.includes(`\\\\${options.inFolder}\\\\`)\n );\n });\n }\n\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((f) => {\n return f.name && regex.test(f.name);\n });\n }\n\n if (options?.isTopLevel) {\n filtered = filtered.filter((f) => f.is_top_level);\n }\n\n return {\n type: 'FunctionLocator',\n functions: filtered,\n projectData,\n };\n}\n","import type { RuleResult } from '../types';\nimport type { LayeredArchitectureData } from './types';\n\nexport function checkLayeredArchitecture(\n data: LayeredArchitectureData,\n): RuleResult {\n const violations: string[] = [];\n for (const assertion of data.assertions) {\n violations.push(...assertion(data.files));\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { FileData, ProjectData } from '../dto';\nimport type { LayeredArchitectureData } from './types';\n\nexport function createLayeredArchitecture(\n files: FileData[],\n projectData: ProjectData,\n): LayeredArchitectureData {\n return {\n type: 'LayeredArchitecture',\n files,\n layers: new Map<string, string>(),\n assertions: [],\n projectData,\n };\n}\n","import type { LayeredArchitectureData } from './types';\n\nexport function layer(\n data: LayeredArchitectureData,\n name: string,\n folderPattern: string,\n): LayeredArchitectureData {\n data.layers.set(name, folderPattern);\n return data;\n}\n","import type { FileData, ProjectData } from '../dto';\n\nexport function getLayerDependencies(\n sourceFile: FileData,\n projectData: ProjectData,\n): string[] {\n return sourceFile.dependencies || [];\n}\n","import { getLayerDependencies } from './getLayerDependencies';\nimport type { LayeredArchitectureData } from './types';\n\nexport function layerShouldNotBeAccessedByAnyLayer(\n data: LayeredArchitectureData,\n targetLayer: string,\n): LayeredArchitectureData {\n if (!data.layers.has(targetLayer)) {\n throw new Error(`Layer ${targetLayer} is not defined`);\n }\n\n data.assertions.push((files) => {\n const violations: string[] = [];\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const targetPattern = data.layers.get(targetLayer)!;\n\n for (const file of files) {\n const filePath = file.path;\n if (\n !filePath.includes(`/${targetPattern}/`) &&\n !filePath.includes(`\\\\${targetPattern}\\\\`)\n ) {\n const dependencies = getLayerDependencies(file, data.projectData);\n const importsTarget = dependencies.some(\n (dep) =>\n dep.includes(`/${targetPattern}/`) ||\n dep.includes(`\\\\${targetPattern}\\\\`),\n );\n if (importsTarget) {\n violations.push(\n `File ${filePath} accesses layer ${targetLayer} but it shouldn't.`,\n );\n }\n }\n }\n return violations;\n });\n\n return data;\n}\n","import { getLayerDependencies } from './getLayerDependencies';\nimport type { LayeredArchitectureData } from './types';\n\nexport function layerShouldOnlyBeAccessedBy(\n data: LayeredArchitectureData,\n targetLayer: string,\n allowedLayers: string[],\n): LayeredArchitectureData {\n if (!data.layers.has(targetLayer)) {\n throw new Error(`Layer ${targetLayer} is not defined`);\n }\n\n data.assertions.push((files) => {\n const violations: string[] = [];\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const targetPattern = data.layers.get(targetLayer)!;\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const allowedPatterns = allowedLayers.map((l) => data.layers.get(l)!);\n\n for (const file of files) {\n const filePath = file.path;\n const isInAllowedLayer = allowedPatterns.some(\n (p) => filePath.includes(`/${p}/`) || filePath.includes(`\\\\${p}\\\\`),\n );\n\n if (\n !filePath.includes(`/${targetPattern}/`) &&\n !filePath.includes(`\\\\${targetPattern}\\\\`) &&\n !isInAllowedLayer\n ) {\n const dependencies = getLayerDependencies(file, data.projectData);\n const importsTarget = dependencies.some(\n (dep) =>\n dep.includes(`/${targetPattern}/`) ||\n dep.includes(`\\\\${targetPattern}\\\\`),\n );\n if (importsTarget) {\n violations.push(\n `File ${filePath} accesses layer ${targetLayer} but only ${allowedLayers.join(', ')} are allowed.`,\n );\n }\n }\n }\n return violations;\n });\n\n return data;\n}\n","import type { ProjectData, PropertyData } from '../dto';\nimport type { PropertyLocatorData, PropertyQueryOptions } from './types';\n\nexport function locateProperties(\n properties: (PropertyData & { _filePath: string })[],\n projectData: ProjectData,\n options?: PropertyQueryOptions,\n): PropertyLocatorData {\n let filtered = properties;\n\n if (options?.inFolder) {\n filtered = filtered.filter((p) => {\n return (\n p._filePath.includes(`/${options.inFolder}/`) ||\n p._filePath.includes(`\\\\${options.inFolder}\\\\`)\n );\n });\n }\n\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((p) => {\n return regex.test(p.name);\n });\n }\n\n return {\n type: 'PropertyLocator',\n properties: filtered,\n projectData,\n };\n}\n","import type { FileData, ProjectData } from '../dto';\nimport type { SliceLocatorData } from './types';\n\nexport function locateSlices(\n sourceFiles: FileData[],\n projectData: ProjectData,\n pattern: string,\n): SliceLocatorData {\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regexStr = escaped.replace(/\\*/g, '([^/\\\\\\\\]+)');\n const slicePattern = new RegExp(regexStr);\n\n const sliceIds = new Set<string>();\n const sliceFiles = new Map<string, FileData[]>();\n\n for (const sf of sourceFiles) {\n const match = sf.path.match(slicePattern);\n if (match?.[1]) {\n const sliceId = match[1];\n sliceIds.add(sliceId);\n if (!sliceFiles.has(sliceId)) {\n sliceFiles.set(sliceId, []);\n }\n sliceFiles.get(sliceId)?.push(sf);\n }\n }\n\n return {\n type: 'SliceLocator',\n slicePattern,\n sliceIds,\n sliceFiles,\n projectData,\n };\n}\n","import { dirname } from 'node:path';\nimport { ArchestProject } from '@archest/core-rust';\nimport * as ts from 'typescript';\nimport { locateClasses } from '../classes/locateClasses';\nimport type { ClassQueryOptions } from '../classes/types';\nimport type { ProjectData } from '../dto';\nimport { locateFiles } from '../files/locateFiles';\nimport type { FileQueryOptions } from '../files/types';\nimport { locateFunctions } from '../functions/locateFunctions';\nimport type { FunctionQueryOptions } from '../functions/types';\nimport { checkLayeredArchitecture } from '../layers/checkLayeredArchitecture';\nimport { createLayeredArchitecture } from '../layers/createLayeredArchitecture';\nimport { layer } from '../layers/layer';\nimport { layerShouldNotBeAccessedByAnyLayer } from '../layers/layerShouldNotBeAccessedByAnyLayer';\nimport { layerShouldOnlyBeAccessedBy } from '../layers/layerShouldOnlyBeAccessedBy';\nimport { locateProperties } from '../properties/locateProperties';\nimport type { PropertyQueryOptions } from '../properties/types';\nimport { locateSlices } from '../slices/locateSlices';\n\n/**\n * Options to configure how the project is parsed and analyzed.\n */\nexport interface ParseProjectOptions {\n /**\n * An optional absolute path to a specific tsconfig.json file.\n * If omitted, Archest will attempt to find the nearest tsconfig.json in the current working directory.\n */\n tsConfigFilePath?: string;\n /** An array of glob patterns specifying which files to include in the AST parsing. Overrides the tsconfig.json `include` array. */\n include?: string[];\n /** An array of glob patterns specifying which files to exclude from the AST parsing. Overrides the tsconfig.json `exclude` array. */\n exclude?: string[];\n}\n\n/**\n * The primary entry point for Archest. Parses a TypeScript or JavaScript project into a searchable\n * Abstract Syntax Tree (AST) using the high-performance native Rust engine.\n *\n * @param options - Optional configuration for locating the tsconfig and filtering files.\n * @returns A fluent API object containing Locators used to query the project's architecture.\n *\n * @example\n * ```typescript\n * import { parseProject } from '@archest/vitest';\n *\n * const project = parseProject({\n * include: ['src/domain/**\\/*.ts'],\n * exclude: ['**\\/*.test.ts']\n * });\n *\n * const domainFiles = project.getFiles();\n * ```\n */\nexport function parseProject(options: ParseProjectOptions = {}) {\n const configPath =\n options.tsConfigFilePath ||\n ts.findConfigFile(process.cwd(), ts.sys.fileExists, 'tsconfig.json');\n\n if (!configPath) {\n throw new Error('Could not find tsconfig.json');\n }\n\n const projectDir = dirname(configPath);\n\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile);\n if (options.include) configFile.config.include = options.include;\n if (options.exclude) configFile.config.exclude = options.exclude;\n\n const parsedCommandLine = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n projectDir,\n undefined,\n configPath,\n undefined,\n [\n {\n extension: '.vue',\n isMixedContent: true,\n scriptKind: ts.ScriptKind.TS,\n },\n {\n extension: '.svelte',\n isMixedContent: true,\n scriptKind: ts.ScriptKind.TS,\n },\n ],\n );\n\n const archestProject = ArchestProject.parse(parsedCommandLine.fileNames);\n const projectData: ProjectData = JSON.parse(archestProject.getProjectData());\n\n return {\n projectData,\n getFiles: (queryOptions?: FileQueryOptions) => {\n return locateFiles(\n projectData.files,\n projectData,\n archestProject,\n queryOptions,\n );\n },\n\n getClasses: (queryOptions?: ClassQueryOptions) => {\n const allClasses = projectData.files.flatMap((f) =>\n f.classes.map((c) => ({ ...c, _filePath: f.path })),\n );\n return locateClasses(allClasses, projectData, queryOptions);\n },\n\n layeredArchitecture: () => {\n let data = createLayeredArchitecture(projectData.files, projectData);\n const api = {\n layer: (name: string, folderPattern: string) => {\n data = layer(data, name, folderPattern);\n return api;\n },\n whereLayer: (name: string) => {\n return {\n shouldNotBeAccessedByAnyLayer: () => {\n data = layerShouldNotBeAccessedByAnyLayer(data, name);\n return api;\n },\n shouldOnlyBeAccessedBy: (...allowedLayers: string[]) => {\n data = layerShouldOnlyBeAccessedBy(data, name, allowedLayers);\n return api;\n },\n };\n },\n check: () => checkLayeredArchitecture(data),\n get data() {\n return data;\n },\n };\n return api;\n },\n\n getFunctions: (queryOptions?: FunctionQueryOptions) => {\n const allFunctions = projectData.files.flatMap((f) =>\n f.functions.map((fn) => ({ ...fn, _filePath: f.path })),\n );\n return locateFunctions(allFunctions, projectData, queryOptions);\n },\n\n getProperties: (queryOptions?: PropertyQueryOptions) => {\n const allProperties = projectData.files.flatMap((f) =>\n f.properties.map((p) => ({ ...p, _filePath: f.path })),\n );\n return locateProperties(allProperties, projectData, queryOptions);\n },\n\n getSlices: (pattern: string) => {\n return locateSlices(projectData.files, projectData, pattern);\n },\n };\n}\n","import type { RuleResult } from '../types';\nimport type { PropertyLocatorData } from './types';\n\nexport function propertyCheckBeReadonly(\n locator: PropertyLocatorData,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const p of locator.properties) {\n const name = p.name || 'Anonymous Property';\n const matches = p.is_readonly;\n\n if (isNot && matches) {\n violations.push(`Property ${name} is readonly, but it shouldn't be.`);\n } else if (!isNot && !matches) {\n violations.push(`Property ${name} is not readonly, but it should be.`);\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { RuleResult } from '../types';\nimport type { SliceLocatorData } from './types';\n\nexport function sliceCheckBeFreeOfCycles(\n locator: SliceLocatorData,\n isNot: boolean,\n): RuleResult {\n const graph: Map<string, Set<string>> = new Map();\n for (const slice of locator.sliceIds) {\n graph.set(slice, new Set());\n }\n\n for (const [sliceId, files] of locator.sliceFiles.entries()) {\n for (const sf of files) {\n if (!sf.dependencies) continue;\n for (const importPath of sf.dependencies) {\n const targetMatch = importPath.match(locator.slicePattern);\n if (targetMatch?.[1]) {\n const targetSlice = targetMatch[1];\n if (targetSlice !== sliceId && locator.sliceIds.has(targetSlice)) {\n graph.get(sliceId)?.add(targetSlice);\n }\n }\n }\n }\n }\n\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const violations: string[] = [];\n\n const dfs = (node: string, path: string[]): boolean => {\n visited.add(node);\n recursionStack.add(node);\n\n for (const neighbor of graph.get(node) || []) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor, [...path, neighbor])) return true;\n } else if (recursionStack.has(neighbor)) {\n violations.push(\n `Cycle detected between slices: ${path.join(' -> ')} -> ${neighbor}`,\n );\n return true;\n }\n }\n\n recursionStack.delete(node);\n return false;\n };\n\n for (const slice of locator.sliceIds) {\n if (!visited.has(slice)) {\n dfs(slice, [slice]);\n }\n }\n\n if (isNot) {\n return {\n pass: violations.length > 0,\n message: () =>\n violations.length > 0\n ? ''\n : 'Expected cycles between slices but found none.',\n };\n } else {\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n }\n}\n","import type { RuleResult } from '../types';\nimport type { SliceLocatorData } from './types';\n\nexport function sliceCheckHaveMaxDistanceFromMainSequence(\n locator: SliceLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n\n const ceMap = new Map<string, Set<string>>(); // Slices this slice depends on\n const caMap = new Map<string, Set<string>>(); // Slices depending on this slice\n\n for (const slice of locator.sliceIds) {\n ceMap.set(slice, new Set());\n caMap.set(slice, new Set());\n }\n\n for (const [sliceId, files] of locator.sliceFiles.entries()) {\n for (const sf of files) {\n if (!sf.dependencies) continue;\n for (const importPath of sf.dependencies) {\n const targetMatch = importPath.match(locator.slicePattern);\n if (targetMatch?.[1]) {\n const targetSlice = targetMatch[1];\n if (targetSlice !== sliceId && locator.sliceIds.has(targetSlice)) {\n ceMap.get(sliceId)?.add(targetSlice);\n caMap.get(targetSlice)?.add(sliceId);\n }\n }\n }\n }\n }\n\n for (const sliceId of locator.sliceIds) {\n const ce = ceMap.get(sliceId)?.size || 0;\n const ca = caMap.get(sliceId)?.size || 0;\n\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const files = locator.sliceFiles.get(sliceId)!;\n let na = 0; // abstract classes + interfaces\n let nc = 0; // all classes + interfaces\n\n for (const sf of files) {\n for (const c of sf.classes) {\n nc++;\n if (c.is_abstract) {\n na++;\n }\n }\n }\n\n const I = ce + ca === 0 ? 0 : ce / (ca + ce);\n const A = nc === 0 ? 0 : na / nc;\n\n const D = Math.abs(A + I - 1);\n const exceeds = D > max;\n\n if (isNot && exceeds) {\n violations.push(\n `Slice ${sliceId} has a Distance from the Main Sequence of ${D.toFixed(2)}, which exceeds the maximum of ${max}, but it shouldn't.`,\n );\n } else if (!isNot && exceeds) {\n violations.push(\n `Slice ${sliceId} has a Distance from the Main Sequence of ${D.toFixed(2)}, which exceeds the maximum of ${max}.`,\n );\n }\n }\n\n return {\n pass: isNot ? violations.length > 0 : violations.length === 0,\n message: () =>\n violations.join('\\n') ||\n (isNot\n ? 'Expected some slices to exceed maximum distance from main sequence, but none did.'\n : ''),\n };\n}\n","import { ArchestProject } from '@archest/core-rust';\nimport * as ts from 'typescript';\n\nimport type {\n ClassData,\n FileData,\n FunctionData,\n ProjectData,\n PropertyData,\n} from './dto';\n\nexport function createSourceFile(\n code: string,\n fileName = 'test.ts',\n): ts.SourceFile {\n return ts.createSourceFile(fileName, code, ts.ScriptTarget.Latest, true);\n}\n\nexport function createMockProgram(sourceFiles: ts.SourceFile[]): ProjectData {\n return {\n files: sourceFiles.map((sf) => ({\n path: sf.fileName,\n classes: getClasses(sf),\n functions: getFunctions(sf),\n properties: getProperties(sf),\n })),\n };\n}\n\nexport function createMockArchestProject(\n projectData: ProjectData,\n): ArchestProject {\n return ArchestProject.parseMock(JSON.stringify(projectData));\n}\n\nexport function getClasses(\n sourceFile: ts.SourceFile,\n): (ClassData & { _filePath: string })[] {\n const classes: (ClassData & { _filePath: string })[] = [];\n ts.forEachChild(sourceFile, (node) => {\n if (ts.isClassDeclaration(node)) {\n let extendsName: string | null = null;\n const implementsNames: string[] = [];\n if (node.heritageClauses) {\n for (const clause of node.heritageClauses) {\n if (clause.token === ts.SyntaxKind.ExtendsKeyword) {\n for (const t of clause.types) {\n if (ts.isIdentifier(t.expression))\n extendsName = t.expression.text;\n }\n }\n if (clause.token === ts.SyntaxKind.ImplementsKeyword) {\n for (const t of clause.types) {\n if (ts.isIdentifier(t.expression))\n implementsNames.push(t.expression.text);\n }\n }\n }\n }\n\n const decorators: string[] = [];\n if (ts.canHaveDecorators(node)) {\n const decs = ts.getDecorators(node);\n if (decs) {\n for (const d of decs) {\n if (ts.isIdentifier(d.expression))\n decorators.push(d.expression.text);\n else if (\n ts.isCallExpression(d.expression) &&\n ts.isIdentifier(d.expression.expression)\n )\n decorators.push(d.expression.expression.text);\n }\n }\n }\n\n classes.push({\n name: node.name?.text || null,\n is_exported: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) || false\n : false,\n is_default: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword) || false\n : false,\n is_abstract: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.AbstractKeyword) || false\n : false,\n extends: extendsName,\n implements: implementsNames,\n decorators,\n _filePath: sourceFile.fileName,\n });\n }\n });\n return classes;\n}\n\nexport function getFunctions(\n sourceFile: ts.SourceFile,\n): (FunctionData & { _filePath: string })[] {\n const functions: (FunctionData & { _filePath: string })[] = [];\n ts.forEachChild(sourceFile, (node) => {\n if (\n ts.isFunctionDeclaration(node) ||\n ts.isMethodDeclaration(node) ||\n ts.isArrowFunction(node)\n ) {\n let name: string | null = null;\n if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) {\n name = node.name?.getText() || null;\n }\n\n functions.push({\n name,\n is_exported: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) || false\n : false,\n is_async: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) || false\n : false,\n is_top_level: true,\n has_explicit_return_type: !!(node as any).type,\n _filePath: sourceFile.fileName,\n });\n }\n });\n return functions;\n}\n\nexport function getProperties(\n sourceFile: ts.SourceFile,\n): (PropertyData & { _filePath: string })[] {\n const properties: (PropertyData & { _filePath: string })[] = [];\n ts.forEachChild(sourceFile, (node) => {\n if (ts.isClassDeclaration(node)) {\n node.members.forEach((member) => {\n if (ts.isPropertyDeclaration(member)) {\n properties.push({\n name: member.name.getText(),\n is_readonly: ts.canHaveModifiers(member)\n ? ts\n .getModifiers(member)\n ?.some((m) => m.kind === ts.SyntaxKind.ReadonlyKeyword) ||\n false\n : false,\n _filePath: sourceFile.fileName,\n });\n }\n });\n }\n });\n return properties;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/classes/classCheckExtendClass.ts","../src/utils/ruleBuilder.ts","../src/shared/sharedCheckHaveMaxCyclomaticComplexity.ts","../src/classes/classCheckHaveMaxCyclomaticComplexity.ts","../src/shared/sharedCheckHaveModifier.ts","../src/classes/classCheckHaveModifier.ts","../src/shared/sharedCheckHaveNameMatchingFileName.ts","../src/classes/classCheckHaveNameMatchingFileName.ts","../src/classes/classCheckImplementInterface.ts","../src/shared/sharedCheckMatchNamePattern.ts","../src/classes/classCheckMatchNamePattern.ts","../src/classes/classCheckResideInFolder.ts","../src/classes/locateClasses.ts","../src/files/checkDependOnExternalModule.ts","../src/files/getFileDependencies.ts","../src/files/checkDependOnFilesInFolder.ts","../src/files/fileCheckBeFreeOfCycles.ts","../src/files/fileCheckHaveMaxCyclomaticComplexity.ts","../src/files/fileCheckHaveMaxExportedFunctions.ts","../src/shared/sharedCheckHaveMinMaintainabilityIndex.ts","../src/files/fileCheckHaveMinMaintainabilityIndex.ts","../src/files/fileCheckMatchNamePattern.ts","../src/files/locateFiles.ts","../src/functions/functionCheckHaveExplicitReturnType.ts","../src/functions/functionCheckHaveMaxCyclomaticComplexity.ts","../src/functions/functionCheckHaveMinMaintainabilityIndex.ts","../src/functions/functionCheckHaveModifier.ts","../src/functions/functionCheckHaveNameMatchingFileName.ts","../src/functions/functionCheckMatchNamePattern.ts","../src/functions/locateFunctions.ts","../src/layers/checkLayeredArchitecture.ts","../src/layers/createLayeredArchitecture.ts","../src/layers/layer.ts","../src/layers/getLayerDependencies.ts","../src/layers/layerShouldNotBeAccessedByAnyLayer.ts","../src/layers/layerShouldOnlyBeAccessedBy.ts","../src/properties/locateProperties.ts","../src/slices/locateSlices.ts","../src/project/parseProject.ts","../src/properties/propertyCheckBeReadonly.ts","../src/slices/sliceCheckBeFreeOfCycles.ts","../src/slices/sliceCheckHaveMaxDistanceFromMainSequence.ts","../src/testUtils.ts"],"sourcesContent":["import type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckExtendClass(\n locator: ClassLocatorData,\n className: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const c of locator.classes) {\n const name = c.name || 'Anonymous';\n let matches = false;\n if (c.extends === className) {\n matches = true;\n }\n if (isNot && matches) {\n violations.push(`Class ${name} extends ${className}, but it shouldn't.`);\n } else if (!isNot && !matches) {\n violations.push(\n `Class ${name} does not extend ${className}, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { RuleResult } from '../types';\n\nexport function ruleBuilder<T>(\n items: T[],\n isNot: boolean,\n evaluate: (item: T) => {\n passes: boolean;\n failMessage: string;\n failNotMessage: string;\n },\n): RuleResult {\n const violations: string[] = [];\n\n for (const item of items) {\n const { passes, failMessage, failNotMessage } = evaluate(item);\n\n if (isNot && passes) {\n if (failNotMessage) violations.push(failNotMessage);\n } else if (!isNot && !passes) {\n if (failMessage) violations.push(failMessage);\n }\n }\n\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveMaxCyclomaticComplexity<T>(\n items: T[],\n getName: (item: T) => string | undefined | null,\n getComplexity: (item: T) => number,\n label: string,\n max: number,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n const complexity = getComplexity(item);\n const exceeds = complexity > max;\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes: !exceeds,\n failMessage: `${desc} has a total cyclomatic complexity of ${complexity}, which exceeds the maximum of ${max}.`,\n failNotMessage: `${desc} has a total cyclomatic complexity of ${complexity}, which exceeds the maximum of ${max}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveMaxCyclomaticComplexity } from '../shared/sharedCheckHaveMaxCyclomaticComplexity';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckHaveMaxCyclomaticComplexity(\n locator: ClassLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMaxCyclomaticComplexity(\n locator.classes,\n (c) => c.name,\n (c) => c.cyclomatic_complexity || 0,\n 'Class',\n max,\n isNot,\n );\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveModifier<\n T extends {\n is_exported?: boolean;\n is_default?: boolean;\n is_abstract?: boolean;\n is_async?: boolean;\n is_readonly?: boolean;\n },\n>(\n items: T[],\n getName: (item: T) => string | null | undefined,\n label: string,\n modifierStr: string,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n let passes = false;\n switch (modifierStr) {\n case 'export':\n passes = !!item.is_exported;\n break;\n case 'default':\n passes = !!item.is_default;\n break;\n case 'abstract':\n passes = !!item.is_abstract;\n break;\n case 'async':\n passes = !!item.is_async;\n break;\n case 'readonly':\n passes = !!item.is_readonly;\n break;\n default:\n throw new Error(`Modifier ${modifierStr} is not fully supported.`);\n }\n\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes,\n failMessage: `${desc} does not have modifier ${modifierStr}, but it should.`,\n failNotMessage: `${desc} has modifier ${modifierStr}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveModifier } from '../shared/sharedCheckHaveModifier';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckHaveModifier(\n locator: ClassLocatorData,\n modifierStr: string,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveModifier(\n locator.classes,\n (c) => c.name,\n 'Class',\n modifierStr,\n isNot,\n );\n}\n","import * as path from 'node:path';\nimport { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveNameMatchingFileName<\n T extends { _filePath: string },\n>(\n items: T[],\n getName: (item: T) => string | null | undefined,\n label: string,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n\n if (!item._filePath) {\n return { passes: true, failMessage: '', failNotMessage: '' };\n }\n\n const basename = path.basename(\n item._filePath,\n path.extname(item._filePath),\n );\n const passes = name === basename;\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes,\n failMessage: `${desc} does not have a name matching its filename ${basename}, but it should.`,\n failNotMessage: `${desc} has a name matching its filename ${basename}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveNameMatchingFileName } from '../shared/sharedCheckHaveNameMatchingFileName';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckHaveNameMatchingFileName(\n locator: ClassLocatorData,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveNameMatchingFileName(\n locator.classes,\n (c) => c.name,\n 'Class',\n isNot,\n );\n}\n","import type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckImplementInterface(\n locator: ClassLocatorData,\n interfaceName: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const c of locator.classes) {\n const name = c.name || 'Anonymous';\n let matches = false;\n if (c.implements.includes(interfaceName)) {\n matches = true;\n }\n if (isNot && matches) {\n violations.push(\n `Class ${name} implements ${interfaceName}, but it shouldn't.`,\n );\n } else if (!isNot && !matches) {\n violations.push(\n `Class ${name} does not implement ${interfaceName}, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckMatchNamePattern<T>(\n items: T[],\n getName: (item: T) => string | undefined | null,\n label: string,\n pattern: string | RegExp,\n isNot: boolean,\n) {\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n const passes = name ? regex.test(name) : false;\n const desc = `${label} ${name || 'Anonymous'}`;\n return {\n passes,\n failMessage: `${desc} does not match pattern ${pattern}, but it should.`,\n failNotMessage: `${desc} matches pattern ${pattern}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckMatchNamePattern } from '../shared/sharedCheckMatchNamePattern';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckMatchNamePattern(\n locator: ClassLocatorData,\n pattern: string | RegExp,\n isNot: boolean,\n): RuleResult {\n return sharedCheckMatchNamePattern(\n locator.classes,\n (c) => c.name,\n 'Class',\n pattern,\n isNot,\n );\n}\n","import type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckResideInFolder(\n locator: ClassLocatorData,\n targetFolder: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const c of locator.classes) {\n const className = c.name || 'Anonymous Class';\n const filePath = c._filePath;\n const inTargetFolder =\n filePath.includes(`/${targetFolder}/`) ||\n filePath.includes(`\\\\${targetFolder}\\\\`);\n\n if (isNot && inTargetFolder) {\n violations.push(\n `Class ${className} resides in ${targetFolder}, but it shouldn't.`,\n );\n } else if (!isNot && !inTargetFolder) {\n violations.push(\n `Class ${className} does not reside in ${targetFolder}, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { ClassData, ProjectData } from '../dto';\nimport type { ClassLocatorData, ClassQueryOptions } from './types';\n\nexport function locateClasses(\n classes: (ClassData & { _filePath: string })[],\n projectData: ProjectData,\n options?: ClassQueryOptions,\n): ClassLocatorData {\n let filtered = classes;\n\n if (options?.inFolder) {\n filtered = filtered.filter((c) => {\n return (\n c._filePath.includes(`/${options.inFolder}/`) ||\n c._filePath.includes(`\\\\${options.inFolder}\\\\`)\n );\n });\n }\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((c) => {\n return c.name && regex.test(c.name);\n });\n }\n if (options?.withDecorator) {\n const decorator = options.withDecorator;\n filtered = filtered.filter((c) => {\n return c.decorators.includes(decorator);\n });\n }\n if (options?.extending) {\n filtered = filtered.filter((c) => {\n return c.extends === options.extending;\n });\n }\n if (options?.implementing) {\n const implementing = options.implementing;\n filtered = filtered.filter((c) => {\n return c.implements.includes(implementing);\n });\n }\n if (options?.havingModifier) {\n filtered = filtered.filter((c) => {\n switch (options.havingModifier) {\n case 'export':\n return c.is_exported;\n case 'default':\n return c.is_default;\n case 'abstract':\n return c.is_abstract;\n default:\n throw new Error(\n `Modifier ${options.havingModifier} is not fully supported.`,\n );\n }\n });\n }\n\n return {\n type: 'ClassLocator',\n classes: filtered,\n projectData,\n };\n}\n","import type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function checkDependOnExternalModule(\n locator: FileLocatorData,\n moduleName: string | RegExp,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n\n const regex =\n typeof moduleName === 'string' ? new RegExp(moduleName) : moduleName;\n\n for (const file of locator.files) {\n const deps = file.external_dependencies || [];\n const dependsOnModule = deps.some((dep) => regex.test(dep));\n\n if (isNot && dependsOnModule) {\n violations.push(\n `${file.path} incorrectly depends on external module '${moduleName}'`,\n );\n } else if (!isNot && !dependsOnModule) {\n violations.push(\n `${file.path} does not depend on external module '${moduleName}'`,\n );\n }\n }\n\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { FileData, ProjectData } from '../dto';\n\nexport function getFileDependencies(\n sourceFile: FileData,\n _projectData: ProjectData,\n): string[] {\n return sourceFile.dependencies || [];\n}\n","import type { RuleResult } from '../types';\nimport { getFileDependencies } from './getFileDependencies';\nimport type { FileLocatorData } from './types';\n\nexport function checkDependOnFilesInFolder(\n locator: FileLocatorData,\n targetFolder: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n\n for (const file of locator.files) {\n const dependencies = getFileDependencies(file, locator.projectData);\n\n const dependsOnTarget = dependencies.some(\n (depPath) =>\n depPath.includes(`/${targetFolder}/`) ||\n depPath.includes(`\\\\${targetFolder}\\\\`),\n );\n\n if (isNot && dependsOnTarget) {\n violations.push(\n `File ${file.path} depends on files in ${targetFolder}, but it shouldn't.`,\n );\n } else if (!isNot && !dependsOnTarget) {\n violations.push(\n `File ${file.path} does not depend on files in ${targetFolder}, but it should.`,\n );\n }\n }\n\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckBeFreeOfCycles(\n locator: FileLocatorData,\n isNot: boolean,\n): RuleResult {\n const targetFiles = locator.files.map((f) => f.path);\n\n const archestProject = locator.archestProject;\n if (!archestProject) {\n // Fallback for mocked tests or if registry is missing\n return {\n pass: true,\n message: () => 'Mock pass: archestProject not in registry',\n };\n }\n\n const result = archestProject.checkFileCycles(targetFiles, !!isNot);\n\n return {\n pass: result.pass,\n message: () => result.message,\n };\n}\n","import { sharedCheckHaveMaxCyclomaticComplexity } from '../shared/sharedCheckHaveMaxCyclomaticComplexity';\nimport type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckHaveMaxCyclomaticComplexity(\n locator: FileLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMaxCyclomaticComplexity(\n locator.files,\n (f) => f.path,\n (file) => {\n let complexity = 0;\n for (const func of file.functions) {\n complexity += func.cyclomatic_complexity || 0;\n }\n for (const cls of file.classes) {\n complexity += cls.cyclomatic_complexity || 0;\n }\n return complexity;\n },\n 'File',\n max,\n isNot,\n );\n}\n","import type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckHaveMaxExportedFunctions(\n locator: FileLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const file of locator.files) {\n const exportedFuncCount = file.functions.filter(\n (f) => f.is_exported,\n ).length;\n\n const exceeds = exportedFuncCount > max;\n\n if (isNot && exceeds) {\n violations.push(\n `File ${file.path} has ${exportedFuncCount} exported functions, which exceeds the maximum of ${max}, but it shouldn't.`,\n );\n } else if (!isNot && exceeds) {\n violations.push(\n `File ${file.path} has ${exportedFuncCount} exported functions, which exceeds the maximum of ${max}.`,\n );\n }\n }\n return {\n pass: isNot ? violations.length > 0 : violations.length === 0,\n message: () =>\n violations.join('\\n') ||\n (isNot\n ? 'Expected some files to exceed maximum exported functions, but none did.'\n : ''),\n };\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveMinMaintainabilityIndex<T>(\n items: T[],\n getName: (item: T) => string | undefined | null,\n getMi: (item: T) => number,\n label: string,\n min: number,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n const mi = getMi(item);\n const fallsBelow = mi < min;\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes: !fallsBelow,\n failMessage: `${desc} has a maintainability index of ${mi.toFixed(2)}, which falls below the minimum of ${min}.`,\n failNotMessage: `${desc} has a maintainability index of ${mi.toFixed(2)}, which falls below the minimum of ${min}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveMinMaintainabilityIndex } from '../shared/sharedCheckHaveMinMaintainabilityIndex';\nimport type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckHaveMinMaintainabilityIndex(\n locator: FileLocatorData,\n min: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMinMaintainabilityIndex(\n locator.files,\n (f) => f.path,\n (file) => {\n if (file.functions.length > 0) {\n return file.functions[0].maintainability_index || 100;\n }\n return 100;\n },\n 'File',\n min,\n isNot,\n );\n}\n","import { sharedCheckMatchNamePattern } from '../shared/sharedCheckMatchNamePattern';\nimport type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckMatchNamePattern(\n locator: FileLocatorData,\n pattern: string | RegExp,\n isNot: boolean,\n): RuleResult {\n return sharedCheckMatchNamePattern(\n locator.files,\n (f) => f.path,\n 'File',\n pattern,\n isNot,\n );\n}\n","import type { ArchestProject } from '@archest/core-rust';\nimport type { FileData, ProjectData } from '../dto';\nimport type { FileLocatorData, FileQueryOptions } from './types';\n\nexport function locateFiles(\n sourceFiles: FileData[],\n projectData: ProjectData,\n archestProject?: ArchestProject,\n options?: FileQueryOptions,\n): FileLocatorData {\n let filtered = sourceFiles;\n\n if (options?.inFolder) {\n filtered = filtered.filter(\n (file) =>\n file.path.includes(`/${options.inFolder}/`) ||\n file.path.includes(`\\\\${options.inFolder}\\\\`),\n );\n }\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((file) => regex.test(file.path));\n }\n\n const result: FileLocatorData = {\n type: 'FileLocator',\n files: filtered,\n projectData,\n };\n\n if (archestProject) {\n Object.defineProperty(result, 'archestProject', {\n value: archestProject,\n enumerable: false,\n });\n }\n\n return result;\n}\n","import type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveExplicitReturnType(\n locator: FunctionLocatorData,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const f of locator.functions) {\n const name = f.name || 'Anonymous Function';\n const hasType = f.has_explicit_return_type;\n\n if (isNot && hasType) {\n violations.push(\n `Function ${name} has an explicit return type, but it shouldn't.`,\n );\n } else if (!isNot && !hasType) {\n violations.push(\n `Function ${name} does not have an explicit return type, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import { sharedCheckHaveMaxCyclomaticComplexity } from '../shared/sharedCheckHaveMaxCyclomaticComplexity';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveMaxCyclomaticComplexity(\n locator: FunctionLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMaxCyclomaticComplexity(\n locator.functions,\n (f) => f.name,\n (f) => f.cyclomatic_complexity || 0,\n 'Function',\n max,\n isNot,\n );\n}\n","import { sharedCheckHaveMinMaintainabilityIndex } from '../shared/sharedCheckHaveMinMaintainabilityIndex';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveMinMaintainabilityIndex(\n locator: FunctionLocatorData,\n min: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMinMaintainabilityIndex(\n locator.functions,\n (f) => f.name,\n (f) => f.maintainability_index || 100,\n 'Function',\n min,\n isNot,\n );\n}\n","import { sharedCheckHaveModifier } from '../shared/sharedCheckHaveModifier';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveModifier(\n locator: FunctionLocatorData,\n modifierStr: string,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveModifier(\n locator.functions,\n (f) => f.name,\n 'Function',\n modifierStr,\n isNot,\n );\n}\n","import { sharedCheckHaveNameMatchingFileName } from '../shared/sharedCheckHaveNameMatchingFileName';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveNameMatchingFileName(\n locator: FunctionLocatorData,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveNameMatchingFileName(\n locator.functions,\n (f) => f.name,\n 'Function',\n isNot,\n );\n}\n","import { sharedCheckMatchNamePattern } from '../shared/sharedCheckMatchNamePattern';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckMatchNamePattern(\n locator: FunctionLocatorData,\n pattern: string | RegExp,\n isNot: boolean,\n): RuleResult {\n return sharedCheckMatchNamePattern(\n locator.functions,\n (f) => f.name,\n 'Function',\n pattern,\n isNot,\n );\n}\n","import type { FunctionData, ProjectData } from '../dto';\nimport type { FunctionLocatorData, FunctionQueryOptions } from './types';\n\nexport function locateFunctions(\n functions: (FunctionData & { _filePath: string })[],\n projectData: ProjectData,\n options?: FunctionQueryOptions,\n): FunctionLocatorData {\n let filtered = functions;\n\n if (options?.inFolder) {\n filtered = filtered.filter((f) => {\n return (\n f._filePath.includes(`/${options.inFolder}/`) ||\n f._filePath.includes(`\\\\${options.inFolder}\\\\`)\n );\n });\n }\n\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((f) => {\n return f.name && regex.test(f.name);\n });\n }\n\n if (options?.isTopLevel) {\n filtered = filtered.filter((f) => f.is_top_level);\n }\n\n return {\n type: 'FunctionLocator',\n functions: filtered,\n projectData,\n };\n}\n","import type { RuleResult } from '../types';\nimport type { LayeredArchitectureData } from './types';\n\nexport function checkLayeredArchitecture(\n data: LayeredArchitectureData,\n): RuleResult {\n const violations: string[] = [];\n for (const assertion of data.assertions) {\n violations.push(...assertion(data.files));\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { FileData, ProjectData } from '../dto';\nimport type { LayeredArchitectureData } from './types';\n\nexport function createLayeredArchitecture(\n files: FileData[],\n projectData: ProjectData,\n): LayeredArchitectureData {\n return {\n type: 'LayeredArchitecture',\n files,\n layers: new Map<string, string>(),\n assertions: [],\n projectData,\n };\n}\n","import type { LayeredArchitectureData } from './types';\n\nexport function layer(\n data: LayeredArchitectureData,\n name: string,\n folderPattern: string,\n): LayeredArchitectureData {\n data.layers.set(name, folderPattern);\n return data;\n}\n","import type { FileData, ProjectData } from '../dto';\n\nexport function getLayerDependencies(\n sourceFile: FileData,\n _projectData: ProjectData,\n): string[] {\n return sourceFile.dependencies || [];\n}\n","import { getLayerDependencies } from './getLayerDependencies';\nimport type { LayeredArchitectureData } from './types';\n\nexport function layerShouldNotBeAccessedByAnyLayer(\n data: LayeredArchitectureData,\n targetLayer: string,\n): LayeredArchitectureData {\n if (!data.layers.has(targetLayer)) {\n throw new Error(`Layer ${targetLayer} is not defined`);\n }\n\n data.assertions.push((files) => {\n const violations: string[] = [];\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const targetPattern = data.layers.get(targetLayer)!;\n\n for (const file of files) {\n const filePath = file.path;\n if (\n !filePath.includes(`/${targetPattern}/`) &&\n !filePath.includes(`\\\\${targetPattern}\\\\`)\n ) {\n const dependencies = getLayerDependencies(file, data.projectData);\n const importsTarget = dependencies.some(\n (dep) =>\n dep.includes(`/${targetPattern}/`) ||\n dep.includes(`\\\\${targetPattern}\\\\`),\n );\n if (importsTarget) {\n violations.push(\n `File ${filePath} accesses layer ${targetLayer} but it shouldn't.`,\n );\n }\n }\n }\n return violations;\n });\n\n return data;\n}\n","import { getLayerDependencies } from './getLayerDependencies';\nimport type { LayeredArchitectureData } from './types';\n\nexport function layerShouldOnlyBeAccessedBy(\n data: LayeredArchitectureData,\n targetLayer: string,\n allowedLayers: string[],\n): LayeredArchitectureData {\n if (!data.layers.has(targetLayer)) {\n throw new Error(`Layer ${targetLayer} is not defined`);\n }\n\n data.assertions.push((files) => {\n const violations: string[] = [];\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const targetPattern = data.layers.get(targetLayer)!;\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const allowedPatterns = allowedLayers.map((l) => data.layers.get(l)!);\n\n for (const file of files) {\n const filePath = file.path;\n const isInAllowedLayer = allowedPatterns.some(\n (p) => filePath.includes(`/${p}/`) || filePath.includes(`\\\\${p}\\\\`),\n );\n\n if (\n !filePath.includes(`/${targetPattern}/`) &&\n !filePath.includes(`\\\\${targetPattern}\\\\`) &&\n !isInAllowedLayer\n ) {\n const dependencies = getLayerDependencies(file, data.projectData);\n const importsTarget = dependencies.some(\n (dep) =>\n dep.includes(`/${targetPattern}/`) ||\n dep.includes(`\\\\${targetPattern}\\\\`),\n );\n if (importsTarget) {\n violations.push(\n `File ${filePath} accesses layer ${targetLayer} but only ${allowedLayers.join(', ')} are allowed.`,\n );\n }\n }\n }\n return violations;\n });\n\n return data;\n}\n","import type { ProjectData, PropertyData } from '../dto';\nimport type { PropertyLocatorData, PropertyQueryOptions } from './types';\n\nexport function locateProperties(\n properties: (PropertyData & { _filePath: string })[],\n projectData: ProjectData,\n options?: PropertyQueryOptions,\n): PropertyLocatorData {\n let filtered = properties;\n\n if (options?.inFolder) {\n filtered = filtered.filter((p) => {\n return (\n p._filePath.includes(`/${options.inFolder}/`) ||\n p._filePath.includes(`\\\\${options.inFolder}\\\\`)\n );\n });\n }\n\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((p) => {\n return regex.test(p.name);\n });\n }\n\n return {\n type: 'PropertyLocator',\n properties: filtered,\n projectData,\n };\n}\n","import type { FileData, ProjectData } from '../dto';\nimport type { SliceLocatorData } from './types';\n\nexport function locateSlices(\n sourceFiles: FileData[],\n projectData: ProjectData,\n pattern: string,\n): SliceLocatorData {\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regexStr = escaped.replace(/\\*/g, '([^/\\\\\\\\]+)');\n const slicePattern = new RegExp(regexStr);\n\n const sliceIds = new Set<string>();\n const sliceFiles = new Map<string, FileData[]>();\n\n for (const sf of sourceFiles) {\n const match = sf.path.match(slicePattern);\n if (match?.[1]) {\n const sliceId = match[1];\n sliceIds.add(sliceId);\n if (!sliceFiles.has(sliceId)) {\n sliceFiles.set(sliceId, []);\n }\n sliceFiles.get(sliceId)?.push(sf);\n }\n }\n\n return {\n type: 'SliceLocator',\n slicePattern,\n sliceIds,\n sliceFiles,\n projectData,\n };\n}\n","import { dirname } from 'node:path';\nimport { ArchestProject } from '@archest/core-rust';\nimport * as ts from 'typescript';\nimport { locateClasses } from '../classes/locateClasses';\nimport type { ClassQueryOptions } from '../classes/types';\nimport type { ProjectData } from '../dto';\nimport { locateFiles } from '../files/locateFiles';\nimport type { FileQueryOptions } from '../files/types';\nimport { locateFunctions } from '../functions/locateFunctions';\nimport type { FunctionQueryOptions } from '../functions/types';\nimport { checkLayeredArchitecture } from '../layers/checkLayeredArchitecture';\nimport { createLayeredArchitecture } from '../layers/createLayeredArchitecture';\nimport { layer } from '../layers/layer';\nimport { layerShouldNotBeAccessedByAnyLayer } from '../layers/layerShouldNotBeAccessedByAnyLayer';\nimport { layerShouldOnlyBeAccessedBy } from '../layers/layerShouldOnlyBeAccessedBy';\nimport { locateProperties } from '../properties/locateProperties';\nimport type { PropertyQueryOptions } from '../properties/types';\nimport { locateSlices } from '../slices/locateSlices';\n\n/**\n * Options to configure how the project is parsed and analyzed.\n */\nexport interface ParseProjectOptions {\n /**\n * An optional absolute path to a specific tsconfig.json file.\n * If omitted, Archest will attempt to find the nearest tsconfig.json in the current working directory.\n */\n tsConfigFilePath?: string;\n /** An array of glob patterns specifying which files to include in the AST parsing. Overrides the tsconfig.json `include` array. */\n include?: string[];\n /** An array of glob patterns specifying which files to exclude from the AST parsing. Overrides the tsconfig.json `exclude` array. */\n exclude?: string[];\n}\n\n/**\n * The primary entry point for Archest. Parses a TypeScript or JavaScript project into a searchable\n * Abstract Syntax Tree (AST) using the high-performance native Rust engine.\n *\n * @param options - Optional configuration for locating the tsconfig and filtering files.\n * @returns A fluent API object containing Locators used to query the project's architecture.\n *\n * @example\n * ```typescript\n * import { parseProject } from '@archest/vitest';\n *\n * const project = parseProject({\n * include: ['src/domain/**\\/*.ts'],\n * exclude: ['**\\/*.test.ts']\n * });\n *\n * const domainFiles = project.getFiles();\n * ```\n */\nexport function parseProject(options: ParseProjectOptions = {}) {\n const configPath =\n options.tsConfigFilePath ||\n ts.findConfigFile(process.cwd(), ts.sys.fileExists, 'tsconfig.json');\n\n if (!configPath) {\n throw new Error('Could not find tsconfig.json');\n }\n\n const projectDir = dirname(configPath);\n\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile);\n if (options.include) configFile.config.include = options.include;\n if (options.exclude) configFile.config.exclude = options.exclude;\n\n const parsedCommandLine = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n projectDir,\n undefined,\n configPath,\n undefined,\n [\n {\n extension: '.vue',\n isMixedContent: true,\n scriptKind: ts.ScriptKind.TS,\n },\n {\n extension: '.svelte',\n isMixedContent: true,\n scriptKind: ts.ScriptKind.TS,\n },\n ],\n );\n\n const archestProject = ArchestProject.parse(parsedCommandLine.fileNames);\n const projectData: ProjectData = JSON.parse(archestProject.getProjectData());\n\n return {\n projectData,\n getFiles: (queryOptions?: FileQueryOptions) => {\n return locateFiles(\n projectData.files,\n projectData,\n archestProject,\n queryOptions,\n );\n },\n\n getClasses: (queryOptions?: ClassQueryOptions) => {\n const allClasses = projectData.files.flatMap((f) =>\n f.classes.map((c) => ({ ...c, _filePath: f.path })),\n );\n return locateClasses(allClasses, projectData, queryOptions);\n },\n\n layeredArchitecture: () => {\n let data = createLayeredArchitecture(projectData.files, projectData);\n const api = {\n layer: (name: string, folderPattern: string) => {\n data = layer(data, name, folderPattern);\n return api;\n },\n whereLayer: (name: string) => {\n return {\n shouldNotBeAccessedByAnyLayer: () => {\n data = layerShouldNotBeAccessedByAnyLayer(data, name);\n return api;\n },\n shouldOnlyBeAccessedBy: (...allowedLayers: string[]) => {\n data = layerShouldOnlyBeAccessedBy(data, name, allowedLayers);\n return api;\n },\n };\n },\n check: () => checkLayeredArchitecture(data),\n get data() {\n return data;\n },\n };\n return api;\n },\n\n getFunctions: (queryOptions?: FunctionQueryOptions) => {\n const allFunctions = projectData.files.flatMap((f) =>\n f.functions.map((fn) => ({ ...fn, _filePath: f.path })),\n );\n return locateFunctions(allFunctions, projectData, queryOptions);\n },\n\n getProperties: (queryOptions?: PropertyQueryOptions) => {\n const allProperties = projectData.files.flatMap((f) =>\n f.properties.map((p) => ({ ...p, _filePath: f.path })),\n );\n return locateProperties(allProperties, projectData, queryOptions);\n },\n\n getSlices: (pattern: string) => {\n return locateSlices(projectData.files, projectData, pattern);\n },\n };\n}\n","import type { RuleResult } from '../types';\nimport type { PropertyLocatorData } from './types';\n\nexport function propertyCheckBeReadonly(\n locator: PropertyLocatorData,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const p of locator.properties) {\n const name = p.name || 'Anonymous Property';\n const matches = p.is_readonly;\n\n if (isNot && matches) {\n violations.push(`Property ${name} is readonly, but it shouldn't be.`);\n } else if (!isNot && !matches) {\n violations.push(`Property ${name} is not readonly, but it should be.`);\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { RuleResult } from '../types';\nimport type { SliceLocatorData } from './types';\n\nexport function sliceCheckBeFreeOfCycles(\n locator: SliceLocatorData,\n isNot: boolean,\n): RuleResult {\n const graph: Map<string, Set<string>> = new Map();\n for (const slice of locator.sliceIds) {\n graph.set(slice, new Set());\n }\n\n for (const [sliceId, files] of locator.sliceFiles.entries()) {\n for (const sf of files) {\n if (!sf.dependencies) continue;\n for (const importPath of sf.dependencies) {\n const targetMatch = importPath.match(locator.slicePattern);\n if (targetMatch?.[1]) {\n const targetSlice = targetMatch[1];\n if (targetSlice !== sliceId && locator.sliceIds.has(targetSlice)) {\n graph.get(sliceId)?.add(targetSlice);\n }\n }\n }\n }\n }\n\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const violations: string[] = [];\n\n const dfs = (node: string, path: string[]): boolean => {\n visited.add(node);\n recursionStack.add(node);\n\n for (const neighbor of graph.get(node) || []) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor, [...path, neighbor])) return true;\n } else if (recursionStack.has(neighbor)) {\n violations.push(\n `Cycle detected between slices: ${path.join(' -> ')} -> ${neighbor}`,\n );\n return true;\n }\n }\n\n recursionStack.delete(node);\n return false;\n };\n\n for (const slice of locator.sliceIds) {\n if (!visited.has(slice)) {\n dfs(slice, [slice]);\n }\n }\n\n if (isNot) {\n return {\n pass: violations.length > 0,\n message: () =>\n violations.length > 0\n ? ''\n : 'Expected cycles between slices but found none.',\n };\n } else {\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n }\n}\n","import type { RuleResult } from '../types';\nimport type { SliceLocatorData } from './types';\n\nexport function sliceCheckHaveMaxDistanceFromMainSequence(\n locator: SliceLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n\n const ceMap = new Map<string, Set<string>>(); // Slices this slice depends on\n const caMap = new Map<string, Set<string>>(); // Slices depending on this slice\n\n for (const slice of locator.sliceIds) {\n ceMap.set(slice, new Set());\n caMap.set(slice, new Set());\n }\n\n for (const [sliceId, files] of locator.sliceFiles.entries()) {\n for (const sf of files) {\n if (!sf.dependencies) continue;\n for (const importPath of sf.dependencies) {\n const targetMatch = importPath.match(locator.slicePattern);\n if (targetMatch?.[1]) {\n const targetSlice = targetMatch[1];\n if (targetSlice !== sliceId && locator.sliceIds.has(targetSlice)) {\n ceMap.get(sliceId)?.add(targetSlice);\n caMap.get(targetSlice)?.add(sliceId);\n }\n }\n }\n }\n }\n\n for (const sliceId of locator.sliceIds) {\n const ce = ceMap.get(sliceId)?.size || 0;\n const ca = caMap.get(sliceId)?.size || 0;\n\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const files = locator.sliceFiles.get(sliceId)!;\n let na = 0; // abstract classes + interfaces\n let nc = 0; // all classes + interfaces\n\n for (const sf of files) {\n for (const c of sf.classes) {\n nc++;\n if (c.is_abstract) {\n na++;\n }\n }\n }\n\n const I = ce + ca === 0 ? 0 : ce / (ca + ce);\n const A = nc === 0 ? 0 : na / nc;\n\n const D = Math.abs(A + I - 1);\n const exceeds = D > max;\n\n if (isNot && exceeds) {\n violations.push(\n `Slice ${sliceId} has a Distance from the Main Sequence of ${D.toFixed(2)}, which exceeds the maximum of ${max}, but it shouldn't.`,\n );\n } else if (!isNot && exceeds) {\n violations.push(\n `Slice ${sliceId} has a Distance from the Main Sequence of ${D.toFixed(2)}, which exceeds the maximum of ${max}.`,\n );\n }\n }\n\n return {\n pass: isNot ? violations.length > 0 : violations.length === 0,\n message: () =>\n violations.join('\\n') ||\n (isNot\n ? 'Expected some slices to exceed maximum distance from main sequence, but none did.'\n : ''),\n };\n}\n","import { ArchestProject } from '@archest/core-rust';\nimport * as ts from 'typescript';\n\nimport type { ClassData, FunctionData, ProjectData, PropertyData } from './dto';\n\nexport function createSourceFile(\n code: string,\n fileName = 'test.ts',\n): ts.SourceFile {\n return ts.createSourceFile(fileName, code, ts.ScriptTarget.Latest, true);\n}\n\nexport function createMockProgram(sourceFiles: ts.SourceFile[]): ProjectData {\n return {\n files: sourceFiles.map((sf) => ({\n path: sf.fileName,\n classes: getClasses(sf),\n functions: getFunctions(sf),\n properties: getProperties(sf),\n })),\n };\n}\n\nexport function createMockArchestProject(\n projectData: ProjectData,\n): ArchestProject {\n return ArchestProject.parseMock(JSON.stringify(projectData));\n}\n\nexport function getClasses(\n sourceFile: ts.SourceFile,\n): (ClassData & { _filePath: string })[] {\n const classes: (ClassData & { _filePath: string })[] = [];\n ts.forEachChild(sourceFile, (node) => {\n if (ts.isClassDeclaration(node)) {\n let extendsName: string | null = null;\n const implementsNames: string[] = [];\n if (node.heritageClauses) {\n for (const clause of node.heritageClauses) {\n if (clause.token === ts.SyntaxKind.ExtendsKeyword) {\n for (const t of clause.types) {\n if (ts.isIdentifier(t.expression))\n extendsName = t.expression.text;\n }\n }\n if (clause.token === ts.SyntaxKind.ImplementsKeyword) {\n for (const t of clause.types) {\n if (ts.isIdentifier(t.expression))\n implementsNames.push(t.expression.text);\n }\n }\n }\n }\n\n const decorators: string[] = [];\n if (ts.canHaveDecorators(node)) {\n const decs = ts.getDecorators(node);\n if (decs) {\n for (const d of decs) {\n if (ts.isIdentifier(d.expression))\n decorators.push(d.expression.text);\n else if (\n ts.isCallExpression(d.expression) &&\n ts.isIdentifier(d.expression.expression)\n )\n decorators.push(d.expression.expression.text);\n }\n }\n }\n\n classes.push({\n name: node.name?.text || null,\n is_exported: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) || false\n : false,\n is_default: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword) || false\n : false,\n is_abstract: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.AbstractKeyword) || false\n : false,\n extends: extendsName,\n implements: implementsNames,\n decorators,\n _filePath: sourceFile.fileName,\n });\n }\n });\n return classes;\n}\n\nexport function getFunctions(\n sourceFile: ts.SourceFile,\n): (FunctionData & { _filePath: string })[] {\n const functions: (FunctionData & { _filePath: string })[] = [];\n ts.forEachChild(sourceFile, (node) => {\n if (\n ts.isFunctionDeclaration(node) ||\n ts.isMethodDeclaration(node) ||\n ts.isArrowFunction(node)\n ) {\n let name: string | null = null;\n if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) {\n name = node.name?.getText() || null;\n }\n\n functions.push({\n name,\n is_exported: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) || false\n : false,\n is_async: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) || false\n : false,\n is_top_level: true,\n // biome-ignore lint/suspicious/noExplicitAny: Mocking typescript node types for tests\n has_explicit_return_type: !!(node as any).type,\n _filePath: sourceFile.fileName,\n });\n }\n });\n return functions;\n}\n\nexport function getProperties(\n sourceFile: ts.SourceFile,\n): (PropertyData & { _filePath: string })[] {\n const properties: (PropertyData & { _filePath: string })[] = [];\n ts.forEachChild(sourceFile, (node) => {\n if (ts.isClassDeclaration(node)) {\n node.members.forEach((member) => {\n if (ts.isPropertyDeclaration(member)) {\n properties.push({\n name: member.name.getText(),\n is_readonly: ts.canHaveModifiers(member)\n ? ts\n .getModifiers(member)\n ?.some((m) => m.kind === ts.SyntaxKind.ReadonlyKeyword) ||\n false\n : false,\n _filePath: sourceFile.fileName,\n });\n }\n });\n }\n });\n return properties;\n}\n"],"mappings":"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"}
@@ -155,7 +155,15 @@ function g(e, t, n) {
155
155
  let e = typeof n.matchNamePattern == "string" ? new RegExp(n.matchNamePattern) : n.matchNamePattern;
156
156
  r = r.filter((t) => t.name && e.test(t.name));
157
157
  }
158
- return n?.withDecorator && (r = r.filter((e) => e.decorators.includes(n.withDecorator))), n?.extending && (r = r.filter((e) => e.extends === n.extending)), n?.implementing && (r = r.filter((e) => e.implements.includes(n.implementing))), n?.havingModifier && (r = r.filter((e) => {
158
+ if (n?.withDecorator) {
159
+ let e = n.withDecorator;
160
+ r = r.filter((t) => t.decorators.includes(e));
161
+ }
162
+ if (n?.extending && (r = r.filter((e) => e.extends === n.extending)), n?.implementing) {
163
+ let e = n.implementing;
164
+ r = r.filter((t) => t.implements.includes(e));
165
+ }
166
+ return n?.havingModifier && (r = r.filter((e) => {
159
167
  switch (n.havingModifier) {
160
168
  case "export": return e.is_exported;
161
169
  case "default": return e.is_default;
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/classes/classCheckExtendClass.ts","../src/utils/ruleBuilder.ts","../src/shared/sharedCheckHaveMaxCyclomaticComplexity.ts","../src/classes/classCheckHaveMaxCyclomaticComplexity.ts","../src/shared/sharedCheckHaveModifier.ts","../src/classes/classCheckHaveModifier.ts","../src/shared/sharedCheckHaveNameMatchingFileName.ts","../src/classes/classCheckHaveNameMatchingFileName.ts","../src/classes/classCheckImplementInterface.ts","../src/shared/sharedCheckMatchNamePattern.ts","../src/classes/classCheckMatchNamePattern.ts","../src/classes/classCheckResideInFolder.ts","../src/classes/locateClasses.ts","../src/files/checkDependOnExternalModule.ts","../src/files/getFileDependencies.ts","../src/files/checkDependOnFilesInFolder.ts","../src/files/fileCheckBeFreeOfCycles.ts","../src/files/fileCheckHaveMaxCyclomaticComplexity.ts","../src/files/fileCheckHaveMaxExportedFunctions.ts","../src/shared/sharedCheckHaveMinMaintainabilityIndex.ts","../src/files/fileCheckHaveMinMaintainabilityIndex.ts","../src/files/fileCheckMatchNamePattern.ts","../src/files/locateFiles.ts","../src/functions/functionCheckHaveExplicitReturnType.ts","../src/functions/functionCheckHaveMaxCyclomaticComplexity.ts","../src/functions/functionCheckHaveMinMaintainabilityIndex.ts","../src/functions/functionCheckHaveModifier.ts","../src/functions/functionCheckHaveNameMatchingFileName.ts","../src/functions/functionCheckMatchNamePattern.ts","../src/functions/locateFunctions.ts","../src/layers/checkLayeredArchitecture.ts","../src/layers/createLayeredArchitecture.ts","../src/layers/layer.ts","../src/layers/getLayerDependencies.ts","../src/layers/layerShouldNotBeAccessedByAnyLayer.ts","../src/layers/layerShouldOnlyBeAccessedBy.ts","../src/properties/locateProperties.ts","../src/slices/locateSlices.ts","../src/project/parseProject.ts","../src/properties/propertyCheckBeReadonly.ts","../src/slices/sliceCheckBeFreeOfCycles.ts","../src/slices/sliceCheckHaveMaxDistanceFromMainSequence.ts","../src/testUtils.ts"],"sourcesContent":["import type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckExtendClass(\n locator: ClassLocatorData,\n className: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const c of locator.classes) {\n const name = c.name || 'Anonymous';\n let matches = false;\n if (c.extends === className) {\n matches = true;\n }\n if (isNot && matches) {\n violations.push(`Class ${name} extends ${className}, but it shouldn't.`);\n } else if (!isNot && !matches) {\n violations.push(\n `Class ${name} does not extend ${className}, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { RuleResult } from '../types';\n\nexport function ruleBuilder<T>(\n items: T[],\n isNot: boolean,\n evaluate: (item: T) => {\n passes: boolean;\n failMessage: string;\n failNotMessage: string;\n },\n): RuleResult {\n const violations: string[] = [];\n\n for (const item of items) {\n const { passes, failMessage, failNotMessage } = evaluate(item);\n\n if (isNot && passes) {\n if (failNotMessage) violations.push(failNotMessage);\n } else if (!isNot && !passes) {\n if (failMessage) violations.push(failMessage);\n }\n }\n\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveMaxCyclomaticComplexity<T>(\n items: T[],\n getName: (item: T) => string | undefined | null,\n getComplexity: (item: T) => number,\n label: string,\n max: number,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n const complexity = getComplexity(item);\n const exceeds = complexity > max;\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes: !exceeds,\n failMessage: `${desc} has a total cyclomatic complexity of ${complexity}, which exceeds the maximum of ${max}.`,\n failNotMessage: `${desc} has a total cyclomatic complexity of ${complexity}, which exceeds the maximum of ${max}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveMaxCyclomaticComplexity } from '../shared/sharedCheckHaveMaxCyclomaticComplexity';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckHaveMaxCyclomaticComplexity(\n locator: ClassLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMaxCyclomaticComplexity(\n locator.classes,\n (c) => c.name,\n (c) => c.cyclomatic_complexity || 0,\n 'Class',\n max,\n isNot,\n );\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveModifier<\n T extends {\n is_exported?: boolean;\n is_default?: boolean;\n is_abstract?: boolean;\n is_async?: boolean;\n is_readonly?: boolean;\n },\n>(\n items: T[],\n getName: (item: T) => string | null | undefined,\n label: string,\n modifierStr: string,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n let passes = false;\n switch (modifierStr) {\n case 'export':\n passes = !!item.is_exported;\n break;\n case 'default':\n passes = !!item.is_default;\n break;\n case 'abstract':\n passes = !!item.is_abstract;\n break;\n case 'async':\n passes = !!item.is_async;\n break;\n case 'readonly':\n passes = !!item.is_readonly;\n break;\n default:\n throw new Error(`Modifier ${modifierStr} is not fully supported.`);\n }\n\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes,\n failMessage: `${desc} does not have modifier ${modifierStr}, but it should.`,\n failNotMessage: `${desc} has modifier ${modifierStr}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveModifier } from '../shared/sharedCheckHaveModifier';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckHaveModifier(\n locator: ClassLocatorData,\n modifierStr: string,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveModifier(\n locator.classes,\n (c) => c.name,\n 'Class',\n modifierStr,\n isNot,\n );\n}\n","import * as path from 'node:path';\nimport { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveNameMatchingFileName<\n T extends { _filePath: string },\n>(\n items: T[],\n getName: (item: T) => string | null | undefined,\n label: string,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n\n if (!item._filePath) {\n return { passes: true, failMessage: '', failNotMessage: '' };\n }\n\n const basename = path.basename(\n item._filePath,\n path.extname(item._filePath),\n );\n const passes = name === basename;\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes,\n failMessage: `${desc} does not have a name matching its filename ${basename}, but it should.`,\n failNotMessage: `${desc} has a name matching its filename ${basename}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveNameMatchingFileName } from '../shared/sharedCheckHaveNameMatchingFileName';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckHaveNameMatchingFileName(\n locator: ClassLocatorData,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveNameMatchingFileName(\n locator.classes,\n (c) => c.name,\n 'Class',\n isNot,\n );\n}\n","import type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckImplementInterface(\n locator: ClassLocatorData,\n interfaceName: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const c of locator.classes) {\n const name = c.name || 'Anonymous';\n let matches = false;\n if (c.implements.includes(interfaceName)) {\n matches = true;\n }\n if (isNot && matches) {\n violations.push(\n `Class ${name} implements ${interfaceName}, but it shouldn't.`,\n );\n } else if (!isNot && !matches) {\n violations.push(\n `Class ${name} does not implement ${interfaceName}, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckMatchNamePattern<T>(\n items: T[],\n getName: (item: T) => string | undefined | null,\n label: string,\n pattern: string | RegExp,\n isNot: boolean,\n) {\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n const passes = name ? regex.test(name) : false;\n const desc = `${label} ${name || 'Anonymous'}`;\n return {\n passes,\n failMessage: `${desc} does not match pattern ${pattern}, but it should.`,\n failNotMessage: `${desc} matches pattern ${pattern}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckMatchNamePattern } from '../shared/sharedCheckMatchNamePattern';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckMatchNamePattern(\n locator: ClassLocatorData,\n pattern: string | RegExp,\n isNot: boolean,\n): RuleResult {\n return sharedCheckMatchNamePattern(\n locator.classes,\n (c) => c.name,\n 'Class',\n pattern,\n isNot,\n );\n}\n","import type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckResideInFolder(\n locator: ClassLocatorData,\n targetFolder: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const c of locator.classes) {\n const className = c.name || 'Anonymous Class';\n const filePath = c._filePath;\n const inTargetFolder =\n filePath.includes(`/${targetFolder}/`) ||\n filePath.includes(`\\\\${targetFolder}\\\\`);\n\n if (isNot && inTargetFolder) {\n violations.push(\n `Class ${className} resides in ${targetFolder}, but it shouldn't.`,\n );\n } else if (!isNot && !inTargetFolder) {\n violations.push(\n `Class ${className} does not reside in ${targetFolder}, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { ClassData, ProjectData } from '../dto';\nimport type { ClassLocatorData, ClassQueryOptions } from './types';\n\nexport function locateClasses(\n classes: (ClassData & { _filePath: string })[],\n projectData: ProjectData,\n options?: ClassQueryOptions,\n): ClassLocatorData {\n let filtered = classes;\n\n if (options?.inFolder) {\n filtered = filtered.filter((c) => {\n return (\n c._filePath.includes(`/${options.inFolder}/`) ||\n c._filePath.includes(`\\\\${options.inFolder}\\\\`)\n );\n });\n }\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((c) => {\n return c.name && regex.test(c.name);\n });\n }\n if (options?.withDecorator) {\n filtered = filtered.filter((c) => {\n return c.decorators.includes(options.withDecorator!);\n });\n }\n if (options?.extending) {\n filtered = filtered.filter((c) => {\n return c.extends === options.extending;\n });\n }\n if (options?.implementing) {\n filtered = filtered.filter((c) => {\n return c.implements.includes(options.implementing!);\n });\n }\n if (options?.havingModifier) {\n filtered = filtered.filter((c) => {\n switch (options.havingModifier) {\n case 'export':\n return c.is_exported;\n case 'default':\n return c.is_default;\n case 'abstract':\n return c.is_abstract;\n default:\n throw new Error(\n `Modifier ${options.havingModifier} is not fully supported.`,\n );\n }\n });\n }\n\n return {\n type: 'ClassLocator',\n classes: filtered,\n projectData,\n };\n}\n","import type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function checkDependOnExternalModule(\n locator: FileLocatorData,\n moduleName: string | RegExp,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n\n const regex =\n typeof moduleName === 'string' ? new RegExp(moduleName) : moduleName;\n\n for (const file of locator.files) {\n const deps = file.external_dependencies || [];\n const dependsOnModule = deps.some((dep) => regex.test(dep));\n\n if (isNot && dependsOnModule) {\n violations.push(\n `${file.path} incorrectly depends on external module '${moduleName}'`,\n );\n } else if (!isNot && !dependsOnModule) {\n violations.push(\n `${file.path} does not depend on external module '${moduleName}'`,\n );\n }\n }\n\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { FileData, ProjectData } from '../dto';\n\nexport function getFileDependencies(\n sourceFile: FileData,\n projectData: ProjectData,\n): string[] {\n return sourceFile.dependencies || [];\n}\n","import type { RuleResult } from '../types';\nimport { getFileDependencies } from './getFileDependencies';\nimport type { FileLocatorData } from './types';\n\nexport function checkDependOnFilesInFolder(\n locator: FileLocatorData,\n targetFolder: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n\n for (const file of locator.files) {\n const dependencies = getFileDependencies(file, locator.projectData);\n\n const dependsOnTarget = dependencies.some(\n (depPath) =>\n depPath.includes(`/${targetFolder}/`) ||\n depPath.includes(`\\\\${targetFolder}\\\\`),\n );\n\n if (isNot && dependsOnTarget) {\n violations.push(\n `File ${file.path} depends on files in ${targetFolder}, but it shouldn't.`,\n );\n } else if (!isNot && !dependsOnTarget) {\n violations.push(\n `File ${file.path} does not depend on files in ${targetFolder}, but it should.`,\n );\n }\n }\n\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { RuleResult } from '../types';\nimport { getFileDependencies } from './getFileDependencies';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckBeFreeOfCycles(\n locator: FileLocatorData,\n isNot: boolean,\n): RuleResult {\n const targetFiles = locator.files.map((f) => f.path);\n\n const archestProject = locator.archestProject;\n if (!archestProject) {\n // Fallback for mocked tests or if registry is missing\n return {\n pass: true,\n message: () => 'Mock pass: archestProject not in registry',\n };\n }\n\n const result = archestProject.checkFileCycles(targetFiles, !!isNot);\n\n return {\n pass: result.pass,\n message: () => result.message,\n };\n}\n","import { sharedCheckHaveMaxCyclomaticComplexity } from '../shared/sharedCheckHaveMaxCyclomaticComplexity';\nimport type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckHaveMaxCyclomaticComplexity(\n locator: FileLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMaxCyclomaticComplexity(\n locator.files,\n (f) => f.path,\n (file) => {\n let complexity = 0;\n for (const func of file.functions) {\n complexity += func.cyclomatic_complexity || 0;\n }\n for (const cls of file.classes) {\n complexity += cls.cyclomatic_complexity || 0;\n }\n return complexity;\n },\n 'File',\n max,\n isNot,\n );\n}\n","import type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckHaveMaxExportedFunctions(\n locator: FileLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const file of locator.files) {\n const exportedFuncCount = file.functions.filter(\n (f) => f.is_exported,\n ).length;\n\n const exceeds = exportedFuncCount > max;\n\n if (isNot && exceeds) {\n violations.push(\n `File ${file.path} has ${exportedFuncCount} exported functions, which exceeds the maximum of ${max}, but it shouldn't.`,\n );\n } else if (!isNot && exceeds) {\n violations.push(\n `File ${file.path} has ${exportedFuncCount} exported functions, which exceeds the maximum of ${max}.`,\n );\n }\n }\n return {\n pass: isNot ? violations.length > 0 : violations.length === 0,\n message: () =>\n violations.join('\\n') ||\n (isNot\n ? 'Expected some files to exceed maximum exported functions, but none did.'\n : ''),\n };\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveMinMaintainabilityIndex<T>(\n items: T[],\n getName: (item: T) => string | undefined | null,\n getMi: (item: T) => number,\n label: string,\n min: number,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n const mi = getMi(item);\n const fallsBelow = mi < min;\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes: !fallsBelow,\n failMessage: `${desc} has a maintainability index of ${mi.toFixed(2)}, which falls below the minimum of ${min}.`,\n failNotMessage: `${desc} has a maintainability index of ${mi.toFixed(2)}, which falls below the minimum of ${min}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveMinMaintainabilityIndex } from '../shared/sharedCheckHaveMinMaintainabilityIndex';\nimport type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckHaveMinMaintainabilityIndex(\n locator: FileLocatorData,\n min: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMinMaintainabilityIndex(\n locator.files,\n (f) => f.path,\n (file) => {\n if (file.functions.length > 0) {\n return file.functions[0].maintainability_index || 100;\n }\n return 100;\n },\n 'File',\n min,\n isNot,\n );\n}\n","import { sharedCheckMatchNamePattern } from '../shared/sharedCheckMatchNamePattern';\nimport type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckMatchNamePattern(\n locator: FileLocatorData,\n pattern: string | RegExp,\n isNot: boolean,\n): RuleResult {\n return sharedCheckMatchNamePattern(\n locator.files,\n (f) => f.path,\n 'File',\n pattern,\n isNot,\n );\n}\n","import type { ArchestProject } from '@archest/core-rust';\nimport type { FileData, ProjectData } from '../dto';\nimport type { FileLocatorData, FileQueryOptions } from './types';\n\nexport function locateFiles(\n sourceFiles: FileData[],\n projectData: ProjectData,\n archestProject?: ArchestProject,\n options?: FileQueryOptions,\n): FileLocatorData {\n let filtered = sourceFiles;\n\n if (options?.inFolder) {\n filtered = filtered.filter(\n (file) =>\n file.path.includes(`/${options.inFolder}/`) ||\n file.path.includes(`\\\\${options.inFolder}\\\\`),\n );\n }\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((file) => regex.test(file.path));\n }\n\n const result: FileLocatorData = {\n type: 'FileLocator',\n files: filtered,\n projectData,\n };\n\n if (archestProject) {\n Object.defineProperty(result, 'archestProject', {\n value: archestProject,\n enumerable: false,\n });\n }\n\n return result;\n}\n","import type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveExplicitReturnType(\n locator: FunctionLocatorData,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const f of locator.functions) {\n const name = f.name || 'Anonymous Function';\n const hasType = f.has_explicit_return_type;\n\n if (isNot && hasType) {\n violations.push(\n `Function ${name} has an explicit return type, but it shouldn't.`,\n );\n } else if (!isNot && !hasType) {\n violations.push(\n `Function ${name} does not have an explicit return type, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import { sharedCheckHaveMaxCyclomaticComplexity } from '../shared/sharedCheckHaveMaxCyclomaticComplexity';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveMaxCyclomaticComplexity(\n locator: FunctionLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMaxCyclomaticComplexity(\n locator.functions,\n (f) => f.name,\n (f) => f.cyclomatic_complexity || 0,\n 'Function',\n max,\n isNot,\n );\n}\n","import { sharedCheckHaveMinMaintainabilityIndex } from '../shared/sharedCheckHaveMinMaintainabilityIndex';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveMinMaintainabilityIndex(\n locator: FunctionLocatorData,\n min: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMinMaintainabilityIndex(\n locator.functions,\n (f) => f.name,\n (f) => f.maintainability_index || 100,\n 'Function',\n min,\n isNot,\n );\n}\n","import { sharedCheckHaveModifier } from '../shared/sharedCheckHaveModifier';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveModifier(\n locator: FunctionLocatorData,\n modifierStr: string,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveModifier(\n locator.functions,\n (f) => f.name,\n 'Function',\n modifierStr,\n isNot,\n );\n}\n","import { sharedCheckHaveNameMatchingFileName } from '../shared/sharedCheckHaveNameMatchingFileName';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveNameMatchingFileName(\n locator: FunctionLocatorData,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveNameMatchingFileName(\n locator.functions,\n (f) => f.name,\n 'Function',\n isNot,\n );\n}\n","import { sharedCheckMatchNamePattern } from '../shared/sharedCheckMatchNamePattern';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckMatchNamePattern(\n locator: FunctionLocatorData,\n pattern: string | RegExp,\n isNot: boolean,\n): RuleResult {\n return sharedCheckMatchNamePattern(\n locator.functions,\n (f) => f.name,\n 'Function',\n pattern,\n isNot,\n );\n}\n","import type { FunctionData, ProjectData } from '../dto';\nimport type { FunctionLocatorData, FunctionQueryOptions } from './types';\n\nexport function locateFunctions(\n functions: (FunctionData & { _filePath: string })[],\n projectData: ProjectData,\n options?: FunctionQueryOptions,\n): FunctionLocatorData {\n let filtered = functions;\n\n if (options?.inFolder) {\n filtered = filtered.filter((f) => {\n return (\n f._filePath.includes(`/${options.inFolder}/`) ||\n f._filePath.includes(`\\\\${options.inFolder}\\\\`)\n );\n });\n }\n\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((f) => {\n return f.name && regex.test(f.name);\n });\n }\n\n if (options?.isTopLevel) {\n filtered = filtered.filter((f) => f.is_top_level);\n }\n\n return {\n type: 'FunctionLocator',\n functions: filtered,\n projectData,\n };\n}\n","import type { RuleResult } from '../types';\nimport type { LayeredArchitectureData } from './types';\n\nexport function checkLayeredArchitecture(\n data: LayeredArchitectureData,\n): RuleResult {\n const violations: string[] = [];\n for (const assertion of data.assertions) {\n violations.push(...assertion(data.files));\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { FileData, ProjectData } from '../dto';\nimport type { LayeredArchitectureData } from './types';\n\nexport function createLayeredArchitecture(\n files: FileData[],\n projectData: ProjectData,\n): LayeredArchitectureData {\n return {\n type: 'LayeredArchitecture',\n files,\n layers: new Map<string, string>(),\n assertions: [],\n projectData,\n };\n}\n","import type { LayeredArchitectureData } from './types';\n\nexport function layer(\n data: LayeredArchitectureData,\n name: string,\n folderPattern: string,\n): LayeredArchitectureData {\n data.layers.set(name, folderPattern);\n return data;\n}\n","import type { FileData, ProjectData } from '../dto';\n\nexport function getLayerDependencies(\n sourceFile: FileData,\n projectData: ProjectData,\n): string[] {\n return sourceFile.dependencies || [];\n}\n","import { getLayerDependencies } from './getLayerDependencies';\nimport type { LayeredArchitectureData } from './types';\n\nexport function layerShouldNotBeAccessedByAnyLayer(\n data: LayeredArchitectureData,\n targetLayer: string,\n): LayeredArchitectureData {\n if (!data.layers.has(targetLayer)) {\n throw new Error(`Layer ${targetLayer} is not defined`);\n }\n\n data.assertions.push((files) => {\n const violations: string[] = [];\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const targetPattern = data.layers.get(targetLayer)!;\n\n for (const file of files) {\n const filePath = file.path;\n if (\n !filePath.includes(`/${targetPattern}/`) &&\n !filePath.includes(`\\\\${targetPattern}\\\\`)\n ) {\n const dependencies = getLayerDependencies(file, data.projectData);\n const importsTarget = dependencies.some(\n (dep) =>\n dep.includes(`/${targetPattern}/`) ||\n dep.includes(`\\\\${targetPattern}\\\\`),\n );\n if (importsTarget) {\n violations.push(\n `File ${filePath} accesses layer ${targetLayer} but it shouldn't.`,\n );\n }\n }\n }\n return violations;\n });\n\n return data;\n}\n","import { getLayerDependencies } from './getLayerDependencies';\nimport type { LayeredArchitectureData } from './types';\n\nexport function layerShouldOnlyBeAccessedBy(\n data: LayeredArchitectureData,\n targetLayer: string,\n allowedLayers: string[],\n): LayeredArchitectureData {\n if (!data.layers.has(targetLayer)) {\n throw new Error(`Layer ${targetLayer} is not defined`);\n }\n\n data.assertions.push((files) => {\n const violations: string[] = [];\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const targetPattern = data.layers.get(targetLayer)!;\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const allowedPatterns = allowedLayers.map((l) => data.layers.get(l)!);\n\n for (const file of files) {\n const filePath = file.path;\n const isInAllowedLayer = allowedPatterns.some(\n (p) => filePath.includes(`/${p}/`) || filePath.includes(`\\\\${p}\\\\`),\n );\n\n if (\n !filePath.includes(`/${targetPattern}/`) &&\n !filePath.includes(`\\\\${targetPattern}\\\\`) &&\n !isInAllowedLayer\n ) {\n const dependencies = getLayerDependencies(file, data.projectData);\n const importsTarget = dependencies.some(\n (dep) =>\n dep.includes(`/${targetPattern}/`) ||\n dep.includes(`\\\\${targetPattern}\\\\`),\n );\n if (importsTarget) {\n violations.push(\n `File ${filePath} accesses layer ${targetLayer} but only ${allowedLayers.join(', ')} are allowed.`,\n );\n }\n }\n }\n return violations;\n });\n\n return data;\n}\n","import type { ProjectData, PropertyData } from '../dto';\nimport type { PropertyLocatorData, PropertyQueryOptions } from './types';\n\nexport function locateProperties(\n properties: (PropertyData & { _filePath: string })[],\n projectData: ProjectData,\n options?: PropertyQueryOptions,\n): PropertyLocatorData {\n let filtered = properties;\n\n if (options?.inFolder) {\n filtered = filtered.filter((p) => {\n return (\n p._filePath.includes(`/${options.inFolder}/`) ||\n p._filePath.includes(`\\\\${options.inFolder}\\\\`)\n );\n });\n }\n\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((p) => {\n return regex.test(p.name);\n });\n }\n\n return {\n type: 'PropertyLocator',\n properties: filtered,\n projectData,\n };\n}\n","import type { FileData, ProjectData } from '../dto';\nimport type { SliceLocatorData } from './types';\n\nexport function locateSlices(\n sourceFiles: FileData[],\n projectData: ProjectData,\n pattern: string,\n): SliceLocatorData {\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regexStr = escaped.replace(/\\*/g, '([^/\\\\\\\\]+)');\n const slicePattern = new RegExp(regexStr);\n\n const sliceIds = new Set<string>();\n const sliceFiles = new Map<string, FileData[]>();\n\n for (const sf of sourceFiles) {\n const match = sf.path.match(slicePattern);\n if (match?.[1]) {\n const sliceId = match[1];\n sliceIds.add(sliceId);\n if (!sliceFiles.has(sliceId)) {\n sliceFiles.set(sliceId, []);\n }\n sliceFiles.get(sliceId)?.push(sf);\n }\n }\n\n return {\n type: 'SliceLocator',\n slicePattern,\n sliceIds,\n sliceFiles,\n projectData,\n };\n}\n","import { dirname } from 'node:path';\nimport { ArchestProject } from '@archest/core-rust';\nimport * as ts from 'typescript';\nimport { locateClasses } from '../classes/locateClasses';\nimport type { ClassQueryOptions } from '../classes/types';\nimport type { ProjectData } from '../dto';\nimport { locateFiles } from '../files/locateFiles';\nimport type { FileQueryOptions } from '../files/types';\nimport { locateFunctions } from '../functions/locateFunctions';\nimport type { FunctionQueryOptions } from '../functions/types';\nimport { checkLayeredArchitecture } from '../layers/checkLayeredArchitecture';\nimport { createLayeredArchitecture } from '../layers/createLayeredArchitecture';\nimport { layer } from '../layers/layer';\nimport { layerShouldNotBeAccessedByAnyLayer } from '../layers/layerShouldNotBeAccessedByAnyLayer';\nimport { layerShouldOnlyBeAccessedBy } from '../layers/layerShouldOnlyBeAccessedBy';\nimport { locateProperties } from '../properties/locateProperties';\nimport type { PropertyQueryOptions } from '../properties/types';\nimport { locateSlices } from '../slices/locateSlices';\n\n/**\n * Options to configure how the project is parsed and analyzed.\n */\nexport interface ParseProjectOptions {\n /**\n * An optional absolute path to a specific tsconfig.json file.\n * If omitted, Archest will attempt to find the nearest tsconfig.json in the current working directory.\n */\n tsConfigFilePath?: string;\n /** An array of glob patterns specifying which files to include in the AST parsing. Overrides the tsconfig.json `include` array. */\n include?: string[];\n /** An array of glob patterns specifying which files to exclude from the AST parsing. Overrides the tsconfig.json `exclude` array. */\n exclude?: string[];\n}\n\n/**\n * The primary entry point for Archest. Parses a TypeScript or JavaScript project into a searchable\n * Abstract Syntax Tree (AST) using the high-performance native Rust engine.\n *\n * @param options - Optional configuration for locating the tsconfig and filtering files.\n * @returns A fluent API object containing Locators used to query the project's architecture.\n *\n * @example\n * ```typescript\n * import { parseProject } from '@archest/vitest';\n *\n * const project = parseProject({\n * include: ['src/domain/**\\/*.ts'],\n * exclude: ['**\\/*.test.ts']\n * });\n *\n * const domainFiles = project.getFiles();\n * ```\n */\nexport function parseProject(options: ParseProjectOptions = {}) {\n const configPath =\n options.tsConfigFilePath ||\n ts.findConfigFile(process.cwd(), ts.sys.fileExists, 'tsconfig.json');\n\n if (!configPath) {\n throw new Error('Could not find tsconfig.json');\n }\n\n const projectDir = dirname(configPath);\n\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile);\n if (options.include) configFile.config.include = options.include;\n if (options.exclude) configFile.config.exclude = options.exclude;\n\n const parsedCommandLine = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n projectDir,\n undefined,\n configPath,\n undefined,\n [\n {\n extension: '.vue',\n isMixedContent: true,\n scriptKind: ts.ScriptKind.TS,\n },\n {\n extension: '.svelte',\n isMixedContent: true,\n scriptKind: ts.ScriptKind.TS,\n },\n ],\n );\n\n const archestProject = ArchestProject.parse(parsedCommandLine.fileNames);\n const projectData: ProjectData = JSON.parse(archestProject.getProjectData());\n\n return {\n projectData,\n getFiles: (queryOptions?: FileQueryOptions) => {\n return locateFiles(\n projectData.files,\n projectData,\n archestProject,\n queryOptions,\n );\n },\n\n getClasses: (queryOptions?: ClassQueryOptions) => {\n const allClasses = projectData.files.flatMap((f) =>\n f.classes.map((c) => ({ ...c, _filePath: f.path })),\n );\n return locateClasses(allClasses, projectData, queryOptions);\n },\n\n layeredArchitecture: () => {\n let data = createLayeredArchitecture(projectData.files, projectData);\n const api = {\n layer: (name: string, folderPattern: string) => {\n data = layer(data, name, folderPattern);\n return api;\n },\n whereLayer: (name: string) => {\n return {\n shouldNotBeAccessedByAnyLayer: () => {\n data = layerShouldNotBeAccessedByAnyLayer(data, name);\n return api;\n },\n shouldOnlyBeAccessedBy: (...allowedLayers: string[]) => {\n data = layerShouldOnlyBeAccessedBy(data, name, allowedLayers);\n return api;\n },\n };\n },\n check: () => checkLayeredArchitecture(data),\n get data() {\n return data;\n },\n };\n return api;\n },\n\n getFunctions: (queryOptions?: FunctionQueryOptions) => {\n const allFunctions = projectData.files.flatMap((f) =>\n f.functions.map((fn) => ({ ...fn, _filePath: f.path })),\n );\n return locateFunctions(allFunctions, projectData, queryOptions);\n },\n\n getProperties: (queryOptions?: PropertyQueryOptions) => {\n const allProperties = projectData.files.flatMap((f) =>\n f.properties.map((p) => ({ ...p, _filePath: f.path })),\n );\n return locateProperties(allProperties, projectData, queryOptions);\n },\n\n getSlices: (pattern: string) => {\n return locateSlices(projectData.files, projectData, pattern);\n },\n };\n}\n","import type { RuleResult } from '../types';\nimport type { PropertyLocatorData } from './types';\n\nexport function propertyCheckBeReadonly(\n locator: PropertyLocatorData,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const p of locator.properties) {\n const name = p.name || 'Anonymous Property';\n const matches = p.is_readonly;\n\n if (isNot && matches) {\n violations.push(`Property ${name} is readonly, but it shouldn't be.`);\n } else if (!isNot && !matches) {\n violations.push(`Property ${name} is not readonly, but it should be.`);\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { RuleResult } from '../types';\nimport type { SliceLocatorData } from './types';\n\nexport function sliceCheckBeFreeOfCycles(\n locator: SliceLocatorData,\n isNot: boolean,\n): RuleResult {\n const graph: Map<string, Set<string>> = new Map();\n for (const slice of locator.sliceIds) {\n graph.set(slice, new Set());\n }\n\n for (const [sliceId, files] of locator.sliceFiles.entries()) {\n for (const sf of files) {\n if (!sf.dependencies) continue;\n for (const importPath of sf.dependencies) {\n const targetMatch = importPath.match(locator.slicePattern);\n if (targetMatch?.[1]) {\n const targetSlice = targetMatch[1];\n if (targetSlice !== sliceId && locator.sliceIds.has(targetSlice)) {\n graph.get(sliceId)?.add(targetSlice);\n }\n }\n }\n }\n }\n\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const violations: string[] = [];\n\n const dfs = (node: string, path: string[]): boolean => {\n visited.add(node);\n recursionStack.add(node);\n\n for (const neighbor of graph.get(node) || []) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor, [...path, neighbor])) return true;\n } else if (recursionStack.has(neighbor)) {\n violations.push(\n `Cycle detected between slices: ${path.join(' -> ')} -> ${neighbor}`,\n );\n return true;\n }\n }\n\n recursionStack.delete(node);\n return false;\n };\n\n for (const slice of locator.sliceIds) {\n if (!visited.has(slice)) {\n dfs(slice, [slice]);\n }\n }\n\n if (isNot) {\n return {\n pass: violations.length > 0,\n message: () =>\n violations.length > 0\n ? ''\n : 'Expected cycles between slices but found none.',\n };\n } else {\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n }\n}\n","import type { RuleResult } from '../types';\nimport type { SliceLocatorData } from './types';\n\nexport function sliceCheckHaveMaxDistanceFromMainSequence(\n locator: SliceLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n\n const ceMap = new Map<string, Set<string>>(); // Slices this slice depends on\n const caMap = new Map<string, Set<string>>(); // Slices depending on this slice\n\n for (const slice of locator.sliceIds) {\n ceMap.set(slice, new Set());\n caMap.set(slice, new Set());\n }\n\n for (const [sliceId, files] of locator.sliceFiles.entries()) {\n for (const sf of files) {\n if (!sf.dependencies) continue;\n for (const importPath of sf.dependencies) {\n const targetMatch = importPath.match(locator.slicePattern);\n if (targetMatch?.[1]) {\n const targetSlice = targetMatch[1];\n if (targetSlice !== sliceId && locator.sliceIds.has(targetSlice)) {\n ceMap.get(sliceId)?.add(targetSlice);\n caMap.get(targetSlice)?.add(sliceId);\n }\n }\n }\n }\n }\n\n for (const sliceId of locator.sliceIds) {\n const ce = ceMap.get(sliceId)?.size || 0;\n const ca = caMap.get(sliceId)?.size || 0;\n\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const files = locator.sliceFiles.get(sliceId)!;\n let na = 0; // abstract classes + interfaces\n let nc = 0; // all classes + interfaces\n\n for (const sf of files) {\n for (const c of sf.classes) {\n nc++;\n if (c.is_abstract) {\n na++;\n }\n }\n }\n\n const I = ce + ca === 0 ? 0 : ce / (ca + ce);\n const A = nc === 0 ? 0 : na / nc;\n\n const D = Math.abs(A + I - 1);\n const exceeds = D > max;\n\n if (isNot && exceeds) {\n violations.push(\n `Slice ${sliceId} has a Distance from the Main Sequence of ${D.toFixed(2)}, which exceeds the maximum of ${max}, but it shouldn't.`,\n );\n } else if (!isNot && exceeds) {\n violations.push(\n `Slice ${sliceId} has a Distance from the Main Sequence of ${D.toFixed(2)}, which exceeds the maximum of ${max}.`,\n );\n }\n }\n\n return {\n pass: isNot ? violations.length > 0 : violations.length === 0,\n message: () =>\n violations.join('\\n') ||\n (isNot\n ? 'Expected some slices to exceed maximum distance from main sequence, but none did.'\n : ''),\n };\n}\n","import { ArchestProject } from '@archest/core-rust';\nimport * as ts from 'typescript';\n\nimport type {\n ClassData,\n FileData,\n FunctionData,\n ProjectData,\n PropertyData,\n} from './dto';\n\nexport function createSourceFile(\n code: string,\n fileName = 'test.ts',\n): ts.SourceFile {\n return ts.createSourceFile(fileName, code, ts.ScriptTarget.Latest, true);\n}\n\nexport function createMockProgram(sourceFiles: ts.SourceFile[]): ProjectData {\n return {\n files: sourceFiles.map((sf) => ({\n path: sf.fileName,\n classes: getClasses(sf),\n functions: getFunctions(sf),\n properties: getProperties(sf),\n })),\n };\n}\n\nexport function createMockArchestProject(\n projectData: ProjectData,\n): ArchestProject {\n return ArchestProject.parseMock(JSON.stringify(projectData));\n}\n\nexport function getClasses(\n sourceFile: ts.SourceFile,\n): (ClassData & { _filePath: string })[] {\n const classes: (ClassData & { _filePath: string })[] = [];\n ts.forEachChild(sourceFile, (node) => {\n if (ts.isClassDeclaration(node)) {\n let extendsName: string | null = null;\n const implementsNames: string[] = [];\n if (node.heritageClauses) {\n for (const clause of node.heritageClauses) {\n if (clause.token === ts.SyntaxKind.ExtendsKeyword) {\n for (const t of clause.types) {\n if (ts.isIdentifier(t.expression))\n extendsName = t.expression.text;\n }\n }\n if (clause.token === ts.SyntaxKind.ImplementsKeyword) {\n for (const t of clause.types) {\n if (ts.isIdentifier(t.expression))\n implementsNames.push(t.expression.text);\n }\n }\n }\n }\n\n const decorators: string[] = [];\n if (ts.canHaveDecorators(node)) {\n const decs = ts.getDecorators(node);\n if (decs) {\n for (const d of decs) {\n if (ts.isIdentifier(d.expression))\n decorators.push(d.expression.text);\n else if (\n ts.isCallExpression(d.expression) &&\n ts.isIdentifier(d.expression.expression)\n )\n decorators.push(d.expression.expression.text);\n }\n }\n }\n\n classes.push({\n name: node.name?.text || null,\n is_exported: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) || false\n : false,\n is_default: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword) || false\n : false,\n is_abstract: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.AbstractKeyword) || false\n : false,\n extends: extendsName,\n implements: implementsNames,\n decorators,\n _filePath: sourceFile.fileName,\n });\n }\n });\n return classes;\n}\n\nexport function getFunctions(\n sourceFile: ts.SourceFile,\n): (FunctionData & { _filePath: string })[] {\n const functions: (FunctionData & { _filePath: string })[] = [];\n ts.forEachChild(sourceFile, (node) => {\n if (\n ts.isFunctionDeclaration(node) ||\n ts.isMethodDeclaration(node) ||\n ts.isArrowFunction(node)\n ) {\n let name: string | null = null;\n if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) {\n name = node.name?.getText() || null;\n }\n\n functions.push({\n name,\n is_exported: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) || false\n : false,\n is_async: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) || false\n : false,\n is_top_level: true,\n has_explicit_return_type: !!(node as any).type,\n _filePath: sourceFile.fileName,\n });\n }\n });\n return functions;\n}\n\nexport function getProperties(\n sourceFile: ts.SourceFile,\n): (PropertyData & { _filePath: string })[] {\n const properties: (PropertyData & { _filePath: string })[] = [];\n ts.forEachChild(sourceFile, (node) => {\n if (ts.isClassDeclaration(node)) {\n node.members.forEach((member) => {\n if (ts.isPropertyDeclaration(member)) {\n properties.push({\n name: member.name.getText(),\n is_readonly: ts.canHaveModifiers(member)\n ? ts\n .getModifiers(member)\n ?.some((m) => m.kind === ts.SyntaxKind.ReadonlyKeyword) ||\n false\n : false,\n _filePath: sourceFile.fileName,\n });\n }\n });\n }\n });\n return properties;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/classes/classCheckExtendClass.ts","../src/utils/ruleBuilder.ts","../src/shared/sharedCheckHaveMaxCyclomaticComplexity.ts","../src/classes/classCheckHaveMaxCyclomaticComplexity.ts","../src/shared/sharedCheckHaveModifier.ts","../src/classes/classCheckHaveModifier.ts","../src/shared/sharedCheckHaveNameMatchingFileName.ts","../src/classes/classCheckHaveNameMatchingFileName.ts","../src/classes/classCheckImplementInterface.ts","../src/shared/sharedCheckMatchNamePattern.ts","../src/classes/classCheckMatchNamePattern.ts","../src/classes/classCheckResideInFolder.ts","../src/classes/locateClasses.ts","../src/files/checkDependOnExternalModule.ts","../src/files/getFileDependencies.ts","../src/files/checkDependOnFilesInFolder.ts","../src/files/fileCheckBeFreeOfCycles.ts","../src/files/fileCheckHaveMaxCyclomaticComplexity.ts","../src/files/fileCheckHaveMaxExportedFunctions.ts","../src/shared/sharedCheckHaveMinMaintainabilityIndex.ts","../src/files/fileCheckHaveMinMaintainabilityIndex.ts","../src/files/fileCheckMatchNamePattern.ts","../src/files/locateFiles.ts","../src/functions/functionCheckHaveExplicitReturnType.ts","../src/functions/functionCheckHaveMaxCyclomaticComplexity.ts","../src/functions/functionCheckHaveMinMaintainabilityIndex.ts","../src/functions/functionCheckHaveModifier.ts","../src/functions/functionCheckHaveNameMatchingFileName.ts","../src/functions/functionCheckMatchNamePattern.ts","../src/functions/locateFunctions.ts","../src/layers/checkLayeredArchitecture.ts","../src/layers/createLayeredArchitecture.ts","../src/layers/layer.ts","../src/layers/getLayerDependencies.ts","../src/layers/layerShouldNotBeAccessedByAnyLayer.ts","../src/layers/layerShouldOnlyBeAccessedBy.ts","../src/properties/locateProperties.ts","../src/slices/locateSlices.ts","../src/project/parseProject.ts","../src/properties/propertyCheckBeReadonly.ts","../src/slices/sliceCheckBeFreeOfCycles.ts","../src/slices/sliceCheckHaveMaxDistanceFromMainSequence.ts","../src/testUtils.ts"],"sourcesContent":["import type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckExtendClass(\n locator: ClassLocatorData,\n className: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const c of locator.classes) {\n const name = c.name || 'Anonymous';\n let matches = false;\n if (c.extends === className) {\n matches = true;\n }\n if (isNot && matches) {\n violations.push(`Class ${name} extends ${className}, but it shouldn't.`);\n } else if (!isNot && !matches) {\n violations.push(\n `Class ${name} does not extend ${className}, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { RuleResult } from '../types';\n\nexport function ruleBuilder<T>(\n items: T[],\n isNot: boolean,\n evaluate: (item: T) => {\n passes: boolean;\n failMessage: string;\n failNotMessage: string;\n },\n): RuleResult {\n const violations: string[] = [];\n\n for (const item of items) {\n const { passes, failMessage, failNotMessage } = evaluate(item);\n\n if (isNot && passes) {\n if (failNotMessage) violations.push(failNotMessage);\n } else if (!isNot && !passes) {\n if (failMessage) violations.push(failMessage);\n }\n }\n\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveMaxCyclomaticComplexity<T>(\n items: T[],\n getName: (item: T) => string | undefined | null,\n getComplexity: (item: T) => number,\n label: string,\n max: number,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n const complexity = getComplexity(item);\n const exceeds = complexity > max;\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes: !exceeds,\n failMessage: `${desc} has a total cyclomatic complexity of ${complexity}, which exceeds the maximum of ${max}.`,\n failNotMessage: `${desc} has a total cyclomatic complexity of ${complexity}, which exceeds the maximum of ${max}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveMaxCyclomaticComplexity } from '../shared/sharedCheckHaveMaxCyclomaticComplexity';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckHaveMaxCyclomaticComplexity(\n locator: ClassLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMaxCyclomaticComplexity(\n locator.classes,\n (c) => c.name,\n (c) => c.cyclomatic_complexity || 0,\n 'Class',\n max,\n isNot,\n );\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveModifier<\n T extends {\n is_exported?: boolean;\n is_default?: boolean;\n is_abstract?: boolean;\n is_async?: boolean;\n is_readonly?: boolean;\n },\n>(\n items: T[],\n getName: (item: T) => string | null | undefined,\n label: string,\n modifierStr: string,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n let passes = false;\n switch (modifierStr) {\n case 'export':\n passes = !!item.is_exported;\n break;\n case 'default':\n passes = !!item.is_default;\n break;\n case 'abstract':\n passes = !!item.is_abstract;\n break;\n case 'async':\n passes = !!item.is_async;\n break;\n case 'readonly':\n passes = !!item.is_readonly;\n break;\n default:\n throw new Error(`Modifier ${modifierStr} is not fully supported.`);\n }\n\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes,\n failMessage: `${desc} does not have modifier ${modifierStr}, but it should.`,\n failNotMessage: `${desc} has modifier ${modifierStr}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveModifier } from '../shared/sharedCheckHaveModifier';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckHaveModifier(\n locator: ClassLocatorData,\n modifierStr: string,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveModifier(\n locator.classes,\n (c) => c.name,\n 'Class',\n modifierStr,\n isNot,\n );\n}\n","import * as path from 'node:path';\nimport { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveNameMatchingFileName<\n T extends { _filePath: string },\n>(\n items: T[],\n getName: (item: T) => string | null | undefined,\n label: string,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n\n if (!item._filePath) {\n return { passes: true, failMessage: '', failNotMessage: '' };\n }\n\n const basename = path.basename(\n item._filePath,\n path.extname(item._filePath),\n );\n const passes = name === basename;\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes,\n failMessage: `${desc} does not have a name matching its filename ${basename}, but it should.`,\n failNotMessage: `${desc} has a name matching its filename ${basename}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveNameMatchingFileName } from '../shared/sharedCheckHaveNameMatchingFileName';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckHaveNameMatchingFileName(\n locator: ClassLocatorData,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveNameMatchingFileName(\n locator.classes,\n (c) => c.name,\n 'Class',\n isNot,\n );\n}\n","import type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckImplementInterface(\n locator: ClassLocatorData,\n interfaceName: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const c of locator.classes) {\n const name = c.name || 'Anonymous';\n let matches = false;\n if (c.implements.includes(interfaceName)) {\n matches = true;\n }\n if (isNot && matches) {\n violations.push(\n `Class ${name} implements ${interfaceName}, but it shouldn't.`,\n );\n } else if (!isNot && !matches) {\n violations.push(\n `Class ${name} does not implement ${interfaceName}, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckMatchNamePattern<T>(\n items: T[],\n getName: (item: T) => string | undefined | null,\n label: string,\n pattern: string | RegExp,\n isNot: boolean,\n) {\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n const passes = name ? regex.test(name) : false;\n const desc = `${label} ${name || 'Anonymous'}`;\n return {\n passes,\n failMessage: `${desc} does not match pattern ${pattern}, but it should.`,\n failNotMessage: `${desc} matches pattern ${pattern}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckMatchNamePattern } from '../shared/sharedCheckMatchNamePattern';\nimport type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckMatchNamePattern(\n locator: ClassLocatorData,\n pattern: string | RegExp,\n isNot: boolean,\n): RuleResult {\n return sharedCheckMatchNamePattern(\n locator.classes,\n (c) => c.name,\n 'Class',\n pattern,\n isNot,\n );\n}\n","import type { RuleResult } from '../types';\nimport type { ClassLocatorData } from './types';\n\nexport function classCheckResideInFolder(\n locator: ClassLocatorData,\n targetFolder: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const c of locator.classes) {\n const className = c.name || 'Anonymous Class';\n const filePath = c._filePath;\n const inTargetFolder =\n filePath.includes(`/${targetFolder}/`) ||\n filePath.includes(`\\\\${targetFolder}\\\\`);\n\n if (isNot && inTargetFolder) {\n violations.push(\n `Class ${className} resides in ${targetFolder}, but it shouldn't.`,\n );\n } else if (!isNot && !inTargetFolder) {\n violations.push(\n `Class ${className} does not reside in ${targetFolder}, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { ClassData, ProjectData } from '../dto';\nimport type { ClassLocatorData, ClassQueryOptions } from './types';\n\nexport function locateClasses(\n classes: (ClassData & { _filePath: string })[],\n projectData: ProjectData,\n options?: ClassQueryOptions,\n): ClassLocatorData {\n let filtered = classes;\n\n if (options?.inFolder) {\n filtered = filtered.filter((c) => {\n return (\n c._filePath.includes(`/${options.inFolder}/`) ||\n c._filePath.includes(`\\\\${options.inFolder}\\\\`)\n );\n });\n }\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((c) => {\n return c.name && regex.test(c.name);\n });\n }\n if (options?.withDecorator) {\n const decorator = options.withDecorator;\n filtered = filtered.filter((c) => {\n return c.decorators.includes(decorator);\n });\n }\n if (options?.extending) {\n filtered = filtered.filter((c) => {\n return c.extends === options.extending;\n });\n }\n if (options?.implementing) {\n const implementing = options.implementing;\n filtered = filtered.filter((c) => {\n return c.implements.includes(implementing);\n });\n }\n if (options?.havingModifier) {\n filtered = filtered.filter((c) => {\n switch (options.havingModifier) {\n case 'export':\n return c.is_exported;\n case 'default':\n return c.is_default;\n case 'abstract':\n return c.is_abstract;\n default:\n throw new Error(\n `Modifier ${options.havingModifier} is not fully supported.`,\n );\n }\n });\n }\n\n return {\n type: 'ClassLocator',\n classes: filtered,\n projectData,\n };\n}\n","import type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function checkDependOnExternalModule(\n locator: FileLocatorData,\n moduleName: string | RegExp,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n\n const regex =\n typeof moduleName === 'string' ? new RegExp(moduleName) : moduleName;\n\n for (const file of locator.files) {\n const deps = file.external_dependencies || [];\n const dependsOnModule = deps.some((dep) => regex.test(dep));\n\n if (isNot && dependsOnModule) {\n violations.push(\n `${file.path} incorrectly depends on external module '${moduleName}'`,\n );\n } else if (!isNot && !dependsOnModule) {\n violations.push(\n `${file.path} does not depend on external module '${moduleName}'`,\n );\n }\n }\n\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { FileData, ProjectData } from '../dto';\n\nexport function getFileDependencies(\n sourceFile: FileData,\n _projectData: ProjectData,\n): string[] {\n return sourceFile.dependencies || [];\n}\n","import type { RuleResult } from '../types';\nimport { getFileDependencies } from './getFileDependencies';\nimport type { FileLocatorData } from './types';\n\nexport function checkDependOnFilesInFolder(\n locator: FileLocatorData,\n targetFolder: string,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n\n for (const file of locator.files) {\n const dependencies = getFileDependencies(file, locator.projectData);\n\n const dependsOnTarget = dependencies.some(\n (depPath) =>\n depPath.includes(`/${targetFolder}/`) ||\n depPath.includes(`\\\\${targetFolder}\\\\`),\n );\n\n if (isNot && dependsOnTarget) {\n violations.push(\n `File ${file.path} depends on files in ${targetFolder}, but it shouldn't.`,\n );\n } else if (!isNot && !dependsOnTarget) {\n violations.push(\n `File ${file.path} does not depend on files in ${targetFolder}, but it should.`,\n );\n }\n }\n\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckBeFreeOfCycles(\n locator: FileLocatorData,\n isNot: boolean,\n): RuleResult {\n const targetFiles = locator.files.map((f) => f.path);\n\n const archestProject = locator.archestProject;\n if (!archestProject) {\n // Fallback for mocked tests or if registry is missing\n return {\n pass: true,\n message: () => 'Mock pass: archestProject not in registry',\n };\n }\n\n const result = archestProject.checkFileCycles(targetFiles, !!isNot);\n\n return {\n pass: result.pass,\n message: () => result.message,\n };\n}\n","import { sharedCheckHaveMaxCyclomaticComplexity } from '../shared/sharedCheckHaveMaxCyclomaticComplexity';\nimport type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckHaveMaxCyclomaticComplexity(\n locator: FileLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMaxCyclomaticComplexity(\n locator.files,\n (f) => f.path,\n (file) => {\n let complexity = 0;\n for (const func of file.functions) {\n complexity += func.cyclomatic_complexity || 0;\n }\n for (const cls of file.classes) {\n complexity += cls.cyclomatic_complexity || 0;\n }\n return complexity;\n },\n 'File',\n max,\n isNot,\n );\n}\n","import type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckHaveMaxExportedFunctions(\n locator: FileLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const file of locator.files) {\n const exportedFuncCount = file.functions.filter(\n (f) => f.is_exported,\n ).length;\n\n const exceeds = exportedFuncCount > max;\n\n if (isNot && exceeds) {\n violations.push(\n `File ${file.path} has ${exportedFuncCount} exported functions, which exceeds the maximum of ${max}, but it shouldn't.`,\n );\n } else if (!isNot && exceeds) {\n violations.push(\n `File ${file.path} has ${exportedFuncCount} exported functions, which exceeds the maximum of ${max}.`,\n );\n }\n }\n return {\n pass: isNot ? violations.length > 0 : violations.length === 0,\n message: () =>\n violations.join('\\n') ||\n (isNot\n ? 'Expected some files to exceed maximum exported functions, but none did.'\n : ''),\n };\n}\n","import { ruleBuilder } from '../utils/ruleBuilder';\n\nexport function sharedCheckHaveMinMaintainabilityIndex<T>(\n items: T[],\n getName: (item: T) => string | undefined | null,\n getMi: (item: T) => number,\n label: string,\n min: number,\n isNot: boolean,\n) {\n return ruleBuilder(items, isNot, (item) => {\n const name = getName(item);\n const mi = getMi(item);\n const fallsBelow = mi < min;\n const desc = `${label} ${name || 'Anonymous'}`;\n\n return {\n passes: !fallsBelow,\n failMessage: `${desc} has a maintainability index of ${mi.toFixed(2)}, which falls below the minimum of ${min}.`,\n failNotMessage: `${desc} has a maintainability index of ${mi.toFixed(2)}, which falls below the minimum of ${min}, but it shouldn't.`,\n };\n });\n}\n","import { sharedCheckHaveMinMaintainabilityIndex } from '../shared/sharedCheckHaveMinMaintainabilityIndex';\nimport type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckHaveMinMaintainabilityIndex(\n locator: FileLocatorData,\n min: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMinMaintainabilityIndex(\n locator.files,\n (f) => f.path,\n (file) => {\n if (file.functions.length > 0) {\n return file.functions[0].maintainability_index || 100;\n }\n return 100;\n },\n 'File',\n min,\n isNot,\n );\n}\n","import { sharedCheckMatchNamePattern } from '../shared/sharedCheckMatchNamePattern';\nimport type { RuleResult } from '../types';\nimport type { FileLocatorData } from './types';\n\nexport function fileCheckMatchNamePattern(\n locator: FileLocatorData,\n pattern: string | RegExp,\n isNot: boolean,\n): RuleResult {\n return sharedCheckMatchNamePattern(\n locator.files,\n (f) => f.path,\n 'File',\n pattern,\n isNot,\n );\n}\n","import type { ArchestProject } from '@archest/core-rust';\nimport type { FileData, ProjectData } from '../dto';\nimport type { FileLocatorData, FileQueryOptions } from './types';\n\nexport function locateFiles(\n sourceFiles: FileData[],\n projectData: ProjectData,\n archestProject?: ArchestProject,\n options?: FileQueryOptions,\n): FileLocatorData {\n let filtered = sourceFiles;\n\n if (options?.inFolder) {\n filtered = filtered.filter(\n (file) =>\n file.path.includes(`/${options.inFolder}/`) ||\n file.path.includes(`\\\\${options.inFolder}\\\\`),\n );\n }\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((file) => regex.test(file.path));\n }\n\n const result: FileLocatorData = {\n type: 'FileLocator',\n files: filtered,\n projectData,\n };\n\n if (archestProject) {\n Object.defineProperty(result, 'archestProject', {\n value: archestProject,\n enumerable: false,\n });\n }\n\n return result;\n}\n","import type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveExplicitReturnType(\n locator: FunctionLocatorData,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const f of locator.functions) {\n const name = f.name || 'Anonymous Function';\n const hasType = f.has_explicit_return_type;\n\n if (isNot && hasType) {\n violations.push(\n `Function ${name} has an explicit return type, but it shouldn't.`,\n );\n } else if (!isNot && !hasType) {\n violations.push(\n `Function ${name} does not have an explicit return type, but it should.`,\n );\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import { sharedCheckHaveMaxCyclomaticComplexity } from '../shared/sharedCheckHaveMaxCyclomaticComplexity';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveMaxCyclomaticComplexity(\n locator: FunctionLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMaxCyclomaticComplexity(\n locator.functions,\n (f) => f.name,\n (f) => f.cyclomatic_complexity || 0,\n 'Function',\n max,\n isNot,\n );\n}\n","import { sharedCheckHaveMinMaintainabilityIndex } from '../shared/sharedCheckHaveMinMaintainabilityIndex';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveMinMaintainabilityIndex(\n locator: FunctionLocatorData,\n min: number,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveMinMaintainabilityIndex(\n locator.functions,\n (f) => f.name,\n (f) => f.maintainability_index || 100,\n 'Function',\n min,\n isNot,\n );\n}\n","import { sharedCheckHaveModifier } from '../shared/sharedCheckHaveModifier';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveModifier(\n locator: FunctionLocatorData,\n modifierStr: string,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveModifier(\n locator.functions,\n (f) => f.name,\n 'Function',\n modifierStr,\n isNot,\n );\n}\n","import { sharedCheckHaveNameMatchingFileName } from '../shared/sharedCheckHaveNameMatchingFileName';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckHaveNameMatchingFileName(\n locator: FunctionLocatorData,\n isNot: boolean,\n): RuleResult {\n return sharedCheckHaveNameMatchingFileName(\n locator.functions,\n (f) => f.name,\n 'Function',\n isNot,\n );\n}\n","import { sharedCheckMatchNamePattern } from '../shared/sharedCheckMatchNamePattern';\nimport type { RuleResult } from '../types';\nimport type { FunctionLocatorData } from './types';\n\nexport function functionCheckMatchNamePattern(\n locator: FunctionLocatorData,\n pattern: string | RegExp,\n isNot: boolean,\n): RuleResult {\n return sharedCheckMatchNamePattern(\n locator.functions,\n (f) => f.name,\n 'Function',\n pattern,\n isNot,\n );\n}\n","import type { FunctionData, ProjectData } from '../dto';\nimport type { FunctionLocatorData, FunctionQueryOptions } from './types';\n\nexport function locateFunctions(\n functions: (FunctionData & { _filePath: string })[],\n projectData: ProjectData,\n options?: FunctionQueryOptions,\n): FunctionLocatorData {\n let filtered = functions;\n\n if (options?.inFolder) {\n filtered = filtered.filter((f) => {\n return (\n f._filePath.includes(`/${options.inFolder}/`) ||\n f._filePath.includes(`\\\\${options.inFolder}\\\\`)\n );\n });\n }\n\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((f) => {\n return f.name && regex.test(f.name);\n });\n }\n\n if (options?.isTopLevel) {\n filtered = filtered.filter((f) => f.is_top_level);\n }\n\n return {\n type: 'FunctionLocator',\n functions: filtered,\n projectData,\n };\n}\n","import type { RuleResult } from '../types';\nimport type { LayeredArchitectureData } from './types';\n\nexport function checkLayeredArchitecture(\n data: LayeredArchitectureData,\n): RuleResult {\n const violations: string[] = [];\n for (const assertion of data.assertions) {\n violations.push(...assertion(data.files));\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { FileData, ProjectData } from '../dto';\nimport type { LayeredArchitectureData } from './types';\n\nexport function createLayeredArchitecture(\n files: FileData[],\n projectData: ProjectData,\n): LayeredArchitectureData {\n return {\n type: 'LayeredArchitecture',\n files,\n layers: new Map<string, string>(),\n assertions: [],\n projectData,\n };\n}\n","import type { LayeredArchitectureData } from './types';\n\nexport function layer(\n data: LayeredArchitectureData,\n name: string,\n folderPattern: string,\n): LayeredArchitectureData {\n data.layers.set(name, folderPattern);\n return data;\n}\n","import type { FileData, ProjectData } from '../dto';\n\nexport function getLayerDependencies(\n sourceFile: FileData,\n _projectData: ProjectData,\n): string[] {\n return sourceFile.dependencies || [];\n}\n","import { getLayerDependencies } from './getLayerDependencies';\nimport type { LayeredArchitectureData } from './types';\n\nexport function layerShouldNotBeAccessedByAnyLayer(\n data: LayeredArchitectureData,\n targetLayer: string,\n): LayeredArchitectureData {\n if (!data.layers.has(targetLayer)) {\n throw new Error(`Layer ${targetLayer} is not defined`);\n }\n\n data.assertions.push((files) => {\n const violations: string[] = [];\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const targetPattern = data.layers.get(targetLayer)!;\n\n for (const file of files) {\n const filePath = file.path;\n if (\n !filePath.includes(`/${targetPattern}/`) &&\n !filePath.includes(`\\\\${targetPattern}\\\\`)\n ) {\n const dependencies = getLayerDependencies(file, data.projectData);\n const importsTarget = dependencies.some(\n (dep) =>\n dep.includes(`/${targetPattern}/`) ||\n dep.includes(`\\\\${targetPattern}\\\\`),\n );\n if (importsTarget) {\n violations.push(\n `File ${filePath} accesses layer ${targetLayer} but it shouldn't.`,\n );\n }\n }\n }\n return violations;\n });\n\n return data;\n}\n","import { getLayerDependencies } from './getLayerDependencies';\nimport type { LayeredArchitectureData } from './types';\n\nexport function layerShouldOnlyBeAccessedBy(\n data: LayeredArchitectureData,\n targetLayer: string,\n allowedLayers: string[],\n): LayeredArchitectureData {\n if (!data.layers.has(targetLayer)) {\n throw new Error(`Layer ${targetLayer} is not defined`);\n }\n\n data.assertions.push((files) => {\n const violations: string[] = [];\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const targetPattern = data.layers.get(targetLayer)!;\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const allowedPatterns = allowedLayers.map((l) => data.layers.get(l)!);\n\n for (const file of files) {\n const filePath = file.path;\n const isInAllowedLayer = allowedPatterns.some(\n (p) => filePath.includes(`/${p}/`) || filePath.includes(`\\\\${p}\\\\`),\n );\n\n if (\n !filePath.includes(`/${targetPattern}/`) &&\n !filePath.includes(`\\\\${targetPattern}\\\\`) &&\n !isInAllowedLayer\n ) {\n const dependencies = getLayerDependencies(file, data.projectData);\n const importsTarget = dependencies.some(\n (dep) =>\n dep.includes(`/${targetPattern}/`) ||\n dep.includes(`\\\\${targetPattern}\\\\`),\n );\n if (importsTarget) {\n violations.push(\n `File ${filePath} accesses layer ${targetLayer} but only ${allowedLayers.join(', ')} are allowed.`,\n );\n }\n }\n }\n return violations;\n });\n\n return data;\n}\n","import type { ProjectData, PropertyData } from '../dto';\nimport type { PropertyLocatorData, PropertyQueryOptions } from './types';\n\nexport function locateProperties(\n properties: (PropertyData & { _filePath: string })[],\n projectData: ProjectData,\n options?: PropertyQueryOptions,\n): PropertyLocatorData {\n let filtered = properties;\n\n if (options?.inFolder) {\n filtered = filtered.filter((p) => {\n return (\n p._filePath.includes(`/${options.inFolder}/`) ||\n p._filePath.includes(`\\\\${options.inFolder}\\\\`)\n );\n });\n }\n\n if (options?.matchNamePattern) {\n const regex =\n typeof options.matchNamePattern === 'string'\n ? new RegExp(options.matchNamePattern)\n : options.matchNamePattern;\n filtered = filtered.filter((p) => {\n return regex.test(p.name);\n });\n }\n\n return {\n type: 'PropertyLocator',\n properties: filtered,\n projectData,\n };\n}\n","import type { FileData, ProjectData } from '../dto';\nimport type { SliceLocatorData } from './types';\n\nexport function locateSlices(\n sourceFiles: FileData[],\n projectData: ProjectData,\n pattern: string,\n): SliceLocatorData {\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const regexStr = escaped.replace(/\\*/g, '([^/\\\\\\\\]+)');\n const slicePattern = new RegExp(regexStr);\n\n const sliceIds = new Set<string>();\n const sliceFiles = new Map<string, FileData[]>();\n\n for (const sf of sourceFiles) {\n const match = sf.path.match(slicePattern);\n if (match?.[1]) {\n const sliceId = match[1];\n sliceIds.add(sliceId);\n if (!sliceFiles.has(sliceId)) {\n sliceFiles.set(sliceId, []);\n }\n sliceFiles.get(sliceId)?.push(sf);\n }\n }\n\n return {\n type: 'SliceLocator',\n slicePattern,\n sliceIds,\n sliceFiles,\n projectData,\n };\n}\n","import { dirname } from 'node:path';\nimport { ArchestProject } from '@archest/core-rust';\nimport * as ts from 'typescript';\nimport { locateClasses } from '../classes/locateClasses';\nimport type { ClassQueryOptions } from '../classes/types';\nimport type { ProjectData } from '../dto';\nimport { locateFiles } from '../files/locateFiles';\nimport type { FileQueryOptions } from '../files/types';\nimport { locateFunctions } from '../functions/locateFunctions';\nimport type { FunctionQueryOptions } from '../functions/types';\nimport { checkLayeredArchitecture } from '../layers/checkLayeredArchitecture';\nimport { createLayeredArchitecture } from '../layers/createLayeredArchitecture';\nimport { layer } from '../layers/layer';\nimport { layerShouldNotBeAccessedByAnyLayer } from '../layers/layerShouldNotBeAccessedByAnyLayer';\nimport { layerShouldOnlyBeAccessedBy } from '../layers/layerShouldOnlyBeAccessedBy';\nimport { locateProperties } from '../properties/locateProperties';\nimport type { PropertyQueryOptions } from '../properties/types';\nimport { locateSlices } from '../slices/locateSlices';\n\n/**\n * Options to configure how the project is parsed and analyzed.\n */\nexport interface ParseProjectOptions {\n /**\n * An optional absolute path to a specific tsconfig.json file.\n * If omitted, Archest will attempt to find the nearest tsconfig.json in the current working directory.\n */\n tsConfigFilePath?: string;\n /** An array of glob patterns specifying which files to include in the AST parsing. Overrides the tsconfig.json `include` array. */\n include?: string[];\n /** An array of glob patterns specifying which files to exclude from the AST parsing. Overrides the tsconfig.json `exclude` array. */\n exclude?: string[];\n}\n\n/**\n * The primary entry point for Archest. Parses a TypeScript or JavaScript project into a searchable\n * Abstract Syntax Tree (AST) using the high-performance native Rust engine.\n *\n * @param options - Optional configuration for locating the tsconfig and filtering files.\n * @returns A fluent API object containing Locators used to query the project's architecture.\n *\n * @example\n * ```typescript\n * import { parseProject } from '@archest/vitest';\n *\n * const project = parseProject({\n * include: ['src/domain/**\\/*.ts'],\n * exclude: ['**\\/*.test.ts']\n * });\n *\n * const domainFiles = project.getFiles();\n * ```\n */\nexport function parseProject(options: ParseProjectOptions = {}) {\n const configPath =\n options.tsConfigFilePath ||\n ts.findConfigFile(process.cwd(), ts.sys.fileExists, 'tsconfig.json');\n\n if (!configPath) {\n throw new Error('Could not find tsconfig.json');\n }\n\n const projectDir = dirname(configPath);\n\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile);\n if (options.include) configFile.config.include = options.include;\n if (options.exclude) configFile.config.exclude = options.exclude;\n\n const parsedCommandLine = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n projectDir,\n undefined,\n configPath,\n undefined,\n [\n {\n extension: '.vue',\n isMixedContent: true,\n scriptKind: ts.ScriptKind.TS,\n },\n {\n extension: '.svelte',\n isMixedContent: true,\n scriptKind: ts.ScriptKind.TS,\n },\n ],\n );\n\n const archestProject = ArchestProject.parse(parsedCommandLine.fileNames);\n const projectData: ProjectData = JSON.parse(archestProject.getProjectData());\n\n return {\n projectData,\n getFiles: (queryOptions?: FileQueryOptions) => {\n return locateFiles(\n projectData.files,\n projectData,\n archestProject,\n queryOptions,\n );\n },\n\n getClasses: (queryOptions?: ClassQueryOptions) => {\n const allClasses = projectData.files.flatMap((f) =>\n f.classes.map((c) => ({ ...c, _filePath: f.path })),\n );\n return locateClasses(allClasses, projectData, queryOptions);\n },\n\n layeredArchitecture: () => {\n let data = createLayeredArchitecture(projectData.files, projectData);\n const api = {\n layer: (name: string, folderPattern: string) => {\n data = layer(data, name, folderPattern);\n return api;\n },\n whereLayer: (name: string) => {\n return {\n shouldNotBeAccessedByAnyLayer: () => {\n data = layerShouldNotBeAccessedByAnyLayer(data, name);\n return api;\n },\n shouldOnlyBeAccessedBy: (...allowedLayers: string[]) => {\n data = layerShouldOnlyBeAccessedBy(data, name, allowedLayers);\n return api;\n },\n };\n },\n check: () => checkLayeredArchitecture(data),\n get data() {\n return data;\n },\n };\n return api;\n },\n\n getFunctions: (queryOptions?: FunctionQueryOptions) => {\n const allFunctions = projectData.files.flatMap((f) =>\n f.functions.map((fn) => ({ ...fn, _filePath: f.path })),\n );\n return locateFunctions(allFunctions, projectData, queryOptions);\n },\n\n getProperties: (queryOptions?: PropertyQueryOptions) => {\n const allProperties = projectData.files.flatMap((f) =>\n f.properties.map((p) => ({ ...p, _filePath: f.path })),\n );\n return locateProperties(allProperties, projectData, queryOptions);\n },\n\n getSlices: (pattern: string) => {\n return locateSlices(projectData.files, projectData, pattern);\n },\n };\n}\n","import type { RuleResult } from '../types';\nimport type { PropertyLocatorData } from './types';\n\nexport function propertyCheckBeReadonly(\n locator: PropertyLocatorData,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n for (const p of locator.properties) {\n const name = p.name || 'Anonymous Property';\n const matches = p.is_readonly;\n\n if (isNot && matches) {\n violations.push(`Property ${name} is readonly, but it shouldn't be.`);\n } else if (!isNot && !matches) {\n violations.push(`Property ${name} is not readonly, but it should be.`);\n }\n }\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n}\n","import type { RuleResult } from '../types';\nimport type { SliceLocatorData } from './types';\n\nexport function sliceCheckBeFreeOfCycles(\n locator: SliceLocatorData,\n isNot: boolean,\n): RuleResult {\n const graph: Map<string, Set<string>> = new Map();\n for (const slice of locator.sliceIds) {\n graph.set(slice, new Set());\n }\n\n for (const [sliceId, files] of locator.sliceFiles.entries()) {\n for (const sf of files) {\n if (!sf.dependencies) continue;\n for (const importPath of sf.dependencies) {\n const targetMatch = importPath.match(locator.slicePattern);\n if (targetMatch?.[1]) {\n const targetSlice = targetMatch[1];\n if (targetSlice !== sliceId && locator.sliceIds.has(targetSlice)) {\n graph.get(sliceId)?.add(targetSlice);\n }\n }\n }\n }\n }\n\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const violations: string[] = [];\n\n const dfs = (node: string, path: string[]): boolean => {\n visited.add(node);\n recursionStack.add(node);\n\n for (const neighbor of graph.get(node) || []) {\n if (!visited.has(neighbor)) {\n if (dfs(neighbor, [...path, neighbor])) return true;\n } else if (recursionStack.has(neighbor)) {\n violations.push(\n `Cycle detected between slices: ${path.join(' -> ')} -> ${neighbor}`,\n );\n return true;\n }\n }\n\n recursionStack.delete(node);\n return false;\n };\n\n for (const slice of locator.sliceIds) {\n if (!visited.has(slice)) {\n dfs(slice, [slice]);\n }\n }\n\n if (isNot) {\n return {\n pass: violations.length > 0,\n message: () =>\n violations.length > 0\n ? ''\n : 'Expected cycles between slices but found none.',\n };\n } else {\n return {\n pass: violations.length === 0,\n message: () => violations.join('\\n'),\n };\n }\n}\n","import type { RuleResult } from '../types';\nimport type { SliceLocatorData } from './types';\n\nexport function sliceCheckHaveMaxDistanceFromMainSequence(\n locator: SliceLocatorData,\n max: number,\n isNot: boolean,\n): RuleResult {\n const violations: string[] = [];\n\n const ceMap = new Map<string, Set<string>>(); // Slices this slice depends on\n const caMap = new Map<string, Set<string>>(); // Slices depending on this slice\n\n for (const slice of locator.sliceIds) {\n ceMap.set(slice, new Set());\n caMap.set(slice, new Set());\n }\n\n for (const [sliceId, files] of locator.sliceFiles.entries()) {\n for (const sf of files) {\n if (!sf.dependencies) continue;\n for (const importPath of sf.dependencies) {\n const targetMatch = importPath.match(locator.slicePattern);\n if (targetMatch?.[1]) {\n const targetSlice = targetMatch[1];\n if (targetSlice !== sliceId && locator.sliceIds.has(targetSlice)) {\n ceMap.get(sliceId)?.add(targetSlice);\n caMap.get(targetSlice)?.add(sliceId);\n }\n }\n }\n }\n }\n\n for (const sliceId of locator.sliceIds) {\n const ce = ceMap.get(sliceId)?.size || 0;\n const ca = caMap.get(sliceId)?.size || 0;\n\n // biome-ignore lint/style/noNonNullAssertion: Safe map lookup\n const files = locator.sliceFiles.get(sliceId)!;\n let na = 0; // abstract classes + interfaces\n let nc = 0; // all classes + interfaces\n\n for (const sf of files) {\n for (const c of sf.classes) {\n nc++;\n if (c.is_abstract) {\n na++;\n }\n }\n }\n\n const I = ce + ca === 0 ? 0 : ce / (ca + ce);\n const A = nc === 0 ? 0 : na / nc;\n\n const D = Math.abs(A + I - 1);\n const exceeds = D > max;\n\n if (isNot && exceeds) {\n violations.push(\n `Slice ${sliceId} has a Distance from the Main Sequence of ${D.toFixed(2)}, which exceeds the maximum of ${max}, but it shouldn't.`,\n );\n } else if (!isNot && exceeds) {\n violations.push(\n `Slice ${sliceId} has a Distance from the Main Sequence of ${D.toFixed(2)}, which exceeds the maximum of ${max}.`,\n );\n }\n }\n\n return {\n pass: isNot ? violations.length > 0 : violations.length === 0,\n message: () =>\n violations.join('\\n') ||\n (isNot\n ? 'Expected some slices to exceed maximum distance from main sequence, but none did.'\n : ''),\n };\n}\n","import { ArchestProject } from '@archest/core-rust';\nimport * as ts from 'typescript';\n\nimport type { ClassData, FunctionData, ProjectData, PropertyData } from './dto';\n\nexport function createSourceFile(\n code: string,\n fileName = 'test.ts',\n): ts.SourceFile {\n return ts.createSourceFile(fileName, code, ts.ScriptTarget.Latest, true);\n}\n\nexport function createMockProgram(sourceFiles: ts.SourceFile[]): ProjectData {\n return {\n files: sourceFiles.map((sf) => ({\n path: sf.fileName,\n classes: getClasses(sf),\n functions: getFunctions(sf),\n properties: getProperties(sf),\n })),\n };\n}\n\nexport function createMockArchestProject(\n projectData: ProjectData,\n): ArchestProject {\n return ArchestProject.parseMock(JSON.stringify(projectData));\n}\n\nexport function getClasses(\n sourceFile: ts.SourceFile,\n): (ClassData & { _filePath: string })[] {\n const classes: (ClassData & { _filePath: string })[] = [];\n ts.forEachChild(sourceFile, (node) => {\n if (ts.isClassDeclaration(node)) {\n let extendsName: string | null = null;\n const implementsNames: string[] = [];\n if (node.heritageClauses) {\n for (const clause of node.heritageClauses) {\n if (clause.token === ts.SyntaxKind.ExtendsKeyword) {\n for (const t of clause.types) {\n if (ts.isIdentifier(t.expression))\n extendsName = t.expression.text;\n }\n }\n if (clause.token === ts.SyntaxKind.ImplementsKeyword) {\n for (const t of clause.types) {\n if (ts.isIdentifier(t.expression))\n implementsNames.push(t.expression.text);\n }\n }\n }\n }\n\n const decorators: string[] = [];\n if (ts.canHaveDecorators(node)) {\n const decs = ts.getDecorators(node);\n if (decs) {\n for (const d of decs) {\n if (ts.isIdentifier(d.expression))\n decorators.push(d.expression.text);\n else if (\n ts.isCallExpression(d.expression) &&\n ts.isIdentifier(d.expression.expression)\n )\n decorators.push(d.expression.expression.text);\n }\n }\n }\n\n classes.push({\n name: node.name?.text || null,\n is_exported: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) || false\n : false,\n is_default: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword) || false\n : false,\n is_abstract: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.AbstractKeyword) || false\n : false,\n extends: extendsName,\n implements: implementsNames,\n decorators,\n _filePath: sourceFile.fileName,\n });\n }\n });\n return classes;\n}\n\nexport function getFunctions(\n sourceFile: ts.SourceFile,\n): (FunctionData & { _filePath: string })[] {\n const functions: (FunctionData & { _filePath: string })[] = [];\n ts.forEachChild(sourceFile, (node) => {\n if (\n ts.isFunctionDeclaration(node) ||\n ts.isMethodDeclaration(node) ||\n ts.isArrowFunction(node)\n ) {\n let name: string | null = null;\n if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) {\n name = node.name?.getText() || null;\n }\n\n functions.push({\n name,\n is_exported: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) || false\n : false,\n is_async: ts.canHaveModifiers(node)\n ? ts\n .getModifiers(node)\n ?.some((m) => m.kind === ts.SyntaxKind.AsyncKeyword) || false\n : false,\n is_top_level: true,\n // biome-ignore lint/suspicious/noExplicitAny: Mocking typescript node types for tests\n has_explicit_return_type: !!(node as any).type,\n _filePath: sourceFile.fileName,\n });\n }\n });\n return functions;\n}\n\nexport function getProperties(\n sourceFile: ts.SourceFile,\n): (PropertyData & { _filePath: string })[] {\n const properties: (PropertyData & { _filePath: string })[] = [];\n ts.forEachChild(sourceFile, (node) => {\n if (ts.isClassDeclaration(node)) {\n node.members.forEach((member) => {\n if (ts.isPropertyDeclaration(member)) {\n properties.push({\n name: member.name.getText(),\n is_readonly: ts.canHaveModifiers(member)\n ? ts\n .getModifiers(member)\n ?.some((m) => m.kind === ts.SyntaxKind.ReadonlyKeyword) ||\n false\n : false,\n _filePath: sourceFile.fileName,\n });\n }\n });\n }\n });\n return properties;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
1
  import { FileData, ProjectData } from '../dto';
2
- export declare function getLayerDependencies(sourceFile: FileData, projectData: ProjectData): string[];
2
+ export declare function getLayerDependencies(sourceFile: FileData, _projectData: ProjectData): string[];
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archest/core",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/hinterdupfinger/archest.git"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archest/core-rust",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "private": true,
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archest/jest",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/hinterdupfinger/archest.git"
@@ -41,8 +41,8 @@
41
41
  "typescript": "^5.x || ^6.x"
42
42
  },
43
43
  "dependencies": {
44
- "@archest/core-rust": "1.0.0",
45
- "@archest/core": "1.0.1"
44
+ "@archest/core-rust": "1.0.2",
45
+ "@archest/core": "1.0.2"
46
46
  },
47
47
  "bundledDependencies": [
48
48
  "@archest/core",
@@ -50,7 +50,7 @@
50
50
  ],
51
51
  "scripts": {
52
52
  "build": "vite build",
53
- "test": "vitest run",
53
+ "test": "vitest run --passWithNoTests",
54
54
  "test:watch": "vitest"
55
55
  }
56
56
  }