@redocly/recheck 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1023 -56
- package/dist/cli.js +40 -7
- package/dist/cli.js.map +1 -1
- package/dist/commands/markdoc-schema.d.ts +17 -0
- package/dist/commands/markdoc-schema.d.ts.map +1 -0
- package/dist/commands/markdoc-schema.js +127 -0
- package/dist/commands/markdoc-schema.js.map +1 -0
- package/dist/commands/run.d.ts +2 -1
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +87 -10
- package/dist/commands/run.js.map +1 -1
- package/dist/config/load.d.ts +11 -0
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +12 -2
- package/dist/config/load.js.map +1 -1
- package/dist/config/presets/google.d.ts +3 -0
- package/dist/config/presets/google.d.ts.map +1 -0
- package/dist/config/presets/google.js +1671 -0
- package/dist/config/presets/google.js.map +1 -0
- package/dist/config/presets/inclusive-language.d.ts +3 -0
- package/dist/config/presets/inclusive-language.d.ts.map +1 -0
- package/dist/config/presets/inclusive-language.js +321 -0
- package/dist/config/presets/inclusive-language.js.map +1 -0
- package/dist/config/presets/index.d.ts +67 -0
- package/dist/config/presets/index.d.ts.map +1 -0
- package/dist/config/presets/index.js +137 -0
- package/dist/config/presets/index.js.map +1 -0
- package/dist/config/presets/markdoc.d.ts +21 -0
- package/dist/config/presets/markdoc.d.ts.map +1 -0
- package/dist/config/presets/markdoc.js +101 -0
- package/dist/config/presets/markdoc.js.map +1 -0
- package/dist/config/presets/markdown-relaxed.d.ts +3 -0
- package/dist/config/presets/markdown-relaxed.d.ts.map +1 -0
- package/dist/config/presets/markdown-relaxed.js +98 -0
- package/dist/config/presets/markdown-relaxed.js.map +1 -0
- package/dist/config/presets/markdown.d.ts +43 -0
- package/dist/config/presets/markdown.d.ts.map +1 -0
- package/dist/config/presets/markdown.js +132 -0
- package/dist/config/presets/markdown.js.map +1 -0
- package/dist/config/presets/microsoft.d.ts +3 -0
- package/dist/config/presets/microsoft.d.ts.map +1 -0
- package/dist/config/presets/microsoft.js +2268 -0
- package/dist/config/presets/microsoft.js.map +1 -0
- package/dist/config/presets/minimal.d.ts +3 -0
- package/dist/config/presets/minimal.d.ts.map +1 -0
- package/dist/config/presets/minimal.js +21 -0
- package/dist/config/presets/minimal.js.map +1 -0
- package/dist/config/presets/plain-language.d.ts +3 -0
- package/dist/config/presets/plain-language.d.ts.map +1 -0
- package/dist/config/presets/plain-language.js +351 -0
- package/dist/config/presets/plain-language.js.map +1 -0
- package/dist/config/presets/prose.d.ts +52 -0
- package/dist/config/presets/prose.d.ts.map +1 -0
- package/dist/config/presets/prose.js +138 -0
- package/dist/config/presets/prose.js.map +1 -0
- package/dist/config/schema.d.ts +128 -22
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +105 -21
- package/dist/config/schema.js.map +1 -1
- package/dist/config/validate.d.ts +12 -2
- package/dist/config/validate.d.ts.map +1 -1
- package/dist/config/validate.js +1200 -44
- package/dist/config/validate.js.map +1 -1
- package/dist/core/auto-fix.d.ts +8 -13
- package/dist/core/auto-fix.d.ts.map +1 -1
- package/dist/core/auto-fix.js +94 -75
- package/dist/core/auto-fix.js.map +1 -1
- package/dist/core/case-preserve.d.ts +46 -0
- package/dist/core/case-preserve.d.ts.map +1 -0
- package/dist/core/case-preserve.js +57 -0
- package/dist/core/case-preserve.js.map +1 -0
- package/dist/core/directives.d.ts +9 -0
- package/dist/core/directives.d.ts.map +1 -0
- package/dist/core/directives.js +73 -0
- package/dist/core/directives.js.map +1 -0
- package/dist/core/files.d.ts +63 -0
- package/dist/core/files.d.ts.map +1 -1
- package/dist/core/files.js +185 -0
- package/dist/core/files.js.map +1 -1
- package/dist/core/inline-code.d.ts +87 -0
- package/dist/core/inline-code.d.ts.map +1 -0
- package/dist/core/inline-code.js +104 -0
- package/dist/core/inline-code.js.map +1 -0
- package/dist/core/line-endings.d.ts +32 -0
- package/dist/core/line-endings.d.ts.map +1 -0
- package/dist/core/line-endings.js +65 -0
- package/dist/core/line-endings.js.map +1 -0
- package/dist/core/markdoc-tags.d.ts +79 -0
- package/dist/core/markdoc-tags.d.ts.map +1 -0
- package/dist/core/markdoc-tags.js +131 -0
- package/dist/core/markdoc-tags.js.map +1 -0
- package/dist/core/rule-filters.d.ts +17 -0
- package/dist/core/rule-filters.d.ts.map +1 -1
- package/dist/core/rule-filters.js +64 -0
- package/dist/core/rule-filters.js.map +1 -1
- package/dist/core/runner.d.ts +92 -3
- package/dist/core/runner.d.ts.map +1 -1
- package/dist/core/runner.js +348 -110
- package/dist/core/runner.js.map +1 -1
- package/dist/core/timing.d.ts.map +1 -1
- package/dist/data/markdoc-realm-schema.d.ts +3 -0
- package/dist/data/markdoc-realm-schema.d.ts.map +1 -0
- package/dist/data/markdoc-realm-schema.js +760 -0
- package/dist/data/markdoc-realm-schema.js.map +1 -0
- package/dist/data/proper-nouns.d.ts +2 -0
- package/dist/data/proper-nouns.d.ts.map +1 -0
- package/dist/data/proper-nouns.js +47 -0
- package/dist/data/proper-nouns.js.map +1 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +152 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/formulas.d.ts +17 -0
- package/dist/metrics/formulas.d.ts.map +1 -0
- package/dist/metrics/formulas.js +70 -0
- package/dist/metrics/formulas.js.map +1 -0
- package/dist/metrics/index.d.ts +5 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +3 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/statistics.d.ts +27 -0
- package/dist/metrics/statistics.d.ts.map +1 -0
- package/dist/metrics/statistics.js +56 -0
- package/dist/metrics/statistics.js.map +1 -0
- package/dist/parser/index.d.ts +18 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +168 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/markdoc/extract-statics.d.ts +45 -0
- package/dist/parser/markdoc/extract-statics.d.ts.map +1 -0
- package/dist/parser/markdoc/extract-statics.js +139 -0
- package/dist/parser/markdoc/extract-statics.js.map +1 -0
- package/dist/parser/markdoc/pairing.d.ts +63 -0
- package/dist/parser/markdoc/pairing.d.ts.map +1 -0
- package/dist/parser/markdoc/pairing.js +94 -0
- package/dist/parser/markdoc/pairing.js.map +1 -0
- package/dist/parser/markdoc/schema.d.ts +85 -0
- package/dist/parser/markdoc/schema.d.ts.map +1 -0
- package/dist/parser/markdoc/schema.js +86 -0
- package/dist/parser/markdoc/schema.js.map +1 -0
- package/dist/parser/markdoc/span.d.ts +64 -0
- package/dist/parser/markdoc/span.d.ts.map +1 -0
- package/dist/parser/markdoc/span.js +729 -0
- package/dist/parser/markdoc/span.js.map +1 -0
- package/dist/parser/markdoc/structure.d.ts +28 -0
- package/dist/parser/markdoc/structure.d.ts.map +1 -0
- package/dist/parser/markdoc/structure.js +153 -0
- package/dist/parser/markdoc/structure.js.map +1 -0
- package/dist/parser/markdoc/syntax.d.ts +44 -0
- package/dist/parser/markdoc/syntax.d.ts.map +1 -0
- package/dist/parser/markdoc/syntax.js +317 -0
- package/dist/parser/markdoc/syntax.js.map +1 -0
- package/dist/parser/types.d.ts +18 -0
- package/dist/parser/types.d.ts.map +1 -0
- package/dist/parser/types.js.map +1 -0
- package/dist/reporter/fixes.d.ts.map +1 -1
- package/dist/reporter/fixes.js +22 -1
- package/dist/reporter/fixes.js.map +1 -1
- package/dist/reporter/statistics.d.ts +1 -8
- package/dist/reporter/statistics.d.ts.map +1 -1
- package/dist/reporter/statistics.js.map +1 -1
- package/dist/rules/registry.d.ts +15 -0
- package/dist/rules/registry.d.ts.map +1 -0
- package/dist/rules/registry.js +81 -0
- package/dist/rules/registry.js.map +1 -0
- package/dist/rules/scope/capitalization.d.ts +3 -0
- package/dist/rules/scope/capitalization.d.ts.map +1 -0
- package/dist/rules/scope/capitalization.js +163 -0
- package/dist/rules/scope/capitalization.js.map +1 -0
- package/dist/rules/scope/conditional.d.ts +3 -0
- package/dist/rules/scope/conditional.d.ts.map +1 -0
- package/dist/rules/scope/conditional.js +112 -0
- package/dist/rules/scope/conditional.js.map +1 -0
- package/dist/rules/scope/consistency.d.ts +3 -0
- package/dist/rules/scope/consistency.d.ts.map +1 -0
- package/dist/rules/scope/consistency.js +178 -0
- package/dist/rules/scope/consistency.js.map +1 -0
- package/dist/rules/scope/length.d.ts +3 -0
- package/dist/rules/scope/length.d.ts.map +1 -0
- package/dist/rules/scope/length.js +69 -0
- package/dist/rules/scope/length.js.map +1 -0
- package/dist/rules/scope/max-image-size.d.ts +3 -0
- package/dist/rules/scope/max-image-size.d.ts.map +1 -0
- package/dist/rules/scope/max-image-size.js +65 -0
- package/dist/rules/scope/max-image-size.js.map +1 -0
- package/dist/rules/scope/metric.d.ts +17 -0
- package/dist/rules/scope/metric.d.ts.map +1 -0
- package/dist/rules/scope/metric.js +216 -0
- package/dist/rules/scope/metric.js.map +1 -0
- package/dist/rules/scope/occurrence.d.ts +3 -0
- package/dist/rules/scope/occurrence.d.ts.map +1 -0
- package/dist/rules/scope/occurrence.js +48 -0
- package/dist/rules/scope/occurrence.js.map +1 -0
- package/dist/rules/scope/pattern.d.ts +3 -0
- package/dist/rules/scope/pattern.d.ts.map +1 -0
- package/dist/rules/scope/pattern.js +75 -0
- package/dist/rules/scope/pattern.js.map +1 -0
- package/dist/rules/scope/repetition.d.ts +3 -0
- package/dist/rules/scope/repetition.d.ts.map +1 -0
- package/dist/rules/scope/repetition.js +139 -0
- package/dist/rules/scope/repetition.js.map +1 -0
- package/dist/rules/scope/semantic-line-breaks.d.ts +3 -0
- package/dist/rules/scope/semantic-line-breaks.d.ts.map +1 -0
- package/dist/rules/scope/semantic-line-breaks.js +213 -0
- package/dist/rules/scope/semantic-line-breaks.js.map +1 -0
- package/dist/rules/scope/spelling.d.ts +27 -0
- package/dist/rules/scope/spelling.d.ts.map +1 -0
- package/dist/rules/scope/spelling.js +227 -0
- package/dist/rules/scope/spelling.js.map +1 -0
- package/dist/rules/scope/swap.d.ts +3 -0
- package/dist/rules/scope/swap.d.ts.map +1 -0
- package/dist/rules/scope/swap.js +149 -0
- package/dist/rules/scope/swap.js.map +1 -0
- package/dist/rules/scope/title-case.d.ts +46 -0
- package/dist/rules/scope/title-case.d.ts.map +1 -0
- package/dist/rules/scope/title-case.js +301 -0
- package/dist/rules/scope/title-case.js.map +1 -0
- package/dist/rules/token/blanks-around-fences.d.ts +3 -0
- package/dist/rules/token/blanks-around-fences.d.ts.map +1 -0
- package/dist/rules/token/blanks-around-fences.js +44 -0
- package/dist/rules/token/blanks-around-fences.js.map +1 -0
- package/dist/rules/token/blanks-around-headings.d.ts +3 -0
- package/dist/rules/token/blanks-around-headings.d.ts.map +1 -0
- package/dist/rules/token/blanks-around-headings.js +108 -0
- package/dist/rules/token/blanks-around-headings.js.map +1 -0
- package/dist/rules/token/blanks-around-lists.d.ts +3 -0
- package/dist/rules/token/blanks-around-lists.d.ts.map +1 -0
- package/dist/rules/token/blanks-around-lists.js +56 -0
- package/dist/rules/token/blanks-around-lists.js.map +1 -0
- package/dist/rules/token/blanks-around-tables.d.ts +3 -0
- package/dist/rules/token/blanks-around-tables.d.ts.map +1 -0
- package/dist/rules/token/blanks-around-tables.js +42 -0
- package/dist/rules/token/blanks-around-tables.js.map +1 -0
- package/dist/rules/token/code-block-style.d.ts +3 -0
- package/dist/rules/token/code-block-style.d.ts.map +1 -0
- package/dist/rules/token/code-block-style.js +30 -0
- package/dist/rules/token/code-block-style.js.map +1 -0
- package/dist/rules/token/code-fence-style.d.ts +3 -0
- package/dist/rules/token/code-fence-style.d.ts.map +1 -0
- package/dist/rules/token/code-fence-style.js +35 -0
- package/dist/rules/token/code-fence-style.js.map +1 -0
- package/dist/rules/token/commands-show-output.d.ts +3 -0
- package/dist/rules/token/commands-show-output.d.ts.map +1 -0
- package/dist/rules/token/commands-show-output.js +38 -0
- package/dist/rules/token/commands-show-output.js.map +1 -0
- package/dist/rules/token/descriptive-link-text.d.ts +3 -0
- package/dist/rules/token/descriptive-link-text.d.ts.map +1 -0
- package/dist/rules/token/descriptive-link-text.js +53 -0
- package/dist/rules/token/descriptive-link-text.js.map +1 -0
- package/dist/rules/token/emphasis-style.d.ts +3 -0
- package/dist/rules/token/emphasis-style.d.ts.map +1 -0
- package/dist/rules/token/emphasis-style.js +51 -0
- package/dist/rules/token/emphasis-style.js.map +1 -0
- package/dist/rules/token/fenced-code-language.d.ts +3 -0
- package/dist/rules/token/fenced-code-language.d.ts.map +1 -0
- package/dist/rules/token/fenced-code-language.js +35 -0
- package/dist/rules/token/fenced-code-language.js.map +1 -0
- package/dist/rules/token/first-line-h1.d.ts +3 -0
- package/dist/rules/token/first-line-h1.d.ts.map +1 -0
- package/dist/rules/token/first-line-h1.js +107 -0
- package/dist/rules/token/first-line-h1.js.map +1 -0
- package/dist/rules/token/heading-increment.d.ts +3 -0
- package/dist/rules/token/heading-increment.d.ts.map +1 -0
- package/dist/rules/token/heading-increment.js +27 -0
- package/dist/rules/token/heading-increment.js.map +1 -0
- package/dist/rules/token/heading-start-left.d.ts +3 -0
- package/dist/rules/token/heading-start-left.d.ts.map +1 -0
- package/dist/rules/token/heading-start-left.js +31 -0
- package/dist/rules/token/heading-start-left.js.map +1 -0
- package/dist/rules/token/heading-style.d.ts +3 -0
- package/dist/rules/token/heading-style.d.ts.map +1 -0
- package/dist/rules/token/heading-style.js +41 -0
- package/dist/rules/token/heading-style.js.map +1 -0
- package/dist/rules/token/helpers.d.ts +313 -0
- package/dist/rules/token/helpers.d.ts.map +1 -0
- package/dist/rules/token/helpers.js +746 -0
- package/dist/rules/token/helpers.js.map +1 -0
- package/dist/rules/token/hr-style.d.ts +3 -0
- package/dist/rules/token/hr-style.d.ts.map +1 -0
- package/dist/rules/token/hr-style.js +28 -0
- package/dist/rules/token/hr-style.js.map +1 -0
- package/dist/rules/token/index.d.ts +75 -0
- package/dist/rules/token/index.d.ts.map +1 -0
- package/dist/rules/token/index.js +226 -0
- package/dist/rules/token/index.js.map +1 -0
- package/dist/rules/token/line-length.d.ts +3 -0
- package/dist/rules/token/line-length.d.ts.map +1 -0
- package/dist/rules/token/line-length.js +120 -0
- package/dist/rules/token/line-length.js.map +1 -0
- package/dist/rules/token/link-fragments.d.ts +3 -0
- package/dist/rules/token/link-fragments.d.ts.map +1 -0
- package/dist/rules/token/link-fragments.js +145 -0
- package/dist/rules/token/link-fragments.js.map +1 -0
- package/dist/rules/token/link-image-reference-definitions.d.ts +3 -0
- package/dist/rules/token/link-image-reference-definitions.d.ts.map +1 -0
- package/dist/rules/token/link-image-reference-definitions.js +50 -0
- package/dist/rules/token/link-image-reference-definitions.js.map +1 -0
- package/dist/rules/token/link-image-style.d.ts +3 -0
- package/dist/rules/token/link-image-style.d.ts.map +1 -0
- package/dist/rules/token/link-image-style.js +131 -0
- package/dist/rules/token/link-image-style.js.map +1 -0
- package/dist/rules/token/list-indent.d.ts +3 -0
- package/dist/rules/token/list-indent.d.ts.map +1 -0
- package/dist/rules/token/list-indent.js +60 -0
- package/dist/rules/token/list-indent.js.map +1 -0
- package/dist/rules/token/list-length.d.ts +3 -0
- package/dist/rules/token/list-length.d.ts.map +1 -0
- package/dist/rules/token/list-length.js +55 -0
- package/dist/rules/token/list-length.js.map +1 -0
- package/dist/rules/token/list-marker-space.d.ts +3 -0
- package/dist/rules/token/list-marker-space.d.ts.map +1 -0
- package/dist/rules/token/list-marker-space.js +52 -0
- package/dist/rules/token/list-marker-space.js.map +1 -0
- package/dist/rules/token/markdoc-attributes.d.ts +3 -0
- package/dist/rules/token/markdoc-attributes.d.ts.map +1 -0
- package/dist/rules/token/markdoc-attributes.js +269 -0
- package/dist/rules/token/markdoc-attributes.js.map +1 -0
- package/dist/rules/token/markdoc-pairing.d.ts +3 -0
- package/dist/rules/token/markdoc-pairing.d.ts.map +1 -0
- package/dist/rules/token/markdoc-pairing.js +73 -0
- package/dist/rules/token/markdoc-pairing.js.map +1 -0
- package/dist/rules/token/markdoc-syntax.d.ts +3 -0
- package/dist/rules/token/markdoc-syntax.d.ts.map +1 -0
- package/dist/rules/token/markdoc-syntax.js +119 -0
- package/dist/rules/token/markdoc-syntax.js.map +1 -0
- package/dist/rules/token/markdoc-unknown-tag.d.ts +3 -0
- package/dist/rules/token/markdoc-unknown-tag.d.ts.map +1 -0
- package/dist/rules/token/markdoc-unknown-tag.js +64 -0
- package/dist/rules/token/markdoc-unknown-tag.js.map +1 -0
- package/dist/rules/token/messages.d.ts +4 -0
- package/dist/rules/token/messages.d.ts.map +1 -0
- package/dist/rules/token/messages.js +20 -0
- package/dist/rules/token/messages.js.map +1 -0
- package/dist/rules/token/no-alt-text.d.ts +3 -0
- package/dist/rules/token/no-alt-text.d.ts.map +1 -0
- package/dist/rules/token/no-alt-text.js +47 -0
- package/dist/rules/token/no-alt-text.js.map +1 -0
- package/dist/rules/token/no-bare-urls.d.ts +3 -0
- package/dist/rules/token/no-bare-urls.d.ts.map +1 -0
- package/dist/rules/token/no-bare-urls.js +88 -0
- package/dist/rules/token/no-bare-urls.js.map +1 -0
- package/dist/rules/token/no-blanks-blockquote.d.ts +3 -0
- package/dist/rules/token/no-blanks-blockquote.d.ts.map +1 -0
- package/dist/rules/token/no-blanks-blockquote.js +39 -0
- package/dist/rules/token/no-blanks-blockquote.js.map +1 -0
- package/dist/rules/token/no-duplicate-heading.d.ts +3 -0
- package/dist/rules/token/no-duplicate-heading.d.ts.map +1 -0
- package/dist/rules/token/no-duplicate-heading.js +101 -0
- package/dist/rules/token/no-duplicate-heading.js.map +1 -0
- package/dist/rules/token/no-duplicate-link-destinations.d.ts +3 -0
- package/dist/rules/token/no-duplicate-link-destinations.d.ts.map +1 -0
- package/dist/rules/token/no-duplicate-link-destinations.js +65 -0
- package/dist/rules/token/no-duplicate-link-destinations.js.map +1 -0
- package/dist/rules/token/no-emphasis-as-heading.d.ts +3 -0
- package/dist/rules/token/no-emphasis-as-heading.d.ts.map +1 -0
- package/dist/rules/token/no-emphasis-as-heading.js +44 -0
- package/dist/rules/token/no-emphasis-as-heading.js.map +1 -0
- package/dist/rules/token/no-empty-headings.d.ts +3 -0
- package/dist/rules/token/no-empty-headings.d.ts.map +1 -0
- package/dist/rules/token/no-empty-headings.js +28 -0
- package/dist/rules/token/no-empty-headings.js.map +1 -0
- package/dist/rules/token/no-empty-links.d.ts +3 -0
- package/dist/rules/token/no-empty-links.d.ts.map +1 -0
- package/dist/rules/token/no-empty-links.js +67 -0
- package/dist/rules/token/no-empty-links.js.map +1 -0
- package/dist/rules/token/no-hard-tabs.d.ts +3 -0
- package/dist/rules/token/no-hard-tabs.d.ts.map +1 -0
- package/dist/rules/token/no-hard-tabs.js +76 -0
- package/dist/rules/token/no-hard-tabs.js.map +1 -0
- package/dist/rules/token/no-inline-html.d.ts +3 -0
- package/dist/rules/token/no-inline-html.d.ts.map +1 -0
- package/dist/rules/token/no-inline-html.js +45 -0
- package/dist/rules/token/no-inline-html.js.map +1 -0
- package/dist/rules/token/no-missing-space-atx.d.ts +3 -0
- package/dist/rules/token/no-missing-space-atx.d.ts.map +1 -0
- package/dist/rules/token/no-missing-space-atx.js +36 -0
- package/dist/rules/token/no-missing-space-atx.js.map +1 -0
- package/dist/rules/token/no-missing-space-closed-atx.d.ts +3 -0
- package/dist/rules/token/no-missing-space-closed-atx.d.ts.map +1 -0
- package/dist/rules/token/no-missing-space-closed-atx.js +45 -0
- package/dist/rules/token/no-missing-space-closed-atx.js.map +1 -0
- package/dist/rules/token/no-multiple-blanks.d.ts +3 -0
- package/dist/rules/token/no-multiple-blanks.d.ts.map +1 -0
- package/dist/rules/token/no-multiple-blanks.js +35 -0
- package/dist/rules/token/no-multiple-blanks.js.map +1 -0
- package/dist/rules/token/no-multiple-space-atx.d.ts +13 -0
- package/dist/rules/token/no-multiple-space-atx.d.ts.map +1 -0
- package/dist/rules/token/no-multiple-space-atx.js +50 -0
- package/dist/rules/token/no-multiple-space-atx.js.map +1 -0
- package/dist/rules/token/no-multiple-space-blockquote.d.ts +3 -0
- package/dist/rules/token/no-multiple-space-blockquote.d.ts.map +1 -0
- package/dist/rules/token/no-multiple-space-blockquote.js +43 -0
- package/dist/rules/token/no-multiple-space-blockquote.js.map +1 -0
- package/dist/rules/token/no-multiple-space-closed-atx.d.ts +3 -0
- package/dist/rules/token/no-multiple-space-closed-atx.d.ts.map +1 -0
- package/dist/rules/token/no-multiple-space-closed-atx.js +19 -0
- package/dist/rules/token/no-multiple-space-closed-atx.js.map +1 -0
- package/dist/rules/token/no-reversed-links.d.ts +3 -0
- package/dist/rules/token/no-reversed-links.d.ts.map +1 -0
- package/dist/rules/token/no-reversed-links.js +52 -0
- package/dist/rules/token/no-reversed-links.js.map +1 -0
- package/dist/rules/token/no-space-in-code.d.ts +3 -0
- package/dist/rules/token/no-space-in-code.d.ts.map +1 -0
- package/dist/rules/token/no-space-in-code.js +75 -0
- package/dist/rules/token/no-space-in-code.js.map +1 -0
- package/dist/rules/token/no-space-in-emphasis.d.ts +3 -0
- package/dist/rules/token/no-space-in-emphasis.d.ts.map +1 -0
- package/dist/rules/token/no-space-in-emphasis.js +79 -0
- package/dist/rules/token/no-space-in-emphasis.js.map +1 -0
- package/dist/rules/token/no-space-in-links.d.ts +3 -0
- package/dist/rules/token/no-space-in-links.d.ts.map +1 -0
- package/dist/rules/token/no-space-in-links.js +48 -0
- package/dist/rules/token/no-space-in-links.js.map +1 -0
- package/dist/rules/token/no-trailing-punctuation.d.ts +3 -0
- package/dist/rules/token/no-trailing-punctuation.d.ts.map +1 -0
- package/dist/rules/token/no-trailing-punctuation.js +38 -0
- package/dist/rules/token/no-trailing-punctuation.js.map +1 -0
- package/dist/rules/token/no-trailing-spaces.d.ts +3 -0
- package/dist/rules/token/no-trailing-spaces.d.ts.map +1 -0
- package/dist/rules/token/no-trailing-spaces.js +89 -0
- package/dist/rules/token/no-trailing-spaces.js.map +1 -0
- package/dist/rules/token/ol-prefix.d.ts +3 -0
- package/dist/rules/token/ol-prefix.d.ts.map +1 -0
- package/dist/rules/token/ol-prefix.js +70 -0
- package/dist/rules/token/ol-prefix.js.map +1 -0
- package/dist/rules/token/proper-names.d.ts +3 -0
- package/dist/rules/token/proper-names.d.ts.map +1 -0
- package/dist/rules/token/proper-names.js +93 -0
- package/dist/rules/token/proper-names.js.map +1 -0
- package/dist/rules/token/reference-links-images.d.ts +3 -0
- package/dist/rules/token/reference-links-images.d.ts.map +1 -0
- package/dist/rules/token/reference-links-images.js +36 -0
- package/dist/rules/token/reference-links-images.js.map +1 -0
- package/dist/rules/token/required-headings.d.ts +3 -0
- package/dist/rules/token/required-headings.d.ts.map +1 -0
- package/dist/rules/token/required-headings.js +83 -0
- package/dist/rules/token/required-headings.js.map +1 -0
- package/dist/rules/token/single-h1.d.ts +3 -0
- package/dist/rules/token/single-h1.d.ts.map +1 -0
- package/dist/rules/token/single-h1.js +56 -0
- package/dist/rules/token/single-h1.js.map +1 -0
- package/dist/rules/token/single-trailing-newline.d.ts +3 -0
- package/dist/rules/token/single-trailing-newline.d.ts.map +1 -0
- package/dist/rules/token/single-trailing-newline.js +25 -0
- package/dist/rules/token/single-trailing-newline.js.map +1 -0
- package/dist/rules/token/strong-style.d.ts +3 -0
- package/dist/rules/token/strong-style.d.ts.map +1 -0
- package/dist/rules/token/strong-style.js +51 -0
- package/dist/rules/token/strong-style.js.map +1 -0
- package/dist/rules/token/table-column-count.d.ts +3 -0
- package/dist/rules/token/table-column-count.d.ts.map +1 -0
- package/dist/rules/token/table-column-count.js +44 -0
- package/dist/rules/token/table-column-count.js.map +1 -0
- package/dist/rules/token/table-column-style.d.ts +3 -0
- package/dist/rules/token/table-column-style.d.ts.map +1 -0
- package/dist/rules/token/table-column-style.js +179 -0
- package/dist/rules/token/table-column-style.js.map +1 -0
- package/dist/rules/token/table-pipe-style.d.ts +3 -0
- package/dist/rules/token/table-pipe-style.d.ts.map +1 -0
- package/dist/rules/token/table-pipe-style.js +54 -0
- package/dist/rules/token/table-pipe-style.js.map +1 -0
- package/dist/rules/token/ul-indent.d.ts +3 -0
- package/dist/rules/token/ul-indent.d.ts.map +1 -0
- package/dist/rules/token/ul-indent.js +72 -0
- package/dist/rules/token/ul-indent.js.map +1 -0
- package/dist/rules/token/ul-style.d.ts +3 -0
- package/dist/rules/token/ul-style.d.ts.map +1 -0
- package/dist/rules/token/ul-style.js +80 -0
- package/dist/rules/token/ul-style.js.map +1 -0
- package/dist/rules/types.d.ts +81 -0
- package/dist/rules/types.d.ts.map +1 -0
- package/dist/rules/types.js +2 -0
- package/dist/rules/types.js.map +1 -0
- package/dist/rules/utils.d.ts +29 -0
- package/dist/rules/utils.d.ts.map +1 -0
- package/dist/{assertions → rules}/utils.js +27 -0
- package/dist/rules/utils.js.map +1 -0
- package/dist/scopes/extractor.d.ts +7 -0
- package/dist/scopes/extractor.d.ts.map +1 -0
- package/dist/scopes/extractor.js +475 -0
- package/dist/scopes/extractor.js.map +1 -0
- package/dist/scopes/selector.d.ts +51 -0
- package/dist/scopes/selector.d.ts.map +1 -0
- package/dist/scopes/selector.js +121 -0
- package/dist/scopes/selector.js.map +1 -0
- package/dist/scopes/sentences.d.ts +15 -0
- package/dist/scopes/sentences.d.ts.map +1 -0
- package/dist/scopes/sentences.js +124 -0
- package/dist/scopes/sentences.js.map +1 -0
- package/dist/scopes/types.d.ts +44 -0
- package/dist/scopes/types.d.ts.map +1 -0
- package/dist/scopes/types.js +2 -0
- package/dist/scopes/types.js.map +1 -0
- package/dist/scopes/vocabulary.d.ts +16 -0
- package/dist/scopes/vocabulary.d.ts.map +1 -0
- package/dist/scopes/vocabulary.js +70 -0
- package/dist/scopes/vocabulary.js.map +1 -0
- package/dist/types/assertions.d.ts +95 -32
- package/dist/types/assertions.d.ts.map +1 -1
- package/dist/types/problems.d.ts +4 -5
- package/dist/types/problems.d.ts.map +1 -1
- package/dist/types/rules.d.ts +4 -6
- package/dist/types/rules.d.ts.map +1 -1
- package/examples/appendices/google.appendix.yaml +91 -0
- package/examples/appendices/inclusive-language.appendix.yaml +61 -0
- package/examples/appendices/microsoft.appendix.yaml +99 -0
- package/examples/appendices/plain-language.appendix.yaml +88 -0
- package/examples/google.yaml +1525 -0
- package/examples/inclusive-language.yaml +304 -0
- package/examples/microsoft.yaml +1542 -0
- package/examples/plain-language.yaml +325 -0
- package/package.json +49 -16
- package/presets/google/PROVENANCE.md +1022 -0
- package/presets/google/sources.json +192 -0
- package/presets/inclusive-language/PROVENANCE.md +174 -0
- package/presets/inclusive-language/sources.json +107 -0
- package/presets/microsoft/PROVENANCE.md +1555 -0
- package/presets/microsoft/sources.json +494 -0
- package/presets/plain-language/PROVENANCE.md +364 -0
- package/presets/plain-language/sources.json +108 -0
- package/dist/assertions/bullet-style.d.ts +0 -3
- package/dist/assertions/bullet-style.d.ts.map +0 -1
- package/dist/assertions/bullet-style.js +0 -60
- package/dist/assertions/bullet-style.js.map +0 -1
- package/dist/assertions/index.d.ts +0 -21
- package/dist/assertions/index.d.ts.map +0 -1
- package/dist/assertions/index.js +0 -30
- package/dist/assertions/index.js.map +0 -1
- package/dist/assertions/max-image-size.d.ts +0 -3
- package/dist/assertions/max-image-size.d.ts.map +0 -1
- package/dist/assertions/max-image-size.js +0 -73
- package/dist/assertions/max-image-size.js.map +0 -1
- package/dist/assertions/max-line-length.d.ts +0 -3
- package/dist/assertions/max-line-length.d.ts.map +0 -1
- package/dist/assertions/max-line-length.js +0 -68
- package/dist/assertions/max-line-length.js.map +0 -1
- package/dist/assertions/no-broken-fragment-links.d.ts +0 -3
- package/dist/assertions/no-broken-fragment-links.d.ts.map +0 -1
- package/dist/assertions/no-broken-fragment-links.js +0 -79
- package/dist/assertions/no-broken-fragment-links.js.map +0 -1
- package/dist/assertions/no-duplicate-headings.d.ts +0 -3
- package/dist/assertions/no-duplicate-headings.d.ts.map +0 -1
- package/dist/assertions/no-duplicate-headings.js +0 -66
- package/dist/assertions/no-duplicate-headings.js.map +0 -1
- package/dist/assertions/no-hard-tabs.d.ts +0 -3
- package/dist/assertions/no-hard-tabs.d.ts.map +0 -1
- package/dist/assertions/no-hard-tabs.js +0 -63
- package/dist/assertions/no-hard-tabs.js.map +0 -1
- package/dist/assertions/no-trailing-spaces.d.ts +0 -3
- package/dist/assertions/no-trailing-spaces.d.ts.map +0 -1
- package/dist/assertions/no-trailing-spaces.js +0 -72
- package/dist/assertions/no-trailing-spaces.js.map +0 -1
- package/dist/assertions/pattern.d.ts +0 -3
- package/dist/assertions/pattern.d.ts.map +0 -1
- package/dist/assertions/pattern.js +0 -39
- package/dist/assertions/pattern.js.map +0 -1
- package/dist/assertions/semantic-line-breaks.d.ts +0 -3
- package/dist/assertions/semantic-line-breaks.d.ts.map +0 -1
- package/dist/assertions/semantic-line-breaks.js +0 -152
- package/dist/assertions/semantic-line-breaks.js.map +0 -1
- package/dist/assertions/swap.d.ts +0 -3
- package/dist/assertions/swap.d.ts.map +0 -1
- package/dist/assertions/swap.js +0 -39
- package/dist/assertions/swap.js.map +0 -1
- package/dist/assertions/utils.d.ts +0 -8
- package/dist/assertions/utils.d.ts.map +0 -1
- package/dist/assertions/utils.js.map +0 -1
- package/dist/core/scope-parser.d.ts +0 -26
- package/dist/core/scope-parser.d.ts.map +0 -1
- package/dist/core/scope-parser.js +0 -110
- package/dist/core/scope-parser.js.map +0 -1
- package/dist/files.d.ts +0 -2
- package/dist/files.d.ts.map +0 -1
- package/dist/files.js +0 -39
- package/dist/files.js.map +0 -1
- package/dist/load-config.d.ts +0 -25
- package/dist/load-config.d.ts.map +0 -1
- package/dist/load-config.js +0 -104
- package/dist/load-config.js.map +0 -1
- package/dist/load.d.ts +0 -25
- package/dist/load.d.ts.map +0 -1
- package/dist/load.js +0 -112
- package/dist/load.js.map +0 -1
- package/dist/scope.d.ts +0 -26
- package/dist/scope.d.ts.map +0 -1
- package/dist/scope.js +0 -110
- package/dist/scope.js.map +0 -1
- package/dist/types.d.ts +0 -109
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/validate.d.ts +0 -31
- package/dist/validate.d.ts.map +0 -1
- package/dist/validate.js +0 -154
- package/dist/validate.js.map +0 -1
- /package/dist/{types.js → parser/types.js} +0 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
// Schema-aware attribute validation for tags `markdoc-unknown-tag` already
|
|
2
|
+
// accepts as known (that rule owns the tag NAME itself). Detection-only.
|
|
3
|
+
// Re-parses each tag's text via `parseMarkdocSpan` because the child tokens
|
|
4
|
+
// structure.ts synthesizes carry positions but no `valueKind`/`value`/
|
|
5
|
+
// `dynamic` data.
|
|
6
|
+
//
|
|
7
|
+
// Only `tag-open`/`tag-self-closing` kinds are checked: close tags carry no
|
|
8
|
+
// attributes in Markdoc's grammar, and annotation/variable/function/malformed
|
|
9
|
+
// spans have no tag name to look up a schema with. Annotations are a known v1
|
|
10
|
+
// gap -- real Markdoc does check their attributes against the node they attach
|
|
11
|
+
// to, but no per-annotation schema is modeled here. Unknown tags are skipped
|
|
12
|
+
// too: upstream reports `tag-undefined` and no attribute errors for them, so
|
|
13
|
+
// adding attribute reports on top of `markdoc-unknown-tag`'s would be noise.
|
|
14
|
+
import { parseMarkdocSpan, } from '../../parser/markdoc/span.js';
|
|
15
|
+
import { filterByTypes } from '../../parser/index.js';
|
|
16
|
+
/**
|
|
17
|
+
* Real Markdoc merges `{ ...globalAttributes, ...schema.attributes }` before
|
|
18
|
+
* validating, so `class`/`id` are never unknown -- but a tag that declares one
|
|
19
|
+
* itself wins that merge and has it value-checked like any other attribute
|
|
20
|
+
* (four realm tags declare their own `id`: `input`, `step`, `tabs`, `toggle`).
|
|
21
|
+
* The carve-out below therefore fires only when the tag's own schema has no
|
|
22
|
+
* entry for the name, which is also why `.x`/`#x` shortcuts are always
|
|
23
|
+
* schema-valid. The global case can't be value-checked at all: Markdoc's
|
|
24
|
+
* `Class`/`Id` validators are custom classes, out of reach for a
|
|
25
|
+
* statics-only schema -- see `MarkdocAttributeSchema`'s `dynamic` comment.
|
|
26
|
+
*/
|
|
27
|
+
const GLOBAL_ATTRIBUTE_NAMES = new Set(['class', 'id']);
|
|
28
|
+
function describeValueKind(kind) {
|
|
29
|
+
if (kind === 'null')
|
|
30
|
+
return 'null';
|
|
31
|
+
const article = 'aeiou'.includes(kind[0]) ? 'an' : 'a';
|
|
32
|
+
return `${article} ${kind}`;
|
|
33
|
+
}
|
|
34
|
+
function formatEnum(values) {
|
|
35
|
+
return values.map((value) => `"${value}"`).join(', ');
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Type + enum ("matches") checks for one already-known, non-dynamic,
|
|
39
|
+
* non-opaque attribute value -- shared by named attributes and the positional
|
|
40
|
+
* primary, which real Markdoc validates identically. Upstream treats the two
|
|
41
|
+
* checks as independent (a wrong-type value that also fails `matches` reports
|
|
42
|
+
* both), so this pushes up to two reports rather than short-circuiting.
|
|
43
|
+
*/
|
|
44
|
+
function checkValue(attrName, valueKind, value, attrSchema, position, reports) {
|
|
45
|
+
if (valueKind !== attrSchema.type) {
|
|
46
|
+
reports.push({
|
|
47
|
+
line: position.startLine,
|
|
48
|
+
column: position.startColumn,
|
|
49
|
+
context: `"${attrName}" must be a ${attrSchema.type} value — got ${describeValueKind(valueKind)}`,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (attrSchema.enum && !attrSchema.enum.includes(String(value))) {
|
|
53
|
+
reports.push({
|
|
54
|
+
line: position.startLine,
|
|
55
|
+
column: position.startColumn,
|
|
56
|
+
context: `"${attrName}" must be one of ${formatEnum(attrSchema.enum)} — got "${String(value)}"`,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** Value kinds this rule cannot statically check: `variable`/`function` are
|
|
61
|
+
* opaque at parse time, and `bareword` is already `markdoc-syntax`'s report --
|
|
62
|
+
* a type/enum verdict on a value that isn't legal Markdoc would contradict
|
|
63
|
+
* that rule's "quote the value" advice. */
|
|
64
|
+
function isOpaqueOrSyntaxOwned(kind) {
|
|
65
|
+
return kind === 'variable' || kind === 'function' || kind === 'bareword';
|
|
66
|
+
}
|
|
67
|
+
export const markdocAttributes = {
|
|
68
|
+
name: 'markdoc-attributes',
|
|
69
|
+
tags: ['markdoc'],
|
|
70
|
+
fixable: false,
|
|
71
|
+
// Bare placeholder: every `onError` call supplies the complete sentence
|
|
72
|
+
// via `context`.
|
|
73
|
+
defaults: {
|
|
74
|
+
message: '%s',
|
|
75
|
+
},
|
|
76
|
+
check(ctx) {
|
|
77
|
+
if (!ctx.markdoc)
|
|
78
|
+
return; // flag off -- no markdocTag tokens exist at all
|
|
79
|
+
const { schema } = ctx.markdoc;
|
|
80
|
+
if (!schema)
|
|
81
|
+
return; // `schema: false` -- nothing to validate attributes against
|
|
82
|
+
// One tag can produce reports from four independent checks (primary,
|
|
83
|
+
// per-attribute, missing-required, duplicate) run in whatever order is
|
|
84
|
+
// convenient to compute, so reports are collected and sorted at the end
|
|
85
|
+
// to leave this rule in document order rather than check order.
|
|
86
|
+
const reports = [];
|
|
87
|
+
for (const token of filterByTypes(ctx.tree, ['markdocTag'])) {
|
|
88
|
+
if (token.markdocKind !== 'tag-open' && token.markdocKind !== 'tag-self-closing')
|
|
89
|
+
continue;
|
|
90
|
+
const nameChild = token.children.find((child) => child.type === 'markdocTagName');
|
|
91
|
+
const tagName = nameChild?.text;
|
|
92
|
+
if (!tagName)
|
|
93
|
+
continue; // defensive only: both kinds always carry a name child
|
|
94
|
+
const tagSchema = schema.tags[tagName];
|
|
95
|
+
if (!tagSchema)
|
|
96
|
+
continue; // unknown tag -- markdoc-unknown-tag's report, not this rule's
|
|
97
|
+
const attributes = tagSchema.attributes ?? {};
|
|
98
|
+
const parsed = parseMarkdocSpan(token.text);
|
|
99
|
+
// Defensive only: `token.markdocKind` came from this same parse.
|
|
100
|
+
if (parsed.kind !== 'tag-open' && parsed.kind !== 'tag-self-closing')
|
|
101
|
+
continue;
|
|
102
|
+
// ---- primary: Markdoc's positional value slot, validated against the
|
|
103
|
+
// schema attribute literally named `primary`. Checked before the
|
|
104
|
+
// named-attribute loop only because its span offset is always earlier;
|
|
105
|
+
// the final sort makes that ordering non-load-bearing.
|
|
106
|
+
let primaryPresent = false;
|
|
107
|
+
// Hoisted out of the branch below: the duplicate-attribute walk needs
|
|
108
|
+
// this position too.
|
|
109
|
+
const primaryToken = token.children.find((child) => child.type === 'markdocTagPrimary');
|
|
110
|
+
if (parsed.primary) {
|
|
111
|
+
primaryPresent = true;
|
|
112
|
+
const { valueKind, value } = parsed.primary;
|
|
113
|
+
if (!isOpaqueOrSyntaxOwned(valueKind)) {
|
|
114
|
+
const position = primaryToken ?? token;
|
|
115
|
+
const primarySchema = attributes.primary;
|
|
116
|
+
if (!primarySchema) {
|
|
117
|
+
// Upstream treats a primary value on a tag that declares no
|
|
118
|
+
// `primary` attribute like any other undeclared name, so this is
|
|
119
|
+
// the "unknown attribute" class -- `warn`, per AttributeReport.
|
|
120
|
+
reports.push({
|
|
121
|
+
line: position.startLine,
|
|
122
|
+
column: position.startColumn,
|
|
123
|
+
context: `"primary" is not a known attribute of "${tagName}" — check for a typo`,
|
|
124
|
+
severity: 'warn',
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
else if (!primarySchema.dynamic) {
|
|
128
|
+
checkValue('primary', valueKind, value, primarySchema, position, reports);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// ---- named attributes. Real Markdoc validates the MERGED
|
|
133
|
+
// last-write-wins attributes object, not the raw source list, so
|
|
134
|
+
// `{% t a=1 a=2 %}` with `a` undeclared reports `attribute-undefined`
|
|
135
|
+
// once, not twice. `lastByName` reproduces that collapse: the
|
|
136
|
+
// unknown/type/enum checks below fire once per NAME, on the last
|
|
137
|
+
// occurrence's value and position. The separate duplicate pass further
|
|
138
|
+
// down still walks every raw occurrence, since it needs the repetition
|
|
139
|
+
// this map erases.
|
|
140
|
+
const attributeTokens = token.children.filter((child) => child.type === 'markdocAttribute');
|
|
141
|
+
// `index` is carried alongside the pair so the value-position lookup in
|
|
142
|
+
// the loop is an O(1) array read rather than an `indexOf` scan per
|
|
143
|
+
// entry -- otherwise O(n²) for a long attribute list.
|
|
144
|
+
const lastByName = new Map();
|
|
145
|
+
parsed.attributes.forEach((attribute, index) => {
|
|
146
|
+
const attributeToken = attributeTokens[index];
|
|
147
|
+
const nameToken = attributeToken?.children.find((child) => child.type === 'markdocAttributeName') ??
|
|
148
|
+
attributeToken ??
|
|
149
|
+
token;
|
|
150
|
+
lastByName.set(attribute.name, { attribute, index, position: nameToken });
|
|
151
|
+
});
|
|
152
|
+
for (const [attrName, entry] of lastByName) {
|
|
153
|
+
const { attribute, index: attributeIndex, position: nameTokenPos } = entry;
|
|
154
|
+
const attrSchema = attributes[attrName];
|
|
155
|
+
if (!attrSchema) {
|
|
156
|
+
// `class`/`id` are never "unknown" when the tag itself declares no
|
|
157
|
+
// entry for the name; a tag that does declare its own takes the
|
|
158
|
+
// ordinary declared-attribute path (see `GLOBAL_ATTRIBUTE_NAMES`).
|
|
159
|
+
if (GLOBAL_ATTRIBUTE_NAMES.has(attrName))
|
|
160
|
+
continue;
|
|
161
|
+
// `warn` -- the "unknown attribute" class, per AttributeReport.
|
|
162
|
+
reports.push({
|
|
163
|
+
line: nameTokenPos.startLine,
|
|
164
|
+
column: nameTokenPos.startColumn,
|
|
165
|
+
context: `"${attrName}" is not a known attribute of "${tagName}" — check for a typo`,
|
|
166
|
+
severity: 'warn',
|
|
167
|
+
});
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (attrSchema.dynamic)
|
|
171
|
+
continue; // value checks skip dynamic attributes (see schema.ts)
|
|
172
|
+
if (isOpaqueOrSyntaxOwned(attribute.valueKind))
|
|
173
|
+
continue;
|
|
174
|
+
// Value checks report at the value's own position, not the name's --
|
|
175
|
+
// the same split `markdoc-syntax` uses for its bareword check.
|
|
176
|
+
const attributeToken = attributeTokens[attributeIndex];
|
|
177
|
+
const valueTokenPos = attributeToken?.children.find((child) => child.type === 'markdocAttributeValue') ??
|
|
178
|
+
attributeToken ??
|
|
179
|
+
token;
|
|
180
|
+
checkValue(attrName, attribute.valueKind, attribute.value, attrSchema, valueTokenPos, reports);
|
|
181
|
+
}
|
|
182
|
+
// ---- missing required. Unlike the type/enum checks above, this runs
|
|
183
|
+
// even for `dynamic` attributes: upstream enforces `required` purely on
|
|
184
|
+
// absence, independent of `type`/`matches`/a tag-level `validate()`.
|
|
185
|
+
// The realm schema has attributes that are both `required` and
|
|
186
|
+
// `dynamic` (`diagram.file`, `diagram.type`, `code-snippet.file`), so
|
|
187
|
+
// skipping those would silently diverge from upstream. (`partial.file`
|
|
188
|
+
// carries no `required` in the composed schema at all.)
|
|
189
|
+
//
|
|
190
|
+
// Presence folds three sources: named attributes, the positional
|
|
191
|
+
// primary (any value kind -- even a `bareword`, whose shape is
|
|
192
|
+
// `markdoc-syntax`'s report; it still occupies the slot, so `required`
|
|
193
|
+
// is satisfied and nothing double-reports), and class/id shortcuts.
|
|
194
|
+
const presentNames = new Set(lastByName.keys());
|
|
195
|
+
if (primaryPresent)
|
|
196
|
+
presentNames.add('primary');
|
|
197
|
+
for (const shortcut of parsed.shortcuts ?? [])
|
|
198
|
+
presentNames.add(shortcut.kind);
|
|
199
|
+
for (const [attrName, attrSchema] of Object.entries(attributes)) {
|
|
200
|
+
if (!attrSchema.required || presentNames.has(attrName))
|
|
201
|
+
continue;
|
|
202
|
+
reports.push({
|
|
203
|
+
line: token.startLine,
|
|
204
|
+
column: token.startColumn,
|
|
205
|
+
context: `"${tagName}" is missing its required "${attrName}" attribute`,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
// ---- duplicate-attribute. One pass over the positional primary, every
|
|
209
|
+
// named attribute and every shortcut IN SOURCE ORDER, replicating real
|
|
210
|
+
// Markdoc's own parser, the only place it raises this error:
|
|
211
|
+
//
|
|
212
|
+
// - The positional primary, a named attribute and an `id` shortcut all
|
|
213
|
+
// go through one branch upstream, which checks whether the name is
|
|
214
|
+
// already set, reports if so, then marks it set either way. The
|
|
215
|
+
// primary always sits at the lowest offset, so it can only ever be
|
|
216
|
+
// the item something else collides WITH, never the collider.
|
|
217
|
+
// - A `class` shortcut takes a separate branch that never checks -- it
|
|
218
|
+
// only merges into the `class` map -- so class shortcuts never
|
|
219
|
+
// collide with each other.
|
|
220
|
+
// - Hence an order-dependent asymmetry: `{% t .a class="b" %}` reports
|
|
221
|
+
// a duplicate, while `{% t class="b" .a %}` reports nothing. Walking
|
|
222
|
+
// in true source order reproduces both verdicts; direction-agnostic
|
|
223
|
+
// set membership would not.
|
|
224
|
+
const shortcutTokens = token.children.filter((child) => child.type === 'markdocShortcut');
|
|
225
|
+
const duplicateItems = [
|
|
226
|
+
...(parsed.primary
|
|
227
|
+
? [
|
|
228
|
+
{
|
|
229
|
+
offset: parsed.primary.valueStart,
|
|
230
|
+
checked: true,
|
|
231
|
+
name: 'primary',
|
|
232
|
+
position: primaryToken ?? token,
|
|
233
|
+
},
|
|
234
|
+
]
|
|
235
|
+
: []),
|
|
236
|
+
...parsed.attributes.map((attribute, index) => ({
|
|
237
|
+
offset: attribute.nameStart,
|
|
238
|
+
checked: true,
|
|
239
|
+
name: attribute.name,
|
|
240
|
+
position: attributeTokens[index]?.children.find((child) => child.type === 'markdocAttributeName') ??
|
|
241
|
+
attributeTokens[index] ??
|
|
242
|
+
token,
|
|
243
|
+
})),
|
|
244
|
+
...(parsed.shortcuts ?? []).map((shortcut, index) => ({
|
|
245
|
+
offset: shortcut.start,
|
|
246
|
+
checked: shortcut.kind === 'id',
|
|
247
|
+
name: shortcut.kind, // the schema attribute it folds into, not its own text
|
|
248
|
+
position: shortcutTokens[index] ?? token,
|
|
249
|
+
})),
|
|
250
|
+
];
|
|
251
|
+
duplicateItems.sort((a, b) => a.offset - b.offset);
|
|
252
|
+
const setNames = new Set();
|
|
253
|
+
for (const item of duplicateItems) {
|
|
254
|
+
if (item.checked && setNames.has(item.name)) {
|
|
255
|
+
reports.push({
|
|
256
|
+
line: item.position.startLine,
|
|
257
|
+
column: item.position.startColumn,
|
|
258
|
+
context: `"${item.name}" is already set earlier on this tag`,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
setNames.add(item.name);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
reports.sort((a, b) => a.line - b.line || a.column - b.column);
|
|
265
|
+
for (const report of reports)
|
|
266
|
+
ctx.onError(report);
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
//# sourceMappingURL=markdoc-attributes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdoc-attributes.js","sourceRoot":"","sources":["../../../src/rules/token/markdoc-attributes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdoc-pairing.d.ts","sourceRoot":"","sources":["../../../src/rules/token/markdoc-pairing.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAiB7C,eAAO,MAAM,cAAc,EAAE,SAsE5B,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tag's own name, from its synthesized `markdocTagName` child. Only
|
|
3
|
+
* `tag-open`/`tag-close` tokens ever reach a pairing bucket and both always
|
|
4
|
+
* carry a name child, so the `''` fallback is defensive only.
|
|
5
|
+
*/
|
|
6
|
+
function tagName(token) {
|
|
7
|
+
return token.children.find((child) => child.type === 'markdocTagName')?.text ?? '';
|
|
8
|
+
}
|
|
9
|
+
export const markdocPairing = {
|
|
10
|
+
name: 'markdoc-pairing',
|
|
11
|
+
tags: ['markdoc'],
|
|
12
|
+
fixable: false,
|
|
13
|
+
defaults: {
|
|
14
|
+
message: '%s',
|
|
15
|
+
},
|
|
16
|
+
check(ctx) {
|
|
17
|
+
if (!ctx.markdoc)
|
|
18
|
+
return; // flag off -- no markdocTag tokens exist to pair at all
|
|
19
|
+
const { pairing, selfClosingTags } = ctx.markdoc;
|
|
20
|
+
// Each bucket below has its own order, so emitting inline would
|
|
21
|
+
// interleave lines (a line-90 unclosed before a line-12 orphan). Reports
|
|
22
|
+
// are collected and sorted into document order before they leave the rule.
|
|
23
|
+
const reports = [];
|
|
24
|
+
for (const open of pairing.unclosed) {
|
|
25
|
+
reports.push({
|
|
26
|
+
token: open,
|
|
27
|
+
context: `"${tagName(open)}" is opened here but never closed before the document ends`,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
for (const close of pairing.orphaned) {
|
|
31
|
+
// The open may exist but be malformed (e.g. a multi-line tag inside a
|
|
32
|
+
// blockquote) rather than genuinely absent, so the message must not
|
|
33
|
+
// claim the open is missing.
|
|
34
|
+
reports.push({
|
|
35
|
+
token: close,
|
|
36
|
+
context: `"/${tagName(close)}" close tag found, but no well-formed matching open was found`,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
for (const pair of pairing.crossed) {
|
|
40
|
+
reports.push({
|
|
41
|
+
token: pair.open,
|
|
42
|
+
context: `"${tagName(pair.open)}" and its close are interleaved (crossed) with another tag pair instead of properly nested — Markdoc requires tags to nest`,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
for (const open of pairing.voidMissingSlash) {
|
|
46
|
+
const name = tagName(open);
|
|
47
|
+
reports.push({ token: open, context: `"${name}" is self-closing — write {% ${name} /%}` });
|
|
48
|
+
}
|
|
49
|
+
// Self-closing tag used with an explicit close, detected from `pairs`
|
|
50
|
+
// since no bucket covers it. Without a schema the set is empty, which
|
|
51
|
+
// makes this inert just as `voidMissingSlash` already is.
|
|
52
|
+
if (selfClosingTags.size > 0) {
|
|
53
|
+
for (const pair of pairing.pairs) {
|
|
54
|
+
const name = tagName(pair.open);
|
|
55
|
+
if (!selfClosingTags.has(name))
|
|
56
|
+
continue;
|
|
57
|
+
reports.push({
|
|
58
|
+
token: pair.open,
|
|
59
|
+
context: `"${name}" is self-closing and must not be used with a matching {% /${name} %} close — write {% ${name} /%} instead`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
reports.sort((a, b) => a.token.startLine - b.token.startLine || a.token.startColumn - b.token.startColumn);
|
|
64
|
+
for (const report of reports) {
|
|
65
|
+
ctx.onError({
|
|
66
|
+
line: report.token.startLine,
|
|
67
|
+
column: report.token.startColumn,
|
|
68
|
+
context: report.context,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=markdoc-pairing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdoc-pairing.js","sourceRoot":"","sources":["../../../src/rules/token/markdoc-pairing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdoc-syntax.d.ts","sourceRoot":"","sources":["../../../src/rules/token/markdoc-syntax.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,eAAO,MAAM,aAAa,EAAE,SAgG3B,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// Grammar-level Markdoc syntax validation -- detection-only. Uses
|
|
2
|
+
// `markdocKind` as a cheap short-circuit, then re-parses each tag's own text
|
|
3
|
+
// via `parseMarkdocSpan` for the semantic detail the `Token` never retains:
|
|
4
|
+
// the parse `reason` and each attribute/primary's `valueKind`. Re-parsing
|
|
5
|
+
// keeps this rule from forcing a `reason`/`attributes` field onto the `Token`
|
|
6
|
+
// shape that it would be the only consumer of.
|
|
7
|
+
//
|
|
8
|
+
// Every check here is GRAMMAR-level, so it fires the same way on a custom tag
|
|
9
|
+
// and under `schema: false` as under the realm schema -- real Markdoc rejects
|
|
10
|
+
// these shapes regardless of any schema. That is why this rule never reads
|
|
11
|
+
// `ctx.markdoc.schema`, only the flag-is-on signal.
|
|
12
|
+
//
|
|
13
|
+
// Reports:
|
|
14
|
+
// - `malformed` spans, with the parser's `reason`, positioned at the offending
|
|
15
|
+
// character when `reasonOffset` gives one.
|
|
16
|
+
// - close tags carrying attributes: Markdoc's close-tag production is `'/'
|
|
17
|
+
// TagName` only, but recheck's span parser parses an attribute list anyway,
|
|
18
|
+
// so this rule is what surfaces it.
|
|
19
|
+
// - bareword values in an attribute OR the positional `primary` slot, both
|
|
20
|
+
// critical parse errors upstream. `primary` is checked as its own field
|
|
21
|
+
// because iterating `attributes` alone would miss it.
|
|
22
|
+
//
|
|
23
|
+
// Deliberately never reports: `{%- -%}` trim markers (stripped before parsing
|
|
24
|
+
// sees them), glued attributes (`a=1b=2`, parsed as two attributes),
|
|
25
|
+
// duplicate attributes (`markdoc-attributes` owns the class/id-fold-aware
|
|
26
|
+
// version), or annotation/variable/function kinds (out of scope; skipped
|
|
27
|
+
// explicitly below rather than relying on their attribute lists being empty).
|
|
28
|
+
import { filterByTypes } from '../../parser/index.js';
|
|
29
|
+
import { parseMarkdocSpan } from '../../parser/markdoc/span.js';
|
|
30
|
+
import { offsetToPosition } from '../../parser/markdoc/structure.js';
|
|
31
|
+
export const markdocSyntax = {
|
|
32
|
+
name: 'markdoc-syntax',
|
|
33
|
+
tags: ['markdoc'],
|
|
34
|
+
fixable: false,
|
|
35
|
+
defaults: {
|
|
36
|
+
message: 'Markdoc syntax error',
|
|
37
|
+
},
|
|
38
|
+
check(ctx) {
|
|
39
|
+
// Flag off: no `markdocTag` tokens exist in the tree at all, so this is a
|
|
40
|
+
// defensive no-op rather than something the loop below must handle.
|
|
41
|
+
if (!ctx.markdoc)
|
|
42
|
+
return;
|
|
43
|
+
for (const token of filterByTypes(ctx.tree, ['markdocTag'])) {
|
|
44
|
+
// Annotation/variable/function bodies are out of scope. Skipping up
|
|
45
|
+
// front is cheaper and clearer than relying on their attribute lists
|
|
46
|
+
// coming back empty.
|
|
47
|
+
if (token.markdocKind === 'annotation' ||
|
|
48
|
+
token.markdocKind === 'variable' ||
|
|
49
|
+
token.markdocKind === 'function') {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const parsed = parseMarkdocSpan(token.text);
|
|
53
|
+
if (parsed.kind === 'malformed') {
|
|
54
|
+
// `reasonOffset` is relative to the span text, so it is converted to
|
|
55
|
+
// a document position instead of quoted in the message -- a
|
|
56
|
+
// span-relative "at position 7" next to the report's own absolute
|
|
57
|
+
// column reads as a contradiction. When the scanner had no single
|
|
58
|
+
// offending position (empty body, missing delimiter), the tag's own
|
|
59
|
+
// start stands in.
|
|
60
|
+
const position = parsed.reasonOffset === undefined
|
|
61
|
+
? { line: token.startLine, column: token.startColumn }
|
|
62
|
+
: offsetToPosition(token, parsed.reasonOffset);
|
|
63
|
+
ctx.onError({
|
|
64
|
+
line: position.line,
|
|
65
|
+
column: position.column,
|
|
66
|
+
context: token.text,
|
|
67
|
+
detail: parsed.reason,
|
|
68
|
+
});
|
|
69
|
+
continue; // malformed spans carry no attributes/primary to check further
|
|
70
|
+
}
|
|
71
|
+
// Reported at the first attribute's own position when that synthesized
|
|
72
|
+
// child exists, falling back to the tag's start.
|
|
73
|
+
if (parsed.kind === 'tag-close' && parsed.attributes.length > 0) {
|
|
74
|
+
const firstAttribute = token.children.find((child) => child.type === 'markdocAttribute');
|
|
75
|
+
const position = firstAttribute ?? token;
|
|
76
|
+
ctx.onError({
|
|
77
|
+
line: position.startLine,
|
|
78
|
+
column: position.startColumn,
|
|
79
|
+
context: token.text,
|
|
80
|
+
detail: `close tag "{% /${parsed.name} %}" must not carry attributes — Markdoc's close-tag syntax accepts none`,
|
|
81
|
+
});
|
|
82
|
+
// Stop here: the fix just reported is to delete the whole attribute
|
|
83
|
+
// list, so also advising a reader to quote a bareword inside it would
|
|
84
|
+
// contradict that.
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
// Primary is checked before the attribute loop because it sits right
|
|
88
|
+
// after the tag name, so its offset is always the earlier one. This rule
|
|
89
|
+
// emits as it goes and never sorts, so check order is emission order.
|
|
90
|
+
if (parsed.primary?.valueKind === 'bareword' && parsed.name !== null) {
|
|
91
|
+
const primaryToken = token.children.find((child) => child.type === 'markdocTagPrimary');
|
|
92
|
+
const position = primaryToken ?? token;
|
|
93
|
+
ctx.onError({
|
|
94
|
+
line: position.startLine,
|
|
95
|
+
column: position.startColumn,
|
|
96
|
+
context: token.text,
|
|
97
|
+
detail: `quote the value: {% ${parsed.name} "${String(parsed.primary.value)}" %}`,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
// structure.ts synthesizes attribute children in the same source order
|
|
101
|
+
// as `parsed.attributes`, so index-aligning the two arrays is safe and
|
|
102
|
+
// reuses the offset-to-position math structure.ts already did.
|
|
103
|
+
const attributeTokens = token.children.filter((child) => child.type === 'markdocAttribute');
|
|
104
|
+
parsed.attributes.forEach((attribute, index) => {
|
|
105
|
+
if (attribute.valueKind !== 'bareword')
|
|
106
|
+
return;
|
|
107
|
+
const valueToken = attributeTokens[index]?.children.find((child) => child.type === 'markdocAttributeValue');
|
|
108
|
+
const position = valueToken ?? token;
|
|
109
|
+
ctx.onError({
|
|
110
|
+
line: position.startLine,
|
|
111
|
+
column: position.startColumn,
|
|
112
|
+
context: token.text,
|
|
113
|
+
detail: `quote the value: ${attribute.name}="${String(attribute.value)}"`,
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=markdoc-syntax.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdoc-syntax.js","sourceRoot":"","sources":["../../../src/rules/token/markdoc-syntax.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdoc-unknown-tag.d.ts","sourceRoot":"","sources":["../../../src/rules/token/markdoc-unknown-tag.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAgB7C,eAAO,MAAM,iBAAiB,EAAE,SAsC/B,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Schema-aware "is this even a real tag" check; `markdoc-attributes` validates
|
|
2
|
+
// a known tag's attribute list. Detection-only, and only ever a warning: an
|
|
3
|
+
// unknown tag is often intentional -- a project's own tag, or one the schema
|
|
4
|
+
// generator couldn't statically resolve (see the carve-out below).
|
|
5
|
+
//
|
|
6
|
+
// `ctx.markdoc.schema` is `null` under `schema: false`, which makes this rule
|
|
7
|
+
// inert (parsing and pairing still run). A custom tag declared via
|
|
8
|
+
// `extend.tags` is merged into `schema.tags` by `resolveMarkdocConfig` before
|
|
9
|
+
// it reaches here, so it validates as known with no extra plumbing.
|
|
10
|
+
//
|
|
11
|
+
// Only `tag-open`/`tag-self-closing` kinds are checked: real Markdoc raises
|
|
12
|
+
// exactly one `tag-undefined` per unknown tag node, at the open, so checking
|
|
13
|
+
// the matching close would double-report the same name.
|
|
14
|
+
// `annotation`/`variable`/`function` kinds carry no tag name at all and never
|
|
15
|
+
// reach Markdoc's tag lookup either way, and `malformed` spans have no
|
|
16
|
+
// reliably parseable name and are `markdoc-syntax`'s report already.
|
|
17
|
+
import { filterByTypes } from '../../parser/index.js';
|
|
18
|
+
/**
|
|
19
|
+
* Realm registers `schemaDefinition` inline in its own markdoc options, not in
|
|
20
|
+
* the tag module `scripts/generate-markdoc-schema.mjs` reads, so it can never
|
|
21
|
+
* appear in `MARKDOC_REALM_SCHEMA` even though every Realm build has it.
|
|
22
|
+
* Without this carve-out the rule would warn on an always-valid tag name.
|
|
23
|
+
*/
|
|
24
|
+
const KNOWN_UNKNOWN_TAGS = new Set(['schemaDefinition']);
|
|
25
|
+
export const markdocUnknownTag = {
|
|
26
|
+
name: 'markdoc-unknown-tag',
|
|
27
|
+
tags: ['markdoc'],
|
|
28
|
+
fixable: false,
|
|
29
|
+
// Bare placeholder: every `onError` call supplies the complete sentence via
|
|
30
|
+
// `context`, so tests can assert whole messages with `toBe`.
|
|
31
|
+
defaults: {
|
|
32
|
+
message: '%s',
|
|
33
|
+
},
|
|
34
|
+
check(ctx) {
|
|
35
|
+
if (!ctx.markdoc)
|
|
36
|
+
return; // flag off -- no markdocTag tokens exist at all
|
|
37
|
+
const { schema } = ctx.markdoc;
|
|
38
|
+
if (!schema)
|
|
39
|
+
return; // `schema: false` -- nothing to check tag names against
|
|
40
|
+
// Collected then sorted rather than reported inline: `tree.flat` happens
|
|
41
|
+
// to yield `markdocTag` tokens in document order today, but that is not a
|
|
42
|
+
// guarantee this rule should lean on silently.
|
|
43
|
+
const reports = [];
|
|
44
|
+
for (const token of filterByTypes(ctx.tree, ['markdocTag'])) {
|
|
45
|
+
if (token.markdocKind !== 'tag-open' && token.markdocKind !== 'tag-self-closing')
|
|
46
|
+
continue;
|
|
47
|
+
const nameChild = token.children.find((child) => child.type === 'markdocTagName');
|
|
48
|
+
const name = nameChild?.text;
|
|
49
|
+
if (!name)
|
|
50
|
+
continue; // defensive only: both kinds always carry a name child
|
|
51
|
+
if (schema.tags[name] || KNOWN_UNKNOWN_TAGS.has(name))
|
|
52
|
+
continue;
|
|
53
|
+
reports.push({
|
|
54
|
+
line: token.startLine,
|
|
55
|
+
column: token.startColumn,
|
|
56
|
+
context: `"${name}" is not a known Markdoc tag — check for a typo, or declare it via "extend.tags" if intentional`,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
reports.sort((a, b) => a.line - b.line || a.column - b.column);
|
|
60
|
+
for (const report of reports)
|
|
61
|
+
ctx.onError(report);
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=markdoc-unknown-tag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdoc-unknown-tag.js","sourceRoot":"","sources":["../../../src/rules/token/markdoc-unknown-tag.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,4EAA4E;AAC5E,6EAA6E;AAC7E,mEAAmE;AACnE,EAAE;AACF,8EAA8E;AAC9E,mEAAmE;AACnE,8EAA8E;AAC9E,oEAAoE;AACpE,EAAE;AACF,4EAA4E;AAC5E,6EAA6E;AAC7E,wDAAwD;AACxD,8EAA8E;AAC9E,uEAAuE;AACvE,qEAAqE;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD;;;;;GAKG;AACH,MAAM,kBAAkB,GAAwB,IAAI,GAAG,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAQ9E,MAAM,CAAC,MAAM,iBAAiB,GAAc;IAC1C,IAAI,EAAE,qBAAqB;IAC3B,IAAI,EAAE,CAAC,SAAS,CAAC;IACjB,OAAO,EAAE,KAAK;IACd,4EAA4E;IAC5E,6DAA6D;IAC7D,QAAQ,EAAE;QACR,OAAO,EAAE,IAAI;KACd;IACD,KAAK,CAAC,GAAG;QACP,IAAI,CAAC,GAAG,CAAC,OAAO;YAAE,OAAO,CAAC,gDAAgD;QAC1E,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,wDAAwD;QAE7E,yEAAyE;QACzE,0EAA0E;QAC1E,+CAA+C;QAC/C,MAAM,OAAO,GAAuB,EAAE,CAAC;QAEvC,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC;YAC5D,IAAI,KAAK,CAAC,WAAW,KAAK,UAAU,IAAI,KAAK,CAAC,WAAW,KAAK,kBAAkB;gBAAE,SAAS;YAE3F,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC;YAClF,MAAM,IAAI,GAAG,SAAS,EAAE,IAAI,CAAC;YAC7B,IAAI,CAAC,IAAI;gBAAE,SAAS,CAAC,uDAAuD;YAE5E,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,SAAS;YAEhE,OAAO,CAAC,IAAI,CAAC;gBACX,IAAI,EAAE,KAAK,CAAC,SAAS;gBACrB,MAAM,EAAE,KAAK,CAAC,WAAW;gBACzB,OAAO,EAAE,IAAI,IAAI,iGAAiG;aACnH,CAAC,CAAC;QACL,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;QAC/D,KAAK,MAAM,MAAM,IAAI,OAAO;YAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TokenRule, TokenRuleOnErrorInfo } from '../types.js';
|
|
2
|
+
export declare function formatTemplate(template: string, ...values: string[]): string;
|
|
3
|
+
export declare function formatTokenMessage(configMessage: string | undefined, rule: TokenRule, info: TokenRuleOnErrorInfo): string;
|
|
4
|
+
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/rules/token/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAEnE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAU5E;AAED,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,oBAAoB,GACzB,MAAM,CAMR"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export function formatTemplate(template, ...values) {
|
|
2
|
+
let result = '';
|
|
3
|
+
let rest = template;
|
|
4
|
+
for (const value of values) {
|
|
5
|
+
const index = rest.indexOf('%s');
|
|
6
|
+
if (index === -1)
|
|
7
|
+
break;
|
|
8
|
+
result += rest.slice(0, index) + value;
|
|
9
|
+
rest = rest.slice(index + 2);
|
|
10
|
+
}
|
|
11
|
+
return result + rest;
|
|
12
|
+
}
|
|
13
|
+
export function formatTokenMessage(configMessage, rule, info) {
|
|
14
|
+
const base = configMessage ?? String(rule.defaults.message ?? rule.name);
|
|
15
|
+
const substituted = info.context ? formatTemplate(base, info.context) : base;
|
|
16
|
+
return info.detail && !substituted.includes(info.detail)
|
|
17
|
+
? `${substituted} (${info.detail})`
|
|
18
|
+
: substituted;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/rules/token/messages.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,GAAG,MAAgB;IAClE,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,IAAI,GAAG,QAAQ,CAAC;IACpB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,MAAM;QACxB,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC;QACvC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,MAAM,GAAG,IAAI,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,aAAiC,EACjC,IAAe,EACf,IAA0B;IAE1B,MAAM,IAAI,GAAG,aAAa,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;IACzE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7E,OAAO,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;QACtD,CAAC,CAAC,GAAG,WAAW,KAAK,IAAI,CAAC,MAAM,GAAG;QACnC,CAAC,CAAC,WAAW,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-alt-text.d.ts","sourceRoot":"","sources":["../../../src/rules/token/no-alt-text.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAQ7C,eAAO,MAAM,SAAS,EAAE,SA2CvB,CAAC"}
|