@archest/vitest 1.0.0 → 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.
Files changed (95) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.js +1 -17
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +118 -551
  5. package/dist/index.mjs.map +1 -1
  6. package/dist/matchers/index.d.ts +21 -0
  7. package/dist/matchers/models.d.ts +201 -0
  8. package/node_modules/@archest/core/dist/classes/classCheckExtendClass.d.ts +3 -0
  9. package/node_modules/@archest/core/dist/classes/classCheckHaveMaxCyclomaticComplexity.d.ts +3 -0
  10. package/node_modules/@archest/core/dist/classes/classCheckHaveModifier.d.ts +3 -0
  11. package/node_modules/@archest/core/dist/classes/classCheckHaveNameMatchingFileName.d.ts +3 -0
  12. package/node_modules/@archest/core/dist/classes/classCheckImplementInterface.d.ts +3 -0
  13. package/node_modules/@archest/core/dist/classes/classCheckMatchNamePattern.d.ts +3 -0
  14. package/node_modules/@archest/core/dist/classes/classCheckResideInFolder.d.ts +3 -0
  15. package/node_modules/@archest/core/dist/classes/locateClasses.d.ts +5 -0
  16. package/node_modules/@archest/core/dist/classes/types.d.ts +25 -0
  17. package/node_modules/@archest/core/dist/dto.d.ts +78 -0
  18. package/node_modules/@archest/core/dist/files/checkDependOnExternalModule.d.ts +3 -0
  19. package/node_modules/@archest/core/dist/files/checkDependOnFilesInFolder.d.ts +3 -0
  20. package/node_modules/@archest/core/dist/files/fileCheckBeFreeOfCycles.d.ts +3 -0
  21. package/node_modules/@archest/core/dist/files/fileCheckHaveMaxCyclomaticComplexity.d.ts +3 -0
  22. package/node_modules/@archest/core/dist/files/fileCheckHaveMaxExportedFunctions.d.ts +3 -0
  23. package/node_modules/@archest/core/dist/files/fileCheckHaveMinMaintainabilityIndex.d.ts +3 -0
  24. package/node_modules/@archest/core/dist/files/fileCheckMatchNamePattern.d.ts +3 -0
  25. package/node_modules/@archest/core/dist/files/getFileDependencies.d.ts +2 -0
  26. package/node_modules/@archest/core/dist/files/locateFiles.d.ts +4 -0
  27. package/node_modules/@archest/core/dist/files/types.d.ts +17 -0
  28. package/node_modules/@archest/core/dist/functions/functionCheckHaveExplicitReturnType.d.ts +3 -0
  29. package/node_modules/@archest/core/dist/functions/functionCheckHaveMaxCyclomaticComplexity.d.ts +3 -0
  30. package/node_modules/@archest/core/dist/functions/functionCheckHaveMinMaintainabilityIndex.d.ts +3 -0
  31. package/node_modules/@archest/core/dist/functions/functionCheckHaveModifier.d.ts +3 -0
  32. package/node_modules/@archest/core/dist/functions/functionCheckHaveNameMatchingFileName.d.ts +3 -0
  33. package/node_modules/@archest/core/dist/functions/functionCheckMatchNamePattern.d.ts +3 -0
  34. package/node_modules/@archest/core/dist/functions/locateFunctions.d.ts +5 -0
  35. package/node_modules/@archest/core/dist/functions/types.d.ts +19 -0
  36. package/node_modules/@archest/core/dist/index.d.ts +43 -0
  37. package/node_modules/@archest/core/dist/index.js +14 -0
  38. package/node_modules/@archest/core/dist/index.js.map +1 -0
  39. package/node_modules/@archest/core/dist/index.mjs +615 -0
  40. package/node_modules/@archest/core/dist/index.mjs.map +1 -0
  41. package/node_modules/@archest/core/dist/layers/checkLayeredArchitecture.d.ts +3 -0
  42. package/node_modules/@archest/core/dist/layers/createLayeredArchitecture.d.ts +3 -0
  43. package/node_modules/@archest/core/dist/layers/getLayerDependencies.d.ts +2 -0
  44. package/node_modules/@archest/core/dist/layers/layer.d.ts +2 -0
  45. package/node_modules/@archest/core/dist/layers/layerShouldNotBeAccessedByAnyLayer.d.ts +2 -0
  46. package/node_modules/@archest/core/dist/layers/layerShouldOnlyBeAccessedBy.d.ts +2 -0
  47. package/node_modules/@archest/core/dist/layers/types.d.ts +8 -0
  48. package/node_modules/@archest/core/dist/metrics/calculateCyclomaticComplexity.d.ts +2 -0
  49. package/node_modules/@archest/core/dist/metrics/calculateMaintainabilityIndex.d.ts +2 -0
  50. package/node_modules/@archest/core/dist/project/parseProject.d.ts +55 -0
  51. package/node_modules/@archest/core/dist/properties/locateProperties.d.ts +5 -0
  52. package/node_modules/@archest/core/dist/properties/propertyCheckBeReadonly.d.ts +3 -0
  53. package/node_modules/@archest/core/dist/properties/types.d.ts +17 -0
  54. package/node_modules/@archest/core/dist/shared/sharedCheckHaveMaxCyclomaticComplexity.d.ts +1 -0
  55. package/node_modules/@archest/core/dist/shared/sharedCheckHaveMinMaintainabilityIndex.d.ts +1 -0
  56. package/node_modules/@archest/core/dist/shared/sharedCheckHaveModifier.d.ts +7 -0
  57. package/node_modules/@archest/core/dist/shared/sharedCheckHaveNameMatchingFileName.d.ts +3 -0
  58. package/node_modules/@archest/core/dist/shared/sharedCheckMatchNamePattern.d.ts +1 -0
  59. package/node_modules/@archest/core/dist/slices/locateSlices.d.ts +3 -0
  60. package/node_modules/@archest/core/dist/slices/sliceCheckBeFreeOfCycles.d.ts +3 -0
  61. package/node_modules/@archest/core/dist/slices/sliceCheckHaveMaxDistanceFromMainSequence.d.ts +3 -0
  62. package/node_modules/@archest/core/dist/slices/types.d.ts +8 -0
  63. package/node_modules/@archest/core/dist/types.d.ts +11 -0
  64. package/node_modules/@archest/core/dist/utils/ruleBuilder.d.ts +6 -0
  65. package/node_modules/@archest/core/package.json +49 -0
  66. package/node_modules/@archest/core-rust/core-rust.darwin-arm64.node +0 -0
  67. package/node_modules/@archest/core-rust/core-rust.linux-x64-gnu.node +0 -0
  68. package/node_modules/@archest/core-rust/core-rust.win32-x64-msvc.node +0 -0
  69. package/node_modules/@archest/core-rust/index.d.ts +16 -0
  70. package/node_modules/@archest/core-rust/index.js +316 -0
  71. package/node_modules/@archest/core-rust/package.json +34 -0
  72. package/package.json +12 -1
  73. package/dist/src/core/ClassLocator.d.ts +0 -20
  74. package/dist/src/core/FileLocator.d.ts +0 -15
  75. package/dist/src/core/FunctionLocator.d.ts +0 -15
  76. package/dist/src/core/LayerLocator.d.ts +0 -23
  77. package/dist/src/core/Project.d.ts +0 -20
  78. package/dist/src/core/PropertyLocator.d.ts +0 -12
  79. package/dist/src/core/SliceLocator.d.ts +0 -10
  80. package/dist/src/core/types.d.ts +0 -4
  81. package/dist/src/index.d.ts +0 -9
  82. package/dist/src/matchers/index.d.ts +0 -15
  83. package/src/core/ClassLocator.ts +0 -226
  84. package/src/core/FileLocator.ts +0 -168
  85. package/src/core/FunctionLocator.ts +0 -105
  86. package/src/core/LayerLocator.ts +0 -119
  87. package/src/core/Project.ts +0 -171
  88. package/src/core/PropertyLocator.ts +0 -50
  89. package/src/core/SliceLocator.ts +0 -92
  90. package/src/core/types.ts +0 -4
  91. package/src/index.ts +0 -9
  92. package/src/matchers/index.ts +0 -113
  93. package/test/architecture.test.ts +0 -59
  94. package/tsconfig.json +0 -17
  95. package/vite.config.ts +0 -18
package/dist/index.mjs CHANGED
@@ -1,596 +1,163 @@
1
- import * as e from "typescript";
2
- import * as t from "path";
3
- import { expect as n } from "vitest";
4
- //#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
- if (typeof require < "u") return require.apply(this, arguments);
7
- 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));
16
- }
17
- this.files = r;
18
- }
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));
27
- }
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
- }
38
- return {
39
- pass: n.length === 0,
40
- message: () => n.join("\n")
41
- };
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;
59
- };
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(" -> ")}`);
63
- return {
64
- pass: t.length === 0,
65
- message: () => t.join("\n")
66
- };
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
- }
74
- return {
75
- pass: n.length === 0,
76
- message: () => n.join("\n")
77
- };
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;
126
- break;
127
- default: throw Error(`Modifier ${r.havingModifier} is not fully supported.`);
128
- }
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
- }
134
- this.classes = i;
135
- }
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
- }
142
- return {
143
- pass: n.length === 0,
144
- message: () => n.join("\n")
145
- };
146
- }
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.`);
152
- }
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
- }
169
- }
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
- }
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
- }
188
- }
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
- }
191
- return {
192
- pass: r.length === 0,
193
- message: () => r.join("\n")
194
- };
195
- }
196
- checkHaveModifier(t, n) {
197
- let r;
198
- switch (t) {
199
- case "export":
200
- r = e.SyntaxKind.ExportKeyword;
201
- break;
202
- case "default":
203
- r = e.SyntaxKind.DefaultKeyword;
204
- break;
205
- case "abstract":
206
- r = e.SyntaxKind.AbstractKeyword;
207
- 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.`);
214
- }
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;
267
- }
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.`);
318
- }
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.`);
323
- }
324
- return {
325
- pass: i.length === 0,
326
- message: () => i.join("\n")
327
- };
328
- }
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
- }
335
- return {
336
- pass: n.length === 0,
337
- message: () => n.join("\n")
338
- };
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.`);
345
- }
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));
362
- }
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.`);
370
- }
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
- }
390
- }
391
- }
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);
403
- }
404
- }
405
- }
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
- }
457
- }
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
- }
464
- }
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
- };
483
- n(t);
484
- }
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);
497
- }
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) {
503
- let n = (t) => {
504
- e.isPropertyDeclaration(t) && r.push(t), e.forEachChild(t, n);
505
- };
506
- n(t);
507
- }
508
- return new l(r, this.program, t);
509
- }
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 });
516
- }
517
- //#endregion
1
+ import { checkDependOnExternalModule as e, checkDependOnFilesInFolder as t, checkLayeredArchitecture as n, classCheckExtendClass as r, classCheckHaveMaxCyclomaticComplexity as i, classCheckHaveModifier as a, classCheckHaveNameMatchingFileName as o, classCheckImplementInterface as s, classCheckMatchNamePattern as c, classCheckResideInFolder as l, fileCheckBeFreeOfCycles as u, fileCheckHaveMaxCyclomaticComplexity as d, fileCheckHaveMaxExportedFunctions as f, fileCheckHaveMinMaintainabilityIndex as p, fileCheckMatchNamePattern as m, functionCheckHaveExplicitReturnType as h, functionCheckHaveMaxCyclomaticComplexity as g, functionCheckHaveMinMaintainabilityIndex as _, functionCheckHaveModifier as v, functionCheckHaveNameMatchingFileName as y, functionCheckMatchNamePattern as b, parseProject as x, propertyCheckBeReadonly as S, sliceCheckBeFreeOfCycles as C, sliceCheckHaveMaxDistanceFromMainSequence as w } from "@archest/core";
2
+ import { expect as T } from "vitest";
518
3
  //#region src/matchers/index.ts
519
- function p() {
520
- n.extend({
4
+ function E() {
5
+ T.extend({
521
6
  toPass(e) {
522
- let { pass: t, message: n } = e instanceof o ? e.check() : e;
7
+ let t;
8
+ t = e?.data && e.data.type === "LayeredArchitecture" ? n(e.data) : e;
9
+ let { pass: r, message: i } = t;
523
10
  return {
524
- pass: this.isNot ? !t : t,
525
- message: t ? () => "Expected rule not to pass" : () => n()
11
+ pass: this.isNot ? !r : r,
12
+ message: r ? () => "Expected rule not to pass" : () => i()
526
13
  };
527
14
  },
528
15
  toResideInFolder(e, t) {
529
- let { pass: n, message: r } = e.checkResideInFolder(t, this.isNot);
16
+ let n;
17
+ if (e.type === "ClassLocator") n = l(e, t, this.isNot);
18
+ else throw Error(`toResideInFolder matcher does not support ${e.type}`);
530
19
  return {
531
- pass: this.isNot ? !n : n,
532
- message: r
20
+ pass: this.isNot ? !n.pass : n.pass,
21
+ message: n.message
533
22
  };
534
23
  },
535
24
  toHaveModifier(e, t) {
536
- let { pass: n, message: r } = e.checkHaveModifier(t, this.isNot);
25
+ let n;
26
+ if (e.type === "ClassLocator") n = a(e, t, this.isNot);
27
+ else if (e.type === "FunctionLocator") n = v(e, t, this.isNot);
28
+ else throw Error(`toHaveModifier matcher does not support ${e.type}`);
537
29
  return {
538
- pass: this.isNot ? !n : n,
539
- message: r
30
+ pass: this.isNot ? !n.pass : n.pass,
31
+ message: n.message
540
32
  };
541
33
  },
542
34
  toExtendClass(e, t) {
543
- let { pass: n, message: r } = e.checkExtendClass(t, this.isNot);
35
+ let n;
36
+ if (e.type === "ClassLocator") n = r(e, t, this.isNot);
37
+ else throw Error(`toExtendClass matcher does not support ${e.type}`);
544
38
  return {
545
- pass: this.isNot ? !n : n,
546
- message: r
39
+ pass: this.isNot ? !n.pass : n.pass,
40
+ message: n.message
547
41
  };
548
42
  },
549
43
  toImplementInterface(e, t) {
550
- let { pass: n, message: r } = e.checkImplementInterface(t, this.isNot);
44
+ let n;
45
+ if (e.type === "ClassLocator") n = s(e, t, this.isNot);
46
+ else throw Error(`toImplementInterface matcher does not support ${e.type}`);
551
47
  return {
552
- pass: this.isNot ? !n : n,
553
- message: r
48
+ pass: this.isNot ? !n.pass : n.pass,
49
+ message: n.message
554
50
  };
555
51
  },
556
52
  toHaveExplicitReturnType(e) {
557
- let { pass: t, message: n } = e.checkHaveExplicitReturnType(this.isNot);
53
+ let t;
54
+ if (e.type === "FunctionLocator") t = h(e, this.isNot);
55
+ else throw Error(`toHaveExplicitReturnType matcher does not support ${e.type}`);
558
56
  return {
559
- pass: this.isNot ? !t : t,
560
- message: n
57
+ pass: this.isNot ? !t.pass : t.pass,
58
+ message: t.message
561
59
  };
562
60
  },
563
61
  toBeReadonly(e) {
564
- let { pass: t, message: n } = e.checkBeReadonly(this.isNot);
62
+ let t;
63
+ if (e.type === "PropertyLocator") t = S(e, this.isNot);
64
+ else throw Error(`toBeReadonly matcher does not support ${e.type}`);
565
65
  return {
566
- pass: this.isNot ? !t : t,
567
- message: n
66
+ pass: this.isNot ? !t.pass : t.pass,
67
+ message: t.message
568
68
  };
569
69
  },
570
- toDependOnFilesInFolder(e, t) {
571
- let { pass: n, message: r } = e.checkDependOnFilesInFolder(t, this.isNot);
70
+ toDependOnFilesInFolder(e, n) {
71
+ let r;
72
+ if (e.type === "FileLocator") r = t(e, n, this.isNot);
73
+ else throw Error(`toDependOnFilesInFolder matcher does not support ${e.type}`);
572
74
  return {
573
- pass: this.isNot ? !n : n,
574
- message: r
75
+ pass: this.isNot ? !r.pass : r.pass,
76
+ message: r.message
77
+ };
78
+ },
79
+ toDependOnExternalModule(t, n) {
80
+ let r;
81
+ if (t.type === "FileLocator") r = e(t, n, this.isNot);
82
+ else throw Error(`toDependOnExternalModule matcher does not support ${t.type}`);
83
+ return {
84
+ pass: this.isNot ? !r.pass : r.pass,
85
+ message: r.message
575
86
  };
576
87
  },
577
88
  toBeFreeOfCycles(e) {
578
- let { pass: t, message: n } = e.checkBeFreeOfCycles(this.isNot);
89
+ let t;
90
+ if (e.type === "FileLocator") t = u(e, this.isNot);
91
+ else if (e.type === "SliceLocator") t = C(e, this.isNot);
92
+ else throw Error(`toBeFreeOfCycles matcher does not support ${e.type}`);
579
93
  return {
580
- pass: this.isNot ? !t : t,
581
- message: n
94
+ pass: this.isNot ? !t.pass : t.pass,
95
+ message: t.message
582
96
  };
583
97
  },
584
98
  toMatchNamePattern(e, t) {
585
- let { pass: n, message: r } = e.checkMatchNamePattern(t, this.isNot);
99
+ let n;
100
+ if (e.type === "FileLocator") n = m(e, t, this.isNot);
101
+ else if (e.type === "ClassLocator") n = c(e, t, this.isNot);
102
+ else if (e.type === "FunctionLocator") n = b(e, t, this.isNot);
103
+ else throw Error(`toMatchNamePattern matcher does not support ${e.type}`);
104
+ return {
105
+ pass: this.isNot ? !n.pass : n.pass,
106
+ message: n.message
107
+ };
108
+ },
109
+ toHaveMaxCyclomaticComplexity(e, t) {
110
+ let n;
111
+ if (e.type === "FileLocator") n = d(e, t, this.isNot);
112
+ else if (e.type === "ClassLocator") n = i(e, t, this.isNot);
113
+ else if (e.type === "FunctionLocator") n = g(e, t, this.isNot);
114
+ else throw Error(`toHaveMaxCyclomaticComplexity matcher does not support ${e.type}`);
115
+ return {
116
+ pass: this.isNot ? !n.pass : n.pass,
117
+ message: n.message
118
+ };
119
+ },
120
+ toHaveMinMaintainabilityIndex(e, t) {
121
+ let n;
122
+ if (e.type === "FileLocator") n = p(e, t, this.isNot);
123
+ else if (e.type === "FunctionLocator") n = _(e, t, this.isNot);
124
+ else throw Error(`toHaveMinMaintainabilityIndex matcher does not support ${e.type}`);
125
+ return {
126
+ pass: this.isNot ? !n.pass : n.pass,
127
+ message: n.message
128
+ };
129
+ },
130
+ toHaveMaxDistanceFromMainSequence(e, t) {
131
+ let n;
132
+ if (e.type === "SliceLocator") n = w(e, t, this.isNot);
133
+ else throw Error(`toHaveMaxDistanceFromMainSequence matcher does not support ${e.type}`);
134
+ return {
135
+ pass: this.isNot ? !n.pass : n.pass,
136
+ message: n.message
137
+ };
138
+ },
139
+ toHaveNameMatchingFileName(e) {
140
+ let t;
141
+ if (e.type === "FunctionLocator") t = y(e, this.isNot);
142
+ else if (e.type === "ClassLocator") t = o(e, this.isNot);
143
+ else throw Error(`toHaveNameMatchingFileName matcher does not support ${e.type}`);
144
+ return {
145
+ pass: this.isNot ? !t.pass : t.pass,
146
+ message: t.message
147
+ };
148
+ },
149
+ toHaveMaxExportedFunctions(e, t) {
150
+ let n;
151
+ if (e.type === "FileLocator") n = f(e, t, this.isNot);
152
+ else throw Error(`toHaveMaxExportedFunctions matcher does not support ${e.type}`);
586
153
  return {
587
- pass: this.isNot ? !n : n,
588
- message: r
154
+ pass: this.isNot ? !n.pass : n.pass,
155
+ message: n.message
589
156
  };
590
157
  }
591
158
  });
592
159
  }
593
160
  //#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 };
161
+ export { x as parseProject, E as setupMatchers };
595
162
 
596
163
  //# sourceMappingURL=index.mjs.map