@nielspeter/eess-ts 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +364 -0
- package/dist/builders/call-rule-builder.d.ts +199 -0
- package/dist/builders/call-rule-builder.d.ts.map +1 -0
- package/dist/builders/call-rule-builder.js +254 -0
- package/dist/builders/call-rule-builder.js.map +1 -0
- package/dist/builders/class-rule-builder.d.ts +136 -0
- package/dist/builders/class-rule-builder.d.ts.map +1 -0
- package/dist/builders/class-rule-builder.js +253 -0
- package/dist/builders/class-rule-builder.js.map +1 -0
- package/dist/builders/cross-layer-builder.d.ts +96 -0
- package/dist/builders/cross-layer-builder.d.ts.map +1 -0
- package/dist/builders/cross-layer-builder.js +172 -0
- package/dist/builders/cross-layer-builder.js.map +1 -0
- package/dist/builders/function-rule-builder.d.ts +198 -0
- package/dist/builders/function-rule-builder.d.ts.map +1 -0
- package/dist/builders/function-rule-builder.js +287 -0
- package/dist/builders/function-rule-builder.js.map +1 -0
- package/dist/builders/jsx-rule-builder.d.ts +113 -0
- package/dist/builders/jsx-rule-builder.d.ts.map +1 -0
- package/dist/builders/jsx-rule-builder.js +150 -0
- package/dist/builders/jsx-rule-builder.js.map +1 -0
- package/dist/builders/module-rule-builder.d.ts +159 -0
- package/dist/builders/module-rule-builder.d.ts.map +1 -0
- package/dist/builders/module-rule-builder.js +237 -0
- package/dist/builders/module-rule-builder.js.map +1 -0
- package/dist/builders/scoped-function-rule-builder.d.ts +21 -0
- package/dist/builders/scoped-function-rule-builder.d.ts.map +1 -0
- package/dist/builders/scoped-function-rule-builder.js +26 -0
- package/dist/builders/scoped-function-rule-builder.js.map +1 -0
- package/dist/builders/slice-rule-builder.d.ts +85 -0
- package/dist/builders/slice-rule-builder.d.ts.map +1 -0
- package/dist/builders/slice-rule-builder.js +134 -0
- package/dist/builders/slice-rule-builder.js.map +1 -0
- package/dist/builders/type-rule-builder.d.ts +103 -0
- package/dist/builders/type-rule-builder.d.ts.map +1 -0
- package/dist/builders/type-rule-builder.js +170 -0
- package/dist/builders/type-rule-builder.js.map +1 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +4 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/commands/baseline.d.ts +11 -0
- package/dist/cli/commands/baseline.d.ts.map +1 -0
- package/dist/cli/commands/baseline.js +16 -0
- package/dist/cli/commands/baseline.js.map +1 -0
- package/dist/cli/commands/check.d.ts +21 -0
- package/dist/cli/commands/check.d.ts.map +1 -0
- package/dist/cli/commands/check.js +94 -0
- package/dist/cli/commands/check.js.map +1 -0
- package/dist/cli/commands/explain.d.ts +9 -0
- package/dist/cli/commands/explain.d.ts.map +1 -0
- package/dist/cli/commands/explain.js +49 -0
- package/dist/cli/commands/explain.js.map +1 -0
- package/dist/cli/config.d.ts +31 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +20 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/index.d.ts +21 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +168 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/load-rules.d.ts +20 -0
- package/dist/cli/load-rules.d.ts.map +1 -0
- package/dist/cli/load-rules.js +97 -0
- package/dist/cli/load-rules.js.map +1 -0
- package/dist/cli/resolve-config.d.ts +11 -0
- package/dist/cli/resolve-config.d.ts.map +1 -0
- package/dist/cli/resolve-config.js +61 -0
- package/dist/cli/resolve-config.js.map +1 -0
- package/dist/cli/watch.d.ts +49 -0
- package/dist/cli/watch.d.ts.map +1 -0
- package/dist/cli/watch.js +138 -0
- package/dist/cli/watch.js.map +1 -0
- package/dist/conditions/body-analysis-function.d.ts +23 -0
- package/dist/conditions/body-analysis-function.d.ts.map +1 -0
- package/dist/conditions/body-analysis-function.js +103 -0
- package/dist/conditions/body-analysis-function.js.map +1 -0
- package/dist/conditions/body-analysis-module.d.ts +27 -0
- package/dist/conditions/body-analysis-module.d.ts.map +1 -0
- package/dist/conditions/body-analysis-module.js +99 -0
- package/dist/conditions/body-analysis-module.js.map +1 -0
- package/dist/conditions/body-analysis.d.ts +34 -0
- package/dist/conditions/body-analysis.d.ts.map +1 -0
- package/dist/conditions/body-analysis.js +95 -0
- package/dist/conditions/body-analysis.js.map +1 -0
- package/dist/conditions/call.d.ts +62 -0
- package/dist/conditions/call.d.ts.map +1 -0
- package/dist/conditions/call.js +267 -0
- package/dist/conditions/call.js.map +1 -0
- package/dist/conditions/catch-analysis.d.ts +31 -0
- package/dist/conditions/catch-analysis.d.ts.map +1 -0
- package/dist/conditions/catch-analysis.js +78 -0
- package/dist/conditions/catch-analysis.js.map +1 -0
- package/dist/conditions/class.d.ts +33 -0
- package/dist/conditions/class.d.ts.map +1 -0
- package/dist/conditions/class.js +110 -0
- package/dist/conditions/class.js.map +1 -0
- package/dist/conditions/cross-layer.d.ts +28 -0
- package/dist/conditions/cross-layer.d.ts.map +1 -0
- package/dist/conditions/cross-layer.js +105 -0
- package/dist/conditions/cross-layer.js.map +1 -0
- package/dist/conditions/dependency.d.ts +73 -0
- package/dist/conditions/dependency.d.ts.map +1 -0
- package/dist/conditions/dependency.js +177 -0
- package/dist/conditions/dependency.js.map +1 -0
- package/dist/conditions/exports.d.ts +33 -0
- package/dist/conditions/exports.d.ts.map +1 -0
- package/dist/conditions/exports.js +101 -0
- package/dist/conditions/exports.js.map +1 -0
- package/dist/conditions/function.d.ts +79 -0
- package/dist/conditions/function.d.ts.map +1 -0
- package/dist/conditions/function.js +167 -0
- package/dist/conditions/function.js.map +1 -0
- package/dist/conditions/helpers.d.ts +14 -0
- package/dist/conditions/helpers.d.ts.map +1 -0
- package/dist/conditions/helpers.js +26 -0
- package/dist/conditions/helpers.js.map +1 -0
- package/dist/conditions/jsx.d.ts +40 -0
- package/dist/conditions/jsx.d.ts.map +1 -0
- package/dist/conditions/jsx.js +133 -0
- package/dist/conditions/jsx.js.map +1 -0
- package/dist/conditions/members.d.ts +74 -0
- package/dist/conditions/members.d.ts.map +1 -0
- package/dist/conditions/members.js +224 -0
- package/dist/conditions/members.js.map +1 -0
- package/dist/conditions/pattern.d.ts +20 -0
- package/dist/conditions/pattern.d.ts.map +1 -0
- package/dist/conditions/pattern.js +108 -0
- package/dist/conditions/pattern.js.map +1 -0
- package/dist/conditions/reverse-dependency.d.ts +28 -0
- package/dist/conditions/reverse-dependency.d.ts.map +1 -0
- package/dist/conditions/reverse-dependency.js +275 -0
- package/dist/conditions/reverse-dependency.js.map +1 -0
- package/dist/conditions/slice.d.ts +49 -0
- package/dist/conditions/slice.d.ts.map +1 -0
- package/dist/conditions/slice.js +153 -0
- package/dist/conditions/slice.js.map +1 -0
- package/dist/conditions/structural.d.ts +58 -0
- package/dist/conditions/structural.d.ts.map +1 -0
- package/dist/conditions/structural.js +102 -0
- package/dist/conditions/structural.js.map +1 -0
- package/dist/conditions/type-level.d.ts +29 -0
- package/dist/conditions/type-level.d.ts.map +1 -0
- package/dist/conditions/type-level.js +48 -0
- package/dist/conditions/type-level.js.map +1 -0
- package/dist/core/import-options.d.ts +32 -0
- package/dist/core/import-options.d.ts.map +1 -0
- package/dist/core/import-options.js +29 -0
- package/dist/core/import-options.js.map +1 -0
- package/dist/core/module-dependencies.d.ts +28 -0
- package/dist/core/module-dependencies.d.ts.map +1 -0
- package/dist/core/module-dependencies.js +35 -0
- package/dist/core/module-dependencies.js.map +1 -0
- package/dist/core/pair-condition.d.ts +10 -0
- package/dist/core/pair-condition.d.ts.map +1 -0
- package/dist/core/pair-condition.js +2 -0
- package/dist/core/pair-condition.js.map +1 -0
- package/dist/core/project.d.ts +68 -0
- package/dist/core/project.d.ts.map +1 -0
- package/dist/core/project.js +127 -0
- package/dist/core/project.js.map +1 -0
- package/dist/core/type-matcher.d.ts +10 -0
- package/dist/core/type-matcher.d.ts.map +1 -0
- package/dist/core/type-matcher.js +2 -0
- package/dist/core/type-matcher.js.map +1 -0
- package/dist/core/violation.d.ts +38 -0
- package/dist/core/violation.d.ts.map +1 -0
- package/dist/core/violation.js +130 -0
- package/dist/core/violation.js.map +1 -0
- package/dist/graphql/index.d.ts +76 -0
- package/dist/graphql/index.d.ts.map +1 -0
- package/dist/graphql/index.js +108 -0
- package/dist/graphql/index.js.map +1 -0
- package/dist/graphql/resolver-rule-builder.d.ts +75 -0
- package/dist/graphql/resolver-rule-builder.d.ts.map +1 -0
- package/dist/graphql/resolver-rule-builder.js +146 -0
- package/dist/graphql/resolver-rule-builder.js.map +1 -0
- package/dist/graphql/schema-conditions.d.ts +31 -0
- package/dist/graphql/schema-conditions.d.ts.map +1 -0
- package/dist/graphql/schema-conditions.js +119 -0
- package/dist/graphql/schema-conditions.js.map +1 -0
- package/dist/graphql/schema-loader.d.ts +75 -0
- package/dist/graphql/schema-loader.d.ts.map +1 -0
- package/dist/graphql/schema-loader.js +113 -0
- package/dist/graphql/schema-loader.js.map +1 -0
- package/dist/graphql/schema-predicates.d.ts +42 -0
- package/dist/graphql/schema-predicates.d.ts.map +1 -0
- package/dist/graphql/schema-predicates.js +74 -0
- package/dist/graphql/schema-predicates.js.map +1 -0
- package/dist/graphql/schema-rule-builder.d.ts +74 -0
- package/dist/graphql/schema-rule-builder.d.ts.map +1 -0
- package/dist/graphql/schema-rule-builder.js +188 -0
- package/dist/graphql/schema-rule-builder.js.map +1 -0
- package/dist/helpers/body-traversal.d.ts +58 -0
- package/dist/helpers/body-traversal.d.ts.map +1 -0
- package/dist/helpers/body-traversal.js +180 -0
- package/dist/helpers/body-traversal.js.map +1 -0
- package/dist/helpers/callback-extractor.d.ts +28 -0
- package/dist/helpers/callback-extractor.d.ts.map +1 -0
- package/dist/helpers/callback-extractor.js +159 -0
- package/dist/helpers/callback-extractor.js.map +1 -0
- package/dist/helpers/complexity.d.ts +26 -0
- package/dist/helpers/complexity.d.ts.map +1 -0
- package/dist/helpers/complexity.js +64 -0
- package/dist/helpers/complexity.js.map +1 -0
- package/dist/helpers/matchers.d.ts +206 -0
- package/dist/helpers/matchers.d.ts.map +1 -0
- package/dist/helpers/matchers.js +470 -0
- package/dist/helpers/matchers.js.map +1 -0
- package/dist/helpers/pattern.d.ts +37 -0
- package/dist/helpers/pattern.d.ts.map +1 -0
- package/dist/helpers/pattern.js +22 -0
- package/dist/helpers/pattern.js.map +1 -0
- package/dist/helpers/slice-graph.d.ts +32 -0
- package/dist/helpers/slice-graph.d.ts.map +1 -0
- package/dist/helpers/slice-graph.js +89 -0
- package/dist/helpers/slice-graph.js.map +1 -0
- package/dist/helpers/tarjan.d.ts +21 -0
- package/dist/helpers/tarjan.d.ts.map +1 -0
- package/dist/helpers/tarjan.js +71 -0
- package/dist/helpers/tarjan.js.map +1 -0
- package/dist/helpers/type-matchers.d.ts +67 -0
- package/dist/helpers/type-matchers.d.ts.map +1 -0
- package/dist/helpers/type-matchers.js +108 -0
- package/dist/helpers/type-matchers.js.map +1 -0
- package/dist/helpers/within.d.ts +41 -0
- package/dist/helpers/within.d.ts.map +1 -0
- package/dist/helpers/within.js +32 -0
- package/dist/helpers/within.js.map +1 -0
- package/dist/index.d.ts +101 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +116 -0
- package/dist/index.js.map +1 -0
- package/dist/models/arch-call.d.ts +83 -0
- package/dist/models/arch-call.d.ts.map +1 -0
- package/dist/models/arch-call.js +90 -0
- package/dist/models/arch-call.js.map +1 -0
- package/dist/models/arch-function.d.ts +76 -0
- package/dist/models/arch-function.d.ts.map +1 -0
- package/dist/models/arch-function.js +122 -0
- package/dist/models/arch-function.js.map +1 -0
- package/dist/models/arch-jsx-element.d.ts +75 -0
- package/dist/models/arch-jsx-element.d.ts.map +1 -0
- package/dist/models/arch-jsx-element.js +231 -0
- package/dist/models/arch-jsx-element.js.map +1 -0
- package/dist/models/cross-layer.d.ts +15 -0
- package/dist/models/cross-layer.d.ts.map +1 -0
- package/dist/models/cross-layer.js +2 -0
- package/dist/models/cross-layer.js.map +1 -0
- package/dist/models/slice.d.ts +60 -0
- package/dist/models/slice.d.ts.map +1 -0
- package/dist/models/slice.js +89 -0
- package/dist/models/slice.js.map +1 -0
- package/dist/predicates/call.d.ts +49 -0
- package/dist/predicates/call.d.ts.map +1 -0
- package/dist/predicates/call.js +115 -0
- package/dist/predicates/call.js.map +1 -0
- package/dist/predicates/class.d.ts +42 -0
- package/dist/predicates/class.d.ts.map +1 -0
- package/dist/predicates/class.js +83 -0
- package/dist/predicates/class.js.map +1 -0
- package/dist/predicates/function.d.ts +81 -0
- package/dist/predicates/function.d.ts.map +1 -0
- package/dist/predicates/function.js +157 -0
- package/dist/predicates/function.js.map +1 -0
- package/dist/predicates/identity.d.ts +55 -0
- package/dist/predicates/identity.d.ts.map +1 -0
- package/dist/predicates/identity.js +96 -0
- package/dist/predicates/identity.js.map +1 -0
- package/dist/predicates/index.d.ts +4 -0
- package/dist/predicates/index.d.ts.map +1 -0
- package/dist/predicates/index.js +3 -0
- package/dist/predicates/index.js.map +1 -0
- package/dist/predicates/jsx.d.ts +41 -0
- package/dist/predicates/jsx.d.ts.map +1 -0
- package/dist/predicates/jsx.js +84 -0
- package/dist/predicates/jsx.js.map +1 -0
- package/dist/predicates/metrics.d.ts +30 -0
- package/dist/predicates/metrics.d.ts.map +1 -0
- package/dist/predicates/metrics.js +65 -0
- package/dist/predicates/metrics.js.map +1 -0
- package/dist/predicates/module.d.ts +44 -0
- package/dist/predicates/module.d.ts.map +1 -0
- package/dist/predicates/module.js +70 -0
- package/dist/predicates/module.js.map +1 -0
- package/dist/predicates/type.d.ts +48 -0
- package/dist/predicates/type.d.ts.map +1 -0
- package/dist/predicates/type.js +107 -0
- package/dist/predicates/type.js.map +1 -0
- package/dist/presets/boundaries.d.ts +19 -0
- package/dist/presets/boundaries.d.ts.map +1 -0
- package/dist/presets/boundaries.js +93 -0
- package/dist/presets/boundaries.js.map +1 -0
- package/dist/presets/data-layer.d.ts +20 -0
- package/dist/presets/data-layer.d.ts.map +1 -0
- package/dist/presets/data-layer.js +30 -0
- package/dist/presets/data-layer.js.map +1 -0
- package/dist/presets/index.d.ts +9 -0
- package/dist/presets/index.d.ts.map +1 -0
- package/dist/presets/index.js +5 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/presets/layered.d.ts +21 -0
- package/dist/presets/layered.d.ts.map +1 -0
- package/dist/presets/layered.js +103 -0
- package/dist/presets/layered.js.map +1 -0
- package/dist/presets/shared.d.ts +3 -0
- package/dist/presets/shared.d.ts.map +1 -0
- package/dist/presets/shared.js +5 -0
- package/dist/presets/shared.js.map +1 -0
- package/dist/rules/architecture.d.ts +10 -0
- package/dist/rules/architecture.d.ts.map +1 -0
- package/dist/rules/architecture.js +14 -0
- package/dist/rules/architecture.js.map +1 -0
- package/dist/rules/code-quality.d.ts +55 -0
- package/dist/rules/code-quality.d.ts.map +1 -0
- package/dist/rules/code-quality.js +116 -0
- package/dist/rules/code-quality.js.map +1 -0
- package/dist/rules/dependencies.d.ts +32 -0
- package/dist/rules/dependencies.d.ts.map +1 -0
- package/dist/rules/dependencies.js +37 -0
- package/dist/rules/dependencies.js.map +1 -0
- package/dist/rules/errors.d.ts +31 -0
- package/dist/rules/errors.d.ts.map +1 -0
- package/dist/rules/errors.js +97 -0
- package/dist/rules/errors.js.map +1 -0
- package/dist/rules/hygiene.d.ts +54 -0
- package/dist/rules/hygiene.d.ts.map +1 -0
- package/dist/rules/hygiene.js +62 -0
- package/dist/rules/hygiene.js.map +1 -0
- package/dist/rules/metrics-function.d.ts +45 -0
- package/dist/rules/metrics-function.d.ts.map +1 -0
- package/dist/rules/metrics-function.js +87 -0
- package/dist/rules/metrics-function.js.map +1 -0
- package/dist/rules/metrics.d.ts +64 -0
- package/dist/rules/metrics.d.ts.map +1 -0
- package/dist/rules/metrics.js +157 -0
- package/dist/rules/metrics.js.map +1 -0
- package/dist/rules/naming.d.ts +24 -0
- package/dist/rules/naming.d.ts.map +1 -0
- package/dist/rules/naming.js +51 -0
- package/dist/rules/naming.js.map +1 -0
- package/dist/rules/security.d.ts +59 -0
- package/dist/rules/security.d.ts.map +1 -0
- package/dist/rules/security.js +92 -0
- package/dist/rules/security.js.map +1 -0
- package/dist/rules/typescript.d.ts +73 -0
- package/dist/rules/typescript.d.ts.map +1 -0
- package/dist/rules/typescript.js +105 -0
- package/dist/rules/typescript.js.map +1 -0
- package/dist/smells/duplicate-bodies.d.ts +24 -0
- package/dist/smells/duplicate-bodies.d.ts.map +1 -0
- package/dist/smells/duplicate-bodies.js +131 -0
- package/dist/smells/duplicate-bodies.js.map +1 -0
- package/dist/smells/fingerprint.d.ts +27 -0
- package/dist/smells/fingerprint.d.ts.map +1 -0
- package/dist/smells/fingerprint.js +50 -0
- package/dist/smells/fingerprint.js.map +1 -0
- package/dist/smells/inconsistent-siblings.d.ts +21 -0
- package/dist/smells/inconsistent-siblings.d.ts.map +1 -0
- package/dist/smells/inconsistent-siblings.js +135 -0
- package/dist/smells/inconsistent-siblings.js.map +1 -0
- package/dist/smells/index.d.ts +12 -0
- package/dist/smells/index.d.ts.map +1 -0
- package/dist/smells/index.js +15 -0
- package/dist/smells/index.js.map +1 -0
- package/dist/smells/smell-builder.d.ts +37 -0
- package/dist/smells/smell-builder.d.ts.map +1 -0
- package/dist/smells/smell-builder.js +51 -0
- package/dist/smells/smell-builder.js.map +1 -0
- package/package.json +121 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { comment, STUB_PATTERNS } from '../helpers/matchers.js';
|
|
2
|
+
import { beImported, haveNoUnusedExports } from '../conditions/reverse-dependency.js';
|
|
3
|
+
import { functionNotContain, functionNotHaveEmptyBody, } from '../conditions/body-analysis-function.js';
|
|
4
|
+
/**
|
|
5
|
+
* Module must be imported by at least one other module.
|
|
6
|
+
* Detects dead/orphaned files that nobody references.
|
|
7
|
+
*
|
|
8
|
+
* Exclude entry points (index.ts, main.ts) via .excluding().
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* modules(p)
|
|
12
|
+
* .that().resideInFolder('src/**')
|
|
13
|
+
* .should().satisfy(noDeadModules())
|
|
14
|
+
* .excluding('index.ts', 'main.ts')
|
|
15
|
+
* .check()
|
|
16
|
+
*/
|
|
17
|
+
export function noDeadModules() {
|
|
18
|
+
return beImported();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Every exported symbol must be referenced by at least one other file.
|
|
22
|
+
* Detects exports that bloat the public API without consumers.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* modules(p)
|
|
26
|
+
* .that().resideInFolder('src/**')
|
|
27
|
+
* .should().satisfy(noUnusedExports())
|
|
28
|
+
* .check()
|
|
29
|
+
*/
|
|
30
|
+
export function noUnusedExports() {
|
|
31
|
+
return haveNoUnusedExports();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* No stub or deferred-work comments in function bodies.
|
|
35
|
+
* Catches common markers (see STUB_PATTERNS) and phrases like
|
|
36
|
+
* "not implemented" or "coming soon".
|
|
37
|
+
*
|
|
38
|
+
* Pass a custom pattern to override the defaults.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* functions(p)
|
|
42
|
+
* .that().resideInFolder('src/**')
|
|
43
|
+
* .should().satisfy(noStubComments())
|
|
44
|
+
* .check()
|
|
45
|
+
*/
|
|
46
|
+
export function noStubComments(pattern = STUB_PATTERNS) {
|
|
47
|
+
return functionNotContain(comment(pattern));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Functions must not have empty bodies.
|
|
51
|
+
* An empty function compiles and passes type checks but does nothing.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* functions(p)
|
|
55
|
+
* .that().resideInFolder('src/**')
|
|
56
|
+
* .should().satisfy(noEmptyBodies())
|
|
57
|
+
* .check()
|
|
58
|
+
*/
|
|
59
|
+
export function noEmptyBodies() {
|
|
60
|
+
return functionNotHaveEmptyBody();
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=hygiene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hygiene.js","sourceRoot":"","sources":["../../src/rules/hygiene.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAA;AACrF,OAAO,EACL,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,yCAAyC,CAAA;AAEhD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,UAAU,EAAE,CAAA;AACrB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO,mBAAmB,EAAE,CAAA;AAC9B,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,UAAkB,aAAa;IAC5D,OAAO,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;AAC7C,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,wBAAwB,EAAE,CAAA;AACnC,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { ArchFunction } from '../models/arch-function.js';
|
|
2
|
+
import type { Condition } from '@nielspeter/eess';
|
|
3
|
+
/**
|
|
4
|
+
* Function must not exceed the given cyclomatic complexity.
|
|
5
|
+
*
|
|
6
|
+
* Uses fn.getBody() which returns the body Node for all function
|
|
7
|
+
* kinds (declarations, arrow functions, methods).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { maxFunctionComplexity } from '@nielspeter/eess-ts/rules/metrics'
|
|
12
|
+
*
|
|
13
|
+
* functions(p).that().resideInFolder('src/**')
|
|
14
|
+
* .should().satisfy(maxFunctionComplexity(15))
|
|
15
|
+
* .check()
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function maxFunctionComplexity(threshold: number): Condition<ArchFunction>;
|
|
19
|
+
/**
|
|
20
|
+
* Function must not exceed the given number of lines (span lines).
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { maxFunctionLines } from '@nielspeter/eess-ts/rules/metrics'
|
|
25
|
+
*
|
|
26
|
+
* functions(p).should().satisfy(maxFunctionLines(40)).warn()
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function maxFunctionLines(threshold: number): Condition<ArchFunction>;
|
|
30
|
+
/**
|
|
31
|
+
* Function must not have more than the given number of parameters.
|
|
32
|
+
*
|
|
33
|
+
* Uses fn.getParameters() from the ArchFunction interface.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* ```ts
|
|
37
|
+
* import { maxFunctionParameters } from '@nielspeter/eess-ts/rules/metrics'
|
|
38
|
+
*
|
|
39
|
+
* functions(p).that().areExported()
|
|
40
|
+
* .should().satisfy(maxFunctionParameters(4))
|
|
41
|
+
* .check()
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function maxFunctionParameters(threshold: number): Condition<ArchFunction>;
|
|
45
|
+
//# sourceMappingURL=metrics-function.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics-function.d.ts","sourceRoot":"","sources":["../../src/rules/metrics-function.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,kBAAkB,CAAA;AAKnE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,CAoBhF;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,CAoB3E;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,YAAY,CAAC,CAoBhF"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { createViolation } from '../core/violation.js';
|
|
2
|
+
import { cyclomaticComplexity, linesOfCode } from '../helpers/complexity.js';
|
|
3
|
+
/**
|
|
4
|
+
* Function must not exceed the given cyclomatic complexity.
|
|
5
|
+
*
|
|
6
|
+
* Uses fn.getBody() which returns the body Node for all function
|
|
7
|
+
* kinds (declarations, arrow functions, methods).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { maxFunctionComplexity } from '@nielspeter/eess-ts/rules/metrics'
|
|
12
|
+
*
|
|
13
|
+
* functions(p).that().resideInFolder('src/**')
|
|
14
|
+
* .should().satisfy(maxFunctionComplexity(15))
|
|
15
|
+
* .check()
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export function maxFunctionComplexity(threshold) {
|
|
19
|
+
return {
|
|
20
|
+
description: `have cyclomatic complexity <= ${String(threshold)}`,
|
|
21
|
+
evaluate(elements, context) {
|
|
22
|
+
const violations = [];
|
|
23
|
+
for (const fn of elements) {
|
|
24
|
+
const cc = cyclomaticComplexity(fn.getBody());
|
|
25
|
+
if (cc > threshold) {
|
|
26
|
+
violations.push(createViolation(fn.getNode(), `${fn.getName() ?? '<anonymous>'} has cyclomatic complexity ${String(cc)} (max: ${String(threshold)})`, context));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return violations;
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Function must not exceed the given number of lines (span lines).
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* import { maxFunctionLines } from '@nielspeter/eess-ts/rules/metrics'
|
|
39
|
+
*
|
|
40
|
+
* functions(p).should().satisfy(maxFunctionLines(40)).warn()
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
export function maxFunctionLines(threshold) {
|
|
44
|
+
return {
|
|
45
|
+
description: `have no more than ${String(threshold)} lines`,
|
|
46
|
+
evaluate(elements, context) {
|
|
47
|
+
const violations = [];
|
|
48
|
+
for (const fn of elements) {
|
|
49
|
+
const loc = linesOfCode(fn.getNode());
|
|
50
|
+
if (loc > threshold) {
|
|
51
|
+
violations.push(createViolation(fn.getNode(), `${fn.getName() ?? '<anonymous>'} has ${String(loc)} lines (max: ${String(threshold)})`, context));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return violations;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Function must not have more than the given number of parameters.
|
|
60
|
+
*
|
|
61
|
+
* Uses fn.getParameters() from the ArchFunction interface.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { maxFunctionParameters } from '@nielspeter/eess-ts/rules/metrics'
|
|
66
|
+
*
|
|
67
|
+
* functions(p).that().areExported()
|
|
68
|
+
* .should().satisfy(maxFunctionParameters(4))
|
|
69
|
+
* .check()
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export function maxFunctionParameters(threshold) {
|
|
73
|
+
return {
|
|
74
|
+
description: `have no more than ${String(threshold)} parameters`,
|
|
75
|
+
evaluate(elements, context) {
|
|
76
|
+
const violations = [];
|
|
77
|
+
for (const fn of elements) {
|
|
78
|
+
const params = fn.getParameters().length;
|
|
79
|
+
if (params > threshold) {
|
|
80
|
+
violations.push(createViolation(fn.getNode(), `${fn.getName() ?? '<anonymous>'} has ${String(params)} parameters (max: ${String(threshold)}) — use an options object`, context));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return violations;
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=metrics-function.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics-function.js","sourceRoot":"","sources":["../../src/rules/metrics-function.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAE5E;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAiB;IACrD,OAAO;QACL,WAAW,EAAE,iCAAiC,MAAM,CAAC,SAAS,CAAC,EAAE;QACjE,QAAQ,CAAC,QAAwB,EAAE,OAAyB;YAC1D,MAAM,UAAU,GAAoB,EAAE,CAAA;YACtC,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;gBAC1B,MAAM,EAAE,GAAG,oBAAoB,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;gBAC7C,IAAI,EAAE,GAAG,SAAS,EAAE,CAAC;oBACnB,UAAU,CAAC,IAAI,CACb,eAAe,CACb,EAAE,CAAC,OAAO,EAAE,EACZ,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,aAAa,8BAA8B,MAAM,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,SAAS,CAAC,GAAG,EACtG,OAAO,CACR,CACF,CAAA;gBACH,CAAC;YACH,CAAC;YACD,OAAO,UAAU,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,OAAO;QACL,WAAW,EAAE,qBAAqB,MAAM,CAAC,SAAS,CAAC,QAAQ;QAC3D,QAAQ,CAAC,QAAwB,EAAE,OAAyB;YAC1D,MAAM,UAAU,GAAoB,EAAE,CAAA;YACtC,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;gBAC1B,MAAM,GAAG,GAAG,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAA;gBACrC,IAAI,GAAG,GAAG,SAAS,EAAE,CAAC;oBACpB,UAAU,CAAC,IAAI,CACb,eAAe,CACb,EAAE,CAAC,OAAO,EAAE,EACZ,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,aAAa,QAAQ,MAAM,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,SAAS,CAAC,GAAG,EACvF,OAAO,CACR,CACF,CAAA;gBACH,CAAC;YACH,CAAC;YACD,OAAO,UAAU,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAiB;IACrD,OAAO;QACL,WAAW,EAAE,qBAAqB,MAAM,CAAC,SAAS,CAAC,aAAa;QAChE,QAAQ,CAAC,QAAwB,EAAE,OAAyB;YAC1D,MAAM,UAAU,GAAoB,EAAE,CAAA;YACtC,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;gBAC1B,MAAM,MAAM,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC,MAAM,CAAA;gBACxC,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC;oBACvB,UAAU,CAAC,IAAI,CACb,eAAe,CACb,EAAE,CAAC,OAAO,EAAE,EACZ,GAAG,EAAE,CAAC,OAAO,EAAE,IAAI,aAAa,QAAQ,MAAM,CAAC,MAAM,CAAC,qBAAqB,MAAM,CAAC,SAAS,CAAC,2BAA2B,EACvH,OAAO,CACR,CACF,CAAA;gBACH,CAAC;YACH,CAAC;YACD,OAAO,UAAU,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ClassDeclaration } from 'ts-morph';
|
|
2
|
+
import type { Condition } from '@nielspeter/eess';
|
|
3
|
+
/**
|
|
4
|
+
* No method/constructor/getter/setter in the class may exceed the given
|
|
5
|
+
* cyclomatic complexity.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { maxCyclomaticComplexity } from '@nielspeter/eess-ts/rules/metrics'
|
|
10
|
+
*
|
|
11
|
+
* classes(p).should().satisfy(maxCyclomaticComplexity(15)).check()
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare function maxCyclomaticComplexity(threshold: number): Condition<ClassDeclaration>;
|
|
15
|
+
/**
|
|
16
|
+
* No class may exceed the given number of lines (span lines).
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { maxClassLines } from '@nielspeter/eess-ts/rules/metrics'
|
|
21
|
+
*
|
|
22
|
+
* classes(p).should().satisfy(maxClassLines(300)).warn()
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function maxClassLines(threshold: number): Condition<ClassDeclaration>;
|
|
26
|
+
/**
|
|
27
|
+
* No method/constructor/getter/setter may exceed the given number of lines.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```ts
|
|
31
|
+
* import { maxMethodLines } from '@nielspeter/eess-ts/rules/metrics'
|
|
32
|
+
*
|
|
33
|
+
* classes(p).should().satisfy(maxMethodLines(50)).warn()
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function maxMethodLines(threshold: number): Condition<ClassDeclaration>;
|
|
37
|
+
/**
|
|
38
|
+
* No class may have more than the given number of methods.
|
|
39
|
+
*
|
|
40
|
+
* Counts methods only (not constructors/getters/setters).
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* import { maxMethods } from '@nielspeter/eess-ts/rules/metrics'
|
|
45
|
+
*
|
|
46
|
+
* classes(p).should().satisfy(maxMethods(15)).warn()
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare function maxMethods(threshold: number): Condition<ClassDeclaration>;
|
|
50
|
+
/**
|
|
51
|
+
* No method/constructor may have more than the given number of parameters.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```ts
|
|
55
|
+
* import { maxParameters } from '@nielspeter/eess-ts/rules/metrics'
|
|
56
|
+
*
|
|
57
|
+
* classes(p).should().satisfy(maxParameters(4))
|
|
58
|
+
* .because('use an options object for >4 parameters')
|
|
59
|
+
* .check()
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function maxParameters(threshold: number): Condition<ClassDeclaration>;
|
|
63
|
+
export { maxFunctionComplexity, maxFunctionLines, maxFunctionParameters, } from './metrics-function.js';
|
|
64
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/rules/metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAKjB,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,kBAAkB,CAAA;AA8BnE;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAsBtF;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAoB5E;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAsB7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAoBzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAsB5E;AAGD,OAAO,EACL,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,GACtB,MAAM,uBAAuB,CAAA"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { createViolation } from '../core/violation.js';
|
|
2
|
+
import { cyclomaticComplexity, linesOfCode } from '../helpers/complexity.js';
|
|
3
|
+
function getClassMembers(cls) {
|
|
4
|
+
return [
|
|
5
|
+
...cls.getMethods(),
|
|
6
|
+
...cls.getConstructors(),
|
|
7
|
+
...cls.getGetAccessors(),
|
|
8
|
+
...cls.getSetAccessors(),
|
|
9
|
+
];
|
|
10
|
+
}
|
|
11
|
+
function getMemberName(cls, member) {
|
|
12
|
+
const clsName = cls.getName() ?? '<anonymous>';
|
|
13
|
+
if ('getName' in member && typeof member.getName === 'function') {
|
|
14
|
+
const memberName = String(member.getName());
|
|
15
|
+
return `${clsName}.${memberName}`;
|
|
16
|
+
}
|
|
17
|
+
return `${clsName}.constructor`;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* No method/constructor/getter/setter in the class may exceed the given
|
|
21
|
+
* cyclomatic complexity.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```ts
|
|
25
|
+
* import { maxCyclomaticComplexity } from '@nielspeter/eess-ts/rules/metrics'
|
|
26
|
+
*
|
|
27
|
+
* classes(p).should().satisfy(maxCyclomaticComplexity(15)).check()
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export function maxCyclomaticComplexity(threshold) {
|
|
31
|
+
return {
|
|
32
|
+
description: `have no method with cyclomatic complexity > ${String(threshold)}`,
|
|
33
|
+
evaluate(elements, context) {
|
|
34
|
+
const violations = [];
|
|
35
|
+
for (const cls of elements) {
|
|
36
|
+
for (const member of getClassMembers(cls)) {
|
|
37
|
+
const cc = cyclomaticComplexity(member.getBody());
|
|
38
|
+
if (cc > threshold) {
|
|
39
|
+
violations.push(createViolation(member, `${getMemberName(cls, member)} has cyclomatic complexity ${String(cc)} (max: ${String(threshold)}) — split into smaller methods`, context));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return violations;
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* No class may exceed the given number of lines (span lines).
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* import { maxClassLines } from '@nielspeter/eess-ts/rules/metrics'
|
|
53
|
+
*
|
|
54
|
+
* classes(p).should().satisfy(maxClassLines(300)).warn()
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export function maxClassLines(threshold) {
|
|
58
|
+
return {
|
|
59
|
+
description: `have no more than ${String(threshold)} lines`,
|
|
60
|
+
evaluate(elements, context) {
|
|
61
|
+
const violations = [];
|
|
62
|
+
for (const cls of elements) {
|
|
63
|
+
const loc = linesOfCode(cls);
|
|
64
|
+
if (loc > threshold) {
|
|
65
|
+
violations.push(createViolation(cls, `${cls.getName() ?? '<anonymous>'} has ${String(loc)} lines (max: ${String(threshold)}) — consider splitting into focused classes`, context));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return violations;
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* No method/constructor/getter/setter may exceed the given number of lines.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* import { maxMethodLines } from '@nielspeter/eess-ts/rules/metrics'
|
|
78
|
+
*
|
|
79
|
+
* classes(p).should().satisfy(maxMethodLines(50)).warn()
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export function maxMethodLines(threshold) {
|
|
83
|
+
return {
|
|
84
|
+
description: `have no method longer than ${String(threshold)} lines`,
|
|
85
|
+
evaluate(elements, context) {
|
|
86
|
+
const violations = [];
|
|
87
|
+
for (const cls of elements) {
|
|
88
|
+
for (const member of getClassMembers(cls)) {
|
|
89
|
+
const loc = linesOfCode(member);
|
|
90
|
+
if (loc > threshold) {
|
|
91
|
+
violations.push(createViolation(member, `${getMemberName(cls, member)} has ${String(loc)} lines (max: ${String(threshold)})`, context));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return violations;
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* No class may have more than the given number of methods.
|
|
101
|
+
*
|
|
102
|
+
* Counts methods only (not constructors/getters/setters).
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```ts
|
|
106
|
+
* import { maxMethods } from '@nielspeter/eess-ts/rules/metrics'
|
|
107
|
+
*
|
|
108
|
+
* classes(p).should().satisfy(maxMethods(15)).warn()
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export function maxMethods(threshold) {
|
|
112
|
+
return {
|
|
113
|
+
description: `have no more than ${String(threshold)} methods`,
|
|
114
|
+
evaluate(elements, context) {
|
|
115
|
+
const violations = [];
|
|
116
|
+
for (const cls of elements) {
|
|
117
|
+
const count = cls.getMethods().length;
|
|
118
|
+
if (count > threshold) {
|
|
119
|
+
violations.push(createViolation(cls, `${cls.getName() ?? '<anonymous>'} has ${String(count)} methods (max: ${String(threshold)}) — consider splitting into focused classes`, context));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return violations;
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* No method/constructor may have more than the given number of parameters.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```ts
|
|
131
|
+
* import { maxParameters } from '@nielspeter/eess-ts/rules/metrics'
|
|
132
|
+
*
|
|
133
|
+
* classes(p).should().satisfy(maxParameters(4))
|
|
134
|
+
* .because('use an options object for >4 parameters')
|
|
135
|
+
* .check()
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
export function maxParameters(threshold) {
|
|
139
|
+
return {
|
|
140
|
+
description: `have no method with more than ${String(threshold)} parameters`,
|
|
141
|
+
evaluate(elements, context) {
|
|
142
|
+
const violations = [];
|
|
143
|
+
for (const cls of elements) {
|
|
144
|
+
for (const member of getClassMembers(cls)) {
|
|
145
|
+
const params = member.getParameters().length;
|
|
146
|
+
if (params > threshold) {
|
|
147
|
+
violations.push(createViolation(member, `${getMemberName(cls, member)} has ${String(params)} parameters (max: ${String(threshold)}) — use an options object`, context));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return violations;
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
// Re-export function-level metric conditions from the same sub-path
|
|
156
|
+
export { maxFunctionComplexity, maxFunctionLines, maxFunctionParameters, } from './metrics-function.js';
|
|
157
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/rules/metrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ClassDeclaration } from 'ts-morph';
|
|
2
|
+
import type { Condition } from '@nielspeter/eess';
|
|
3
|
+
/**
|
|
4
|
+
* Class name must match a regex pattern.
|
|
5
|
+
*
|
|
6
|
+
* This is the condition version of the `haveNameMatching` predicate.
|
|
7
|
+
* Use when you want to assert naming, not filter by it.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* classes(p).that().resideInFolder('** /controllers/** ')
|
|
11
|
+
* .should().satisfy(mustMatchName(/Controller$/))
|
|
12
|
+
* .check()
|
|
13
|
+
*/
|
|
14
|
+
export declare function mustMatchName(pattern: RegExp): Condition<ClassDeclaration>;
|
|
15
|
+
/**
|
|
16
|
+
* Class must not have a specific suffix (anti-pattern detection).
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* classes(p).that().resideInFolder('** /domain/** ')
|
|
20
|
+
* .should().satisfy(mustNotEndWith('Entity'))
|
|
21
|
+
* .check()
|
|
22
|
+
*/
|
|
23
|
+
export declare function mustNotEndWith(suffix: string): Condition<ClassDeclaration>;
|
|
24
|
+
//# sourceMappingURL=naming.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../../src/rules/naming.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,KAAK,EAAE,SAAS,EAAoB,MAAM,kBAAkB,CAAA;AAInE;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAoB1E;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAc1E"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createViolation } from '../core/violation.js';
|
|
2
|
+
/**
|
|
3
|
+
* Class name must match a regex pattern.
|
|
4
|
+
*
|
|
5
|
+
* This is the condition version of the `haveNameMatching` predicate.
|
|
6
|
+
* Use when you want to assert naming, not filter by it.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* classes(p).that().resideInFolder('** /controllers/** ')
|
|
10
|
+
* .should().satisfy(mustMatchName(/Controller$/))
|
|
11
|
+
* .check()
|
|
12
|
+
*/
|
|
13
|
+
export function mustMatchName(pattern) {
|
|
14
|
+
return {
|
|
15
|
+
description: `have name matching ${String(pattern)}`,
|
|
16
|
+
evaluate(elements, context) {
|
|
17
|
+
const violations = [];
|
|
18
|
+
for (const cls of elements) {
|
|
19
|
+
const name = cls.getName() ?? '<anonymous>';
|
|
20
|
+
if (!pattern.test(name)) {
|
|
21
|
+
violations.push(createViolation(cls, `${name} does not match naming convention ${String(pattern)}`, context));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return violations;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Class must not have a specific suffix (anti-pattern detection).
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* classes(p).that().resideInFolder('** /domain/** ')
|
|
33
|
+
* .should().satisfy(mustNotEndWith('Entity'))
|
|
34
|
+
* .check()
|
|
35
|
+
*/
|
|
36
|
+
export function mustNotEndWith(suffix) {
|
|
37
|
+
return {
|
|
38
|
+
description: `not have name ending with "${suffix}"`,
|
|
39
|
+
evaluate(elements, context) {
|
|
40
|
+
const violations = [];
|
|
41
|
+
for (const cls of elements) {
|
|
42
|
+
const name = cls.getName() ?? '<anonymous>';
|
|
43
|
+
if (name.endsWith(suffix)) {
|
|
44
|
+
violations.push(createViolation(cls, `${name} should not end with "${suffix}"`, context));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return violations;
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=naming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming.js","sourceRoot":"","sources":["../../src/rules/naming.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEtD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,OAAO;QACL,WAAW,EAAE,sBAAsB,MAAM,CAAC,OAAO,CAAC,EAAE;QACpD,QAAQ,CAAC,QAA4B,EAAE,OAAyB;YAC9D,MAAM,UAAU,GAAoB,EAAE,CAAA;YACtC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,IAAI,aAAa,CAAA;gBAC3C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACxB,UAAU,CAAC,IAAI,CACb,eAAe,CACb,GAAG,EACH,GAAG,IAAI,qCAAqC,MAAM,CAAC,OAAO,CAAC,EAAE,EAC7D,OAAO,CACR,CACF,CAAA;gBACH,CAAC;YACH,CAAC;YACD,OAAO,UAAU,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO;QACL,WAAW,EAAE,8BAA8B,MAAM,GAAG;QACpD,QAAQ,CAAC,QAA4B,EAAE,OAAyB;YAC9D,MAAM,UAAU,GAAoB,EAAE,CAAA;YACtC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE,IAAI,aAAa,CAAA;gBAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC1B,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,GAAG,IAAI,yBAAyB,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC,CAAA;gBAC3F,CAAC;YACH,CAAC;YACD,OAAO,UAAU,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ClassDeclaration, SourceFile } from 'ts-morph';
|
|
2
|
+
import type { Condition } from '@nielspeter/eess';
|
|
3
|
+
import type { ArchFunction } from '../models/arch-function.js';
|
|
4
|
+
/**
|
|
5
|
+
* No eval() calls in class methods.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* classes(p).should().satisfy(noEval()).check()
|
|
9
|
+
*/
|
|
10
|
+
export declare function noEval(): Condition<ClassDeclaration>;
|
|
11
|
+
/**
|
|
12
|
+
* No new Function() constructor (equivalent to eval).
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* classes(p).should().satisfy(noFunctionConstructor()).check()
|
|
16
|
+
*/
|
|
17
|
+
export declare function noFunctionConstructor(): Condition<ClassDeclaration>;
|
|
18
|
+
/**
|
|
19
|
+
* No direct process.env access in class methods.
|
|
20
|
+
*
|
|
21
|
+
* Use dependency injection for configuration instead.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* classes(p).that().resideInFolder('** /domain/** ')
|
|
25
|
+
* .should().satisfy(noProcessEnv())
|
|
26
|
+
* .because('use Config injection instead')
|
|
27
|
+
* .check()
|
|
28
|
+
*/
|
|
29
|
+
export declare function noProcessEnv(): Condition<ClassDeclaration>;
|
|
30
|
+
/**
|
|
31
|
+
* No console.log calls in class methods.
|
|
32
|
+
*
|
|
33
|
+
* Use a logger abstraction instead.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* classes(p).that().resideInFolder('** /src/** ')
|
|
37
|
+
* .should().satisfy(noConsoleLog())
|
|
38
|
+
* .check()
|
|
39
|
+
*/
|
|
40
|
+
export declare function noConsoleLog(): Condition<ClassDeclaration>;
|
|
41
|
+
/**
|
|
42
|
+
* No direct console access (any method: log, warn, error, debug, info).
|
|
43
|
+
* Stricter than noConsoleLog — catches all console methods.
|
|
44
|
+
*/
|
|
45
|
+
export declare function noConsole(): Condition<ClassDeclaration>;
|
|
46
|
+
/**
|
|
47
|
+
* No JSON.parse calls — centralize deserialization.
|
|
48
|
+
*/
|
|
49
|
+
export declare function noJsonParse(): Condition<ClassDeclaration>;
|
|
50
|
+
export declare function functionNoEval(): Condition<ArchFunction>;
|
|
51
|
+
export declare function functionNoFunctionConstructor(): Condition<ArchFunction>;
|
|
52
|
+
export declare function functionNoProcessEnv(): Condition<ArchFunction>;
|
|
53
|
+
export declare function functionNoConsoleLog(): Condition<ArchFunction>;
|
|
54
|
+
export declare function functionNoConsole(): Condition<ArchFunction>;
|
|
55
|
+
export declare function functionNoJsonParse(): Condition<ArchFunction>;
|
|
56
|
+
export declare function moduleNoEval(): Condition<SourceFile>;
|
|
57
|
+
export declare function moduleNoProcessEnv(): Condition<SourceFile>;
|
|
58
|
+
export declare function moduleNoConsoleLog(): Condition<SourceFile>;
|
|
59
|
+
//# sourceMappingURL=security.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/rules/security.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAM9D;;;;;GAKG;AACH,wBAAgB,MAAM,IAAI,SAAS,CAAC,gBAAgB,CAAC,CAEpD;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,SAAS,CAAC,gBAAgB,CAAC,CAEnE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAAC,gBAAgB,CAAC,CAE1D;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAAC,gBAAgB,CAAC,CAE1D;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI,SAAS,CAAC,gBAAgB,CAAC,CAEvD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,SAAS,CAAC,gBAAgB,CAAC,CAEzD;AAID,wBAAgB,cAAc,IAAI,SAAS,CAAC,YAAY,CAAC,CAExD;AAED,wBAAgB,6BAA6B,IAAI,SAAS,CAAC,YAAY,CAAC,CAEvE;AAED,wBAAgB,oBAAoB,IAAI,SAAS,CAAC,YAAY,CAAC,CAE9D;AAED,wBAAgB,oBAAoB,IAAI,SAAS,CAAC,YAAY,CAAC,CAE9D;AAED,wBAAgB,iBAAiB,IAAI,SAAS,CAAC,YAAY,CAAC,CAE3D;AAED,wBAAgB,mBAAmB,IAAI,SAAS,CAAC,YAAY,CAAC,CAE7D;AAID,wBAAgB,YAAY,IAAI,SAAS,CAAC,UAAU,CAAC,CAEpD;AAED,wBAAgB,kBAAkB,IAAI,SAAS,CAAC,UAAU,CAAC,CAE1D;AAED,wBAAgB,kBAAkB,IAAI,SAAS,CAAC,UAAU,CAAC,CAE1D"}
|