@archest/vitest 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/dist/index.js +13 -17
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +776 -489
  4. package/dist/index.mjs.map +1 -1
  5. package/dist/src/core/classes/classCheckExtendClass.d.ts +3 -0
  6. package/dist/src/core/classes/classCheckHaveMaxCyclomaticComplexity.d.ts +3 -0
  7. package/dist/src/core/classes/classCheckHaveModifier.d.ts +3 -0
  8. package/dist/src/core/classes/classCheckHaveNameMatchingFileName.d.ts +3 -0
  9. package/dist/src/core/classes/classCheckImplementInterface.d.ts +3 -0
  10. package/dist/src/core/classes/classCheckMatchNamePattern.d.ts +3 -0
  11. package/dist/src/core/classes/classCheckResideInFolder.d.ts +3 -0
  12. package/dist/src/core/classes/locateClasses.d.ts +3 -0
  13. package/dist/src/core/classes/types.d.ts +14 -0
  14. package/dist/src/core/files/checkDependOnFilesInFolder.d.ts +3 -0
  15. package/dist/src/core/files/fileCheckBeFreeOfCycles.d.ts +3 -0
  16. package/dist/src/core/files/fileCheckHaveMaxCyclomaticComplexity.d.ts +3 -0
  17. package/dist/src/core/files/fileCheckHaveMaxExportedFunctions.d.ts +3 -0
  18. package/dist/src/core/files/fileCheckHaveMinMaintainabilityIndex.d.ts +3 -0
  19. package/dist/src/core/files/fileCheckMatchNamePattern.d.ts +3 -0
  20. package/dist/src/core/files/getFileDependencies.d.ts +2 -0
  21. package/dist/src/core/files/locateFiles.d.ts +3 -0
  22. package/dist/src/core/files/types.d.ts +10 -0
  23. package/dist/src/core/functions/functionCheckHaveExplicitReturnType.d.ts +3 -0
  24. package/dist/src/core/functions/functionCheckHaveMaxCyclomaticComplexity.d.ts +3 -0
  25. package/dist/src/core/functions/functionCheckHaveMinMaintainabilityIndex.d.ts +3 -0
  26. package/dist/src/core/functions/functionCheckHaveModifier.d.ts +3 -0
  27. package/dist/src/core/functions/functionCheckHaveNameMatchingFileName.d.ts +3 -0
  28. package/dist/src/core/functions/functionCheckMatchNamePattern.d.ts +3 -0
  29. package/dist/src/core/functions/locateFunctions.d.ts +3 -0
  30. package/dist/src/core/functions/types.d.ts +11 -0
  31. package/dist/src/core/layers/checkLayeredArchitecture.d.ts +3 -0
  32. package/dist/src/core/layers/createLayeredArchitecture.d.ts +3 -0
  33. package/dist/src/core/layers/getLayerDependencies.d.ts +2 -0
  34. package/dist/src/core/layers/layer.d.ts +2 -0
  35. package/dist/src/core/layers/layerShouldNotBeAccessedByAnyLayer.d.ts +2 -0
  36. package/dist/src/core/layers/layerShouldOnlyBeAccessedBy.d.ts +2 -0
  37. package/dist/src/core/layers/types.d.ts +8 -0
  38. package/dist/src/core/metrics/calculateCyclomaticComplexity.d.ts +2 -0
  39. package/dist/src/core/metrics/calculateMaintainabilityIndex.d.ts +2 -0
  40. package/dist/src/core/project/parseProject.d.ts +22 -0
  41. package/dist/src/core/properties/locateProperties.d.ts +3 -0
  42. package/dist/src/core/properties/propertyCheckBeReadonly.d.ts +3 -0
  43. package/dist/src/core/properties/types.d.ts +10 -0
  44. package/dist/src/core/shared/sharedCheckHaveMaxCyclomaticComplexity.d.ts +1 -0
  45. package/dist/src/core/shared/sharedCheckHaveMinMaintainabilityIndex.d.ts +1 -0
  46. package/dist/src/core/shared/sharedCheckHaveModifier.d.ts +2 -0
  47. package/dist/src/core/shared/sharedCheckHaveNameMatchingFileName.d.ts +2 -0
  48. package/dist/src/core/shared/sharedCheckMatchNamePattern.d.ts +1 -0
  49. package/dist/src/core/slices/locateSlices.d.ts +3 -0
  50. package/dist/src/core/slices/sliceCheckBeFreeOfCycles.d.ts +3 -0
  51. package/dist/src/core/slices/sliceCheckHaveMaxDistanceFromMainSequence.d.ts +3 -0
  52. package/dist/src/core/slices/types.d.ts +8 -0
  53. package/dist/src/core/types.d.ts +7 -0
  54. package/dist/src/core/utils/ruleBuilder.d.ts +6 -0
  55. package/dist/src/index.d.ts +34 -8
  56. package/dist/src/matchers/index.d.ts +5 -0
  57. package/package.json +1 -1
  58. package/src/core/classes/classCheckExtendClass.test.ts +30 -0
  59. package/src/core/classes/classCheckExtendClass.ts +41 -0
  60. package/src/core/classes/classCheckHaveMaxCyclomaticComplexity.test.ts +8 -0
  61. package/src/core/classes/classCheckHaveMaxCyclomaticComplexity.ts +35 -0
  62. package/src/core/classes/classCheckHaveModifier.test.ts +30 -0
  63. package/src/core/classes/classCheckHaveModifier.ts +17 -0
  64. package/src/core/classes/classCheckHaveNameMatchingFileName.test.ts +30 -0
  65. package/src/core/classes/classCheckHaveNameMatchingFileName.ts +15 -0
  66. package/src/core/classes/classCheckImplementInterface.test.ts +30 -0
  67. package/src/core/classes/classCheckImplementInterface.ts +43 -0
  68. package/src/core/classes/classCheckMatchNamePattern.test.ts +8 -0
  69. package/src/core/classes/classCheckMatchNamePattern.ts +17 -0
  70. package/src/core/classes/classCheckResideInFolder.test.ts +8 -0
  71. package/src/core/classes/classCheckResideInFolder.ts +31 -0
  72. package/src/core/classes/locateClasses.test.ts +13 -0
  73. package/src/core/classes/locateClasses.ts +127 -0
  74. package/src/core/classes/types.ts +16 -0
  75. package/src/core/files/checkDependOnFilesInFolder.test.ts +7 -0
  76. package/src/core/files/checkDependOnFilesInFolder.ts +36 -0
  77. package/src/core/files/fileCheckBeFreeOfCycles.test.ts +7 -0
  78. package/src/core/files/fileCheckBeFreeOfCycles.ts +72 -0
  79. package/src/core/files/fileCheckHaveMaxCyclomaticComplexity.test.ts +8 -0
  80. package/src/core/files/fileCheckHaveMaxCyclomaticComplexity.ts +35 -0
  81. package/src/core/files/fileCheckHaveMaxExportedFunctions.test.ts +32 -0
  82. package/src/core/files/fileCheckHaveMaxExportedFunctions.ts +45 -0
  83. package/src/core/files/fileCheckHaveMinMaintainabilityIndex.test.ts +8 -0
  84. package/src/core/files/fileCheckHaveMinMaintainabilityIndex.ts +19 -0
  85. package/src/core/files/fileCheckMatchNamePattern.test.ts +30 -0
  86. package/src/core/files/fileCheckMatchNamePattern.ts +17 -0
  87. package/src/core/files/getFileDependencies.ts +43 -0
  88. package/src/core/files/locateFiles.test.ts +30 -0
  89. package/src/core/files/locateFiles.ts +31 -0
  90. package/src/core/files/types.ts +12 -0
  91. package/src/core/functions/functionCheckHaveExplicitReturnType.test.ts +30 -0
  92. package/src/core/functions/functionCheckHaveExplicitReturnType.ts +29 -0
  93. package/src/core/functions/functionCheckHaveMaxCyclomaticComplexity.test.ts +8 -0
  94. package/src/core/functions/functionCheckHaveMaxCyclomaticComplexity.ts +20 -0
  95. package/src/core/functions/functionCheckHaveMinMaintainabilityIndex.test.ts +8 -0
  96. package/src/core/functions/functionCheckHaveMinMaintainabilityIndex.ts +20 -0
  97. package/src/core/functions/functionCheckHaveModifier.test.ts +30 -0
  98. package/src/core/functions/functionCheckHaveModifier.ts +18 -0
  99. package/src/core/functions/functionCheckHaveNameMatchingFileName.test.ts +30 -0
  100. package/src/core/functions/functionCheckHaveNameMatchingFileName.ts +16 -0
  101. package/src/core/functions/functionCheckMatchNamePattern.test.ts +30 -0
  102. package/src/core/functions/functionCheckMatchNamePattern.ts +18 -0
  103. package/src/core/functions/locateFunctions.test.ts +16 -0
  104. package/src/core/functions/locateFunctions.ts +47 -0
  105. package/src/core/functions/types.ts +13 -0
  106. package/src/core/layers/checkLayeredArchitecture.test.ts +23 -0
  107. package/src/core/layers/checkLayeredArchitecture.ts +15 -0
  108. package/src/core/layers/createLayeredArchitecture.test.ts +13 -0
  109. package/src/core/layers/createLayeredArchitecture.ts +15 -0
  110. package/src/core/layers/getLayerDependencies.ts +45 -0
  111. package/src/core/layers/layer.test.ts +12 -0
  112. package/src/core/layers/layer.ts +10 -0
  113. package/src/core/layers/layerShouldNotBeAccessedByAnyLayer.test.ts +14 -0
  114. package/src/core/layers/layerShouldNotBeAccessedByAnyLayer.ts +40 -0
  115. package/src/core/layers/layerShouldOnlyBeAccessedBy.test.ts +15 -0
  116. package/src/core/layers/layerShouldOnlyBeAccessedBy.ts +48 -0
  117. package/src/core/layers/types.ts +9 -0
  118. package/src/core/metrics/calculateCyclomaticComplexity.test.ts +23 -0
  119. package/src/core/metrics/calculateCyclomaticComplexity.ts +36 -0
  120. package/src/core/metrics/calculateMaintainabilityIndex.test.ts +38 -0
  121. package/src/core/metrics/calculateMaintainabilityIndex.ts +47 -0
  122. package/src/core/project/parseProject.test.ts +19 -0
  123. package/src/core/project/parseProject.ts +216 -0
  124. package/src/core/properties/locateProperties.test.ts +19 -0
  125. package/src/core/properties/locateProperties.ts +41 -0
  126. package/src/core/properties/propertyCheckBeReadonly.test.ts +32 -0
  127. package/src/core/properties/propertyCheckBeReadonly.ts +27 -0
  128. package/src/core/properties/types.ts +12 -0
  129. package/src/core/shared/sharedCheckHaveMaxCyclomaticComplexity.test.ts +30 -0
  130. package/src/core/shared/sharedCheckHaveMaxCyclomaticComplexity.ts +23 -0
  131. package/src/core/shared/sharedCheckHaveMinMaintainabilityIndex.test.ts +30 -0
  132. package/src/core/shared/sharedCheckHaveMinMaintainabilityIndex.ts +23 -0
  133. package/src/core/shared/sharedCheckHaveModifier.test.ts +31 -0
  134. package/src/core/shared/sharedCheckHaveModifier.ts +51 -0
  135. package/src/core/shared/sharedCheckHaveNameMatchingFileName.test.ts +17 -0
  136. package/src/core/shared/sharedCheckHaveNameMatchingFileName.ts +36 -0
  137. package/src/core/shared/sharedCheckMatchNamePattern.test.ts +29 -0
  138. package/src/core/shared/sharedCheckMatchNamePattern.ts +22 -0
  139. package/src/core/slices/locateSlices.test.ts +22 -0
  140. package/src/core/slices/locateSlices.ts +35 -0
  141. package/src/core/slices/sliceCheckBeFreeOfCycles.test.ts +26 -0
  142. package/src/core/slices/sliceCheckBeFreeOfCycles.ts +91 -0
  143. package/src/core/slices/sliceCheckHaveMaxDistanceFromMainSequence.test.ts +27 -0
  144. package/src/core/slices/sliceCheckHaveMaxDistanceFromMainSequence.ts +110 -0
  145. package/src/core/slices/types.ts +9 -0
  146. package/src/core/testUtils.ts +61 -0
  147. package/src/core/types.ts +15 -0
  148. package/src/core/utils/ruleBuilder.test.ts +24 -0
  149. package/src/core/utils/ruleBuilder.ts +28 -0
  150. package/src/index.ts +34 -8
  151. package/src/matchers/index.ts +269 -51
  152. package/test/architecture.test.ts +109 -16
  153. package/tsconfig.json +2 -1
  154. package/vite.config.ts +2 -2
  155. package/dist/src/core/ClassLocator.d.ts +0 -20
  156. package/dist/src/core/FileLocator.d.ts +0 -15
  157. package/dist/src/core/FunctionLocator.d.ts +0 -15
  158. package/dist/src/core/LayerLocator.d.ts +0 -23
  159. package/dist/src/core/Project.d.ts +0 -20
  160. package/dist/src/core/PropertyLocator.d.ts +0 -12
  161. package/dist/src/core/SliceLocator.d.ts +0 -10
  162. package/src/core/ClassLocator.ts +0 -226
  163. package/src/core/FileLocator.ts +0 -168
  164. package/src/core/FunctionLocator.ts +0 -105
  165. package/src/core/LayerLocator.ts +0 -119
  166. package/src/core/Project.ts +0 -171
  167. package/src/core/PropertyLocator.ts +0 -50
  168. package/src/core/SliceLocator.ts +0 -92
package/dist/index.mjs CHANGED
@@ -1,596 +1,883 @@
1
1
  import * as e from "typescript";
2
- import * as t from "path";
3
- import { expect as n } from "vitest";
2
+ import * as t from "node:path";
3
+ import { dirname as n } from "node:path";
4
+ import { expect as r } from "vitest";
4
5
  //#region \0rolldown/runtime.js
5
- var r = /* @__PURE__ */ ((e) => typeof require < "u" ? require : typeof Proxy < "u" ? new Proxy(e, { get: (e, t) => (typeof require < "u" ? require : e)[t] }) : e)(function(e) {
6
+ var i = /* @__PURE__ */ ((e) => typeof require < "u" ? require : typeof Proxy < "u" ? new Proxy(e, { get: (e, t) => (typeof require < "u" ? require : e)[t] }) : e)(function(e) {
6
7
  if (typeof require < "u") return require.apply(this, arguments);
7
8
  throw Error("Calling `require` for \"" + e + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
8
- }), i = class {
9
- files;
10
- constructor(e, t, n) {
11
- this.program = t;
12
- let r = e;
13
- if (n?.inFolder && (r = r.filter((e) => e.fileName.includes(`/${n.inFolder}/`) || e.fileName.includes(`\\${n.inFolder}\\`))), n?.matchNamePattern) {
14
- let e = typeof n.matchNamePattern == "string" ? new RegExp(n.matchNamePattern) : n.matchNamePattern;
15
- r = r.filter((t) => e.test(t.fileName));
9
+ });
10
+ //#endregion
11
+ //#region src/core/classes/classCheckExtendClass.ts
12
+ function a(t, n, r) {
13
+ let i = [];
14
+ for (let a of t.classes) {
15
+ let t = a.name?.text || "Anonymous", o = !1;
16
+ if (a.heritageClauses) {
17
+ for (let t of a.heritageClauses) if (t.token === e.SyntaxKind.ExtendsKeyword) {
18
+ for (let r of t.types) if (e.isIdentifier(r.expression) && r.expression.text === n) {
19
+ o = !0;
20
+ break;
21
+ }
22
+ }
16
23
  }
17
- this.files = r;
24
+ r && o ? i.push(`Class ${t} extends ${n}, but it shouldn't.`) : !r && !o && i.push(`Class ${t} does not extend ${n}, but it should.`);
18
25
  }
19
- getFileDependencies(t) {
20
- let n = [], r = this.program.getCompilerOptions(), i = (a) => {
21
- if (e.isImportDeclaration(a)) {
22
- let i = a.moduleSpecifier.text, o = e.resolveModuleName(i, t.fileName, r, e.sys);
23
- o.resolvedModule && o.resolvedModule.resolvedFileName && (o.resolvedModule.isExternalLibraryImport || n.push(o.resolvedModule.resolvedFileName));
24
- } else if (e.isExportDeclaration(a) && a.moduleSpecifier) {
25
- let i = a.moduleSpecifier.text, o = e.resolveModuleName(i, t.fileName, r, e.sys);
26
- o.resolvedModule && o.resolvedModule.resolvedFileName && (o.resolvedModule.isExternalLibraryImport || n.push(o.resolvedModule.resolvedFileName));
26
+ return {
27
+ pass: i.length === 0,
28
+ message: () => i.join("\n")
29
+ };
30
+ }
31
+ //#endregion
32
+ //#region src/core/metrics/calculateCyclomaticComplexity.ts
33
+ function o(t) {
34
+ let n = 1, r = (t) => {
35
+ switch (t.kind) {
36
+ case e.SyntaxKind.IfStatement:
37
+ case e.SyntaxKind.ForStatement:
38
+ case e.SyntaxKind.ForInStatement:
39
+ case e.SyntaxKind.ForOfStatement:
40
+ case e.SyntaxKind.WhileStatement:
41
+ case e.SyntaxKind.DoStatement:
42
+ case e.SyntaxKind.CaseClause:
43
+ case e.SyntaxKind.CatchClause:
44
+ case e.SyntaxKind.ConditionalExpression:
45
+ n++;
46
+ break;
47
+ case e.SyntaxKind.BinaryExpression: {
48
+ let r = t;
49
+ (r.operatorToken.kind === e.SyntaxKind.AmpersandAmpersandToken || r.operatorToken.kind === e.SyntaxKind.BarBarToken || r.operatorToken.kind === e.SyntaxKind.QuestionQuestionToken) && n++;
50
+ break;
27
51
  }
28
- e.forEachChild(a, i);
29
- };
30
- return i(t), n;
31
- }
32
- checkDependOnFilesInFolder(e, t) {
33
- let n = [];
34
- for (let r of this.files) {
35
- let i = this.getFileDependencies(r).some((t) => t.includes(`/${e}/`) || t.includes(`\\${e}\\`));
36
- t && i ? n.push(`File ${r.fileName} depends on files in ${e}, but it shouldn't.`) : !t && !i && n.push(`File ${r.fileName} does not depend on files in ${e}, but it should.`);
37
52
  }
53
+ e.forEachChild(t, r);
54
+ };
55
+ return e.forEachChild(t, r), n;
56
+ }
57
+ //#endregion
58
+ //#region src/core/utils/ruleBuilder.ts
59
+ function s(e, t, n) {
60
+ let r = [];
61
+ for (let i of e) {
62
+ let { passes: e, failMessage: a, failNotMessage: o } = n(i);
63
+ t && e ? o && r.push(o) : !t && !e && a && r.push(a);
64
+ }
65
+ return {
66
+ pass: r.length === 0,
67
+ message: () => r.join("\n")
68
+ };
69
+ }
70
+ //#endregion
71
+ //#region src/core/shared/sharedCheckHaveMaxCyclomaticComplexity.ts
72
+ function c(e, t, n, r, i, a) {
73
+ return s(e, a, (e) => {
74
+ let a = t(e), o = n(e), s = o > i, c = `${r} ${a || "Anonymous"}`;
38
75
  return {
39
- pass: n.length === 0,
40
- message: () => n.join("\n")
76
+ passes: !s,
77
+ failMessage: `${c} has a total cyclomatic complexity of ${o}, which exceeds the maximum of ${i}.`,
78
+ failNotMessage: `${c} has a total cyclomatic complexity of ${o}, which exceeds the maximum of ${i}, but it shouldn't.`
41
79
  };
42
- }
43
- checkBeFreeOfCycles(e) {
44
- let t = [], n = new Set(this.files.map((e) => e.fileName)), r = /* @__PURE__ */ new Map();
45
- for (let e of this.files) {
46
- let t = e.fileName, i = this.getFileDependencies(e).filter((e) => n.has(e));
47
- r.set(t, i);
48
- }
49
- let i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = [], s = (e, t) => {
50
- if (a.has(e)) {
51
- let n = t.indexOf(e), r = [...t.slice(n), e].join("->");
52
- return o.some((e) => e.join("->") === r) || o.push([...t.slice(n), e]), !0;
53
- }
54
- if (i.has(e)) return !1;
55
- i.add(e), a.add(e), t.push(e);
56
- let n = r.get(e) || [];
57
- for (let e of n) s(e, t);
58
- return a.delete(e), t.pop(), !1;
80
+ });
81
+ }
82
+ //#endregion
83
+ //#region src/core/classes/classCheckHaveMaxCyclomaticComplexity.ts
84
+ function l(t, n, r) {
85
+ return c(t.classes, (e) => e.name?.text, (t) => {
86
+ let n = 0, r = (t) => {
87
+ (e.isMethodDeclaration(t) || e.isConstructorDeclaration(t) || e.isGetAccessor(t) || e.isSetAccessor(t)) && (n += o(t)), e.forEachChild(t, r);
59
88
  };
60
- for (let e of r.keys()) i.has(e) || s(e, []);
61
- if (e && o.length === 0) t.push("Expected cyclic dependencies, but found none.");
62
- else if (!e && o.length > 0) for (let e of o) t.push(`Cycle detected: ${e.join(" -> ")}`);
89
+ return r(t), n;
90
+ }, "Class", n, r);
91
+ }
92
+ //#endregion
93
+ //#region src/core/shared/sharedCheckHaveModifier.ts
94
+ function u(t, n, r, i, a) {
95
+ let o;
96
+ switch (i) {
97
+ case "export":
98
+ o = e.SyntaxKind.ExportKeyword;
99
+ break;
100
+ case "default":
101
+ o = e.SyntaxKind.DefaultKeyword;
102
+ break;
103
+ case "abstract":
104
+ o = e.SyntaxKind.AbstractKeyword;
105
+ break;
106
+ case "async":
107
+ o = e.SyntaxKind.AsyncKeyword;
108
+ break;
109
+ case "public":
110
+ o = e.SyntaxKind.PublicKeyword;
111
+ break;
112
+ case "private":
113
+ o = e.SyntaxKind.PrivateKeyword;
114
+ break;
115
+ default: throw Error(`Modifier ${i} is not fully supported.`);
116
+ }
117
+ return s(t, a, (t) => {
118
+ let a = n(t), s = e.canHaveModifiers(t) ? e.getModifiers(t) : void 0, c = s ? s.some((e) => e.kind === o) : !1, l = `${r} ${a || "Anonymous"}`;
63
119
  return {
64
- pass: t.length === 0,
65
- message: () => t.join("\n")
120
+ passes: c,
121
+ failMessage: `${l} does not have modifier ${i}, but it should.`,
122
+ failNotMessage: `${l} has modifier ${i}, but it shouldn't.`
66
123
  };
67
- }
68
- checkMatchNamePattern(e, t) {
69
- let n = [], r = typeof e == "string" ? new RegExp(e) : e;
70
- for (let i of this.files) {
71
- let a = r.test(i.fileName);
72
- t && a ? n.push(`File ${i.fileName} matches pattern ${e}, but it shouldn't.`) : !t && !a && n.push(`File ${i.fileName} does not match pattern ${e}, but it should.`);
73
- }
124
+ });
125
+ }
126
+ //#endregion
127
+ //#region src/core/classes/classCheckHaveModifier.ts
128
+ function d(e, t, n) {
129
+ return u(e.classes, (e) => e.name?.text, "Class", t, n);
130
+ }
131
+ //#endregion
132
+ //#region src/core/shared/sharedCheckHaveNameMatchingFileName.ts
133
+ function f(n, r, i, a) {
134
+ return s(n, a, (n) => {
135
+ let a = r(n), o = n.getSourceFile ? n.getSourceFile() : n.parent ? e.getSourceFileOfNode(n) : void 0;
136
+ if (!o) return {
137
+ passes: !0,
138
+ failMessage: "",
139
+ failNotMessage: ""
140
+ };
141
+ let s = t.basename(o.fileName, t.extname(o.fileName)), c = a === s, l = `${i} ${a || "Anonymous"}`;
74
142
  return {
75
- pass: n.length === 0,
76
- message: () => n.join("\n")
143
+ passes: c,
144
+ failMessage: `${l} does not have a name matching its filename ${s}, but it should.`,
145
+ failNotMessage: `${l} has a name matching its filename ${s}, but it shouldn't.`
77
146
  };
78
- }
79
- }, a = class {
80
- classes;
81
- constructor(t, n, r) {
82
- this.program = n;
83
- let i = t;
84
- if (r?.inFolder && (i = i.filter((e) => {
85
- let t = e.getSourceFile();
86
- return t.fileName.includes(`/${r.inFolder}/`) || t.fileName.includes(`\\${r.inFolder}\\`);
87
- })), r?.matchNamePattern) {
88
- let e = typeof r.matchNamePattern == "string" ? new RegExp(r.matchNamePattern) : r.matchNamePattern;
89
- i = i.filter((t) => {
90
- let n = t.name?.text;
91
- return n && e.test(n);
92
- });
93
- }
94
- if (r?.withDecorator && (i = i.filter((t) => {
95
- let n = e.canHaveDecorators(t) ? e.getDecorators(t) : void 0, i = !1;
96
- if (n) for (let t of n) {
97
- let n = t.expression, a = "";
98
- e.isIdentifier(n) ? a = n.text : e.isCallExpression(n) && e.isIdentifier(n.expression) && (a = n.expression.text), a === r.withDecorator && (i = !0);
99
- }
100
- return i;
101
- })), r?.extending && (i = i.filter((t) => {
102
- if (t.heritageClauses) {
103
- for (let n of t.heritageClauses) if (n.token === e.SyntaxKind.ExtendsKeyword) {
104
- for (let t of n.types) if (e.isIdentifier(t.expression) && t.expression.text === r.extending) return !0;
105
- }
106
- }
107
- return !1;
108
- })), r?.implementing && (i = i.filter((t) => {
109
- if (t.heritageClauses) {
110
- for (let n of t.heritageClauses) if (n.token === e.SyntaxKind.ImplementsKeyword) {
111
- for (let t of n.types) if (e.isIdentifier(t.expression) && t.expression.text === r.implementing) return !0;
112
- }
113
- }
114
- return !1;
115
- })), r?.havingModifier) {
116
- let t;
117
- switch (r.havingModifier) {
118
- case "export":
119
- t = e.SyntaxKind.ExportKeyword;
120
- break;
121
- case "default":
122
- t = e.SyntaxKind.DefaultKeyword;
123
- break;
124
- case "abstract":
125
- t = e.SyntaxKind.AbstractKeyword;
147
+ });
148
+ }
149
+ //#endregion
150
+ //#region src/core/classes/classCheckHaveNameMatchingFileName.ts
151
+ function p(e, t) {
152
+ return f(e.classes, (e) => e.name?.text, "Class", t);
153
+ }
154
+ //#endregion
155
+ //#region src/core/classes/classCheckImplementInterface.ts
156
+ function m(t, n, r) {
157
+ let i = [];
158
+ for (let a of t.classes) {
159
+ let t = a.name?.text || "Anonymous", o = !1;
160
+ if (a.heritageClauses) {
161
+ for (let t of a.heritageClauses) if (t.token === e.SyntaxKind.ImplementsKeyword) {
162
+ for (let r of t.types) if (e.isIdentifier(r.expression) && r.expression.text === n) {
163
+ o = !0;
126
164
  break;
127
- default: throw Error(`Modifier ${r.havingModifier} is not fully supported.`);
165
+ }
128
166
  }
129
- i = i.filter((n) => {
130
- let r = e.canHaveModifiers(n) ? e.getModifiers(n) : void 0;
131
- return r && r.some((e) => e.kind === t);
132
- });
133
167
  }
134
- this.classes = i;
168
+ r && o ? i.push(`Class ${t} implements ${n}, but it shouldn't.`) : !r && !o && i.push(`Class ${t} does not implement ${n}, but it should.`);
135
169
  }
136
- checkResideInFolder(e, t) {
137
- let n = [];
138
- for (let r of this.classes) {
139
- let i = r.name?.text || "Anonymous Class", a = r.getSourceFile(), o = a.fileName.includes(`/${e}/`) || a.fileName.includes(`\\${e}\\`);
140
- t && o ? n.push(`Class ${i} resides in ${e}, but it shouldn't.`) : !t && !o && n.push(`Class ${i} does not reside in ${e}, but it should.`);
141
- }
170
+ return {
171
+ pass: i.length === 0,
172
+ message: () => i.join("\n")
173
+ };
174
+ }
175
+ //#endregion
176
+ //#region src/core/shared/sharedCheckMatchNamePattern.ts
177
+ function h(e, t, n, r, i) {
178
+ let a = typeof r == "string" ? new RegExp(r) : r;
179
+ return s(e, i, (e) => {
180
+ let i = t(e), o = i ? a.test(i) : !1, s = `${n} ${i || "Anonymous"}`;
142
181
  return {
143
- pass: n.length === 0,
144
- message: () => n.join("\n")
182
+ passes: o,
183
+ failMessage: `${s} does not match pattern ${r}, but it should.`,
184
+ failNotMessage: `${s} matches pattern ${r}, but it shouldn't.`
145
185
  };
186
+ });
187
+ }
188
+ //#endregion
189
+ //#region src/core/classes/classCheckMatchNamePattern.ts
190
+ function g(e, t, n) {
191
+ return h(e.classes, (e) => e.name?.text, "Class", t, n);
192
+ }
193
+ //#endregion
194
+ //#region src/core/classes/classCheckResideInFolder.ts
195
+ function _(e, t, n) {
196
+ let r = [];
197
+ for (let i of e.classes) {
198
+ let e = i.name?.text || "Anonymous Class", a = i.getSourceFile(), o = a.fileName.includes(`/${t}/`) || a.fileName.includes(`\\${t}\\`);
199
+ 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.`);
200
+ }
201
+ return {
202
+ pass: r.length === 0,
203
+ message: () => r.join("\n")
204
+ };
205
+ }
206
+ //#endregion
207
+ //#region src/core/classes/locateClasses.ts
208
+ function v(t, n, r) {
209
+ let i = t;
210
+ if (r?.inFolder && (i = i.filter((t) => {
211
+ let n = t.getSourceFile ? t.getSourceFile() : t.parent ? e.getSourceFileOfNode(t) : void 0;
212
+ return n ? n.fileName.includes(`/${r.inFolder}/`) || n.fileName.includes(`\\${r.inFolder}\\`) : !1;
213
+ })), r?.matchNamePattern) {
214
+ let e = typeof r.matchNamePattern == "string" ? new RegExp(r.matchNamePattern) : r.matchNamePattern;
215
+ i = i.filter((t) => {
216
+ let n = t.name?.text;
217
+ return n && e.test(n);
218
+ });
146
219
  }
147
- checkMatchNamePattern(e, t) {
148
- let n = [], r = typeof e == "string" ? new RegExp(e) : e;
149
- for (let i of this.classes) {
150
- let a = i.name?.text, o = a && r.test(a);
151
- t && o ? n.push(`Class ${a} matches pattern ${e}, but it shouldn't.`) : !t && !o && n.push(`Class ${a || "Anonymous"} does not match pattern ${e}, but it should.`);
220
+ if (r?.withDecorator && (i = i.filter((t) => {
221
+ let n = e.canHaveDecorators(t) ? e.getDecorators(t) : void 0, i = !1;
222
+ if (n) for (let t of n) {
223
+ let n = t.expression, a = "";
224
+ e.isIdentifier(n) ? a = n.text : e.isCallExpression(n) && e.isIdentifier(n.expression) && (a = n.expression.text), a === r.withDecorator && (i = !0);
152
225
  }
153
- return {
154
- pass: n.length === 0,
155
- message: () => n.join("\n")
156
- };
157
- }
158
- checkExtendClass(t, n) {
159
- let r = [];
160
- for (let i of this.classes) {
161
- let a = i.name?.text || "Anonymous", o = !1;
162
- if (i.heritageClauses) {
163
- for (let n of i.heritageClauses) if (n.token === e.SyntaxKind.ExtendsKeyword) {
164
- for (let r of n.types) if (e.isIdentifier(r.expression) && r.expression.text === t) {
165
- o = !0;
166
- break;
167
- }
168
- }
226
+ return i;
227
+ })), r?.extending && (i = i.filter((t) => {
228
+ if (t.heritageClauses) {
229
+ for (let n of t.heritageClauses) if (n.token === e.SyntaxKind.ExtendsKeyword) {
230
+ for (let t of n.types) if (e.isIdentifier(t.expression) && t.expression.text === r.extending) return !0;
169
231
  }
170
- n && o ? r.push(`Class ${a} extends ${t}, but it shouldn't.`) : !n && !o && r.push(`Class ${a} does not extend ${t}, but it should.`);
171
232
  }
172
- return {
173
- pass: r.length === 0,
174
- message: () => r.join("\n")
175
- };
176
- }
177
- checkImplementInterface(t, n) {
178
- let r = [];
179
- for (let i of this.classes) {
180
- let a = i.name?.text || "Anonymous", o = !1;
181
- if (i.heritageClauses) {
182
- for (let n of i.heritageClauses) if (n.token === e.SyntaxKind.ImplementsKeyword) {
183
- for (let r of n.types) if (e.isIdentifier(r.expression) && r.expression.text === t) {
184
- o = !0;
185
- break;
186
- }
187
- }
233
+ return !1;
234
+ })), r?.implementing && (i = i.filter((t) => {
235
+ if (t.heritageClauses) {
236
+ for (let n of t.heritageClauses) if (n.token === e.SyntaxKind.ImplementsKeyword) {
237
+ for (let t of n.types) if (e.isIdentifier(t.expression) && t.expression.text === r.implementing) return !0;
188
238
  }
189
- n && o ? r.push(`Class ${a} implements ${t}, but it shouldn't.`) : !n && !o && r.push(`Class ${a} does not implement ${t}, but it should.`);
190
239
  }
191
- return {
192
- pass: r.length === 0,
193
- message: () => r.join("\n")
194
- };
195
- }
196
- checkHaveModifier(t, n) {
197
- let r;
198
- switch (t) {
240
+ return !1;
241
+ })), r?.havingModifier) {
242
+ let t;
243
+ switch (r.havingModifier) {
199
244
  case "export":
200
- r = e.SyntaxKind.ExportKeyword;
245
+ t = e.SyntaxKind.ExportKeyword;
201
246
  break;
202
247
  case "default":
203
- r = e.SyntaxKind.DefaultKeyword;
248
+ t = e.SyntaxKind.DefaultKeyword;
204
249
  break;
205
250
  case "abstract":
206
- r = e.SyntaxKind.AbstractKeyword;
251
+ t = e.SyntaxKind.AbstractKeyword;
207
252
  break;
208
- default: throw Error(`Modifier ${t} is not fully supported.`);
209
- }
210
- let i = [];
211
- for (let a of this.classes) {
212
- let o = a.name?.text || "Anonymous", s = e.canHaveModifiers(a) ? e.getModifiers(a) : void 0, c = s && s.some((e) => e.kind === r);
213
- n && c ? i.push(`Class ${o} has modifier ${t}, but it shouldn't.`) : !n && !c && i.push(`Class ${o} does not have modifier ${t}, but it should.`);
253
+ default: throw Error(`Modifier ${r.havingModifier} is not fully supported.`);
214
254
  }
215
- return {
216
- pass: i.length === 0,
217
- message: () => i.join("\n")
218
- };
219
- }
220
- }, o = class {
221
- files;
222
- layers = /* @__PURE__ */ new Map();
223
- assertions = [];
224
- constructor(e, t) {
225
- this.program = t, this.files = e;
226
- }
227
- layer(e, t) {
228
- return this.layers.set(e, t), this;
229
- }
230
- whereLayer(e) {
231
- if (!this.layers.has(e)) throw Error(`Layer ${e} is not defined`);
232
- return new s(this, e);
233
- }
234
- addAssertion(e) {
235
- this.assertions.push(e);
236
- }
237
- getFiles() {
238
- return this.files;
239
- }
240
- getLayerPattern(e) {
241
- return this.layers.get(e);
242
- }
243
- getFileDependencies(t) {
244
- let n = [], r = this.program.getCompilerOptions(), i = (a) => {
245
- if (e.isImportDeclaration(a)) {
246
- let i = a.moduleSpecifier.text, o = e.resolveModuleName(i, t.fileName, r, e.sys);
247
- o.resolvedModule && o.resolvedModule.resolvedFileName && !o.resolvedModule.isExternalLibraryImport && n.push(o.resolvedModule.resolvedFileName);
248
- } else if (e.isExportDeclaration(a) && a.moduleSpecifier) {
249
- let i = a.moduleSpecifier.text, o = e.resolveModuleName(i, t.fileName, r, e.sys);
250
- o.resolvedModule && o.resolvedModule.resolvedFileName && !o.resolvedModule.isExternalLibraryImport && n.push(o.resolvedModule.resolvedFileName);
251
- }
252
- e.forEachChild(a, i);
253
- };
254
- return i(t), n;
255
- }
256
- check() {
257
- let e = [];
258
- for (let t of this.assertions) e.push(...t(this.files));
259
- return {
260
- pass: e.length === 0,
261
- message: () => e.join("\n")
262
- };
263
- }
264
- }, s = class {
265
- constructor(e, t) {
266
- this.parent = e, this.targetLayer = t;
255
+ i = i.filter((n) => (e.canHaveModifiers(n) ? e.getModifiers(n) : void 0)?.some((e) => e.kind === t));
267
256
  }
268
- shouldNotBeAccessedByAnyLayer() {
269
- return this.parent.addAssertion((e) => {
270
- let t = [], n = this.parent.getLayerPattern(this.targetLayer);
271
- for (let r of e) {
272
- let e = r.fileName;
273
- !e.includes(`/${n}/`) && !e.includes(`\\${n}\\`) && this.parent.getFileDependencies(r).some((e) => e.includes(`/${n}/`) || e.includes(`\\${n}\\`)) && t.push(`File ${e} accesses layer ${this.targetLayer} but it shouldn't.`);
274
- }
275
- return t;
276
- }), this.parent;
277
- }
278
- shouldOnlyBeAccessedBy(...e) {
279
- return this.parent.addAssertion((t) => {
280
- let n = [], r = this.parent.getLayerPattern(this.targetLayer), i = e.map((e) => this.parent.getLayerPattern(e));
281
- for (let a of t) {
282
- let t = a.fileName, o = i.some((e) => t.includes(`/${e}/`) || t.includes(`\\${e}\\`));
283
- !t.includes(`/${r}/`) && !t.includes(`\\${r}\\`) && !o && this.parent.getFileDependencies(a).some((e) => e.includes(`/${r}/`) || e.includes(`\\${r}\\`)) && n.push(`File ${t} accesses layer ${this.targetLayer} but only ${e.join(", ")} are allowed.`);
284
- }
285
- return n;
286
- }), this.parent;
287
- }
288
- }, c = class {
289
- functions;
290
- constructor(t, n, r) {
291
- this.program = n;
292
- let i = t;
293
- if (r?.inFolder && (i = i.filter((e) => {
294
- let t = e.getSourceFile();
295
- return t.fileName.includes(`/${r.inFolder}/`) || t.fileName.includes(`\\${r.inFolder}\\`);
296
- })), r?.matchNamePattern) {
297
- let t = typeof r.matchNamePattern == "string" ? new RegExp(r.matchNamePattern) : r.matchNamePattern;
298
- i = i.filter((n) => n.name && e.isIdentifier(n.name) && t.test(n.name.text));
299
- }
300
- r?.isTopLevel && (i = i.filter((t) => e.isSourceFile(t.parent))), this.functions = i;
301
- }
302
- checkHaveModifier(t, n) {
303
- let r;
304
- switch (t) {
305
- case "export":
306
- r = e.SyntaxKind.ExportKeyword;
307
- break;
308
- case "async":
309
- r = e.SyntaxKind.AsyncKeyword;
310
- break;
311
- case "private":
312
- r = e.SyntaxKind.PrivateKeyword;
313
- break;
314
- case "public":
315
- r = e.SyntaxKind.PublicKeyword;
316
- break;
317
- default: throw Error(`Modifier ${t} is not fully supported.`);
257
+ return {
258
+ type: "ClassLocator",
259
+ classes: i,
260
+ program: n
261
+ };
262
+ }
263
+ //#endregion
264
+ //#region src/core/files/getFileDependencies.ts
265
+ function y(t, n) {
266
+ let r = [], i = n.getCompilerOptions(), a = (n) => {
267
+ if (e.isImportDeclaration(n)) {
268
+ let a = n.moduleSpecifier.text, o = e.resolveModuleName(a, t.fileName, i, e.sys);
269
+ o.resolvedModule?.resolvedFileName && (o.resolvedModule.isExternalLibraryImport || r.push(o.resolvedModule.resolvedFileName));
270
+ } else if (e.isExportDeclaration(n) && n.moduleSpecifier) {
271
+ let a = n.moduleSpecifier.text, o = e.resolveModuleName(a, t.fileName, i, e.sys);
272
+ o.resolvedModule?.resolvedFileName && (o.resolvedModule.isExternalLibraryImport || r.push(o.resolvedModule.resolvedFileName));
318
273
  }
319
- let i = [];
320
- for (let a of this.functions) {
321
- let o = a.name && e.isIdentifier(a.name) ? a.name.text : "Anonymous Function", s = e.canHaveModifiers(a) ? e.getModifiers(a) : void 0, c = s && s.some((e) => e.kind === r);
322
- n && c ? i.push(`Function ${o} has modifier ${t}, but it shouldn't.`) : !n && !c && i.push(`Function ${o} does not have modifier ${t}, but it should.`);
274
+ e.forEachChild(n, a);
275
+ };
276
+ return a(t), r;
277
+ }
278
+ //#endregion
279
+ //#region src/core/files/checkDependOnFilesInFolder.ts
280
+ function b(e, t, n) {
281
+ let r = [];
282
+ for (let i of e.files) {
283
+ let a = y(i, e.program).some((e) => e.includes(`/${t}/`) || e.includes(`\\${t}\\`));
284
+ n && a ? r.push(`File ${i.fileName} depends on files in ${t}, but it shouldn't.`) : !n && !a && r.push(`File ${i.fileName} does not depend on files in ${t}, but it should.`);
285
+ }
286
+ return {
287
+ pass: r.length === 0,
288
+ message: () => r.join("\n")
289
+ };
290
+ }
291
+ //#endregion
292
+ //#region src/core/files/fileCheckBeFreeOfCycles.ts
293
+ function x(e, t) {
294
+ let n = [], r = new Set(e.files.map((e) => e.fileName)), i = /* @__PURE__ */ new Map();
295
+ for (let t of e.files) {
296
+ let n = t.fileName, a = y(t, e.program).filter((e) => r.has(e));
297
+ i.set(n, a);
298
+ }
299
+ let a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Set(), s = [], c = (e, t) => {
300
+ if (o.has(e)) {
301
+ let n = t.indexOf(e), r = [...t.slice(n), e].join("->");
302
+ return s.some((e) => e.join("->") === r) || s.push([...t.slice(n), e]), !0;
323
303
  }
324
- return {
325
- pass: i.length === 0,
326
- message: () => i.join("\n")
304
+ if (a.has(e)) return !1;
305
+ a.add(e), o.add(e), t.push(e);
306
+ let n = i.get(e) || [];
307
+ for (let e of n) c(e, t);
308
+ return o.delete(e), t.pop(), !1;
309
+ };
310
+ for (let e of i.keys()) a.has(e) || c(e, []);
311
+ if (t && s.length === 0) n.push("Expected cyclic dependencies, but found none.");
312
+ else if (!t && s.length > 0) for (let e of s) n.push(`Cycle detected: ${e.join(" -> ")}`);
313
+ return {
314
+ pass: n.length === 0,
315
+ message: () => n.join("\n")
316
+ };
317
+ }
318
+ //#endregion
319
+ //#region src/core/files/fileCheckHaveMaxCyclomaticComplexity.ts
320
+ function S(t, n, r) {
321
+ return c(t.files, (e) => e.fileName, (t) => {
322
+ let n = 0, r = (t) => {
323
+ (e.isFunctionDeclaration(t) || e.isMethodDeclaration(t) || e.isArrowFunction(t) || e.isFunctionExpression(t)) && (n += o(t)), e.forEachChild(t, r);
327
324
  };
325
+ return r(t), n;
326
+ }, "File", n, r);
327
+ }
328
+ //#endregion
329
+ //#region src/core/files/fileCheckHaveMaxExportedFunctions.ts
330
+ function C(t, n, r) {
331
+ let i = [];
332
+ for (let a of t.files) {
333
+ let t = 0;
334
+ e.forEachChild(a, (n) => {
335
+ e.isFunctionDeclaration(n) && (e.canHaveModifiers(n) ? e.getModifiers(n) : void 0)?.some((t) => t.kind === e.SyntaxKind.ExportKeyword) && t++;
336
+ });
337
+ let o = t > n;
338
+ r && o ? i.push(`File ${a.fileName} has ${t} exported functions, which exceeds the maximum of ${n}, but it shouldn't.`) : !r && o && i.push(`File ${a.fileName} has ${t} exported functions, which exceeds the maximum of ${n}.`);
328
339
  }
329
- checkHaveExplicitReturnType(t) {
330
- let n = [];
331
- for (let r of this.functions) {
332
- let i = r.name && e.isIdentifier(r.name) ? r.name.text : "Anonymous Function", a = !!r.type;
333
- t && a ? n.push(`Function ${i} has an explicit return type, but it shouldn't.`) : !t && !a && n.push(`Function ${i} does not have an explicit return type, but it should.`);
334
- }
340
+ return {
341
+ pass: r ? i.length > 0 : i.length === 0,
342
+ message: () => i.join("\n") || (r ? "Expected some files to exceed maximum exported functions, but none did." : "")
343
+ };
344
+ }
345
+ //#endregion
346
+ //#region src/core/metrics/calculateMaintainabilityIndex.ts
347
+ function w(t) {
348
+ let n = 0, r = 0, i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), s = 1, c = t.getSourceFile();
349
+ if (c) {
350
+ let e = c.getLineAndCharacterOfPosition(t.getStart());
351
+ s = c.getLineAndCharacterOfPosition(t.getEnd()).line - e.line + 1;
352
+ }
353
+ let l = (t) => {
354
+ e.isBinaryExpression(t) || e.isPrefixUnaryExpression(t) || e.isPostfixUnaryExpression(t) ? (n++, i.add(t.kind)) : (e.isIdentifier(t) || e.isLiteralExpression(t)) && (r++, a.add(t.getText(c))), e.forEachChild(t, l);
355
+ };
356
+ l(t);
357
+ let u = n + r, d = i.size + a.size, f = d === 0 ? 0 : u * Math.log2(d), p = o(t);
358
+ return Math.max(0, (171 - 5.2 * Math.log(f || 1) - .23 * p - 16.2 * Math.log(s)) * 100 / 171);
359
+ }
360
+ //#endregion
361
+ //#region src/core/shared/sharedCheckHaveMinMaintainabilityIndex.ts
362
+ function T(e, t, n, r, i, a) {
363
+ return s(e, a, (e) => {
364
+ let a = t(e), o = n(e), s = o < i, c = `${r} ${a || "Anonymous"}`;
335
365
  return {
336
- pass: n.length === 0,
337
- message: () => n.join("\n")
366
+ passes: !s,
367
+ failMessage: `${c} has a maintainability index of ${o.toFixed(2)}, which falls below the minimum of ${i}.`,
368
+ failNotMessage: `${c} has a maintainability index of ${o.toFixed(2)}, which falls below the minimum of ${i}, but it shouldn't.`
338
369
  };
339
- }
340
- checkMatchNamePattern(t, n) {
341
- let r = [], i = typeof t == "string" ? new RegExp(t) : t;
342
- for (let a of this.functions) {
343
- let o = a.name && e.isIdentifier(a.name) ? a.name.text : void 0, s = o && i.test(o);
344
- n && s ? r.push(`Function ${o} matches pattern ${t}, but it shouldn't.`) : !n && !s && r.push(`Function ${o || "Anonymous Function"} does not match pattern ${t}, but it should.`);
370
+ });
371
+ }
372
+ //#endregion
373
+ //#region src/core/files/fileCheckHaveMinMaintainabilityIndex.ts
374
+ function E(e, t, n) {
375
+ return T(e.files, (e) => e.fileName, w, "File", t, n);
376
+ }
377
+ //#endregion
378
+ //#region src/core/files/fileCheckMatchNamePattern.ts
379
+ function D(e, t, n) {
380
+ return h(e.files, (e) => e.fileName, "File", t, n);
381
+ }
382
+ //#endregion
383
+ //#region src/core/files/locateFiles.ts
384
+ function O(e, t, n) {
385
+ let r = e;
386
+ if (n?.inFolder && (r = r.filter((e) => e.fileName.includes(`/${n.inFolder}/`) || e.fileName.includes(`\\${n.inFolder}\\`))), n?.matchNamePattern) {
387
+ let e = typeof n.matchNamePattern == "string" ? new RegExp(n.matchNamePattern) : n.matchNamePattern;
388
+ r = r.filter((t) => e.test(t.fileName));
389
+ }
390
+ return {
391
+ type: "FileLocator",
392
+ files: r,
393
+ program: t
394
+ };
395
+ }
396
+ //#endregion
397
+ //#region src/core/functions/functionCheckHaveExplicitReturnType.ts
398
+ function k(t, n) {
399
+ let r = [];
400
+ for (let i of t.functions) {
401
+ let t = i.name && e.isIdentifier(i.name) ? i.name.text : "Anonymous Function", a = !!i.type;
402
+ n && a ? r.push(`Function ${t} has an explicit return type, but it shouldn't.`) : !n && !a && r.push(`Function ${t} does not have an explicit return type, but it should.`);
403
+ }
404
+ return {
405
+ pass: r.length === 0,
406
+ message: () => r.join("\n")
407
+ };
408
+ }
409
+ //#endregion
410
+ //#region src/core/functions/functionCheckHaveMaxCyclomaticComplexity.ts
411
+ function A(t, n, r) {
412
+ return c(t.functions, (t) => t.name && e.isIdentifier(t.name) ? t.name.text : void 0, o, "Function", n, r);
413
+ }
414
+ //#endregion
415
+ //#region src/core/functions/functionCheckHaveMinMaintainabilityIndex.ts
416
+ function j(t, n, r) {
417
+ return T(t.functions, (t) => t.name && e.isIdentifier(t.name) ? t.name.text : void 0, w, "Function", n, r);
418
+ }
419
+ //#endregion
420
+ //#region src/core/functions/functionCheckHaveModifier.ts
421
+ function M(t, n, r) {
422
+ return u(t.functions, (t) => t.name && e.isIdentifier(t.name) ? t.name.text : void 0, "Function", n, r);
423
+ }
424
+ //#endregion
425
+ //#region src/core/functions/functionCheckHaveNameMatchingFileName.ts
426
+ function N(t, n) {
427
+ return f(t.functions, (t) => t.name && e.isIdentifier(t.name) ? t.name.text : void 0, "Function", n);
428
+ }
429
+ //#endregion
430
+ //#region src/core/functions/functionCheckMatchNamePattern.ts
431
+ function P(t, n, r) {
432
+ return h(t.functions, (t) => t.name && e.isIdentifier(t.name) ? t.name.text : void 0, "Function", n, r);
433
+ }
434
+ //#endregion
435
+ //#region src/core/functions/locateFunctions.ts
436
+ function F(t, n, r) {
437
+ let i = t;
438
+ if (r?.inFolder && (i = i.filter((t) => {
439
+ let n = t.getSourceFile ? t.getSourceFile() : t.parent ? e.getSourceFileOfNode(t) : void 0;
440
+ return n ? n.fileName.includes(`/${r.inFolder}/`) || n.fileName.includes(`\\${r.inFolder}\\`) : !1;
441
+ })), r?.matchNamePattern) {
442
+ let t = typeof r.matchNamePattern == "string" ? new RegExp(r.matchNamePattern) : r.matchNamePattern;
443
+ i = i.filter((n) => n.name && e.isIdentifier(n.name) && t.test(n.name.text));
444
+ }
445
+ return r?.isTopLevel && (i = i.filter((t) => e.isSourceFile(t.parent))), {
446
+ type: "FunctionLocator",
447
+ functions: i,
448
+ program: n
449
+ };
450
+ }
451
+ //#endregion
452
+ //#region src/core/layers/checkLayeredArchitecture.ts
453
+ function I(e) {
454
+ let t = [];
455
+ for (let n of e.assertions) t.push(...n(e.files));
456
+ return {
457
+ pass: t.length === 0,
458
+ message: () => t.join("\n")
459
+ };
460
+ }
461
+ //#endregion
462
+ //#region src/core/layers/createLayeredArchitecture.ts
463
+ function L(e, t) {
464
+ return {
465
+ type: "LayeredArchitecture",
466
+ files: e,
467
+ layers: /* @__PURE__ */ new Map(),
468
+ assertions: [],
469
+ program: t
470
+ };
471
+ }
472
+ //#endregion
473
+ //#region src/core/layers/layer.ts
474
+ function R(e, t, n) {
475
+ return e.layers.set(t, n), e;
476
+ }
477
+ //#endregion
478
+ //#region src/core/layers/getLayerDependencies.ts
479
+ function z(t, n) {
480
+ let r = [], i = n.getCompilerOptions(), a = (n) => {
481
+ if (e.isImportDeclaration(n)) {
482
+ let a = n.moduleSpecifier.text, o = e.resolveModuleName(a, t.fileName, i, e.sys);
483
+ o.resolvedModule?.resolvedFileName && !o.resolvedModule.isExternalLibraryImport && r.push(o.resolvedModule.resolvedFileName);
484
+ } else if (e.isExportDeclaration(n) && n.moduleSpecifier) {
485
+ let a = n.moduleSpecifier.text, o = e.resolveModuleName(a, t.fileName, i, e.sys);
486
+ o.resolvedModule?.resolvedFileName && !o.resolvedModule.isExternalLibraryImport && r.push(o.resolvedModule.resolvedFileName);
345
487
  }
346
- return {
347
- pass: r.length === 0,
348
- message: () => r.join("\n")
349
- };
350
- }
351
- }, l = class {
352
- properties;
353
- constructor(t, n, r) {
354
- this.program = n;
355
- let i = t;
356
- if (r?.inFolder && (i = i.filter((e) => {
357
- let t = e.getSourceFile();
358
- return t.fileName.includes(`/${r.inFolder}/`) || t.fileName.includes(`\\${r.inFolder}\\`);
359
- })), r?.matchNamePattern) {
360
- let t = typeof r.matchNamePattern == "string" ? new RegExp(r.matchNamePattern) : r.matchNamePattern;
361
- i = i.filter((n) => e.isIdentifier(n.name) && t.test(n.name.text));
488
+ e.forEachChild(n, a);
489
+ };
490
+ return a(t), r;
491
+ }
492
+ //#endregion
493
+ //#region src/core/layers/layerShouldNotBeAccessedByAnyLayer.ts
494
+ function B(e, t) {
495
+ if (!e.layers.has(t)) throw Error(`Layer ${t} is not defined`);
496
+ return e.assertions.push((n) => {
497
+ let r = [], i = e.layers.get(t);
498
+ for (let a of n) {
499
+ let n = a.fileName;
500
+ !n.includes(`/${i}/`) && !n.includes(`\\${i}\\`) && z(a, e.program).some((e) => e.includes(`/${i}/`) || e.includes(`\\${i}\\`)) && r.push(`File ${n} accesses layer ${t} but it shouldn't.`);
362
501
  }
363
- this.properties = i;
364
- }
365
- checkBeReadonly(t) {
366
- let n = [];
367
- for (let r of this.properties) {
368
- let i = e.isIdentifier(r.name) ? r.name.text : "Anonymous Property", a = e.canHaveModifiers(r) ? e.getModifiers(r) : void 0, o = a && a.some((t) => t.kind === e.SyntaxKind.ReadonlyKeyword);
369
- t && o ? n.push(`Property ${i} is readonly, but it shouldn't be.`) : !t && !o && n.push(`Property ${i} is not readonly, but it should be.`);
502
+ return r;
503
+ }), e;
504
+ }
505
+ //#endregion
506
+ //#region src/core/layers/layerShouldOnlyBeAccessedBy.ts
507
+ function V(e, t, n) {
508
+ if (!e.layers.has(t)) throw Error(`Layer ${t} is not defined`);
509
+ return e.assertions.push((r) => {
510
+ let i = [], a = e.layers.get(t), o = n.map((t) => e.layers.get(t));
511
+ for (let s of r) {
512
+ let r = s.fileName, c = o.some((e) => r.includes(`/${e}/`) || r.includes(`\\${e}\\`));
513
+ !r.includes(`/${a}/`) && !r.includes(`\\${a}\\`) && !c && z(s, e.program).some((e) => e.includes(`/${a}/`) || e.includes(`\\${a}\\`)) && i.push(`File ${r} accesses layer ${t} but only ${n.join(", ")} are allowed.`);
370
514
  }
371
- return {
372
- pass: n.length === 0,
373
- message: () => n.join("\n")
374
- };
375
- }
376
- }, u = class {
377
- slicePattern;
378
- sliceIds = /* @__PURE__ */ new Set();
379
- sliceFiles = /* @__PURE__ */ new Map();
380
- constructor(e, t, n) {
381
- this.program = t;
382
- let r = n.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "([^/\\\\]+)");
383
- this.slicePattern = new RegExp(r);
384
- for (let t of e) {
385
- let e = t.fileName.match(this.slicePattern);
386
- if (e && e[1]) {
387
- let n = e[1];
388
- this.sliceIds.add(n), this.sliceFiles.has(n) || this.sliceFiles.set(n, []), this.sliceFiles.get(n).push(t);
389
- }
515
+ return i;
516
+ }), e;
517
+ }
518
+ //#endregion
519
+ //#region src/core/properties/locateProperties.ts
520
+ function H(t, n, r) {
521
+ let i = t;
522
+ if (r?.inFolder && (i = i.filter((t) => {
523
+ let n = t.getSourceFile ? t.getSourceFile() : t.parent ? e.getSourceFileOfNode(t) : void 0;
524
+ return n ? n.fileName.includes(`/${r.inFolder}/`) || n.fileName.includes(`\\${r.inFolder}\\`) : !1;
525
+ })), r?.matchNamePattern) {
526
+ let t = typeof r.matchNamePattern == "string" ? new RegExp(r.matchNamePattern) : r.matchNamePattern;
527
+ i = i.filter((n) => e.isIdentifier(n.name) && t.test(n.name.text));
528
+ }
529
+ return {
530
+ type: "PropertyLocator",
531
+ properties: i,
532
+ program: n
533
+ };
534
+ }
535
+ //#endregion
536
+ //#region src/core/slices/locateSlices.ts
537
+ function U(e, t, n) {
538
+ let r = n.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, "([^/\\\\]+)"), i = new RegExp(r), a = /* @__PURE__ */ new Set(), o = /* @__PURE__ */ new Map();
539
+ for (let t of e) {
540
+ let e = t.fileName.match(i);
541
+ if (e?.[1]) {
542
+ let n = e[1];
543
+ a.add(n), o.has(n) || o.set(n, []), o.get(n)?.push(t);
390
544
  }
391
545
  }
392
- checkBeFreeOfCycles(t) {
393
- let n = /* @__PURE__ */ new Map();
394
- for (let e of this.sliceIds) n.set(e, /* @__PURE__ */ new Set());
395
- for (let [t, r] of this.sliceFiles.entries()) for (let i of r) e.forEachChild(i, (r) => {
396
- if (e.isImportDeclaration(r) && r.moduleSpecifier && e.isStringLiteral(r.moduleSpecifier)) {
397
- let a = r.moduleSpecifier.text, o = e.resolveModuleName(a, i.fileName, this.program.getCompilerOptions(), e.sys);
398
- if (o.resolvedModule && o.resolvedModule.resolvedFileName) {
399
- let e = o.resolvedModule.resolvedFileName.match(this.slicePattern);
400
- if (e && e[1]) {
401
- let r = e[1];
402
- r !== t && this.sliceIds.has(r) && n.get(t).add(r);
546
+ return {
547
+ type: "SliceLocator",
548
+ slicePattern: i,
549
+ sliceIds: a,
550
+ sliceFiles: o,
551
+ program: t
552
+ };
553
+ }
554
+ //#endregion
555
+ //#region src/core/project/parseProject.ts
556
+ function W(t = {}) {
557
+ let r = {}, a = t.tsConfigFilePath || e.findConfigFile(process.cwd(), e.sys.fileExists, "tsconfig.json"), o;
558
+ if (a) {
559
+ let t = e.readConfigFile(a, e.sys.readFile), s = e.parseJsonConfigFileContent(t.config, e.sys, n(a), void 0, a, void 0, [{
560
+ extension: ".vue",
561
+ isMixedContent: !0,
562
+ scriptKind: e.ScriptKind.TS
563
+ }, {
564
+ extension: ".svelte",
565
+ isMixedContent: !0,
566
+ scriptKind: e.ScriptKind.TS
567
+ }]);
568
+ r = s.options;
569
+ let c = e.createCompilerHost(r), l = c.getSourceFile, u;
570
+ try {
571
+ u = i("@vue/compiler-sfc");
572
+ } catch {}
573
+ c.getSourceFile = (t, n, r, i) => {
574
+ if (t.endsWith(".vue")) {
575
+ let r = e.sys.readFile(t);
576
+ if (r) {
577
+ let i = "";
578
+ if (u) {
579
+ let e = u.parse(r), t = e.descriptor.script, n = e.descriptor.scriptSetup;
580
+ t && (i += `${t.content}\n`), n && (i += `${n.content}\n`);
581
+ } else {
582
+ let e = r.match(/<script[^>]*>(.*?)<\/script>/s);
583
+ e && (i = e[1]);
403
584
  }
585
+ return e.createSourceFile(t, i, n, !0, e.ScriptKind.TS);
404
586
  }
405
587
  }
406
- });
407
- let r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Set(), a = [], o = (e, t) => {
408
- r.add(e), i.add(e);
409
- for (let s of n.get(e) || []) if (!r.has(s)) {
410
- if (o(s, [...t, s])) return !0;
411
- } else if (i.has(s)) return a.push(`Cycle detected between slices: ${t.join(" -> ")} -> ${s}`), !0;
412
- return i.delete(e), !1;
413
- };
414
- for (let e of this.sliceIds) r.has(e) || o(e, [e]);
415
- return t ? {
416
- pass: a.length > 0,
417
- message: () => a.length > 0 ? "" : "Expected cycles between slices but found none."
418
- } : {
419
- pass: a.length === 0,
420
- message: () => a.join("\n")
421
- };
422
- }
423
- }, d = class {
424
- program;
425
- typeChecker;
426
- constructor(n = {}) {
427
- let i = {}, a = n.tsConfigFilePath || e.findConfigFile(process.cwd(), e.sys.fileExists, "tsconfig.json");
428
- if (a) {
429
- let n = e.readConfigFile(a, e.sys.readFile), o = e.parseJsonConfigFileContent(n.config, e.sys, t.dirname(a), void 0, a, void 0, [{
430
- extension: ".vue",
431
- isMixedContent: !0,
432
- scriptKind: e.ScriptKind.TS
433
- }, {
434
- extension: ".svelte",
435
- isMixedContent: !0,
436
- scriptKind: e.ScriptKind.TS
437
- }]);
438
- i = o.options;
439
- let s = e.createCompilerHost(i), c = s.getSourceFile, l;
440
- try {
441
- l = r("@vue/compiler-sfc");
442
- } catch {}
443
- s.getSourceFile = (t, n, r, i) => {
444
- if (t.endsWith(".vue")) {
445
- let r = e.sys.readFile(t);
446
- if (r) {
447
- let i = "";
448
- if (l) {
449
- let e = l.parse(r), t = e.descriptor.script, n = e.descriptor.scriptSetup;
450
- t && (i += t.content + "\n"), n && (i += n.content + "\n");
451
- } else {
452
- let e = r.match(/<script[^>]*>(.*?)<\/script>/s);
453
- e && (i = e[1]);
454
- }
455
- return e.createSourceFile(t, i, n, !0, e.ScriptKind.TS);
456
- }
588
+ if (t.endsWith(".svelte")) {
589
+ let r = e.sys.readFile(t);
590
+ if (r) {
591
+ let i = "", a = r.match(/<script[^>]*>(.*?)<\/script>/s);
592
+ return a && (i = a[1]), e.createSourceFile(t, i, n, !0, e.ScriptKind.TS);
457
593
  }
458
- if (t.endsWith(".svelte")) {
459
- let r = e.sys.readFile(t);
460
- if (r) {
461
- let i = "", a = r.match(/<script[^>]*>(.*?)<\/script>/s);
462
- return a && (i = a[1]), e.createSourceFile(t, i, n, !0, e.ScriptKind.TS);
463
- }
594
+ }
595
+ return l(t, n, r, i);
596
+ }, o = e.createProgram({
597
+ rootNames: s.fileNames,
598
+ options: r,
599
+ host: c
600
+ }), o.getTypeChecker();
601
+ } else throw Error("Could not find tsconfig.json");
602
+ let s = () => o.getSourceFiles().filter((e) => !e.isDeclarationFile && !e.fileName.includes("node_modules"));
603
+ return {
604
+ getFiles: (e) => O(s(), o, e),
605
+ getClasses: (t) => {
606
+ let n = [];
607
+ for (let t of s()) {
608
+ let r = (t) => {
609
+ e.isClassDeclaration(t) && n.push(t), e.forEachChild(t, r);
610
+ };
611
+ r(t);
612
+ }
613
+ return v(n, o, t);
614
+ },
615
+ layeredArchitecture: () => {
616
+ let e = L(s(), o), t = {
617
+ layer: (n, r) => (e = R(e, n, r), t),
618
+ whereLayer: (n) => ({
619
+ shouldNotBeAccessedByAnyLayer: () => (e = B(e, n), t),
620
+ shouldOnlyBeAccessedBy: (...r) => (e = V(e, n, r), t)
621
+ }),
622
+ check: () => I(e),
623
+ get data() {
624
+ return e;
464
625
  }
465
- return c(t, n, r, i);
466
- }, this.program = e.createProgram({
467
- rootNames: o.fileNames,
468
- options: i,
469
- host: s
470
- });
471
- } else throw Error("Could not find tsconfig.json");
472
- this.typeChecker = this.program.getTypeChecker();
473
- }
474
- getFiles(e) {
475
- return new i(this.program.getSourceFiles().filter((e) => !e.isDeclarationFile && !e.fileName.includes("node_modules")), this.program, e);
476
- }
477
- getClasses(t) {
478
- let n = this.program.getSourceFiles().filter((e) => !e.isDeclarationFile && !e.fileName.includes("node_modules")), r = [];
479
- for (let t of n) {
480
- let n = (t) => {
481
- e.isClassDeclaration(t) && r.push(t), e.forEachChild(t, n);
482
626
  };
483
- n(t);
627
+ return t;
628
+ },
629
+ getFunctions: (t) => {
630
+ let n = [];
631
+ for (let t of s()) {
632
+ let r = (t) => {
633
+ (e.isFunctionDeclaration(t) || e.isMethodDeclaration(t) || e.isArrowFunction(t)) && n.push(t), e.forEachChild(t, r);
634
+ };
635
+ r(t);
636
+ }
637
+ return F(n, o, t);
638
+ },
639
+ getProperties: (t) => {
640
+ let n = [];
641
+ for (let t of s()) {
642
+ let r = (t) => {
643
+ e.isPropertyDeclaration(t) && n.push(t), e.forEachChild(t, r);
644
+ };
645
+ r(t);
646
+ }
647
+ return H(n, o, t);
648
+ },
649
+ getSlices: (e) => U(s(), o, e)
650
+ };
651
+ }
652
+ //#endregion
653
+ //#region src/core/properties/propertyCheckBeReadonly.ts
654
+ function G(t, n) {
655
+ let r = [];
656
+ for (let i of t.properties) {
657
+ let t = e.isIdentifier(i.name) ? i.name.text : "Anonymous Property", a = (e.canHaveModifiers(i) ? e.getModifiers(i) : void 0)?.some((t) => t.kind === e.SyntaxKind.ReadonlyKeyword);
658
+ n && a ? r.push(`Property ${t} is readonly, but it shouldn't be.`) : !n && !a && r.push(`Property ${t} is not readonly, but it should be.`);
659
+ }
660
+ return {
661
+ pass: r.length === 0,
662
+ message: () => r.join("\n")
663
+ };
664
+ }
665
+ //#endregion
666
+ //#region src/core/slices/sliceCheckBeFreeOfCycles.ts
667
+ function K(t, n) {
668
+ let r = /* @__PURE__ */ new Map();
669
+ for (let e of t.sliceIds) r.set(e, /* @__PURE__ */ new Set());
670
+ for (let [n, i] of t.sliceFiles.entries()) for (let a of i) e.forEachChild(a, (i) => {
671
+ if (e.isImportDeclaration(i) && i.moduleSpecifier && e.isStringLiteral(i.moduleSpecifier)) {
672
+ let o = i.moduleSpecifier.text, s = e.resolveModuleName(o, a.fileName, t.program.getCompilerOptions(), e.sys);
673
+ if (s.resolvedModule?.resolvedFileName) {
674
+ let e = s.resolvedModule.resolvedFileName.match(t.slicePattern);
675
+ if (e?.[1]) {
676
+ let i = e[1];
677
+ i !== n && t.sliceIds.has(i) && r.get(n)?.add(i);
678
+ }
679
+ }
484
680
  }
485
- return new a(r, this.program, t);
486
- }
487
- layeredArchitecture() {
488
- return new o(this.program.getSourceFiles().filter((e) => !e.isDeclarationFile && !e.fileName.includes("node_modules")), this.program);
489
- }
490
- getFunctions(t) {
491
- let n = this.program.getSourceFiles().filter((e) => !e.isDeclarationFile && !e.fileName.includes("node_modules")), r = [];
492
- for (let t of n) {
493
- let n = (t) => {
494
- (e.isFunctionDeclaration(t) || e.isMethodDeclaration(t) || e.isArrowFunction(t)) && r.push(t), e.forEachChild(t, n);
495
- };
496
- n(t);
681
+ });
682
+ let i = /* @__PURE__ */ new Set(), a = /* @__PURE__ */ new Set(), o = [], s = (e, t) => {
683
+ i.add(e), a.add(e);
684
+ for (let n of r.get(e) || []) if (!i.has(n)) {
685
+ if (s(n, [...t, n])) return !0;
686
+ } else if (a.has(n)) return o.push(`Cycle detected between slices: ${t.join(" -> ")} -> ${n}`), !0;
687
+ return a.delete(e), !1;
688
+ };
689
+ for (let e of t.sliceIds) i.has(e) || s(e, [e]);
690
+ return n ? {
691
+ pass: o.length > 0,
692
+ message: () => o.length > 0 ? "" : "Expected cycles between slices but found none."
693
+ } : {
694
+ pass: o.length === 0,
695
+ message: () => o.join("\n")
696
+ };
697
+ }
698
+ //#endregion
699
+ //#region src/core/slices/sliceCheckHaveMaxDistanceFromMainSequence.ts
700
+ function q(t, n, r) {
701
+ let i = [], a = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map();
702
+ for (let e of t.sliceIds) a.set(e, /* @__PURE__ */ new Set()), o.set(e, /* @__PURE__ */ new Set());
703
+ for (let [n, r] of t.sliceFiles.entries()) for (let i of r) e.forEachChild(i, (r) => {
704
+ if (e.isImportDeclaration(r) && r.moduleSpecifier && e.isStringLiteral(r.moduleSpecifier)) {
705
+ let s = r.moduleSpecifier.text, c = e.resolveModuleName(s, i.fileName, t.program.getCompilerOptions(), e.sys);
706
+ if (c.resolvedModule?.resolvedFileName) {
707
+ let e = c.resolvedModule.resolvedFileName.match(t.slicePattern);
708
+ if (e?.[1]) {
709
+ let r = e[1];
710
+ r !== n && t.sliceIds.has(r) && (a.get(n)?.add(r), o.get(r)?.add(n));
711
+ }
712
+ }
497
713
  }
498
- return new c(r, this.program, t);
499
- }
500
- getProperties(t) {
501
- let n = this.program.getSourceFiles().filter((e) => !e.isDeclarationFile && !e.fileName.includes("node_modules")), r = [];
502
- for (let t of n) {
714
+ });
715
+ for (let s of t.sliceIds) {
716
+ let c = a.get(s)?.size, l = o.get(s)?.size, u = t.sliceFiles.get(s), d = 0, f = 0;
717
+ for (let t of u) {
503
718
  let n = (t) => {
504
- e.isPropertyDeclaration(t) && r.push(t), e.forEachChild(t, n);
719
+ e.isClassDeclaration(t) ? (f++, (e.canHaveModifiers(t) ? e.getModifiers(t) : void 0)?.some((t) => t.kind === e.SyntaxKind.AbstractKeyword) && d++) : e.isInterfaceDeclaration(t) && (f++, d++), e.forEachChild(t, n);
505
720
  };
506
721
  n(t);
507
722
  }
508
- return new l(r, this.program, t);
723
+ let p = c + l === 0 ? 0 : c / (l + c), m = f === 0 ? 0 : d / f, h = Math.abs(m + p - 1), g = h > n;
724
+ r && g ? i.push(`Slice ${s} has a Distance from the Main Sequence of ${h.toFixed(2)}, which exceeds the maximum of ${n}, but it shouldn't.`) : !r && g && i.push(`Slice ${s} has a Distance from the Main Sequence of ${h.toFixed(2)}, which exceeds the maximum of ${n}.`);
509
725
  }
510
- getSlices(e) {
511
- return new u(this.program.getSourceFiles().filter((e) => !e.isDeclarationFile && !e.fileName.includes("node_modules")), this.program, e);
512
- }
513
- };
514
- function f(e) {
515
- return new d({ tsConfigFilePath: e });
726
+ return {
727
+ pass: r ? i.length > 0 : i.length === 0,
728
+ message: () => i.join("\n") || (r ? "Expected some slices to exceed maximum distance from main sequence, but none did." : "")
729
+ };
516
730
  }
517
731
  //#endregion
518
732
  //#region src/matchers/index.ts
519
- function p() {
520
- n.extend({
733
+ function J() {
734
+ r.extend({
521
735
  toPass(e) {
522
- let { pass: t, message: n } = e instanceof o ? e.check() : e;
736
+ let t;
737
+ t = e?.data && e.data.type === "LayeredArchitecture" ? I(e.data) : e;
738
+ let { pass: n, message: r } = t;
523
739
  return {
524
- pass: this.isNot ? !t : t,
525
- message: t ? () => "Expected rule not to pass" : () => n()
740
+ pass: this.isNot ? !n : n,
741
+ message: n ? () => "Expected rule not to pass" : () => r()
526
742
  };
527
743
  },
528
744
  toResideInFolder(e, t) {
529
- let { pass: n, message: r } = e.checkResideInFolder(t, this.isNot);
745
+ let n;
746
+ if (e.type === "ClassLocator") n = _(e, t, this.isNot);
747
+ else throw Error(`toResideInFolder matcher does not support ${e.type}`);
530
748
  return {
531
- pass: this.isNot ? !n : n,
532
- message: r
749
+ pass: this.isNot ? !n.pass : n.pass,
750
+ message: n.message
533
751
  };
534
752
  },
535
753
  toHaveModifier(e, t) {
536
- let { pass: n, message: r } = e.checkHaveModifier(t, this.isNot);
754
+ let n;
755
+ if (e.type === "ClassLocator") n = d(e, t, this.isNot);
756
+ else if (e.type === "FunctionLocator") n = M(e, t, this.isNot);
757
+ else throw Error(`toHaveModifier matcher does not support ${e.type}`);
537
758
  return {
538
- pass: this.isNot ? !n : n,
539
- message: r
759
+ pass: this.isNot ? !n.pass : n.pass,
760
+ message: n.message
540
761
  };
541
762
  },
542
763
  toExtendClass(e, t) {
543
- let { pass: n, message: r } = e.checkExtendClass(t, this.isNot);
764
+ let n;
765
+ if (e.type === "ClassLocator") n = a(e, t, this.isNot);
766
+ else throw Error(`toExtendClass matcher does not support ${e.type}`);
544
767
  return {
545
- pass: this.isNot ? !n : n,
546
- message: r
768
+ pass: this.isNot ? !n.pass : n.pass,
769
+ message: n.message
547
770
  };
548
771
  },
549
772
  toImplementInterface(e, t) {
550
- let { pass: n, message: r } = e.checkImplementInterface(t, this.isNot);
773
+ let n;
774
+ if (e.type === "ClassLocator") n = m(e, t, this.isNot);
775
+ else throw Error(`toImplementInterface matcher does not support ${e.type}`);
551
776
  return {
552
- pass: this.isNot ? !n : n,
553
- message: r
777
+ pass: this.isNot ? !n.pass : n.pass,
778
+ message: n.message
554
779
  };
555
780
  },
556
781
  toHaveExplicitReturnType(e) {
557
- let { pass: t, message: n } = e.checkHaveExplicitReturnType(this.isNot);
782
+ let t;
783
+ if (e.type === "FunctionLocator") t = k(e, this.isNot);
784
+ else throw Error(`toHaveExplicitReturnType matcher does not support ${e.type}`);
558
785
  return {
559
- pass: this.isNot ? !t : t,
560
- message: n
786
+ pass: this.isNot ? !t.pass : t.pass,
787
+ message: t.message
561
788
  };
562
789
  },
563
790
  toBeReadonly(e) {
564
- let { pass: t, message: n } = e.checkBeReadonly(this.isNot);
791
+ let t;
792
+ if (e.type === "PropertyLocator") t = G(e, this.isNot);
793
+ else throw Error(`toBeReadonly matcher does not support ${e.type}`);
565
794
  return {
566
- pass: this.isNot ? !t : t,
567
- message: n
795
+ pass: this.isNot ? !t.pass : t.pass,
796
+ message: t.message
568
797
  };
569
798
  },
570
799
  toDependOnFilesInFolder(e, t) {
571
- let { pass: n, message: r } = e.checkDependOnFilesInFolder(t, this.isNot);
800
+ let n;
801
+ if (e.type === "FileLocator") n = b(e, t, this.isNot);
802
+ else throw Error(`toDependOnFilesInFolder matcher does not support ${e.type}`);
572
803
  return {
573
- pass: this.isNot ? !n : n,
574
- message: r
804
+ pass: this.isNot ? !n.pass : n.pass,
805
+ message: n.message
575
806
  };
576
807
  },
577
808
  toBeFreeOfCycles(e) {
578
- let { pass: t, message: n } = e.checkBeFreeOfCycles(this.isNot);
809
+ let t;
810
+ if (e.type === "FileLocator") t = x(e, this.isNot);
811
+ else if (e.type === "SliceLocator") t = K(e, this.isNot);
812
+ else throw Error(`toBeFreeOfCycles matcher does not support ${e.type}`);
579
813
  return {
580
- pass: this.isNot ? !t : t,
581
- message: n
814
+ pass: this.isNot ? !t.pass : t.pass,
815
+ message: t.message
582
816
  };
583
817
  },
584
818
  toMatchNamePattern(e, t) {
585
- let { pass: n, message: r } = e.checkMatchNamePattern(t, this.isNot);
819
+ let n;
820
+ if (e.type === "FileLocator") n = D(e, t, this.isNot);
821
+ else if (e.type === "ClassLocator") n = g(e, t, this.isNot);
822
+ else if (e.type === "FunctionLocator") n = P(e, t, this.isNot);
823
+ else throw Error(`toMatchNamePattern matcher does not support ${e.type}`);
586
824
  return {
587
- pass: this.isNot ? !n : n,
588
- message: r
825
+ pass: this.isNot ? !n.pass : n.pass,
826
+ message: n.message
827
+ };
828
+ },
829
+ toHaveMaxCyclomaticComplexity(e, t) {
830
+ let n;
831
+ if (e.type === "FileLocator") n = S(e, t, this.isNot);
832
+ else if (e.type === "ClassLocator") n = l(e, t, this.isNot);
833
+ else if (e.type === "FunctionLocator") n = A(e, t, this.isNot);
834
+ else throw Error(`toHaveMaxCyclomaticComplexity matcher does not support ${e.type}`);
835
+ return {
836
+ pass: this.isNot ? !n.pass : n.pass,
837
+ message: n.message
838
+ };
839
+ },
840
+ toHaveMinMaintainabilityIndex(e, t) {
841
+ let n;
842
+ if (e.type === "FileLocator") n = E(e, t, this.isNot);
843
+ else if (e.type === "FunctionLocator") n = j(e, t, this.isNot);
844
+ else throw Error(`toHaveMinMaintainabilityIndex matcher does not support ${e.type}`);
845
+ return {
846
+ pass: this.isNot ? !n.pass : n.pass,
847
+ message: n.message
848
+ };
849
+ },
850
+ toHaveMaxDistanceFromMainSequence(e, t) {
851
+ let n;
852
+ if (e.type === "SliceLocator") n = q(e, t, this.isNot);
853
+ else throw Error(`toHaveMaxDistanceFromMainSequence matcher does not support ${e.type}`);
854
+ return {
855
+ pass: this.isNot ? !n.pass : n.pass,
856
+ message: n.message
857
+ };
858
+ },
859
+ toHaveNameMatchingFileName(e) {
860
+ let t;
861
+ if (e.type === "FunctionLocator") t = N(e, this.isNot);
862
+ else if (e.type === "ClassLocator") t = p(e, this.isNot);
863
+ else throw Error(`toHaveNameMatchingFileName matcher does not support ${e.type}`);
864
+ return {
865
+ pass: this.isNot ? !t.pass : t.pass,
866
+ message: t.message
867
+ };
868
+ },
869
+ toHaveMaxExportedFunctions(e, t) {
870
+ let n;
871
+ if (e.type === "FileLocator") n = C(e, t, this.isNot);
872
+ else throw Error(`toHaveMaxExportedFunctions matcher does not support ${e.type}`);
873
+ return {
874
+ pass: this.isNot ? !n.pass : n.pass,
875
+ message: n.message
589
876
  };
590
877
  }
591
878
  });
592
879
  }
593
880
  //#endregion
594
- export { a as ClassLocator, i as FileLocator, c as FunctionLocator, s as LayerAssertionBuilder, o as LayeredArchitectureBuilder, d as Project, l as PropertyLocator, u as SliceLocator, f as parseProject, p as setupMatchers };
881
+ export { b as checkDependOnFilesInFolder, I as checkLayeredArchitecture, a as classCheckExtendClass, l as classCheckHaveMaxCyclomaticComplexity, d as classCheckHaveModifier, p as classCheckHaveNameMatchingFileName, m as classCheckImplementInterface, g as classCheckMatchNamePattern, _ as classCheckResideInFolder, L as createLayeredArchitecture, x as fileCheckBeFreeOfCycles, S as fileCheckHaveMaxCyclomaticComplexity, C as fileCheckHaveMaxExportedFunctions, E as fileCheckHaveMinMaintainabilityIndex, D as fileCheckMatchNamePattern, k as functionCheckHaveExplicitReturnType, A as functionCheckHaveMaxCyclomaticComplexity, j as functionCheckHaveMinMaintainabilityIndex, M as functionCheckHaveModifier, N as functionCheckHaveNameMatchingFileName, P as functionCheckMatchNamePattern, R as layer, B as layerShouldNotBeAccessedByAnyLayer, V as layerShouldOnlyBeAccessedBy, v as locateClasses, O as locateFiles, F as locateFunctions, H as locateProperties, U as locateSlices, W as parseProject, G as propertyCheckBeReadonly, J as setupMatchers, K as sliceCheckBeFreeOfCycles, q as sliceCheckHaveMaxDistanceFromMainSequence };
595
882
 
596
883
  //# sourceMappingURL=index.mjs.map