@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
|
@@ -1,21 +1,142 @@
|
|
|
1
|
+
import type { RuleDescription } from '@nielspeter/eess';
|
|
1
2
|
import { SmellBuilder } from './smell-builder.js';
|
|
2
3
|
import type { ExpressionMatcher } from '../helpers/matchers.js';
|
|
3
|
-
import type { ArchViolation } from '
|
|
4
|
+
import type { ArchViolation } from '@nielspeter/eess';
|
|
4
5
|
import type { ArchProject } from '../core/project.js';
|
|
5
6
|
export declare class InconsistentSiblingsBuilder extends SmellBuilder {
|
|
6
7
|
private _pattern?;
|
|
7
8
|
constructor(project: ArchProject);
|
|
8
9
|
/** The pattern that most siblings should follow. */
|
|
9
10
|
forPattern(matcher: ExpressionMatcher): this;
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Sibling files in folders large enough to be compared — plan 0096, and the
|
|
13
|
+
* ONE method both readers call.
|
|
14
|
+
*
|
|
15
|
+
* The `>= 2` threshold lives HERE rather than in `detect()`'s loop, which is
|
|
16
|
+
* what makes this a shared derivation instead of two that agree by luck.
|
|
17
|
+
* Filtering before the caller's sort is safe: `groupFilesByFolder()` returns
|
|
18
|
+
* insertion order and `detect()` sorts by folder name, a total order, so
|
|
19
|
+
* removing entries cannot reorder the survivors.
|
|
20
|
+
*/
|
|
21
|
+
private selected;
|
|
22
|
+
/**
|
|
23
|
+
* Units this detector examined — plan 0096: sibling files in folders large
|
|
24
|
+
* enough to be compared.
|
|
25
|
+
*
|
|
26
|
+
* Counted in units ITERATED, never in pattern matches: a tripwire that
|
|
27
|
+
* examines every sibling and matches none has non-empty evidence, which is the
|
|
28
|
+
* 0.34.0 carve-out this must not break.
|
|
29
|
+
*/
|
|
30
|
+
examinedUnits(): number;
|
|
31
|
+
/**
|
|
32
|
+
* Pure recomputation of the corpus split — never accumulated on `this`. It is
|
|
33
|
+
* the SINGLE source the finding's message, the gate, and the diagnostic preview
|
|
34
|
+
* all read, so the preview and the finding cannot diverge, and calling it twice
|
|
35
|
+
* cannot double-count (each call recomputes). Mirrors `examinedUnits()`: one
|
|
36
|
+
* derivation, not an instance field.
|
|
37
|
+
*
|
|
38
|
+
* `canFireSoon` is true when any folder is at or within ONE edit of a majority —
|
|
39
|
+
* such a folder can fire, so it is not inert even though it does not fire today.
|
|
40
|
+
*
|
|
41
|
+
* The GUARD lives here, not at the emit site. A preview read through this
|
|
42
|
+
* accessor can then never report on a rule that can fire: a healthy control
|
|
43
|
+
* (majority present, `editsToMajority <= 1`) gets `canFireSoon = true`, and the
|
|
44
|
+
* hook below returns the empty string for it. The check-time emit and the
|
|
45
|
+
* diagnostic preview share this one predicate by construction.
|
|
46
|
+
*/
|
|
47
|
+
private inertAssessment;
|
|
14
48
|
/** Build violations for non-matching files in a folder where the majority matches. */
|
|
49
|
+
/**
|
|
50
|
+
* The two description strings travel together as one `describe` — adjacent
|
|
51
|
+
* positional strings are the transposition the parameter cap guards against,
|
|
52
|
+
* and these two read alike.
|
|
53
|
+
*/
|
|
15
54
|
private buildFolderViolations;
|
|
55
|
+
/**
|
|
56
|
+
* Whether this rule states an assertion at all — the assertion gate's question.
|
|
57
|
+
*
|
|
58
|
+
* True once a condition has been added.
|
|
59
|
+
*
|
|
60
|
+
* Overrides the `TerminalBuilder` default (`true`), whose JSDoc carries the
|
|
61
|
+
* contract and the reason this is public rather than protected.
|
|
62
|
+
*/
|
|
63
|
+
assertsSomething(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Named by id or by what the detector checks — the inherited version says
|
|
66
|
+
* 'unnamed'. Uses `describe()` rather than a call-site locator for the same
|
|
67
|
+
* reason as `SliceRuleBuilder`: `explain --format agent` reads this field.
|
|
68
|
+
*/
|
|
69
|
+
/**
|
|
70
|
+
* This detector counts sibling FILES, not function bodies — plan 0099.
|
|
71
|
+
*
|
|
72
|
+
* It inherited `SmellBuilder`'s noun while `examinedUnits()` sums
|
|
73
|
+
* `files.length`, so the message read "examined 0 function bodies" for a
|
|
74
|
+
* file-counting detector: the category error this plan exists to remove, in the
|
|
75
|
+
* family sitting directly under the override.
|
|
76
|
+
*/
|
|
77
|
+
protected examinedUnitNoun(): string;
|
|
78
|
+
/**
|
|
79
|
+
* A structural description of this rule without executing it — what `explain`
|
|
80
|
+
* prints and what the ADR/citation gates read.
|
|
81
|
+
*/
|
|
82
|
+
describeRule(): RuleDescription;
|
|
83
|
+
/**
|
|
84
|
+
* The remedy for this builder's assertion-less state, as one string.
|
|
85
|
+
*
|
|
86
|
+
* One channel, so `diagnose()`'s advice and the finding's own message cannot
|
|
87
|
+
* disagree. Overrides `TerminalBuilder`'s generic text with wording specific to
|
|
88
|
+
* what this builder is missing.
|
|
89
|
+
*/
|
|
90
|
+
assertionAdvice(): string;
|
|
91
|
+
/** The file-selection facts `sibling-files.ts` needs, stated as a value. */
|
|
92
|
+
private scope;
|
|
16
93
|
protected detect(): ArchViolation[];
|
|
94
|
+
/**
|
|
95
|
+
* The `DiagnosableRule` hook — public, no-arg, exactly the shape the
|
|
96
|
+
* interface requires. Recomputes `inertAssessment()` fresh, so `diagnose()`
|
|
97
|
+
* on a builder that never ran `check()` still gets truthful numbers.
|
|
98
|
+
*/
|
|
99
|
+
inertAdvice(): string;
|
|
100
|
+
/**
|
|
101
|
+
* THE single derivation for both surfaces, and the guard. Returns the empty
|
|
102
|
+
* string unless the rule is genuinely inert (`matching > 0 && !canFireSoon &&
|
|
103
|
+
* !declaresEmpty()`), so a healthy control (majority present, within one edit
|
|
104
|
+
* of one, or declared empty) gets `''` and diagnose() reports nothing for it.
|
|
105
|
+
* Both `inertAdvice()` above and `detect()`'s emit call this with an
|
|
106
|
+
* `Assessment` — the SAME guard and the SAME message either way, so the
|
|
107
|
+
* preview and the finding cannot diverge.
|
|
108
|
+
*
|
|
109
|
+
* `!this.declaresEmpty()` lives HERE, not only in `inertEmitEnabled()` (review:
|
|
110
|
+
* architect) — a declared-empty rule reports its expiry, not the inert finding,
|
|
111
|
+
* on BOTH surfaces, so `diagnose()`'s preview and `check()`'s eventual failure
|
|
112
|
+
* name the same cause for the same rule state. Before this fix the two clauses
|
|
113
|
+
* were split across two functions and only the emit path read the declaration,
|
|
114
|
+
* so a rule carrying `.expectEmpty()` could preview one cause via `diagnose()`
|
|
115
|
+
* and fail with a different one via `check()` — the exact drift this shared-
|
|
116
|
+
* derivation design exists to make impossible "by construction".
|
|
117
|
+
*/
|
|
118
|
+
private inertAdviceFor;
|
|
119
|
+
private inertViolation;
|
|
120
|
+
/**
|
|
121
|
+
* The pure version gate — nothing else. The `_expectEmpty` precedence
|
|
122
|
+
* (`!this.declaresEmpty()`) moved into `inertAdviceFor()` above, so it applies
|
|
123
|
+
* identically to `diagnose()`'s preview and to this emit path; this function's
|
|
124
|
+
* only job is "has the N+1 release happened yet."
|
|
125
|
+
*
|
|
126
|
+
* `INERT_FINDING_EMIT` is deliberately a bare, non-exported module `const` —
|
|
127
|
+
* not an env var, constructor option, or per-project override. The
|
|
128
|
+
* `bypassFilters: true` / unsuppressable design above depends on there being
|
|
129
|
+
* no configuration surface a future contributor could "helpfully" expose,
|
|
130
|
+
* which would undermine it silently.
|
|
131
|
+
*
|
|
132
|
+
* `protected`, not `private` — a test-only subclass overrides this to exercise
|
|
133
|
+
* the emit path (`inertViolation()`, `inertElement()`, the `detect()` branch
|
|
134
|
+
* that pushes them) before the N+1 flip ships, so that path is not shipped
|
|
135
|
+
* with zero test coverage merely because the real gate is off today (review:
|
|
136
|
+
* testing). See `tests/smells/inconsistent-siblings.test.ts`'s
|
|
137
|
+
* `EmittingSiblings` subclass.
|
|
138
|
+
*/
|
|
139
|
+
protected inertEmitEnabled(): boolean;
|
|
17
140
|
protected describe(): string;
|
|
18
|
-
/** Group source files by parent folder, applying all filters. */
|
|
19
|
-
private groupFilesByFolder;
|
|
20
141
|
}
|
|
21
142
|
//# sourceMappingURL=inconsistent-siblings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inconsistent-siblings.d.ts","sourceRoot":"","sources":["../../src/smells/inconsistent-siblings.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"inconsistent-siblings.d.ts","sourceRoot":"","sources":["../../src/smells/inconsistent-siblings.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAGvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAyBrD,qBAAa,2BAA4B,SAAQ,YAAY;IAC3D,OAAO,CAAC,QAAQ,CAAC,CAAmB;gBAExB,OAAO,EAAE,WAAW;IAIhC,oDAAoD;IACpD,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAM5C;;;;;;;;;OASG;IACH,OAAO,CAAC,QAAQ;IAMhB;;;;;;;OAOG;IACH,aAAa,IAAI,MAAM;IAIvB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,eAAe;IAuCvB,sFAAsF;IACtF;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IA8B7B;;;;;;;OAOG;IACM,gBAAgB,IAAI,OAAO;IAIpC;;;;OAIG;IACH;;;;;;;OAOG;cACgB,gBAAgB,IAAI,MAAM;IAI7C;;;OAGG;IACM,YAAY,IAAI,eAAe;IAOxC;;;;;;OAMG;IACM,eAAe,IAAI,MAAM;IAOlC,4EAA4E;IAC5E,OAAO,CAAC,KAAK;IAWb,SAAS,CAAC,MAAM,IAAI,aAAa,EAAE;IA8DnC;;;;OAIG;IACH,WAAW,IAAI,MAAM;IAMrB;;;;;;;;;;;;;;;;;OAiBG;IACH,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,cAAc;IA2BtB;;;;;;;;;;;;;;;;;;OAkBG;IACH,SAAS,CAAC,gBAAgB,IAAI,OAAO;IAIrC,SAAS,CAAC,QAAQ,IAAI,MAAM;CAI7B"}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { groupFilesByFolder, inertElement, inertMessage, partitionByPattern, } from './sibling-files.js';
|
|
2
|
+
import { selectionMemo } from '@nielspeter/eess/internal';
|
|
3
3
|
import { SmellBuilder } from './smell-builder.js';
|
|
4
|
-
import { collectFunctions } from '../models/arch-function.js';
|
|
5
|
-
import { searchFunctionBody } from '../helpers/body-traversal.js';
|
|
6
4
|
/** Majority threshold — flag when >= 60% of siblings match but a file doesn't. */
|
|
7
5
|
const MAJORITY_THRESHOLD = 0.6;
|
|
8
6
|
/** Test file patterns for ignoreTests(). */
|
|
9
|
-
const
|
|
7
|
+
const selectionOf = selectionMemo();
|
|
8
|
+
/**
|
|
9
|
+
* 0102: diagnostic-first. N ships false (diagnose previews, check passes); the
|
|
10
|
+
* flip release sets true (check fails). Not a warn-first migration — a
|
|
11
|
+
* warning is invisible in a test run (bug 0024) and trains suppression.
|
|
12
|
+
* The N+1 flip is tracked in plan 0105.
|
|
13
|
+
*/
|
|
14
|
+
const INERT_FINDING_EMIT = false;
|
|
10
15
|
export class InconsistentSiblingsBuilder extends SmellBuilder {
|
|
11
16
|
_pattern;
|
|
12
17
|
constructor(project) {
|
|
@@ -14,40 +19,98 @@ export class InconsistentSiblingsBuilder extends SmellBuilder {
|
|
|
14
19
|
}
|
|
15
20
|
/** The pattern that most siblings should follow. */
|
|
16
21
|
forPattern(matcher) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
22
|
+
const next = this.copy();
|
|
23
|
+
next._pattern = matcher;
|
|
24
|
+
return next;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Sibling files in folders large enough to be compared — plan 0096, and the
|
|
28
|
+
* ONE method both readers call.
|
|
29
|
+
*
|
|
30
|
+
* The `>= 2` threshold lives HERE rather than in `detect()`'s loop, which is
|
|
31
|
+
* what makes this a shared derivation instead of two that agree by luck.
|
|
32
|
+
* Filtering before the caller's sort is safe: `groupFilesByFolder()` returns
|
|
33
|
+
* insertion order and `detect()` sorts by folder name, a total order, so
|
|
34
|
+
* removing entries cannot reorder the survivors.
|
|
35
|
+
*/
|
|
36
|
+
selected() {
|
|
37
|
+
return selectionOf(this, () => [...groupFilesByFolder(this.scope()).entries()].filter(([, files]) => files.length >= 2));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Units this detector examined — plan 0096: sibling files in folders large
|
|
41
|
+
* enough to be compared.
|
|
42
|
+
*
|
|
43
|
+
* Counted in units ITERATED, never in pattern matches: a tripwire that
|
|
44
|
+
* examines every sibling and matches none has non-empty evidence, which is the
|
|
45
|
+
* 0.34.0 carve-out this must not break.
|
|
46
|
+
*/
|
|
47
|
+
examinedUnits() {
|
|
48
|
+
return this.selected().reduce((total, [, files]) => total + files.length, 0);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Pure recomputation of the corpus split — never accumulated on `this`. It is
|
|
52
|
+
* the SINGLE source the finding's message, the gate, and the diagnostic preview
|
|
53
|
+
* all read, so the preview and the finding cannot diverge, and calling it twice
|
|
54
|
+
* cannot double-count (each call recomputes). Mirrors `examinedUnits()`: one
|
|
55
|
+
* derivation, not an instance field.
|
|
56
|
+
*
|
|
57
|
+
* `canFireSoon` is true when any folder is at or within ONE edit of a majority —
|
|
58
|
+
* such a folder can fire, so it is not inert even though it does not fire today.
|
|
59
|
+
*
|
|
60
|
+
* The GUARD lives here, not at the emit site. A preview read through this
|
|
61
|
+
* accessor can then never report on a rule that can fire: a healthy control
|
|
62
|
+
* (majority present, `editsToMajority <= 1`) gets `canFireSoon = true`, and the
|
|
63
|
+
* hook below returns the empty string for it. The check-time emit and the
|
|
64
|
+
* diagnostic preview share this one predicate by construction.
|
|
65
|
+
*/
|
|
66
|
+
inertAssessment(pattern) {
|
|
67
|
+
let matching = 0;
|
|
68
|
+
let total = 0;
|
|
69
|
+
let canFireSoon = false;
|
|
70
|
+
const folders = [];
|
|
71
|
+
for (const [folder, files] of this.selected()) {
|
|
72
|
+
const { matching: m, nonMatching } = partitionByPattern(files, pattern, this._minLines);
|
|
73
|
+
const t = m.length + nonMatching.length;
|
|
74
|
+
// Unreachable today: selected() already filters to files.length >= 2
|
|
75
|
+
// and partitionByPattern drops nothing, so t always equals a folder's
|
|
76
|
+
// file count and is never 0 here. Kept as future-proofing against a
|
|
77
|
+
// change to selected(), not a live branch.
|
|
78
|
+
if (t === 0)
|
|
28
79
|
continue;
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
80
|
+
matching += m.length;
|
|
81
|
+
total += t;
|
|
82
|
+
folders.push({ folder, matching: m, nonMatching });
|
|
83
|
+
// A folder at or within one edit of a majority is a live tripwire. Latched
|
|
84
|
+
// regardless of nonMatching===0: a fully-conforming majority folder is one
|
|
85
|
+
// divergent file away from firing, so it must suppress the inert finding.
|
|
86
|
+
//
|
|
87
|
+
// KNOWN LIMIT, conservative direction only (review: architect): for t=2,
|
|
88
|
+
// m=1 this reads editsToMajority = ceil(1.2) - 1 = 1 <= 1 and latches —
|
|
89
|
+
// but the only available edit (adopting the second file) yields m=2,
|
|
90
|
+
// nonMatching=0, which still cannot fire; a THIRD file would be needed.
|
|
91
|
+
// A two-file folder with one match (e.g. an index.ts plus one impl) is
|
|
92
|
+
// an ordinary shape, so this latch is reachable in practice, not a
|
|
93
|
+
// corner case. Never a false POSITIVE (a rule that can genuinely fire
|
|
94
|
+
// soon is never reported inert) — only a false latch that keeps a
|
|
95
|
+
// genuinely-inert corpus silent, and it is OR'd across every folder in
|
|
96
|
+
// scope, so one such folder anywhere suppresses the whole rule's inert
|
|
97
|
+
// finding. Not fixed here: the arithmetic is a documented approximation
|
|
98
|
+
// of "close to firing", not a precise one, and narrowing it is a
|
|
99
|
+
// separate, non-urgent piece of work.
|
|
100
|
+
const editsToMajority = Math.ceil(MAJORITY_THRESHOLD * t) - m.length;
|
|
101
|
+
if (editsToMajority <= 1)
|
|
102
|
+
canFireSoon = true;
|
|
45
103
|
}
|
|
46
|
-
return { matching,
|
|
104
|
+
return { matching, total, canFireSoon, folders };
|
|
47
105
|
}
|
|
48
106
|
/** Build violations for non-matching files in a folder where the majority matches. */
|
|
49
|
-
|
|
50
|
-
|
|
107
|
+
/**
|
|
108
|
+
* The two description strings travel together as one `describe` — adjacent
|
|
109
|
+
* positional strings are the transposition the parameter cap guards against,
|
|
110
|
+
* and these two read alike.
|
|
111
|
+
*/
|
|
112
|
+
buildFolderViolations(folder, matching, nonMatching, describe) {
|
|
113
|
+
const { rule: ruleDescription, pattern: patternDesc } = describe;
|
|
51
114
|
const total = matching.length + nonMatching.length;
|
|
52
115
|
const violations = [];
|
|
53
116
|
for (const sf of nonMatching) {
|
|
@@ -58,78 +121,217 @@ export class InconsistentSiblingsBuilder extends SmellBuilder {
|
|
|
58
121
|
line: 1,
|
|
59
122
|
message: `${String(matching.length)} of ${String(total)} files in ${folder} use ${patternDesc}, ` +
|
|
60
123
|
`but ${sf.getBaseName()} does not`,
|
|
124
|
+
// The message states the population ("3 of 5"), which is a fact about
|
|
125
|
+
// the folder rather than about this file: adding one unrelated sibling
|
|
126
|
+
// rewrites it, and every already-accepted finding in the folder loses
|
|
127
|
+
// its identity. The finding itself is "this file, in this folder, does
|
|
128
|
+
// not follow this pattern" — that, and only that, is the identity.
|
|
129
|
+
identity: `inconsistent-sibling::${sf.getFilePath()}::${patternDesc}`,
|
|
61
130
|
because: this._reason,
|
|
62
131
|
});
|
|
63
132
|
}
|
|
64
133
|
return violations;
|
|
65
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Whether this rule states an assertion at all — the assertion gate's question.
|
|
137
|
+
*
|
|
138
|
+
* True once a condition has been added.
|
|
139
|
+
*
|
|
140
|
+
* Overrides the `TerminalBuilder` default (`true`), whose JSDoc carries the
|
|
141
|
+
* contract and the reason this is public rather than protected.
|
|
142
|
+
*/
|
|
143
|
+
assertsSomething() {
|
|
144
|
+
return this._pattern !== undefined;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Named by id or by what the detector checks — the inherited version says
|
|
148
|
+
* 'unnamed'. Uses `describe()` rather than a call-site locator for the same
|
|
149
|
+
* reason as `SliceRuleBuilder`: `explain --format agent` reads this field.
|
|
150
|
+
*/
|
|
151
|
+
/**
|
|
152
|
+
* This detector counts sibling FILES, not function bodies — plan 0099.
|
|
153
|
+
*
|
|
154
|
+
* It inherited `SmellBuilder`'s noun while `examinedUnits()` sums
|
|
155
|
+
* `files.length`, so the message read "examined 0 function bodies" for a
|
|
156
|
+
* file-counting detector: the category error this plan exists to remove, in the
|
|
157
|
+
* family sitting directly under the override.
|
|
158
|
+
*/
|
|
159
|
+
examinedUnitNoun() {
|
|
160
|
+
return 'sibling files';
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* A structural description of this rule without executing it — what `explain`
|
|
164
|
+
* prints and what the ADR/citation gates read.
|
|
165
|
+
*/
|
|
166
|
+
describeRule() {
|
|
167
|
+
return {
|
|
168
|
+
...super.describeRule(),
|
|
169
|
+
rule: this._metadata?.id ?? this.describe(),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* The remedy for this builder's assertion-less state, as one string.
|
|
174
|
+
*
|
|
175
|
+
* One channel, so `diagnose()`'s advice and the finding's own message cannot
|
|
176
|
+
* disagree. Overrides `TerminalBuilder`'s generic text with wording specific to
|
|
177
|
+
* what this builder is missing.
|
|
178
|
+
*/
|
|
179
|
+
assertionAdvice() {
|
|
180
|
+
return ('this detector has no pattern, so it detects nothing and can never fail. Add ' +
|
|
181
|
+
'.forPattern(...), or use smells.duplicateBodies() for patternless duplicate detection.');
|
|
182
|
+
}
|
|
183
|
+
/** The file-selection facts `sibling-files.ts` needs, stated as a value. */
|
|
184
|
+
scope() {
|
|
185
|
+
return {
|
|
186
|
+
project: this.project,
|
|
187
|
+
folders: this._folders,
|
|
188
|
+
ignorePaths: this._ignorePaths,
|
|
189
|
+
ignoreTests: this._ignoreTests,
|
|
190
|
+
minLines: this._minLines,
|
|
191
|
+
pattern: this._pattern,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
66
194
|
detect() {
|
|
67
|
-
|
|
195
|
+
// Unreachable at runtime as of 0.23.0: the assertion gate reports a
|
|
196
|
+
// patternless detector as a configuration finding before `detect()` is
|
|
197
|
+
// called (bug 0019), so `_pattern` is always set by the time we get here.
|
|
198
|
+
// The branch stays only because strict null checks need the narrowing —
|
|
199
|
+
// hence the local, which the rest of the method reads instead of the field.
|
|
200
|
+
// Do not treat it as the answer to "what happens with no pattern": the loud
|
|
201
|
+
// answer is the gate, and if this ever returns `[]` again the gate is gone.
|
|
202
|
+
const pattern = this._pattern;
|
|
203
|
+
if (!pattern)
|
|
68
204
|
return [];
|
|
69
|
-
const filesByFolder = this.groupFilesByFolder();
|
|
70
205
|
const ruleDescription = this.describe();
|
|
71
|
-
const patternDesc =
|
|
72
|
-
const folderEntries = [...filesByFolder.entries()];
|
|
73
|
-
if (this._groupByFolder) {
|
|
74
|
-
folderEntries.sort((a, b) => a[0].localeCompare(b[0]));
|
|
75
|
-
}
|
|
206
|
+
const patternDesc = pattern.description;
|
|
76
207
|
const violations = [];
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
208
|
+
// ONE assessment — the single partition walk. It returns the aggregate
|
|
209
|
+
// (matching/total/canFireSoon) AND the per-folder partitions; detect() uses
|
|
210
|
+
// both. Do NOT call partitionByPattern again below: the searchFunctionBody
|
|
211
|
+
// walk is the dominant cost and must run once per check().
|
|
212
|
+
const a = this.inertAssessment(pattern);
|
|
213
|
+
// Preserves groupByFolder()'s existing violation-ordering contract for
|
|
214
|
+
// THIS family (review: testing — an earlier version of this comment cited
|
|
215
|
+
// tests/integration/coverage-gaps.test.ts's "groupByFolder produces
|
|
216
|
+
// violations sorted by directory" row, which covers duplicateBodies and
|
|
217
|
+
// asserts only `.toThrow()`, not order, for either family; the real guard
|
|
218
|
+
// for inconsistentSiblings is
|
|
219
|
+
// "groupByFolder() sorts violations across folders" below). Sorting the
|
|
220
|
+
// returned folder array is O(k log k) on folder COUNT, not a second AST
|
|
221
|
+
// walk: inertAssessment()'s searchFunctionBody pass already ran once,
|
|
222
|
+
// above, and this sort touches only its already-computed output.
|
|
223
|
+
const folders = this._groupByFolder
|
|
224
|
+
? [...a.folders].sort((x, y) => x.folder.localeCompare(y.folder))
|
|
225
|
+
: a.folders;
|
|
226
|
+
for (const { folder, matching, nonMatching } of folders) {
|
|
81
227
|
const total = matching.length + nonMatching.length;
|
|
82
|
-
if (total === 0)
|
|
83
|
-
continue;
|
|
84
228
|
if (matching.length / total < MAJORITY_THRESHOLD)
|
|
85
229
|
continue;
|
|
86
230
|
if (nonMatching.length === 0)
|
|
87
231
|
continue;
|
|
88
|
-
violations.push(...this.buildFolderViolations({
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
nonMatching,
|
|
92
|
-
ruleDescription,
|
|
93
|
-
patternDesc,
|
|
232
|
+
violations.push(...this.buildFolderViolations(folder, matching, nonMatching, {
|
|
233
|
+
rule: ruleDescription,
|
|
234
|
+
pattern: patternDesc,
|
|
94
235
|
}));
|
|
95
236
|
}
|
|
237
|
+
// The adequacy floor, VERSION-GATED and SHARED-SOURCE. NOT a floor extension —
|
|
238
|
+
// the real floor fires at violations===0 && examined===0; this fires at
|
|
239
|
+
// violations===0 && examined>0 && no folder is within one edit of a majority.
|
|
240
|
+
// The guard lives in the shared advice function, not here: the emit and the
|
|
241
|
+
// diagnostic preview are the same derivation, so the preview can never report
|
|
242
|
+
// on a rule that can fire. detect() passes the assessment it ALREADY computed
|
|
243
|
+
// (no second partition walk); the empty-string return means "not inert".
|
|
244
|
+
const advice = this.inertAdviceFor(a);
|
|
245
|
+
if (violations.length === 0 && this.inertEmitEnabled() && advice !== '') {
|
|
246
|
+
return [this.inertViolation(advice), ...violations];
|
|
247
|
+
}
|
|
96
248
|
return violations;
|
|
97
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* The `DiagnosableRule` hook — public, no-arg, exactly the shape the
|
|
252
|
+
* interface requires. Recomputes `inertAssessment()` fresh, so `diagnose()`
|
|
253
|
+
* on a builder that never ran `check()` still gets truthful numbers.
|
|
254
|
+
*/
|
|
255
|
+
inertAdvice() {
|
|
256
|
+
const pattern = this._pattern;
|
|
257
|
+
if (!pattern)
|
|
258
|
+
return '';
|
|
259
|
+
return this.inertAdviceFor(this.inertAssessment(pattern));
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* THE single derivation for both surfaces, and the guard. Returns the empty
|
|
263
|
+
* string unless the rule is genuinely inert (`matching > 0 && !canFireSoon &&
|
|
264
|
+
* !declaresEmpty()`), so a healthy control (majority present, within one edit
|
|
265
|
+
* of one, or declared empty) gets `''` and diagnose() reports nothing for it.
|
|
266
|
+
* Both `inertAdvice()` above and `detect()`'s emit call this with an
|
|
267
|
+
* `Assessment` — the SAME guard and the SAME message either way, so the
|
|
268
|
+
* preview and the finding cannot diverge.
|
|
269
|
+
*
|
|
270
|
+
* `!this.declaresEmpty()` lives HERE, not only in `inertEmitEnabled()` (review:
|
|
271
|
+
* architect) — a declared-empty rule reports its expiry, not the inert finding,
|
|
272
|
+
* on BOTH surfaces, so `diagnose()`'s preview and `check()`'s eventual failure
|
|
273
|
+
* name the same cause for the same rule state. Before this fix the two clauses
|
|
274
|
+
* were split across two functions and only the emit path read the declaration,
|
|
275
|
+
* so a rule carrying `.expectEmpty()` could preview one cause via `diagnose()`
|
|
276
|
+
* and fail with a different one via `check()` — the exact drift this shared-
|
|
277
|
+
* derivation design exists to make impossible "by construction".
|
|
278
|
+
*/
|
|
279
|
+
inertAdviceFor(a) {
|
|
280
|
+
if (a.matching === 0 || a.canFireSoon || this.declaresEmpty())
|
|
281
|
+
return ''; // the GUARD lives here
|
|
282
|
+
return inertMessage(a, this._pattern?.description ?? 'unknown pattern');
|
|
283
|
+
}
|
|
284
|
+
inertViolation(advice) {
|
|
285
|
+
return {
|
|
286
|
+
rule: this.describe(),
|
|
287
|
+
ruleId: this._metadata?.id,
|
|
288
|
+
element: inertElement(this.scope()),
|
|
289
|
+
file: '',
|
|
290
|
+
line: 0,
|
|
291
|
+
message: advice,
|
|
292
|
+
// Its own remedy, never the author's (bug 0021): the message IS the remedy.
|
|
293
|
+
suggestion: advice,
|
|
294
|
+
because: this._reason,
|
|
295
|
+
// Adequacy finding: the rule enforces nothing, which is not a severity the
|
|
296
|
+
// author grades (ADR-009 rule 1). Config-level: no file to attribute, so it
|
|
297
|
+
// must survive diff/baseline or the guard re-greens under standard CI.
|
|
298
|
+
bypassFilters: true,
|
|
299
|
+
// No `identity` set, deliberately, NOT an oversight (review: architect
|
|
300
|
+
// flagged the gap; this is why it stays a gap): `bypassFilters: true`
|
|
301
|
+
// means baseline/diff never read one today, so setting one buys nothing
|
|
302
|
+
// yet — and `message` embeds the population count ("examined N... only
|
|
303
|
+
// M of them"), which ADR-009 rule 4 forbids putting in an identity (a
|
|
304
|
+
// count rots). If `bypassFilters` is ever relaxed for this family, an
|
|
305
|
+
// `identity` has to be added HERE, population-free, before that ships —
|
|
306
|
+
// this comment is the tripwire for that future change, not a promise
|
|
307
|
+
// the coupling is already handled.
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* The pure version gate — nothing else. The `_expectEmpty` precedence
|
|
312
|
+
* (`!this.declaresEmpty()`) moved into `inertAdviceFor()` above, so it applies
|
|
313
|
+
* identically to `diagnose()`'s preview and to this emit path; this function's
|
|
314
|
+
* only job is "has the N+1 release happened yet."
|
|
315
|
+
*
|
|
316
|
+
* `INERT_FINDING_EMIT` is deliberately a bare, non-exported module `const` —
|
|
317
|
+
* not an env var, constructor option, or per-project override. The
|
|
318
|
+
* `bypassFilters: true` / unsuppressable design above depends on there being
|
|
319
|
+
* no configuration surface a future contributor could "helpfully" expose,
|
|
320
|
+
* which would undermine it silently.
|
|
321
|
+
*
|
|
322
|
+
* `protected`, not `private` — a test-only subclass overrides this to exercise
|
|
323
|
+
* the emit path (`inertViolation()`, `inertElement()`, the `detect()` branch
|
|
324
|
+
* that pushes them) before the N+1 flip ships, so that path is not shipped
|
|
325
|
+
* with zero test coverage merely because the real gate is off today (review:
|
|
326
|
+
* testing). See `tests/smells/inconsistent-siblings.test.ts`'s
|
|
327
|
+
* `EmittingSiblings` subclass.
|
|
328
|
+
*/
|
|
329
|
+
inertEmitEnabled() {
|
|
330
|
+
return INERT_FINDING_EMIT;
|
|
331
|
+
}
|
|
98
332
|
describe() {
|
|
99
333
|
const pattern = this._pattern?.description ?? 'unknown pattern';
|
|
100
334
|
return `Sibling files should consistently use ${pattern}`;
|
|
101
335
|
}
|
|
102
|
-
/** Group source files by parent folder, applying all filters. */
|
|
103
|
-
groupFilesByFolder() {
|
|
104
|
-
const sourceFiles = this.project.getSourceFiles();
|
|
105
|
-
const folderMatchers = this._folders.map((g) => picomatch(g));
|
|
106
|
-
const ignoreMatchers = this._ignorePaths.map((g) => picomatch(g));
|
|
107
|
-
const testMatchers = this._ignoreTests ? TEST_PATTERNS.map((g) => picomatch(g)) : [];
|
|
108
|
-
const groups = new Map();
|
|
109
|
-
for (const sf of sourceFiles) {
|
|
110
|
-
const filePath = sf.getFilePath();
|
|
111
|
-
// Folder filter: if folders specified, file must match at least one
|
|
112
|
-
if (folderMatchers.length > 0 && !folderMatchers.some((m) => m(filePath))) {
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
// Ignore paths filter
|
|
116
|
-
if (ignoreMatchers.some((m) => m(filePath))) {
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
// Test file filter
|
|
120
|
-
if (testMatchers.some((m) => m(filePath))) {
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
const folder = path.dirname(filePath);
|
|
124
|
-
const existing = groups.get(folder);
|
|
125
|
-
if (existing) {
|
|
126
|
-
existing.push(sf);
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
groups.set(folder, [sf]);
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return groups;
|
|
133
|
-
}
|
|
134
336
|
}
|
|
135
337
|
//# sourceMappingURL=inconsistent-siblings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inconsistent-siblings.js","sourceRoot":"","sources":["../../src/smells/inconsistent-siblings.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"inconsistent-siblings.js","sourceRoot":"","sources":["../../src/smells/inconsistent-siblings.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,kBAAkB,GACnB,MAAM,oBAAoB,CAAA;AAI3B,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAKjD,kFAAkF;AAClF,MAAM,kBAAkB,GAAG,GAAG,CAAA;AAE9B,4CAA4C;AAE5C,MAAM,WAAW,GAAG,aAAa,EAA0B,CAAA;AAE3D;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,KAAK,CAAA;AAUhC,MAAM,OAAO,2BAA4B,SAAQ,YAAY;IACnD,QAAQ,CAAoB;IAEpC,YAAY,OAAoB;QAC9B,KAAK,CAAC,OAAO,CAAC,CAAA;IAChB,CAAC;IAED,oDAAoD;IACpD,UAAU,CAAC,OAA0B;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QACxB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;QACvB,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;;;;;;;;OASG;IACK,QAAQ;QACd,OAAO,WAAW,CAAC,IAAI,EAAE,GAAG,EAAE,CAC5B,CAAC,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CACzF,CAAA;IACH,CAAC;IAED;;;;;;;OAOG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;IAC9E,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACK,eAAe,CAAC,OAA0B;QAChD,IAAI,QAAQ,GAAG,CAAC,CAAA;QAChB,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,IAAI,WAAW,GAAG,KAAK,CAAA;QACvB,MAAM,OAAO,GAA0B,EAAE,CAAA;QACzC,KAAK,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC9C,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,GAAG,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;YACvF,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAA;YACvC,qEAAqE;YACrE,sEAAsE;YACtE,oEAAoE;YACpE,2CAA2C;YAC3C,IAAI,CAAC,KAAK,CAAC;gBAAE,SAAQ;YACrB,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAA;YACpB,KAAK,IAAI,CAAC,CAAA;YACV,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,CAAA;YAClD,2EAA2E;YAC3E,2EAA2E;YAC3E,0EAA0E;YAC1E,EAAE;YACF,yEAAyE;YACzE,wEAAwE;YACxE,qEAAqE;YACrE,wEAAwE;YACxE,uEAAuE;YACvE,mEAAmE;YACnE,sEAAsE;YACtE,kEAAkE;YAClE,uEAAuE;YACvE,uEAAuE;YACvE,wEAAwE;YACxE,iEAAiE;YACjE,sCAAsC;YACtC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAA;YACpE,IAAI,eAAe,IAAI,CAAC;gBAAE,WAAW,GAAG,IAAI,CAAA;QAC9C,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,CAAA;IAClD,CAAC;IAED,sFAAsF;IACtF;;;;OAIG;IACK,qBAAqB,CAC3B,MAAc,EACd,QAAsB,EACtB,WAAyB,EACzB,QAA2C;QAE3C,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAA;QAChE,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAA;QAClD,MAAM,UAAU,GAAoB,EAAE,CAAA;QACtC,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;YAC7B,UAAU,CAAC,IAAI,CAAC;gBACd,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,EAAE,CAAC,WAAW,EAAE;gBACzB,IAAI,EAAE,EAAE,CAAC,WAAW,EAAE;gBACtB,IAAI,EAAE,CAAC;gBACP,OAAO,EACL,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,KAAK,CAAC,aAAa,MAAM,QAAQ,WAAW,IAAI;oBACxF,OAAO,EAAE,CAAC,WAAW,EAAE,WAAW;gBACpC,sEAAsE;gBACtE,uEAAuE;gBACvE,sEAAsE;gBACtE,uEAAuE;gBACvE,mEAAmE;gBACnE,QAAQ,EAAE,yBAAyB,EAAE,CAAC,WAAW,EAAE,KAAK,WAAW,EAAE;gBACrE,OAAO,EAAE,IAAI,CAAC,OAAO;aACtB,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;IAED;;;;;;;OAOG;IACM,gBAAgB;QACvB,OAAO,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAA;IACpC,CAAC;IAED;;;;OAIG;IACH;;;;;;;OAOG;IACgB,gBAAgB;QACjC,OAAO,eAAe,CAAA;IACxB,CAAC;IAED;;;OAGG;IACM,YAAY;QACnB,OAAO;YACL,GAAG,KAAK,CAAC,YAAY,EAAE;YACvB,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE;SAC5C,CAAA;IACH,CAAC;IAED;;;;;;OAMG;IACM,eAAe;QACtB,OAAO,CACL,8EAA8E;YAC9E,wFAAwF,CACzF,CAAA;IACH,CAAC;IAED,4EAA4E;IACpE,KAAK;QACX,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,OAAO,EAAE,IAAI,CAAC,QAAQ;YACtB,WAAW,EAAE,IAAI,CAAC,YAAY;YAC9B,WAAW,EAAE,IAAI,CAAC,YAAY;YAC9B,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,OAAO,EAAE,IAAI,CAAC,QAAQ;SACvB,CAAA;IACH,CAAC;IAES,MAAM;QACd,oEAAoE;QACpE,uEAAuE;QACvE,0EAA0E;QAC1E,wEAAwE;QACxE,4EAA4E;QAC5E,4EAA4E;QAC5E,4EAA4E;QAC5E,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC7B,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAA;QAEvB,MAAM,eAAe,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;QACvC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAA;QACvC,MAAM,UAAU,GAAoB,EAAE,CAAA;QAEtC,uEAAuE;QACvE,4EAA4E;QAC5E,2EAA2E;QAC3E,2DAA2D;QAC3D,MAAM,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;QAEvC,uEAAuE;QACvE,0EAA0E;QAC1E,oEAAoE;QACpE,wEAAwE;QACxE,0EAA0E;QAC1E,8BAA8B;QAC9B,wEAAwE;QACxE,wEAAwE;QACxE,sEAAsE;QACtE,iEAAiE;QACjE,MAAM,OAAO,GAAG,IAAI,CAAC,cAAc;YACjC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YACjE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;QAEb,KAAK,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,OAAO,EAAE,CAAC;YACxD,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,CAAA;YAClD,IAAI,QAAQ,CAAC,MAAM,GAAG,KAAK,GAAG,kBAAkB;gBAAE,SAAQ;YAC1D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAQ;YAEtC,UAAU,CAAC,IAAI,CACb,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE;gBAC3D,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,WAAW;aACrB,CAAC,CACH,CAAA;QACH,CAAC;QAED,+EAA+E;QAC/E,wEAAwE;QACxE,8EAA8E;QAC9E,4EAA4E;QAC5E,8EAA8E;QAC9E,8EAA8E;QAC9E,yEAAyE;QACzE,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAA;QACrC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,gBAAgB,EAAE,IAAI,MAAM,KAAK,EAAE,EAAE,CAAC;YACxE,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,GAAG,UAAU,CAAC,CAAA;QACrD,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;IAED;;;;OAIG;IACH,WAAW;QACT,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC7B,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,CAAA;QACvB,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAA;IAC3D,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACK,cAAc,CAAC,CAAa;QAClC,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,EAAE;YAAE,OAAO,EAAE,CAAA,CAAC,uBAAuB;QAChG,OAAO,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,IAAI,iBAAiB,CAAC,CAAA;IACzE,CAAC;IAEO,cAAc,CAAC,MAAc;QACnC,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE;YACrB,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE;YAC1B,OAAO,EAAE,YAAY,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YACnC,IAAI,EAAE,EAAE;YACR,IAAI,EAAE,CAAC;YACP,OAAO,EAAE,MAAM;YACf,4EAA4E;YAC5E,UAAU,EAAE,MAAM;YAClB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,2EAA2E;YAC3E,4EAA4E;YAC5E,uEAAuE;YACvE,aAAa,EAAE,IAAI;YACnB,uEAAuE;YACvE,sEAAsE;YACtE,wEAAwE;YACxE,uEAAuE;YACvE,sEAAsE;YACtE,sEAAsE;YACtE,wEAAwE;YACxE,qEAAqE;YACrE,mCAAmC;SACpC,CAAA;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACO,gBAAgB;QACxB,OAAO,kBAAkB,CAAA;IAC3B,CAAC;IAES,QAAQ;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,WAAW,IAAI,iBAAiB,CAAA;QAC/D,OAAO,yCAAyC,OAAO,EAAE,CAAA;IAC3D,CAAC;CACF"}
|