@nielspeter/eess-ts 0.2.1 → 0.5.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/README.md +61 -35
- package/dist/builders/call-rule-builder.d.ts +66 -26
- package/dist/builders/call-rule-builder.d.ts.map +1 -1
- package/dist/builders/call-rule-builder.js +75 -32
- package/dist/builders/call-rule-builder.js.map +1 -1
- package/dist/builders/class-rule-builder.d.ts +125 -26
- package/dist/builders/class-rule-builder.d.ts.map +1 -1
- package/dist/builders/class-rule-builder.js +141 -55
- package/dist/builders/class-rule-builder.js.map +1 -1
- package/dist/builders/correspondence-builder.d.ts +287 -0
- package/dist/builders/correspondence-builder.d.ts.map +1 -0
- package/dist/builders/correspondence-builder.js +385 -0
- package/dist/builders/correspondence-builder.js.map +1 -0
- package/dist/builders/correspondence-findings.d.ts +104 -0
- package/dist/builders/correspondence-findings.d.ts.map +1 -0
- package/dist/builders/correspondence-findings.js +301 -0
- package/dist/builders/correspondence-findings.js.map +1 -0
- package/dist/builders/cross-layer-builder.d.ts +99 -16
- package/dist/builders/cross-layer-builder.d.ts.map +1 -1
- package/dist/builders/cross-layer-builder.js +182 -35
- package/dist/builders/cross-layer-builder.js.map +1 -1
- package/dist/builders/function-rule-builder.d.ts +144 -25
- package/dist/builders/function-rule-builder.d.ts.map +1 -1
- package/dist/builders/function-rule-builder.js +177 -39
- package/dist/builders/function-rule-builder.js.map +1 -1
- package/dist/builders/jsx-rule-builder.d.ts +70 -14
- package/dist/builders/jsx-rule-builder.d.ts.map +1 -1
- package/dist/builders/jsx-rule-builder.js +73 -14
- package/dist/builders/jsx-rule-builder.js.map +1 -1
- package/dist/builders/module-rule-builder.d.ts +2 -2
- package/dist/builders/module-rule-builder.d.ts.map +1 -1
- package/dist/builders/module-rule-builder.js +16 -19
- package/dist/builders/module-rule-builder.js.map +1 -1
- package/dist/builders/scoped-function-rule-builder.d.ts +11 -0
- package/dist/builders/scoped-function-rule-builder.d.ts.map +1 -1
- package/dist/builders/scoped-function-rule-builder.js +12 -0
- package/dist/builders/scoped-function-rule-builder.js.map +1 -1
- package/dist/builders/slice-discovery-message.d.ts +36 -0
- package/dist/builders/slice-discovery-message.d.ts.map +1 -0
- package/dist/builders/slice-discovery-message.js +181 -0
- package/dist/builders/slice-discovery-message.js.map +1 -0
- package/dist/builders/slice-rule-builder.d.ts +151 -12
- package/dist/builders/slice-rule-builder.d.ts.map +1 -1
- package/dist/builders/slice-rule-builder.js +243 -35
- package/dist/builders/slice-rule-builder.js.map +1 -1
- package/dist/builders/type-rule-builder.d.ts +95 -24
- package/dist/builders/type-rule-builder.d.ts.map +1 -1
- package/dist/builders/type-rule-builder.js +109 -42
- package/dist/builders/type-rule-builder.js.map +1 -1
- package/dist/{helpers → builders}/within.d.ts +2 -2
- package/dist/builders/within.d.ts.map +1 -0
- package/dist/{helpers → builders}/within.js +1 -1
- package/dist/builders/within.js.map +1 -0
- package/dist/cli/commands/baseline.d.ts +8 -3
- package/dist/cli/commands/baseline.d.ts.map +1 -1
- package/dist/cli/commands/baseline.js +111 -7
- package/dist/cli/commands/baseline.js.map +1 -1
- package/dist/cli/commands/check.d.ts +7 -2
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +385 -47
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts +29 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +224 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/explain.d.ts +2 -1
- package/dist/cli/commands/explain.d.ts.map +1 -1
- package/dist/cli/commands/explain.js +19 -10
- package/dist/cli/commands/explain.js.map +1 -1
- package/dist/cli/commands/init.d.ts +9 -3
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +162 -137
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/import-rule-module.d.ts +29 -0
- package/dist/cli/import-rule-module.d.ts.map +1 -0
- package/dist/cli/import-rule-module.js +47 -0
- package/dist/cli/import-rule-module.js.map +1 -0
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +101 -43
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/load-rules.d.ts +6 -11
- package/dist/cli/load-rules.d.ts.map +1 -1
- package/dist/cli/load-rules.js +25 -32
- package/dist/cli/load-rules.js.map +1 -1
- package/dist/cli/resolve-config.d.ts +0 -8
- package/dist/cli/resolve-config.d.ts.map +1 -1
- package/dist/cli/resolve-config.js +25 -55
- package/dist/cli/resolve-config.js.map +1 -1
- package/dist/cli/rule-file-findings.d.ts +178 -0
- package/dist/cli/rule-file-findings.d.ts.map +1 -0
- package/dist/cli/rule-file-findings.js +351 -0
- package/dist/cli/rule-file-findings.js.map +1 -0
- package/dist/cli/watch.d.ts +17 -34
- package/dist/cli/watch.d.ts.map +1 -1
- package/dist/cli/watch.js +14 -129
- package/dist/cli/watch.js.map +1 -1
- package/dist/conditions/body-analysis-function.d.ts.map +1 -1
- package/dist/conditions/body-analysis-function.js +16 -7
- package/dist/conditions/body-analysis-function.js.map +1 -1
- package/dist/conditions/body-analysis-module.d.ts.map +1 -1
- package/dist/conditions/body-analysis-module.js +14 -9
- package/dist/conditions/body-analysis-module.js.map +1 -1
- package/dist/conditions/body-analysis.d.ts.map +1 -1
- package/dist/conditions/body-analysis.js +16 -7
- package/dist/conditions/body-analysis.js.map +1 -1
- package/dist/conditions/call.d.ts.map +1 -1
- package/dist/conditions/call.js +41 -19
- package/dist/conditions/call.js.map +1 -1
- package/dist/conditions/catch-analysis.d.ts +2 -1
- package/dist/conditions/catch-analysis.d.ts.map +1 -1
- package/dist/conditions/catch-analysis.js.map +1 -1
- package/dist/conditions/cross-layer.d.ts +2 -10
- package/dist/conditions/cross-layer.d.ts.map +1 -1
- package/dist/conditions/cross-layer.js +227 -23
- package/dist/conditions/cross-layer.js.map +1 -1
- package/dist/conditions/dependency.d.ts +35 -6
- package/dist/conditions/dependency.d.ts.map +1 -1
- package/dist/conditions/dependency.js +299 -45
- package/dist/conditions/dependency.js.map +1 -1
- package/dist/conditions/exports.d.ts.map +1 -1
- package/dist/conditions/exports.js +41 -37
- package/dist/conditions/exports.js.map +1 -1
- package/dist/conditions/function.d.ts.map +1 -1
- package/dist/conditions/function.js +19 -5
- package/dist/conditions/function.js.map +1 -1
- package/dist/conditions/helpers.d.ts +2 -1
- package/dist/conditions/helpers.d.ts.map +1 -1
- package/dist/conditions/helpers.js +4 -1
- package/dist/conditions/helpers.js.map +1 -1
- package/dist/conditions/jsx.d.ts.map +1 -1
- package/dist/conditions/jsx.js +7 -2
- package/dist/conditions/jsx.js.map +1 -1
- package/dist/conditions/match-identity.d.ts +43 -0
- package/dist/conditions/match-identity.d.ts.map +1 -0
- package/dist/conditions/match-identity.js +43 -0
- package/dist/conditions/match-identity.js.map +1 -0
- package/dist/conditions/members.d.ts.map +1 -1
- package/dist/conditions/members.js +20 -6
- package/dist/conditions/members.js.map +1 -1
- package/dist/conditions/reverse-dependency.d.ts +18 -5
- package/dist/conditions/reverse-dependency.d.ts.map +1 -1
- package/dist/conditions/reverse-dependency.js +155 -93
- package/dist/conditions/reverse-dependency.js.map +1 -1
- package/dist/conditions/slice.d.ts +86 -2
- package/dist/conditions/slice.d.ts.map +1 -1
- package/dist/conditions/slice.js +234 -53
- package/dist/conditions/slice.js.map +1 -1
- package/dist/conditions/structural.d.ts.map +1 -1
- package/dist/conditions/structural.js +16 -4
- package/dist/conditions/structural.js.map +1 -1
- package/dist/core/check-all.d.ts +19 -0
- package/dist/core/check-all.d.ts.map +1 -0
- package/dist/core/check-all.js +150 -0
- package/dist/core/check-all.js.map +1 -0
- package/dist/core/combinators.d.ts +48 -0
- package/dist/core/combinators.d.ts.map +1 -0
- package/dist/core/combinators.js +49 -0
- package/dist/core/combinators.js.map +1 -0
- package/dist/core/descendant-cache.d.ts +36 -0
- package/dist/core/descendant-cache.d.ts.map +1 -0
- package/dist/core/descendant-cache.js +117 -0
- package/dist/core/descendant-cache.js.map +1 -0
- package/dist/core/diagnose.d.ts +234 -0
- package/dist/core/diagnose.d.ts.map +1 -0
- package/dist/core/diagnose.js +390 -0
- package/dist/core/diagnose.js.map +1 -0
- package/dist/core/disk-set.d.ts +48 -0
- package/dist/core/disk-set.d.ts.map +1 -0
- package/dist/core/disk-set.js +218 -0
- package/dist/core/disk-set.js.map +1 -0
- package/dist/core/element-cache.d.ts +75 -0
- package/dist/core/element-cache.d.ts.map +1 -0
- package/dist/core/element-cache.js +32 -0
- package/dist/core/element-cache.js.map +1 -0
- package/dist/core/empty-project-advice.d.ts +75 -0
- package/dist/core/empty-project-advice.d.ts.map +1 -0
- package/dist/core/empty-project-advice.js +61 -0
- package/dist/core/empty-project-advice.js.map +1 -0
- package/dist/core/exclusion-comments.d.ts +19 -0
- package/dist/core/exclusion-comments.d.ts.map +1 -0
- package/dist/core/exclusion-comments.js +7 -0
- package/dist/core/exclusion-comments.js.map +1 -0
- package/dist/core/execute-rule.d.ts +158 -0
- package/dist/core/execute-rule.d.ts.map +1 -0
- package/dist/core/execute-rule.js +666 -0
- package/dist/core/execute-rule.js.map +1 -0
- package/dist/core/glob-diagnosis.d.ts +78 -0
- package/dist/core/glob-diagnosis.d.ts.map +1 -0
- package/dist/core/glob-diagnosis.js +134 -0
- package/dist/core/glob-diagnosis.js.map +1 -0
- package/dist/core/glob-evaluator.d.ts +48 -0
- package/dist/core/glob-evaluator.d.ts.map +1 -0
- package/dist/core/glob-evaluator.js +89 -0
- package/dist/core/glob-evaluator.js.map +1 -0
- package/dist/core/import-candidates.d.ts +60 -0
- package/dist/core/import-candidates.d.ts.map +1 -0
- package/dist/core/import-candidates.js +93 -0
- package/dist/core/import-candidates.js.map +1 -0
- package/dist/core/import-options.d.ts +55 -2
- package/dist/core/import-options.d.ts.map +1 -1
- package/dist/core/import-options.js +64 -0
- package/dist/core/import-options.js.map +1 -1
- package/dist/core/invalidate-on-modify.d.ts +20 -0
- package/dist/core/invalidate-on-modify.d.ts.map +1 -0
- package/dist/core/invalidate-on-modify.js +26 -0
- package/dist/core/invalidate-on-modify.js.map +1 -0
- package/dist/core/line-index.d.ts +3 -0
- package/dist/core/line-index.d.ts.map +1 -0
- package/dist/core/line-index.js +227 -0
- package/dist/core/line-index.js.map +1 -0
- package/dist/core/metric-violation.d.ts +86 -0
- package/dist/core/metric-violation.d.ts.map +1 -0
- package/dist/core/metric-violation.js +132 -0
- package/dist/core/metric-violation.js.map +1 -0
- package/dist/core/module-edges.d.ts +361 -0
- package/dist/core/module-edges.d.ts.map +1 -0
- package/dist/core/module-edges.js +593 -0
- package/dist/core/module-edges.js.map +1 -0
- package/dist/core/object-literal-functions.d.ts +42 -0
- package/dist/core/object-literal-functions.d.ts.map +1 -0
- package/dist/core/object-literal-functions.js +75 -0
- package/dist/core/object-literal-functions.js.map +1 -0
- package/dist/core/orphan-exclusions.d.ts +44 -0
- package/dist/core/orphan-exclusions.d.ts.map +1 -0
- package/dist/core/orphan-exclusions.js +224 -0
- package/dist/core/orphan-exclusions.js.map +1 -0
- package/dist/core/pair-condition.d.ts +32 -3
- package/dist/core/pair-condition.d.ts.map +1 -1
- package/dist/core/path-universe.d.ts +22 -0
- package/dist/core/path-universe.d.ts.map +1 -0
- package/dist/core/path-universe.js +45 -0
- package/dist/core/path-universe.js.map +1 -0
- package/dist/core/per-root-compiler-options.d.ts +20 -0
- package/dist/core/per-root-compiler-options.d.ts.map +1 -0
- package/dist/core/per-root-compiler-options.js +57 -0
- package/dist/core/per-root-compiler-options.js.map +1 -0
- package/dist/core/project-relative.d.ts +98 -0
- package/dist/core/project-relative.d.ts.map +1 -0
- package/dist/core/project-relative.js +185 -0
- package/dist/core/project-relative.js.map +1 -0
- package/dist/core/project.d.ts +7 -1
- package/dist/core/project.d.ts.map +1 -1
- package/dist/core/project.js +29 -4
- package/dist/core/project.js.map +1 -1
- package/dist/core/rule-builder.d.ts +303 -0
- package/dist/core/rule-builder.d.ts.map +1 -0
- package/dist/core/rule-builder.js +463 -0
- package/dist/core/rule-builder.js.map +1 -0
- package/dist/core/rule-declaration.d.ts +32 -0
- package/dist/core/rule-declaration.d.ts.map +1 -0
- package/dist/core/rule-declaration.js +88 -0
- package/dist/core/rule-declaration.js.map +1 -0
- package/dist/core/terminal-builder.d.ts +629 -0
- package/dist/core/terminal-builder.d.ts.map +1 -0
- package/dist/core/terminal-builder.js +807 -0
- package/dist/core/terminal-builder.js.map +1 -0
- package/dist/core/terminal-execution.d.ts +39 -0
- package/dist/core/terminal-execution.d.ts.map +1 -0
- package/dist/core/terminal-execution.js +103 -0
- package/dist/core/terminal-execution.js.map +1 -0
- package/dist/core/ts-comment-mask.d.ts +2 -0
- package/dist/core/ts-comment-mask.d.ts.map +1 -0
- package/dist/core/ts-comment-mask.js +102 -0
- package/dist/core/ts-comment-mask.js.map +1 -0
- package/dist/core/vacuity-diagnosis.d.ts +103 -0
- package/dist/core/vacuity-diagnosis.d.ts.map +1 -0
- package/dist/core/vacuity-diagnosis.js +415 -0
- package/dist/core/vacuity-diagnosis.js.map +1 -0
- package/dist/core/violation.d.ts +16 -11
- package/dist/core/violation.d.ts.map +1 -1
- package/dist/core/violation.js +33 -13
- package/dist/core/violation.js.map +1 -1
- package/dist/graphql/graphql-rule-builder.d.ts +95 -0
- package/dist/graphql/graphql-rule-builder.d.ts.map +1 -0
- package/dist/graphql/graphql-rule-builder.js +127 -0
- package/dist/graphql/graphql-rule-builder.js.map +1 -0
- package/dist/graphql/index.d.ts +1 -0
- package/dist/graphql/index.d.ts.map +1 -1
- package/dist/graphql/index.js +2 -1
- package/dist/graphql/index.js.map +1 -1
- package/dist/graphql/resolver-rule-builder.d.ts +44 -23
- package/dist/graphql/resolver-rule-builder.d.ts.map +1 -1
- package/dist/graphql/resolver-rule-builder.js +80 -72
- package/dist/graphql/resolver-rule-builder.js.map +1 -1
- package/dist/graphql/schema-loader.d.ts +21 -0
- package/dist/graphql/schema-loader.d.ts.map +1 -1
- package/dist/graphql/schema-loader.js +82 -12
- package/dist/graphql/schema-loader.js.map +1 -1
- package/dist/graphql/schema-predicates.d.ts.map +1 -1
- package/dist/graphql/schema-predicates.js +17 -12
- package/dist/graphql/schema-predicates.js.map +1 -1
- package/dist/graphql/schema-rule-builder.d.ts +15 -24
- package/dist/graphql/schema-rule-builder.d.ts.map +1 -1
- package/dist/graphql/schema-rule-builder.js +39 -77
- package/dist/graphql/schema-rule-builder.js.map +1 -1
- package/dist/helpers/baseline-diagnostics.d.ts +45 -0
- package/dist/helpers/baseline-diagnostics.d.ts.map +1 -0
- package/dist/helpers/baseline-diagnostics.js +168 -0
- package/dist/helpers/baseline-diagnostics.js.map +1 -0
- package/dist/helpers/baseline-generator.d.ts +28 -0
- package/dist/helpers/baseline-generator.d.ts.map +1 -0
- package/dist/helpers/baseline-generator.js +27 -0
- package/dist/helpers/baseline-generator.js.map +1 -0
- package/dist/helpers/baseline.d.ts +336 -0
- package/dist/helpers/baseline.d.ts.map +1 -0
- package/dist/helpers/baseline.js +664 -0
- package/dist/helpers/baseline.js.map +1 -0
- package/dist/helpers/body-traversal.d.ts +27 -2
- package/dist/helpers/body-traversal.d.ts.map +1 -1
- package/dist/helpers/body-traversal.js +135 -16
- package/dist/helpers/body-traversal.js.map +1 -1
- package/dist/helpers/callback-extractor.d.ts.map +1 -1
- package/dist/helpers/callback-extractor.js +53 -84
- package/dist/helpers/callback-extractor.js.map +1 -1
- package/dist/helpers/complexity.d.ts +13 -5
- package/dist/helpers/complexity.d.ts.map +1 -1
- package/dist/helpers/complexity.js +15 -6
- package/dist/helpers/complexity.js.map +1 -1
- package/dist/helpers/diff-aware.d.ts +16 -0
- package/dist/helpers/diff-aware.d.ts.map +1 -0
- package/dist/helpers/diff-aware.js +16 -0
- package/dist/helpers/diff-aware.js.map +1 -0
- package/dist/helpers/matchers.d.ts +68 -7
- package/dist/helpers/matchers.d.ts.map +1 -1
- package/dist/helpers/matchers.js +164 -86
- package/dist/helpers/matchers.js.map +1 -1
- package/dist/helpers/slice-graph.d.ts +100 -8
- package/dist/helpers/slice-graph.d.ts.map +1 -1
- package/dist/helpers/slice-graph.js +126 -34
- package/dist/helpers/slice-graph.js.map +1 -1
- package/dist/helpers/tarjan.d.ts +0 -14
- package/dist/helpers/tarjan.d.ts.map +1 -1
- package/dist/helpers/tarjan.js +29 -16
- package/dist/helpers/tarjan.js.map +1 -1
- package/dist/index.d.ts +55 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +67 -15
- package/dist/index.js.map +1 -1
- package/dist/models/arch-call.d.ts +3 -2
- package/dist/models/arch-call.d.ts.map +1 -1
- package/dist/models/arch-call.js.map +1 -1
- package/dist/models/arch-function.d.ts +54 -8
- package/dist/models/arch-function.d.ts.map +1 -1
- package/dist/models/arch-function.js +145 -8
- package/dist/models/arch-function.js.map +1 -1
- package/dist/models/arch-jsx-element.d.ts.map +1 -1
- package/dist/models/arch-jsx-element.js +18 -19
- package/dist/models/arch-jsx-element.js.map +1 -1
- package/dist/models/slice.d.ts +33 -9
- package/dist/models/slice.d.ts.map +1 -1
- package/dist/models/slice.js +129 -19
- package/dist/models/slice.js.map +1 -1
- package/dist/predicates/call.d.ts.map +1 -1
- package/dist/predicates/call.js +5 -0
- package/dist/predicates/call.js.map +1 -1
- package/dist/predicates/identity.d.ts +21 -0
- package/dist/predicates/identity.d.ts.map +1 -1
- package/dist/predicates/identity.js +75 -3
- package/dist/predicates/identity.js.map +1 -1
- package/dist/predicates/index.d.ts +1 -1
- package/dist/predicates/index.d.ts.map +1 -1
- package/dist/predicates/index.js +1 -1
- package/dist/predicates/index.js.map +1 -1
- package/dist/predicates/jsx.d.ts.map +1 -1
- package/dist/predicates/jsx.js +2 -1
- package/dist/predicates/jsx.js.map +1 -1
- package/dist/predicates/metrics.d.ts +4 -2
- package/dist/predicates/metrics.d.ts.map +1 -1
- package/dist/predicates/metrics.js +4 -2
- package/dist/predicates/metrics.js.map +1 -1
- package/dist/predicates/module.d.ts +4 -12
- package/dist/predicates/module.d.ts.map +1 -1
- package/dist/predicates/module.js +57 -37
- package/dist/predicates/module.js.map +1 -1
- package/dist/presets/agent-guardrails.d.ts +49 -16
- package/dist/presets/agent-guardrails.d.ts.map +1 -1
- package/dist/presets/agent-guardrails.js +308 -19
- package/dist/presets/agent-guardrails.js.map +1 -1
- package/dist/presets/boundaries.d.ts +46 -3
- package/dist/presets/boundaries.d.ts.map +1 -1
- package/dist/presets/boundaries.js +132 -23
- package/dist/presets/boundaries.js.map +1 -1
- package/dist/presets/data-layer.d.ts +23 -3
- package/dist/presets/data-layer.d.ts.map +1 -1
- package/dist/presets/data-layer.js +58 -16
- package/dist/presets/data-layer.js.map +1 -1
- package/dist/presets/index.d.ts +10 -5
- package/dist/presets/index.d.ts.map +1 -1
- package/dist/presets/index.js +19 -3
- package/dist/presets/index.js.map +1 -1
- package/dist/presets/layered.d.ts +47 -3
- package/dist/presets/layered.d.ts.map +1 -1
- package/dist/presets/layered.js +66 -29
- package/dist/presets/layered.js.map +1 -1
- package/dist/presets/recommended.d.ts +81 -10
- package/dist/presets/recommended.d.ts.map +1 -1
- package/dist/presets/recommended.js +25 -23
- package/dist/presets/recommended.js.map +1 -1
- package/dist/presets/shared.d.ts +267 -2
- package/dist/presets/shared.d.ts.map +1 -1
- package/dist/presets/shared.js +367 -4
- package/dist/presets/shared.js.map +1 -1
- package/dist/rules/code-quality.d.ts.map +1 -1
- package/dist/rules/code-quality.js +15 -6
- package/dist/rules/code-quality.js.map +1 -1
- package/dist/rules/hygiene.d.ts +1 -1
- package/dist/rules/hygiene.js +1 -1
- package/dist/rules/metrics-function.d.ts +2 -1
- package/dist/rules/metrics-function.d.ts.map +1 -1
- package/dist/rules/metrics-function.js +63 -39
- package/dist/rules/metrics-function.js.map +1 -1
- package/dist/rules/metrics.d.ts +2 -1
- package/dist/rules/metrics.d.ts.map +1 -1
- package/dist/rules/metrics.js +80 -47
- package/dist/rules/metrics.js.map +1 -1
- package/dist/smells/clusters.d.ts +78 -0
- package/dist/smells/clusters.d.ts.map +1 -0
- package/dist/smells/clusters.js +124 -0
- package/dist/smells/clusters.js.map +1 -0
- package/dist/smells/duplicate-bodies.d.ts +92 -5
- package/dist/smells/duplicate-bodies.d.ts.map +1 -1
- package/dist/smells/duplicate-bodies.js +203 -73
- package/dist/smells/duplicate-bodies.js.map +1 -1
- package/dist/smells/duplicate-report.d.ts +90 -0
- package/dist/smells/duplicate-report.d.ts.map +1 -0
- package/dist/smells/duplicate-report.js +344 -0
- package/dist/smells/duplicate-report.js.map +1 -0
- package/dist/smells/fingerprint.d.ts +20 -1
- package/dist/smells/fingerprint.d.ts.map +1 -1
- package/dist/smells/fingerprint.js +27 -3
- package/dist/smells/fingerprint.js.map +1 -1
- package/dist/smells/inconsistent-siblings.d.ts +128 -7
- package/dist/smells/inconsistent-siblings.d.ts.map +1 -1
- package/dist/smells/inconsistent-siblings.js +288 -86
- package/dist/smells/inconsistent-siblings.js.map +1 -1
- package/dist/smells/sibling-files.d.ts +47 -0
- package/dist/smells/sibling-files.d.ts.map +1 -0
- package/dist/smells/sibling-files.js +104 -0
- package/dist/smells/sibling-files.js.map +1 -0
- package/dist/smells/similar-pairs.d.ts +28 -0
- package/dist/smells/similar-pairs.d.ts.map +1 -0
- package/dist/smells/similar-pairs.js +134 -0
- package/dist/smells/similar-pairs.js.map +1 -0
- package/dist/smells/smell-builder.d.ts +57 -12
- package/dist/smells/smell-builder.d.ts.map +1 -1
- package/dist/smells/smell-builder.js +112 -14
- package/dist/smells/smell-builder.js.map +1 -1
- package/dist/smells/variation.d.ts +47 -0
- package/dist/smells/variation.d.ts.map +1 -0
- package/dist/smells/variation.js +90 -0
- package/dist/smells/variation.js.map +1 -0
- package/dist/tsconfig/index.d.ts +19 -0
- package/dist/tsconfig/index.d.ts.map +1 -0
- package/dist/tsconfig/index.js +20 -0
- package/dist/tsconfig/index.js.map +1 -0
- package/dist/tsconfig/tsconfig-builder.d.ts +42 -9
- package/dist/tsconfig/tsconfig-builder.d.ts.map +1 -1
- package/dist/tsconfig/tsconfig-builder.js +65 -16
- package/dist/tsconfig/tsconfig-builder.js.map +1 -1
- package/package.json +4 -2
- package/dist/core/module-dependencies.d.ts +0 -28
- package/dist/core/module-dependencies.d.ts.map +0 -1
- package/dist/core/module-dependencies.js +0 -35
- package/dist/core/module-dependencies.js.map +0 -1
- package/dist/helpers/within.d.ts.map +0 -1
- package/dist/helpers/within.js.map +0 -1
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
import { DECLARE_INSTEAD, isFaultPosition, UNSUPPRESSABLE } from '@nielspeter/eess/internal';
|
|
2
|
+
import { diagnoseGlob, FAULT_ADVICE, ON_DISK_ADVICE } from './glob-diagnosis.js';
|
|
3
|
+
import { globSitesOf, isDeadGlobTree, isDeadSite } from './glob-evaluator.js';
|
|
4
|
+
import { pathUniverse } from './path-universe.js';
|
|
5
|
+
import { diskSet } from './disk-set.js';
|
|
6
|
+
import { emptyProjectAdvice, loadedNothing } from './empty-project-advice.js';
|
|
7
|
+
/**
|
|
8
|
+
* The unit noun, singular when there is one of it — plan 0099.
|
|
9
|
+
*
|
|
10
|
+
* `n === 1` is the MOST likely expiry case: a declaration expires the day the
|
|
11
|
+
* first thing appears, so "it examined 1 subjects" is the sentence a reader is
|
|
12
|
+
* likeliest to meet. The zero-subjects sentence one method away already
|
|
13
|
+
* pluralises its file count correctly.
|
|
14
|
+
*/
|
|
15
|
+
function singularise(noun, n) {
|
|
16
|
+
if (n !== 1)
|
|
17
|
+
return noun;
|
|
18
|
+
return noun.endsWith('ies') ? `${noun.slice(0, -3)}y` : noun.replace(/s$/, '');
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* What a rule can be asked about itself, without running it.
|
|
22
|
+
*
|
|
23
|
+
* Every diagnosis in this module is a function of these and nothing else — none
|
|
24
|
+
* of them evaluates the rule. That is what let them leave `TerminalBuilder`:
|
|
25
|
+
* they were never terminal behaviour, they were explanations OF it, and keeping
|
|
26
|
+
* them on the class is most of why it carried 372 code lines.
|
|
27
|
+
*/
|
|
28
|
+
// Consumed by the test suite; the build tsconfig this gate reads excludes tests,
|
|
29
|
+
// so `src` is the only usage it can see. The directive sits LAST because a
|
|
30
|
+
// single-line waiver covers exactly the next line.
|
|
31
|
+
// eess-exclude eess/no-unused-exports: test-only consumer
|
|
32
|
+
export const ASSERTION_DOCS = 'https://github.com/nielspeter/eess/blob/main/docs/violation-reporting.md#a-rule-must-assert-something';
|
|
33
|
+
/**
|
|
34
|
+
* The finding for a rule that states no assertion at all.
|
|
35
|
+
*
|
|
36
|
+
* Extracted from `collectWithAssertionGuard`, which was the assertion gate,
|
|
37
|
+
* the dead-selector gate, the evidence floor AND this constructor in one
|
|
38
|
+
* method — most of its branching was the reader having to hold all four.
|
|
39
|
+
*/
|
|
40
|
+
export function assertionLessFinding(facts) {
|
|
41
|
+
const described = facts.describeRule();
|
|
42
|
+
const name = described.id || described.rule || facts.ruleClass.name;
|
|
43
|
+
// ADR-009 rule 3: where there is deliberately no escape hatch, say so, and
|
|
44
|
+
// say what to do instead. Stated on the finding rather than inside
|
|
45
|
+
// `assertionAdvice()` so the seven per-shape remedies stay one sentence each
|
|
46
|
+
// and this stays one sentence in one place. Measured before it was added: a
|
|
47
|
+
// reader given only the remedy tries `.asSeverity('warn')`, `.excluding()`,
|
|
48
|
+
// the baseline and `--changed` — four CI cycles — because nothing told them
|
|
49
|
+
// those were refused.
|
|
50
|
+
const advice = `${facts.assertionAdvice()} ${UNSUPPRESSABLE}`;
|
|
51
|
+
return [
|
|
52
|
+
{
|
|
53
|
+
rule: name,
|
|
54
|
+
ruleId: described.id,
|
|
55
|
+
element: name,
|
|
56
|
+
file: '',
|
|
57
|
+
line: 0,
|
|
58
|
+
message: advice,
|
|
59
|
+
// Its own remedy, never the author's (bug 0021): their `suggestion`
|
|
60
|
+
// describes how to fix a violation of the rule, and this finding says
|
|
61
|
+
// the rule cannot produce one. Same for `docs` — the author's link is
|
|
62
|
+
// about their rule; this one is about the grammar the rule broke.
|
|
63
|
+
suggestion: advice,
|
|
64
|
+
docs: ASSERTION_DOCS,
|
|
65
|
+
bypassFilters: true,
|
|
66
|
+
// `ruleId` and `because` are deliberately NOT set here. `applyFilters`
|
|
67
|
+
// fills both from the rule's metadata for every finding that leaves
|
|
68
|
+
// them unset, and all three callers of this method go through it — so
|
|
69
|
+
// setting them here was two lines that read as load-bearing and were
|
|
70
|
+
// not: sabotage removed each with nothing failing. The remedy fields
|
|
71
|
+
// above are the opposite case, and must stay, because `applyFilters`
|
|
72
|
+
// deliberately refuses to supply those for a `bypassFilters` finding.
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Walk the glob trees and split the dead sites by position.
|
|
78
|
+
*
|
|
79
|
+
* Extracted from `deadSelectorFindings`, which is otherwise five guard clauses
|
|
80
|
+
* and this loop — the guards are the interesting part and the nesting was most
|
|
81
|
+
* of the branching.
|
|
82
|
+
*/
|
|
83
|
+
function deadSitesIn(facts, trees, project) {
|
|
84
|
+
const universe = pathUniverse(project);
|
|
85
|
+
const selector = [];
|
|
86
|
+
const discovery = [];
|
|
87
|
+
for (const tree of trees) {
|
|
88
|
+
// Only inside a tree that is dead as a whole: `or(dead, live)` is a
|
|
89
|
+
// working rule, and reporting its dead branch is the false red the tree
|
|
90
|
+
// model exists to prevent.
|
|
91
|
+
if (!isDeadGlobTree(tree, universe))
|
|
92
|
+
continue;
|
|
93
|
+
for (const site of globSitesOf(tree)) {
|
|
94
|
+
// `isFaultPosition`, shared with `diagnose()` — the two used inverse
|
|
95
|
+
// hand-maintained lists and disagreed about exactly `discovery`, which
|
|
96
|
+
// is why `doctor` reported a dead layer glob and the build did not.
|
|
97
|
+
if (!isFaultPosition(site.position))
|
|
98
|
+
continue;
|
|
99
|
+
if (!isDeadSite(site, universe))
|
|
100
|
+
continue;
|
|
101
|
+
const finding = deadSelectorViolation(facts, site, universe, project);
|
|
102
|
+
if (site.position === 'discovery')
|
|
103
|
+
discovery.push(finding);
|
|
104
|
+
else
|
|
105
|
+
selector.push(finding);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return { selector, discovery };
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The finding for one dead selector glob.
|
|
112
|
+
*
|
|
113
|
+
* Carries the SAME cause and advice `doctor` prints, from the same two
|
|
114
|
+
* tables — a reader who ran the pre-flight must not be told something
|
|
115
|
+
* different by the build that fails. Bugs 0031 and 0032 are why the tables
|
|
116
|
+
* are worth reusing rather than paraphrasing: both were cases where the
|
|
117
|
+
* cause stated was wrong for the input, and both were fixed in one place.
|
|
118
|
+
*
|
|
119
|
+
* `bypassFilters` makes it a configuration finding: `error` severity
|
|
120
|
+
* regardless of `.asSeverity('warn')`, refused by `.excluding()`, and
|
|
121
|
+
* skipped by diff and baseline (ADR-009 rule 1). A rule that can never have
|
|
122
|
+
* subjects is not a violation you triage; it is a rule that does not work.
|
|
123
|
+
*/
|
|
124
|
+
function deadSelectorViolation(facts, site, universe, project) {
|
|
125
|
+
const described = facts.describeRule();
|
|
126
|
+
const name = described.id || described.rule || facts.ruleClass.name;
|
|
127
|
+
const diagnosis = diagnoseGlob(site, universe, diskSet(project));
|
|
128
|
+
const onDisk = diagnosis.onDisk === undefined ? '' : ON_DISK_ADVICE[diagnosis.onDisk];
|
|
129
|
+
const cause = onDisk === '' ? FAULT_ADVICE[diagnosis.fault] : onDisk;
|
|
130
|
+
// Position-aware in BOTH clauses, not just the noun (plan 0080).
|
|
131
|
+
//
|
|
132
|
+
// Admitting `discovery` globs made this sentence wrong twice over for them.
|
|
133
|
+
// The noun was the obvious half — a `smells.duplicateBodies().inFolder()` glob
|
|
134
|
+
// is not a "selector". The **consequence clause** was the part that actually
|
|
135
|
+
// lied: "it has no subjects and cannot fail" describes a rule that selects
|
|
136
|
+
// nothing, while a dead discovery glob means the rule discovered nothing to
|
|
137
|
+
// compare — there may be plenty of subjects. Review flagged that fixing the
|
|
138
|
+
// noun alone ships a grammatical sentence that is still false.
|
|
139
|
+
const isDiscovery = site.position === 'discovery';
|
|
140
|
+
const what = isDiscovery ? 'discovery glob' : 'selector';
|
|
141
|
+
const consequence = isDiscovery
|
|
142
|
+
? 'so it discovers nothing to check and cannot fail'
|
|
143
|
+
: 'so it has no subjects and cannot fail';
|
|
144
|
+
const advice = `This rule's ${what} ${site.origin} can never match anything in this project, ` +
|
|
145
|
+
`${consequence} — ${cause}. ` +
|
|
146
|
+
`Correct the glob, or remove the rule. ${UNSUPPRESSABLE}`;
|
|
147
|
+
return {
|
|
148
|
+
rule: name,
|
|
149
|
+
ruleId: described.id,
|
|
150
|
+
element: site.glob,
|
|
151
|
+
file: '',
|
|
152
|
+
line: 0,
|
|
153
|
+
message: advice,
|
|
154
|
+
// Its own remedy, never the author's (bug 0021): their `suggestion` is
|
|
155
|
+
// for a violation of the rule, and this says the rule cannot produce one.
|
|
156
|
+
suggestion: advice,
|
|
157
|
+
bypassFilters: true,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* ADR-010's floor: what to report when a family produced NOTHING from NOTHING.
|
|
162
|
+
*
|
|
163
|
+
* `undefined` means "no floor finding — carry on", which is not the same as
|
|
164
|
+
* an empty array (that is a deliberate pass, and `assertsCardinality()`
|
|
165
|
+
* returns one).
|
|
166
|
+
*
|
|
167
|
+
* A family that produced ANY finding passes through untouched. The floor
|
|
168
|
+
* fires only where a family produced nothing from nothing — bug 0066's shape.
|
|
169
|
+
* Each family's own empty-selection block stays as the better-attributed
|
|
170
|
+
* implementation; this is a floor beneath them, not a replacement.
|
|
171
|
+
*
|
|
172
|
+
* Precedence has already removed the other causes by the time this is reached:
|
|
173
|
+
* no dead selector glob, no missing assertion, no empty project, no cardinality
|
|
174
|
+
* assertion, no declaration. So the remedy names ONE cause without the hedging
|
|
175
|
+
* ADR-009 rule 2 forbids.
|
|
176
|
+
*
|
|
177
|
+
* Three defects in 0098's preview wording are fixed here, from its
|
|
178
|
+
* user-perspective review:
|
|
179
|
+
*
|
|
180
|
+
* - **It hedged where we hold the fact.** "including any default it applies
|
|
181
|
+
* that you did not write" was printed as a hypothetical while the rule knew
|
|
182
|
+
* the answer. We materialized the selection, so we know the project loaded N
|
|
183
|
+
* files and the selection produced 0 — print the numbers.
|
|
184
|
+
* - **"can never fail" overstated.** For a `crossLayer` rule whose pairs do not
|
|
185
|
+
* exist yet, or a folder empty in a young repository, the rule is correct and
|
|
186
|
+
* matches nothing *today*. "never" made a true statement false.
|
|
187
|
+
* - **The ranking was wrong for the people most likely to adopt early.** It
|
|
188
|
+
* called widening the fix and declaring "the exception… proves nothing". For
|
|
189
|
+
* a team whose second layer is not built yet, widening is *impossible* — the
|
|
190
|
+
* code does not exist — so the only available action was the one the message
|
|
191
|
+
* disparaged. Both are now offered as peers, and the declaration is described
|
|
192
|
+
* by what it does: it expires.
|
|
193
|
+
*/
|
|
194
|
+
export function evidenceFloor(facts, violations, examined) {
|
|
195
|
+
if (violations.length !== 0 || examined !== 0)
|
|
196
|
+
return undefined;
|
|
197
|
+
// The instrument outranks the selection. A declaration asserts a fact
|
|
198
|
+
// about a LOADED corpus; over zero loaded files it asserts nothing, and
|
|
199
|
+
// the expiry that justifies `.expectEmpty()` can never engage — so on a
|
|
200
|
+
// solution-style tsconfig a one-line declaration would restore bug 0066's
|
|
201
|
+
// 401-findings-reported-clean permanently, through the sanctioned door.
|
|
202
|
+
// This supersedes the precedence bug 0066's root-cause note endorsed:
|
|
203
|
+
// that ordering is right at SELECTION level and wrong at INSTRUMENT level.
|
|
204
|
+
//
|
|
205
|
+
// `getProject()` may be undefined and that is honest, not a gap:
|
|
206
|
+
// `crossProject` discards its project by documented design, and an
|
|
207
|
+
// ADR-010 dialect over a non-TypeScript element type has none. The
|
|
208
|
+
// instrument check is skipped; the zero-subjects floor below still holds.
|
|
209
|
+
const project = facts.getProject();
|
|
210
|
+
if (project !== undefined && loadedNothing(project)) {
|
|
211
|
+
return [emptyProjectViolation(facts, project)];
|
|
212
|
+
}
|
|
213
|
+
// `.notExist()` and friends examine zero BECAUSE that is what they
|
|
214
|
+
// assert. Exempt since 0.34.0, and `diagnose()` exempts it too — the two
|
|
215
|
+
// must agree or `doctor` and `check` disagree about a working rule.
|
|
216
|
+
if (facts.assertsCardinality())
|
|
217
|
+
return violations;
|
|
218
|
+
// The author said empty is the point. `declaresEmpty()` — not
|
|
219
|
+
// `_expectEmpty` — because `CrossProjectBuilder` declares per side and
|
|
220
|
+
// overrides this; asking a fully-declared crossProject to declare would
|
|
221
|
+
// be ADR-009 rule 2's loop, and the base implementation cannot express it.
|
|
222
|
+
if (!facts.declaresEmpty())
|
|
223
|
+
return [facts.zeroSubjectsViolation(project)];
|
|
224
|
+
return undefined;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* The finding for a project that loaded no source files.
|
|
228
|
+
*
|
|
229
|
+
* Deliberately **not** `deadSelectorViolation` with different text: that one
|
|
230
|
+
* names a glob as its `element`, and here no glob is at fault. The element is
|
|
231
|
+
* the rule, matching how `diagnose()` reports this state.
|
|
232
|
+
*
|
|
233
|
+
* Carries the same advice `doctor` prints, from the one owner
|
|
234
|
+
* (`empty-project-advice.ts`) — the parity `deadSelectorViolation`'s docstring
|
|
235
|
+
* claims for the whole gate, which was false for this input until bug 0048.
|
|
236
|
+
*/
|
|
237
|
+
function emptyProjectViolation(facts, project) {
|
|
238
|
+
const described = facts.describeRule();
|
|
239
|
+
const name = described.id || described.rule || facts.ruleClass.name;
|
|
240
|
+
// `emptyProjectAdvice` deliberately returns a lowercase, period-less clause so
|
|
241
|
+
// each caller can frame it. Capitalised inline rather than via a shared helper:
|
|
242
|
+
// `slice-rule-builder.ts` has its own local `capitalize` and core has none, so
|
|
243
|
+
// importing across that boundary for one character would be the worse trade.
|
|
244
|
+
const shared = emptyProjectAdvice(project);
|
|
245
|
+
const advice = `${shared.charAt(0).toUpperCase()}${shared.slice(1)}. ${UNSUPPRESSABLE}`;
|
|
246
|
+
return {
|
|
247
|
+
rule: name,
|
|
248
|
+
ruleId: described.id,
|
|
249
|
+
element: name,
|
|
250
|
+
file: '',
|
|
251
|
+
line: 0,
|
|
252
|
+
message: advice,
|
|
253
|
+
// Its own remedy, never the author's (bug 0021).
|
|
254
|
+
suggestion: advice,
|
|
255
|
+
bypassFilters: true,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* A declaration that has expired — plan 0099.
|
|
260
|
+
*
|
|
261
|
+
* The property that makes `.expectEmpty()` an assertion rather than
|
|
262
|
+
* `allowEmpty()`'s permission, which had no failing state and so stayed green
|
|
263
|
+
* forever. Here the number IS the finding: the author asserted zero and the
|
|
264
|
+
* answer is not zero.
|
|
265
|
+
*
|
|
266
|
+
* The remedy is DISTINCT from the message, because `format.ts` drops the `Fix:`
|
|
267
|
+
* line when the two are equal — a defect this producer's rule-builder ancestor
|
|
268
|
+
* shipped with, found in review of plan 0089.
|
|
269
|
+
*/
|
|
270
|
+
export function expiredDeclarationViolation(facts, examined) {
|
|
271
|
+
const described = facts.describeRule();
|
|
272
|
+
const name = described.id || described.rule || facts.ruleClass.name;
|
|
273
|
+
const declaration = facts.emptyDeclarationAdvice();
|
|
274
|
+
const message = `${declaration} asserted this rule examines nothing, and it examined ${String(examined)} ${singularise(facts.examinedUnitNoun(), examined)}.`;
|
|
275
|
+
const suggestion = `Remove ${declaration} and let the rule enforce itself — the thing you were waiting for has ` +
|
|
276
|
+
`appeared, and the rule now has something to check. If instead the selection is wider than you ` +
|
|
277
|
+
`meant, narrow it and keep the declaration. ` +
|
|
278
|
+
`The rule's own violations are reported as separate findings under the same rule id. ` +
|
|
279
|
+
UNSUPPRESSABLE;
|
|
280
|
+
return {
|
|
281
|
+
rule: name,
|
|
282
|
+
ruleId: described.id,
|
|
283
|
+
// The DESCRIPTION, not the id — and this is the one place in this file
|
|
284
|
+
// where that differs on purpose.
|
|
285
|
+
//
|
|
286
|
+
// `dedupeConfigFindings` keys on `(file, ruleId ?? rule, element)`. With
|
|
287
|
+
// `file: ''` and the id in both remaining slots, every instance of a
|
|
288
|
+
// fanned-out preset id collapses to one and picks up `affectedNote`'s
|
|
289
|
+
// "this one option generated N rules that cannot enforce anything".
|
|
290
|
+
//
|
|
291
|
+
// For `zeroSubjectsViolation` that collapse is CORRECT: those N rules
|
|
292
|
+
// genuinely cannot enforce, and they are one edit. Here it is false — a
|
|
293
|
+
// rule whose declaration expired enforces fine, and its violations are
|
|
294
|
+
// reported alongside. Measured in review of plan 0089: 4 findings became 3,
|
|
295
|
+
// the survivor claiming two rules could not enforce while both their real
|
|
296
|
+
// violations sat below it. `RuleBuilder.describeRule()` returns the chain
|
|
297
|
+
// description, which differs per instance and keeps them distinct.
|
|
298
|
+
element: described.rule || name,
|
|
299
|
+
file: '',
|
|
300
|
+
line: 0,
|
|
301
|
+
message,
|
|
302
|
+
suggestion,
|
|
303
|
+
bypassFilters: true,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* A dead glob's findings, **split by whether the builder might own the message**.
|
|
308
|
+
*
|
|
309
|
+
* `selector` and `discovery` are both faults (`isFaultPosition`), but the caller
|
|
310
|
+
* treats them differently: a dead selector short-circuits before the AST walk,
|
|
311
|
+
* while a dead discovery glob defers to whatever the builder produced. An
|
|
312
|
+
* `ArchViolation` carries no position, so the split happens here rather than
|
|
313
|
+
* being recovered by inspecting findings downstream.
|
|
314
|
+
*/
|
|
315
|
+
export function deadSelectorFindings(facts) {
|
|
316
|
+
// Annotated: inferred, this is `{ selector: never[]; discovery: never[] }`,
|
|
317
|
+
// and it is returned from four early-exit paths. Nothing mutates it today —
|
|
318
|
+
// but a `push` onto a `never[]` is a type error whose message points at the
|
|
319
|
+
// literal rather than at the caller that meant to add a finding.
|
|
320
|
+
const empty = {
|
|
321
|
+
selector: [],
|
|
322
|
+
discovery: [],
|
|
323
|
+
};
|
|
324
|
+
const project = facts.getProject();
|
|
325
|
+
if (project === undefined)
|
|
326
|
+
return empty;
|
|
327
|
+
// A condition that asserts CARDINALITY is satisfied by having no subjects,
|
|
328
|
+
// so an unsatisfiable selector is this rule working rather than failing —
|
|
329
|
+
// the pre-emptive guard `.should().notExist()` expresses. Declared by the
|
|
330
|
+
// condition, never probed: evaluating any condition against `[]` returns no
|
|
331
|
+
// violations, so probing answers "satisfied" for all of them.
|
|
332
|
+
if (facts.assertsCardinality())
|
|
333
|
+
return empty;
|
|
334
|
+
const trees = facts.globs();
|
|
335
|
+
if (trees.length === 0)
|
|
336
|
+
return empty;
|
|
337
|
+
// The project loaded nothing, so no glob can match and none of them is at
|
|
338
|
+
// fault — [ts-archunit bug 0048](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0048-the-dead-glob-gate-blames-the-glob-when-the-project-is-empty.md).
|
|
339
|
+
//
|
|
340
|
+
// Without this the gate reported every selector glob dead and told the
|
|
341
|
+
// reader to *"Correct the glob, or remove the rule"*, which is a remedy for
|
|
342
|
+
// a fault that is not theirs: measured on an empty tsconfig, the glob was
|
|
343
|
+
// correct and the tsconfig had loaded 0 files. `diagnose()` short-circuited
|
|
344
|
+
// here (bug 0031) and `SliceRuleBuilder` had its own branch; this gate had
|
|
345
|
+
// neither, so the wrong remedy sat on the path every `modules()`,
|
|
346
|
+
// `classes()`, `functions()` and `types()` rule takes.
|
|
347
|
+
//
|
|
348
|
+
// One finding for the project, not one per glob — the identity of this fault
|
|
349
|
+
// is the tsconfig, which is what ADR-009 rule 4 asks be named, and it is why
|
|
350
|
+
// `diagnose()` dedupes by project too.
|
|
351
|
+
if (loadedNothing(project))
|
|
352
|
+
return { selector: [emptyProjectViolation(facts, project)], discovery: [] };
|
|
353
|
+
return deadSitesIn(facts, trees, project);
|
|
354
|
+
}
|
|
355
|
+
/** The value behind `TerminalBuilder.zeroSubjectsAdvice()`. */
|
|
356
|
+
export function zeroSubjectsAdviceOf(facts) {
|
|
357
|
+
const project = facts.getProject();
|
|
358
|
+
const loaded = project === undefined ? undefined : project.getSourceFiles().length;
|
|
359
|
+
// The project file count is CONTEXT in parentheses, never a denominator: the
|
|
360
|
+
// rule did not examine files, and "0 of 616" reads as a glob problem when the
|
|
361
|
+
// glob may already match everything.
|
|
362
|
+
const context = loaded === undefined
|
|
363
|
+
? ''
|
|
364
|
+
: ` (the project loaded ${String(loaded)} file${loaded === 1 ? '' : 's'})`;
|
|
365
|
+
const counted = `This rule examined 0 ${facts.examinedUnitNoun()}${context}`;
|
|
366
|
+
// Name the excluder when the family knows it; name the POSSIBILITY when it
|
|
367
|
+
// does not. Deleting the possibility was a measured regression: 0.58's
|
|
368
|
+
// preview said "including any default it applies that you did not write",
|
|
369
|
+
// this plan called that hedging, and the replacement printed numbers that
|
|
370
|
+
// disclose no cause — net information loss on the commonest real case.
|
|
371
|
+
// "removed them" asserts there was something to remove. On a corpus that
|
|
372
|
+
// never contained a single unit of this family's kind, nothing was removed
|
|
373
|
+
// and the true cause is upstream — `narrowingHint()`'s own docstring promises
|
|
374
|
+
// the caller "names the possibility rather than asserting a cause it cannot
|
|
375
|
+
// verify", and asserting removal breaks that promise.
|
|
376
|
+
const hint = facts.narrowingHint();
|
|
377
|
+
const cause = hint === undefined
|
|
378
|
+
? ' Its own narrowing may have removed them — including any default it applies that you did not write.'
|
|
379
|
+
: ` ${hint}`;
|
|
380
|
+
return (`${counted}, so it enforces nothing as written today.${cause} ` +
|
|
381
|
+
`Either close the gap — widen the selector, or add the code it is waiting for — or declare ` +
|
|
382
|
+
`the empty state with ${facts.emptyDeclarationAdvice()} — a declaration is an assertion, not ` +
|
|
383
|
+
`a silencer: it fails the day something does match.`);
|
|
384
|
+
}
|
|
385
|
+
/** The value behind `TerminalBuilder.zeroSubjectsViolation()`. */
|
|
386
|
+
export function zeroSubjectsViolationOf(facts, project) {
|
|
387
|
+
// The precedence lives HERE, not only at the call site, because this
|
|
388
|
+
// producer's docstring declares "no empty project" as a precondition and an
|
|
389
|
+
// assumed precondition is one a second caller forgets.
|
|
390
|
+
//
|
|
391
|
+
// Measured: `rule-builder`'s `emptySelectionViolation` called this directly,
|
|
392
|
+
// and `deadSelectorFindings` only catches a rule that DECLARES a glob — so
|
|
393
|
+
// `functions(p).that().haveNameMatching(/x/)` over a zero-file project was
|
|
394
|
+
// told "widen it, or declare the empty state". Both remedies are impossible
|
|
395
|
+
// on that input, and the sentence stated the instrument-level fact and then
|
|
396
|
+
// gave selection-level advice contradicting it.
|
|
397
|
+
if (project !== undefined && loadedNothing(project)) {
|
|
398
|
+
return emptyProjectViolation(facts, project);
|
|
399
|
+
}
|
|
400
|
+
const described = facts.describeRule();
|
|
401
|
+
const name = described.id || described.rule || facts.ruleClass.name;
|
|
402
|
+
const advice = `${facts.zeroSubjectsAdvice()} ${UNSUPPRESSABLE} ${DECLARE_INSTEAD}`;
|
|
403
|
+
return {
|
|
404
|
+
rule: name,
|
|
405
|
+
ruleId: described.id,
|
|
406
|
+
element: name,
|
|
407
|
+
file: '',
|
|
408
|
+
line: 0,
|
|
409
|
+
message: advice,
|
|
410
|
+
// Its own remedy, never the author's (bug 0021).
|
|
411
|
+
suggestion: advice,
|
|
412
|
+
bypassFilters: true,
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
//# sourceMappingURL=vacuity-diagnosis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vacuity-diagnosis.js","sourceRoot":"","sources":["../../src/core/vacuity-diagnosis.ts"],"names":[],"mappings":"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"}
|
package/dist/core/violation.d.ts
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
1
|
import { Node } from 'ts-morph';
|
|
2
|
-
import {
|
|
3
|
-
export
|
|
2
|
+
import type { ArchViolation } from '@nielspeter/eess';
|
|
3
|
+
export declare function getElementName(node: Node): string;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* The structural name of the nearest ENCLOSING declaration — always an ancestor
|
|
6
|
+
* walk, never the node's own name.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
8
|
+
* Split out of `getElementName`, which returns the node's own name when it has
|
|
9
|
+
* one and only walks ancestors otherwise. That difference is invisible until
|
|
10
|
+
* something needs "what encloses this?" rather than "what is this called?", and
|
|
11
|
+
* then it is a defect: a metric identity built on `getElementName` as if it were
|
|
12
|
+
* a scope left method-shorthand object-literal functions (`{ build() {} }`)
|
|
13
|
+
* unqualified, because a `MethodDeclaration` has its own name — so two factories
|
|
14
|
+
* each returning `{ build() {} }` shared one identity while the arrow spelling
|
|
15
|
+
* of the same code did not.
|
|
12
16
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
17
|
+
* Returns `undefined` when no named declaration encloses the node, which is a
|
|
18
|
+
* real answer — a literal passed as a call argument at module level has no scope
|
|
19
|
+
* — and not a value to substitute a kind name for.
|
|
15
20
|
*/
|
|
16
|
-
export declare function
|
|
21
|
+
export declare function enclosingScopeName(node: Node): string | undefined;
|
|
17
22
|
/**
|
|
18
23
|
* Get the absolute file path for a ts-morph Node.
|
|
19
24
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"violation.d.ts","sourceRoot":"","sources":["../../src/core/violation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAC/B,OAAO,
|
|
1
|
+
{"version":3,"file":"violation.d.ts","sourceRoot":"","sources":["../../src/core/violation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AA8ErD,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAIjD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAsBjE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEjD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEjD;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,GACA,aAAa,CAef"}
|
package/dist/core/violation.js
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { Node } from 'ts-morph';
|
|
2
2
|
import { generateCodeFrame } from '@nielspeter/eess';
|
|
3
|
+
/**
|
|
4
|
+
* The ts-morph half of violation construction — plan 0165 Phase 2.
|
|
5
|
+
*
|
|
6
|
+
* Everything here takes a `Node`, which is why it cannot live in the kernel:
|
|
7
|
+
* `@nielspeter/eess` is engine-independent by charter (ADR-007), and the five
|
|
8
|
+
* dialects that sit on it have no AST in common. The pure half — the
|
|
9
|
+
* `ArchViolation` shape itself, `severityFor`, `remedyRepeatsMessage`,
|
|
10
|
+
* `byCodepoint`, `subjectOf` and the identity-collision machinery — is the
|
|
11
|
+
* kernel's, and there is now exactly ONE copy of it at runtime rather than two.
|
|
12
|
+
* Two copies is not a tidiness complaint: Phase 1 measured a comment-suppression
|
|
13
|
+
* registry written by one and read by the other.
|
|
14
|
+
*/
|
|
3
15
|
/**
|
|
4
16
|
* Check if a node is a named declaration and return its name, or undefined.
|
|
5
17
|
* Constructors return "constructor" since they have no getName().
|
|
@@ -55,22 +67,30 @@ function isTopLevelDeclaration(node) {
|
|
|
55
67
|
Node.isEnumDeclaration(node) ||
|
|
56
68
|
Node.isFunctionDeclaration(node));
|
|
57
69
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Extract a human-readable name from a ts-morph Node.
|
|
60
|
-
*
|
|
61
|
-
* If the node itself is a named declaration (class, function, method, etc.),
|
|
62
|
-
* returns its name directly. Otherwise, walks up the AST ancestors to find
|
|
63
|
-
* the nearest named declaration and builds a qualified name like
|
|
64
|
-
* "ClassName.methodName". This ensures that inner nodes (e.g., AsExpression,
|
|
65
|
-
* CallExpression) produce meaningful element names for `.excluding()` matching.
|
|
66
|
-
*
|
|
67
|
-
* Falls back to the node's kind name only if no named ancestor is found
|
|
68
|
-
* (e.g., top-level expressions in a module).
|
|
69
|
-
*/
|
|
70
70
|
export function getElementName(node) {
|
|
71
71
|
const directName = getNodeName(node);
|
|
72
72
|
if (directName !== undefined)
|
|
73
73
|
return directName;
|
|
74
|
+
return enclosingScopeName(node) ?? node.getKindName();
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The structural name of the nearest ENCLOSING declaration — always an ancestor
|
|
78
|
+
* walk, never the node's own name.
|
|
79
|
+
*
|
|
80
|
+
* Split out of `getElementName`, which returns the node's own name when it has
|
|
81
|
+
* one and only walks ancestors otherwise. That difference is invisible until
|
|
82
|
+
* something needs "what encloses this?" rather than "what is this called?", and
|
|
83
|
+
* then it is a defect: a metric identity built on `getElementName` as if it were
|
|
84
|
+
* a scope left method-shorthand object-literal functions (`{ build() {} }`)
|
|
85
|
+
* unqualified, because a `MethodDeclaration` has its own name — so two factories
|
|
86
|
+
* each returning `{ build() {} }` shared one identity while the arrow spelling
|
|
87
|
+
* of the same code did not.
|
|
88
|
+
*
|
|
89
|
+
* Returns `undefined` when no named declaration encloses the node, which is a
|
|
90
|
+
* real answer — a literal passed as a call argument at module level has no scope
|
|
91
|
+
* — and not a value to substitute a kind name for.
|
|
92
|
+
*/
|
|
93
|
+
export function enclosingScopeName(node) {
|
|
74
94
|
// Walk up ancestors collecting structural names: method/constructor/accessor
|
|
75
95
|
// at the member level, class/function at the top level. Skips variables,
|
|
76
96
|
// properties, and expressions — those are implementation detail.
|
|
@@ -91,7 +111,7 @@ export function getElementName(node) {
|
|
|
91
111
|
}
|
|
92
112
|
current = current.getParent();
|
|
93
113
|
}
|
|
94
|
-
return parts.length > 0 ? parts.join('.') :
|
|
114
|
+
return parts.length > 0 ? parts.join('.') : undefined;
|
|
95
115
|
}
|
|
96
116
|
/**
|
|
97
117
|
* Get the absolute file path for a ts-morph Node.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"violation.js","sourceRoot":"","sources":["../../src/core/violation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"violation.js","sourceRoot":"","sources":["../../src/core/violation.ts"],"names":[],"mappings":"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"}
|