@nielspeter/eess-ts 0.2.0 → 0.4.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 +87 -34
- 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 +73 -31
- 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 +134 -30
- 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 +393 -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 +181 -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 +173 -26
- 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 +12 -3
- 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 +242 -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 +105 -29
- 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 +3 -2
- package/dist/cli/commands/baseline.d.ts.map +1 -1
- package/dist/cli/commands/baseline.js +68 -6
- 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 +241 -45
- 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 +60 -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 +98 -33
- 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 +21 -29
- package/dist/cli/load-rules.js.map +1 -1
- package/dist/cli/resolve-config.d.ts.map +1 -1
- package/dist/cli/resolve-config.js +24 -14
- 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 +293 -0
- package/dist/cli/rule-file-findings.js.map +1 -0
- package/dist/cli/watch.d.ts +20 -7
- package/dist/cli/watch.d.ts.map +1 -1
- package/dist/cli/watch.js +39 -14
- 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 +38 -17
- 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 +10 -0
- 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 +17 -4
- 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 +109 -92
- 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 +96 -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 +56 -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 +119 -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 +382 -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 +54 -0
- package/dist/core/exclusion-comments.d.ts.map +1 -0
- package/dist/core/exclusion-comments.js +310 -0
- package/dist/core/exclusion-comments.js.map +1 -0
- package/dist/core/execute-rule.d.ts +150 -0
- package/dist/core/execute-rule.d.ts.map +1 -0
- package/dist/core/execute-rule.js +580 -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/line-index.d.ts +3 -0
- package/dist/core/line-index.d.ts.map +1 -0
- package/dist/core/line-index.js +229 -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 +592 -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 +214 -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 +54 -0
- package/dist/core/path-universe.d.ts.map +1 -0
- package/dist/core/path-universe.js +65 -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 +24 -0
- package/dist/core/project.js.map +1 -1
- package/dist/core/rule-builder.d.ts +282 -0
- package/dist/core/rule-builder.d.ts.map +1 -0
- package/dist/core/rule-builder.js +445 -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 +126 -0
- package/dist/core/rule-declaration.js.map +1 -0
- package/dist/core/terminal-builder.d.ts +625 -0
- package/dist/core/terminal-builder.d.ts.map +1 -0
- package/dist/core/terminal-builder.js +787 -0
- package/dist/core/terminal-builder.js.map +1 -0
- package/dist/core/terminal-execution.d.ts +23 -0
- package/dist/core/terminal-execution.d.ts.map +1 -0
- package/dist/core/terminal-execution.js +71 -0
- package/dist/core/terminal-execution.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/index.js +1 -1
- package/dist/graphql/index.js.map +1 -1
- package/dist/graphql/resolver-rule-builder.d.ts +98 -23
- package/dist/graphql/resolver-rule-builder.d.ts.map +1 -1
- package/dist/graphql/resolver-rule-builder.js +151 -21
- 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 +81 -12
- package/dist/graphql/schema-loader.js.map +1 -1
- package/dist/graphql/schema-rule-builder.d.ts +57 -20
- package/dist/graphql/schema-rule-builder.d.ts.map +1 -1
- package/dist/graphql/schema-rule-builder.js +101 -25
- 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 +19 -0
- package/dist/helpers/baseline-generator.d.ts.map +1 -0
- package/dist/helpers/baseline-generator.js +18 -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 +122 -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 +48 -47
- 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 +44 -0
- package/dist/helpers/diff-aware.d.ts.map +1 -0
- package/dist/helpers/diff-aware.js +84 -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 +114 -20
- 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 +56 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +57 -13
- 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 +28 -6
- package/dist/models/arch-function.d.ts.map +1 -1
- package/dist/models/arch-function.js +106 -3
- package/dist/models/arch-function.js.map +1 -1
- package/dist/models/arch-jsx-element.js +2 -2
- 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/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 +22 -15
- package/dist/presets/agent-guardrails.d.ts.map +1 -1
- package/dist/presets/agent-guardrails.js +124 -19
- package/dist/presets/agent-guardrails.js.map +1 -1
- package/dist/presets/boundaries.d.ts +45 -2
- 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 +22 -2
- 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 +7 -5
- package/dist/presets/index.d.ts.map +1 -1
- package/dist/presets/index.js +9 -3
- package/dist/presets/index.js.map +1 -1
- package/dist/presets/layered.d.ts +46 -2
- 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 +80 -9
- 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 +270 -2
- package/dist/presets/shared.d.ts.map +1 -1
- package/dist/presets/shared.js +338 -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 +33 -6
- 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 +39 -9
- package/dist/rules/metrics.js.map +1 -1
- package/dist/smells/duplicate-bodies.d.ts +58 -5
- package/dist/smells/duplicate-bodies.d.ts.map +1 -1
- package/dist/smells/duplicate-bodies.js +137 -56
- package/dist/smells/duplicate-bodies.js.map +1 -1
- package/dist/smells/fingerprint.d.ts +8 -1
- package/dist/smells/fingerprint.d.ts.map +1 -1
- package/dist/smells/fingerprint.js +21 -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 +27 -0
- package/dist/smells/similar-pairs.d.ts.map +1 -0
- package/dist/smells/similar-pairs.js +52 -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 +111 -14
- package/dist/smells/smell-builder.js.map +1 -1
- 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 +64 -16
- package/dist/tsconfig/tsconfig-builder.js.map +1 -1
- package/package.json +3 -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,178 @@
|
|
|
1
|
+
import type { ArchViolation } from '@nielspeter/eess';
|
|
2
|
+
/**
|
|
3
|
+
* Attribute findings that have no source location of their own to the rule file
|
|
4
|
+
* they came from.
|
|
5
|
+
*
|
|
6
|
+
* [ts-archunit Bug 0026](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0026-a-location-less-finding-does-not-say-which-rule-file-it-came-from.md):
|
|
7
|
+
* a configuration finding carries `file: ''` because it reports a fault in the
|
|
8
|
+
* rule rather than in the code, so two identical vacuous rules in two rule files
|
|
9
|
+
* rendered as two identical paragraphs with nothing saying which to open. In a
|
|
10
|
+
* test the frame comes free from vitest; in the CLI — the golden-path default —
|
|
11
|
+
* nothing supplied it, even though this loop knows the file and was discarding it.
|
|
12
|
+
*
|
|
13
|
+
* `line: 1`, following `tsconfig()`'s precedent for a fault that belongs to a
|
|
14
|
+
* file rather than to a position in it (`docs/config-rules.md` documents that
|
|
15
|
+
* choice). The builders cannot know the line: a rule with no glob has no
|
|
16
|
+
* position anywhere, and the assertion-gate findings are exactly the rules that
|
|
17
|
+
* may have none. Not `line: 0` — `::error file=x,line=0` is not a valid GitHub
|
|
18
|
+
* annotation and gets dropped or misplaced.
|
|
19
|
+
*
|
|
20
|
+
* **Safe against a `eess-exclude` comment only because these findings carry
|
|
21
|
+
* `bypassFilters`.** `execute-rule.ts` filters comment exclusions with
|
|
22
|
+
* `v.bypassFilters === true || !isExcludedByComment(...)`, and that first clause
|
|
23
|
+
* is what stops a real path here from making the finding suppressible by a
|
|
24
|
+
* comment in the rule file. It was written for this exact temptation, and until
|
|
25
|
+
* this change nothing tested it, because no such finding had a readable path.
|
|
26
|
+
* `tests/helpers/exclusion-comments.test.ts` now pins it.
|
|
27
|
+
*/
|
|
28
|
+
export declare function attributeToRuleFile(violations: readonly ArchViolation[], file: string): ArchViolation[];
|
|
29
|
+
/**
|
|
30
|
+
* A rule file, or one rule in it, that could not be evaluated at all.
|
|
31
|
+
*
|
|
32
|
+
* [ts-archunit Bug 0025](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0025-a-non-archruleerror-from-one-rule-file-drops-every-other-finding.md):
|
|
33
|
+
* `runCheck` and `runBaseline` caught `ArchRuleError` and rethrew everything
|
|
34
|
+
* else, so any other error escaped the per-file loop and terminated the process
|
|
35
|
+
* — no report written, no exit code returned, and every finding already
|
|
36
|
+
* collected discarded. Measured: one malformed `crossProject()` in one file
|
|
37
|
+
* silenced a second file's four real violations, and printed a raw Node stack
|
|
38
|
+
* trace with `node_modules` paths in their place.
|
|
39
|
+
*
|
|
40
|
+
* Reported as a **configuration finding** (`bypassFilters`): a rule that could
|
|
41
|
+
* not run enforced nothing, which is not a violation of the rule and is not
|
|
42
|
+
* something to accept into a baseline. Same reasoning as the assertion gate,
|
|
43
|
+
* and it inherits the same treatment — `error` severity whatever the rule
|
|
44
|
+
* asked for, refused by `.excluding()`, skipped by diff and baseline.
|
|
45
|
+
*
|
|
46
|
+
* `line: 1` with the rule file as `file`, following `tsconfig()`'s precedent for
|
|
47
|
+
* a fault that belongs to a file rather than to a position in it. Not `line: 0`:
|
|
48
|
+
* `::error file=x,line=0` is not a valid GitHub annotation and gets dropped or
|
|
49
|
+
* misplaced (the v0.22.0 defect), and only a `file` of `''` takes the run-level
|
|
50
|
+
* branch that avoids it.
|
|
51
|
+
*/
|
|
52
|
+
export declare function ruleFileFailure(file: string, error: unknown, ruleFiles: number): ArchViolation;
|
|
53
|
+
/**
|
|
54
|
+
* What to collect when evaluating a rule file, or one rule in it, threw.
|
|
55
|
+
*
|
|
56
|
+
* An `ArchRuleError` already carries findings — those ARE the report, and this
|
|
57
|
+
* is the pre-existing path for a rule file that self-executes a failing
|
|
58
|
+
* `.check()` at import. Anything else becomes one configuration finding naming
|
|
59
|
+
* the file. Never a rethrow: that discarded every finding already collected in
|
|
60
|
+
* the run, including other files' (bug 0025).
|
|
61
|
+
*
|
|
62
|
+
* One definition, imported by both `runCheck` and `runBaseline`. They had a copy
|
|
63
|
+
* each for the ArchRuleError half and the two had already diverged in what they
|
|
64
|
+
* did with everything else.
|
|
65
|
+
*/
|
|
66
|
+
export declare function failureOrViolations(file: string, error: unknown, ruleFiles: number): ArchViolation[];
|
|
67
|
+
/**
|
|
68
|
+
* A rule file stopped evaluating partway, so the rules after that point never ran.
|
|
69
|
+
*
|
|
70
|
+
* [ts-archunit Bug 0029](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0029-a-throwing-warn-truncates-the-rest-of-the-rule-file.md),
|
|
71
|
+
* and the half [ts-archunit plan 0069](https://github.com/nielspeter/ts-archunit/blob/main/plans/completed/0069-no-rule-may-certify-nothing.md)'s R3a
|
|
72
|
+
* specified and did not build: *"R3a states the semantics, and the CLI **reports the
|
|
73
|
+
* truncation rather than absorbing it**."* The semantics shipped in v0.23.0; this is
|
|
74
|
+
* the reporting.
|
|
75
|
+
*
|
|
76
|
+
* In a **self-executing** rule file — the shape `init` scaffolds and `docs/cli.md`
|
|
77
|
+
* documents — every rule calls its own terminal at module scope. A throw there aborts
|
|
78
|
+
* the module, so every rule declared after it is never evaluated. The CLI then folds
|
|
79
|
+
* the thrown finding into the run and the output looks entirely ordinary. Measured on
|
|
80
|
+
* v0.28.0, the same two rules in each style:
|
|
81
|
+
*
|
|
82
|
+
* | rule file shape | findings reported |
|
|
83
|
+
* | -------------------------------- | ----------------- |
|
|
84
|
+
* | `export default [rule1, rule2]` | **5** — the configuration finding and all four violations |
|
|
85
|
+
* | self-executing | **1** — the four violations silently absent |
|
|
86
|
+
*
|
|
87
|
+
* Worse than a crash, because the run is **red for the other finding**: someone fixes
|
|
88
|
+
* that, moves on, and never learns the rest of the file was skipped — or takes the
|
|
89
|
+
* sanctioned remedy for a dead glob, which is to delete the rule, and still never
|
|
90
|
+
* learns it.
|
|
91
|
+
*
|
|
92
|
+
* **What this can and cannot say.** The module never finished, so the CLI cannot know
|
|
93
|
+
* *what* was lost — only that anything after the throw did not run. Naming a count or
|
|
94
|
+
* a rule would be invention. It says the file stopped and what to do, which is all it
|
|
95
|
+
* has.
|
|
96
|
+
*
|
|
97
|
+
* `bypassFilters` because it reports missing coverage: nothing to grade, exclude or
|
|
98
|
+
* accept into a baseline.
|
|
99
|
+
*/
|
|
100
|
+
export declare function ruleFileTruncated(file: string, ruleFiles: number): ArchViolation;
|
|
101
|
+
/**
|
|
102
|
+
* `--baseline` was passed, but the rule file printed findings the baseline never
|
|
103
|
+
* filtered. Bug 0199.
|
|
104
|
+
*
|
|
105
|
+
* **The mechanism, corrected TWICE. This is the third version and the measured one.**
|
|
106
|
+
*
|
|
107
|
+
* 1. *"The preset throws before baseline filtering runs."* False. `runCheck` collects
|
|
108
|
+
* a thrown terminal's violations off the error (`failureOrViolations`) and filters
|
|
109
|
+
* them; measured, its collection came back empty against a matching baseline.
|
|
110
|
+
* 2. *"`setCallerAggregatesReports` is module state that does not cross jiti's
|
|
111
|
+
* registry."* Also false, and it was the premise of a whole record. The flag is
|
|
112
|
+
* read at exactly ONE site — `core/execute-rule.ts`, inside `executeWarn`.
|
|
113
|
+
* And jiti is not even the default loader: `cli/import-rule-module.ts` imports
|
|
114
|
+
* natively first and reaches jiti only on a module-format refusal.
|
|
115
|
+
* (Line numbers deliberately omitted: the fix for (3) moved every one of them,
|
|
116
|
+
* and the first version of this docblock cited three that had already drifted.)
|
|
117
|
+
*
|
|
118
|
+
* 3. **What is actually true:** `executeCheck` calls `writeReport(...)`
|
|
119
|
+
* **unconditionally** at `core/execute-rule.ts`, one line before it throws.
|
|
120
|
+
* A `.check()` at module scope therefore prints its findings always — same
|
|
121
|
+
* registry, no jiti, no flag involved. The CLI cannot un-print them.
|
|
122
|
+
*
|
|
123
|
+
* The disproof of (2) is one line: a fixture importing the same module graph as the
|
|
124
|
+
* test's `runCheck`, so the flag was fully visible, printed all four violations
|
|
125
|
+
* anyway.
|
|
126
|
+
*
|
|
127
|
+
* **Why a notice and not the repair.** Making `executeCheck` honour the flag is a
|
|
128
|
+
* change to when a terminal emits — ADR-008 territory, and it would alter behaviour
|
|
129
|
+
* for every caller that relies on `.check()` printing, including test files. That is
|
|
130
|
+
* bug 0201. Until it is decided the run must not be silent about output it could not
|
|
131
|
+
* filter.
|
|
132
|
+
*
|
|
133
|
+
* **Fires only when something was actually printed.** `executeWarn` throws the same
|
|
134
|
+
* error type, and when the CLI aggregates it writes only non-`bypassFilters` entries
|
|
135
|
+
* — for a configuration finding, nothing at all. The first version fired on the bare
|
|
136
|
+
* `isArchRuleError` condition and so claimed a leak that never happened, pointing at
|
|
137
|
+
* a finding whose own text says a baseline can never suppress it. Asserting a cause
|
|
138
|
+
* the run cannot verify is the ADR-009 rule 2 defect `ruleFileFailure` names above.
|
|
139
|
+
*
|
|
140
|
+
* **What this can and cannot say.** The leaked lines were written before the CLI saw
|
|
141
|
+
* them, so it cannot know how many there were. Naming a count would be invention.
|
|
142
|
+
*
|
|
143
|
+
* `bypassFilters` because it reports a gap in filtering — accepting it into a
|
|
144
|
+
* baseline would suppress the notice that the baseline is not being applied.
|
|
145
|
+
*/
|
|
146
|
+
export declare function baselineNotApplied(file: string, filters: {
|
|
147
|
+
baseline?: string;
|
|
148
|
+
changed: boolean;
|
|
149
|
+
}): ArchViolation;
|
|
150
|
+
/**
|
|
151
|
+
* A rule file loaded cleanly and contributed **zero** rules.
|
|
152
|
+
*
|
|
153
|
+
* `check` used to print `✓ eess-ts — 0 rules across 1 file · 0 failing` and exit 0
|
|
154
|
+
* over exactly this, while `doctor` on the same file already refused it with "no
|
|
155
|
+
* rules found in the given files". Two commands in one CLI disagreeing about
|
|
156
|
+
* whether "no rules" is an error, and the one wired into CI was the one blessing
|
|
157
|
+
* it.
|
|
158
|
+
*
|
|
159
|
+
* **The shape that makes it urgent** is a migration from `@nielspeter/ts-archunit`,
|
|
160
|
+
* whose `recommended()` returned builders unconditionally and had no `report`
|
|
161
|
+
* option. eess-ts's runs and throws by default, so the line ts-archunit's own
|
|
162
|
+
* `init` scaffolded — `export default [...recommended(p)]` — spreads a *violations*
|
|
163
|
+
* array. On a codebase with findings that fails loudly (the loader rejects a
|
|
164
|
+
* non-builder entry). **On a clean codebase the array is empty**, so the file
|
|
165
|
+
* exports `[]`, the CLI loads nothing, and the run is green with every rule gone.
|
|
166
|
+
* `tsc --noEmit` passes; nothing reaches stderr.
|
|
167
|
+
*
|
|
168
|
+
* The adopter this hits is the one who did the baseline work and cleaned up.
|
|
169
|
+
*
|
|
170
|
+
* `CLAUDE.md` already tells agents that a zero denominator "means the gate matched
|
|
171
|
+
* little or nothing — treat that as a red flag". This makes the CLI agree with its
|
|
172
|
+
* own instruction instead of printing `✓` over its alarm value.
|
|
173
|
+
*
|
|
174
|
+
* `bypassFilters` because it reports absent coverage: there is nothing to grade,
|
|
175
|
+
* exclude, or accept into a baseline.
|
|
176
|
+
*/
|
|
177
|
+
export declare function ruleFileContributedNoRules(file: string): ArchViolation;
|
|
178
|
+
//# sourceMappingURL=rule-file-findings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-file-findings.d.ts","sourceRoot":"","sources":["../../src/cli/rule-file-findings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAIrD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,IAAI,EAAE,MAAM,GACX,aAAa,EAAE,CAEjB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,CA0B9F;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,MAAM,GAChB,aAAa,EAAE,CAEjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,CAqBhF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAC/C,aAAa,CAkDf;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAsBtE"}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { isArchRuleError } from '@nielspeter/eess';
|
|
2
|
+
import { basename } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Attribute findings that have no source location of their own to the rule file
|
|
5
|
+
* they came from.
|
|
6
|
+
*
|
|
7
|
+
* [ts-archunit Bug 0026](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0026-a-location-less-finding-does-not-say-which-rule-file-it-came-from.md):
|
|
8
|
+
* a configuration finding carries `file: ''` because it reports a fault in the
|
|
9
|
+
* rule rather than in the code, so two identical vacuous rules in two rule files
|
|
10
|
+
* rendered as two identical paragraphs with nothing saying which to open. In a
|
|
11
|
+
* test the frame comes free from vitest; in the CLI — the golden-path default —
|
|
12
|
+
* nothing supplied it, even though this loop knows the file and was discarding it.
|
|
13
|
+
*
|
|
14
|
+
* `line: 1`, following `tsconfig()`'s precedent for a fault that belongs to a
|
|
15
|
+
* file rather than to a position in it (`docs/config-rules.md` documents that
|
|
16
|
+
* choice). The builders cannot know the line: a rule with no glob has no
|
|
17
|
+
* position anywhere, and the assertion-gate findings are exactly the rules that
|
|
18
|
+
* may have none. Not `line: 0` — `::error file=x,line=0` is not a valid GitHub
|
|
19
|
+
* annotation and gets dropped or misplaced.
|
|
20
|
+
*
|
|
21
|
+
* **Safe against a `eess-exclude` comment only because these findings carry
|
|
22
|
+
* `bypassFilters`.** `execute-rule.ts` filters comment exclusions with
|
|
23
|
+
* `v.bypassFilters === true || !isExcludedByComment(...)`, and that first clause
|
|
24
|
+
* is what stops a real path here from making the finding suppressible by a
|
|
25
|
+
* comment in the rule file. It was written for this exact temptation, and until
|
|
26
|
+
* this change nothing tested it, because no such finding had a readable path.
|
|
27
|
+
* `tests/helpers/exclusion-comments.test.ts` now pins it.
|
|
28
|
+
*/
|
|
29
|
+
export function attributeToRuleFile(violations, file) {
|
|
30
|
+
return violations.map((v) => (v.file === '' ? { ...v, file, line: 1 } : v));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* A rule file, or one rule in it, that could not be evaluated at all.
|
|
34
|
+
*
|
|
35
|
+
* [ts-archunit Bug 0025](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0025-a-non-archruleerror-from-one-rule-file-drops-every-other-finding.md):
|
|
36
|
+
* `runCheck` and `runBaseline` caught `ArchRuleError` and rethrew everything
|
|
37
|
+
* else, so any other error escaped the per-file loop and terminated the process
|
|
38
|
+
* — no report written, no exit code returned, and every finding already
|
|
39
|
+
* collected discarded. Measured: one malformed `crossProject()` in one file
|
|
40
|
+
* silenced a second file's four real violations, and printed a raw Node stack
|
|
41
|
+
* trace with `node_modules` paths in their place.
|
|
42
|
+
*
|
|
43
|
+
* Reported as a **configuration finding** (`bypassFilters`): a rule that could
|
|
44
|
+
* not run enforced nothing, which is not a violation of the rule and is not
|
|
45
|
+
* something to accept into a baseline. Same reasoning as the assertion gate,
|
|
46
|
+
* and it inherits the same treatment — `error` severity whatever the rule
|
|
47
|
+
* asked for, refused by `.excluding()`, skipped by diff and baseline.
|
|
48
|
+
*
|
|
49
|
+
* `line: 1` with the rule file as `file`, following `tsconfig()`'s precedent for
|
|
50
|
+
* a fault that belongs to a file rather than to a position in it. Not `line: 0`:
|
|
51
|
+
* `::error file=x,line=0` is not a valid GitHub annotation and gets dropped or
|
|
52
|
+
* misplaced (the v0.22.0 defect), and only a `file` of `''` takes the run-level
|
|
53
|
+
* branch that avoids it.
|
|
54
|
+
*/
|
|
55
|
+
// eess-exclude eess/no-unused-exports: consumed by the test suite; the build tsconfig this gate reads excludes tests, so `src` is the only usage it can see
|
|
56
|
+
export function ruleFileFailure(file, error, ruleFiles) {
|
|
57
|
+
const raw = error instanceof Error ? error.message : String(error);
|
|
58
|
+
// An error message may or may not end in punctuation, and the sentence after
|
|
59
|
+
// it ran straight on: "…(reading 'config') The other rule files…". Measured on
|
|
60
|
+
// the real CLI, which is the only place the two strings meet.
|
|
61
|
+
const detail = /[.!?]$/.test(raw.trimEnd()) ? raw.trimEnd() : `${raw.trimEnd()}.`;
|
|
62
|
+
const others = ruleFiles > 1 ? ' The other rule files in this run were still checked.' : '';
|
|
63
|
+
return {
|
|
64
|
+
// The path goes in `file` and nowhere else it would be re-rendered. It used
|
|
65
|
+
// to appear four times in one finding — in `rule`, in `element`, in the
|
|
66
|
+
// location line, and in the remedy — and the location line renders it
|
|
67
|
+
// through `path.relative(cwd, …)`, so a rule file outside the cwd printed as
|
|
68
|
+
// `../../../../../../private/tmp/…`. Measured on the real CLI.
|
|
69
|
+
rule: 'eess-ts: rule file',
|
|
70
|
+
element: basename(file),
|
|
71
|
+
file,
|
|
72
|
+
line: 1,
|
|
73
|
+
message: `This rule file could not be evaluated, so its rules enforced nothing in this run: ${detail}${others}`,
|
|
74
|
+
// Conditional, never asserted — this fires for any error a rule file or a
|
|
75
|
+
// builder can raise (a syntax error, a missing dependency, a misconfigured
|
|
76
|
+
// builder), and naming one cause for all of them is the ADR-009 rule 2
|
|
77
|
+
// defect. The error message above is the evidence; the builder sentence is
|
|
78
|
+
// offered as the common case that is fixable without touching source code.
|
|
79
|
+
suggestion: `Fix the error named above in this rule file. If it names a builder method — for example a crossProject() with the wrong number of .side(...) calls — the rule is misconfigured rather than violated, so the fix is in the rule file and not in the code it checks.`,
|
|
80
|
+
bypassFilters: true,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* What to collect when evaluating a rule file, or one rule in it, threw.
|
|
85
|
+
*
|
|
86
|
+
* An `ArchRuleError` already carries findings — those ARE the report, and this
|
|
87
|
+
* is the pre-existing path for a rule file that self-executes a failing
|
|
88
|
+
* `.check()` at import. Anything else becomes one configuration finding naming
|
|
89
|
+
* the file. Never a rethrow: that discarded every finding already collected in
|
|
90
|
+
* the run, including other files' (bug 0025).
|
|
91
|
+
*
|
|
92
|
+
* One definition, imported by both `runCheck` and `runBaseline`. They had a copy
|
|
93
|
+
* each for the ArchRuleError half and the two had already diverged in what they
|
|
94
|
+
* did with everything else.
|
|
95
|
+
*/
|
|
96
|
+
export function failureOrViolations(file, error, ruleFiles) {
|
|
97
|
+
return isArchRuleError(error) ? error.violations : [ruleFileFailure(file, error, ruleFiles)];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* A rule file stopped evaluating partway, so the rules after that point never ran.
|
|
101
|
+
*
|
|
102
|
+
* [ts-archunit Bug 0029](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0029-a-throwing-warn-truncates-the-rest-of-the-rule-file.md),
|
|
103
|
+
* and the half [ts-archunit plan 0069](https://github.com/nielspeter/ts-archunit/blob/main/plans/completed/0069-no-rule-may-certify-nothing.md)'s R3a
|
|
104
|
+
* specified and did not build: *"R3a states the semantics, and the CLI **reports the
|
|
105
|
+
* truncation rather than absorbing it**."* The semantics shipped in v0.23.0; this is
|
|
106
|
+
* the reporting.
|
|
107
|
+
*
|
|
108
|
+
* In a **self-executing** rule file — the shape `init` scaffolds and `docs/cli.md`
|
|
109
|
+
* documents — every rule calls its own terminal at module scope. A throw there aborts
|
|
110
|
+
* the module, so every rule declared after it is never evaluated. The CLI then folds
|
|
111
|
+
* the thrown finding into the run and the output looks entirely ordinary. Measured on
|
|
112
|
+
* v0.28.0, the same two rules in each style:
|
|
113
|
+
*
|
|
114
|
+
* | rule file shape | findings reported |
|
|
115
|
+
* | -------------------------------- | ----------------- |
|
|
116
|
+
* | `export default [rule1, rule2]` | **5** — the configuration finding and all four violations |
|
|
117
|
+
* | self-executing | **1** — the four violations silently absent |
|
|
118
|
+
*
|
|
119
|
+
* Worse than a crash, because the run is **red for the other finding**: someone fixes
|
|
120
|
+
* that, moves on, and never learns the rest of the file was skipped — or takes the
|
|
121
|
+
* sanctioned remedy for a dead glob, which is to delete the rule, and still never
|
|
122
|
+
* learns it.
|
|
123
|
+
*
|
|
124
|
+
* **What this can and cannot say.** The module never finished, so the CLI cannot know
|
|
125
|
+
* *what* was lost — only that anything after the throw did not run. Naming a count or
|
|
126
|
+
* a rule would be invention. It says the file stopped and what to do, which is all it
|
|
127
|
+
* has.
|
|
128
|
+
*
|
|
129
|
+
* `bypassFilters` because it reports missing coverage: nothing to grade, exclude or
|
|
130
|
+
* accept into a baseline.
|
|
131
|
+
*/
|
|
132
|
+
export function ruleFileTruncated(file, ruleFiles) {
|
|
133
|
+
const others = ruleFiles > 1 ? ' The other rule files in this run were still checked.' : '';
|
|
134
|
+
return {
|
|
135
|
+
rule: 'eess-ts: rule file',
|
|
136
|
+
element: basename(file),
|
|
137
|
+
file,
|
|
138
|
+
line: 1,
|
|
139
|
+
message: `This rule file stopped evaluating at the finding above, so any rule declared after ` +
|
|
140
|
+
`that point never ran and its violations are not in this report. Rules that had already ` +
|
|
141
|
+
`run are reported normally.${others}`,
|
|
142
|
+
suggestion: `Fix the finding above, then re-run to see the rest of this file. To make the file ` +
|
|
143
|
+
`always evaluate in full: if its rules come from a preset, pass \`report: 'builders'\` — ` +
|
|
144
|
+
`e.g. \`recommended(p, { report: 'builders' })\` — which returns the builders instead of ` +
|
|
145
|
+
`running them at module scope. A spread like \`export default [...recommended(p)]\` does ` +
|
|
146
|
+
`NOT avoid this on its own, because the spread evaluates before the array exists. ` +
|
|
147
|
+
`Otherwise move the rules into \`export default [rule1, rule2]\` and drop the terminal ` +
|
|
148
|
+
`calls, so every rule is built before any of them runs.`,
|
|
149
|
+
bypassFilters: true,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* `--baseline` was passed, but the rule file printed findings the baseline never
|
|
154
|
+
* filtered. Bug 0199.
|
|
155
|
+
*
|
|
156
|
+
* **The mechanism, corrected TWICE. This is the third version and the measured one.**
|
|
157
|
+
*
|
|
158
|
+
* 1. *"The preset throws before baseline filtering runs."* False. `runCheck` collects
|
|
159
|
+
* a thrown terminal's violations off the error (`failureOrViolations`) and filters
|
|
160
|
+
* them; measured, its collection came back empty against a matching baseline.
|
|
161
|
+
* 2. *"`setCallerAggregatesReports` is module state that does not cross jiti's
|
|
162
|
+
* registry."* Also false, and it was the premise of a whole record. The flag is
|
|
163
|
+
* read at exactly ONE site — `core/execute-rule.ts`, inside `executeWarn`.
|
|
164
|
+
* And jiti is not even the default loader: `cli/import-rule-module.ts` imports
|
|
165
|
+
* natively first and reaches jiti only on a module-format refusal.
|
|
166
|
+
* (Line numbers deliberately omitted: the fix for (3) moved every one of them,
|
|
167
|
+
* and the first version of this docblock cited three that had already drifted.)
|
|
168
|
+
*
|
|
169
|
+
* 3. **What is actually true:** `executeCheck` calls `writeReport(...)`
|
|
170
|
+
* **unconditionally** at `core/execute-rule.ts`, one line before it throws.
|
|
171
|
+
* A `.check()` at module scope therefore prints its findings always — same
|
|
172
|
+
* registry, no jiti, no flag involved. The CLI cannot un-print them.
|
|
173
|
+
*
|
|
174
|
+
* The disproof of (2) is one line: a fixture importing the same module graph as the
|
|
175
|
+
* test's `runCheck`, so the flag was fully visible, printed all four violations
|
|
176
|
+
* anyway.
|
|
177
|
+
*
|
|
178
|
+
* **Why a notice and not the repair.** Making `executeCheck` honour the flag is a
|
|
179
|
+
* change to when a terminal emits — ADR-008 territory, and it would alter behaviour
|
|
180
|
+
* for every caller that relies on `.check()` printing, including test files. That is
|
|
181
|
+
* bug 0201. Until it is decided the run must not be silent about output it could not
|
|
182
|
+
* filter.
|
|
183
|
+
*
|
|
184
|
+
* **Fires only when something was actually printed.** `executeWarn` throws the same
|
|
185
|
+
* error type, and when the CLI aggregates it writes only non-`bypassFilters` entries
|
|
186
|
+
* — for a configuration finding, nothing at all. The first version fired on the bare
|
|
187
|
+
* `isArchRuleError` condition and so claimed a leak that never happened, pointing at
|
|
188
|
+
* a finding whose own text says a baseline can never suppress it. Asserting a cause
|
|
189
|
+
* the run cannot verify is the ADR-009 rule 2 defect `ruleFileFailure` names above.
|
|
190
|
+
*
|
|
191
|
+
* **What this can and cannot say.** The leaked lines were written before the CLI saw
|
|
192
|
+
* them, so it cannot know how many there were. Naming a count would be invention.
|
|
193
|
+
*
|
|
194
|
+
* `bypassFilters` because it reports a gap in filtering — accepting it into a
|
|
195
|
+
* baseline would suppress the notice that the baseline is not being applied.
|
|
196
|
+
*/
|
|
197
|
+
export function baselineNotApplied(file, filters) {
|
|
198
|
+
// Name the filters that were actually in play. `--baseline` is not the only one,
|
|
199
|
+
// and it is not always a FLAG — a config file can set it, and telling someone
|
|
200
|
+
// "`--baseline` was not applied" when they never typed it sends them looking for
|
|
201
|
+
// an argument they did not pass (adopter review of PR #74).
|
|
202
|
+
const names = [];
|
|
203
|
+
if (filters.baseline !== undefined)
|
|
204
|
+
names.push(`the baseline \`${basename(filters.baseline)}\``);
|
|
205
|
+
if (filters.changed)
|
|
206
|
+
names.push('`--changed` (diff-aware mode)');
|
|
207
|
+
const list = names.join(' and ');
|
|
208
|
+
return {
|
|
209
|
+
// NOT `eess-ts: rule file` — `dedupeConfigFindings` keys on
|
|
210
|
+
// `file + rule + element`, so sharing that label merges this into
|
|
211
|
+
// `ruleFileTruncated()` and the notice disappears. Measured: it did.
|
|
212
|
+
//
|
|
213
|
+
// NOT `eess-ts: baseline` either: it fires for `--changed` too, and three
|
|
214
|
+
// existing findings already use that label for baseline diagnostics.
|
|
215
|
+
//
|
|
216
|
+
// And NOT `eess-ts: filtering`, which it briefly was — across `docs/`
|
|
217
|
+
// "filtering" is the `.that()` predicate phase (`docs/core-concepts.md:91`,
|
|
218
|
+
// repeated on every dialect page), so a reader seeing it on a red build would
|
|
219
|
+
// most reasonably conclude their predicate was wrong. `reporting` is ADR-008's
|
|
220
|
+
// own noun for what this finding is actually about: who emitted, and when.
|
|
221
|
+
rule: 'eess-ts: reporting',
|
|
222
|
+
element: basename(file),
|
|
223
|
+
file,
|
|
224
|
+
line: 1,
|
|
225
|
+
message: `This rule file reported findings itself, so ${list} ` +
|
|
226
|
+
`${names.length > 1 ? 'were' : 'was'} NOT applied to them — anything it printed ` +
|
|
227
|
+
`reached you unfiltered, and findings you have already accepted or excluded can ` +
|
|
228
|
+
`appear as failures. The findings the CLI collected were filtered normally, which ` +
|
|
229
|
+
`is why the counts in this run disagree.`,
|
|
230
|
+
because: `A CLI-side filter can only act on findings the CLI collects. A rule file that ` +
|
|
231
|
+
`calls its own terminal at module scope prints them first, so the run you are ` +
|
|
232
|
+
`reading is not the run the filter describes.`,
|
|
233
|
+
// The remedy is ordered generic-first ON PURPOSE. This finding fires for ANY
|
|
234
|
+
// terminal throwing at module scope — a hand-written `.check()` with no preset
|
|
235
|
+
// in sight reaches it too — so naming the preset fix alone would be the ADR-009
|
|
236
|
+
// rule 2 defect its neighbour `ruleFileFailure` calls out by name.
|
|
237
|
+
suggestion: `Move this file's rules into \`export default [rule1, rule2]\` and drop the ` +
|
|
238
|
+
`terminal calls — an array export hands every rule to the CLI, which then owns ` +
|
|
239
|
+
`reporting and applies every filter to all of it. If the rules come from a ` +
|
|
240
|
+
`preset, pass \`report: 'builders'\` instead — e.g. ` +
|
|
241
|
+
`\`recommended(p, { report: 'builders' })\` — which returns the builders rather ` +
|
|
242
|
+
`than running them. \`eess-ts init\` scaffolds both forms correctly.`,
|
|
243
|
+
bypassFilters: true,
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* A rule file loaded cleanly and contributed **zero** rules.
|
|
248
|
+
*
|
|
249
|
+
* `check` used to print `✓ eess-ts — 0 rules across 1 file · 0 failing` and exit 0
|
|
250
|
+
* over exactly this, while `doctor` on the same file already refused it with "no
|
|
251
|
+
* rules found in the given files". Two commands in one CLI disagreeing about
|
|
252
|
+
* whether "no rules" is an error, and the one wired into CI was the one blessing
|
|
253
|
+
* it.
|
|
254
|
+
*
|
|
255
|
+
* **The shape that makes it urgent** is a migration from `@nielspeter/ts-archunit`,
|
|
256
|
+
* whose `recommended()` returned builders unconditionally and had no `report`
|
|
257
|
+
* option. eess-ts's runs and throws by default, so the line ts-archunit's own
|
|
258
|
+
* `init` scaffolded — `export default [...recommended(p)]` — spreads a *violations*
|
|
259
|
+
* array. On a codebase with findings that fails loudly (the loader rejects a
|
|
260
|
+
* non-builder entry). **On a clean codebase the array is empty**, so the file
|
|
261
|
+
* exports `[]`, the CLI loads nothing, and the run is green with every rule gone.
|
|
262
|
+
* `tsc --noEmit` passes; nothing reaches stderr.
|
|
263
|
+
*
|
|
264
|
+
* The adopter this hits is the one who did the baseline work and cleaned up.
|
|
265
|
+
*
|
|
266
|
+
* `CLAUDE.md` already tells agents that a zero denominator "means the gate matched
|
|
267
|
+
* little or nothing — treat that as a red flag". This makes the CLI agree with its
|
|
268
|
+
* own instruction instead of printing `✓` over its alarm value.
|
|
269
|
+
*
|
|
270
|
+
* `bypassFilters` because it reports absent coverage: there is nothing to grade,
|
|
271
|
+
* exclude, or accept into a baseline.
|
|
272
|
+
*/
|
|
273
|
+
export function ruleFileContributedNoRules(file) {
|
|
274
|
+
return {
|
|
275
|
+
rule: 'eess-ts: rule file',
|
|
276
|
+
element: basename(file),
|
|
277
|
+
file,
|
|
278
|
+
line: 1,
|
|
279
|
+
message: `This rule file loaded without error but contributed no rules, so it enforced ` +
|
|
280
|
+
`nothing in this run. A green result here would mean "every rule passed" when ` +
|
|
281
|
+
`what happened is "there were no rules".`,
|
|
282
|
+
because: `A gate that checks nothing cannot fail, and a passing build is only evidence ` +
|
|
283
|
+
`if something was actually examined.`,
|
|
284
|
+
suggestion: `Check what this file's default export actually contains. The usual cause is a ` +
|
|
285
|
+
`preset spread without \`report: 'builders'\` — \`export default ` +
|
|
286
|
+
`[...recommended(p)]\` spreads the preset's RESULT, which on a codebase with no ` +
|
|
287
|
+
`violations is an empty array. Use \`recommended(p, { report: 'builders' })\`. ` +
|
|
288
|
+
`If the file is deliberately empty, delete it rather than leaving a rule file ` +
|
|
289
|
+
`that enforces nothing.`,
|
|
290
|
+
bypassFilters: true,
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=rule-file-findings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-file-findings.js","sourceRoot":"","sources":["../../src/cli/rule-file-findings.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/watch.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
interface WatchOptions {
|
|
2
2
|
/** Directories to watch for changes */
|
|
3
3
|
watchDirs: string[];
|
|
4
4
|
/** Additional files to watch (e.g., rule files) */
|
|
@@ -22,13 +22,17 @@ export declare class RunScheduler {
|
|
|
22
22
|
private _pendingRerun;
|
|
23
23
|
private readonly debounceMs;
|
|
24
24
|
private readonly onRun;
|
|
25
|
-
|
|
25
|
+
/** Completed runs. */
|
|
26
26
|
get runCount(): number;
|
|
27
|
+
constructor(onRun: (trigger: string) => Promise<void>, debounceMs?: number);
|
|
27
28
|
get pendingRerun(): boolean;
|
|
28
29
|
get isRunning(): boolean;
|
|
29
30
|
/**
|
|
30
|
-
* Queue a run
|
|
31
|
-
*
|
|
31
|
+
* Queue a re-run, debounced.
|
|
32
|
+
*
|
|
33
|
+
* A run already in flight is not interrupted: the request is remembered and
|
|
34
|
+
* replayed when it finishes, so a save during a run is never dropped and
|
|
35
|
+
* never starts a second concurrent run.
|
|
32
36
|
*/
|
|
33
37
|
schedule(trigger: string): void;
|
|
34
38
|
private executeRun;
|
|
@@ -41,9 +45,18 @@ export declare class RunScheduler {
|
|
|
41
45
|
* a run is in progress, it is queued and executed after the
|
|
42
46
|
* current run completes.
|
|
43
47
|
*
|
|
44
|
-
* Known limitation: each re-run
|
|
45
|
-
*
|
|
46
|
-
* periodically for long sessions.
|
|
48
|
+
* Known limitation: each re-run uses `importFresh` which creates
|
|
49
|
+
* a new ESM module cache entry. Over long sessions, memory grows.
|
|
50
|
+
* Restart the watcher periodically for long sessions.
|
|
47
51
|
*/
|
|
48
52
|
export declare function watchAndRerun(options: WatchOptions): void;
|
|
53
|
+
/**
|
|
54
|
+
* Import a module with cache-busting for watch mode.
|
|
55
|
+
*
|
|
56
|
+
* Node ESM has no cache eviction API. Each call creates a new
|
|
57
|
+
* module entry via a unique query string. Over long sessions
|
|
58
|
+
* this leaks memory — see watchAndRerun JSDoc.
|
|
59
|
+
*/
|
|
60
|
+
export declare function importFresh(filePath: string): Promise<unknown>;
|
|
61
|
+
export {};
|
|
49
62
|
//# sourceMappingURL=watch.d.ts.map
|
package/dist/cli/watch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/cli/watch.ts"],"names":[],"mappings":"AAKA,
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/cli/watch.ts"],"names":[],"mappings":"AAKA,UAAU,YAAY;IACpB,uCAAuC;IACvC,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,mDAAmD;IACnD,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,0CAA0C;IAC1C,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAGD,eAAO,MAAM,UAAU,QAAiB,CAAA;AAExC;;;;;GAKG;AAEH,qBAAa,YAAY;;IACvB,OAAO,CAAC,aAAa,CAA2C;IAChE,OAAO,CAAC,OAAO,CAAQ;IACvB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAoC;IAU1D,sBAAsB;IACtB,IAAI,QAAQ,IAAI,MAAM,CAErB;gBAEW,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,SAAM;IAKvE,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAW/B,OAAO,CAAC,UAAU;CAwBnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAsDzD;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAIpE"}
|
package/dist/cli/watch.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { watch } from 'node:fs/promises';
|
|
2
|
+
import { isNullaryCallable } from '@nielspeter/eess';
|
|
2
3
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
4
|
-
// eess-exclude eess/no-unused-exports: consumed by the test suite
|
|
4
|
+
import { isArchRuleError } from '@nielspeter/eess';
|
|
5
|
+
// eess-exclude eess/no-unused-exports: consumed by the test suite; the build tsconfig this gate reads excludes tests, so `src` is the only usage it can see
|
|
5
6
|
export const TS_FILE_RE = /\.[cm]?tsx?$/;
|
|
6
7
|
/**
|
|
7
8
|
* Scheduling logic for watch mode — extracted for testability.
|
|
@@ -9,21 +10,29 @@ export const TS_FILE_RE = /\.[cm]?tsx?$/;
|
|
|
9
10
|
* Debounces rapid triggers. If a trigger arrives while the callback
|
|
10
11
|
* is running, it queues a re-run after the current run completes.
|
|
11
12
|
*/
|
|
12
|
-
// eess-exclude eess/no-unused-exports: consumed by the test suite
|
|
13
|
+
// eess-exclude eess/no-unused-exports: consumed by the test suite; the build tsconfig this gate reads excludes tests, so `src` is the only usage it can see
|
|
13
14
|
export class RunScheduler {
|
|
14
15
|
debounceTimer;
|
|
15
16
|
running = false;
|
|
16
17
|
_pendingRerun = false;
|
|
17
18
|
debounceMs;
|
|
18
19
|
onRun;
|
|
20
|
+
/**
|
|
21
|
+
* How many runs have completed — read by the watch loop's own tests.
|
|
22
|
+
*
|
|
23
|
+
* Hard-private with a getter, matching `eess-mermaid`'s `RunScheduler`: the
|
|
24
|
+
* counter is this class's bookkeeping and a caller that could reassign it
|
|
25
|
+
* would make the number mean nothing.
|
|
26
|
+
*/
|
|
19
27
|
#runCount = 0;
|
|
28
|
+
/** Completed runs. */
|
|
29
|
+
get runCount() {
|
|
30
|
+
return this.#runCount;
|
|
31
|
+
}
|
|
20
32
|
constructor(onRun, debounceMs = 250) {
|
|
21
33
|
this.onRun = onRun;
|
|
22
34
|
this.debounceMs = debounceMs;
|
|
23
35
|
}
|
|
24
|
-
get runCount() {
|
|
25
|
-
return this.#runCount;
|
|
26
|
-
}
|
|
27
36
|
get pendingRerun() {
|
|
28
37
|
return this._pendingRerun;
|
|
29
38
|
}
|
|
@@ -31,8 +40,11 @@ export class RunScheduler {
|
|
|
31
40
|
return this.running;
|
|
32
41
|
}
|
|
33
42
|
/**
|
|
34
|
-
* Queue a run
|
|
35
|
-
*
|
|
43
|
+
* Queue a re-run, debounced.
|
|
44
|
+
*
|
|
45
|
+
* A run already in flight is not interrupted: the request is remembered and
|
|
46
|
+
* replayed when it finishes, so a save during a run is never dropped and
|
|
47
|
+
* never starts a second concurrent run.
|
|
36
48
|
*/
|
|
37
49
|
schedule(trigger) {
|
|
38
50
|
if (this.debounceTimer)
|
|
@@ -54,7 +66,7 @@ export class RunScheduler {
|
|
|
54
66
|
this.onRun(trigger)
|
|
55
67
|
.catch((err) => {
|
|
56
68
|
// Rule failures are expected — swallow ArchRuleError, print others
|
|
57
|
-
if (!(err
|
|
69
|
+
if (!isArchRuleError(err)) {
|
|
58
70
|
if (err instanceof Error) {
|
|
59
71
|
console.error(err.message);
|
|
60
72
|
}
|
|
@@ -79,9 +91,9 @@ export class RunScheduler {
|
|
|
79
91
|
* a run is in progress, it is queued and executed after the
|
|
80
92
|
* current run completes.
|
|
81
93
|
*
|
|
82
|
-
* Known limitation: each re-run
|
|
83
|
-
*
|
|
84
|
-
* periodically for long sessions.
|
|
94
|
+
* Known limitation: each re-run uses `importFresh` which creates
|
|
95
|
+
* a new ESM module cache entry. Over long sessions, memory grows.
|
|
96
|
+
* Restart the watcher periodically for long sessions.
|
|
85
97
|
*/
|
|
86
98
|
export function watchAndRerun(options) {
|
|
87
99
|
const { watchDirs, watchFiles, onChangeDetected, debounceMs = 250 } = options;
|
|
@@ -129,10 +141,23 @@ export function watchAndRerun(options) {
|
|
|
129
141
|
// Graceful shutdown — close all watchers on SIGINT
|
|
130
142
|
process.on('SIGINT', () => {
|
|
131
143
|
for (const w of watchers) {
|
|
132
|
-
|
|
133
|
-
|
|
144
|
+
if ('return' in w && isNullaryCallable(w.return)) {
|
|
145
|
+
void w.return();
|
|
146
|
+
}
|
|
134
147
|
}
|
|
135
148
|
process.exit(0);
|
|
136
149
|
});
|
|
137
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Import a module with cache-busting for watch mode.
|
|
153
|
+
*
|
|
154
|
+
* Node ESM has no cache eviction API. Each call creates a new
|
|
155
|
+
* module entry via a unique query string. Over long sessions
|
|
156
|
+
* this leaks memory — see watchAndRerun JSDoc.
|
|
157
|
+
*/
|
|
158
|
+
export async function importFresh(filePath) {
|
|
159
|
+
const resolved = path.resolve(filePath);
|
|
160
|
+
const url = `file://${resolved}?t=${Date.now()}`;
|
|
161
|
+
return import(url);
|
|
162
|
+
}
|
|
138
163
|
//# sourceMappingURL=watch.js.map
|