@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,132 @@
|
|
|
1
|
+
import { createViolation, enclosingScopeName, getElementName } from './violation.js';
|
|
2
|
+
/**
|
|
3
|
+
* A finding whose message states a **measurement** — bug 0012.
|
|
4
|
+
*
|
|
5
|
+
* Metric conditions write the measured value into the message:
|
|
6
|
+
*
|
|
7
|
+
* Big has 10 methods (max: 5) — consider splitting into focused classes
|
|
8
|
+
*
|
|
9
|
+
* `hashViolation` identifies a violation by its message, so the identity moved
|
|
10
|
+
* whenever the measurement moved — **in either direction**. Baseline a class at
|
|
11
|
+
* 10 methods, delete two, and the finding was reported as new:
|
|
12
|
+
*
|
|
13
|
+
* 10 → 10 green ✓
|
|
14
|
+
* 10 → 12 red ✓ (worse)
|
|
15
|
+
* 10 → 8 RED ✗ (better — the defect)
|
|
16
|
+
* 10 → 5 green ✓ (under the threshold)
|
|
17
|
+
*
|
|
18
|
+
* Paying down the debt failed CI, and kept failing on every incremental step
|
|
19
|
+
* until the class dropped under the threshold entirely. A team that split four
|
|
20
|
+
* methods out of an 87-method service got a red build for its trouble. The
|
|
21
|
+
* external audit that motivated this recommends adopting these rules "behind a
|
|
22
|
+
* ratchet (accept today's god objects, block new regressions)" and records them
|
|
23
|
+
* at **zero uses** — the ratchet they were told to use did not work.
|
|
24
|
+
*
|
|
25
|
+
* ## Why identity alone cannot fix it
|
|
26
|
+
*
|
|
27
|
+
* Bug 0010 added `identity` for messages that state a derived population, and
|
|
28
|
+
* applying it naively here trades one failure for a worse one:
|
|
29
|
+
*
|
|
30
|
+
* | identity contains | improving to 8 | regressing to 12 |
|
|
31
|
+
* | ----------------- | -------------- | ---------------- |
|
|
32
|
+
* | the count | **red** ✗ | red ✓ |
|
|
33
|
+
* | no count | green ✓ | **green** ✗ |
|
|
34
|
+
*
|
|
35
|
+
* Dropping the count turns the baseline into a mute button. Identity answers
|
|
36
|
+
* "is this the same finding?", and a metric needs "is it **worse** than what we
|
|
37
|
+
* accepted?" — a comparison, not an equality. So this carries both: a stable
|
|
38
|
+
* identity that finds the entry, and `measured`, which the baseline stores and
|
|
39
|
+
* compares. See `Baseline.isKnown`.
|
|
40
|
+
*
|
|
41
|
+
* **Ten sites produce these, not the eight the bug enumerated.** That table was
|
|
42
|
+
* built by grepping the `has N <noun>` message shape, which misses the two
|
|
43
|
+
* complexity conditions — `has cyclomatic complexity N` puts the number last.
|
|
44
|
+
* Both were left on `createViolation` in the first cut of this fix while the
|
|
45
|
+
* docs already claimed complexity was ratcheted, so a reader would have removed
|
|
46
|
+
* their CI escape hatch for a gate that still fired on every improvement. Found
|
|
47
|
+
* by review; a mechanical enumeration by *shape* is not one by *behaviour*.
|
|
48
|
+
*/
|
|
49
|
+
export function metricViolation(node, options, context) {
|
|
50
|
+
const base = createViolation(node, options.message, context);
|
|
51
|
+
return {
|
|
52
|
+
...base,
|
|
53
|
+
// The qualified name reaches `element` too, not only `identity` — bug 0068's
|
|
54
|
+
// first consequence. `createViolation` derives it with `getElementName`,
|
|
55
|
+
// which resolves an unnamed node up to its nearest named ancestor, so a
|
|
56
|
+
// finding ABOUT an object-literal function was labelled with the ENCLOSING
|
|
57
|
+
// function's name while its own message named it correctly. `element` is
|
|
58
|
+
// what the terminal prints, what the JSON reports, and one of the three
|
|
59
|
+
// fields string-form `.excluding()` matches by exact membership
|
|
60
|
+
// (`execute-rule.ts`), so the disagreement also made an exclusion written
|
|
61
|
+
// against the printed name silently miss.
|
|
62
|
+
element: options.qualifiedName ?? base.element,
|
|
63
|
+
// File, element and metric — never the value. The value is the thing being
|
|
64
|
+
// ratcheted, so putting it here makes every change a new finding, which is
|
|
65
|
+
// the bug. Leaving the FILE out is the other half, and it was shipped once:
|
|
66
|
+
// two classes named `Big` in different files produced one identity, one
|
|
67
|
+
// hash, and `withBaseline`'s last-write-wins picked whichever ceiling came
|
|
68
|
+
// last — measured, a real 10 → 15 regression was silently accepted while
|
|
69
|
+
// the sibling sat at 20. That is bug 0028's shape recreated inside bug
|
|
70
|
+
// 0012's fix, and `ArchViolation.identity`'s own contract forbids it: "two
|
|
71
|
+
// distinct violations sharing one identity are one violation to the
|
|
72
|
+
// baseline, and accepting either accepts both."
|
|
73
|
+
//
|
|
74
|
+
// A path here is portable: `hashViolation` scrubs identity through
|
|
75
|
+
// `normalizeIdentityText(text, root)`, which is what that scrub is for.
|
|
76
|
+
identity: `${node.getSourceFile().getFilePath()}::${identityName(node, options.qualifiedName)}::${options.metric}`,
|
|
77
|
+
measured: options.measured,
|
|
78
|
+
// Defaults to the metric's own name: for `methods` or `parameters` the name
|
|
79
|
+
// IS the unit, and only a metric that can change what it counts under a
|
|
80
|
+
// stable name needs to say so explicitly.
|
|
81
|
+
measuredUnit: options.unit ?? options.metric,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* The name segment of a metric identity: the subject's own name, **prefixed by the
|
|
86
|
+
* name of whatever encloses it**, so that two subjects sharing a name in one file
|
|
87
|
+
* are still two identities.
|
|
88
|
+
*
|
|
89
|
+
* Measured, across every function shape — neither name alone is sufficient:
|
|
90
|
+
*
|
|
91
|
+
* | shape | own name | enclosing scope | identity segment |
|
|
92
|
+
* | ------------------------------------ | ------------------- | --------------- | ------------------------- |
|
|
93
|
+
* | two factories returning `{build}` | `build`, `build` | `makeBeta`, `makeGamma` | `makeBeta.build`, … |
|
|
94
|
+
* | an arrow inside a named function | `errorResponseBuilder` | `makeAlpha` | `makeAlpha.errorResponseBuilder` |
|
|
95
|
+
* | a top-level `function takesFive` | `takesFive` | none | `takesFive` — unchanged |
|
|
96
|
+
* | a class method via `functions()` | `Repo.save` | `Repo` | `Repo.save` — already carries it |
|
|
97
|
+
*
|
|
98
|
+
* Two mistakes are recorded here because both shipped and both were found by
|
|
99
|
+
* review rather than by reasoning:
|
|
100
|
+
*
|
|
101
|
+
* 1. **The own name alone** (bug 0068's first fix) moved the collision instead of
|
|
102
|
+
* closing it: `owningBindingName` deliberately declines to prefix a literal
|
|
103
|
+
* returned from a factory, so both `build`s are just `build`.
|
|
104
|
+
* 2. **`getElementName` is not a scope.** It returns the node's OWN name when the
|
|
105
|
+
* node has one and only walks ancestors otherwise — so for method shorthand
|
|
106
|
+
* (`{ build() {} }`, a `MethodDeclaration`) it returned `build`, the prefix was
|
|
107
|
+
* skipped, and the fix worked for the arrow spelling of the same code and not
|
|
108
|
+
* for this one. The scope now comes from `enclosingScopeName`, which always
|
|
109
|
+
* walks from the parent.
|
|
110
|
+
*
|
|
111
|
+
* There is deliberately **no `own === scope` short-circuit**: a nested function
|
|
112
|
+
* whose name equals its enclosing function's (`function save() { return { save:
|
|
113
|
+
* … } }`) is exactly the case that needs the prefix, and equality of strings
|
|
114
|
+
* cannot tell "the scope is me" from "the scope happens to share my name".
|
|
115
|
+
*
|
|
116
|
+
* Known limit, stated rather than papered over: a literal in a **call argument**
|
|
117
|
+
* at module level (`register({ handler: … })`) has no enclosing named
|
|
118
|
+
* declaration, so two of them in one file still share an identity. Nothing stable
|
|
119
|
+
* distinguishes them — that is bug 0067's territory ("there is no right name
|
|
120
|
+
* yet"), not this one's.
|
|
121
|
+
*/
|
|
122
|
+
function identityName(node, qualifiedName) {
|
|
123
|
+
const own = qualifiedName ?? getElementName(node);
|
|
124
|
+
const scope = enclosingScopeName(node);
|
|
125
|
+
if (scope === undefined)
|
|
126
|
+
return own;
|
|
127
|
+
// Already carries it — a class method's `Repo.save` under scope `Repo`.
|
|
128
|
+
if (own.startsWith(`${scope}.`) || own.endsWith(`.${scope}`))
|
|
129
|
+
return own;
|
|
130
|
+
return `${scope}.${own}`;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=metric-violation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metric-violation.js","sourceRoot":"","sources":["../../src/core/metric-violation.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAU,EACV,OA6BC,EACD,OAMC;IAED,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC5D,OAAO;QACL,GAAG,IAAI;QACP,6EAA6E;QAC7E,yEAAyE;QACzE,wEAAwE;QACxE,2EAA2E;QAC3E,yEAAyE;QACzE,wEAAwE;QACxE,gEAAgE;QAChE,0EAA0E;QAC1E,0CAA0C;QAC1C,OAAO,EAAE,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO;QAC9C,2EAA2E;QAC3E,2EAA2E;QAC3E,4EAA4E;QAC5E,wEAAwE;QACxE,2EAA2E;QAC3E,yEAAyE;QACzE,uEAAuE;QACvE,2EAA2E;QAC3E,oEAAoE;QACpE,gDAAgD;QAChD,EAAE;QACF,mEAAmE;QACnE,wEAAwE;QACxE,QAAQ,EAAE,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,OAAO,CAAC,MAAM,EAAE;QAClH,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,4EAA4E;QAC5E,wEAAwE;QACxE,0CAA0C;QAC1C,YAAY,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM;KAC7C,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,SAAS,YAAY,CAAC,IAAU,EAAE,aAAiC;IACjE,MAAM,GAAG,GAAG,aAAa,IAAI,cAAc,CAAC,IAAI,CAAC,CAAA;IACjD,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAA;IACtC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,GAAG,CAAA;IACnC,wEAAwE;IACxE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,KAAK,EAAE,CAAC;QAAE,OAAO,GAAG,CAAA;IACxE,OAAO,GAAG,KAAK,IAAI,GAAG,EAAE,CAAA;AAC1B,CAAC"}
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import type { SourceFile } from 'ts-morph';
|
|
2
|
+
/**
|
|
3
|
+
* One definition of "a module edge", for every condition that needs one.
|
|
4
|
+
*
|
|
5
|
+
* [ts-archunit Bug 0022](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0022-forward-import-conditions-are-blind-to-reexports-and-dynamic-imports.md):
|
|
6
|
+
* `src/conditions/dependency.ts` collected edges from `sf.getImportDeclarations()`
|
|
7
|
+
* at five sites — static `import` statements and nothing else — while the reverse
|
|
8
|
+
* graph indexed static imports, re-exports **and** dynamic imports. So
|
|
9
|
+
* `onlyBeImportedVia('…')` saw a re-export as an import and `notImportFrom('…')`
|
|
10
|
+
* did not, and `export { x } from './banned.js'` crossed every banned edge
|
|
11
|
+
* unflagged.
|
|
12
|
+
*
|
|
13
|
+
* `SourceFile.getImportStringLiterals()` returns one literal per module
|
|
14
|
+
* specifier across every edge-carrying form, from the binder's cached
|
|
15
|
+
* `compilerNode.imports` rather than a descendant walk. Measured over 20 forms;
|
|
16
|
+
* the table lives in plan 0071 §1 and the fixture that pins it is
|
|
17
|
+
* `tests/fixtures/module-edge-forms/`.
|
|
18
|
+
*
|
|
19
|
+
* **Two classification traps**, both of which would mark a *runtime* dependency
|
|
20
|
+
* as erased — and both are why `kind` is a five-member union rather than four:
|
|
21
|
+
*
|
|
22
|
+
* - `import x = require('s')` has parent `ExternalModuleReference`. A 4-way
|
|
23
|
+
* branch ending in `else → 'type-expression'` gives it `typeOnly: true`,
|
|
24
|
+
* exempt under `ignoreTypeImports`. Common in hand-written `.d.ts`.
|
|
25
|
+
* - `require('s')` in `.js` under `allowJs` has parent `CallExpression`, the same
|
|
26
|
+
* as `import('s')`. `getExpression().getKind() === ImportKeyword` is the only
|
|
27
|
+
* discriminator, as `reverse-dependency.ts` already knew.
|
|
28
|
+
*
|
|
29
|
+
* **Nothing here narrows the literal.** `getImportStringLiterals()` is declared
|
|
30
|
+
* `StringLiteral[]` and ``import(`./x.js`)`` yields a
|
|
31
|
+
* `NoSubstitutionTemplateLiteral`, for which `Node.isStringLiteral()` is
|
|
32
|
+
* **false**. ADR-005 bars the `as` that would re-narrow it, so an implementer
|
|
33
|
+
* narrowing defensively silently drops the edge and `tsc` says nothing.
|
|
34
|
+
* `getLiteralText()` typechecks and is correct for both.
|
|
35
|
+
*/
|
|
36
|
+
export type ModuleEdgeKind = 'import' | 'reexport' | 'dynamic' | 'type-expression' | 'require';
|
|
37
|
+
/** One module specifier leaving one file. */
|
|
38
|
+
export interface ModuleEdge {
|
|
39
|
+
readonly kind: ModuleEdgeKind;
|
|
40
|
+
/** The specifier as written. */
|
|
41
|
+
readonly specifier: string;
|
|
42
|
+
/** Resolved absolute path, when the compiler resolved it. */
|
|
43
|
+
readonly resolvedPath: string | undefined;
|
|
44
|
+
/**
|
|
45
|
+
* 1-based line of the **statement** carrying the edge.
|
|
46
|
+
*
|
|
47
|
+
* Equals `decl.getStartLineNumber()` for `kind === 'import'`, which
|
|
48
|
+
* `tests/core/module-edges-corpus.test.ts` asserts across the whole repo: 88
|
|
49
|
+
* of this repo's 1751 import declarations (5.0%) put the specifier on a
|
|
50
|
+
* different line from the keyword, so keying off the literal would move 5% of
|
|
51
|
+
* reported lines. Not a baseline concern — `hashViolation` never sees the line
|
|
52
|
+
* — but it drives the code frame and the GitHub annotation position.
|
|
53
|
+
*
|
|
54
|
+
* The same gap exists for every other kind, which is why the fixture carries a
|
|
55
|
+
* multi-line form of each: a multi-line `export { … } from` and a multi-line
|
|
56
|
+
* `import(…)` both move too, and a line taken from the literal passes every
|
|
57
|
+
* single-line test.
|
|
58
|
+
*/
|
|
59
|
+
readonly line: number;
|
|
60
|
+
/**
|
|
61
|
+
* The **bindings** crossing this edge are type-level. Per-kind; see below.
|
|
62
|
+
*
|
|
63
|
+
* This is the *coupling* question — "does this file reference that file's types" —
|
|
64
|
+
* and it is what `dependOn`, `notImportFrom`, `onlyImportFrom` and the module
|
|
65
|
+
* predicates ask. It is deliberately NOT the same question as
|
|
66
|
+
* {@link erasesModuleRequest}, and conflating them was
|
|
67
|
+
* [ts-archunit plan 0087](https://github.com/nielspeter/ts-archunit/blob/main/plans/completed/0087-an-inline-type-import-still-requests-the-module.md).
|
|
68
|
+
*/
|
|
69
|
+
readonly typeOnly: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* The whole statement disappears, so **no module request is emitted** and the
|
|
72
|
+
* target module is never evaluated.
|
|
73
|
+
*
|
|
74
|
+
* This is the *module-initialization* question — "will importing this file cause
|
|
75
|
+
* that file to run" — and it is what cycle detection must ask. A cycle is a
|
|
76
|
+
* deadlock in initialization order; a coupling is not.
|
|
77
|
+
*
|
|
78
|
+
* The two differ for exactly two spellings, and only under
|
|
79
|
+
* `verbatimModuleSyntax: true`. Measured through ts-morph's own emit, same source,
|
|
80
|
+
* both settings:
|
|
81
|
+
*
|
|
82
|
+
* | form | `vms: false` | `vms: true` |
|
|
83
|
+
* | ----------------------------- | ------------ | --------------------------- |
|
|
84
|
+
* | `import type { X } from 's'` | erased | erased |
|
|
85
|
+
* | `import { type X } from 's'` | erased | **`import {} from 's'`** |
|
|
86
|
+
* | `import { type X, y } from` | requests | requests |
|
|
87
|
+
* | `export type { X } from 's'` | erased | erased |
|
|
88
|
+
* | `export { type X } from 's'` | erased | **`export {} from 's'`** |
|
|
89
|
+
* | `export { type X, y } from` | requests | requests |
|
|
90
|
+
* | `export * from 's'` | requests | requests |
|
|
91
|
+
* | `export type * as N from 's'` | erased | erased |
|
|
92
|
+
*
|
|
93
|
+
* The specifiers vanish; the module request does not. So under that flag those two
|
|
94
|
+
* forms are eager edges that can close a cycle, and treating them as erased is a
|
|
95
|
+
* false negative — which is what `beFreeOfCycles` did until v0.49.0.
|
|
96
|
+
*
|
|
97
|
+
* `erasesModuleRequest` implies `typeOnly`: a statement cannot vanish while still
|
|
98
|
+
* binding a runtime value. `tests/conditions/verbatim-module-syntax.test.ts` asserts that
|
|
99
|
+
* invariant over every form rather than leaving it as a claim.
|
|
100
|
+
*/
|
|
101
|
+
readonly erasesModuleRequest: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Named bindings crossing the edge.
|
|
104
|
+
*
|
|
105
|
+
* **The name, not the local binding** — and which one differs per kind:
|
|
106
|
+
*
|
|
107
|
+
* - `reexport`: the **outward** name, `getAliasNode() ?? getName()`. For
|
|
108
|
+
* `export { INNER as OUTER } from 's'` this is `OUTER`, because that is the
|
|
109
|
+
* key the re-exporting module's runtime namespace carries, and the runtime
|
|
110
|
+
* independence guard compares against a runtime namespace. Under the
|
|
111
|
+
* local-name reading that guard fails on a *correct* implementation.
|
|
112
|
+
* - `import`: the **inward** name, `getName()`. For `import { c as d }` this is
|
|
113
|
+
* `c` — the name crossing the edge, not the local binding `d`.
|
|
114
|
+
*
|
|
115
|
+
* **Empty for `export *`**, and not because the names are unknowable:
|
|
116
|
+
* `sf.getExportSymbols()` flattens `export *` in a single call, and on a
|
|
117
|
+
* circular pair the compiler and the Node runtime independently agree.
|
|
118
|
+
* Nothing is recursive. It is empty for two other reasons:
|
|
119
|
+
*
|
|
120
|
+
* 1. it cannot separate an erased re-export from a runtime one — `export type
|
|
121
|
+
* { X } from` and `export { X } from` both come back with
|
|
122
|
+
* `SymbolFlags.Alias` and a single `ExportSpecifier`, indistinguishable
|
|
123
|
+
* without `getAliasedSymbol()` per name; and
|
|
124
|
+
* 2. it includes names with no runtime existence — a `declare module
|
|
125
|
+
* './star-src.js' { export const INJECTED: number }` augmentation anywhere
|
|
126
|
+
* in the project injects `INJECTED` into the star target's exports.
|
|
127
|
+
*
|
|
128
|
+
* (`symbol.getExports()` does **not** flatten; it hands back a synthetic
|
|
129
|
+
* `__export` member. The obvious call gives the unflattened view.)
|
|
130
|
+
*
|
|
131
|
+
* **`export * as NS from 's'` is not a star for this purpose**: it contributes
|
|
132
|
+
* exactly one name, `NS`, statically, with no recursion. `isNamespaceExport()`
|
|
133
|
+
* returns **true for both** star forms — measured — so `getNamespaceExport()`
|
|
134
|
+
* is the only discriminator.
|
|
135
|
+
*
|
|
136
|
+
* Also empty for `dynamic`, `require`, `type-expression`, and for a default or
|
|
137
|
+
* namespace `import` binding (`import D from 's'`, `import * as NS from 's'`),
|
|
138
|
+
* which cross an edge under a name the specifier list does not carry.
|
|
139
|
+
*/
|
|
140
|
+
readonly names: readonly string[];
|
|
141
|
+
/**
|
|
142
|
+
* How many edges of the same `kind` and `specifier` precede this one in the file,
|
|
143
|
+
* in source order. `0` for the first.
|
|
144
|
+
*
|
|
145
|
+
* It exists because {@link names} is **empty** wherever no name crosses the edge,
|
|
146
|
+
* and a finding's identity is built from `kind::specifier::names`. That is `dynamic`,
|
|
147
|
+
* `require` and `type-expression` — and also four ordinary `import`/`reexport`
|
|
148
|
+
* spellings: `import D from`, `import * as NS from`, a bare `import './x.js'`, and
|
|
149
|
+
* `export * from`. So two lazy imports of the same module from one file produced two
|
|
150
|
+
* findings and **one** baseline hash — measured 2/1, against a control of 2/2 for two
|
|
151
|
+
* named imports — which means one accepted entry silently pre-accepts the next one
|
|
152
|
+
* someone adds. Measured on `main`, the same 2/1 held for two default imports and for
|
|
153
|
+
* two bare side-effect imports, in **both** families. Bug 0028's shape, wherever a
|
|
154
|
+
* kind or a spelling had no discriminator
|
|
155
|
+
* ([ts-archunit bug 0059](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0059-slice-conditions-and-module-conditions-disagree-about-a-dependency.md)).
|
|
156
|
+
*
|
|
157
|
+
* **Source-order ordinal rather than the line**, deliberately: a line moves when
|
|
158
|
+
* anything above it is edited, and `identity` exists precisely to survive that.
|
|
159
|
+
* The ordinal only moves when an edge of the same kind to the same module is
|
|
160
|
+
* added or removed before it — which is a real change to what the file does.
|
|
161
|
+
*
|
|
162
|
+
* The residual caveat, and it is inherent to any positional tiebreaker. **A baseline entry
|
|
163
|
+
* accepts "an edge of this kind to this module at position n", not _this_ edge.** Measured
|
|
164
|
+
* end-to-end, v0.55.3 baselines replayed through this version:
|
|
165
|
+
*
|
|
166
|
+
* | edit to an accepted colliding pair | new reds reported |
|
|
167
|
+
* | --------------------------------------- | ----------------- |
|
|
168
|
+
* | add a third sibling | 1 — correct |
|
|
169
|
+
* | insert a sibling **above** the first | 1 — correct |
|
|
170
|
+
* | **delete the first, add a different one**| **0 — silent** |
|
|
171
|
+
*
|
|
172
|
+
* So the insertion case is safe and the equal-count swap is a fail-open: a dependency edge
|
|
173
|
+
* that did not exist when the baseline was written arrives accepted. This is strictly better
|
|
174
|
+
* than the pre-ordinal behaviour, where *any* number of added siblings was pre-accepted
|
|
175
|
+
* rather than only an equal-count swap — but it is a limitation, not a guarantee, and it is
|
|
176
|
+
* why {@link edgeDiscriminator} is a tiebreaker of last resort rather than an identity
|
|
177
|
+
* component. The durable fix is a `binding` field consulted before the ordinal, which would
|
|
178
|
+
* separate `import A` from `import C` outright; recorded as out-of-scope in
|
|
179
|
+
* [ts-archunit plan 0094](https://github.com/nielspeter/ts-archunit/blob/main/plans/0094-the-residual-findings-from-the-v0-56-0-review.md).
|
|
180
|
+
*
|
|
181
|
+
* Both collectors must agree on it, so both walk the literals in source order;
|
|
182
|
+
* `edgeStream` sorts for that reason and not for output tidiness.
|
|
183
|
+
*/
|
|
184
|
+
readonly ordinal: number;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Every module edge leaving each file, in one call (ADR-007 rule 2).
|
|
188
|
+
*
|
|
189
|
+
* **Cached since plan 0076**, per file, invalidated by `onModified`. The
|
|
190
|
+
* sentence this paragraph used to carry — *"No cache … if a consumer reports a
|
|
191
|
+
* multiple-slowdown, the fix is a cache of resolution, not of the walk"* — was
|
|
192
|
+
* half right: a consumer did report one, and the walk is indeed not the cost
|
|
193
|
+
* (1ms across five passes over 520 files). But resolution is not the cost
|
|
194
|
+
* either. Building the `ModuleEdge` is: 15ms resolution against ~32ms
|
|
195
|
+
* construction, of 48ms total. So the cache is of the built edges, and the
|
|
196
|
+
* forward commitment this docstring made — *"what it forecloses is batching a
|
|
197
|
+
* resolution cache later"* — is discharged rather than left standing.
|
|
198
|
+
*
|
|
199
|
+
*/
|
|
200
|
+
export declare function moduleEdges(files: readonly SourceFile[]): ReadonlyMap<string, readonly ModuleEdge[]>;
|
|
201
|
+
/**
|
|
202
|
+
* Every module edge leaving one file, in source order.
|
|
203
|
+
*
|
|
204
|
+
* Exported for the predicate sites, which are per-element by construction and
|
|
205
|
+
* would otherwise build a one-entry `Map` per file just to read it back out.
|
|
206
|
+
*/
|
|
207
|
+
export declare function edgesOf(sourceFile: SourceFile): readonly ModuleEdge[];
|
|
208
|
+
/**
|
|
209
|
+
* What tells two edges of the same kind, from the same file, to the same module apart.
|
|
210
|
+
*
|
|
211
|
+
* `names` when there are any; the source-order ordinal when there are not — and **`names` is
|
|
212
|
+
* empty for a SPELLING, not for a kind**, which is the distinction the whole of this comment
|
|
213
|
+
* turns on. `dynamic`, `require` and `type-expression` never carry names, and neither do four
|
|
214
|
+
* ordinary `import`/`reexport` spellings (`import D from`, `import * as NS from`, a bare
|
|
215
|
+
* `import './x.js'`, `export * from`). Any of them, twice to one module from one file,
|
|
216
|
+
* measured **2 findings, 1 hash** against a control of 2/2 for two named imports — so one
|
|
217
|
+
* accepted baseline entry silently pre-accepts the next one someone adds. Bug 0028's shape,
|
|
218
|
+
* in every spelling that reached this function without a discriminator; the lazy kinds are
|
|
219
|
+
* merely the ones
|
|
220
|
+
* [ts-archunit bug 0059](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0059-slice-conditions-and-module-conditions-disagree-about-a-dependency.md)
|
|
221
|
+
* made reportable, which is how the narrower reading got written here in the first place.
|
|
222
|
+
*
|
|
223
|
+
* The sort and the `,` are load-bearing and cheap to lose: `getNamedImports()` returns source
|
|
224
|
+
* order, so without the sort a cosmetic reorder of a named import list moves every multi-name
|
|
225
|
+
* entry in an adopter's baseline — an import-sorting lint autofix would do it. Without the
|
|
226
|
+
* separator, `['a','b']` and `['ab']` collide. Both are pinned by the multi-name row in
|
|
227
|
+
* `tests/conditions/identity-does-not-move.test.ts`, and by nothing else in the suite.
|
|
228
|
+
*
|
|
229
|
+
* **No existing baseline entry moves**, and that is what the `ordinal === 0` branch buys.
|
|
230
|
+
* The naive form — `#${ordinal}` whenever `names` is empty — moves far more than the three
|
|
231
|
+
* kinds it was written for, because `names` is empty for four ordinary `import`/`reexport`
|
|
232
|
+
* spellings too: `import D from`, `import * as NS from`, a bare `import './x.js'`, and
|
|
233
|
+
* `export * from` (the barrel). `export * as NS from` is **not** among them — it carries one
|
|
234
|
+
* statically-known name. That form shipped briefly in v0.56.0's development and was caught by
|
|
235
|
+
* review, measured against `main` through the public conditions: 4 of 7 spellings moved, in
|
|
236
|
+
* both families, while the CHANGELOG and ts-archunit's `docs/upgrading.md` promised none did.
|
|
237
|
+
*
|
|
238
|
+
* Emitting `''` for the first edge of each group reproduces exactly what the pre-ordinal
|
|
239
|
+
* formula produced (`[...names].sort().join(',')` over an empty list), so every
|
|
240
|
+
* single-occurrence finding keeps a byte-identical identity — measured across all seven
|
|
241
|
+
* spellings plus `dynamic` and `type-expression`, zero diff. The `#n` suffix appears only on
|
|
242
|
+
* the **second and later** edge of one kind to one module from one file, which is precisely
|
|
243
|
+
* the group that had two findings and one hash before, i.e. a baseline entry that was already
|
|
244
|
+
* wrong. So the fail-open closes and the migration is empty — the surviving entry still
|
|
245
|
+
* matches, and only the genuinely-new sibling is reported.
|
|
246
|
+
*
|
|
247
|
+
* Uniqueness still holds: within a group the sequence `''`, `#1`, `#2`, … is injective, and
|
|
248
|
+
* `''` is unreachable from the named branch because no import specifier is an empty
|
|
249
|
+
* identifier.
|
|
250
|
+
*
|
|
251
|
+
* The cost, stated so it is a decision rather than a discovery: the discriminator is no longer
|
|
252
|
+
* uniform, so `…::` no longer distinguishes "names-less, first" from "not computed". That is
|
|
253
|
+
* a readability loss traded for a migration nobody has to perform.
|
|
254
|
+
*/
|
|
255
|
+
export declare function edgeDiscriminator(edge: ModuleEdge): string;
|
|
256
|
+
/**
|
|
257
|
+
* How a finding refers to this kind of edge.
|
|
258
|
+
*
|
|
259
|
+
* **An exhaustive `switch`, not a `Record` lookup or a 4-way branch** (plan 0071
|
|
260
|
+
* §4). Measured on a build with `require` unfiltered and no `require` verb: a
|
|
261
|
+
* `Record` lookup emitted the literal string `undefined` into a message —
|
|
262
|
+
* `cjs-consumer.js undefined "…/target.ts" which matches forbidden […]` — and
|
|
263
|
+
* that text is hashed into a baseline. A missing verb must be a compile error;
|
|
264
|
+
* with an explicit `string` return and no fallthrough, adding a sixth
|
|
265
|
+
* `ModuleEdgeKind` breaks the build here.
|
|
266
|
+
*
|
|
267
|
+
* `require` gets a real verb even though no condition reports it (§3). The
|
|
268
|
+
* alternative — throwing, or returning a placeholder — makes a forgotten kind
|
|
269
|
+
* filter produce nonsense instead of a correct sentence, and a correct sentence
|
|
270
|
+
* costs one line.
|
|
271
|
+
*
|
|
272
|
+
* **`import` must stay byte-identical.** Every existing baselined dependency
|
|
273
|
+
* finding hashes its message, so changing this string for `import` silently
|
|
274
|
+
* invalidates them all; the new kinds get distinct verbs precisely so their
|
|
275
|
+
* findings are NOT absorbed by an existing `import` entry for the same module.
|
|
276
|
+
*/
|
|
277
|
+
export declare function edgeVerb(kind: ModuleEdgeKind): string;
|
|
278
|
+
/**
|
|
279
|
+
* How a finding describes a **runtime** edge of this kind, for
|
|
280
|
+
* `onlyHaveTypeImportsFrom`.
|
|
281
|
+
*
|
|
282
|
+
* Separate from {@link edgeVerb} because that condition's sentence needs a noun
|
|
283
|
+
* phrase ("has a value import from") rather than a verb, and because its remedy
|
|
284
|
+
* differs per kind in a way the verb does not capture — see
|
|
285
|
+
* {@link edgeTypeOnlyRemedy}.
|
|
286
|
+
*/
|
|
287
|
+
export declare function edgeValuePhrase(kind: ModuleEdgeKind): string;
|
|
288
|
+
/**
|
|
289
|
+
* The remedy for a runtime edge that should be type-only — **per kind, because
|
|
290
|
+
* the remedy differs and one of them has a consequence** (ADR-009 rule 2).
|
|
291
|
+
*
|
|
292
|
+
* `onlyHaveTypeImportsFrom`'s shipped preset says *"Use `import type { X }` so
|
|
293
|
+
* the dependency is erased"*. For an `import` that is complete and local. For a
|
|
294
|
+
* re-export it is not: `export type { X } from` erases the edge **and removes a
|
|
295
|
+
* runtime export consumers may be importing as a value**. The finding still
|
|
296
|
+
* stands — the runtime dependency is real — but a remedy that silently changes
|
|
297
|
+
* what the module publishes is a remedy the reader must be told about.
|
|
298
|
+
*
|
|
299
|
+
* `dynamic` is excluded from that condition entirely for the stronger version of
|
|
300
|
+
* the same reason: there is no remedy at all. You cannot erase an
|
|
301
|
+
* `await import(…)`.
|
|
302
|
+
*/
|
|
303
|
+
export declare function edgeTypeOnlyRemedy(edge: Pick<ModuleEdge, 'kind' | 'names'>): string;
|
|
304
|
+
/**
|
|
305
|
+
* The noun for this kind of edge, for `onlyHaveTypeImportsFrom`'s sentence tail.
|
|
306
|
+
*
|
|
307
|
+
* `edgeValuePhrase` was made per-kind and the tail was not, so a re-export read
|
|
308
|
+
* "has a runtime re-export of … which should be a type-only **import**". The two
|
|
309
|
+
* halves have to agree or the sentence contradicts itself.
|
|
310
|
+
*/
|
|
311
|
+
/**
|
|
312
|
+
* The kinds a **forward** dependency site reports on.
|
|
313
|
+
*
|
|
314
|
+
* One constant, because there were two: `DEPENDENCY_KINDS` in
|
|
315
|
+
* `conditions/dependency.ts` and `PREDICATE_KINDS` in `predicates/module.ts`, whose
|
|
316
|
+
* docstring said "the same set as the conditions … and it has to be" with prose as
|
|
317
|
+
* the only enforcement. `notImportFrom` is one identifier with two definitions
|
|
318
|
+
* chosen by chain position, so a predicate that disagreed with its own condition
|
|
319
|
+
* about what an import is would be this release's Problem statement in miniature.
|
|
320
|
+
*
|
|
321
|
+
* **Exhaustive, not an allowlist filter.** A sixth `ModuleEdgeKind` is a compile
|
|
322
|
+
* error here rather than a kind silently excluded everywhere — that fail-open is the
|
|
323
|
+
* same false green this release closes.
|
|
324
|
+
*
|
|
325
|
+
* `require` is `false`: the kind exists so a 4-way branch cannot mark a CJS runtime
|
|
326
|
+
* dependency as erased, not to enforce CJS. The **reverse** graph counts it, which
|
|
327
|
+
* is the opposite disposition and deliberately so — see `indexEdges`'s reasoning.
|
|
328
|
+
* `onlyHaveTypeImportsFrom` diverges further still (`TYPE_IMPORT_KINDS`), and that
|
|
329
|
+
* one divergence is intentional and documented at its own site.
|
|
330
|
+
*/
|
|
331
|
+
export declare const FORWARD_EDGE_KINDS: Record<ModuleEdgeKind, boolean>;
|
|
332
|
+
/**
|
|
333
|
+
* Every module edge leaving one file, **lazily and unsorted**.
|
|
334
|
+
*
|
|
335
|
+
* For a caller that only asks "is there any edge matching X". `edgesOf` builds and
|
|
336
|
+
* resolves the whole array before returning, so `edgesOf(sf).some(...)` pays a
|
|
337
|
+
* `getSymbol()` for every literal in the file even when the first one answers the
|
|
338
|
+
* question — on a 100-import file whose first import matches, 100 checker calls
|
|
339
|
+
* where the pre-0.28.0 code made 1.
|
|
340
|
+
*
|
|
341
|
+
* **Order is unspecified, and since plan 0076 it differs between a cold and a
|
|
342
|
+
* warm call.** Cold, edges arrive in walk order — the declaration forms first,
|
|
343
|
+
* because that is how ts-morph enumerates them. Warm, they arrive in the source
|
|
344
|
+
* order {@link edgesOf} sorted them into. Measured, on a file whose dynamic
|
|
345
|
+
* import precedes its declaration import:
|
|
346
|
+
*
|
|
347
|
+
* cold ./a.js, ./b.js
|
|
348
|
+
* warm ./b.js, ./a.js
|
|
349
|
+
*
|
|
350
|
+
* No verdict depends on it today: the only consumer is `dependOn`
|
|
351
|
+
* (`conditions/dependency.ts`), which is a `.some()` and stops at the first
|
|
352
|
+
* match. But "sometimes sorted" is a worse contract than "never sorted", so it
|
|
353
|
+
* is stated rather than left to be discovered. **Anything that reports a
|
|
354
|
+
* finding must use {@link edgesOf}**, whose source ordering is part of its
|
|
355
|
+
* contract — a reporting site fed from here would name a different edge
|
|
356
|
+
* depending on whether an unrelated rule warmed the file first, which is one
|
|
357
|
+
* finding with two identities.
|
|
358
|
+
*/
|
|
359
|
+
export declare function edgeStream(sourceFile: SourceFile): Generator<ModuleEdge>;
|
|
360
|
+
export declare function edgeTypeOnlyNoun(kind: ModuleEdgeKind): string;
|
|
361
|
+
//# sourceMappingURL=module-edges.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-edges.d.ts","sourceRoot":"","sources":["../../src/core/module-edges.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,UAAU,CAAA;AAKzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,iBAAiB,GAAG,SAAS,CAAA;AAE9F,6CAA6C;AAC7C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;IAC7B,gCAAgC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,6DAA6D;IAC7D,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;IACzC;;;;;;;;;;;;;;OAcG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;;;;;OAQG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;IAC1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAA;IACrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;IACH,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA0CG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,SAAS,UAAU,EAAE,GAC3B,WAAW,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC,CAM5C;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,UAAU,EAAE,CAYrE;AAqFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAY1D;AA0ND;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAErD;AA0BD;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAE5D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,MAAM,CA4BnF;AAED;;;;;;GAMG;AACH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,cAAc,EAAE,OAAO,CAM9D,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAiB,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC,CA8BzE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAW7D"}
|