@herb-tools/linter 0.7.5 → 0.8.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 +253 -13
- package/dist/herb-lint.js +26023 -3424
- package/dist/herb-lint.js.map +1 -1
- package/dist/index.cjs +5759 -1583
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5727 -1584
- package/dist/index.js.map +1 -1
- package/dist/loader.cjs +17010 -0
- package/dist/loader.cjs.map +1 -0
- package/dist/loader.js +16879 -0
- package/dist/loader.js.map +1 -0
- package/dist/package.json +13 -5
- package/dist/src/cli/argument-parser.js +38 -33
- package/dist/src/cli/argument-parser.js.map +1 -1
- package/dist/src/cli/file-processor.js +124 -23
- package/dist/src/cli/file-processor.js.map +1 -1
- package/dist/src/cli/formatters/detailed-formatter.js +18 -3
- package/dist/src/cli/formatters/detailed-formatter.js.map +1 -1
- package/dist/src/cli/formatters/github-actions-formatter.js +15 -1
- package/dist/src/cli/formatters/github-actions-formatter.js.map +1 -1
- package/dist/src/cli/formatters/json-formatter.js +3 -0
- package/dist/src/cli/formatters/json-formatter.js.map +1 -1
- package/dist/src/cli/formatters/simple-formatter.js +20 -7
- package/dist/src/cli/formatters/simple-formatter.js.map +1 -1
- package/dist/src/cli/output-manager.js +22 -3
- package/dist/src/cli/output-manager.js.map +1 -1
- package/dist/src/cli/summary-reporter.js +26 -3
- package/dist/src/cli/summary-reporter.js.map +1 -1
- package/dist/src/cli.js +107 -42
- package/dist/src/cli.js.map +1 -1
- package/dist/src/custom-rule-loader.js +139 -0
- package/dist/src/custom-rule-loader.js.map +1 -0
- package/dist/src/herb-disable-comment-utils.js +129 -0
- package/dist/src/herb-disable-comment-utils.js.map +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/linter.js +369 -34
- package/dist/src/linter.js.map +1 -1
- package/dist/src/loader.js +17 -0
- package/dist/src/loader.js.map +1 -0
- package/dist/src/rules/erb-comment-syntax.js +31 -2
- package/dist/src/rules/erb-comment-syntax.js.map +1 -1
- package/dist/src/rules/erb-no-case-node-children.js +52 -0
- package/dist/src/rules/erb-no-case-node-children.js.map +1 -0
- package/dist/src/rules/erb-no-empty-tags.js +7 -1
- package/dist/src/rules/erb-no-empty-tags.js.map +1 -1
- package/dist/src/rules/erb-no-extra-newline.js +65 -0
- package/dist/src/rules/erb-no-extra-newline.js.map +1 -0
- package/dist/src/rules/erb-no-extra-whitespace-inside-tags.js +95 -0
- package/dist/src/rules/erb-no-extra-whitespace-inside-tags.js.map +1 -0
- package/dist/src/rules/erb-no-output-control-flow.js +7 -1
- package/dist/src/rules/erb-no-output-control-flow.js.map +1 -1
- package/dist/src/rules/erb-no-silent-tag-in-attribute-name.js +7 -1
- package/dist/src/rules/erb-no-silent-tag-in-attribute-name.js.map +1 -1
- package/dist/src/rules/erb-prefer-image-tag-helper.js +7 -1
- package/dist/src/rules/erb-prefer-image-tag-helper.js.map +1 -1
- package/dist/src/rules/erb-require-trailing-newline.js +35 -0
- package/dist/src/rules/erb-require-trailing-newline.js.map +1 -0
- package/dist/src/rules/erb-require-whitespace-inside-tags.js +69 -11
- package/dist/src/rules/erb-require-whitespace-inside-tags.js.map +1 -1
- package/dist/src/rules/erb-right-trim.js +26 -9
- package/dist/src/rules/erb-right-trim.js.map +1 -1
- package/dist/src/rules/herb-disable-comment-base.js +51 -0
- package/dist/src/rules/herb-disable-comment-base.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-malformed.js +51 -0
- package/dist/src/rules/herb-disable-comment-malformed.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-missing-rules.js +29 -0
- package/dist/src/rules/herb-disable-comment-missing-rules.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-no-duplicate-rules.js +32 -0
- package/dist/src/rules/herb-disable-comment-no-duplicate-rules.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-no-redundant-all.js +31 -0
- package/dist/src/rules/herb-disable-comment-no-redundant-all.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-unnecessary.js +65 -0
- package/dist/src/rules/herb-disable-comment-unnecessary.js.map +1 -0
- package/dist/src/rules/herb-disable-comment-valid-rule-name.js +44 -0
- package/dist/src/rules/herb-disable-comment-valid-rule-name.js.map +1 -0
- package/dist/src/rules/html-anchor-require-href.js +7 -1
- package/dist/src/rules/html-anchor-require-href.js.map +1 -1
- package/dist/src/rules/html-aria-attribute-must-be-valid.js +7 -1
- package/dist/src/rules/html-aria-attribute-must-be-valid.js.map +1 -1
- package/dist/src/rules/html-aria-label-is-well-formatted.js +9 -3
- package/dist/src/rules/html-aria-label-is-well-formatted.js.map +1 -1
- package/dist/src/rules/html-aria-level-must-be-valid.js +6 -0
- package/dist/src/rules/html-aria-level-must-be-valid.js.map +1 -1
- package/dist/src/rules/html-aria-role-heading-requires-level.js +7 -1
- package/dist/src/rules/html-aria-role-heading-requires-level.js.map +1 -1
- package/dist/src/rules/html-aria-role-must-be-valid.js +7 -1
- package/dist/src/rules/html-aria-role-must-be-valid.js.map +1 -1
- package/dist/src/rules/html-attribute-double-quotes.js +29 -2
- package/dist/src/rules/html-attribute-double-quotes.js.map +1 -1
- package/dist/src/rules/html-attribute-equals-spacing.js +18 -2
- package/dist/src/rules/html-attribute-equals-spacing.js.map +1 -1
- package/dist/src/rules/html-attribute-values-require-quotes.js +39 -3
- package/dist/src/rules/html-attribute-values-require-quotes.js.map +1 -1
- package/dist/src/rules/html-avoid-both-disabled-and-aria-disabled.js +7 -1
- package/dist/src/rules/html-avoid-both-disabled-and-aria-disabled.js.map +1 -1
- package/dist/src/rules/html-body-only-elements.js +46 -0
- package/dist/src/rules/html-body-only-elements.js.map +1 -0
- package/dist/src/rules/html-boolean-attributes-no-value.js +18 -1
- package/dist/src/rules/html-boolean-attributes-no-value.js.map +1 -1
- package/dist/src/rules/html-head-only-elements.js +51 -0
- package/dist/src/rules/html-head-only-elements.js.map +1 -0
- package/dist/src/rules/html-iframe-has-title.js +8 -2
- package/dist/src/rules/html-iframe-has-title.js.map +1 -1
- package/dist/src/rules/html-img-require-alt.js +7 -1
- package/dist/src/rules/html-img-require-alt.js.map +1 -1
- package/dist/src/rules/html-input-require-autocomplete.js +70 -0
- package/dist/src/rules/html-input-require-autocomplete.js.map +1 -0
- package/dist/src/rules/html-navigation-has-label.js +7 -1
- package/dist/src/rules/html-navigation-has-label.js.map +1 -1
- package/dist/src/rules/html-no-aria-hidden-on-focusable.js +7 -1
- package/dist/src/rules/html-no-aria-hidden-on-focusable.js.map +1 -1
- package/dist/src/rules/html-no-block-inside-inline.js +7 -1
- package/dist/src/rules/html-no-block-inside-inline.js.map +1 -1
- package/dist/src/rules/html-no-duplicate-attributes.js +7 -1
- package/dist/src/rules/html-no-duplicate-attributes.js.map +1 -1
- package/dist/src/rules/html-no-duplicate-ids.js +9 -3
- package/dist/src/rules/html-no-duplicate-ids.js.map +1 -1
- package/dist/src/rules/html-no-duplicate-meta-names.js +136 -0
- package/dist/src/rules/html-no-duplicate-meta-names.js.map +1 -0
- package/dist/src/rules/html-no-empty-attributes.js +45 -7
- package/dist/src/rules/html-no-empty-attributes.js.map +1 -1
- package/dist/src/rules/html-no-empty-headings.js +7 -6
- package/dist/src/rules/html-no-empty-headings.js.map +1 -1
- package/dist/src/rules/html-no-nested-links.js +7 -1
- package/dist/src/rules/html-no-nested-links.js.map +1 -1
- package/dist/src/rules/html-no-positive-tab-index.js +7 -1
- package/dist/src/rules/html-no-positive-tab-index.js.map +1 -1
- package/dist/src/rules/html-no-self-closing.js +48 -3
- package/dist/src/rules/html-no-self-closing.js.map +1 -1
- package/dist/src/rules/html-no-space-in-tag.js +173 -0
- package/dist/src/rules/html-no-space-in-tag.js.map +1 -0
- package/dist/src/rules/html-no-title-attribute.js +7 -1
- package/dist/src/rules/html-no-title-attribute.js.map +1 -1
- package/dist/src/rules/html-no-underscores-in-attribute-names.js +7 -1
- package/dist/src/rules/html-no-underscores-in-attribute-names.js.map +1 -1
- package/dist/src/rules/html-tag-name-lowercase.js +23 -5
- package/dist/src/rules/html-tag-name-lowercase.js.map +1 -1
- package/dist/src/rules/index.js +19 -3
- package/dist/src/rules/index.js.map +1 -1
- package/dist/src/rules/parser-no-errors.js +6 -0
- package/dist/src/rules/parser-no-errors.js.map +1 -1
- package/dist/src/rules/rule-utils.js +211 -31
- package/dist/src/rules/rule-utils.js.map +1 -1
- package/dist/src/rules/svg-tag-name-capitalization.js +22 -2
- package/dist/src/rules/svg-tag-name-capitalization.js.map +1 -1
- package/dist/src/{default-rules.js → rules.js} +44 -16
- package/dist/src/rules.js.map +1 -0
- package/dist/src/types.js +34 -1
- package/dist/src/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/cli/argument-parser.d.ts +8 -2
- package/dist/types/cli/file-processor.d.ts +15 -0
- package/dist/types/cli/formatters/json-formatter.d.ts +6 -0
- package/dist/types/cli/formatters/simple-formatter.d.ts +1 -0
- package/dist/types/cli/summary-reporter.d.ts +6 -0
- package/dist/types/cli.d.ts +9 -4
- package/dist/types/custom-rule-loader.d.ts +62 -0
- package/dist/types/herb-disable-comment-utils.d.ts +69 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/linter.d.ts +99 -3
- package/dist/types/loader.d.ts +20 -0
- package/dist/types/rules/erb-comment-syntax.d.ts +12 -5
- package/dist/types/rules/erb-no-case-node-children.d.ts +8 -0
- package/dist/types/rules/erb-no-empty-tags.d.ts +3 -2
- package/dist/types/rules/erb-no-extra-newline.d.ts +14 -0
- package/dist/types/rules/erb-no-extra-whitespace-inside-tags.d.ts +18 -0
- package/dist/types/rules/erb-no-output-control-flow.d.ts +3 -2
- package/dist/types/rules/erb-no-silent-tag-in-attribute-name.d.ts +3 -2
- package/dist/types/rules/erb-prefer-image-tag-helper.d.ts +3 -2
- package/dist/types/rules/erb-require-trailing-newline.d.ts +9 -0
- package/dist/types/rules/erb-require-whitespace-inside-tags.d.ts +16 -5
- package/dist/types/rules/erb-right-trim.d.ts +12 -5
- package/dist/types/rules/herb-disable-comment-base.d.ts +37 -0
- package/dist/types/rules/herb-disable-comment-malformed.d.ts +8 -0
- package/dist/types/rules/herb-disable-comment-missing-rules.d.ts +8 -0
- package/dist/types/rules/herb-disable-comment-no-duplicate-rules.d.ts +8 -0
- package/dist/types/rules/herb-disable-comment-no-redundant-all.d.ts +8 -0
- package/dist/types/rules/herb-disable-comment-unnecessary.d.ts +8 -0
- package/dist/types/rules/herb-disable-comment-valid-rule-name.d.ts +8 -0
- package/dist/types/rules/html-anchor-require-href.d.ts +3 -2
- package/dist/types/rules/html-aria-attribute-must-be-valid.d.ts +3 -2
- package/dist/types/rules/html-aria-label-is-well-formatted.d.ts +3 -2
- package/dist/types/rules/html-aria-level-must-be-valid.d.ts +3 -2
- package/dist/types/rules/html-aria-role-heading-requires-level.d.ts +3 -2
- package/dist/types/rules/html-aria-role-must-be-valid.d.ts +3 -2
- package/dist/types/rules/html-attribute-double-quotes.d.ts +13 -5
- package/dist/types/rules/html-attribute-equals-spacing.d.ts +12 -5
- package/dist/types/rules/html-attribute-values-require-quotes.d.ts +13 -5
- package/dist/types/rules/html-avoid-both-disabled-and-aria-disabled.d.ts +3 -2
- package/dist/types/rules/html-body-only-elements.d.ts +9 -0
- package/dist/types/rules/html-boolean-attributes-no-value.d.ts +12 -5
- package/dist/types/rules/html-head-only-elements.d.ts +9 -0
- package/dist/types/rules/html-iframe-has-title.d.ts +3 -2
- package/dist/types/rules/html-img-require-alt.d.ts +3 -2
- package/dist/types/rules/html-input-require-autocomplete.d.ts +8 -0
- package/dist/types/rules/html-navigation-has-label.d.ts +3 -2
- package/dist/types/rules/html-no-aria-hidden-on-focusable.d.ts +3 -2
- package/dist/types/rules/html-no-block-inside-inline.d.ts +3 -2
- package/dist/types/rules/html-no-duplicate-attributes.d.ts +3 -2
- package/dist/types/rules/html-no-duplicate-ids.d.ts +3 -2
- package/dist/types/rules/html-no-duplicate-meta-names.d.ts +9 -0
- package/dist/types/rules/html-no-empty-attributes.d.ts +3 -2
- package/dist/types/rules/html-no-empty-headings.d.ts +3 -2
- package/dist/types/rules/html-no-nested-links.d.ts +3 -2
- package/dist/types/rules/html-no-positive-tab-index.d.ts +3 -2
- package/dist/types/rules/html-no-self-closing.d.ts +14 -5
- package/dist/types/rules/html-no-space-in-tag.d.ts +16 -0
- package/dist/types/rules/html-no-title-attribute.d.ts +3 -2
- package/dist/types/rules/html-no-underscores-in-attribute-names.d.ts +3 -2
- package/dist/types/rules/html-tag-name-lowercase.d.ts +16 -6
- package/dist/types/rules/index.d.ts +19 -3
- package/dist/types/rules/parser-no-errors.d.ts +2 -1
- package/dist/types/rules/rule-utils.d.ts +72 -25
- package/dist/types/rules/svg-tag-name-capitalization.d.ts +13 -4
- package/dist/types/rules.d.ts +2 -0
- package/dist/types/src/cli/argument-parser.d.ts +8 -2
- package/dist/types/src/cli/file-processor.d.ts +15 -0
- package/dist/types/src/cli/formatters/json-formatter.d.ts +6 -0
- package/dist/types/src/cli/formatters/simple-formatter.d.ts +1 -0
- package/dist/types/src/cli/summary-reporter.d.ts +6 -0
- package/dist/types/src/cli.d.ts +9 -4
- package/dist/types/src/custom-rule-loader.d.ts +62 -0
- package/dist/types/src/herb-disable-comment-utils.d.ts +69 -0
- package/dist/types/src/index.d.ts +1 -0
- package/dist/types/src/linter.d.ts +99 -3
- package/dist/types/src/loader.d.ts +20 -0
- package/dist/types/src/rules/erb-comment-syntax.d.ts +12 -5
- package/dist/types/src/rules/erb-no-case-node-children.d.ts +8 -0
- package/dist/types/src/rules/erb-no-empty-tags.d.ts +3 -2
- package/dist/types/src/rules/erb-no-extra-newline.d.ts +14 -0
- package/dist/types/src/rules/erb-no-extra-whitespace-inside-tags.d.ts +18 -0
- package/dist/types/src/rules/erb-no-output-control-flow.d.ts +3 -2
- package/dist/types/src/rules/erb-no-silent-tag-in-attribute-name.d.ts +3 -2
- package/dist/types/src/rules/erb-prefer-image-tag-helper.d.ts +3 -2
- package/dist/types/src/rules/erb-require-trailing-newline.d.ts +9 -0
- package/dist/types/src/rules/erb-require-whitespace-inside-tags.d.ts +16 -5
- package/dist/types/src/rules/erb-right-trim.d.ts +12 -5
- package/dist/types/src/rules/herb-disable-comment-base.d.ts +37 -0
- package/dist/types/src/rules/herb-disable-comment-malformed.d.ts +8 -0
- package/dist/types/src/rules/herb-disable-comment-missing-rules.d.ts +8 -0
- package/dist/types/src/rules/herb-disable-comment-no-duplicate-rules.d.ts +8 -0
- package/dist/types/src/rules/herb-disable-comment-no-redundant-all.d.ts +8 -0
- package/dist/types/src/rules/herb-disable-comment-unnecessary.d.ts +8 -0
- package/dist/types/src/rules/herb-disable-comment-valid-rule-name.d.ts +8 -0
- package/dist/types/src/rules/html-anchor-require-href.d.ts +3 -2
- package/dist/types/src/rules/html-aria-attribute-must-be-valid.d.ts +3 -2
- package/dist/types/src/rules/html-aria-label-is-well-formatted.d.ts +3 -2
- package/dist/types/src/rules/html-aria-level-must-be-valid.d.ts +3 -2
- package/dist/types/src/rules/html-aria-role-heading-requires-level.d.ts +3 -2
- package/dist/types/src/rules/html-aria-role-must-be-valid.d.ts +3 -2
- package/dist/types/src/rules/html-attribute-double-quotes.d.ts +13 -5
- package/dist/types/src/rules/html-attribute-equals-spacing.d.ts +12 -5
- package/dist/types/src/rules/html-attribute-values-require-quotes.d.ts +13 -5
- package/dist/types/src/rules/html-avoid-both-disabled-and-aria-disabled.d.ts +3 -2
- package/dist/types/src/rules/html-body-only-elements.d.ts +9 -0
- package/dist/types/src/rules/html-boolean-attributes-no-value.d.ts +12 -5
- package/dist/types/src/rules/html-head-only-elements.d.ts +9 -0
- package/dist/types/src/rules/html-iframe-has-title.d.ts +3 -2
- package/dist/types/src/rules/html-img-require-alt.d.ts +3 -2
- package/dist/types/src/rules/html-input-require-autocomplete.d.ts +8 -0
- package/dist/types/src/rules/html-navigation-has-label.d.ts +3 -2
- package/dist/types/src/rules/html-no-aria-hidden-on-focusable.d.ts +3 -2
- package/dist/types/src/rules/html-no-block-inside-inline.d.ts +3 -2
- package/dist/types/src/rules/html-no-duplicate-attributes.d.ts +3 -2
- package/dist/types/src/rules/html-no-duplicate-ids.d.ts +3 -2
- package/dist/types/src/rules/html-no-duplicate-meta-names.d.ts +9 -0
- package/dist/types/src/rules/html-no-empty-attributes.d.ts +3 -2
- package/dist/types/src/rules/html-no-empty-headings.d.ts +3 -2
- package/dist/types/src/rules/html-no-nested-links.d.ts +3 -2
- package/dist/types/src/rules/html-no-positive-tab-index.d.ts +3 -2
- package/dist/types/src/rules/html-no-self-closing.d.ts +14 -5
- package/dist/types/src/rules/html-no-space-in-tag.d.ts +16 -0
- package/dist/types/src/rules/html-no-title-attribute.d.ts +3 -2
- package/dist/types/src/rules/html-no-underscores-in-attribute-names.d.ts +3 -2
- package/dist/types/src/rules/html-tag-name-lowercase.d.ts +16 -6
- package/dist/types/src/rules/index.d.ts +19 -3
- package/dist/types/src/rules/parser-no-errors.d.ts +2 -1
- package/dist/types/src/rules/rule-utils.d.ts +72 -25
- package/dist/types/src/rules/svg-tag-name-capitalization.d.ts +13 -4
- package/dist/types/src/rules.d.ts +2 -0
- package/dist/types/src/types.d.ts +102 -11
- package/dist/types/types.d.ts +102 -11
- package/docs/rules/README.md +16 -2
- package/docs/rules/erb-no-case-node-children.md +50 -0
- package/docs/rules/erb-no-extra-newline.md +74 -0
- package/docs/rules/erb-no-extra-whitespace-inside-tags.md +39 -0
- package/docs/rules/{erb-requires-trailing-newline.md → erb-require-trailing-newline.md} +1 -1
- package/docs/rules/erb-right-trim.md +5 -10
- package/docs/rules/herb-disable-comment-malformed.md +45 -0
- package/docs/rules/herb-disable-comment-missing-rules.md +60 -0
- package/docs/rules/herb-disable-comment-no-duplicate-rules.md +49 -0
- package/docs/rules/herb-disable-comment-no-redundant-all.md +53 -0
- package/docs/rules/herb-disable-comment-unnecessary.md +44 -0
- package/docs/rules/herb-disable-comment-valid-rule-name.md +41 -0
- package/docs/rules/html-aria-attribute-must-be-valid.md +2 -5
- package/docs/rules/html-aria-label-is-well-formatted.md +1 -1
- package/docs/rules/html-attribute-double-quotes.md +2 -2
- package/docs/rules/html-attribute-equals-spacing.md +2 -2
- package/docs/rules/html-attribute-values-require-quotes.md +3 -3
- package/docs/rules/html-avoid-both-disabled-and-aria-disabled.md +2 -2
- package/docs/rules/html-body-only-elements.md +99 -0
- package/docs/rules/html-boolean-attributes-no-value.md +2 -2
- package/docs/rules/html-head-only-elements.md +81 -0
- package/docs/rules/html-input-require-autocomplete.md +64 -0
- package/docs/rules/html-no-aria-hidden-on-focusable.md +2 -2
- package/docs/rules/html-no-duplicate-attributes.md +2 -2
- package/docs/rules/html-no-duplicate-meta-names.md +64 -0
- package/docs/rules/html-no-empty-attributes.md +3 -3
- package/docs/rules/html-no-empty-headings.md +4 -26
- package/docs/rules/html-no-positive-tab-index.md +1 -2
- package/docs/rules/html-no-self-closing.md +17 -2
- package/docs/rules/html-no-space-in-tag.md +66 -0
- package/docs/rules/html-no-title-attribute.md +2 -2
- package/docs/rules/html-no-underscores-in-attribute-names.md +2 -2
- package/docs/rules/html-tag-name-lowercase.md +2 -2
- package/package.json +13 -5
- package/src/cli/argument-parser.ts +46 -37
- package/src/cli/file-processor.ts +159 -28
- package/src/cli/formatters/detailed-formatter.ts +21 -3
- package/src/cli/formatters/github-actions-formatter.ts +17 -1
- package/src/cli/formatters/json-formatter.ts +9 -0
- package/src/cli/formatters/simple-formatter.ts +24 -8
- package/src/cli/output-manager.ts +23 -3
- package/src/cli/summary-reporter.ts +40 -3
- package/src/cli.ts +134 -51
- package/src/custom-rule-loader.ts +189 -0
- package/src/herb-disable-comment-utils.ts +175 -0
- package/src/index.ts +2 -0
- package/src/linter.ts +501 -36
- package/src/loader.ts +30 -0
- package/src/rules/erb-comment-syntax.ts +53 -10
- package/src/rules/erb-no-case-node-children.ts +68 -0
- package/src/rules/erb-no-empty-tags.ts +9 -3
- package/src/rules/erb-no-extra-newline.ts +91 -0
- package/src/rules/erb-no-extra-whitespace-inside-tags.ts +147 -0
- package/src/rules/erb-no-output-control-flow.ts +9 -3
- package/src/rules/erb-no-silent-tag-in-attribute-name.ts +9 -3
- package/src/rules/erb-prefer-image-tag-helper.ts +9 -3
- package/src/rules/erb-require-trailing-newline.ts +47 -0
- package/src/rules/erb-require-whitespace-inside-tags.ts +94 -16
- package/src/rules/erb-right-trim.ts +45 -22
- package/src/rules/herb-disable-comment-base.ts +76 -0
- package/src/rules/herb-disable-comment-malformed.ts +66 -0
- package/src/rules/herb-disable-comment-missing-rules.ts +41 -0
- package/src/rules/herb-disable-comment-no-duplicate-rules.ts +46 -0
- package/src/rules/herb-disable-comment-no-redundant-all.ts +40 -0
- package/src/rules/herb-disable-comment-unnecessary.ts +103 -0
- package/src/rules/herb-disable-comment-valid-rule-name.ts +62 -0
- package/src/rules/html-anchor-require-href.ts +9 -3
- package/src/rules/html-aria-attribute-must-be-valid.ts +9 -3
- package/src/rules/html-aria-label-is-well-formatted.ts +9 -5
- package/src/rules/html-aria-level-must-be-valid.ts +9 -2
- package/src/rules/html-aria-role-heading-requires-level.ts +9 -3
- package/src/rules/html-aria-role-must-be-valid.ts +9 -3
- package/src/rules/html-attribute-double-quotes.ts +42 -8
- package/src/rules/html-attribute-equals-spacing.ts +31 -7
- package/src/rules/html-attribute-values-require-quotes.ts +56 -10
- package/src/rules/html-avoid-both-disabled-and-aria-disabled.ts +9 -3
- package/src/rules/html-body-only-elements.ts +60 -0
- package/src/rules/html-boolean-attributes-no-value.ts +31 -6
- package/src/rules/html-head-only-elements.ts +65 -0
- package/src/rules/html-iframe-has-title.ts +9 -4
- package/src/rules/html-img-require-alt.ts +10 -4
- package/src/rules/html-input-require-autocomplete.ts +85 -0
- package/src/rules/html-navigation-has-label.ts +9 -3
- package/src/rules/html-no-aria-hidden-on-focusable.ts +9 -3
- package/src/rules/html-no-block-inside-inline.ts +9 -3
- package/src/rules/html-no-duplicate-attributes.ts +9 -3
- package/src/rules/html-no-duplicate-ids.ts +11 -7
- package/src/rules/html-no-duplicate-meta-names.ts +188 -0
- package/src/rules/html-no-empty-attributes.ts +58 -10
- package/src/rules/html-no-empty-headings.ts +10 -8
- package/src/rules/html-no-nested-links.ts +10 -4
- package/src/rules/html-no-positive-tab-index.ts +9 -3
- package/src/rules/html-no-self-closing.ts +69 -9
- package/src/rules/html-no-space-in-tag.ts +221 -0
- package/src/rules/html-no-title-attribute.ts +9 -3
- package/src/rules/html-no-underscores-in-attribute-names.ts +12 -4
- package/src/rules/html-tag-name-lowercase.ts +41 -10
- package/src/rules/index.ts +23 -3
- package/src/rules/parser-no-errors.ts +8 -1
- package/src/rules/rule-utils.ts +248 -42
- package/src/rules/svg-tag-name-capitalization.ts +39 -6
- package/src/{default-rules.ts → rules.ts} +51 -15
- package/src/types.ts +133 -15
- package/dist/src/default-rules.js.map +0 -1
- package/dist/src/rules/erb-requires-trailing-newline.js +0 -22
- package/dist/src/rules/erb-requires-trailing-newline.js.map +0 -1
- package/dist/types/default-rules.d.ts +0 -2
- package/dist/types/rules/erb-requires-trailing-newline.d.ts +0 -6
- package/dist/types/src/default-rules.d.ts +0 -2
- package/dist/types/src/rules/erb-requires-trailing-newline.d.ts +0 -6
- package/src/rules/erb-requires-trailing-newline.ts +0 -29
package/dist/src/linter.js
CHANGED
|
@@ -1,24 +1,104 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Location } from "@herb-tools/core";
|
|
2
|
+
import { IdentityPrinter } from "@herb-tools/printer";
|
|
3
|
+
import { minimatch } from "minimatch";
|
|
4
|
+
import { rules } from "./rules.js";
|
|
5
|
+
import { findNodeByLocation } from "./rules/rule-utils.js";
|
|
6
|
+
import { parseHerbDisableLine } from "./herb-disable-comment-utils.js";
|
|
7
|
+
import { ParserNoErrorsRule } from "./rules/parser-no-errors.js";
|
|
8
|
+
import { DEFAULT_RULE_CONFIG } from "./types.js";
|
|
2
9
|
export class Linter {
|
|
3
10
|
rules;
|
|
11
|
+
allAvailableRules;
|
|
4
12
|
herb;
|
|
5
13
|
offenses;
|
|
14
|
+
config;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new Linter instance with automatic rule filtering based on config.
|
|
17
|
+
*
|
|
18
|
+
* @param herb - The Herb backend instance for parsing and lexing
|
|
19
|
+
* @param config - Optional full Config instance for rule filtering, severity overrides, and path-based filtering
|
|
20
|
+
* @param customRules - Optional array of custom rules to include alongside built-in rules
|
|
21
|
+
* @returns A configured Linter instance
|
|
22
|
+
*/
|
|
23
|
+
static from(herb, config, customRules) {
|
|
24
|
+
const allRules = customRules ? [...rules, ...customRules] : rules;
|
|
25
|
+
const filteredRules = config?.linter?.rules
|
|
26
|
+
? Linter.filterRulesByConfig(allRules, config.linter.rules)
|
|
27
|
+
: undefined;
|
|
28
|
+
return new Linter(herb, filteredRules, config, allRules);
|
|
29
|
+
}
|
|
6
30
|
/**
|
|
7
31
|
* Creates a new Linter instance.
|
|
32
|
+
*
|
|
33
|
+
* For most use cases, prefer `Linter.from()` which handles config-based filtering.
|
|
34
|
+
* Use this constructor directly when you need explicit control over rules.
|
|
35
|
+
*
|
|
8
36
|
* @param herb - The Herb backend instance for parsing and lexing
|
|
9
37
|
* @param rules - Array of rule classes (Parser/AST or Lexer) to use. If not provided, uses default rules.
|
|
38
|
+
* @param config - Optional full Config instance for severity overrides and path-based rule filtering
|
|
39
|
+
* @param allAvailableRules - Optional array of ALL available rules (including disabled) for herb:disable validation
|
|
10
40
|
*/
|
|
11
|
-
constructor(herb, rules) {
|
|
41
|
+
constructor(herb, rules, config, allAvailableRules) {
|
|
12
42
|
this.herb = herb;
|
|
43
|
+
this.config = config;
|
|
13
44
|
this.rules = rules !== undefined ? rules : this.getDefaultRules();
|
|
45
|
+
this.allAvailableRules = allAvailableRules !== undefined ? allAvailableRules : this.rules;
|
|
14
46
|
this.offenses = [];
|
|
15
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Filters rules based on default config and optional user config overrides.
|
|
50
|
+
*
|
|
51
|
+
* Priority:
|
|
52
|
+
* 1. User config override (if rule config exists in userRulesConfig)
|
|
53
|
+
* 2. Default config from rule's defaultConfig getter
|
|
54
|
+
*
|
|
55
|
+
* @param allRules - All available rule classes to filter from
|
|
56
|
+
* @param userRulesConfig - Optional user configuration for rules
|
|
57
|
+
* @returns Filtered array of rule classes that should be enabled
|
|
58
|
+
*/
|
|
59
|
+
static filterRulesByConfig(allRules, userRulesConfig) {
|
|
60
|
+
return allRules.filter(ruleClass => {
|
|
61
|
+
const instance = new ruleClass();
|
|
62
|
+
const ruleName = instance.name;
|
|
63
|
+
const defaultEnabled = instance.defaultConfig?.enabled ?? DEFAULT_RULE_CONFIG.enabled;
|
|
64
|
+
const userRuleConfig = userRulesConfig?.[ruleName];
|
|
65
|
+
if (userRuleConfig !== undefined) {
|
|
66
|
+
return userRuleConfig.enabled !== false;
|
|
67
|
+
}
|
|
68
|
+
return defaultEnabled;
|
|
69
|
+
});
|
|
70
|
+
}
|
|
16
71
|
/**
|
|
17
72
|
* Returns the default set of rule classes used by the linter.
|
|
18
|
-
*
|
|
73
|
+
* These are the rules enabled when no custom rules are provided.
|
|
74
|
+
* Filters all available rules to only include those enabled by default.
|
|
75
|
+
* @returns Array of default rule classes
|
|
19
76
|
*/
|
|
20
77
|
getDefaultRules() {
|
|
21
|
-
return
|
|
78
|
+
return Linter.filterRulesByConfig(rules);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Returns all available rule classes that can be referenced in herb:disable comments.
|
|
82
|
+
* This includes all rules that exist, regardless of whether they're currently enabled.
|
|
83
|
+
* Includes both built-in rules and any loaded custom rules.
|
|
84
|
+
* @returns Array of all available rule classes
|
|
85
|
+
*/
|
|
86
|
+
getAvailableRules() {
|
|
87
|
+
return this.allAvailableRules;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Meta-linting rules for herb:disable comments cannot be disabled
|
|
91
|
+
* This ensures that invalid herb:disable comments are always caught
|
|
92
|
+
*/
|
|
93
|
+
get nonExcludableRules() {
|
|
94
|
+
return [
|
|
95
|
+
"herb-disable-comment-valid-rule-name",
|
|
96
|
+
"herb-disable-comment-no-redundant-all",
|
|
97
|
+
"herb-disable-comment-no-duplicate-rules",
|
|
98
|
+
"herb-disable-comment-malformed",
|
|
99
|
+
"herb-disable-comment-missing-rules",
|
|
100
|
+
"herb-disable-comment-unnecessary"
|
|
101
|
+
];
|
|
22
102
|
}
|
|
23
103
|
getRuleCount() {
|
|
24
104
|
return this.rules.length;
|
|
@@ -35,6 +115,97 @@ export class Linter {
|
|
|
35
115
|
isSourceRule(rule) {
|
|
36
116
|
return rule.constructor.type === "source";
|
|
37
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Execute a single rule and return its unbound offenses.
|
|
120
|
+
* Handles rule type checking (Lexer/Parser/Source) and isEnabled checks.
|
|
121
|
+
*/
|
|
122
|
+
executeRule(rule, parseResult, lexResult, source, context) {
|
|
123
|
+
if (this.config && context?.fileName) {
|
|
124
|
+
if (!this.config.isRuleEnabledForPath(rule.name, context.fileName)) {
|
|
125
|
+
return [];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
if (context?.fileName && !this.config?.linter?.rules?.[rule.name]?.exclude) {
|
|
129
|
+
const defaultExclude = rule.defaultConfig?.exclude ?? DEFAULT_RULE_CONFIG.exclude;
|
|
130
|
+
if (defaultExclude && defaultExclude.length > 0) {
|
|
131
|
+
const isExcluded = defaultExclude.some((pattern) => minimatch(context.fileName, pattern));
|
|
132
|
+
if (isExcluded) {
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
let isEnabled = true;
|
|
138
|
+
let ruleOffenses;
|
|
139
|
+
if (this.isLexerRule(rule)) {
|
|
140
|
+
if (rule.isEnabled) {
|
|
141
|
+
isEnabled = rule.isEnabled(lexResult, context);
|
|
142
|
+
}
|
|
143
|
+
if (isEnabled) {
|
|
144
|
+
ruleOffenses = rule.check(lexResult, context);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
ruleOffenses = [];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else if (this.isSourceRule(rule)) {
|
|
151
|
+
if (rule.isEnabled) {
|
|
152
|
+
isEnabled = rule.isEnabled(source, context);
|
|
153
|
+
}
|
|
154
|
+
if (isEnabled) {
|
|
155
|
+
ruleOffenses = rule.check(source, context);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
ruleOffenses = [];
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
if (rule.isEnabled) {
|
|
163
|
+
isEnabled = rule.isEnabled(parseResult, context);
|
|
164
|
+
}
|
|
165
|
+
if (isEnabled) {
|
|
166
|
+
ruleOffenses = rule.check(parseResult, context);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
ruleOffenses = [];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return ruleOffenses;
|
|
173
|
+
}
|
|
174
|
+
filterOffenses(ruleOffenses, ruleName, ignoredOffensesByLine, herbDisableCache, ignoreDisableComments) {
|
|
175
|
+
const kept = [];
|
|
176
|
+
const ignored = [];
|
|
177
|
+
const wouldBeIgnored = [];
|
|
178
|
+
if (this.nonExcludableRules.includes(ruleName)) {
|
|
179
|
+
return { kept: ruleOffenses, ignored: [], wouldBeIgnored: [] };
|
|
180
|
+
}
|
|
181
|
+
if (ignoreDisableComments) {
|
|
182
|
+
for (const offense of ruleOffenses) {
|
|
183
|
+
const line = offense.location.start.line;
|
|
184
|
+
const disabledRules = herbDisableCache?.get(line) || [];
|
|
185
|
+
if (disabledRules.includes(ruleName) || disabledRules.includes("all")) {
|
|
186
|
+
wouldBeIgnored.push(offense);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return { kept: ruleOffenses, ignored: [], wouldBeIgnored };
|
|
190
|
+
}
|
|
191
|
+
for (const offense of ruleOffenses) {
|
|
192
|
+
const line = offense.location.start.line;
|
|
193
|
+
const disabledRules = herbDisableCache?.get(line) || [];
|
|
194
|
+
if (disabledRules.includes(ruleName) || disabledRules.includes("all")) {
|
|
195
|
+
ignored.push(offense);
|
|
196
|
+
if (ignoredOffensesByLine) {
|
|
197
|
+
if (!ignoredOffensesByLine.has(line)) {
|
|
198
|
+
ignoredOffensesByLine.set(line, new Set());
|
|
199
|
+
}
|
|
200
|
+
const usedRuleName = disabledRules.includes(ruleName) ? ruleName : "all";
|
|
201
|
+
ignoredOffensesByLine.get(line).add(usedRuleName);
|
|
202
|
+
}
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
205
|
+
kept.push(offense);
|
|
206
|
+
}
|
|
207
|
+
return { kept, ignored, wouldBeIgnored: [] };
|
|
208
|
+
}
|
|
38
209
|
/**
|
|
39
210
|
* Lint source code using Parser/AST, Lexer, and Source rules.
|
|
40
211
|
* @param source - The source code to lint
|
|
@@ -42,53 +213,217 @@ export class Linter {
|
|
|
42
213
|
*/
|
|
43
214
|
lint(source, context) {
|
|
44
215
|
this.offenses = [];
|
|
216
|
+
let ignoredCount = 0;
|
|
217
|
+
let wouldBeIgnoredCount = 0;
|
|
45
218
|
const parseResult = this.herb.parse(source, { track_whitespace: true });
|
|
46
219
|
const lexResult = this.herb.lex(source);
|
|
47
|
-
|
|
220
|
+
const hasParserErrors = parseResult.recursiveErrors().length > 0;
|
|
221
|
+
const sourceLines = source.split("\n");
|
|
222
|
+
const ignoredOffensesByLine = new Map();
|
|
223
|
+
const herbDisableCache = new Map();
|
|
224
|
+
if (hasParserErrors) {
|
|
225
|
+
const hasParserRule = this.rules.find(RuleClass => (new RuleClass()).name === "parser-no-errors");
|
|
226
|
+
if (hasParserRule) {
|
|
227
|
+
const rule = new ParserNoErrorsRule();
|
|
228
|
+
const offenses = rule.check(parseResult);
|
|
229
|
+
this.offenses.push(...offenses);
|
|
230
|
+
}
|
|
231
|
+
return {
|
|
232
|
+
offenses: this.offenses,
|
|
233
|
+
errors: this.offenses.filter(o => o.severity === "error").length,
|
|
234
|
+
warnings: this.offenses.filter(o => o.severity === "warning").length,
|
|
235
|
+
info: this.offenses.filter(o => o.severity === "info").length,
|
|
236
|
+
hints: this.offenses.filter(o => o.severity === "hint").length,
|
|
237
|
+
ignored: 0
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
for (let i = 0; i < sourceLines.length; i++) {
|
|
241
|
+
const line = sourceLines[i];
|
|
242
|
+
if (line.includes("herb:disable")) {
|
|
243
|
+
const herbDisable = parseHerbDisableLine(line);
|
|
244
|
+
herbDisableCache.set(i + 1, herbDisable?.ruleNames || []);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
context = {
|
|
248
|
+
...context,
|
|
249
|
+
validRuleNames: this.getAvailableRules().map(RuleClass => new RuleClass().name),
|
|
250
|
+
ignoredOffensesByLine
|
|
251
|
+
};
|
|
252
|
+
const regularRules = this.rules.filter(RuleClass => {
|
|
48
253
|
const rule = new RuleClass();
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
254
|
+
return rule.name !== "herb-disable-comment-unnecessary";
|
|
255
|
+
});
|
|
256
|
+
for (const RuleClass of regularRules) {
|
|
257
|
+
const rule = new RuleClass();
|
|
258
|
+
const unboundOffenses = this.executeRule(rule, parseResult, lexResult, source, context);
|
|
259
|
+
const boundOffenses = this.bindSeverity(unboundOffenses, rule.name);
|
|
260
|
+
const { kept, ignored, wouldBeIgnored } = this.filterOffenses(boundOffenses, rule.name, ignoredOffensesByLine, herbDisableCache, context?.ignoreDisableComments);
|
|
261
|
+
ignoredCount += ignored.length;
|
|
262
|
+
wouldBeIgnoredCount += wouldBeIgnored.length;
|
|
263
|
+
this.offenses.push(...kept);
|
|
264
|
+
}
|
|
265
|
+
const unnecessaryRuleClass = this.rules.find(RuleClass => {
|
|
266
|
+
const rule = new RuleClass();
|
|
267
|
+
return rule.name === "herb-disable-comment-unnecessary";
|
|
268
|
+
});
|
|
269
|
+
if (unnecessaryRuleClass) {
|
|
270
|
+
const unnecessaryRule = new unnecessaryRuleClass();
|
|
271
|
+
const unboundOffenses = unnecessaryRule.check(parseResult, context);
|
|
272
|
+
const boundOffenses = this.bindSeverity(unboundOffenses, unnecessaryRule.name);
|
|
273
|
+
this.offenses.push(...boundOffenses);
|
|
274
|
+
}
|
|
275
|
+
const finalOffenses = this.offenses;
|
|
276
|
+
const errors = finalOffenses.filter(offense => offense.severity === "error").length;
|
|
277
|
+
const warnings = finalOffenses.filter(offense => offense.severity === "warning").length;
|
|
278
|
+
const info = finalOffenses.filter(offense => offense.severity === "info").length;
|
|
279
|
+
const hints = finalOffenses.filter(offense => offense.severity === "hint").length;
|
|
280
|
+
const result = {
|
|
281
|
+
offenses: finalOffenses,
|
|
282
|
+
errors,
|
|
283
|
+
warnings,
|
|
284
|
+
info,
|
|
285
|
+
hints,
|
|
286
|
+
ignored: ignoredCount
|
|
287
|
+
};
|
|
288
|
+
if (wouldBeIgnoredCount > 0) {
|
|
289
|
+
result.wouldBeIgnored = wouldBeIgnoredCount;
|
|
290
|
+
}
|
|
291
|
+
return result;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Bind severity to unbound offenses based on rule's defaultConfig and user config overrides.
|
|
295
|
+
*
|
|
296
|
+
* Priority:
|
|
297
|
+
* 1. User config severity override (if specified in config)
|
|
298
|
+
* 2. Rule's default severity (from defaultConfig.severity)
|
|
299
|
+
*
|
|
300
|
+
* @param unboundOffenses - Array of offenses without severity
|
|
301
|
+
* @param ruleName - Name of the rule that produced the offenses
|
|
302
|
+
* @returns Array of offenses with severity bound
|
|
303
|
+
*/
|
|
304
|
+
bindSeverity(unboundOffenses, ruleName) {
|
|
305
|
+
const RuleClass = this.rules.find(rule => {
|
|
306
|
+
const instance = new rule();
|
|
307
|
+
return instance.name === ruleName;
|
|
308
|
+
});
|
|
309
|
+
if (!RuleClass) {
|
|
310
|
+
return unboundOffenses.map(offense => ({
|
|
311
|
+
...offense,
|
|
312
|
+
severity: "error"
|
|
313
|
+
}));
|
|
314
|
+
}
|
|
315
|
+
const ruleInstance = new RuleClass();
|
|
316
|
+
const defaultSeverity = ruleInstance.defaultConfig?.severity ?? DEFAULT_RULE_CONFIG.severity;
|
|
317
|
+
const userRuleConfig = this.config?.linter?.rules?.[ruleName];
|
|
318
|
+
const severity = userRuleConfig?.severity ?? defaultSeverity;
|
|
319
|
+
return unboundOffenses.map(offense => ({
|
|
320
|
+
...offense,
|
|
321
|
+
severity
|
|
322
|
+
}));
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Automatically fix offenses in the source code.
|
|
326
|
+
* Uses AST mutation for parser rules and token mutation for lexer rules.
|
|
327
|
+
* @param source - The source code to fix
|
|
328
|
+
* @param context - Optional context for linting (e.g., fileName)
|
|
329
|
+
* @param offensesToFix - Optional array of specific offenses to fix. If not provided, all fixable offenses will be fixed.
|
|
330
|
+
* @returns AutofixResult containing the corrected source and lists of fixed/unfixed offenses
|
|
331
|
+
*/
|
|
332
|
+
autofix(source, context, offensesToFix) {
|
|
333
|
+
const lintResult = offensesToFix ? { offenses: offensesToFix } : this.lint(source, context);
|
|
334
|
+
const parserOffenses = [];
|
|
335
|
+
const lexerOffenses = [];
|
|
336
|
+
const sourceOffenses = [];
|
|
337
|
+
for (const offense of lintResult.offenses) {
|
|
338
|
+
const RuleClass = this.rules.find(rule => {
|
|
339
|
+
const instance = new rule();
|
|
340
|
+
return instance.name === offense.rule;
|
|
341
|
+
});
|
|
342
|
+
if (!RuleClass)
|
|
343
|
+
continue;
|
|
344
|
+
if (RuleClass.type === "lexer") {
|
|
345
|
+
lexerOffenses.push(offense);
|
|
346
|
+
}
|
|
347
|
+
else if (RuleClass.type === "source") {
|
|
348
|
+
sourceOffenses.push(offense);
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
parserOffenses.push(offense);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
let currentSource = source;
|
|
355
|
+
const fixed = [];
|
|
356
|
+
const unfixed = [];
|
|
357
|
+
if (parserOffenses.length > 0) {
|
|
358
|
+
const parseResult = this.herb.parse(currentSource, { track_whitespace: true });
|
|
359
|
+
for (const offense of parserOffenses) {
|
|
360
|
+
const RuleClass = this.rules.find(rule => new rule().name === offense.rule);
|
|
361
|
+
if (!RuleClass) {
|
|
362
|
+
unfixed.push(offense);
|
|
363
|
+
continue;
|
|
57
364
|
}
|
|
58
|
-
|
|
59
|
-
|
|
365
|
+
const rule = new RuleClass();
|
|
366
|
+
if (!rule.autofix) {
|
|
367
|
+
unfixed.push(offense);
|
|
368
|
+
continue;
|
|
60
369
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
370
|
+
if (offense.autofixContext) {
|
|
371
|
+
const originalNodeType = offense.autofixContext.node.type;
|
|
372
|
+
const location = offense.autofixContext.node.location ? Location.from(offense.autofixContext.node.location) : offense.location;
|
|
373
|
+
const freshNode = findNodeByLocation(parseResult.value, location, (node) => node.type === originalNodeType);
|
|
374
|
+
if (freshNode) {
|
|
375
|
+
offense.autofixContext.node = freshNode;
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
unfixed.push(offense);
|
|
379
|
+
continue;
|
|
380
|
+
}
|
|
65
381
|
}
|
|
66
|
-
|
|
67
|
-
|
|
382
|
+
const fixedResult = rule.autofix(offense, parseResult, context);
|
|
383
|
+
if (fixedResult) {
|
|
384
|
+
fixed.push(offense);
|
|
68
385
|
}
|
|
69
386
|
else {
|
|
70
|
-
|
|
387
|
+
unfixed.push(offense);
|
|
71
388
|
}
|
|
72
389
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
390
|
+
if (fixed.length > 0) {
|
|
391
|
+
const printer = new IdentityPrinter();
|
|
392
|
+
currentSource = printer.print(parseResult.value);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
if (sourceOffenses.length > 0) {
|
|
396
|
+
const sortedSourceOffenses = sourceOffenses.sort((a, b) => {
|
|
397
|
+
if (a.location.start.line !== b.location.start.line) {
|
|
398
|
+
return b.location.start.line - a.location.start.line;
|
|
399
|
+
}
|
|
400
|
+
return b.location.start.column - a.location.start.column;
|
|
401
|
+
});
|
|
402
|
+
for (const offense of sortedSourceOffenses) {
|
|
403
|
+
const RuleClass = this.rules.find(rule => new rule().name === offense.rule);
|
|
404
|
+
if (!RuleClass) {
|
|
405
|
+
unfixed.push(offense);
|
|
406
|
+
continue;
|
|
76
407
|
}
|
|
77
|
-
|
|
78
|
-
|
|
408
|
+
const rule = new RuleClass();
|
|
409
|
+
if (!rule.autofix) {
|
|
410
|
+
unfixed.push(offense);
|
|
411
|
+
continue;
|
|
412
|
+
}
|
|
413
|
+
const correctedSource = rule.autofix(offense, currentSource, context);
|
|
414
|
+
if (correctedSource) {
|
|
415
|
+
currentSource = correctedSource;
|
|
416
|
+
fixed.push(offense);
|
|
79
417
|
}
|
|
80
418
|
else {
|
|
81
|
-
|
|
419
|
+
unfixed.push(offense);
|
|
82
420
|
}
|
|
83
421
|
}
|
|
84
|
-
this.offenses.push(...ruleOffenses);
|
|
85
422
|
}
|
|
86
|
-
const errors = this.offenses.filter(offense => offense.severity === "error").length;
|
|
87
|
-
const warnings = this.offenses.filter(offense => offense.severity === "warning").length;
|
|
88
423
|
return {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
424
|
+
source: currentSource,
|
|
425
|
+
fixed,
|
|
426
|
+
unfixed
|
|
92
427
|
};
|
|
93
428
|
}
|
|
94
429
|
}
|
package/dist/src/linter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"linter.js","sourceRoot":"","sources":["../../src/linter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"linter.js","sourceRoot":"","sources":["../../src/linter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export * from "./index.js";
|
|
2
|
+
export { CustomRuleLoader } from "./custom-rule-loader.js";
|
|
3
|
+
import { CustomRuleLoader } from "./custom-rule-loader.js";
|
|
4
|
+
/**
|
|
5
|
+
* Loads custom rules from the filesystem.
|
|
6
|
+
* Only available in Node.js environments.
|
|
7
|
+
*/
|
|
8
|
+
export async function loadCustomRules(options) {
|
|
9
|
+
const loader = new CustomRuleLoader(options);
|
|
10
|
+
const { rules: customRules, ruleInfo, duplicateWarnings } = await loader.loadRulesWithInfo();
|
|
11
|
+
return {
|
|
12
|
+
rules: customRules,
|
|
13
|
+
ruleInfo,
|
|
14
|
+
warnings: duplicateWarnings
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/loader.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAE1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAG1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AAG1D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAIrC;IAKC,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAC5C,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,EAAE,CAAA;IAE5F,OAAO;QACL,KAAK,EAAE,WAAW;QAClB,QAAQ;QACR,QAAQ,EAAE,iBAAiB;KAC5B,CAAA;AACH,CAAC"}
|
|
@@ -2,18 +2,47 @@ import { BaseRuleVisitor } from "./rule-utils.js";
|
|
|
2
2
|
import { ParserRule } from "../types.js";
|
|
3
3
|
class ERBCommentSyntaxVisitor extends BaseRuleVisitor {
|
|
4
4
|
visitERBContentNode(node) {
|
|
5
|
-
|
|
5
|
+
const content = node.content?.value || "";
|
|
6
|
+
if (content.match(/^ +#/)) {
|
|
6
7
|
const openingTag = node.tag_opening?.value;
|
|
7
|
-
|
|
8
|
+
if (content.includes("herb:disable")) {
|
|
9
|
+
this.addOffense(`Use \`<%#\` instead of \`${openingTag} #\` for \`herb:disable\` directives. Herb directives only work with ERB comment syntax (\`<%# ... %>\`).`, node.location, { node });
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
this.addOffense(`Use \`<%#\` instead of \`${openingTag} #\`. Ruby comments immediately after ERB tags can cause parsing issues.`, node.location, { node });
|
|
13
|
+
}
|
|
8
14
|
}
|
|
9
15
|
}
|
|
10
16
|
}
|
|
11
17
|
export class ERBCommentSyntax extends ParserRule {
|
|
18
|
+
static autocorrectable = true;
|
|
12
19
|
name = "erb-comment-syntax";
|
|
20
|
+
get defaultConfig() {
|
|
21
|
+
return {
|
|
22
|
+
enabled: true,
|
|
23
|
+
severity: "error"
|
|
24
|
+
};
|
|
25
|
+
}
|
|
13
26
|
check(result, context) {
|
|
14
27
|
const visitor = new ERBCommentSyntaxVisitor(this.name, context);
|
|
15
28
|
visitor.visit(result.value);
|
|
16
29
|
return visitor.offenses;
|
|
17
30
|
}
|
|
31
|
+
autofix(offense, result, _context) {
|
|
32
|
+
if (!offense.autofixContext)
|
|
33
|
+
return null;
|
|
34
|
+
const { node } = offense.autofixContext;
|
|
35
|
+
if (!node.tag_opening)
|
|
36
|
+
return null;
|
|
37
|
+
if (!node.content)
|
|
38
|
+
return null;
|
|
39
|
+
node.tag_opening.value = "<%#";
|
|
40
|
+
const content = node.content.value;
|
|
41
|
+
const match = content.match(/^ +(#)/);
|
|
42
|
+
if (match) {
|
|
43
|
+
node.content.value = content.substring(match[0].length);
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
18
47
|
}
|
|
19
48
|
//# sourceMappingURL=erb-comment-syntax.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"erb-comment-syntax.js","sourceRoot":"","sources":["../../../src/rules/erb-comment-syntax.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"erb-comment-syntax.js","sourceRoot":"","sources":["../../../src/rules/erb-comment-syntax.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,UAAU,EAA+B,MAAM,aAAa,CAAA;AASrE,MAAM,uBAAwB,SAAQ,eAA+C;IACnF,mBAAmB,CAAC,IAAoB;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAA;QAEzC,IAAI,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,KAAK,CAAA;YAE1C,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;gBACrC,IAAI,CAAC,UAAU,CACb,4BAA4B,UAAU,2GAA2G,EACjJ,IAAI,CAAC,QAAQ,EACb,EAAE,IAAI,EAAE,CACT,CAAA;YACH,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,UAAU,CACb,4BAA4B,UAAU,0EAA0E,EAChH,IAAI,CAAC,QAAQ,EACb,EAAE,IAAI,EAAE,CACT,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAED,MAAM,OAAO,gBAAiB,SAAQ,UAA0C;IAC9E,MAAM,CAAC,eAAe,GAAG,IAAI,CAAA;IAC7B,IAAI,GAAG,oBAAoB,CAAA;IAE3B,IAAI,aAAa;QACf,OAAO;YACL,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,OAAO;SAClB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,MAAmB,EAAE,OAA8B;QACvD,MAAM,OAAO,GAAG,IAAI,uBAAuB,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAE/D,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAE3B,OAAO,OAAO,CAAC,QAAQ,CAAA;IACzB,CAAC;IAED,OAAO,CAAC,OAAoD,EAAE,MAAmB,EAAE,QAA+B;QAChH,IAAI,CAAC,OAAO,CAAC,cAAc;YAAE,OAAO,IAAI,CAAA;QAExC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,cAAc,CAAA;QAEvC,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO,IAAI,CAAA;QAClC,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAA;QAE9B,IAAI,CAAC,WAAW,CAAC,KAAK,GAAG,KAAK,CAAA;QAE9B,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAA;QAClC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAErC,IAAI,KAAK,EAAE,CAAC;YACV,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;QACzD,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { BaseRuleVisitor } from "./rule-utils.js";
|
|
2
|
+
import { ParserRule } from "../types.js";
|
|
3
|
+
import { isWhitespaceNode, isLiteralNode, isHTMLTextNode, isCommentNode, isERBNode } from "@herb-tools/core";
|
|
4
|
+
import { IdentityPrinter } from "@herb-tools/printer";
|
|
5
|
+
class ERBNoCaseNodeChildrenVisitor extends BaseRuleVisitor {
|
|
6
|
+
visitERBCaseNode(node) {
|
|
7
|
+
this.checkCaseNodeChildren(node, "when");
|
|
8
|
+
this.visitChildNodes(node);
|
|
9
|
+
}
|
|
10
|
+
visitERBCaseMatchNode(node) {
|
|
11
|
+
this.checkCaseNodeChildren(node, "in");
|
|
12
|
+
this.visitChildNodes(node);
|
|
13
|
+
}
|
|
14
|
+
checkCaseNodeChildren(node, type) {
|
|
15
|
+
if (!node.children || node.children.length === 0)
|
|
16
|
+
return;
|
|
17
|
+
const caseCode = IdentityPrinter.printERBNode(node);
|
|
18
|
+
const firstCondition = node.conditions?.[0];
|
|
19
|
+
const conditionCode = firstCondition && isERBNode(firstCondition) ? IdentityPrinter.printERBNode(firstCondition) : `<% ${type} ... %>`;
|
|
20
|
+
for (const child of node.children) {
|
|
21
|
+
if (!this.isAllowedContent(child)) {
|
|
22
|
+
const childCode = IdentityPrinter.print(child).trim();
|
|
23
|
+
this.addOffense(`Do not place \`${childCode}\` between \`${caseCode}\` and \`${conditionCode}\`. Content here is not part of any branch and will not be rendered.`, child.location);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
isAllowedContent(node) {
|
|
28
|
+
if (isWhitespaceNode(node))
|
|
29
|
+
return true;
|
|
30
|
+
if (isCommentNode(node))
|
|
31
|
+
return true;
|
|
32
|
+
if (isLiteralNode(node) || isHTMLTextNode(node)) {
|
|
33
|
+
return /^\s*$/.test(node.content);
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export class ERBNoCaseNodeChildrenRule extends ParserRule {
|
|
39
|
+
name = "erb-no-case-node-children";
|
|
40
|
+
get defaultConfig() {
|
|
41
|
+
return {
|
|
42
|
+
enabled: true,
|
|
43
|
+
severity: "error"
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
check(result, context) {
|
|
47
|
+
const visitor = new ERBNoCaseNodeChildrenVisitor(this.name, context);
|
|
48
|
+
visitor.visit(result.value);
|
|
49
|
+
return visitor.offenses;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=erb-no-case-node-children.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"erb-no-case-node-children.js","sourceRoot":"","sources":["../../../src/rules/erb-no-case-node-children.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5G,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAKrD,MAAM,4BAA6B,SAAQ,eAAe;IACxD,gBAAgB,CAAC,IAAiB;QAChC,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACxC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;IAC5B,CAAC;IAED,qBAAqB,CAAC,IAAsB;QAC1C,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QACtC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;IAC5B,CAAC;IAEO,qBAAqB,CAAC,IAAoC,EAAE,IAAY;QAC9E,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAExD,MAAM,QAAQ,GAAG,eAAe,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;QACnD,MAAM,cAAc,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAA;QAC3C,MAAM,aAAa,GAAG,cAAc,IAAI,SAAS,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,SAAS,CAAA;QAEtI,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClC,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAA;gBAErD,IAAI,CAAC,UAAU,CACb,kBAAkB,SAAS,gBAAgB,QAAQ,YAAY,aAAa,sEAAsE,EAClJ,KAAK,CAAC,QAAQ,CACf,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAEO,gBAAgB,CAAC,IAAU;QACjC,IAAI,gBAAgB,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QACvC,IAAI,aAAa,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAA;QAEpC,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACnC,CAAC;QAED,OAAO,KAAK,CAAA;IACd,CAAC;CACF;AAED,MAAM,OAAO,yBAA0B,SAAQ,UAAU;IACvD,IAAI,GAAG,2BAA2B,CAAA;IAElC,IAAI,aAAa;QACf,OAAO;YACL,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,OAAO;SAClB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,MAAmB,EAAE,OAA8B;QACvD,MAAM,OAAO,GAAG,IAAI,4BAA4B,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAEpE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAE3B,OAAO,OAAO,CAAC,QAAQ,CAAA;IACzB,CAAC;CACF"}
|
|
@@ -10,11 +10,17 @@ class ERBNoEmptyTagsVisitor extends BaseRuleVisitor {
|
|
|
10
10
|
return;
|
|
11
11
|
if (content.value.trim().length > 0)
|
|
12
12
|
return;
|
|
13
|
-
this.addOffense("ERB tag should not be empty. Remove empty ERB tags or add content.", node.location
|
|
13
|
+
this.addOffense("ERB tag should not be empty. Remove empty ERB tags or add content.", node.location);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
export class ERBNoEmptyTagsRule extends ParserRule {
|
|
17
17
|
name = "erb-no-empty-tags";
|
|
18
|
+
get defaultConfig() {
|
|
19
|
+
return {
|
|
20
|
+
enabled: true,
|
|
21
|
+
severity: "error"
|
|
22
|
+
};
|
|
23
|
+
}
|
|
18
24
|
check(result, context) {
|
|
19
25
|
const visitor = new ERBNoEmptyTagsVisitor(this.name, context);
|
|
20
26
|
visitor.visit(result.value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"erb-no-empty-tags.js","sourceRoot":"","sources":["../../../src/rules/erb-no-empty-tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAIxC,MAAM,qBAAsB,SAAQ,eAAe;IACjD,mBAAmB,CAAC,IAAoB;QACtC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;QAE1B,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,CAAA;QAErC,IAAI,CAAC,OAAO;YAAE,OAAM;QACpB,IAAI,WAAW,EAAE,KAAK,KAAK,EAAE;YAAE,OAAM;QACrC,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;YAAE,OAAM;QAE3C,IAAI,CAAC,UAAU,CACb,oEAAoE,EACpE,IAAI,CAAC,QAAQ,
|
|
1
|
+
{"version":3,"file":"erb-no-empty-tags.js","sourceRoot":"","sources":["../../../src/rules/erb-no-empty-tags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAIxC,MAAM,qBAAsB,SAAQ,eAAe;IACjD,mBAAmB,CAAC,IAAoB;QACtC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;QAE1B,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,CAAA;QAErC,IAAI,CAAC,OAAO;YAAE,OAAM;QACpB,IAAI,WAAW,EAAE,KAAK,KAAK,EAAE;YAAE,OAAM;QACrC,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC;YAAE,OAAM;QAE3C,IAAI,CAAC,UAAU,CACb,oEAAoE,EACpE,IAAI,CAAC,QAAQ,CACd,CAAA;IACH,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,UAAU;IAChD,IAAI,GAAG,mBAAmB,CAAA;IAE1B,IAAI,aAAa;QACf,OAAO;YACL,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,OAAO;SAClB,CAAA;IACH,CAAC;IAED,KAAK,CAAC,MAAmB,EAAE,OAA8B;QACvD,MAAM,OAAO,GAAG,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAE7D,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAE3B,OAAO,OAAO,CAAC,QAAQ,CAAA;IACzB,CAAC;CACF"}
|