@zxyycom/vibe-check 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +154 -0
- package/dist/esm/check/check.mjs +5 -0
- package/dist/esm/check/check.mjs.map +1 -0
- package/dist/esm/check/descriptor-validation.mjs +37 -0
- package/dist/esm/check/descriptor-validation.mjs.map +1 -0
- package/dist/esm/check/descriptor.mjs +2 -0
- package/dist/esm/check/descriptor.mjs.map +1 -0
- package/dist/esm/check/inherited-collection.mjs +62 -0
- package/dist/esm/check/inherited-collection.mjs.map +1 -0
- package/dist/esm/check/options-snapshot.mjs +75 -0
- package/dist/esm/check/options-snapshot.mjs.map +1 -0
- package/dist/esm/check-settlement/fact-validation.mjs +216 -0
- package/dist/esm/check-settlement/fact-validation.mjs.map +1 -0
- package/dist/esm/check-settlement/facts.mjs +2 -0
- package/dist/esm/check-settlement/facts.mjs.map +1 -0
- package/dist/esm/check-settlement/outcome-normalization.mjs +80 -0
- package/dist/esm/check-settlement/outcome-normalization.mjs.map +1 -0
- package/dist/esm/check-settlement/record-store.mjs +59 -0
- package/dist/esm/check-settlement/record-store.mjs.map +1 -0
- package/dist/esm/check-settlement/session.mjs +179 -0
- package/dist/esm/check-settlement/session.mjs.map +1 -0
- package/dist/esm/data-boundary/canonical-data.mjs +159 -0
- package/dist/esm/data-boundary/canonical-data.mjs.map +1 -0
- package/dist/esm/data-boundary/canonical-json.mjs +2 -0
- package/dist/esm/data-boundary/canonical-json.mjs.map +1 -0
- package/dist/esm/data-boundary/closed-values.mjs +98 -0
- package/dist/esm/data-boundary/closed-values.mjs.map +1 -0
- package/dist/esm/data-boundary/value-shapes.mjs +13 -0
- package/dist/esm/data-boundary/value-shapes.mjs.map +1 -0
- package/dist/esm/finding-waivers/reconciliation.mjs +84 -0
- package/dist/esm/finding-waivers/reconciliation.mjs.map +1 -0
- package/dist/esm/index.mjs +26 -0
- package/dist/esm/index.mjs.map +1 -0
- package/dist/esm/machine-output/v4/atomic-publication.mjs +102 -0
- package/dist/esm/machine-output/v4/atomic-publication.mjs.map +1 -0
- package/dist/esm/machine-output/v4/freeze-publication-value.mjs +14 -0
- package/dist/esm/machine-output/v4/freeze-publication-value.mjs.map +1 -0
- package/dist/esm/machine-output/v4/projection.mjs +23 -0
- package/dist/esm/machine-output/v4/projection.mjs.map +1 -0
- package/dist/esm/machine-output/v4/publication-invariants.mjs +59 -0
- package/dist/esm/machine-output/v4/publication-invariants.mjs.map +1 -0
- package/dist/esm/machine-output/v4/publication-model.mjs +19 -0
- package/dist/esm/machine-output/v4/publication-model.mjs.map +1 -0
- package/dist/esm/machine-output/v4/publish.mjs +20 -0
- package/dist/esm/machine-output/v4/publish.mjs.map +1 -0
- package/dist/esm/machine-output/v4/records-fingerprint.mjs +9 -0
- package/dist/esm/machine-output/v4/records-fingerprint.mjs.map +1 -0
- package/dist/esm/machine-output/v4/schema-identities.mjs +8 -0
- package/dist/esm/machine-output/v4/schema-identities.mjs.map +1 -0
- package/dist/esm/machine-output/v4/schema.mjs +50 -0
- package/dist/esm/machine-output/v4/schema.mjs.map +1 -0
- package/dist/esm/machine-output/v4/serializers.mjs +9 -0
- package/dist/esm/machine-output/v4/serializers.mjs.map +1 -0
- package/dist/esm/machine-output/v4/validation-result.mjs +16 -0
- package/dist/esm/machine-output/v4/validation-result.mjs.map +1 -0
- package/dist/esm/machine-output/v4/validation.mjs +131 -0
- package/dist/esm/machine-output/v4/validation.mjs.map +1 -0
- package/dist/esm/package-checks/code-quality-findings/policy.mjs +49 -0
- package/dist/esm/package-checks/code-quality-findings/policy.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/area-policy.mjs +71 -0
- package/dist/esm/package-checks/duplicate-detection/area-policy.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/cache/cache-contract.mjs +2 -0
- package/dist/esm/package-checks/duplicate-detection/cache/cache-contract.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/cache/identity.mjs +37 -0
- package/dist/esm/package-checks/duplicate-detection/cache/identity.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/cache/key.mjs +38 -0
- package/dist/esm/package-checks/duplicate-detection/cache/key.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/cache/payload.mjs +47 -0
- package/dist/esm/package-checks/duplicate-detection/cache/payload.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/cache/store.mjs +44 -0
- package/dist/esm/package-checks/duplicate-detection/cache/store.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/default-check.mjs +39 -0
- package/dist/esm/package-checks/duplicate-detection/default-check.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/execution.mjs +124 -0
- package/dist/esm/package-checks/duplicate-detection/execution.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/final-data.mjs +6 -0
- package/dist/esm/package-checks/duplicate-detection/final-data.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/availability.mjs +77 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/availability.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/command-path.mjs +6 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/command-path.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/command-resolution.mjs +87 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/command-resolution.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/json-report.mjs +94 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/json-report.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/scanner-contract.mjs +2 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/scanner-contract.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/scanner.mjs +180 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/scanner.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/scoped-fragments.mjs +10 -0
- package/dist/esm/package-checks/duplicate-detection/jscpd/scoped-fragments.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/measurement-model.mjs +2 -0
- package/dist/esm/package-checks/duplicate-detection/measurement-model.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/measurement.mjs +151 -0
- package/dist/esm/package-checks/duplicate-detection/measurement.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/options-resolution.mjs +126 -0
- package/dist/esm/package-checks/duplicate-detection/options-resolution.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/options-validation.mjs +60 -0
- package/dist/esm/package-checks/duplicate-detection/options-validation.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/options.mjs +2 -0
- package/dist/esm/package-checks/duplicate-detection/options.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/project-revision.mjs +5 -0
- package/dist/esm/package-checks/duplicate-detection/project-revision.mjs.map +1 -0
- package/dist/esm/package-checks/duplicate-detection/records.mjs +119 -0
- package/dist/esm/package-checks/duplicate-detection/records.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/constructor.mjs +39 -0
- package/dist/esm/package-checks/file-metrics/constructor.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/execution.mjs +170 -0
- package/dist/esm/package-checks/file-metrics/execution.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/final-data.mjs +6 -0
- package/dist/esm/package-checks/file-metrics/final-data.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/measurement-model.mjs +2 -0
- package/dist/esm/package-checks/file-metrics/measurement-model.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/measurement.mjs +33 -0
- package/dist/esm/package-checks/file-metrics/measurement.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/options-resolution.mjs +171 -0
- package/dist/esm/package-checks/file-metrics/options-resolution.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/options-validation.mjs +82 -0
- package/dist/esm/package-checks/file-metrics/options-validation.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/options.mjs +2 -0
- package/dist/esm/package-checks/file-metrics/options.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/records.mjs +109 -0
- package/dist/esm/package-checks/file-metrics/records.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/scc/availability.mjs +59 -0
- package/dist/esm/package-checks/file-metrics/scc/availability.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/scc/csv.mjs +17 -0
- package/dist/esm/package-checks/file-metrics/scc/csv.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/scc/parser.mjs +145 -0
- package/dist/esm/package-checks/file-metrics/scc/parser.mjs.map +1 -0
- package/dist/esm/package-checks/file-metrics/scc/scanner.mjs +54 -0
- package/dist/esm/package-checks/file-metrics/scc/scanner.mjs.map +1 -0
- package/dist/esm/package-checks/final-data-parsing.mjs +35 -0
- package/dist/esm/package-checks/final-data-parsing.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/analysis.mjs +96 -0
- package/dist/esm/package-checks/function-metrics/analysis.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/constructor.mjs +43 -0
- package/dist/esm/package-checks/function-metrics/constructor.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/execution.mjs +178 -0
- package/dist/esm/package-checks/function-metrics/execution.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/final-data.mjs +6 -0
- package/dist/esm/package-checks/function-metrics/final-data.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/lizard/availability.mjs +64 -0
- package/dist/esm/package-checks/function-metrics/lizard/availability.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/lizard/csv.mjs +17 -0
- package/dist/esm/package-checks/function-metrics/lizard/csv.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/lizard/parser.mjs +138 -0
- package/dist/esm/package-checks/function-metrics/lizard/parser.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/lizard/scanner.mjs +35 -0
- package/dist/esm/package-checks/function-metrics/lizard/scanner.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/measurement-model.mjs +2 -0
- package/dist/esm/package-checks/function-metrics/measurement-model.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/measurement.mjs +35 -0
- package/dist/esm/package-checks/function-metrics/measurement.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/options-resolution.mjs +171 -0
- package/dist/esm/package-checks/function-metrics/options-resolution.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/options-validation.mjs +71 -0
- package/dist/esm/package-checks/function-metrics/options-validation.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/options.mjs +2 -0
- package/dist/esm/package-checks/function-metrics/options.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/records.mjs +133 -0
- package/dist/esm/package-checks/function-metrics/records.mjs.map +1 -0
- package/dist/esm/package-checks/function-metrics/target-files.mjs +75 -0
- package/dist/esm/package-checks/function-metrics/target-files.mjs.map +1 -0
- package/dist/esm/package-checks/host-environment/error-message.mjs +4 -0
- package/dist/esm/package-checks/host-environment/error-message.mjs.map +1 -0
- package/dist/esm/package-checks/host-environment/filesystem.mjs +81 -0
- package/dist/esm/package-checks/host-environment/filesystem.mjs.map +1 -0
- package/dist/esm/package-checks/host-environment/git.mjs +51 -0
- package/dist/esm/package-checks/host-environment/git.mjs.map +1 -0
- package/dist/esm/package-checks/host-environment/path.mjs +18 -0
- package/dist/esm/package-checks/host-environment/path.mjs.map +1 -0
- package/dist/esm/package-checks/host-environment/process/command.mjs +13 -0
- package/dist/esm/package-checks/host-environment/process/command.mjs.map +1 -0
- package/dist/esm/package-checks/host-environment/process/contract.mjs +2 -0
- package/dist/esm/package-checks/host-environment/process/contract.mjs.map +1 -0
- package/dist/esm/package-checks/host-environment/process/env.mjs +19 -0
- package/dist/esm/package-checks/host-environment/process/env.mjs.map +1 -0
- package/dist/esm/package-checks/host-environment/process/failure.mjs +34 -0
- package/dist/esm/package-checks/host-environment/process/failure.mjs.map +1 -0
- package/dist/esm/package-checks/host-environment/process/result.mjs +33 -0
- package/dist/esm/package-checks/host-environment/process/result.mjs.map +1 -0
- package/dist/esm/package-checks/host-environment/process/runner.mjs +30 -0
- package/dist/esm/package-checks/host-environment/process/runner.mjs.map +1 -0
- package/dist/esm/package-checks/json-document/strict-document.mjs +163 -0
- package/dist/esm/package-checks/json-document/strict-document.mjs.map +1 -0
- package/dist/esm/package-checks/json-schema-validation/default-check.mjs +39 -0
- package/dist/esm/package-checks/json-schema-validation/default-check.mjs.map +1 -0
- package/dist/esm/package-checks/json-schema-validation/execution-stages.mjs +141 -0
- package/dist/esm/package-checks/json-schema-validation/execution-stages.mjs.map +1 -0
- package/dist/esm/package-checks/json-schema-validation/final-data.mjs +64 -0
- package/dist/esm/package-checks/json-schema-validation/final-data.mjs.map +1 -0
- package/dist/esm/package-checks/json-schema-validation/issue-collector.mjs +35 -0
- package/dist/esm/package-checks/json-schema-validation/issue-collector.mjs.map +1 -0
- package/dist/esm/package-checks/json-schema-validation/json-schema-validation.mjs +118 -0
- package/dist/esm/package-checks/json-schema-validation/json-schema-validation.mjs.map +1 -0
- package/dist/esm/package-checks/json-schema-validation/options-resolution.mjs +45 -0
- package/dist/esm/package-checks/json-schema-validation/options-resolution.mjs.map +1 -0
- package/dist/esm/package-checks/json-schema-validation/options-validation.mjs +212 -0
- package/dist/esm/package-checks/json-schema-validation/options-validation.mjs.map +1 -0
- package/dist/esm/package-checks/json-schema-validation/options.mjs +2 -0
- package/dist/esm/package-checks/json-schema-validation/options.mjs.map +1 -0
- package/dist/esm/package-checks/json-schema-validation/reference-resolver.mjs +128 -0
- package/dist/esm/package-checks/json-schema-validation/reference-resolver.mjs.map +1 -0
- package/dist/esm/package-checks/json-schema-validation/remote-response.mjs +71 -0
- package/dist/esm/package-checks/json-schema-validation/remote-response.mjs.map +1 -0
- package/dist/esm/package-checks/json-schema-validation/schema-engine.mjs +190 -0
- package/dist/esm/package-checks/json-schema-validation/schema-engine.mjs.map +1 -0
- package/dist/esm/package-checks/json-schema-validation/schema-policy.mjs +234 -0
- package/dist/esm/package-checks/json-schema-validation/schema-policy.mjs.map +1 -0
- package/dist/esm/package-checks/json-validation/default-check.mjs +39 -0
- package/dist/esm/package-checks/json-validation/default-check.mjs.map +1 -0
- package/dist/esm/package-checks/json-validation/final-data.mjs +27 -0
- package/dist/esm/package-checks/json-validation/final-data.mjs.map +1 -0
- package/dist/esm/package-checks/json-validation/json-validation.mjs +138 -0
- package/dist/esm/package-checks/json-validation/json-validation.mjs.map +1 -0
- package/dist/esm/package-checks/json-validation/options-resolution.mjs +33 -0
- package/dist/esm/package-checks/json-validation/options-resolution.mjs.map +1 -0
- package/dist/esm/package-checks/json-validation/options-validation.mjs +16 -0
- package/dist/esm/package-checks/json-validation/options-validation.mjs.map +1 -0
- package/dist/esm/package-checks/json-validation/options.mjs +2 -0
- package/dist/esm/package-checks/json-validation/options.mjs.map +1 -0
- package/dist/esm/package-checks/maintenance-reminders/assessment-results.mjs +73 -0
- package/dist/esm/package-checks/maintenance-reminders/assessment-results.mjs.map +1 -0
- package/dist/esm/package-checks/maintenance-reminders/final-data.mjs +153 -0
- package/dist/esm/package-checks/maintenance-reminders/final-data.mjs.map +1 -0
- package/dist/esm/package-checks/maintenance-reminders/maintenance-reminders.mjs +155 -0
- package/dist/esm/package-checks/maintenance-reminders/maintenance-reminders.mjs.map +1 -0
- package/dist/esm/package-checks/maintenance-reminders/maintenance-support.mjs +58 -0
- package/dist/esm/package-checks/maintenance-reminders/maintenance-support.mjs.map +1 -0
- package/dist/esm/package-checks/maintenance-reminders/measurement.mjs +125 -0
- package/dist/esm/package-checks/maintenance-reminders/measurement.mjs.map +1 -0
- package/dist/esm/package-checks/maintenance-reminders/options-validation.mjs +72 -0
- package/dist/esm/package-checks/maintenance-reminders/options-validation.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/default-check.mjs +55 -0
- package/dist/esm/package-checks/markdown-link-validation/default-check.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/execution.mjs +199 -0
- package/dist/esm/package-checks/markdown-link-validation/execution.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/filesystem-probes.mjs +109 -0
- package/dist/esm/package-checks/markdown-link-validation/filesystem-probes.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/final-data.mjs +28 -0
- package/dist/esm/package-checks/markdown-link-validation/final-data.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/local-resolution.mjs +158 -0
- package/dist/esm/package-checks/markdown-link-validation/local-resolution.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/local-resolver.mjs +17 -0
- package/dist/esm/package-checks/markdown-link-validation/local-resolver.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/markdown-parser.mjs +191 -0
- package/dist/esm/package-checks/markdown-link-validation/markdown-parser.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/options-resolution.mjs +83 -0
- package/dist/esm/package-checks/markdown-link-validation/options-resolution.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/options-validation.mjs +50 -0
- package/dist/esm/package-checks/markdown-link-validation/options-validation.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/options.mjs +2 -0
- package/dist/esm/package-checks/markdown-link-validation/options.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/records.mjs +32 -0
- package/dist/esm/package-checks/markdown-link-validation/records.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/resolver-engine.mjs +196 -0
- package/dist/esm/package-checks/markdown-link-validation/resolver-engine.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/target-descriptor.mjs +23 -0
- package/dist/esm/package-checks/markdown-link-validation/target-descriptor.mjs.map +1 -0
- package/dist/esm/package-checks/markdown-link-validation/traversal-result.mjs +41 -0
- package/dist/esm/package-checks/markdown-link-validation/traversal-result.mjs.map +1 -0
- package/dist/esm/package-checks/project-files/collection.mjs +142 -0
- package/dist/esm/package-checks/project-files/collection.mjs.map +1 -0
- package/dist/esm/package-checks/project-files/config-glob.mjs +11 -0
- package/dist/esm/package-checks/project-files/config-glob.mjs.map +1 -0
- package/dist/esm/package-checks/project-files/configuration.mjs +104 -0
- package/dist/esm/package-checks/project-files/configuration.mjs.map +1 -0
- package/dist/esm/package-checks/project-files/exact-input-measurement.mjs +24 -0
- package/dist/esm/package-checks/project-files/exact-input-measurement.mjs.map +1 -0
- package/dist/esm/package-checks/project-files/file-fingerprint.mjs +36 -0
- package/dist/esm/package-checks/project-files/file-fingerprint.mjs.map +1 -0
- package/dist/esm/package-checks/project-files/gitlink-revision.mjs +57 -0
- package/dist/esm/package-checks/project-files/gitlink-revision.mjs.map +1 -0
- package/dist/esm/package-checks/project-files/gitlink-worktree.mjs +72 -0
- package/dist/esm/package-checks/project-files/gitlink-worktree.mjs.map +1 -0
- package/dist/esm/package-checks/project-files/input-eligibility.mjs +13 -0
- package/dist/esm/package-checks/project-files/input-eligibility.mjs.map +1 -0
- package/dist/esm/package-checks/project-files/reported-path.mjs +30 -0
- package/dist/esm/package-checks/project-files/reported-path.mjs.map +1 -0
- package/dist/esm/package-checks/project-files/revision-paths.mjs +19 -0
- package/dist/esm/package-checks/project-files/revision-paths.mjs.map +1 -0
- package/dist/esm/package-checks/project-files/revision-worktree-files.mjs +102 -0
- package/dist/esm/package-checks/project-files/revision-worktree-files.mjs.map +1 -0
- package/dist/esm/project-definition/check-tree/authoring.mjs +242 -0
- package/dist/esm/project-definition/check-tree/authoring.mjs.map +1 -0
- package/dist/esm/project-definition/check-tree/materialization.mjs +50 -0
- package/dist/esm/project-definition/check-tree/materialization.mjs.map +1 -0
- package/dist/esm/project-definition/check-tree/resolution.mjs +60 -0
- package/dist/esm/project-definition/check-tree/resolution.mjs.map +1 -0
- package/dist/esm/project-definition/output-defaults.mjs +7 -0
- package/dist/esm/project-definition/output-defaults.mjs.map +1 -0
- package/dist/esm/project-definition/output-validation.mjs +44 -0
- package/dist/esm/project-definition/output-validation.mjs.map +1 -0
- package/dist/esm/project-definition/project-definition-validation.mjs +95 -0
- package/dist/esm/project-definition/project-definition-validation.mjs.map +1 -0
- package/dist/esm/project-definition/project-definition.mjs +92 -0
- package/dist/esm/project-definition/project-definition.mjs.map +1 -0
- package/dist/esm/project-run/aggregation.mjs +66 -0
- package/dist/esm/project-run/aggregation.mjs.map +1 -0
- package/dist/esm/project-run/check-execution/callback.mjs +70 -0
- package/dist/esm/project-run/check-execution/callback.mjs.map +1 -0
- package/dist/esm/project-run/check-execution/dependencies.mjs +50 -0
- package/dist/esm/project-run/check-execution/dependencies.mjs.map +1 -0
- package/dist/esm/project-run/check-execution/execution-finalization.mjs +103 -0
- package/dist/esm/project-run/check-execution/execution-finalization.mjs.map +1 -0
- package/dist/esm/project-run/check-execution/execution-settlement.mjs +90 -0
- package/dist/esm/project-run/check-execution/execution-settlement.mjs.map +1 -0
- package/dist/esm/project-run/check-execution/messages.mjs +38 -0
- package/dist/esm/project-run/check-execution/messages.mjs.map +1 -0
- package/dist/esm/project-run/check-execution/plan.mjs +35 -0
- package/dist/esm/project-run/check-execution/plan.mjs.map +1 -0
- package/dist/esm/project-run/check-execution/preflight-result.mjs +83 -0
- package/dist/esm/project-run/check-execution/preflight-result.mjs.map +1 -0
- package/dist/esm/project-run/check-execution/preflight.mjs +186 -0
- package/dist/esm/project-run/check-execution/preflight.mjs.map +1 -0
- package/dist/esm/project-run/check-execution/resolved-checks.mjs +168 -0
- package/dist/esm/project-run/check-execution/resolved-checks.mjs.map +1 -0
- package/dist/esm/project-run/check-execution/terminal-result.mjs +49 -0
- package/dist/esm/project-run/check-execution/terminal-result.mjs.map +1 -0
- package/dist/esm/project-run/completion.mjs +173 -0
- package/dist/esm/project-run/completion.mjs.map +1 -0
- package/dist/esm/project-run/controls/contract.mjs +2 -0
- package/dist/esm/project-run/controls/contract.mjs.map +1 -0
- package/dist/esm/project-run/controls/outputs-override-validation.mjs +61 -0
- package/dist/esm/project-run/controls/outputs-override-validation.mjs.map +1 -0
- package/dist/esm/project-run/controls/validation-result.mjs +2 -0
- package/dist/esm/project-run/controls/validation-result.mjs.map +1 -0
- package/dist/esm/project-run/controls/validation.mjs +156 -0
- package/dist/esm/project-run/controls/validation.mjs.map +1 -0
- package/dist/esm/project-run/diagnostic-logging/diagnostic-detail-rendering.mjs +182 -0
- package/dist/esm/project-run/diagnostic-logging/diagnostic-detail-rendering.mjs.map +1 -0
- package/dist/esm/project-run/diagnostic-logging/logger.mjs +242 -0
- package/dist/esm/project-run/diagnostic-logging/logger.mjs.map +1 -0
- package/dist/esm/project-run/invocation-creation.mjs +111 -0
- package/dist/esm/project-run/invocation-creation.mjs.map +1 -0
- package/dist/esm/project-run/invocation.mjs +195 -0
- package/dist/esm/project-run/invocation.mjs.map +1 -0
- package/dist/esm/project-run/machine-publication.mjs +16 -0
- package/dist/esm/project-run/machine-publication.mjs.map +1 -0
- package/dist/esm/project-run/output-configuration.mjs +17 -0
- package/dist/esm/project-run/output-configuration.mjs.map +1 -0
- package/dist/esm/project-run/output-status.mjs +43 -0
- package/dist/esm/project-run/output-status.mjs.map +1 -0
- package/dist/esm/project-run/progress-rendering/presentation.mjs +135 -0
- package/dist/esm/project-run/progress-rendering/presentation.mjs.map +1 -0
- package/dist/esm/project-run/progress-rendering/renderer-formatting.mjs +100 -0
- package/dist/esm/project-run/progress-rendering/renderer-formatting.mjs.map +1 -0
- package/dist/esm/project-run/progress-rendering/renderer-lifecycle.mjs +123 -0
- package/dist/esm/project-run/progress-rendering/renderer-lifecycle.mjs.map +1 -0
- package/dist/esm/project-run/progress-rendering/renderer.mjs +12 -0
- package/dist/esm/project-run/progress-rendering/renderer.mjs.map +1 -0
- package/dist/esm/project-run/project-context.mjs +8 -0
- package/dist/esm/project-run/project-context.mjs.map +1 -0
- package/dist/esm/project-run/result.mjs +54 -0
- package/dist/esm/project-run/result.mjs.map +1 -0
- package/dist/esm/project-run/run.mjs +23 -0
- package/dist/esm/project-run/run.mjs.map +1 -0
- package/dist/esm/project-run/task-scheduler/execution-state.mjs +66 -0
- package/dist/esm/project-run/task-scheduler/execution-state.mjs.map +1 -0
- package/dist/esm/project-run/task-scheduler/graph-validation.mjs +119 -0
- package/dist/esm/project-run/task-scheduler/graph-validation.mjs.map +1 -0
- package/dist/esm/project-run/task-scheduler/graph.mjs +116 -0
- package/dist/esm/project-run/task-scheduler/graph.mjs.map +1 -0
- package/dist/esm/project-run/task-scheduler/scheduler-admission-decision.mjs +82 -0
- package/dist/esm/project-run/task-scheduler/scheduler-admission-decision.mjs.map +1 -0
- package/dist/esm/project-run/task-scheduler/scheduler-blocker-summary.mjs +27 -0
- package/dist/esm/project-run/task-scheduler/scheduler-blocker-summary.mjs.map +1 -0
- package/dist/esm/project-run/task-scheduler/scheduler-decision-inspection.mjs +125 -0
- package/dist/esm/project-run/task-scheduler/scheduler-decision-inspection.mjs.map +1 -0
- package/dist/esm/project-run/task-scheduler/scheduler-decision-model.mjs +45 -0
- package/dist/esm/project-run/task-scheduler/scheduler-decision-model.mjs.map +1 -0
- package/dist/esm/project-run/task-scheduler/scheduler-decision.mjs +74 -0
- package/dist/esm/project-run/task-scheduler/scheduler-decision.mjs.map +1 -0
- package/dist/esm/project-run/task-scheduler/scheduler.mjs +147 -0
- package/dist/esm/project-run/task-scheduler/scheduler.mjs.map +1 -0
- package/docs/api-mechanics.md +205 -0
- package/docs/checks/duplicate-detection.md +195 -0
- package/docs/checks/file-metrics.md +229 -0
- package/docs/checks/function-metrics.md +222 -0
- package/docs/checks/json-schema-validation.md +190 -0
- package/docs/checks/json-validation.md +133 -0
- package/docs/checks/maintenance-reminders.md +158 -0
- package/docs/checks/markdown-link-validation.md +192 -0
- package/docs/examples/artifacts/mixed-outcomes/definition.ts +195 -0
- package/docs/examples/artifacts/mixed-outcomes/records.ndjson +2 -0
- package/docs/examples/artifacts/mixed-outcomes/run.json +70 -0
- package/docs/output.md +97 -0
- package/docs/schemas/vibe-check-record.schema.json +33 -0
- package/docs/schemas/vibe-check-run.schema.json +173 -0
- package/index.mjs +1 -0
- package/package.json +49 -0
- package/src/check/check.ts +497 -0
- package/src/check/descriptor-validation.ts +60 -0
- package/src/check/descriptor.ts +5 -0
- package/src/check/inherited-collection.ts +101 -0
- package/src/check/options-snapshot.ts +80 -0
- package/src/check-settlement/fact-validation.ts +289 -0
- package/src/check-settlement/facts.ts +27 -0
- package/src/check-settlement/outcome-normalization.ts +118 -0
- package/src/check-settlement/record-store.ts +73 -0
- package/src/check-settlement/session.ts +257 -0
- package/src/data-boundary/canonical-data.ts +188 -0
- package/src/data-boundary/canonical-json.ts +11 -0
- package/src/data-boundary/closed-values.ts +126 -0
- package/src/data-boundary/value-shapes.ts +15 -0
- package/src/finding-waivers/reconciliation.ts +176 -0
- package/src/index.ts +123 -0
- package/src/machine-output/v4/atomic-publication.ts +123 -0
- package/src/machine-output/v4/freeze-publication-value.ts +12 -0
- package/src/machine-output/v4/projection.ts +36 -0
- package/src/machine-output/v4/publication-invariants.ts +89 -0
- package/src/machine-output/v4/publication-model.ts +38 -0
- package/src/machine-output/v4/publish.ts +23 -0
- package/src/machine-output/v4/records-fingerprint.ts +12 -0
- package/src/machine-output/v4/schema-identities.ts +8 -0
- package/src/machine-output/v4/schema.ts +97 -0
- package/src/machine-output/v4/serializers.ts +18 -0
- package/src/machine-output/v4/validation-result.ts +59 -0
- package/src/machine-output/v4/validation.ts +166 -0
- package/src/package-checks/code-quality-findings/policy.ts +85 -0
- package/src/package-checks/duplicate-detection/area-policy.ts +103 -0
- package/src/package-checks/duplicate-detection/cache/cache-contract.ts +49 -0
- package/src/package-checks/duplicate-detection/cache/identity.ts +61 -0
- package/src/package-checks/duplicate-detection/cache/key.ts +46 -0
- package/src/package-checks/duplicate-detection/cache/payload.ts +78 -0
- package/src/package-checks/duplicate-detection/cache/store.ts +77 -0
- package/src/package-checks/duplicate-detection/default-check.ts +50 -0
- package/src/package-checks/duplicate-detection/execution.ts +168 -0
- package/src/package-checks/duplicate-detection/final-data.ts +10 -0
- package/src/package-checks/duplicate-detection/jscpd/availability.ts +137 -0
- package/src/package-checks/duplicate-detection/jscpd/command-path.ts +8 -0
- package/src/package-checks/duplicate-detection/jscpd/command-resolution.ts +112 -0
- package/src/package-checks/duplicate-detection/jscpd/json-report.ts +137 -0
- package/src/package-checks/duplicate-detection/jscpd/scanner-contract.ts +18 -0
- package/src/package-checks/duplicate-detection/jscpd/scanner.ts +257 -0
- package/src/package-checks/duplicate-detection/jscpd/scoped-fragments.ts +17 -0
- package/src/package-checks/duplicate-detection/measurement-model.ts +44 -0
- package/src/package-checks/duplicate-detection/measurement.ts +223 -0
- package/src/package-checks/duplicate-detection/options-resolution.ts +162 -0
- package/src/package-checks/duplicate-detection/options-validation.ts +75 -0
- package/src/package-checks/duplicate-detection/options.ts +72 -0
- package/src/package-checks/duplicate-detection/project-revision.ts +5 -0
- package/src/package-checks/duplicate-detection/records.ts +171 -0
- package/src/package-checks/file-metrics/constructor.ts +46 -0
- package/src/package-checks/file-metrics/execution.ts +233 -0
- package/src/package-checks/file-metrics/final-data.ts +10 -0
- package/src/package-checks/file-metrics/measurement-model.ts +10 -0
- package/src/package-checks/file-metrics/measurement.ts +52 -0
- package/src/package-checks/file-metrics/options-resolution.ts +213 -0
- package/src/package-checks/file-metrics/options-validation.ts +104 -0
- package/src/package-checks/file-metrics/options.ts +91 -0
- package/src/package-checks/file-metrics/records.ts +182 -0
- package/src/package-checks/file-metrics/scc/availability.ts +100 -0
- package/src/package-checks/file-metrics/scc/csv.ts +20 -0
- package/src/package-checks/file-metrics/scc/parser.ts +223 -0
- package/src/package-checks/file-metrics/scc/scanner.ts +68 -0
- package/src/package-checks/final-data-parsing.ts +49 -0
- package/src/package-checks/function-metrics/analysis.ts +138 -0
- package/src/package-checks/function-metrics/constructor.ts +55 -0
- package/src/package-checks/function-metrics/execution.ts +263 -0
- package/src/package-checks/function-metrics/final-data.ts +10 -0
- package/src/package-checks/function-metrics/lizard/availability.ts +90 -0
- package/src/package-checks/function-metrics/lizard/csv.ts +20 -0
- package/src/package-checks/function-metrics/lizard/parser.ts +179 -0
- package/src/package-checks/function-metrics/lizard/scanner.ts +62 -0
- package/src/package-checks/function-metrics/measurement-model.ts +30 -0
- package/src/package-checks/function-metrics/measurement.ts +57 -0
- package/src/package-checks/function-metrics/options-resolution.ts +215 -0
- package/src/package-checks/function-metrics/options-validation.ts +89 -0
- package/src/package-checks/function-metrics/options.ts +84 -0
- package/src/package-checks/function-metrics/records.ts +254 -0
- package/src/package-checks/function-metrics/target-files.ts +85 -0
- package/src/package-checks/host-environment/error-message.ts +3 -0
- package/src/package-checks/host-environment/filesystem.ts +110 -0
- package/src/package-checks/host-environment/git.ts +68 -0
- package/src/package-checks/host-environment/path.ts +20 -0
- package/src/package-checks/host-environment/process/command.ts +21 -0
- package/src/package-checks/host-environment/process/contract.ts +56 -0
- package/src/package-checks/host-environment/process/env.ts +25 -0
- package/src/package-checks/host-environment/process/failure.ts +40 -0
- package/src/package-checks/host-environment/process/result.ts +39 -0
- package/src/package-checks/host-environment/process/runner.ts +47 -0
- package/src/package-checks/json-document/strict-document.ts +209 -0
- package/src/package-checks/json-schema-validation/default-check.ts +54 -0
- package/src/package-checks/json-schema-validation/execution-stages.ts +230 -0
- package/src/package-checks/json-schema-validation/final-data.ts +115 -0
- package/src/package-checks/json-schema-validation/issue-collector.ts +43 -0
- package/src/package-checks/json-schema-validation/json-schema-validation.ts +191 -0
- package/src/package-checks/json-schema-validation/options-resolution.ts +61 -0
- package/src/package-checks/json-schema-validation/options-validation.ts +256 -0
- package/src/package-checks/json-schema-validation/options.ts +66 -0
- package/src/package-checks/json-schema-validation/reference-resolver.ts +165 -0
- package/src/package-checks/json-schema-validation/remote-response.ts +84 -0
- package/src/package-checks/json-schema-validation/schema-engine.ts +263 -0
- package/src/package-checks/json-schema-validation/schema-policy.ts +275 -0
- package/src/package-checks/json-validation/default-check.ts +48 -0
- package/src/package-checks/json-validation/final-data.ts +46 -0
- package/src/package-checks/json-validation/json-validation.ts +212 -0
- package/src/package-checks/json-validation/options-resolution.ts +50 -0
- package/src/package-checks/json-validation/options-validation.ts +27 -0
- package/src/package-checks/json-validation/options.ts +18 -0
- package/src/package-checks/maintenance-reminders/assessment-results.ts +117 -0
- package/src/package-checks/maintenance-reminders/final-data.ts +239 -0
- package/src/package-checks/maintenance-reminders/maintenance-reminders.ts +264 -0
- package/src/package-checks/maintenance-reminders/maintenance-support.ts +67 -0
- package/src/package-checks/maintenance-reminders/measurement.ts +183 -0
- package/src/package-checks/maintenance-reminders/options-validation.ts +88 -0
- package/src/package-checks/markdown-link-validation/default-check.ts +70 -0
- package/src/package-checks/markdown-link-validation/execution.ts +325 -0
- package/src/package-checks/markdown-link-validation/filesystem-probes.ts +127 -0
- package/src/package-checks/markdown-link-validation/final-data.ts +47 -0
- package/src/package-checks/markdown-link-validation/local-resolution.ts +306 -0
- package/src/package-checks/markdown-link-validation/local-resolver.ts +51 -0
- package/src/package-checks/markdown-link-validation/markdown-parser.ts +302 -0
- package/src/package-checks/markdown-link-validation/options-resolution.ts +114 -0
- package/src/package-checks/markdown-link-validation/options-validation.ts +72 -0
- package/src/package-checks/markdown-link-validation/options.ts +50 -0
- package/src/package-checks/markdown-link-validation/records.ts +77 -0
- package/src/package-checks/markdown-link-validation/resolver-engine.ts +276 -0
- package/src/package-checks/markdown-link-validation/target-descriptor.ts +34 -0
- package/src/package-checks/markdown-link-validation/traversal-result.ts +58 -0
- package/src/package-checks/project-files/collection.ts +199 -0
- package/src/package-checks/project-files/config-glob.ts +17 -0
- package/src/package-checks/project-files/configuration.ts +152 -0
- package/src/package-checks/project-files/exact-input-measurement.ts +38 -0
- package/src/package-checks/project-files/file-fingerprint.ts +46 -0
- package/src/package-checks/project-files/gitlink-revision.ts +82 -0
- package/src/package-checks/project-files/gitlink-worktree.ts +106 -0
- package/src/package-checks/project-files/input-eligibility.ts +21 -0
- package/src/package-checks/project-files/reported-path.ts +35 -0
- package/src/package-checks/project-files/revision-paths.ts +34 -0
- package/src/package-checks/project-files/revision-worktree-files.ts +148 -0
- package/src/project-definition/check-tree/authoring.ts +332 -0
- package/src/project-definition/check-tree/materialization.ts +56 -0
- package/src/project-definition/check-tree/resolution.ts +108 -0
- package/src/project-definition/output-defaults.ts +6 -0
- package/src/project-definition/output-validation.ts +54 -0
- package/src/project-definition/project-definition-validation.ts +123 -0
- package/src/project-definition/project-definition.ts +184 -0
- package/src/project-run/aggregation.ts +90 -0
- package/src/project-run/check-execution/callback.ts +106 -0
- package/src/project-run/check-execution/dependencies.ts +70 -0
- package/src/project-run/check-execution/execution-finalization.ts +177 -0
- package/src/project-run/check-execution/execution-settlement.ts +147 -0
- package/src/project-run/check-execution/messages.ts +46 -0
- package/src/project-run/check-execution/plan.ts +46 -0
- package/src/project-run/check-execution/preflight-result.ts +131 -0
- package/src/project-run/check-execution/preflight.ts +321 -0
- package/src/project-run/check-execution/resolved-checks.ts +285 -0
- package/src/project-run/check-execution/terminal-result.ts +74 -0
- package/src/project-run/completion.ts +263 -0
- package/src/project-run/controls/contract.ts +24 -0
- package/src/project-run/controls/outputs-override-validation.ts +86 -0
- package/src/project-run/controls/validation-result.ts +12 -0
- package/src/project-run/controls/validation.ts +176 -0
- package/src/project-run/diagnostic-logging/diagnostic-detail-rendering.ts +223 -0
- package/src/project-run/diagnostic-logging/logger.ts +325 -0
- package/src/project-run/invocation-creation.ts +160 -0
- package/src/project-run/invocation.ts +303 -0
- package/src/project-run/machine-publication.ts +23 -0
- package/src/project-run/output-configuration.ts +24 -0
- package/src/project-run/output-status.ts +69 -0
- package/src/project-run/progress-rendering/presentation.ts +189 -0
- package/src/project-run/progress-rendering/renderer-formatting.ts +141 -0
- package/src/project-run/progress-rendering/renderer-lifecycle.ts +152 -0
- package/src/project-run/progress-rendering/renderer.ts +68 -0
- package/src/project-run/project-context.ts +11 -0
- package/src/project-run/result.ts +175 -0
- package/src/project-run/run.ts +50 -0
- package/src/project-run/task-scheduler/execution-state.ts +153 -0
- package/src/project-run/task-scheduler/graph-validation.ts +176 -0
- package/src/project-run/task-scheduler/graph.ts +185 -0
- package/src/project-run/task-scheduler/scheduler-admission-decision.ts +177 -0
- package/src/project-run/task-scheduler/scheduler-blocker-summary.ts +42 -0
- package/src/project-run/task-scheduler/scheduler-decision-inspection.ts +199 -0
- package/src/project-run/task-scheduler/scheduler-decision-model.ts +158 -0
- package/src/project-run/task-scheduler/scheduler-decision.ts +103 -0
- package/src/project-run/task-scheduler/scheduler.ts +228 -0
- package/third-party-licenses/momoa-3.3.12-LICENSE +201 -0
- package/types/check/check.d.ts +350 -0
- package/types/check/descriptor-validation.d.ts +18 -0
- package/types/check/descriptor.d.ts +5 -0
- package/types/check/inherited-collection.d.ts +35 -0
- package/types/check/options-snapshot.d.ts +2 -0
- package/types/check-settlement/fact-validation.d.ts +14 -0
- package/types/check-settlement/facts.d.ts +19 -0
- package/types/check-settlement/outcome-normalization.d.ts +9 -0
- package/types/check-settlement/record-store.d.ts +14 -0
- package/types/check-settlement/session.d.ts +41 -0
- package/types/data-boundary/canonical-data.d.ts +13 -0
- package/types/data-boundary/canonical-json.d.ts +6 -0
- package/types/data-boundary/closed-values.d.ts +8 -0
- package/types/data-boundary/value-shapes.d.ts +4 -0
- package/types/finding-waivers/reconciliation.d.ts +66 -0
- package/types/index.d.ts +57 -0
- package/types/machine-output/v4/atomic-publication.d.ts +9 -0
- package/types/machine-output/v4/freeze-publication-value.d.ts +6 -0
- package/types/machine-output/v4/projection.d.ts +7 -0
- package/types/machine-output/v4/publication-invariants.d.ts +3 -0
- package/types/machine-output/v4/publication-model.d.ts +15 -0
- package/types/machine-output/v4/publish.d.ts +7 -0
- package/types/machine-output/v4/records-fingerprint.d.ts +4 -0
- package/types/machine-output/v4/schema-identities.d.ts +7 -0
- package/types/machine-output/v4/schema.d.ts +44 -0
- package/types/machine-output/v4/serializers.d.ts +6 -0
- package/types/machine-output/v4/validation-result.d.ts +26 -0
- package/types/machine-output/v4/validation.d.ts +6 -0
- package/types/package-checks/code-quality-findings/policy.d.ts +20 -0
- package/types/package-checks/duplicate-detection/area-policy.d.ts +3 -0
- package/types/package-checks/duplicate-detection/cache/cache-contract.d.ts +48 -0
- package/types/package-checks/duplicate-detection/cache/identity.d.ts +17 -0
- package/types/package-checks/duplicate-detection/cache/key.d.ts +4 -0
- package/types/package-checks/duplicate-detection/cache/payload.d.ts +4 -0
- package/types/package-checks/duplicate-detection/cache/store.d.ts +18 -0
- package/types/package-checks/duplicate-detection/default-check.d.ts +11 -0
- package/types/package-checks/duplicate-detection/execution.d.ts +11 -0
- package/types/package-checks/duplicate-detection/final-data.d.ts +5 -0
- package/types/package-checks/duplicate-detection/jscpd/availability.d.ts +19 -0
- package/types/package-checks/duplicate-detection/jscpd/command-path.d.ts +1 -0
- package/types/package-checks/duplicate-detection/jscpd/command-resolution.d.ts +23 -0
- package/types/package-checks/duplicate-detection/jscpd/json-report.d.ts +2 -0
- package/types/package-checks/duplicate-detection/jscpd/scanner-contract.d.ts +11 -0
- package/types/package-checks/duplicate-detection/jscpd/scanner.d.ts +21 -0
- package/types/package-checks/duplicate-detection/jscpd/scoped-fragments.d.ts +4 -0
- package/types/package-checks/duplicate-detection/measurement-model.d.ts +36 -0
- package/types/package-checks/duplicate-detection/measurement.d.ts +14 -0
- package/types/package-checks/duplicate-detection/options-resolution.d.ts +3 -0
- package/types/package-checks/duplicate-detection/options-validation.d.ts +1 -0
- package/types/package-checks/duplicate-detection/options.d.ts +65 -0
- package/types/package-checks/duplicate-detection/project-revision.d.ts +1 -0
- package/types/package-checks/duplicate-detection/records.d.ts +22 -0
- package/types/package-checks/file-metrics/constructor.d.ts +11 -0
- package/types/package-checks/file-metrics/execution.d.ts +11 -0
- package/types/package-checks/file-metrics/final-data.d.ts +5 -0
- package/types/package-checks/file-metrics/measurement-model.d.ts +12 -0
- package/types/package-checks/file-metrics/measurement.d.ts +13 -0
- package/types/package-checks/file-metrics/options-resolution.d.ts +3 -0
- package/types/package-checks/file-metrics/options-validation.d.ts +3 -0
- package/types/package-checks/file-metrics/options.d.ts +75 -0
- package/types/package-checks/file-metrics/records.d.ts +43 -0
- package/types/package-checks/file-metrics/scc/availability.d.ts +18 -0
- package/types/package-checks/file-metrics/scc/csv.d.ts +1 -0
- package/types/package-checks/file-metrics/scc/parser.d.ts +25 -0
- package/types/package-checks/file-metrics/scc/scanner.d.ts +14 -0
- package/types/package-checks/final-data-parsing.d.ts +9 -0
- package/types/package-checks/function-metrics/analysis.d.ts +10 -0
- package/types/package-checks/function-metrics/constructor.d.ts +11 -0
- package/types/package-checks/function-metrics/execution.d.ts +7 -0
- package/types/package-checks/function-metrics/final-data.d.ts +5 -0
- package/types/package-checks/function-metrics/lizard/availability.d.ts +11 -0
- package/types/package-checks/function-metrics/lizard/csv.d.ts +1 -0
- package/types/package-checks/function-metrics/lizard/parser.d.ts +17 -0
- package/types/package-checks/function-metrics/lizard/scanner.d.ts +15 -0
- package/types/package-checks/function-metrics/measurement-model.d.ts +26 -0
- package/types/package-checks/function-metrics/measurement.d.ts +21 -0
- package/types/package-checks/function-metrics/options-resolution.d.ts +3 -0
- package/types/package-checks/function-metrics/options-validation.d.ts +3 -0
- package/types/package-checks/function-metrics/options.d.ts +76 -0
- package/types/package-checks/function-metrics/records.d.ts +37 -0
- package/types/package-checks/function-metrics/target-files.d.ts +3 -0
- package/types/package-checks/host-environment/error-message.d.ts +1 -0
- package/types/package-checks/host-environment/filesystem.d.ts +19 -0
- package/types/package-checks/host-environment/git.d.ts +13 -0
- package/types/package-checks/host-environment/path.d.ts +3 -0
- package/types/package-checks/host-environment/process/command.d.ts +7 -0
- package/types/package-checks/host-environment/process/contract.d.ts +50 -0
- package/types/package-checks/host-environment/process/env.d.ts +16 -0
- package/types/package-checks/host-environment/process/failure.d.ts +4 -0
- package/types/package-checks/host-environment/process/result.d.ts +2 -0
- package/types/package-checks/host-environment/process/runner.d.ts +3 -0
- package/types/package-checks/json-document/strict-document.d.ts +35 -0
- package/types/package-checks/json-schema-validation/default-check.d.ts +11 -0
- package/types/package-checks/json-schema-validation/execution-stages.d.ts +27 -0
- package/types/package-checks/json-schema-validation/final-data.d.ts +15 -0
- package/types/package-checks/json-schema-validation/issue-collector.d.ts +12 -0
- package/types/package-checks/json-schema-validation/json-schema-validation.d.ts +42 -0
- package/types/package-checks/json-schema-validation/options-resolution.d.ts +3 -0
- package/types/package-checks/json-schema-validation/options-validation.d.ts +2 -0
- package/types/package-checks/json-schema-validation/options.d.ts +53 -0
- package/types/package-checks/json-schema-validation/reference-resolver.d.ts +23 -0
- package/types/package-checks/json-schema-validation/remote-response.d.ts +2 -0
- package/types/package-checks/json-schema-validation/schema-engine.d.ts +33 -0
- package/types/package-checks/json-schema-validation/schema-policy.d.ts +17 -0
- package/types/package-checks/json-validation/default-check.d.ts +11 -0
- package/types/package-checks/json-validation/final-data.d.ts +10 -0
- package/types/package-checks/json-validation/json-validation.d.ts +28 -0
- package/types/package-checks/json-validation/options-resolution.d.ts +3 -0
- package/types/package-checks/json-validation/options-validation.d.ts +2 -0
- package/types/package-checks/json-validation/options.d.ts +13 -0
- package/types/package-checks/maintenance-reminders/assessment-results.d.ts +10 -0
- package/types/package-checks/maintenance-reminders/final-data.d.ts +47 -0
- package/types/package-checks/maintenance-reminders/maintenance-reminders.d.ts +111 -0
- package/types/package-checks/maintenance-reminders/maintenance-support.d.ts +7 -0
- package/types/package-checks/maintenance-reminders/measurement.d.ts +10 -0
- package/types/package-checks/maintenance-reminders/options-validation.d.ts +3 -0
- package/types/package-checks/markdown-link-validation/default-check.d.ts +27 -0
- package/types/package-checks/markdown-link-validation/execution.d.ts +12 -0
- package/types/package-checks/markdown-link-validation/filesystem-probes.d.ts +10 -0
- package/types/package-checks/markdown-link-validation/final-data.d.ts +10 -0
- package/types/package-checks/markdown-link-validation/local-resolution.d.ts +92 -0
- package/types/package-checks/markdown-link-validation/local-resolver.d.ts +5 -0
- package/types/package-checks/markdown-link-validation/markdown-parser.d.ts +37 -0
- package/types/package-checks/markdown-link-validation/options-resolution.d.ts +3 -0
- package/types/package-checks/markdown-link-validation/options-validation.d.ts +2 -0
- package/types/package-checks/markdown-link-validation/options.d.ts +43 -0
- package/types/package-checks/markdown-link-validation/records.d.ts +37 -0
- package/types/package-checks/markdown-link-validation/resolver-engine.d.ts +15 -0
- package/types/package-checks/markdown-link-validation/target-descriptor.d.ts +5 -0
- package/types/package-checks/markdown-link-validation/traversal-result.d.ts +12 -0
- package/types/package-checks/project-files/collection.d.ts +9 -0
- package/types/package-checks/project-files/config-glob.d.ts +5 -0
- package/types/package-checks/project-files/configuration.d.ts +31 -0
- package/types/package-checks/project-files/exact-input-measurement.d.ts +12 -0
- package/types/package-checks/project-files/file-fingerprint.d.ts +7 -0
- package/types/package-checks/project-files/gitlink-revision.d.ts +9 -0
- package/types/package-checks/project-files/gitlink-worktree.d.ts +26 -0
- package/types/package-checks/project-files/input-eligibility.d.ts +7 -0
- package/types/package-checks/project-files/reported-path.d.ts +1 -0
- package/types/package-checks/project-files/revision-paths.d.ts +12 -0
- package/types/package-checks/project-files/revision-worktree-files.d.ts +5 -0
- package/types/project-definition/check-tree/authoring.d.ts +41 -0
- package/types/project-definition/check-tree/materialization.d.ts +4 -0
- package/types/project-definition/check-tree/resolution.d.ts +25 -0
- package/types/project-definition/output-defaults.d.ts +14 -0
- package/types/project-definition/output-validation.d.ts +3 -0
- package/types/project-definition/project-definition-validation.d.ts +6 -0
- package/types/project-definition/project-definition.d.ts +88 -0
- package/types/project-run/aggregation.d.ts +7 -0
- package/types/project-run/check-execution/callback.d.ts +24 -0
- package/types/project-run/check-execution/dependencies.d.ts +9 -0
- package/types/project-run/check-execution/execution-finalization.d.ts +18 -0
- package/types/project-run/check-execution/execution-settlement.d.ts +41 -0
- package/types/project-run/check-execution/messages.d.ts +3 -0
- package/types/project-run/check-execution/plan.d.ts +10 -0
- package/types/project-run/check-execution/preflight-result.d.ts +23 -0
- package/types/project-run/check-execution/preflight.d.ts +27 -0
- package/types/project-run/check-execution/resolved-checks.d.ts +51 -0
- package/types/project-run/check-execution/terminal-result.d.ts +27 -0
- package/types/project-run/completion.d.ts +14 -0
- package/types/project-run/controls/contract.d.ts +24 -0
- package/types/project-run/controls/outputs-override-validation.d.ts +3 -0
- package/types/project-run/controls/validation-result.d.ts +14 -0
- package/types/project-run/controls/validation.d.ts +3 -0
- package/types/project-run/diagnostic-logging/diagnostic-detail-rendering.d.ts +11 -0
- package/types/project-run/diagnostic-logging/logger.d.ts +33 -0
- package/types/project-run/invocation-creation.d.ts +12 -0
- package/types/project-run/invocation.d.ts +34 -0
- package/types/project-run/machine-publication.d.ts +10 -0
- package/types/project-run/output-configuration.d.ts +3 -0
- package/types/project-run/output-status.d.ts +21 -0
- package/types/project-run/progress-rendering/presentation.d.ts +28 -0
- package/types/project-run/progress-rendering/renderer-formatting.d.ts +23 -0
- package/types/project-run/progress-rendering/renderer-lifecycle.d.ts +24 -0
- package/types/project-run/progress-rendering/renderer.d.ts +44 -0
- package/types/project-run/project-context.d.ts +7 -0
- package/types/project-run/result.d.ts +99 -0
- package/types/project-run/run.d.ts +18 -0
- package/types/project-run/task-scheduler/execution-state.d.ts +67 -0
- package/types/project-run/task-scheduler/graph-validation.d.ts +11 -0
- package/types/project-run/task-scheduler/graph.d.ts +40 -0
- package/types/project-run/task-scheduler/scheduler-admission-decision.d.ts +8 -0
- package/types/project-run/task-scheduler/scheduler-blocker-summary.d.ts +4 -0
- package/types/project-run/task-scheduler/scheduler-decision-inspection.d.ts +24 -0
- package/types/project-run/task-scheduler/scheduler-decision-model.d.ts +94 -0
- package/types/project-run/task-scheduler/scheduler-decision.d.ts +8 -0
- package/types/project-run/task-scheduler/scheduler.d.ts +3 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { collectProjectFiles } from "../project-files/collection.mjs";
|
|
3
|
+
import { partitionProjectFilesByEligibility } from "../project-files/input-eligibility.mjs";
|
|
4
|
+
import { createMarkdownLocalResolver } from "./local-resolver.mjs";
|
|
5
|
+
import { buildMarkdownInputRejectedRecord, buildMarkdownLinkRecordCandidate } from "./records.mjs";
|
|
6
|
+
import { settledMarkdownTraversalResult } from "./traversal-result.mjs";
|
|
7
|
+
import { validMarkdownLinkValidationOptions } from "./options-validation.mjs";
|
|
8
|
+
export const MARKDOWN_LINK_VALIDATION_CHECK_DEFINITION = {
|
|
9
|
+
checkId: "markdown-link-validation",
|
|
10
|
+
displayName: "Markdown link validation"
|
|
11
|
+
};
|
|
12
|
+
/** 验证本 Check 选中的 Markdown source 的离线本地链接完整性。 */
|
|
13
|
+
export async function executeMarkdownLinkValidation(context) {
|
|
14
|
+
if (!validMarkdownLinkValidationOptions(context.options))
|
|
15
|
+
return unavailable("invalid-options");
|
|
16
|
+
const prepared = await prepareMarkdownTraversal(context);
|
|
17
|
+
if (prepared.kind === "result")
|
|
18
|
+
return prepared.result;
|
|
19
|
+
const { rejectedInputCount, traversal, resolver } = prepared;
|
|
20
|
+
for (const candidate of traversal.candidates) {
|
|
21
|
+
context.records.report({ id: candidate.id }, candidate.data);
|
|
22
|
+
}
|
|
23
|
+
return settledMarkdownTraversalResult({
|
|
24
|
+
findingCount: traversal.candidates.length,
|
|
25
|
+
findingPolicy: context.options.findingPolicy,
|
|
26
|
+
occurrenceCount: traversal.occurrenceCount,
|
|
27
|
+
rejectedInputCount,
|
|
28
|
+
sourceFileCount: traversal.sourceFileCount,
|
|
29
|
+
targetReadCount: resolver.targetReadCount
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async function prepareMarkdownTraversal(context) {
|
|
33
|
+
if (context.signal.aborted)
|
|
34
|
+
return result(unavailable("cancelled"));
|
|
35
|
+
const created = await createMarkdownLocalResolver(context.project.root, context.options.limits.maxTargetReads);
|
|
36
|
+
if (!created.ok)
|
|
37
|
+
return result(unavailable(created.reason));
|
|
38
|
+
if (context.signal.aborted)
|
|
39
|
+
return result(unavailable("cancelled"));
|
|
40
|
+
const sourceDiscovery = discoverMarkdownSourcePaths(context.project, context.options.files);
|
|
41
|
+
if (sourceDiscovery.kind === "unavailable")
|
|
42
|
+
return result(unavailable(sourceDiscovery.reason));
|
|
43
|
+
if (sourceDiscovery.selectedPathCount === 0)
|
|
44
|
+
return result(noEligibleInput());
|
|
45
|
+
if (context.signal.aborted)
|
|
46
|
+
return result(unavailable("cancelled"));
|
|
47
|
+
reportRejectedInputs(context, sourceDiscovery.rejectedPaths);
|
|
48
|
+
const traversal = await traverseMarkdownSources(sourceDiscovery.sourcePaths, {
|
|
49
|
+
resolver: created.resolver,
|
|
50
|
+
options: context.options,
|
|
51
|
+
signal: context.signal
|
|
52
|
+
});
|
|
53
|
+
if (traversal.kind === "unavailable") {
|
|
54
|
+
return result(appendRejectedInputMessage(unavailable(traversal.reason), sourceDiscovery.rejectedPaths.length));
|
|
55
|
+
}
|
|
56
|
+
if (context.signal.aborted) {
|
|
57
|
+
return result(appendRejectedInputMessage(unavailable("cancelled"), sourceDiscovery.rejectedPaths.length));
|
|
58
|
+
}
|
|
59
|
+
return Object.freeze({
|
|
60
|
+
kind: "traversal",
|
|
61
|
+
rejectedInputCount: sourceDiscovery.rejectedPaths.length,
|
|
62
|
+
resolver: created.resolver,
|
|
63
|
+
traversal
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function result(checkResult) {
|
|
67
|
+
return Object.freeze({ kind: "result", result: checkResult });
|
|
68
|
+
}
|
|
69
|
+
function noEligibleInput() {
|
|
70
|
+
return Object.freeze({ status: "not-applicable", reason: { code: "no-eligible-input" } });
|
|
71
|
+
}
|
|
72
|
+
function discoverMarkdownSourcePaths(project, files) {
|
|
73
|
+
try {
|
|
74
|
+
const selectedPaths = collectProjectFiles(project.root, files);
|
|
75
|
+
const partition = partitionProjectFilesByEligibility(selectedPaths, isMarkdownSourcePath);
|
|
76
|
+
return Object.freeze({
|
|
77
|
+
kind: "complete",
|
|
78
|
+
rejectedPaths: partition.rejectedPaths,
|
|
79
|
+
selectedPathCount: selectedPaths.length,
|
|
80
|
+
sourcePaths: partition.acceptedPaths
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return unavailableValidation("source-unavailable");
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function reportRejectedInputs(context, paths) {
|
|
88
|
+
for (const selectedPath of paths) {
|
|
89
|
+
const record = buildMarkdownInputRejectedRecord(selectedPath);
|
|
90
|
+
context.records.report({ id: record.id }, record.data);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function appendRejectedInputMessage(checkResult, rejectedInputCount) {
|
|
94
|
+
if (rejectedInputCount === 0)
|
|
95
|
+
return checkResult;
|
|
96
|
+
return Object.freeze({
|
|
97
|
+
...checkResult,
|
|
98
|
+
messages: Object.freeze([
|
|
99
|
+
...(checkResult.messages ?? []),
|
|
100
|
+
Object.freeze({
|
|
101
|
+
code: "input-rejected",
|
|
102
|
+
level: "warning",
|
|
103
|
+
message: `${rejectedInputCount} selected markdownLinkValidation input file(s) were rejected because only .md/.markdown paths are supported; inspect this Check's Records and narrow files.include/exclude.`
|
|
104
|
+
})
|
|
105
|
+
])
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function unavailableValidation(reason) {
|
|
109
|
+
return Object.freeze({ kind: "unavailable", reason });
|
|
110
|
+
}
|
|
111
|
+
async function traverseMarkdownSources(sourcePaths, run) {
|
|
112
|
+
const candidates = [];
|
|
113
|
+
let occurrenceCount = 0;
|
|
114
|
+
let sourceFileCount = 0;
|
|
115
|
+
for (const sourcePath of sourcePaths) {
|
|
116
|
+
const sourceValidation = await validateMarkdownSource(sourcePath, occurrenceCount, run);
|
|
117
|
+
if (sourceValidation.kind === "unavailable")
|
|
118
|
+
return sourceValidation;
|
|
119
|
+
candidates.push(...sourceValidation.candidates);
|
|
120
|
+
occurrenceCount = sourceValidation.occurrenceCount;
|
|
121
|
+
sourceFileCount += 1;
|
|
122
|
+
}
|
|
123
|
+
return Object.freeze({
|
|
124
|
+
kind: "complete",
|
|
125
|
+
candidates: Object.freeze(candidates),
|
|
126
|
+
occurrenceCount,
|
|
127
|
+
sourceFileCount
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
async function validateMarkdownSource(sourcePath, occurrenceCountBeforeSource, run) {
|
|
131
|
+
if (run.signal.aborted)
|
|
132
|
+
return unavailableValidation("cancelled");
|
|
133
|
+
const sourceRead = await run.resolver.readSource(sourcePath, run.options.limits.maxMarkdownBytes);
|
|
134
|
+
if (run.signal.aborted)
|
|
135
|
+
return unavailableValidation("cancelled");
|
|
136
|
+
if (!sourceRead.ok)
|
|
137
|
+
return unavailableValidation(sourceRead.reason);
|
|
138
|
+
const candidates = [];
|
|
139
|
+
let occurrenceCount = occurrenceCountBeforeSource;
|
|
140
|
+
for (const [occurrenceIndex, occurrence] of sourceRead.source.facts.occurrences.entries()) {
|
|
141
|
+
if (run.signal.aborted)
|
|
142
|
+
return unavailableValidation("cancelled");
|
|
143
|
+
occurrenceCount += 1;
|
|
144
|
+
if (occurrenceCount > run.options.limits.maxOccurrences) {
|
|
145
|
+
return unavailableValidation("occurrence-limit-exceeded");
|
|
146
|
+
}
|
|
147
|
+
const resolution = await run.resolver.resolve({
|
|
148
|
+
source: sourceRead.source,
|
|
149
|
+
rawDestination: occurrence.rawDestination,
|
|
150
|
+
rootExternalTargetMode: run.options.rootExternalTargetMode,
|
|
151
|
+
requireExistingTargets: run.options.requireExistingTargets,
|
|
152
|
+
requireNonEmptyDirectories: run.options.requireNonEmptyDirectories,
|
|
153
|
+
validateSameDocumentAnchors: run.options.validateSameDocumentAnchors,
|
|
154
|
+
validateCrossDocumentAnchors: run.options.validateCrossDocumentAnchors,
|
|
155
|
+
maxMarkdownBytes: run.options.limits.maxMarkdownBytes
|
|
156
|
+
});
|
|
157
|
+
if (run.signal.aborted)
|
|
158
|
+
return unavailableValidation("cancelled");
|
|
159
|
+
if (resolution.kind === "unavailable")
|
|
160
|
+
return unavailableValidation(resolution.reason);
|
|
161
|
+
const candidate = buildMarkdownLinkRecordCandidate(sourceRead.source.path, occurrenceIndex, occurrence, resolution);
|
|
162
|
+
if (candidate !== undefined)
|
|
163
|
+
candidates.push(candidate);
|
|
164
|
+
}
|
|
165
|
+
return Object.freeze({
|
|
166
|
+
kind: "complete",
|
|
167
|
+
candidates: Object.freeze(candidates),
|
|
168
|
+
occurrenceCount
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function isMarkdownSourcePath(filePath) {
|
|
172
|
+
const extension = path.extname(filePath).toLowerCase();
|
|
173
|
+
return extension === ".md" || extension === ".markdown";
|
|
174
|
+
}
|
|
175
|
+
function unavailable(reason) {
|
|
176
|
+
return Object.freeze({
|
|
177
|
+
status: "unavailable",
|
|
178
|
+
reason: { code: reason },
|
|
179
|
+
messages: Object.freeze([
|
|
180
|
+
Object.freeze({ code: reason, level: "error", message: unavailableMessage(reason) })
|
|
181
|
+
])
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
function unavailableMessage(reason) {
|
|
185
|
+
return UNAVAILABLE_MESSAGES[reason];
|
|
186
|
+
}
|
|
187
|
+
const UNAVAILABLE_MESSAGES = {
|
|
188
|
+
"invalid-options": "markdownLinkValidation options are invalid; recreate the Check with markdownLinkValidation(options) or restore its complete resolved options.",
|
|
189
|
+
"project-root-unavailable": "Markdown link validation could not resolve the project root; check that the path exists and is accessible.",
|
|
190
|
+
"source-unavailable": "A selected Markdown source could not be collected, read, decoded, or contained safely; check the file source and permissions.",
|
|
191
|
+
"source-too-large": "A selected Markdown source exceeds maxMarkdownBytes; narrow the file selection or raise the bounded limit.",
|
|
192
|
+
"markdown-parse-failed": "A selected Markdown source could not be parsed completely; inspect that document's Markdown syntax and encoding.",
|
|
193
|
+
"invalid-local-destination": "A local Markdown destination could not be parsed safely; inspect the affected link destination syntax.",
|
|
194
|
+
"target-unavailable": "A local Markdown target could not be probed or read safely; check the target path, permissions, size, and encoding.",
|
|
195
|
+
"occurrence-limit-exceeded": "Markdown link validation exceeded maxOccurrences; narrow the source selection or raise the bounded limit.",
|
|
196
|
+
"target-read-limit-exceeded": "Markdown link validation exceeded maxTargetReads; narrow the source selection or raise the bounded limit.",
|
|
197
|
+
cancelled: "Markdown link validation was cancelled before it could form a complete result; inspect the caller's cancellation reason and retry if appropriate."
|
|
198
|
+
};
|
|
199
|
+
//# sourceMappingURL=execution.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution.mjs","sourceRoot":"","sources":["../../../../src/package-checks/markdown-link-validation/execution.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\n\nimport type { ResolvedMarkdownLinkValidationOptions } from \"./options.ts\";\nimport type { CheckExecutionContext, CheckResult } from \"../../check/check.ts\";\nimport { collectProjectFiles } from \"../project-files/collection.ts\";\nimport type { ProjectFileSelection } from \"../project-files/configuration.ts\";\nimport { partitionProjectFilesByEligibility } from \"../project-files/input-eligibility.ts\";\nimport {\n createMarkdownLocalResolver,\n type MarkdownLocalResolutionReason,\n type MarkdownLocalResolver,\n type MarkdownSourceReadFailureReason\n} from \"./local-resolver.ts\";\nimport type { MarkdownLinkValidationFinalData } from \"./final-data.ts\";\nimport {\n buildMarkdownInputRejectedRecord,\n buildMarkdownLinkRecordCandidate,\n type MarkdownLinkRecordCandidate\n} from \"./records.ts\";\nimport { settledMarkdownTraversalResult } from \"./traversal-result.ts\";\nimport { validMarkdownLinkValidationOptions } from \"./options-validation.ts\";\n\nexport const MARKDOWN_LINK_VALIDATION_CHECK_DEFINITION = {\n checkId: \"markdown-link-validation\",\n displayName: \"Markdown link validation\"\n} as const;\n\ninterface MarkdownLinkValidationRun {\n readonly options: ResolvedMarkdownLinkValidationOptions;\n readonly resolver: MarkdownLocalResolver;\n readonly signal: AbortSignal;\n}\n\n/** `markdown-link-validation` whole-Check unavailable outcome 的稳定 reason code。 */\nexport type MarkdownLinkValidationUnavailableReason =\n | \"invalid-options\"\n | \"cancelled\"\n | \"occurrence-limit-exceeded\"\n | \"project-root-unavailable\"\n | MarkdownLocalResolutionReason\n | MarkdownSourceReadFailureReason;\n\ntype MarkdownLinkValidationUnavailable = Readonly<{\n readonly kind: \"unavailable\";\n readonly reason: MarkdownLinkValidationUnavailableReason;\n}>;\n\ntype MarkdownSourceDiscovery =\n | Readonly<{\n readonly kind: \"complete\";\n readonly rejectedPaths: readonly string[];\n readonly selectedPathCount: number;\n readonly sourcePaths: readonly string[];\n }>\n | MarkdownLinkValidationUnavailable;\n\ntype MarkdownSourceValidation =\n | Readonly<{\n readonly kind: \"complete\";\n readonly candidates: readonly MarkdownLinkRecordCandidate[];\n readonly occurrenceCount: number;\n }>\n | MarkdownLinkValidationUnavailable;\n\ntype MarkdownLinkTraversal =\n | Readonly<{\n readonly kind: \"complete\";\n readonly candidates: readonly MarkdownLinkRecordCandidate[];\n readonly occurrenceCount: number;\n readonly sourceFileCount: number;\n }>\n | MarkdownLinkValidationUnavailable;\n\n/** 验证本 Check 选中的 Markdown source 的离线本地链接完整性。 */\nexport async function executeMarkdownLinkValidation(\n context: CheckExecutionContext<ResolvedMarkdownLinkValidationOptions>\n): Promise<CheckResult<MarkdownLinkValidationFinalData>> {\n if (!validMarkdownLinkValidationOptions(context.options)) return unavailable(\"invalid-options\");\n const prepared = await prepareMarkdownTraversal(context);\n if (prepared.kind === \"result\") return prepared.result;\n const { rejectedInputCount, traversal, resolver } = prepared;\n\n for (const candidate of traversal.candidates) {\n context.records.report({ id: candidate.id }, candidate.data);\n }\n return settledMarkdownTraversalResult({\n findingCount: traversal.candidates.length,\n findingPolicy: context.options.findingPolicy,\n occurrenceCount: traversal.occurrenceCount,\n rejectedInputCount,\n sourceFileCount: traversal.sourceFileCount,\n targetReadCount: resolver.targetReadCount\n });\n}\n\ntype PreparedMarkdownTraversal =\n | Readonly<{\n readonly kind: \"result\";\n readonly result: CheckResult<MarkdownLinkValidationFinalData>;\n }>\n | Readonly<{\n readonly kind: \"traversal\";\n readonly rejectedInputCount: number;\n readonly resolver: MarkdownLocalResolver;\n readonly traversal: Extract<MarkdownLinkTraversal, { readonly kind: \"complete\" }>;\n }>;\n\nasync function prepareMarkdownTraversal(\n context: CheckExecutionContext<ResolvedMarkdownLinkValidationOptions>\n): Promise<PreparedMarkdownTraversal> {\n if (context.signal.aborted) return result(unavailable(\"cancelled\"));\n const created = await createMarkdownLocalResolver(\n context.project.root,\n context.options.limits.maxTargetReads\n );\n if (!created.ok) return result(unavailable(created.reason));\n if (context.signal.aborted) return result(unavailable(\"cancelled\"));\n const sourceDiscovery = discoverMarkdownSourcePaths(context.project, context.options.files);\n if (sourceDiscovery.kind === \"unavailable\") return result(unavailable(sourceDiscovery.reason));\n if (sourceDiscovery.selectedPathCount === 0) return result(noEligibleInput());\n if (context.signal.aborted) return result(unavailable(\"cancelled\"));\n reportRejectedInputs(context, sourceDiscovery.rejectedPaths);\n const traversal = await traverseMarkdownSources(sourceDiscovery.sourcePaths, {\n resolver: created.resolver,\n options: context.options,\n signal: context.signal\n });\n if (traversal.kind === \"unavailable\") {\n return result(\n appendRejectedInputMessage(\n unavailable(traversal.reason),\n sourceDiscovery.rejectedPaths.length\n )\n );\n }\n if (context.signal.aborted) {\n return result(\n appendRejectedInputMessage(unavailable(\"cancelled\"), sourceDiscovery.rejectedPaths.length)\n );\n }\n return Object.freeze({\n kind: \"traversal\",\n rejectedInputCount: sourceDiscovery.rejectedPaths.length,\n resolver: created.resolver,\n traversal\n });\n}\n\nfunction result(\n checkResult: CheckResult<MarkdownLinkValidationFinalData>\n): PreparedMarkdownTraversal {\n return Object.freeze({ kind: \"result\", result: checkResult });\n}\n\nfunction noEligibleInput(): CheckResult<MarkdownLinkValidationFinalData> {\n return Object.freeze({ status: \"not-applicable\", reason: { code: \"no-eligible-input\" } });\n}\n\nfunction discoverMarkdownSourcePaths(\n project: CheckExecutionContext<ResolvedMarkdownLinkValidationOptions>[\"project\"],\n files: ProjectFileSelection\n): MarkdownSourceDiscovery {\n try {\n const selectedPaths = collectProjectFiles(project.root, files);\n const partition = partitionProjectFilesByEligibility(selectedPaths, isMarkdownSourcePath);\n return Object.freeze({\n kind: \"complete\" as const,\n rejectedPaths: partition.rejectedPaths,\n selectedPathCount: selectedPaths.length,\n sourcePaths: partition.acceptedPaths\n });\n } catch {\n return unavailableValidation(\"source-unavailable\");\n }\n}\n\nfunction reportRejectedInputs(\n context: CheckExecutionContext<ResolvedMarkdownLinkValidationOptions>,\n paths: readonly string[]\n): void {\n for (const selectedPath of paths) {\n const record = buildMarkdownInputRejectedRecord(selectedPath);\n context.records.report({ id: record.id }, record.data);\n }\n}\n\nfunction appendRejectedInputMessage(\n checkResult: CheckResult<MarkdownLinkValidationFinalData>,\n rejectedInputCount: number\n): CheckResult<MarkdownLinkValidationFinalData> {\n if (rejectedInputCount === 0) return checkResult;\n return Object.freeze({\n ...checkResult,\n messages: Object.freeze([\n ...(checkResult.messages ?? []),\n Object.freeze({\n code: \"input-rejected\",\n level: \"warning\" as const,\n message: `${rejectedInputCount} selected markdownLinkValidation input file(s) were rejected because only .md/.markdown paths are supported; inspect this Check's Records and narrow files.include/exclude.`\n })\n ])\n });\n}\n\nfunction unavailableValidation(\n reason: MarkdownLinkValidationUnavailableReason\n): MarkdownLinkValidationUnavailable {\n return Object.freeze({ kind: \"unavailable\", reason });\n}\n\nasync function traverseMarkdownSources(\n sourcePaths: readonly string[],\n run: MarkdownLinkValidationRun\n): Promise<MarkdownLinkTraversal> {\n const candidates: MarkdownLinkRecordCandidate[] = [];\n let occurrenceCount = 0;\n let sourceFileCount = 0;\n\n for (const sourcePath of sourcePaths) {\n const sourceValidation = await validateMarkdownSource(sourcePath, occurrenceCount, run);\n if (sourceValidation.kind === \"unavailable\") return sourceValidation;\n\n candidates.push(...sourceValidation.candidates);\n occurrenceCount = sourceValidation.occurrenceCount;\n sourceFileCount += 1;\n }\n\n return Object.freeze({\n kind: \"complete\" as const,\n candidates: Object.freeze(candidates),\n occurrenceCount,\n sourceFileCount\n });\n}\n\nasync function validateMarkdownSource(\n sourcePath: string,\n occurrenceCountBeforeSource: number,\n run: MarkdownLinkValidationRun\n): Promise<MarkdownSourceValidation> {\n if (run.signal.aborted) return unavailableValidation(\"cancelled\");\n const sourceRead = await run.resolver.readSource(sourcePath, run.options.limits.maxMarkdownBytes);\n if (run.signal.aborted) return unavailableValidation(\"cancelled\");\n if (!sourceRead.ok) return unavailableValidation(sourceRead.reason);\n\n const candidates: MarkdownLinkRecordCandidate[] = [];\n let occurrenceCount = occurrenceCountBeforeSource;\n for (const [occurrenceIndex, occurrence] of sourceRead.source.facts.occurrences.entries()) {\n if (run.signal.aborted) return unavailableValidation(\"cancelled\");\n occurrenceCount += 1;\n if (occurrenceCount > run.options.limits.maxOccurrences) {\n return unavailableValidation(\"occurrence-limit-exceeded\");\n }\n\n const resolution = await run.resolver.resolve({\n source: sourceRead.source,\n rawDestination: occurrence.rawDestination,\n rootExternalTargetMode: run.options.rootExternalTargetMode,\n requireExistingTargets: run.options.requireExistingTargets,\n requireNonEmptyDirectories: run.options.requireNonEmptyDirectories,\n validateSameDocumentAnchors: run.options.validateSameDocumentAnchors,\n validateCrossDocumentAnchors: run.options.validateCrossDocumentAnchors,\n maxMarkdownBytes: run.options.limits.maxMarkdownBytes\n });\n if (run.signal.aborted) return unavailableValidation(\"cancelled\");\n if (resolution.kind === \"unavailable\") return unavailableValidation(resolution.reason);\n const candidate = buildMarkdownLinkRecordCandidate(\n sourceRead.source.path,\n occurrenceIndex,\n occurrence,\n resolution\n );\n if (candidate !== undefined) candidates.push(candidate);\n }\n\n return Object.freeze({\n kind: \"complete\" as const,\n candidates: Object.freeze(candidates),\n occurrenceCount\n });\n}\n\nfunction isMarkdownSourcePath(filePath: string): boolean {\n const extension = path.extname(filePath).toLowerCase();\n return extension === \".md\" || extension === \".markdown\";\n}\n\nfunction unavailable(\n reason: MarkdownLinkValidationUnavailableReason\n): CheckResult<MarkdownLinkValidationFinalData> {\n return Object.freeze({\n status: \"unavailable\",\n reason: { code: reason },\n messages: Object.freeze([\n Object.freeze({ code: reason, level: \"error\" as const, message: unavailableMessage(reason) })\n ])\n });\n}\n\nfunction unavailableMessage(reason: MarkdownLinkValidationUnavailableReason): string {\n return UNAVAILABLE_MESSAGES[reason];\n}\n\nconst UNAVAILABLE_MESSAGES: Readonly<Record<MarkdownLinkValidationUnavailableReason, string>> = {\n \"invalid-options\":\n \"markdownLinkValidation options are invalid; recreate the Check with markdownLinkValidation(options) or restore its complete resolved options.\",\n \"project-root-unavailable\":\n \"Markdown link validation could not resolve the project root; check that the path exists and is accessible.\",\n \"source-unavailable\":\n \"A selected Markdown source could not be collected, read, decoded, or contained safely; check the file source and permissions.\",\n \"source-too-large\":\n \"A selected Markdown source exceeds maxMarkdownBytes; narrow the file selection or raise the bounded limit.\",\n \"markdown-parse-failed\":\n \"A selected Markdown source could not be parsed completely; inspect that document's Markdown syntax and encoding.\",\n \"invalid-local-destination\":\n \"A local Markdown destination could not be parsed safely; inspect the affected link destination syntax.\",\n \"target-unavailable\":\n \"A local Markdown target could not be probed or read safely; check the target path, permissions, size, and encoding.\",\n \"occurrence-limit-exceeded\":\n \"Markdown link validation exceeded maxOccurrences; narrow the source selection or raise the bounded limit.\",\n \"target-read-limit-exceeded\":\n \"Markdown link validation exceeded maxTargetReads; narrow the source selection or raise the bounded limit.\",\n cancelled:\n \"Markdown link validation was cancelled before it could form a complete result; inspect the caller's cancellation reason and retry if appropriate.\"\n};\n"]}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { lstat, open, readlink } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { isNotFound, isWithinRoot, relativeSegments } from "./local-resolution.mjs";
|
|
5
|
+
export async function probeRootContainedPath(canonicalProjectRoot, candidatePath) {
|
|
6
|
+
if (!isWithinRoot(canonicalProjectRoot, candidatePath)) {
|
|
7
|
+
return Object.freeze({ kind: "outside" });
|
|
8
|
+
}
|
|
9
|
+
let pendingSegments = relativeSegments(canonicalProjectRoot, candidatePath);
|
|
10
|
+
let currentPath = canonicalProjectRoot;
|
|
11
|
+
let symlinkHops = 0;
|
|
12
|
+
while (pendingSegments.length > 0) {
|
|
13
|
+
const segment = pendingSegments.shift();
|
|
14
|
+
if (segment === undefined) {
|
|
15
|
+
return Object.freeze({ kind: "unavailable" });
|
|
16
|
+
}
|
|
17
|
+
const nextPath = path.join(currentPath, segment);
|
|
18
|
+
let status;
|
|
19
|
+
try {
|
|
20
|
+
status = await lstat(nextPath);
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (isNotFound(error)) {
|
|
24
|
+
return Object.freeze({ kind: "missing", absolutePath: nextPath });
|
|
25
|
+
}
|
|
26
|
+
return Object.freeze({ kind: "unavailable" });
|
|
27
|
+
}
|
|
28
|
+
if (!status.isSymbolicLink()) {
|
|
29
|
+
currentPath = nextPath;
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (symlinkHops >= 40) {
|
|
33
|
+
return Object.freeze({ kind: "unavailable" });
|
|
34
|
+
}
|
|
35
|
+
symlinkHops += 1;
|
|
36
|
+
let linkDestination;
|
|
37
|
+
try {
|
|
38
|
+
linkDestination = path.resolve(path.dirname(nextPath), await readlink(nextPath));
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return Object.freeze({ kind: "unavailable" });
|
|
42
|
+
}
|
|
43
|
+
if (!isWithinRoot(canonicalProjectRoot, linkDestination)) {
|
|
44
|
+
return Object.freeze({ kind: "outside" });
|
|
45
|
+
}
|
|
46
|
+
pendingSegments = [
|
|
47
|
+
...relativeSegments(canonicalProjectRoot, linkDestination),
|
|
48
|
+
...pendingSegments
|
|
49
|
+
];
|
|
50
|
+
currentPath = canonicalProjectRoot;
|
|
51
|
+
}
|
|
52
|
+
return Object.freeze({ kind: "contained", absolutePath: currentPath });
|
|
53
|
+
}
|
|
54
|
+
export async function probeEndpoint(targetPath) {
|
|
55
|
+
let status;
|
|
56
|
+
try {
|
|
57
|
+
status = await lstat(targetPath);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
return isNotFound(error)
|
|
61
|
+
? Object.freeze({ kind: "missing" })
|
|
62
|
+
: Object.freeze({ kind: "unavailable" });
|
|
63
|
+
}
|
|
64
|
+
if (status.isSymbolicLink()) {
|
|
65
|
+
return Object.freeze({ kind: "unavailable" });
|
|
66
|
+
}
|
|
67
|
+
if (status.isDirectory()) {
|
|
68
|
+
return Object.freeze({ kind: "directory" });
|
|
69
|
+
}
|
|
70
|
+
if (status.isFile()) {
|
|
71
|
+
return Object.freeze({ kind: "file" });
|
|
72
|
+
}
|
|
73
|
+
return Object.freeze({ kind: "unsupported" });
|
|
74
|
+
}
|
|
75
|
+
export async function readRegularFile(filePath, maxBytes) {
|
|
76
|
+
let handle;
|
|
77
|
+
try {
|
|
78
|
+
handle = await open(filePath, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
|
|
79
|
+
const status = await handle.stat();
|
|
80
|
+
if (!status.isFile()) {
|
|
81
|
+
return Object.freeze({ ok: false, reason: "unavailable" });
|
|
82
|
+
}
|
|
83
|
+
if (status.size > maxBytes) {
|
|
84
|
+
return Object.freeze({ ok: false, reason: "too-large" });
|
|
85
|
+
}
|
|
86
|
+
const bytes = await readBoundedBytes(handle, maxBytes);
|
|
87
|
+
return bytes === null
|
|
88
|
+
? Object.freeze({ ok: false, reason: "too-large" })
|
|
89
|
+
: Object.freeze({ ok: true, bytes });
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return Object.freeze({ ok: false, reason: "unavailable" });
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
await handle?.close().catch(() => undefined);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
async function readBoundedBytes(handle, maxBytes) {
|
|
99
|
+
const bytes = new Uint8Array(maxBytes + 1);
|
|
100
|
+
let offset = 0;
|
|
101
|
+
while (offset < bytes.byteLength) {
|
|
102
|
+
const result = await handle.read(bytes, offset, bytes.byteLength - offset, offset);
|
|
103
|
+
if (result.bytesRead === 0)
|
|
104
|
+
break;
|
|
105
|
+
offset += result.bytesRead;
|
|
106
|
+
}
|
|
107
|
+
return offset > maxBytes ? null : bytes.slice(0, offset);
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=filesystem-probes.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem-probes.mjs","sourceRoot":"","sources":["../../../../src/package-checks/markdown-link-validation/filesystem-probes.ts"],"names":[],"mappings":"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","sourcesContent":["import { constants } from \"node:fs\";\nimport { lstat, open, readlink } from \"node:fs/promises\";\nimport path from \"node:path\";\n\nimport {\n isNotFound,\n isWithinRoot,\n relativeSegments,\n type EndpointProbe,\n type RootProbe\n} from \"./local-resolution.ts\";\n\nexport async function probeRootContainedPath(\n canonicalProjectRoot: string,\n candidatePath: string\n): Promise<RootProbe> {\n if (!isWithinRoot(canonicalProjectRoot, candidatePath)) {\n return Object.freeze({ kind: \"outside\" as const });\n }\n let pendingSegments = relativeSegments(canonicalProjectRoot, candidatePath);\n let currentPath = canonicalProjectRoot;\n let symlinkHops = 0;\n\n while (pendingSegments.length > 0) {\n const segment = pendingSegments.shift();\n if (segment === undefined) {\n return Object.freeze({ kind: \"unavailable\" as const });\n }\n const nextPath = path.join(currentPath, segment);\n let status: Awaited<ReturnType<typeof lstat>>;\n try {\n status = await lstat(nextPath);\n } catch (error: unknown) {\n if (isNotFound(error)) {\n return Object.freeze({ kind: \"missing\" as const, absolutePath: nextPath });\n }\n return Object.freeze({ kind: \"unavailable\" as const });\n }\n if (!status.isSymbolicLink()) {\n currentPath = nextPath;\n continue;\n }\n if (symlinkHops >= 40) {\n return Object.freeze({ kind: \"unavailable\" as const });\n }\n symlinkHops += 1;\n let linkDestination: string;\n try {\n linkDestination = path.resolve(path.dirname(nextPath), await readlink(nextPath));\n } catch {\n return Object.freeze({ kind: \"unavailable\" as const });\n }\n if (!isWithinRoot(canonicalProjectRoot, linkDestination)) {\n return Object.freeze({ kind: \"outside\" as const });\n }\n pendingSegments = [\n ...relativeSegments(canonicalProjectRoot, linkDestination),\n ...pendingSegments\n ];\n currentPath = canonicalProjectRoot;\n }\n\n return Object.freeze({ kind: \"contained\" as const, absolutePath: currentPath });\n}\n\nexport async function probeEndpoint(targetPath: string): Promise<EndpointProbe> {\n let status: Awaited<ReturnType<typeof lstat>>;\n try {\n status = await lstat(targetPath);\n } catch (error: unknown) {\n return isNotFound(error)\n ? Object.freeze({ kind: \"missing\" as const })\n : Object.freeze({ kind: \"unavailable\" as const });\n }\n if (status.isSymbolicLink()) {\n return Object.freeze({ kind: \"unavailable\" as const });\n }\n if (status.isDirectory()) {\n return Object.freeze({ kind: \"directory\" as const });\n }\n if (status.isFile()) {\n return Object.freeze({ kind: \"file\" as const });\n }\n return Object.freeze({ kind: \"unsupported\" as const });\n}\n\nexport async function readRegularFile(\n filePath: string,\n maxBytes: number\n): Promise<\n | Readonly<{ readonly ok: true; readonly bytes: Uint8Array }>\n | Readonly<{ readonly ok: false; readonly reason: \"too-large\" | \"unavailable\" }>\n> {\n let handle: Awaited<ReturnType<typeof open>> | undefined;\n try {\n handle = await open(filePath, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));\n const status = await handle.stat();\n if (!status.isFile()) {\n return Object.freeze({ ok: false as const, reason: \"unavailable\" as const });\n }\n if (status.size > maxBytes) {\n return Object.freeze({ ok: false as const, reason: \"too-large\" as const });\n }\n const bytes = await readBoundedBytes(handle, maxBytes);\n return bytes === null\n ? Object.freeze({ ok: false as const, reason: \"too-large\" as const })\n : Object.freeze({ ok: true as const, bytes });\n } catch {\n return Object.freeze({ ok: false as const, reason: \"unavailable\" as const });\n } finally {\n await handle?.close().catch(() => undefined);\n }\n}\n\nasync function readBoundedBytes(\n handle: Awaited<ReturnType<typeof open>>,\n maxBytes: number\n): Promise<Uint8Array | null> {\n const bytes = new Uint8Array(maxBytes + 1);\n let offset = 0;\n while (offset < bytes.byteLength) {\n const result = await handle.read(bytes, offset, bytes.byteLength - offset, offset);\n if (result.bytesRead === 0) break;\n offset += result.bytesRead;\n }\n return offset > maxBytes ? null : bytes.slice(0, offset);\n}\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { exactFinalDataRecord, invalidFinalData, nonNegativeSafeInteger } from "../final-data-parsing.mjs";
|
|
2
|
+
/** 验证计数不变量并脱离一份 canonical final-data object。 */
|
|
3
|
+
export function parseMarkdownLinkValidationData(data) {
|
|
4
|
+
const value = exactFinalDataRecord(data, ["sourceFileCount", "occurrenceCount", "targetReadCount", "findingCount", "rejectedInputCount"], "markdownLinkValidation");
|
|
5
|
+
const sourceFileCount = nonNegativeSafeInteger(value.sourceFileCount);
|
|
6
|
+
const occurrenceCount = nonNegativeSafeInteger(value.occurrenceCount);
|
|
7
|
+
const targetReadCount = nonNegativeSafeInteger(value.targetReadCount);
|
|
8
|
+
const findingCount = nonNegativeSafeInteger(value.findingCount);
|
|
9
|
+
const rejectedInputCount = nonNegativeSafeInteger(value.rejectedInputCount);
|
|
10
|
+
if (sourceFileCount === undefined ||
|
|
11
|
+
occurrenceCount === undefined ||
|
|
12
|
+
targetReadCount === undefined ||
|
|
13
|
+
findingCount === undefined ||
|
|
14
|
+
rejectedInputCount === undefined ||
|
|
15
|
+
targetReadCount > occurrenceCount ||
|
|
16
|
+
findingCount < rejectedInputCount ||
|
|
17
|
+
findingCount - rejectedInputCount > occurrenceCount) {
|
|
18
|
+
throw invalidFinalData("markdownLinkValidation");
|
|
19
|
+
}
|
|
20
|
+
return Object.freeze({
|
|
21
|
+
sourceFileCount,
|
|
22
|
+
occurrenceCount,
|
|
23
|
+
targetReadCount,
|
|
24
|
+
findingCount,
|
|
25
|
+
rejectedInputCount
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=final-data.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"final-data.mjs","sourceRoot":"","sources":["../../../../src/package-checks/markdown-link-validation/final-data.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACvB,MAAM,0BAA0B,CAAC;AAWlC,gDAAgD;AAChD,MAAM,UAAU,+BAA+B,CAAC,IAAa;IAC3D,MAAM,KAAK,GAAG,oBAAoB,CAChC,IAAI,EACJ,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,oBAAoB,CAAC,EAC/F,wBAAwB,CACzB,CAAC;IACF,MAAM,eAAe,GAAG,sBAAsB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACtE,MAAM,eAAe,GAAG,sBAAsB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACtE,MAAM,eAAe,GAAG,sBAAsB,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACtE,MAAM,YAAY,GAAG,sBAAsB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAChE,MAAM,kBAAkB,GAAG,sBAAsB,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAC5E,IACE,eAAe,KAAK,SAAS;QAC7B,eAAe,KAAK,SAAS;QAC7B,eAAe,KAAK,SAAS;QAC7B,YAAY,KAAK,SAAS;QAC1B,kBAAkB,KAAK,SAAS;QAChC,eAAe,GAAG,eAAe;QACjC,YAAY,GAAG,kBAAkB;QACjC,YAAY,GAAG,kBAAkB,GAAG,eAAe,EACnD,CAAC;QACD,MAAM,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,eAAe;QACf,eAAe;QACf,eAAe;QACf,YAAY;QACZ,kBAAkB;KACnB,CAAC,CAAC;AACL,CAAC","sourcesContent":["import {\n exactFinalDataRecord,\n invalidFinalData,\n nonNegativeSafeInteger\n} from \"../final-data-parsing.ts\";\n\n/** `markdown-link-validation` 在 passed/failed outcome 中发布的主数据。 */\nexport interface MarkdownLinkValidationFinalData {\n readonly sourceFileCount: number;\n readonly occurrenceCount: number;\n readonly targetReadCount: number;\n readonly findingCount: number;\n readonly rejectedInputCount: number;\n}\n\n/** 验证计数不变量并脱离一份 canonical final-data object。 */\nexport function parseMarkdownLinkValidationData(data: unknown): MarkdownLinkValidationFinalData {\n const value = exactFinalDataRecord(\n data,\n [\"sourceFileCount\", \"occurrenceCount\", \"targetReadCount\", \"findingCount\", \"rejectedInputCount\"],\n \"markdownLinkValidation\"\n );\n const sourceFileCount = nonNegativeSafeInteger(value.sourceFileCount);\n const occurrenceCount = nonNegativeSafeInteger(value.occurrenceCount);\n const targetReadCount = nonNegativeSafeInteger(value.targetReadCount);\n const findingCount = nonNegativeSafeInteger(value.findingCount);\n const rejectedInputCount = nonNegativeSafeInteger(value.rejectedInputCount);\n if (\n sourceFileCount === undefined ||\n occurrenceCount === undefined ||\n targetReadCount === undefined ||\n findingCount === undefined ||\n rejectedInputCount === undefined ||\n targetReadCount > occurrenceCount ||\n findingCount < rejectedInputCount ||\n findingCount - rejectedInputCount > occurrenceCount\n ) {\n throw invalidFinalData(\"markdownLinkValidation\");\n }\n return Object.freeze({\n sourceFileCount,\n occurrenceCount,\n targetReadCount,\n findingCount,\n rejectedInputCount\n });\n}\n"]}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
const NOT_LOCAL_FILE_URI = Symbol("not-local-file-uri");
|
|
3
|
+
export function parseLocalDestination(rawDestination) {
|
|
4
|
+
if (rawDestination.startsWith("//") || rawDestination.startsWith("\\\\")) {
|
|
5
|
+
return "not-local";
|
|
6
|
+
}
|
|
7
|
+
if (isHostWindowsDriveAbsolute(rawDestination)) {
|
|
8
|
+
return parsePathAndFragment(rawDestination, false);
|
|
9
|
+
}
|
|
10
|
+
const scheme = /^([A-Za-z][A-Za-z\d+.-]*):/u.exec(rawDestination);
|
|
11
|
+
if (scheme !== null) {
|
|
12
|
+
if (scheme[1]?.toLowerCase() !== "file") {
|
|
13
|
+
return "not-local";
|
|
14
|
+
}
|
|
15
|
+
return parseFileDestination(rawDestination);
|
|
16
|
+
}
|
|
17
|
+
if (path.sep !== "\\" && /^[A-Za-z]:[\\/]/u.test(rawDestination)) {
|
|
18
|
+
return "not-local";
|
|
19
|
+
}
|
|
20
|
+
return parsePathAndFragment(rawDestination, false);
|
|
21
|
+
}
|
|
22
|
+
function parseFileDestination(rawDestination) {
|
|
23
|
+
const match = /^file:\/\/(\/.*)$/iu.exec(rawDestination);
|
|
24
|
+
if (match === null) {
|
|
25
|
+
return "not-local";
|
|
26
|
+
}
|
|
27
|
+
const uriPathAndFragment = match[1];
|
|
28
|
+
if (uriPathAndFragment === undefined || uriPathAndFragment.startsWith("//")) {
|
|
29
|
+
return "not-local";
|
|
30
|
+
}
|
|
31
|
+
if (hasUriQuery(uriPathAndFragment) || containsUnsafeRawFileCharacter(uriPathAndFragment)) {
|
|
32
|
+
return "not-local";
|
|
33
|
+
}
|
|
34
|
+
const parsed = parsePathAndFragment(uriPathAndFragment, true);
|
|
35
|
+
if (parsed === null || parsed === "not-local") {
|
|
36
|
+
return parsed;
|
|
37
|
+
}
|
|
38
|
+
return Object.freeze({ ...parsed, isAbsolute: true });
|
|
39
|
+
}
|
|
40
|
+
function parsePathAndFragment(rawDestination, isFileUri) {
|
|
41
|
+
const hashIndex = rawDestination.indexOf("#");
|
|
42
|
+
const queryIndex = rawDestination.indexOf("?");
|
|
43
|
+
const pathEnd = [hashIndex, queryIndex]
|
|
44
|
+
.filter((index) => index >= 0)
|
|
45
|
+
.reduce((smallest, index) => Math.min(smallest, index), rawDestination.length);
|
|
46
|
+
const rawPath = rawDestination.slice(0, pathEnd);
|
|
47
|
+
const rawFragment = hashIndex >= 0 ? rawDestination.slice(hashIndex + 1) : null;
|
|
48
|
+
const decodedPath = decodeLocalComponent(rawPath);
|
|
49
|
+
const decodedFragment = rawFragment === null ? null : decodeLocalComponent(rawFragment);
|
|
50
|
+
if (decodedPath === null || (decodedFragment === null && rawFragment !== null)) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const resolvedPath = isFileUri ? hostFileUriPath(decodedPath) : decodedPath;
|
|
54
|
+
if (resolvedPath === null)
|
|
55
|
+
return null;
|
|
56
|
+
if (resolvedPath === NOT_LOCAL_FILE_URI)
|
|
57
|
+
return "not-local";
|
|
58
|
+
return Object.freeze({
|
|
59
|
+
path: resolvedPath,
|
|
60
|
+
fragment: decodedFragment,
|
|
61
|
+
isAbsolute: isFileUri || path.isAbsolute(resolvedPath)
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function decodeLocalComponent(rawComponent) {
|
|
65
|
+
if (containsControlCharacter(rawComponent) || /%(?:2f|5c|00|0[0-9a-f]|7f)/iu.test(rawComponent)) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const decoded = decodeURIComponent(rawComponent);
|
|
70
|
+
return containsControlCharacter(decoded) ? null : decoded;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function isHostWindowsDriveAbsolute(value) {
|
|
77
|
+
return path.sep === "\\" && /^[A-Za-z]:[\\/]/u.test(value);
|
|
78
|
+
}
|
|
79
|
+
function hostFileUriPath(decodedPath) {
|
|
80
|
+
if (decodedPath.includes("\\"))
|
|
81
|
+
return null;
|
|
82
|
+
if (path.sep === "\\") {
|
|
83
|
+
if (!/^\/[A-Za-z]:\//u.test(decodedPath))
|
|
84
|
+
return NOT_LOCAL_FILE_URI;
|
|
85
|
+
return path.normalize(decodedPath.slice(1));
|
|
86
|
+
}
|
|
87
|
+
if (/^\/[A-Za-z]:\//u.test(decodedPath))
|
|
88
|
+
return NOT_LOCAL_FILE_URI;
|
|
89
|
+
return path.isAbsolute(decodedPath) ? decodedPath : null;
|
|
90
|
+
}
|
|
91
|
+
function hasUriQuery(uriPathAndFragment) {
|
|
92
|
+
const queryIndex = uriPathAndFragment.indexOf("?");
|
|
93
|
+
if (queryIndex < 0)
|
|
94
|
+
return false;
|
|
95
|
+
const fragmentIndex = uriPathAndFragment.indexOf("#");
|
|
96
|
+
return fragmentIndex < 0 || queryIndex < fragmentIndex;
|
|
97
|
+
}
|
|
98
|
+
export function anchorResolution(headings, fragment, target) {
|
|
99
|
+
return headings.some((heading) => heading.slug === fragment)
|
|
100
|
+
? valid(target)
|
|
101
|
+
: finding("missing-anchor", target);
|
|
102
|
+
}
|
|
103
|
+
export function isRootRelativePath(canonicalProjectRoot, rootRelativePath) {
|
|
104
|
+
return (!path.isAbsolute(rootRelativePath) &&
|
|
105
|
+
isWithinRoot(canonicalProjectRoot, path.resolve(canonicalProjectRoot, rootRelativePath)));
|
|
106
|
+
}
|
|
107
|
+
export function isWithinRoot(root, candidate) {
|
|
108
|
+
const relativePath = path.relative(root, candidate);
|
|
109
|
+
return (relativePath === "" ||
|
|
110
|
+
(!relativePath.startsWith(`..${path.sep}`) &&
|
|
111
|
+
relativePath !== ".." &&
|
|
112
|
+
!path.isAbsolute(relativePath)));
|
|
113
|
+
}
|
|
114
|
+
export function relativeSegments(root, candidate) {
|
|
115
|
+
const relativePath = path.relative(root, candidate);
|
|
116
|
+
return relativePath === ""
|
|
117
|
+
? []
|
|
118
|
+
: relativePath.split(path.sep).filter((segment) => segment !== "");
|
|
119
|
+
}
|
|
120
|
+
export function sameRootRelativePath(rootRelativePath, targetPath, canonicalProjectRoot) {
|
|
121
|
+
return toSlashPath(path.relative(canonicalProjectRoot, targetPath)) === rootRelativePath;
|
|
122
|
+
}
|
|
123
|
+
export function isMarkdownPath(targetPath) {
|
|
124
|
+
const extension = path.extname(targetPath).toLowerCase();
|
|
125
|
+
return extension === ".md" || extension === ".markdown";
|
|
126
|
+
}
|
|
127
|
+
export function toSlashPath(filePath) {
|
|
128
|
+
return filePath.split(path.sep).join("/");
|
|
129
|
+
}
|
|
130
|
+
function containsUnsafeRawFileCharacter(value) {
|
|
131
|
+
return value.includes("\\") || containsControlCharacter(value) || /\s/u.test(value);
|
|
132
|
+
}
|
|
133
|
+
function containsControlCharacter(value) {
|
|
134
|
+
for (const character of value) {
|
|
135
|
+
const codePoint = character.codePointAt(0);
|
|
136
|
+
if (codePoint !== undefined &&
|
|
137
|
+
(codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f))) {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
export function isNotFound(error) {
|
|
144
|
+
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
145
|
+
}
|
|
146
|
+
export function sourceUnavailable() {
|
|
147
|
+
return Object.freeze({ ok: false, reason: "source-unavailable" });
|
|
148
|
+
}
|
|
149
|
+
export function valid(target) {
|
|
150
|
+
return Object.freeze({ kind: "valid", target });
|
|
151
|
+
}
|
|
152
|
+
export function finding(reason, target) {
|
|
153
|
+
return Object.freeze({ kind: "finding", reason, target });
|
|
154
|
+
}
|
|
155
|
+
export function unavailable(reason) {
|
|
156
|
+
return Object.freeze({ kind: "unavailable", reason });
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=local-resolution.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-resolution.mjs","sourceRoot":"","sources":["../../../../src/package-checks/markdown-link-validation/local-resolution.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,MAAM,kBAAkB,GAAkB,MAAM,CAAC,oBAAoB,CAAC,CAAC;AA6FvE,MAAM,UAAU,qBAAqB,CACnC,cAAsB;IAEtB,IAAI,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACzE,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IAAI,0BAA0B,CAAC,cAAc,CAAC,EAAE,CAAC;QAC/C,OAAO,oBAAoB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,MAAM,GAAG,6BAA6B,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAClE,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;YACxC,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,OAAO,oBAAoB,CAAC,cAAc,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,kBAAkB,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;QACjE,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,OAAO,oBAAoB,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;AACrD,CAAC;AAED,SAAS,oBAAoB,CAAC,cAAsB;IAClD,MAAM,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACzD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,MAAM,kBAAkB,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACpC,IAAI,kBAAkB,KAAK,SAAS,IAAI,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5E,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,IAAI,WAAW,CAAC,kBAAkB,CAAC,IAAI,8BAA8B,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC1F,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,MAAM,MAAM,GAAG,oBAAoB,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;IAC9D,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;QAC9C,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,oBAAoB,CAC3B,cAAsB,EACtB,SAAkB;IAElB,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC;SACpC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC;SAC7B,MAAM,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACjF,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACjD,MAAM,WAAW,GAAG,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAChF,MAAM,WAAW,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,eAAe,GAAG,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACxF,IAAI,WAAW,KAAK,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI,IAAI,WAAW,KAAK,IAAI,CAAC,EAAE,CAAC;QAC/E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;IAC5E,IAAI,YAAY,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,YAAY,KAAK,kBAAkB;QAAE,OAAO,WAAW,CAAC;IAC5D,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,YAAY;QAClB,QAAQ,EAAE,eAAe;QACzB,UAAU,EAAE,SAAS,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC;KACvD,CAAC,CAAC;AACL,CAAC;AAED,SAAS,oBAAoB,CAAC,YAAoB;IAChD,IAAI,wBAAwB,CAAC,YAAY,CAAC,IAAI,8BAA8B,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QAChG,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,kBAAkB,CAAC,YAAY,CAAC,CAAC;QACjD,OAAO,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,0BAA0B,CAAC,KAAa;IAC/C,OAAO,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,eAAe,CAAC,WAAmB;IAC1C,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC;YAAE,OAAO,kBAAkB,CAAC;QACpE,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC;QAAE,OAAO,kBAAkB,CAAC;IACnE,OAAO,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3D,CAAC;AAED,SAAS,WAAW,CAAC,kBAA0B;IAC7C,MAAM,UAAU,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnD,IAAI,UAAU,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACjC,MAAM,aAAa,GAAG,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtD,OAAO,aAAa,GAAG,CAAC,IAAI,UAAU,GAAG,aAAa,CAAC;AACzD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,QAAoC,EACpC,QAAgB,EAChB,MAAoC;IAEpC,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC;QAC1D,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;QACf,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,oBAA4B,EAC5B,gBAAwB;IAExB,OAAO,CACL,CAAC,IAAI,CAAC,UAAU,CAAC,gBAAgB,CAAC;QAClC,YAAY,CAAC,oBAAoB,EAAE,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,gBAAgB,CAAC,CAAC,CACzF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,SAAiB;IAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACpD,OAAO,CACL,YAAY,KAAK,EAAE;QACnB,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,CAAC;YACxC,YAAY,KAAK,IAAI;YACrB,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAClC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,SAAiB;IAC9D,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACpD,OAAO,YAAY,KAAK,EAAE;QACxB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,gBAAwB,EACxB,UAAkB,EAClB,oBAA4B;IAE5B,OAAO,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC,KAAK,gBAAgB,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;IACzD,OAAO,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,WAAW,CAAC;AAC1D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,8BAA8B,CAAC,KAAa;IACnD,OAAO,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,wBAAwB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAa;IAC7C,KAAK,MAAM,SAAS,IAAI,KAAK,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;QAC3C,IACE,SAAS,KAAK,SAAS;YACvB,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,IAAI,SAAS,IAAI,IAAI,CAAC,CAAC,EAC/D,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;AACnG,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAc,EAAE,MAAM,EAAE,oBAA6B,EAAE,CAAC,CAAC;AACtF,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,MAAoC;IACxD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAgB,EAAE,MAAM,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,MAAiC,EACjC,MAAoC;IAEpC,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAqC;IAC/D,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,aAAsB,EAAE,MAAM,EAAE,CAAC,CAAC;AACjE,CAAC","sourcesContent":["import path from \"node:path\";\n\nimport type { MarkdownHeading, ParsedMarkdownLinkFacts } from \"./markdown-parser.ts\";\n\ntype RootExternalTargetMode = \"ignore\" | \"report\" | \"validate\";\nconst NOT_LOCAL_FILE_URI: unique symbol = Symbol(\"not-local-file-uri\");\n\n/** Markdown local-link finding Record 的稳定 reason。 */\nexport type MarkdownLinkFindingReason =\n | \"anchor-on-directory\"\n | \"anchor-target-not-markdown\"\n | \"empty-directory\"\n | \"missing-anchor\"\n | \"missing-target\"\n | \"target-outside-project-root\"\n | \"unsupported-target-type\";\n\ntype MarkdownLocalResolutionReason =\n | \"invalid-local-destination\"\n | \"target-read-limit-exceeded\"\n | \"target-unavailable\";\n\ntype MarkdownSourceReadFailureReason =\n | \"markdown-parse-failed\"\n | \"source-unavailable\"\n | \"source-too-large\";\n\ninterface MarkdownLinkSource {\n readonly path: string;\n readonly facts: ParsedMarkdownLinkFacts;\n}\n\ninterface MarkdownLocalResolver {\n readSource(rootRelativePath: string, maxMarkdownBytes: number): Promise<MarkdownSourceReadResult>;\n resolve(request: MarkdownLocalResolutionRequest): Promise<MarkdownLocalResolution>;\n readonly targetReadCount: number;\n}\n\ninterface MarkdownLocalResolutionRequest {\n readonly source: MarkdownLinkSource;\n readonly rawDestination: string;\n readonly rootExternalTargetMode: RootExternalTargetMode;\n readonly requireExistingTargets: boolean;\n readonly requireNonEmptyDirectories: boolean;\n readonly validateSameDocumentAnchors: boolean;\n readonly validateCrossDocumentAnchors: boolean;\n readonly maxMarkdownBytes: number;\n}\n\ntype MarkdownLocalResolverCreation =\n | Readonly<{ readonly ok: true; readonly resolver: MarkdownLocalResolver }>\n | Readonly<{ readonly ok: false; readonly reason: \"project-root-unavailable\" }>;\n\ntype MarkdownSourceReadResult =\n | Readonly<{ readonly ok: true; readonly source: MarkdownLinkSource }>\n | Readonly<{\n readonly ok: false;\n readonly reason: MarkdownSourceReadFailureReason;\n }>;\n\ntype MarkdownLocalResolution =\n | Readonly<{ readonly kind: \"not-local\" | \"ignored\" }>\n | Readonly<{ readonly kind: \"valid\"; readonly target: MarkdownSafeTargetDescriptor }>\n | Readonly<{\n readonly kind: \"finding\";\n readonly reason: MarkdownLinkFindingReason;\n readonly target: MarkdownSafeTargetDescriptor;\n }>\n | Readonly<{ readonly kind: \"unavailable\"; readonly reason: MarkdownLocalResolutionReason }>;\n\ntype MarkdownSafeTargetDescriptor =\n | Readonly<{\n readonly kind: \"same-document\" | \"project-file\" | \"project-directory\" | \"project-path\";\n readonly path: string;\n readonly fragment: string | null;\n }>\n | Readonly<{ readonly kind: \"outside-project-root\" }>;\n\ninterface ParsedLocalDestination {\n readonly path: string;\n readonly fragment: string | null;\n readonly isAbsolute: boolean;\n}\n\ninterface RootContainedPath {\n readonly kind: \"contained\" | \"missing\";\n readonly absolutePath: string;\n}\n\ntype RootProbe =\n | RootContainedPath\n | Readonly<{ readonly kind: \"outside\" }>\n | Readonly<{ readonly kind: \"unavailable\" }>;\n\ntype EndpointProbe =\n | Readonly<{ readonly kind: \"missing\" }>\n | Readonly<{ readonly kind: \"directory\" | \"file\" | \"unsupported\" | \"unavailable\" }>;\n\nexport function parseLocalDestination(\n rawDestination: string\n): ParsedLocalDestination | \"not-local\" | null {\n if (rawDestination.startsWith(\"//\") || rawDestination.startsWith(\"\\\\\\\\\")) {\n return \"not-local\";\n }\n if (isHostWindowsDriveAbsolute(rawDestination)) {\n return parsePathAndFragment(rawDestination, false);\n }\n const scheme = /^([A-Za-z][A-Za-z\\d+.-]*):/u.exec(rawDestination);\n if (scheme !== null) {\n if (scheme[1]?.toLowerCase() !== \"file\") {\n return \"not-local\";\n }\n return parseFileDestination(rawDestination);\n }\n if (path.sep !== \"\\\\\" && /^[A-Za-z]:[\\\\/]/u.test(rawDestination)) {\n return \"not-local\";\n }\n return parsePathAndFragment(rawDestination, false);\n}\n\nfunction parseFileDestination(rawDestination: string): ParsedLocalDestination | \"not-local\" | null {\n const match = /^file:\\/\\/(\\/.*)$/iu.exec(rawDestination);\n if (match === null) {\n return \"not-local\";\n }\n const uriPathAndFragment = match[1];\n if (uriPathAndFragment === undefined || uriPathAndFragment.startsWith(\"//\")) {\n return \"not-local\";\n }\n if (hasUriQuery(uriPathAndFragment) || containsUnsafeRawFileCharacter(uriPathAndFragment)) {\n return \"not-local\";\n }\n const parsed = parsePathAndFragment(uriPathAndFragment, true);\n if (parsed === null || parsed === \"not-local\") {\n return parsed;\n }\n return Object.freeze({ ...parsed, isAbsolute: true });\n}\n\nfunction parsePathAndFragment(\n rawDestination: string,\n isFileUri: boolean\n): ParsedLocalDestination | \"not-local\" | null {\n const hashIndex = rawDestination.indexOf(\"#\");\n const queryIndex = rawDestination.indexOf(\"?\");\n const pathEnd = [hashIndex, queryIndex]\n .filter((index) => index >= 0)\n .reduce((smallest, index) => Math.min(smallest, index), rawDestination.length);\n const rawPath = rawDestination.slice(0, pathEnd);\n const rawFragment = hashIndex >= 0 ? rawDestination.slice(hashIndex + 1) : null;\n const decodedPath = decodeLocalComponent(rawPath);\n const decodedFragment = rawFragment === null ? null : decodeLocalComponent(rawFragment);\n if (decodedPath === null || (decodedFragment === null && rawFragment !== null)) {\n return null;\n }\n const resolvedPath = isFileUri ? hostFileUriPath(decodedPath) : decodedPath;\n if (resolvedPath === null) return null;\n if (resolvedPath === NOT_LOCAL_FILE_URI) return \"not-local\";\n return Object.freeze({\n path: resolvedPath,\n fragment: decodedFragment,\n isAbsolute: isFileUri || path.isAbsolute(resolvedPath)\n });\n}\n\nfunction decodeLocalComponent(rawComponent: string): string | null {\n if (containsControlCharacter(rawComponent) || /%(?:2f|5c|00|0[0-9a-f]|7f)/iu.test(rawComponent)) {\n return null;\n }\n try {\n const decoded = decodeURIComponent(rawComponent);\n return containsControlCharacter(decoded) ? null : decoded;\n } catch {\n return null;\n }\n}\n\nfunction isHostWindowsDriveAbsolute(value: string): boolean {\n return path.sep === \"\\\\\" && /^[A-Za-z]:[\\\\/]/u.test(value);\n}\n\nfunction hostFileUriPath(decodedPath: string): string | typeof NOT_LOCAL_FILE_URI | null {\n if (decodedPath.includes(\"\\\\\")) return null;\n if (path.sep === \"\\\\\") {\n if (!/^\\/[A-Za-z]:\\//u.test(decodedPath)) return NOT_LOCAL_FILE_URI;\n return path.normalize(decodedPath.slice(1));\n }\n if (/^\\/[A-Za-z]:\\//u.test(decodedPath)) return NOT_LOCAL_FILE_URI;\n return path.isAbsolute(decodedPath) ? decodedPath : null;\n}\n\nfunction hasUriQuery(uriPathAndFragment: string): boolean {\n const queryIndex = uriPathAndFragment.indexOf(\"?\");\n if (queryIndex < 0) return false;\n const fragmentIndex = uriPathAndFragment.indexOf(\"#\");\n return fragmentIndex < 0 || queryIndex < fragmentIndex;\n}\n\nexport function anchorResolution(\n headings: readonly MarkdownHeading[],\n fragment: string,\n target: MarkdownSafeTargetDescriptor\n): MarkdownLocalResolution {\n return headings.some((heading) => heading.slug === fragment)\n ? valid(target)\n : finding(\"missing-anchor\", target);\n}\n\nexport function isRootRelativePath(\n canonicalProjectRoot: string,\n rootRelativePath: string\n): boolean {\n return (\n !path.isAbsolute(rootRelativePath) &&\n isWithinRoot(canonicalProjectRoot, path.resolve(canonicalProjectRoot, rootRelativePath))\n );\n}\n\nexport function isWithinRoot(root: string, candidate: string): boolean {\n const relativePath = path.relative(root, candidate);\n return (\n relativePath === \"\" ||\n (!relativePath.startsWith(`..${path.sep}`) &&\n relativePath !== \"..\" &&\n !path.isAbsolute(relativePath))\n );\n}\n\nexport function relativeSegments(root: string, candidate: string): string[] {\n const relativePath = path.relative(root, candidate);\n return relativePath === \"\"\n ? []\n : relativePath.split(path.sep).filter((segment) => segment !== \"\");\n}\n\nexport function sameRootRelativePath(\n rootRelativePath: string,\n targetPath: string,\n canonicalProjectRoot: string\n): boolean {\n return toSlashPath(path.relative(canonicalProjectRoot, targetPath)) === rootRelativePath;\n}\n\nexport function isMarkdownPath(targetPath: string): boolean {\n const extension = path.extname(targetPath).toLowerCase();\n return extension === \".md\" || extension === \".markdown\";\n}\n\nexport function toSlashPath(filePath: string): string {\n return filePath.split(path.sep).join(\"/\");\n}\n\nfunction containsUnsafeRawFileCharacter(value: string): boolean {\n return value.includes(\"\\\\\") || containsControlCharacter(value) || /\\s/u.test(value);\n}\n\nfunction containsControlCharacter(value: string): boolean {\n for (const character of value) {\n const codePoint = character.codePointAt(0);\n if (\n codePoint !== undefined &&\n (codePoint <= 0x1f || (codePoint >= 0x7f && codePoint <= 0x9f))\n ) {\n return true;\n }\n }\n return false;\n}\n\nexport function isNotFound(error: unknown): boolean {\n return typeof error === \"object\" && error !== null && \"code\" in error && error.code === \"ENOENT\";\n}\n\nexport function sourceUnavailable(): MarkdownSourceReadResult {\n return Object.freeze({ ok: false as const, reason: \"source-unavailable\" as const });\n}\n\nexport function valid(target: MarkdownSafeTargetDescriptor): MarkdownLocalResolution {\n return Object.freeze({ kind: \"valid\" as const, target });\n}\n\nexport function finding(\n reason: MarkdownLinkFindingReason,\n target: MarkdownSafeTargetDescriptor\n): MarkdownLocalResolution {\n return Object.freeze({ kind: \"finding\" as const, reason, target });\n}\n\nexport function unavailable(reason: MarkdownLocalResolutionReason): MarkdownLocalResolution {\n return Object.freeze({ kind: \"unavailable\" as const, reason });\n}\n\nexport type {\n MarkdownLinkSource,\n MarkdownLocalResolution,\n MarkdownLocalResolutionReason,\n MarkdownLocalResolver,\n MarkdownLocalResolverCreation,\n MarkdownLocalResolutionRequest,\n MarkdownSafeTargetDescriptor,\n MarkdownSourceReadResult,\n MarkdownSourceReadFailureReason,\n RootProbe,\n EndpointProbe,\n RootExternalTargetMode\n};\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { realpath } from "node:fs/promises";
|
|
2
|
+
import { LinkLocalResolver } from "./resolver-engine.mjs";
|
|
3
|
+
/** Link-private, per-invocation state for source reads and direct local targets. */
|
|
4
|
+
export async function createMarkdownLocalResolver(projectRoot, maxTargetReads) {
|
|
5
|
+
try {
|
|
6
|
+
const canonicalProjectRoot = await realpath(projectRoot);
|
|
7
|
+
return Object.freeze({
|
|
8
|
+
ok: true,
|
|
9
|
+
resolver: new LinkLocalResolver(canonicalProjectRoot, maxTargetReads)
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return Object.freeze({ ok: false, reason: "project-root-unavailable" });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export { anchorResolution, finding, isMarkdownPath, isNotFound, isRootRelativePath, isWithinRoot, parseLocalDestination, relativeSegments, sameRootRelativePath, sourceUnavailable, toSlashPath, unavailable, valid } from "./local-resolution.mjs";
|
|
17
|
+
//# sourceMappingURL=local-resolver.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-resolver.mjs","sourceRoot":"","sources":["../../../../src/package-checks/markdown-link-validation/local-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,WAAmB,EACnB,cAAsB;IAEtB,IAAI,CAAC;QACH,MAAM,oBAAoB,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,CAAC;QACzD,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,EAAE,EAAE,IAAa;YACjB,QAAQ,EAAE,IAAI,iBAAiB,CAAC,oBAAoB,EAAE,cAAc,CAAC;SACtE,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAc,EAAE,MAAM,EAAE,0BAAmC,EAAE,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC;AAED,OAAO,EACL,gBAAgB,EAChB,OAAO,EACP,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,KAAK,EACN,MAAM,uBAAuB,CAAC","sourcesContent":["import { realpath } from \"node:fs/promises\";\n\nimport { LinkLocalResolver } from \"./resolver-engine.ts\";\nimport type { MarkdownLocalResolverCreation } from \"./local-resolution.ts\";\n\n/** Link-private, per-invocation state for source reads and direct local targets. */\nexport async function createMarkdownLocalResolver(\n projectRoot: string,\n maxTargetReads: number\n): Promise<MarkdownLocalResolverCreation> {\n try {\n const canonicalProjectRoot = await realpath(projectRoot);\n return Object.freeze({\n ok: true as const,\n resolver: new LinkLocalResolver(canonicalProjectRoot, maxTargetReads)\n });\n } catch {\n return Object.freeze({ ok: false as const, reason: \"project-root-unavailable\" as const });\n }\n}\n\nexport {\n anchorResolution,\n finding,\n isMarkdownPath,\n isNotFound,\n isRootRelativePath,\n isWithinRoot,\n parseLocalDestination,\n relativeSegments,\n sameRootRelativePath,\n sourceUnavailable,\n toSlashPath,\n unavailable,\n valid\n} from \"./local-resolution.ts\";\nexport type {\n EndpointProbe,\n MarkdownLinkFindingReason,\n MarkdownLinkSource,\n MarkdownLocalResolution,\n MarkdownLocalResolutionReason,\n MarkdownLocalResolutionRequest,\n MarkdownLocalResolver,\n MarkdownLocalResolverCreation,\n MarkdownSafeTargetDescriptor,\n MarkdownSourceReadFailureReason,\n MarkdownSourceReadResult,\n RootExternalTargetMode,\n RootProbe\n} from \"./local-resolution.ts\";\n"]}
|