pickier 0.1.28 → 0.1.29
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/dist/ast.d.ts +13 -0
- package/dist/bin/cli.js +507 -302
- package/dist/plugins/eslint.d.ts +2 -0
- package/dist/plugins/general.d.ts +2 -0
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/lockfile.d.ts +22 -0
- package/dist/plugins/markdown.d.ts +2 -0
- package/dist/plugins/node.d.ts +2 -0
- package/dist/plugins/perfectionist.d.ts +6 -0
- package/dist/plugins/pickier.d.ts +2 -0
- package/dist/plugins/publint.d.ts +10 -0
- package/dist/plugins/quality.d.ts +2 -0
- package/dist/plugins/regexp.d.ts +2 -0
- package/dist/plugins/shell.d.ts +2 -0
- package/dist/plugins/spell.d.ts +3 -0
- package/dist/plugins/style.d.ts +2 -0
- package/dist/plugins/ts.d.ts +2 -0
- package/dist/plugins/unused-imports.d.ts +6 -0
- package/dist/plugins/utils.d.ts +4 -0
- package/dist/rules/general/_template-tracking.d.ts +31 -0
- package/dist/rules/general/array-callback-return.d.ts +2 -0
- package/dist/rules/general/constructor-super.d.ts +2 -0
- package/dist/rules/general/for-direction.d.ts +2 -0
- package/dist/rules/general/getter-return.d.ts +2 -0
- package/dist/rules/general/no-async-promise-executor.d.ts +2 -0
- package/dist/rules/general/no-compare-neg-zero.d.ts +2 -0
- package/dist/rules/general/no-cond-assign.d.ts +2 -0
- package/dist/rules/general/no-const-assign.d.ts +2 -0
- package/dist/rules/general/no-constant-condition.d.ts +2 -0
- package/dist/rules/general/no-constructor-return.d.ts +2 -0
- package/dist/rules/general/no-dupe-class-members.d.ts +2 -0
- package/dist/rules/general/no-dupe-keys.d.ts +2 -0
- package/dist/rules/general/no-duplicate-case.d.ts +2 -0
- package/dist/rules/general/no-empty-pattern.d.ts +2 -0
- package/dist/rules/general/no-fallthrough.d.ts +2 -0
- package/dist/rules/general/no-irregular-whitespace.d.ts +2 -0
- package/dist/rules/general/no-loss-of-precision.d.ts +2 -0
- package/dist/rules/general/no-new.d.ts +13 -0
- package/dist/rules/general/no-promise-executor-return.d.ts +2 -0
- package/dist/rules/general/no-redeclare.d.ts +2 -0
- package/dist/rules/general/no-regex-spaces.d.ts +10 -0
- package/dist/rules/general/no-self-assign.d.ts +2 -0
- package/dist/rules/general/no-self-compare.d.ts +2 -0
- package/dist/rules/general/no-sparse-arrays.d.ts +2 -0
- package/dist/rules/general/no-undef.d.ts +2 -0
- package/dist/rules/general/no-unreachable.d.ts +2 -0
- package/dist/rules/general/no-unsafe-negation.d.ts +2 -0
- package/dist/rules/general/no-unused-vars.d.ts +2 -0
- package/dist/rules/general/no-useless-catch.d.ts +2 -0
- package/dist/rules/general/prefer-const.d.ts +2 -0
- package/dist/rules/general/prefer-object-spread.d.ts +2 -0
- package/dist/rules/general/prefer-template.d.ts +2 -0
- package/dist/rules/general/use-isnan.d.ts +2 -0
- package/dist/rules/general/valid-typeof.d.ts +2 -0
- package/dist/rules/imports/first.d.ts +2 -0
- package/dist/rules/imports/import-dedupe.d.ts +2 -0
- package/dist/rules/imports/named.d.ts +2 -0
- package/dist/rules/imports/no-cycle.d.ts +2 -0
- package/dist/rules/imports/no-duplicate-imports.d.ts +2 -0
- package/dist/rules/imports/no-import-dist.d.ts +2 -0
- package/dist/rules/imports/no-import-node-modules-by-path.d.ts +2 -0
- package/dist/rules/imports/no-unresolved.d.ts +2 -0
- package/dist/rules/lockfile/parser.d.ts +79 -0
- package/dist/rules/lockfile/validate-host.d.ts +18 -0
- package/dist/rules/lockfile/validate-https.d.ts +14 -0
- package/dist/rules/lockfile/validate-integrity.d.ts +19 -0
- package/dist/rules/lockfile/validate-package-names.d.ts +23 -0
- package/dist/rules/lockfile/validate-scheme.d.ts +17 -0
- package/dist/rules/markdown/_fence-tracking.d.ts +32 -0
- package/dist/rules/markdown/_shared.d.ts +9 -0
- package/dist/rules/markdown/blanks-around-fences.d.ts +5 -0
- package/dist/rules/markdown/blanks-around-headings.d.ts +5 -0
- package/dist/rules/markdown/blanks-around-lists.d.ts +5 -0
- package/dist/rules/markdown/blanks-around-tables.d.ts +5 -0
- package/dist/rules/markdown/code-block-style.d.ts +5 -0
- package/dist/rules/markdown/code-fence-style.d.ts +5 -0
- package/dist/rules/markdown/commands-show-output.d.ts +5 -0
- package/dist/rules/markdown/descriptive-link-text.d.ts +5 -0
- package/dist/rules/markdown/emphasis-style.d.ts +5 -0
- package/dist/rules/markdown/fenced-code-language.d.ts +5 -0
- package/dist/rules/markdown/first-line-heading.d.ts +5 -0
- package/dist/rules/markdown/heading-increment.d.ts +5 -0
- package/dist/rules/markdown/heading-start-left.d.ts +5 -0
- package/dist/rules/markdown/heading-style.d.ts +5 -0
- package/dist/rules/markdown/hr-style.d.ts +5 -0
- package/dist/rules/markdown/line-length.d.ts +5 -0
- package/dist/rules/markdown/link-fragments.d.ts +5 -0
- package/dist/rules/markdown/link-image-reference-definitions.d.ts +5 -0
- package/dist/rules/markdown/link-image-style.d.ts +5 -0
- package/dist/rules/markdown/list-indent.d.ts +5 -0
- package/dist/rules/markdown/list-marker-space.d.ts +5 -0
- package/dist/rules/markdown/no-alt-text.d.ts +5 -0
- package/dist/rules/markdown/no-bare-urls.d.ts +5 -0
- package/dist/rules/markdown/no-blanks-blockquote.d.ts +5 -0
- package/dist/rules/markdown/no-duplicate-heading.d.ts +10 -0
- package/dist/rules/markdown/no-emphasis-as-heading.d.ts +9 -0
- package/dist/rules/markdown/no-empty-links.d.ts +5 -0
- package/dist/rules/markdown/no-hard-tabs.d.ts +5 -0
- package/dist/rules/markdown/no-inline-html.d.ts +5 -0
- package/dist/rules/markdown/no-missing-space-atx.d.ts +5 -0
- package/dist/rules/markdown/no-missing-space-closed-atx.d.ts +5 -0
- package/dist/rules/markdown/no-multiple-blanks.d.ts +5 -0
- package/dist/rules/markdown/no-multiple-space-atx.d.ts +5 -0
- package/dist/rules/markdown/no-multiple-space-blockquote.d.ts +5 -0
- package/dist/rules/markdown/no-multiple-space-closed-atx.d.ts +5 -0
- package/dist/rules/markdown/no-reversed-links.d.ts +5 -0
- package/dist/rules/markdown/no-space-in-code.d.ts +5 -0
- package/dist/rules/markdown/no-space-in-emphasis.d.ts +5 -0
- package/dist/rules/markdown/no-space-in-links.d.ts +5 -0
- package/dist/rules/markdown/no-trailing-punctuation.d.ts +5 -0
- package/dist/rules/markdown/no-trailing-spaces.d.ts +5 -0
- package/dist/rules/markdown/ol-prefix.d.ts +5 -0
- package/dist/rules/markdown/proper-names.d.ts +5 -0
- package/dist/rules/markdown/reference-links-images.d.ts +14 -0
- package/dist/rules/markdown/required-headings.d.ts +5 -0
- package/dist/rules/markdown/single-title.d.ts +5 -0
- package/dist/rules/markdown/single-trailing-newline.d.ts +5 -0
- package/dist/rules/markdown/strong-style.d.ts +5 -0
- package/dist/rules/markdown/table-column-count.d.ts +5 -0
- package/dist/rules/markdown/table-column-style.d.ts +5 -0
- package/dist/rules/markdown/table-pipe-style.d.ts +5 -0
- package/dist/rules/markdown/ul-indent.d.ts +14 -0
- package/dist/rules/markdown/ul-style.d.ts +5 -0
- package/dist/rules/node/prefer-global-buffer.d.ts +9 -0
- package/dist/rules/node/prefer-global-process.d.ts +9 -0
- package/dist/rules/quality/complexity.d.ts +2 -0
- package/dist/rules/quality/default-case.d.ts +2 -0
- package/dist/rules/quality/eqeqeq.d.ts +2 -0
- package/dist/rules/quality/max-depth.d.ts +2 -0
- package/dist/rules/quality/max-lines-per-function.d.ts +2 -0
- package/dist/rules/quality/no-alert.d.ts +2 -0
- package/dist/rules/quality/no-await-in-loop.d.ts +2 -0
- package/dist/rules/quality/no-caller.d.ts +2 -0
- package/dist/rules/quality/no-case-declarations.d.ts +2 -0
- package/dist/rules/quality/no-else-return.d.ts +2 -0
- package/dist/rules/quality/no-empty-function.d.ts +2 -0
- package/dist/rules/quality/no-empty.d.ts +2 -0
- package/dist/rules/quality/no-eval.d.ts +2 -0
- package/dist/rules/quality/no-extend-native.d.ts +2 -0
- package/dist/rules/quality/no-extra-boolean-cast.d.ts +2 -0
- package/dist/rules/quality/no-global-assign.d.ts +2 -0
- package/dist/rules/quality/no-implied-eval.d.ts +2 -0
- package/dist/rules/quality/no-iterator.d.ts +2 -0
- package/dist/rules/quality/no-lonely-if.d.ts +2 -0
- package/dist/rules/quality/no-new-func.d.ts +2 -0
- package/dist/rules/quality/no-new-wrappers.d.ts +2 -0
- package/dist/rules/quality/no-new.d.ts +2 -0
- package/dist/rules/quality/no-octal.d.ts +2 -0
- package/dist/rules/quality/no-param-reassign.d.ts +2 -0
- package/dist/rules/quality/no-proto.d.ts +2 -0
- package/dist/rules/quality/no-return-assign.d.ts +2 -0
- package/dist/rules/quality/no-sequences.d.ts +2 -0
- package/dist/rules/quality/no-shadow.d.ts +2 -0
- package/dist/rules/quality/no-throw-literal.d.ts +2 -0
- package/dist/rules/quality/no-use-before-define.d.ts +2 -0
- package/dist/rules/quality/no-useless-call.d.ts +2 -0
- package/dist/rules/quality/no-useless-concat.d.ts +2 -0
- package/dist/rules/quality/no-useless-escape.d.ts +2 -0
- package/dist/rules/quality/no-useless-rename.d.ts +2 -0
- package/dist/rules/quality/no-useless-return.d.ts +2 -0
- package/dist/rules/quality/no-var.d.ts +2 -0
- package/dist/rules/quality/no-with.d.ts +2 -0
- package/dist/rules/quality/prefer-arrow-callback.d.ts +2 -0
- package/dist/rules/quality/require-await.d.ts +2 -0
- package/dist/rules/regexp/no-super-linear-backtracking.d.ts +2 -0
- package/dist/rules/regexp/no-unused-capturing-group.d.ts +2 -0
- package/dist/rules/regexp/no-useless-lazy.d.ts +9 -0
- package/dist/rules/shell/_shared.d.ts +24 -0
- package/dist/rules/shell/command-substitution.d.ts +6 -0
- package/dist/rules/shell/consistent-case-terminators.d.ts +9 -0
- package/dist/rules/shell/function-style.d.ts +6 -0
- package/dist/rules/shell/heredoc-indent.d.ts +7 -0
- package/dist/rules/shell/indent.d.ts +2 -0
- package/dist/rules/shell/keyword-spacing.d.ts +10 -0
- package/dist/rules/shell/no-broken-redirect.d.ts +7 -0
- package/dist/rules/shell/no-cd-without-check.d.ts +6 -0
- package/dist/rules/shell/no-eval.d.ts +6 -0
- package/dist/rules/shell/no-exit-in-subshell.d.ts +7 -0
- package/dist/rules/shell/no-ls-parsing.d.ts +7 -0
- package/dist/rules/shell/no-trailing-semicolons.d.ts +6 -0
- package/dist/rules/shell/no-trailing-whitespace.d.ts +5 -0
- package/dist/rules/shell/no-useless-cat.d.ts +6 -0
- package/dist/rules/shell/no-variable-in-single-quotes.d.ts +7 -0
- package/dist/rules/shell/operator-spacing.d.ts +11 -0
- package/dist/rules/shell/prefer-double-brackets.d.ts +6 -0
- package/dist/rules/shell/prefer-printf.d.ts +6 -0
- package/dist/rules/shell/quote-variables.d.ts +2 -0
- package/dist/rules/shell/set-options.d.ts +8 -0
- package/dist/rules/shell/shebang.d.ts +2 -0
- package/dist/rules/sort/exports.d.ts +2 -0
- package/dist/rules/sort/heritage-clauses.d.ts +2 -0
- package/dist/rules/sort/imports.d.ts +2 -0
- package/dist/rules/sort/keys.d.ts +2 -0
- package/dist/rules/sort/named-imports.d.ts +2 -0
- package/dist/rules/sort/objects.d.ts +2 -0
- package/dist/rules/sort/tailwind-classes.d.ts +5 -0
- package/dist/rules/style/array-bracket-spacing.d.ts +2 -0
- package/dist/rules/style/arrow-parens.d.ts +2 -0
- package/dist/rules/style/arrow-spacing.d.ts +2 -0
- package/dist/rules/style/block-spacing.d.ts +2 -0
- package/dist/rules/style/brace-style.d.ts +10 -0
- package/dist/rules/style/comma-dangle.d.ts +2 -0
- package/dist/rules/style/comma-spacing.d.ts +2 -0
- package/dist/rules/style/comma-style.d.ts +2 -0
- package/dist/rules/style/computed-property-spacing.d.ts +2 -0
- package/dist/rules/style/consistent-chaining.d.ts +2 -0
- package/dist/rules/style/consistent-list-newline.d.ts +2 -0
- package/dist/rules/style/curly.d.ts +5 -0
- package/dist/rules/style/dot-location.d.ts +2 -0
- package/dist/rules/style/function-call-spacing.d.ts +2 -0
- package/dist/rules/style/generator-star-spacing.d.ts +2 -0
- package/dist/rules/style/if-newline.d.ts +2 -0
- package/dist/rules/style/indent-binary-ops.d.ts +2 -0
- package/dist/rules/style/indent-unindent.d.ts +2 -0
- package/dist/rules/style/key-spacing.d.ts +2 -0
- package/dist/rules/style/keyword-spacing.d.ts +2 -0
- package/dist/rules/style/lines-between-class-members.d.ts +2 -0
- package/dist/rules/style/max-statements-per-line.d.ts +2 -0
- package/dist/rules/style/multiline-ternary.d.ts +2 -0
- package/dist/rules/style/new-parens.d.ts +2 -0
- package/dist/rules/style/no-extra-parens.d.ts +2 -0
- package/dist/rules/style/no-floating-decimal.d.ts +2 -0
- package/dist/rules/style/no-mixed-operators.d.ts +2 -0
- package/dist/rules/style/no-mixed-spaces-and-tabs.d.ts +2 -0
- package/dist/rules/style/no-multi-spaces.d.ts +10 -0
- package/dist/rules/style/no-multiple-empty-lines.d.ts +9 -0
- package/dist/rules/style/no-tabs.d.ts +2 -0
- package/dist/rules/style/no-trailing-spaces.d.ts +9 -0
- package/dist/rules/style/no-whitespace-before-property.d.ts +2 -0
- package/dist/rules/style/object-curly-spacing.d.ts +2 -0
- package/dist/rules/style/operator-linebreak.d.ts +2 -0
- package/dist/rules/style/padded-blocks.d.ts +2 -0
- package/dist/rules/style/quote-props.d.ts +2 -0
- package/dist/rules/style/rest-spread-spacing.d.ts +2 -0
- package/dist/rules/style/semi-spacing.d.ts +2 -0
- package/dist/rules/style/space-before-blocks.d.ts +2 -0
- package/dist/rules/style/space-before-function-paren.d.ts +2 -0
- package/dist/rules/style/space-in-parens.d.ts +2 -0
- package/dist/rules/style/space-infix-ops.d.ts +2 -0
- package/dist/rules/style/space-unary-ops.d.ts +2 -0
- package/dist/rules/style/spaced-comment.d.ts +2 -0
- package/dist/rules/style/switch-colon-spacing.d.ts +2 -0
- package/dist/rules/style/template-curly-spacing.d.ts +2 -0
- package/dist/rules/style/template-tag-spacing.d.ts +2 -0
- package/dist/rules/style/top-level-function.d.ts +6 -0
- package/dist/rules/style/wrap-iife.d.ts +2 -0
- package/dist/rules/style/yield-star-spacing.d.ts +2 -0
- package/dist/rules/ts/member-delimiter-style.d.ts +4 -0
- package/dist/rules/ts/no-explicit-any.d.ts +2 -0
- package/dist/rules/ts/no-floating-promises.d.ts +2 -0
- package/dist/rules/ts/no-misused-promises.d.ts +2 -0
- package/dist/rules/ts/no-require-imports.d.ts +2 -0
- package/dist/rules/ts/no-top-level-await.d.ts +4 -0
- package/dist/rules/ts/no-ts-export-equal.d.ts +2 -0
- package/dist/rules/ts/no-unsafe-assignment.d.ts +2 -0
- package/dist/rules/ts/prefer-nullish-coalescing.d.ts +2 -0
- package/dist/rules/ts/prefer-optional-chain.d.ts +2 -0
- package/dist/rules/ts/type-annotation-spacing.d.ts +2 -0
- package/dist/rules/ts/type-generic-spacing.d.ts +2 -0
- package/dist/rules/ts/type-named-tuple-spacing.d.ts +2 -0
- package/dist/src/index.js +481 -289
- package/dist/utils.d.ts +12 -3
- package/package.json +2 -2
package/dist/src/index.js
CHANGED
|
@@ -9364,6 +9364,16 @@ function unmaskStrings(text, strings) {
|
|
|
9364
9364
|
return text;
|
|
9365
9365
|
return text.replace(/@@S(\d+)@@/g, (_, idx) => strings[Number(idx)] ?? "");
|
|
9366
9366
|
}
|
|
9367
|
+
function collectIdentifierSet(text) {
|
|
9368
|
+
const identifiers = new Set;
|
|
9369
|
+
const identifierRe = /[$A-Z_][\w$]*/gi;
|
|
9370
|
+
let match = identifierRe.exec(text);
|
|
9371
|
+
while (match !== null) {
|
|
9372
|
+
identifiers.add(match[0]);
|
|
9373
|
+
match = identifierRe.exec(text);
|
|
9374
|
+
}
|
|
9375
|
+
return identifiers;
|
|
9376
|
+
}
|
|
9367
9377
|
function formatImports(source) {
|
|
9368
9378
|
const firstChar = source[0];
|
|
9369
9379
|
if (firstChar !== "i" && firstChar !== " " && firstChar !== "\t" && firstChar !== "/" && firstChar !== `
|
|
@@ -9391,17 +9401,8 @@ function formatImports(source) {
|
|
|
9391
9401
|
return source;
|
|
9392
9402
|
const rest = lines.slice(idx).join(`
|
|
9393
9403
|
`);
|
|
9394
|
-
const
|
|
9395
|
-
const
|
|
9396
|
-
const used = (name) => {
|
|
9397
|
-
for (let pos = codeText.indexOf(name, 0);pos !== -1; pos = codeText.indexOf(name, pos + name.length)) {
|
|
9398
|
-
const before = pos > 0 ? codeText[pos - 1] : " ";
|
|
9399
|
-
const after = pos + name.length < codeText.length ? codeText[pos + name.length] : " ";
|
|
9400
|
-
if (!isWordChar(before) && !isWordChar(after))
|
|
9401
|
-
return true;
|
|
9402
|
-
}
|
|
9403
|
-
return false;
|
|
9404
|
-
};
|
|
9404
|
+
const usedIdentifiers = collectIdentifierSet(rest);
|
|
9405
|
+
const used = (name) => usedIdentifiers.has(name);
|
|
9405
9406
|
for (const imp of imports) {
|
|
9406
9407
|
if (imp.kind !== "value")
|
|
9407
9408
|
continue;
|
|
@@ -20322,11 +20323,11 @@ var init_no_unused_vars = __esm(() => {
|
|
|
20322
20323
|
}
|
|
20323
20324
|
};
|
|
20324
20325
|
computeTemplateLines();
|
|
20326
|
+
const declRe = new RegExp("^\\s*(?:const|let|var)\\s+(.+?)" + ";" + "?\\s*$");
|
|
20325
20327
|
for (let i = 0;i < lines.length; i++) {
|
|
20326
20328
|
if (lineStartsInTemplate[i])
|
|
20327
20329
|
continue;
|
|
20328
20330
|
const line = lines[i];
|
|
20329
|
-
const declRe = new RegExp("^\\s*(?:const|let|var)\\s+(.+?)" + ";" + "?\\s*$");
|
|
20330
20331
|
const decl = line.match(declRe);
|
|
20331
20332
|
if (!decl)
|
|
20332
20333
|
continue;
|
|
@@ -21756,6 +21757,90 @@ function findTopLevelEquals(s) {
|
|
|
21756
21757
|
}
|
|
21757
21758
|
return -1;
|
|
21758
21759
|
}
|
|
21760
|
+
function destructuringReassignsName(text, name) {
|
|
21761
|
+
const re = new RegExp(`\\b${name}\\b`);
|
|
21762
|
+
let i = 0;
|
|
21763
|
+
let inStr = null;
|
|
21764
|
+
let escaped = false;
|
|
21765
|
+
while (i < text.length) {
|
|
21766
|
+
const c = text[i];
|
|
21767
|
+
if (escaped) {
|
|
21768
|
+
escaped = false;
|
|
21769
|
+
i++;
|
|
21770
|
+
continue;
|
|
21771
|
+
}
|
|
21772
|
+
if (c === "\\" && inStr) {
|
|
21773
|
+
escaped = true;
|
|
21774
|
+
i++;
|
|
21775
|
+
continue;
|
|
21776
|
+
}
|
|
21777
|
+
if (inStr) {
|
|
21778
|
+
if (inStr === "single" && c === "'" || inStr === "double" && c === '"' || inStr === "template" && c === "`")
|
|
21779
|
+
inStr = null;
|
|
21780
|
+
i++;
|
|
21781
|
+
continue;
|
|
21782
|
+
}
|
|
21783
|
+
if (c === "'") {
|
|
21784
|
+
inStr = "single";
|
|
21785
|
+
i++;
|
|
21786
|
+
continue;
|
|
21787
|
+
}
|
|
21788
|
+
if (c === '"') {
|
|
21789
|
+
inStr = "double";
|
|
21790
|
+
i++;
|
|
21791
|
+
continue;
|
|
21792
|
+
}
|
|
21793
|
+
if (c === "`") {
|
|
21794
|
+
inStr = "template";
|
|
21795
|
+
i++;
|
|
21796
|
+
continue;
|
|
21797
|
+
}
|
|
21798
|
+
if (c === "[" || c === "{") {
|
|
21799
|
+
const open = c;
|
|
21800
|
+
const close = c === "[" ? "]" : "}";
|
|
21801
|
+
let depth = 1;
|
|
21802
|
+
let j = i + 1;
|
|
21803
|
+
while (j < text.length && depth > 0) {
|
|
21804
|
+
const cj = text[j];
|
|
21805
|
+
if (cj === "\\") {
|
|
21806
|
+
j += 2;
|
|
21807
|
+
continue;
|
|
21808
|
+
}
|
|
21809
|
+
if (cj === open)
|
|
21810
|
+
depth++;
|
|
21811
|
+
else if (cj === close)
|
|
21812
|
+
depth--;
|
|
21813
|
+
if (depth === 0)
|
|
21814
|
+
break;
|
|
21815
|
+
j++;
|
|
21816
|
+
}
|
|
21817
|
+
if (depth === 0 && j < text.length) {
|
|
21818
|
+
let k = j + 1;
|
|
21819
|
+
while (k < text.length && (text[k] === " " || text[k] === "\t" || text[k] === "\r" || text[k] === `
|
|
21820
|
+
`))
|
|
21821
|
+
k++;
|
|
21822
|
+
if (text[k] === "=" && text[k + 1] !== "=" && text[k + 1] !== ">") {
|
|
21823
|
+
const inside = text.slice(i + 1, j);
|
|
21824
|
+
if (re.test(inside)) {
|
|
21825
|
+
const keyOnly = new RegExp(`\\b${name}\\b\\s*:`);
|
|
21826
|
+
const valueAfterColon = new RegExp(`:\\s*\\b${name}\\b`);
|
|
21827
|
+
if (open === "{") {
|
|
21828
|
+
const isKeyOnly = keyOnly.test(inside) && !valueAfterColon.test(inside) && !new RegExp(`(?:^|[\\s,{])\\s*${name}\\s*(?:,|\\s*=|\\s*})`).test(inside);
|
|
21829
|
+
if (!isKeyOnly)
|
|
21830
|
+
return true;
|
|
21831
|
+
} else {
|
|
21832
|
+
return true;
|
|
21833
|
+
}
|
|
21834
|
+
}
|
|
21835
|
+
}
|
|
21836
|
+
}
|
|
21837
|
+
i = j + 1;
|
|
21838
|
+
continue;
|
|
21839
|
+
}
|
|
21840
|
+
i++;
|
|
21841
|
+
}
|
|
21842
|
+
return false;
|
|
21843
|
+
}
|
|
21759
21844
|
function analyzeLetDecl(line, text) {
|
|
21760
21845
|
const declRe = new RegExp("^\\s*(?:let|var)\\s+(.+?)" + ";" + "?\\s*$");
|
|
21761
21846
|
const decl = line.match(declRe);
|
|
@@ -21793,7 +21878,8 @@ function analyzeLetDecl(line, text) {
|
|
|
21793
21878
|
const assignPattern = `\\b${name}\\s*(?:${assignOps.map((op) => op.replace(/[|\\^$*+?.(){}[\]]/g, (r) => `\\${r}`)).join("|")})`;
|
|
21794
21879
|
const directAssign = new RegExp(assignPattern).test(rest);
|
|
21795
21880
|
const incDecChanged = new RegExp(`(?:^|[^$w])(?:\\+\\+|--)\\s*${name}\\b|\\b${name}\\s*(?:\\+\\+|--)`).test(rest);
|
|
21796
|
-
|
|
21881
|
+
const destructReassigned = destructuringReassignsName(rest, name);
|
|
21882
|
+
result.push({ name, fixable: !directAssign && !incDecChanged && !destructReassigned });
|
|
21797
21883
|
}
|
|
21798
21884
|
return result;
|
|
21799
21885
|
}
|
|
@@ -21822,8 +21908,20 @@ var init_prefer_const = __esm(() => {
|
|
|
21822
21908
|
},
|
|
21823
21909
|
fix: (text) => {
|
|
21824
21910
|
const lines = text.split(/\r?\n/);
|
|
21911
|
+
const disabledLines = new Set;
|
|
21912
|
+
const disableNextRe = /(?:eslint|pickier)-disable-next-line\b([^*\n]*)/;
|
|
21913
|
+
for (let i = 0;i < lines.length; i++) {
|
|
21914
|
+
const m = lines[i].match(disableNextRe);
|
|
21915
|
+
if (!m)
|
|
21916
|
+
continue;
|
|
21917
|
+
const ruleList = m[1].trim();
|
|
21918
|
+
if (ruleList === "" || /\bprefer-const\b/.test(ruleList))
|
|
21919
|
+
disabledLines.add(i + 2);
|
|
21920
|
+
}
|
|
21825
21921
|
let changed = false;
|
|
21826
21922
|
for (let i = 0;i < lines.length; i++) {
|
|
21923
|
+
if (disabledLines.has(i + 1))
|
|
21924
|
+
continue;
|
|
21827
21925
|
const line = lines[i];
|
|
21828
21926
|
if (!/^\s*let\b/.test(line))
|
|
21829
21927
|
continue;
|
|
@@ -28473,14 +28571,27 @@ function getVariantPriority(cls) {
|
|
|
28473
28571
|
}
|
|
28474
28572
|
return priority;
|
|
28475
28573
|
}
|
|
28574
|
+
function getClassSortKey(cls) {
|
|
28575
|
+
const cached = sortKeyCache.get(cls);
|
|
28576
|
+
if (cached)
|
|
28577
|
+
return cached;
|
|
28578
|
+
const key = {
|
|
28579
|
+
group: getGroupIndex(cls),
|
|
28580
|
+
variant: getVariantPriority(cls)
|
|
28581
|
+
};
|
|
28582
|
+
sortKeyCache.set(cls, key);
|
|
28583
|
+
return key;
|
|
28584
|
+
}
|
|
28476
28585
|
function sortClasses(classes) {
|
|
28477
28586
|
return [...classes].sort((a, b) => {
|
|
28478
|
-
const
|
|
28479
|
-
const
|
|
28587
|
+
const aKey = getClassSortKey(a);
|
|
28588
|
+
const bKey = getClassSortKey(b);
|
|
28589
|
+
const ga = aKey.group;
|
|
28590
|
+
const gb = bKey.group;
|
|
28480
28591
|
if (ga !== gb)
|
|
28481
28592
|
return ga - gb;
|
|
28482
|
-
const va =
|
|
28483
|
-
const vb =
|
|
28593
|
+
const va = aKey.variant;
|
|
28594
|
+
const vb = bKey.variant;
|
|
28484
28595
|
if (va !== vb)
|
|
28485
28596
|
return va - vb;
|
|
28486
28597
|
return a.localeCompare(b);
|
|
@@ -28499,6 +28610,8 @@ function looksLikeJsExpression(value) {
|
|
|
28499
28610
|
}
|
|
28500
28611
|
function extractClassValues(content) {
|
|
28501
28612
|
const matches = [];
|
|
28613
|
+
if (!content.includes("class") && !content.includes("clsx") && !content.includes("cn(") && !content.includes("tw(") && !content.includes("cva(") && !content.includes("tv("))
|
|
28614
|
+
return matches;
|
|
28502
28615
|
for (const re of [ATTR_RE, ATTR_TMPL_RE, UTIL_FN_RE]) {
|
|
28503
28616
|
re.lastIndex = 0;
|
|
28504
28617
|
let m;
|
|
@@ -28545,7 +28658,7 @@ function isSorted(classes) {
|
|
|
28545
28658
|
const sorted = sortClasses(classes);
|
|
28546
28659
|
return classes.every((c, i) => c === sorted[i]);
|
|
28547
28660
|
}
|
|
28548
|
-
var GROUP_ORDER, VARIANT_RE, ATTR_RE, ATTR_TMPL_RE, UTIL_FN_RE, sortTailwindClassesRule;
|
|
28661
|
+
var GROUP_ORDER, VARIANT_RE, sortKeyCache, ATTR_RE, ATTR_TMPL_RE, UTIL_FN_RE, sortTailwindClassesRule;
|
|
28549
28662
|
var init_tailwind_classes = __esm(() => {
|
|
28550
28663
|
GROUP_ORDER = [
|
|
28551
28664
|
[/^(block|inline|inline-block|flex|inline-flex|grid|inline-grid|flow-root|contents|hidden|table|table-caption|table-cell|table-column|table-column-group|table-footer-group|table-header-group|table-row-group|table-row|list-item|subgrid)$/, 0],
|
|
@@ -28569,6 +28682,7 @@ var init_tailwind_classes = __esm(() => {
|
|
|
28569
28682
|
[/^(sr-only|not-sr-only)$/, 15]
|
|
28570
28683
|
];
|
|
28571
28684
|
VARIANT_RE = /^([a-z0-9][-a-z0-9]{0,50}:)+(?!\[)/;
|
|
28685
|
+
sortKeyCache = new Map;
|
|
28572
28686
|
ATTR_RE = /\b(?:class|className|:class)\s*=\s*(?:"([^"]*?)"|'([^']*?)')/g;
|
|
28573
28687
|
ATTR_TMPL_RE = /\b(?:class|className|:class)\s*=\s*\{`([^`]*?)`\}/g;
|
|
28574
28688
|
UTIL_FN_RE = /\b(?:clsx|cn|tw|cva|tv)\s*\(\s*(?:"([^"]*?)"|'([^']*?)')/g;
|
|
@@ -37167,15 +37281,7 @@ function globToRegex(pattern) {
|
|
|
37167
37281
|
}
|
|
37168
37282
|
return new RegExp(`^${src}$`);
|
|
37169
37283
|
}
|
|
37170
|
-
function
|
|
37171
|
-
for (const p of patterns) {
|
|
37172
|
-
const re = globToRegex(p);
|
|
37173
|
-
if (re.test(filePath) || re.test(filePath.replace(/\\/g, "/")))
|
|
37174
|
-
return true;
|
|
37175
|
-
}
|
|
37176
|
-
return false;
|
|
37177
|
-
}
|
|
37178
|
-
function* walkDir(dir, ignore, dot, cwd) {
|
|
37284
|
+
function* walkDirWithMatcher(dir, ignoreMatcher, dot) {
|
|
37179
37285
|
let entries;
|
|
37180
37286
|
try {
|
|
37181
37287
|
entries = readdirSync8(dir);
|
|
@@ -37186,8 +37292,7 @@ function* walkDir(dir, ignore, dot, cwd) {
|
|
|
37186
37292
|
if (!dot && name.startsWith("."))
|
|
37187
37293
|
continue;
|
|
37188
37294
|
const full = join10(dir, name);
|
|
37189
|
-
|
|
37190
|
-
if (ignore.length && matchesAnyPattern(rel, ignore))
|
|
37295
|
+
if (ignoreMatcher(full))
|
|
37191
37296
|
continue;
|
|
37192
37297
|
let st;
|
|
37193
37298
|
try {
|
|
@@ -37196,17 +37301,21 @@ function* walkDir(dir, ignore, dot, cwd) {
|
|
|
37196
37301
|
continue;
|
|
37197
37302
|
}
|
|
37198
37303
|
if (st.isDirectory()) {
|
|
37199
|
-
yield*
|
|
37304
|
+
yield* walkDirWithMatcher(full, ignoreMatcher, dot);
|
|
37200
37305
|
} else {
|
|
37201
37306
|
yield full;
|
|
37202
37307
|
}
|
|
37203
37308
|
}
|
|
37204
37309
|
}
|
|
37310
|
+
function* walkDir(dir, ignore, dot, cwd) {
|
|
37311
|
+
yield* walkDirWithMatcher(dir, createIgnoreMatcher(ignore, cwd), dot);
|
|
37312
|
+
}
|
|
37205
37313
|
async function glob(patterns, opts = {}) {
|
|
37206
37314
|
const cwd = opts.cwd ?? process21.cwd();
|
|
37207
37315
|
const ignore = opts.ignore ?? [];
|
|
37208
37316
|
const dot = opts.dot ?? false;
|
|
37209
37317
|
const absolute = opts.absolute ?? true;
|
|
37318
|
+
const ignoreMatcher = createIgnoreMatcher(ignore, cwd);
|
|
37210
37319
|
if (typeof globalThis.Bun?.Glob !== "undefined") {
|
|
37211
37320
|
const BunGlob = globalThis.Bun.Glob;
|
|
37212
37321
|
const results2 = [];
|
|
@@ -37215,7 +37324,7 @@ async function glob(patterns, opts = {}) {
|
|
|
37215
37324
|
for await (const file of g.scan({ cwd, dot, onlyFiles: opts.onlyFiles ?? true, followSymlinks: false })) {
|
|
37216
37325
|
const full = isAbsolute6(file) ? file : join10(cwd, file);
|
|
37217
37326
|
const rel = full.startsWith(`${cwd}/`) ? full.slice(cwd.length + 1) : full;
|
|
37218
|
-
if (
|
|
37327
|
+
if (ignoreMatcher(full))
|
|
37219
37328
|
continue;
|
|
37220
37329
|
results2.push(absolute ? full : rel);
|
|
37221
37330
|
}
|
|
@@ -37230,7 +37339,7 @@ async function glob(patterns, opts = {}) {
|
|
|
37230
37339
|
const st = statSync5(full);
|
|
37231
37340
|
if (!st.isDirectory()) {
|
|
37232
37341
|
const rel = full.startsWith(`${cwd}/`) ? full.slice(cwd.length + 1) : full;
|
|
37233
|
-
if (!
|
|
37342
|
+
if (!ignoreMatcher(full))
|
|
37234
37343
|
results.push(absolute ? full : rel);
|
|
37235
37344
|
} else {
|
|
37236
37345
|
for (const f of walkDir(full, ignore, dot, cwd))
|
|
@@ -37405,36 +37514,60 @@ function isCodeFile(file, allowedExts) {
|
|
|
37405
37514
|
function toPosixPath(p) {
|
|
37406
37515
|
return p.replace(/\\/g, "/").replace(/\/+/g, "/");
|
|
37407
37516
|
}
|
|
37408
|
-
function
|
|
37409
|
-
const
|
|
37410
|
-
const
|
|
37411
|
-
const effectiveIgnores = isOutsideProject ? ignoreGlobs.filter((pattern) => universalIgnores.includes(pattern)) : ignoreGlobs;
|
|
37412
|
-
const rel = toPosixPath(isOutsideProject ? absPath : absPath.slice(process21.cwd().length));
|
|
37413
|
-
for (const g of effectiveIgnores) {
|
|
37517
|
+
function compileIgnoreGlobs(ignoreGlobs) {
|
|
37518
|
+
const compiled = [];
|
|
37519
|
+
for (const g of ignoreGlobs) {
|
|
37414
37520
|
const gg = toPosixPath(g.trim());
|
|
37521
|
+
if (!gg)
|
|
37522
|
+
continue;
|
|
37415
37523
|
const filePattern = gg.match(/\*\*\/\*\.(.+)$/);
|
|
37416
37524
|
if (filePattern) {
|
|
37417
|
-
|
|
37418
|
-
if (rel.endsWith(`.${extension}`))
|
|
37419
|
-
return true;
|
|
37525
|
+
compiled.push({ raw: gg, kind: "extension", value: filePattern[1] });
|
|
37420
37526
|
continue;
|
|
37421
37527
|
}
|
|
37422
37528
|
const m = gg.match(/\*\*\/(.+?)\/\*\*$/);
|
|
37423
37529
|
if (m) {
|
|
37424
|
-
|
|
37425
|
-
if (rel.includes(`/${name}/`) || rel.endsWith(`/${name}`))
|
|
37426
|
-
return true;
|
|
37530
|
+
compiled.push({ raw: gg, kind: "segment", value: m[1] });
|
|
37427
37531
|
continue;
|
|
37428
37532
|
}
|
|
37429
37533
|
const m2 = gg.match(/\*\*\/(.+)$/);
|
|
37430
37534
|
if (m2) {
|
|
37431
|
-
|
|
37432
|
-
|
|
37433
|
-
|
|
37434
|
-
|
|
37535
|
+
compiled.push({ raw: gg, kind: "suffix", value: m2[1].replace(/\/$/, "") });
|
|
37536
|
+
}
|
|
37537
|
+
}
|
|
37538
|
+
return compiled;
|
|
37539
|
+
}
|
|
37540
|
+
function createIgnoreMatcher(ignoreGlobs, cwd = process21.cwd()) {
|
|
37541
|
+
if (ignoreGlobs.length === 0)
|
|
37542
|
+
return () => false;
|
|
37543
|
+
const compiled = compileIgnoreGlobs(ignoreGlobs);
|
|
37544
|
+
if (compiled.length === 0)
|
|
37545
|
+
return () => false;
|
|
37546
|
+
const universalRaw = new Set(UNIVERSAL_IGNORES);
|
|
37547
|
+
return (absPath) => {
|
|
37548
|
+
const normalizedAbs = toPosixPath(absPath);
|
|
37549
|
+
const normalizedCwd = toPosixPath(cwd).replace(/\/$/, "");
|
|
37550
|
+
const isOutsideProject = !normalizedAbs.startsWith(normalizedCwd);
|
|
37551
|
+
const rel = isOutsideProject ? normalizedAbs : normalizedAbs.slice(normalizedCwd.length);
|
|
37552
|
+
for (const pattern of compiled) {
|
|
37553
|
+
if (isOutsideProject && !universalRaw.has(pattern.raw))
|
|
37554
|
+
continue;
|
|
37555
|
+
if (pattern.kind === "extension") {
|
|
37556
|
+
if (rel.endsWith(`.${pattern.value}`))
|
|
37557
|
+
return true;
|
|
37558
|
+
continue;
|
|
37559
|
+
}
|
|
37560
|
+
if (pattern.kind === "segment" || pattern.kind === "suffix") {
|
|
37561
|
+
const name = pattern.value;
|
|
37562
|
+
if (rel.includes(`/${name}/`) || rel.endsWith(`/${name}`))
|
|
37563
|
+
return true;
|
|
37564
|
+
}
|
|
37435
37565
|
}
|
|
37436
|
-
|
|
37437
|
-
|
|
37566
|
+
return false;
|
|
37567
|
+
};
|
|
37568
|
+
}
|
|
37569
|
+
function shouldIgnorePath(absPath, ignoreGlobs) {
|
|
37570
|
+
return createIgnoreMatcher(ignoreGlobs)(absPath);
|
|
37438
37571
|
}
|
|
37439
37572
|
var MAX_FIXER_PASSES = 5, ENV, UNIVERSAL_IGNORES, colors, _cachedDefaultConfig = null;
|
|
37440
37573
|
var init_utils3 = __esm(() => {
|
|
@@ -37646,6 +37779,7 @@ async function runFormat(globs, options) {
|
|
|
37646
37779
|
return !absBase.startsWith(process23.cwd());
|
|
37647
37780
|
});
|
|
37648
37781
|
const globIgnores = isGlobbingOutsideProject ? [...UNIVERSAL_IGNORES] : cfg.ignores;
|
|
37782
|
+
const ignoreMatcher = createIgnoreMatcher(globIgnores);
|
|
37649
37783
|
let entries = [];
|
|
37650
37784
|
const simpleDirPattern = patterns.length === 1 && /\*\*\/\*$/.test(patterns[0]);
|
|
37651
37785
|
if (simpleDirPattern) {
|
|
@@ -37660,7 +37794,7 @@ async function runFormat(globs, options) {
|
|
|
37660
37794
|
for (const it of items) {
|
|
37661
37795
|
const full = join8(dir, it);
|
|
37662
37796
|
const st = statSync4(full);
|
|
37663
|
-
if (
|
|
37797
|
+
if (ignoreMatcher(full))
|
|
37664
37798
|
continue;
|
|
37665
37799
|
if (st.isDirectory())
|
|
37666
37800
|
stack.push(full);
|
|
@@ -37686,7 +37820,7 @@ async function runFormat(globs, options) {
|
|
|
37686
37820
|
}
|
|
37687
37821
|
trace("globbed entries", entries.length);
|
|
37688
37822
|
const files = entries.filter((f) => {
|
|
37689
|
-
if (
|
|
37823
|
+
if (ignoreMatcher(f))
|
|
37690
37824
|
return false;
|
|
37691
37825
|
const idx = f.lastIndexOf(".");
|
|
37692
37826
|
if (idx < 0)
|
|
@@ -37758,24 +37892,21 @@ function trace2(...args) {
|
|
|
37758
37892
|
getLogger2().error("[pickier:trace]", args);
|
|
37759
37893
|
}
|
|
37760
37894
|
async function lintText(text, cfg, filePath = "untitled", signal) {
|
|
37761
|
-
if (signal?.aborted)
|
|
37895
|
+
if (signal?.aborted)
|
|
37762
37896
|
throw new Error("AbortError");
|
|
37763
|
-
|
|
37764
|
-
const
|
|
37765
|
-
|
|
37766
|
-
const issues = scanContent(filePath, text, cfg);
|
|
37897
|
+
const suppress = parseDisableDirectives(text);
|
|
37898
|
+
const commentLines = getCommentLines(text);
|
|
37899
|
+
const issues = scanContentOptimized(filePath, text, cfg, suppress, commentLines);
|
|
37767
37900
|
if (signal?.aborted)
|
|
37768
37901
|
throw new Error("AbortError");
|
|
37769
37902
|
try {
|
|
37770
37903
|
const pluginIssues = await applyPlugins(filePath, text, cfg);
|
|
37771
|
-
const suppress = parseDisableDirectives(text);
|
|
37772
|
-
const commentLines = getCommentLines(text);
|
|
37773
37904
|
for (const i of pluginIssues) {
|
|
37774
37905
|
if (signal?.aborted)
|
|
37775
37906
|
throw new Error("AbortError");
|
|
37776
37907
|
if (isSuppressed(i.ruleId, i.line, suppress))
|
|
37777
37908
|
continue;
|
|
37778
|
-
if (commentLines.has(i.line))
|
|
37909
|
+
if (commentLines.has(i.line) && shouldSkipCommentOnlyPluginIssue(i.ruleId))
|
|
37779
37910
|
continue;
|
|
37780
37911
|
issues.push({
|
|
37781
37912
|
filePath: i.filePath,
|
|
@@ -37809,6 +37940,7 @@ async function runLintProgrammatic(globs, options, signal) {
|
|
|
37809
37940
|
return !absBase.startsWith(process25.cwd());
|
|
37810
37941
|
});
|
|
37811
37942
|
const globIgnores = isGlobbingOutsideProject ? [...UNIVERSAL_IGNORES] : cfg.ignores;
|
|
37943
|
+
const ignoreMatcher = createIgnoreMatcher(globIgnores);
|
|
37812
37944
|
let entries = [];
|
|
37813
37945
|
const nonGlobSingle = patterns.length === 1 && !/[*?[\]{}()!]/.test(patterns[0]);
|
|
37814
37946
|
if (nonGlobSingle) {
|
|
@@ -37834,7 +37966,7 @@ async function runLintProgrammatic(globs, options, signal) {
|
|
|
37834
37966
|
for (const it of items) {
|
|
37835
37967
|
const full = join11(dir, it);
|
|
37836
37968
|
const st = statSync6(full);
|
|
37837
|
-
if (
|
|
37969
|
+
if (ignoreMatcher(full))
|
|
37838
37970
|
continue;
|
|
37839
37971
|
if (st.isDirectory())
|
|
37840
37972
|
stack.push(full);
|
|
@@ -37873,7 +38005,7 @@ async function runLintProgrammatic(globs, options, signal) {
|
|
|
37873
38005
|
cntNodeModules++;
|
|
37874
38006
|
continue;
|
|
37875
38007
|
}
|
|
37876
|
-
if (
|
|
38008
|
+
if (ignoreMatcher(f)) {
|
|
37877
38009
|
cntIgnored++;
|
|
37878
38010
|
continue;
|
|
37879
38011
|
}
|
|
@@ -37886,15 +38018,12 @@ async function runLintProgrammatic(globs, options, signal) {
|
|
|
37886
38018
|
}
|
|
37887
38019
|
trace2("filter:programmatic", { total: cntTotal, included: cntIncluded, node_modules: cntNodeModules, ignored: cntIgnored, wrongExt: cntWrongExt });
|
|
37888
38020
|
const concurrency = ENV.CONCURRENCY;
|
|
37889
|
-
const limit = createLimiter(concurrency);
|
|
37890
38021
|
const processFile = async (file) => {
|
|
37891
38022
|
if (signal?.aborted)
|
|
37892
38023
|
throw new Error("AbortError");
|
|
37893
38024
|
const src = readFileSync10(file, "utf8");
|
|
37894
38025
|
const suppress = parseDisableDirectives(src);
|
|
37895
38026
|
const commentLines = getCommentLines(src);
|
|
37896
|
-
const cfgAny = cfg;
|
|
37897
|
-
cfgAny._internalSkipPluginRulesInScan = true;
|
|
37898
38027
|
let issues = scanContentOptimized(file, src, cfg, suppress, commentLines);
|
|
37899
38028
|
try {
|
|
37900
38029
|
const pluginIssues = await applyPlugins(file, src, cfg);
|
|
@@ -37903,7 +38032,7 @@ async function runLintProgrammatic(globs, options, signal) {
|
|
|
37903
38032
|
throw new Error("AbortError");
|
|
37904
38033
|
if (isSuppressed(i.ruleId, i.line, suppress))
|
|
37905
38034
|
continue;
|
|
37906
|
-
if (commentLines.has(i.line))
|
|
38035
|
+
if (commentLines.has(i.line) && shouldSkipCommentOnlyPluginIssue(i.ruleId))
|
|
37907
38036
|
continue;
|
|
37908
38037
|
issues.push({
|
|
37909
38038
|
filePath: i.filePath,
|
|
@@ -37953,7 +38082,7 @@ async function runLintProgrammatic(globs, options, signal) {
|
|
|
37953
38082
|
}
|
|
37954
38083
|
return issues;
|
|
37955
38084
|
};
|
|
37956
|
-
const issueArrays = await
|
|
38085
|
+
const issueArrays = await processWithConcurrency(files, concurrency, processFile);
|
|
37957
38086
|
const allIssues = issueArrays.flat();
|
|
37958
38087
|
const errors = allIssues.filter((i) => i.severity === "error").length;
|
|
37959
38088
|
const warnings = allIssues.filter((i) => i.severity === "warning").length;
|
|
@@ -37975,10 +38104,10 @@ function parseDisableDirectives(content) {
|
|
|
37975
38104
|
for (let i = 0;i < lines.length; i++) {
|
|
37976
38105
|
const t = lines[i].trim();
|
|
37977
38106
|
const lineNo = i + 1;
|
|
37978
|
-
const nextLineMatch = t.match(/^\/\/\s*(?:eslint|pickier)-disable-next-line
|
|
38107
|
+
const nextLineMatch = t.match(/^\/\/\s*(?:eslint|pickier)-disable-next-line(?:\s+(\S.*))?$/);
|
|
37979
38108
|
if (nextLineMatch) {
|
|
37980
|
-
const ruleText = nextLineMatch[1]
|
|
37981
|
-
const list = ruleText.split(",").map((s) => s.trim()).filter(Boolean);
|
|
38109
|
+
const ruleText = nextLineMatch[1]?.replace(/\s+--\s.*$/, "");
|
|
38110
|
+
const list = ruleText ? ruleText.split(",").map((s) => s.trim()).filter(Boolean) : ["*"];
|
|
37982
38111
|
if (list.length > 0) {
|
|
37983
38112
|
const target = lineNo + 1;
|
|
37984
38113
|
const set = nextLine.get(target) || new Set;
|
|
@@ -38069,23 +38198,6 @@ function parseDisableDirectives(content) {
|
|
|
38069
38198
|
const sortedEnableLines = Array.from(rangeEnable.keys()).sort((a, b) => a - b);
|
|
38070
38199
|
return { nextLine, fileLevel, rangeDisable, rangeEnable, sortedDisableLines, sortedEnableLines };
|
|
38071
38200
|
}
|
|
38072
|
-
function binarySearchLargestLessThan(arr, target) {
|
|
38073
|
-
if (arr.length === 0 || arr[0] >= target)
|
|
38074
|
-
return -1;
|
|
38075
|
-
let left = 0;
|
|
38076
|
-
let right = arr.length - 1;
|
|
38077
|
-
let result = -1;
|
|
38078
|
-
while (left <= right) {
|
|
38079
|
-
const mid = Math.floor((left + right) / 2);
|
|
38080
|
-
if (arr[mid] < target) {
|
|
38081
|
-
result = arr[mid];
|
|
38082
|
-
left = mid + 1;
|
|
38083
|
-
} else {
|
|
38084
|
-
right = mid - 1;
|
|
38085
|
-
}
|
|
38086
|
-
}
|
|
38087
|
-
return result;
|
|
38088
|
-
}
|
|
38089
38201
|
function isSuppressed(ruleId, line, directives) {
|
|
38090
38202
|
if (directives instanceof Map) {
|
|
38091
38203
|
const set = directives.get(line);
|
|
@@ -38100,14 +38212,28 @@ function isSuppressed(ruleId, line, directives) {
|
|
|
38100
38212
|
const nextLineSet = directives.nextLine.get(line);
|
|
38101
38213
|
if (nextLineSet && matchesRule(ruleId, nextLineSet))
|
|
38102
38214
|
return true;
|
|
38103
|
-
|
|
38104
|
-
|
|
38105
|
-
|
|
38106
|
-
|
|
38107
|
-
|
|
38108
|
-
|
|
38215
|
+
let disabled = false;
|
|
38216
|
+
let disableIndex = 0;
|
|
38217
|
+
let enableIndex = 0;
|
|
38218
|
+
while (true) {
|
|
38219
|
+
const nextDisable = disableIndex < directives.sortedDisableLines.length ? directives.sortedDisableLines[disableIndex] : Number.POSITIVE_INFINITY;
|
|
38220
|
+
const nextEnable = enableIndex < directives.sortedEnableLines.length ? directives.sortedEnableLines[enableIndex] : Number.POSITIVE_INFINITY;
|
|
38221
|
+
const nextDirectiveLine = Math.min(nextDisable, nextEnable);
|
|
38222
|
+
if (nextDirectiveLine >= line)
|
|
38223
|
+
break;
|
|
38224
|
+
if (nextDisable === nextDirectiveLine) {
|
|
38225
|
+
const disabledRules = directives.rangeDisable.get(nextDisable);
|
|
38226
|
+
if (matchesRule(ruleId, disabledRules))
|
|
38227
|
+
disabled = true;
|
|
38228
|
+
disableIndex++;
|
|
38229
|
+
continue;
|
|
38230
|
+
}
|
|
38231
|
+
const enabledRules = directives.rangeEnable.get(nextEnable);
|
|
38232
|
+
if (enabledRules.has("*") || matchesRule(ruleId, enabledRules))
|
|
38233
|
+
disabled = false;
|
|
38234
|
+
enableIndex++;
|
|
38109
38235
|
}
|
|
38110
|
-
return
|
|
38236
|
+
return disabled;
|
|
38111
38237
|
}
|
|
38112
38238
|
function matchesRule(ruleId, ruleSet) {
|
|
38113
38239
|
if (ruleSet.size === 0)
|
|
@@ -38127,6 +38253,9 @@ function matchesRule(ruleId, ruleSet) {
|
|
|
38127
38253
|
}
|
|
38128
38254
|
return false;
|
|
38129
38255
|
}
|
|
38256
|
+
function shouldSkipCommentOnlyPluginIssue(ruleId) {
|
|
38257
|
+
return ruleId !== "spaced-comment" && !ruleId.endsWith("/spaced-comment");
|
|
38258
|
+
}
|
|
38130
38259
|
function ensureHelpText(issue, ruleId) {
|
|
38131
38260
|
if (issue.help) {
|
|
38132
38261
|
return issue;
|
|
@@ -38163,8 +38292,22 @@ async function withTimeout2(p, ms, label) {
|
|
|
38163
38292
|
throw e;
|
|
38164
38293
|
}
|
|
38165
38294
|
}
|
|
38166
|
-
async function
|
|
38167
|
-
const
|
|
38295
|
+
async function processWithConcurrency(items, concurrency, worker) {
|
|
38296
|
+
const results = new Array(items.length);
|
|
38297
|
+
if (items.length === 0)
|
|
38298
|
+
return results;
|
|
38299
|
+
let nextIndex = 0;
|
|
38300
|
+
const workerCount = Math.max(1, Math.min(Math.max(1, concurrency), items.length));
|
|
38301
|
+
async function runWorker() {
|
|
38302
|
+
while (nextIndex < items.length) {
|
|
38303
|
+
const index = nextIndex++;
|
|
38304
|
+
results[index] = await worker(items[index], index);
|
|
38305
|
+
}
|
|
38306
|
+
}
|
|
38307
|
+
await Promise.all(Array.from({ length: workerCount }, runWorker));
|
|
38308
|
+
return results;
|
|
38309
|
+
}
|
|
38310
|
+
function getPluginDefinitions(cfg) {
|
|
38168
38311
|
let pluginDefs = getAllPlugins();
|
|
38169
38312
|
if (cfg.plugins && cfg.plugins.length > 0) {
|
|
38170
38313
|
const coreNames = new Set(["pickier", "style", "regexp", "ts"]);
|
|
@@ -38174,6 +38317,9 @@ async function applyPlugins(filePath, content, cfg) {
|
|
|
38174
38317
|
for (const p of userPlugins)
|
|
38175
38318
|
pluginDefs.push(p);
|
|
38176
38319
|
}
|
|
38320
|
+
return pluginDefs;
|
|
38321
|
+
}
|
|
38322
|
+
function getRulesConfig(cfg, pluginDefs) {
|
|
38177
38323
|
const rulesConfig = { ...cfg.pluginRules || {} };
|
|
38178
38324
|
if (cfg.rules?.noUnusedCapturingGroup)
|
|
38179
38325
|
rulesConfig["regexp/no-unused-capturing-group"] = cfg.rules.noUnusedCapturingGroup;
|
|
@@ -38183,115 +38329,168 @@ async function applyPlugins(filePath, content, cfg) {
|
|
|
38183
38329
|
"antfu/no-top-level-await": "ts/no-top-level-await"
|
|
38184
38330
|
};
|
|
38185
38331
|
for (const [alias, target] of Object.entries(ruleAliases)) {
|
|
38186
|
-
if (rulesConfig[alias])
|
|
38332
|
+
if (rulesConfig[alias])
|
|
38187
38333
|
rulesConfig[target] = rulesConfig[alias];
|
|
38188
|
-
}
|
|
38189
38334
|
}
|
|
38190
38335
|
for (const key of Object.keys(cfg.pluginRules || {})) {
|
|
38191
38336
|
if (!key.includes("/")) {
|
|
38192
38337
|
for (const p of pluginDefs) {
|
|
38193
|
-
if (p.rules && Object.prototype.hasOwnProperty.call(p.rules, key))
|
|
38338
|
+
if (p.rules && Object.prototype.hasOwnProperty.call(p.rules, key))
|
|
38194
38339
|
rulesConfig[`${p.name}/${key}`] = cfg.pluginRules[key];
|
|
38195
|
-
}
|
|
38196
38340
|
}
|
|
38197
38341
|
}
|
|
38198
38342
|
}
|
|
38199
|
-
|
|
38343
|
+
return rulesConfig;
|
|
38344
|
+
}
|
|
38345
|
+
function getPluginPlan(cfg) {
|
|
38346
|
+
const cached = pluginPlanCache.get(cfg);
|
|
38347
|
+
if (cached)
|
|
38348
|
+
return cached;
|
|
38349
|
+
const pluginDefs = getPluginDefinitions(cfg);
|
|
38350
|
+
const rulesConfig = getRulesConfig(cfg, pluginDefs);
|
|
38351
|
+
const checkRules = [];
|
|
38352
|
+
const fixRules = [];
|
|
38353
|
+
const fixableRuleIds = new Set(["no-debugger"]);
|
|
38354
|
+
const fixableBareRuleNames = new Set(["no-debugger"]);
|
|
38200
38355
|
const executedRules = new Set;
|
|
38201
38356
|
for (const plugin of pluginDefs) {
|
|
38202
|
-
const
|
|
38203
|
-
for (const ruleName in r) {
|
|
38357
|
+
for (const ruleName in plugin.rules) {
|
|
38204
38358
|
const fullRuleId = `${plugin.name}/${ruleName}`;
|
|
38205
38359
|
const setting = getRuleSetting(rulesConfig, fullRuleId);
|
|
38206
38360
|
if (!setting.enabled)
|
|
38207
38361
|
continue;
|
|
38208
|
-
if (executedRules.has(ruleName))
|
|
38362
|
+
if (executedRules.has(ruleName))
|
|
38209
38363
|
continue;
|
|
38210
|
-
}
|
|
38211
38364
|
executedRules.add(ruleName);
|
|
38212
|
-
const rule =
|
|
38213
|
-
const
|
|
38214
|
-
|
|
38215
|
-
|
|
38216
|
-
|
|
38217
|
-
|
|
38218
|
-
|
|
38219
|
-
|
|
38220
|
-
|
|
38221
|
-
|
|
38222
|
-
|
|
38223
|
-
|
|
38224
|
-
|
|
38225
|
-
|
|
38365
|
+
const rule = plugin.rules[ruleName];
|
|
38366
|
+
const planned = {
|
|
38367
|
+
pluginName: plugin.name,
|
|
38368
|
+
ruleName,
|
|
38369
|
+
fullRuleId,
|
|
38370
|
+
rule,
|
|
38371
|
+
severity: setting.severity,
|
|
38372
|
+
options: setting.options
|
|
38373
|
+
};
|
|
38374
|
+
if (typeof rule?.check === "function")
|
|
38375
|
+
checkRules.push(planned);
|
|
38376
|
+
else if (setting.severity === "error") {
|
|
38377
|
+
checkRules.push(planned);
|
|
38378
|
+
}
|
|
38379
|
+
if (typeof rule?.fix === "function") {
|
|
38380
|
+
fixRules.push(planned);
|
|
38381
|
+
fixableRuleIds.add(fullRuleId);
|
|
38382
|
+
fixableBareRuleNames.add(ruleName);
|
|
38383
|
+
}
|
|
38384
|
+
}
|
|
38385
|
+
}
|
|
38386
|
+
const plan = { checkRules, fixRules, fixableRuleIds, fixableBareRuleNames };
|
|
38387
|
+
pluginPlanCache.set(cfg, plan);
|
|
38388
|
+
return plan;
|
|
38389
|
+
}
|
|
38390
|
+
function isShellPath(filePath, content) {
|
|
38391
|
+
return /\.(?:sh|bash|zsh|ksh|dash)$/.test(filePath) || /^#!\s*(?:\/usr\/bin\/env\s+)?(?:ba|z|k|da)?sh\b/.test(content);
|
|
38392
|
+
}
|
|
38393
|
+
function isLockfilePath(filePath) {
|
|
38394
|
+
return /(?:^|[/\\])(?:bun\.lock|bun\.lockb|package-lock\.json|pnpm-lock\.yaml|yarn\.lock|npm-shrinkwrap\.json)$/.test(filePath);
|
|
38395
|
+
}
|
|
38396
|
+
function shouldRunPlannedRule(rule, filePath, content) {
|
|
38397
|
+
switch (rule.pluginName) {
|
|
38398
|
+
case "markdown":
|
|
38399
|
+
return filePath.endsWith(".md");
|
|
38400
|
+
case "shell":
|
|
38401
|
+
return isShellPath(filePath, content);
|
|
38402
|
+
case "publint":
|
|
38403
|
+
return /(?:^|[/\\])package\.json$/.test(filePath);
|
|
38404
|
+
case "lockfile":
|
|
38405
|
+
return isLockfilePath(filePath);
|
|
38406
|
+
case "node":
|
|
38407
|
+
case "ts":
|
|
38408
|
+
case "general":
|
|
38409
|
+
case "quality":
|
|
38410
|
+
case "eslint":
|
|
38411
|
+
case "regexp":
|
|
38412
|
+
case "unused-imports":
|
|
38413
|
+
case "perfectionist":
|
|
38414
|
+
return /\.(?:ts|js|tsx|jsx|mts|mjs|cts|cjs)$/.test(filePath);
|
|
38415
|
+
default:
|
|
38416
|
+
return true;
|
|
38417
|
+
}
|
|
38418
|
+
}
|
|
38419
|
+
async function applyPlugins(filePath, content, cfg) {
|
|
38420
|
+
const issues = [];
|
|
38421
|
+
const plan = getPluginPlan(cfg);
|
|
38422
|
+
const baseCtx = { filePath, config: cfg };
|
|
38423
|
+
for (const planned of plan.checkRules) {
|
|
38424
|
+
if (!shouldRunPlannedRule(planned, filePath, content))
|
|
38425
|
+
continue;
|
|
38426
|
+
const { fullRuleId, rule, severity: overrideSeverity } = planned;
|
|
38427
|
+
if (!rule || typeof rule.check !== "function") {
|
|
38428
|
+
if (overrideSeverity === "error") {
|
|
38429
|
+
issues.push({
|
|
38430
|
+
filePath,
|
|
38431
|
+
line: 1,
|
|
38432
|
+
column: 1,
|
|
38433
|
+
ruleId: `${fullRuleId}-internal`,
|
|
38434
|
+
message: "Rule missing implementation (check function is undefined)",
|
|
38435
|
+
severity: "error"
|
|
38436
|
+
});
|
|
38226
38437
|
}
|
|
38227
|
-
|
|
38228
|
-
|
|
38229
|
-
|
|
38230
|
-
|
|
38231
|
-
|
|
38232
|
-
|
|
38233
|
-
|
|
38234
|
-
|
|
38235
|
-
|
|
38236
|
-
|
|
38237
|
-
else
|
|
38238
|
-
issues.push(issueWithHelp);
|
|
38239
|
-
}
|
|
38240
|
-
} catch (e) {
|
|
38438
|
+
continue;
|
|
38439
|
+
}
|
|
38440
|
+
try {
|
|
38441
|
+
trace2("rule:start", fullRuleId);
|
|
38442
|
+
const ruleTimeoutMs = ENV.RULE_TIMEOUT_MS;
|
|
38443
|
+
const ctx = { ...baseCtx, options: planned.options };
|
|
38444
|
+
const started = performance.now();
|
|
38445
|
+
const out = await withTimeout2(Promise.resolve().then(() => rule.check(content, ctx)), ruleTimeoutMs, `rule:${fullRuleId}`);
|
|
38446
|
+
const elapsed = performance.now() - started;
|
|
38447
|
+
if (elapsed > ruleTimeoutMs) {
|
|
38241
38448
|
issues.push({
|
|
38242
38449
|
filePath,
|
|
38243
38450
|
line: 1,
|
|
38244
38451
|
column: 1,
|
|
38245
38452
|
ruleId: `${fullRuleId}-internal`,
|
|
38246
|
-
message: `Rule
|
|
38453
|
+
message: `Rule exceeded timeout budget: ${Math.round(elapsed)}ms > ${ruleTimeoutMs}ms`,
|
|
38247
38454
|
severity: "error"
|
|
38248
38455
|
});
|
|
38249
38456
|
}
|
|
38457
|
+
trace2("rule:end", fullRuleId, Array.isArray(out) ? out.length : 0);
|
|
38458
|
+
for (const i of out) {
|
|
38459
|
+
const issueWithHelp = ensureHelpText(i, fullRuleId);
|
|
38460
|
+
if (overrideSeverity)
|
|
38461
|
+
issues.push({ ...issueWithHelp, severity: overrideSeverity });
|
|
38462
|
+
else
|
|
38463
|
+
issues.push(issueWithHelp);
|
|
38464
|
+
}
|
|
38465
|
+
} catch (e) {
|
|
38466
|
+
issues.push({
|
|
38467
|
+
filePath,
|
|
38468
|
+
line: 1,
|
|
38469
|
+
column: 1,
|
|
38470
|
+
ruleId: `${fullRuleId}-internal`,
|
|
38471
|
+
message: `Rule threw: ${e?.message || e}`,
|
|
38472
|
+
severity: "error"
|
|
38473
|
+
});
|
|
38250
38474
|
}
|
|
38251
38475
|
}
|
|
38252
38476
|
return issues;
|
|
38253
38477
|
}
|
|
38254
38478
|
function applyPluginFixes(filePath, content, cfg) {
|
|
38255
|
-
const
|
|
38256
|
-
if (cfg.plugins && cfg.plugins.length > 0) {
|
|
38257
|
-
for (const p of cfg.plugins) {
|
|
38258
|
-
if (typeof p === "string")
|
|
38259
|
-
continue;
|
|
38260
|
-
pluginDefs.push(p);
|
|
38261
|
-
}
|
|
38262
|
-
}
|
|
38263
|
-
const rulesConfig = { ...cfg.pluginRules || {} };
|
|
38264
|
-
if (cfg.rules?.noUnusedCapturingGroup)
|
|
38265
|
-
rulesConfig["regexp/no-unused-capturing-group"] = cfg.rules.noUnusedCapturingGroup;
|
|
38266
|
-
for (const key of Object.keys(cfg.pluginRules || {})) {
|
|
38267
|
-
if (!key.includes("/")) {
|
|
38268
|
-
for (const p of pluginDefs) {
|
|
38269
|
-
if (p.rules && Object.prototype.hasOwnProperty.call(p.rules, key))
|
|
38270
|
-
rulesConfig[`${p.name}/${key}`] = cfg.pluginRules[key];
|
|
38271
|
-
}
|
|
38272
|
-
}
|
|
38273
|
-
}
|
|
38479
|
+
const plan = getPluginPlan(cfg);
|
|
38274
38480
|
const baseCtx = { filePath, config: cfg };
|
|
38275
38481
|
let out = content;
|
|
38276
38482
|
let changed = true;
|
|
38277
38483
|
let passes = 0;
|
|
38278
38484
|
while (changed && passes++ < MAX_FIXER_PASSES) {
|
|
38279
38485
|
changed = false;
|
|
38280
|
-
for (const
|
|
38281
|
-
|
|
38282
|
-
|
|
38283
|
-
|
|
38284
|
-
|
|
38285
|
-
|
|
38286
|
-
|
|
38287
|
-
|
|
38288
|
-
continue;
|
|
38289
|
-
const ctx = { ...baseCtx, options: setting.options };
|
|
38290
|
-
const next = rule.fix(out, ctx);
|
|
38291
|
-
if (next !== out) {
|
|
38292
|
-
out = next;
|
|
38293
|
-
changed = true;
|
|
38294
|
-
}
|
|
38486
|
+
for (const planned of plan.fixRules) {
|
|
38487
|
+
if (!shouldRunPlannedRule(planned, filePath, out))
|
|
38488
|
+
continue;
|
|
38489
|
+
const ctx = { ...baseCtx, options: planned.options };
|
|
38490
|
+
const next = planned.rule.fix(out, ctx);
|
|
38491
|
+
if (next !== out) {
|
|
38492
|
+
out = next;
|
|
38493
|
+
changed = true;
|
|
38295
38494
|
}
|
|
38296
38495
|
}
|
|
38297
38496
|
}
|
|
@@ -38460,6 +38659,7 @@ function getCommentLines(content) {
|
|
|
38460
38659
|
let state = "code";
|
|
38461
38660
|
let lineNo = 1;
|
|
38462
38661
|
let lineHasCode = false;
|
|
38662
|
+
let lineSawComment = false;
|
|
38463
38663
|
let lineStartedInBlockComment = false;
|
|
38464
38664
|
for (let i = 0;i < content.length; i++) {
|
|
38465
38665
|
const ch = content[i];
|
|
@@ -38469,11 +38669,14 @@ function getCommentLines(content) {
|
|
|
38469
38669
|
`) {
|
|
38470
38670
|
if (lineStartedInBlockComment && state === "block-comment") {
|
|
38471
38671
|
commentLines.add(lineNo);
|
|
38472
|
-
} else if (!lineHasCode && state !== "block-comment") {
|
|
38672
|
+
} else if (!lineHasCode && lineSawComment && state !== "block-comment") {
|
|
38673
|
+
commentLines.add(lineNo);
|
|
38674
|
+
} else if (!lineHasCode && state === "block-comment") {
|
|
38473
38675
|
commentLines.add(lineNo);
|
|
38474
38676
|
}
|
|
38475
38677
|
lineNo++;
|
|
38476
38678
|
lineHasCode = false;
|
|
38679
|
+
lineSawComment = false;
|
|
38477
38680
|
lineStartedInBlockComment = state === "block-comment";
|
|
38478
38681
|
if (state === "line-comment") {
|
|
38479
38682
|
state = "code";
|
|
@@ -38484,6 +38687,7 @@ function getCommentLines(content) {
|
|
|
38484
38687
|
case "code":
|
|
38485
38688
|
if (ch === "/" && next === "/") {
|
|
38486
38689
|
state = "line-comment";
|
|
38690
|
+
lineSawComment = true;
|
|
38487
38691
|
i++;
|
|
38488
38692
|
} else if (ch === "/" && next === "*") {
|
|
38489
38693
|
let isRegex = false;
|
|
@@ -38525,6 +38729,7 @@ function getCommentLines(content) {
|
|
|
38525
38729
|
}
|
|
38526
38730
|
i--;
|
|
38527
38731
|
} else {
|
|
38732
|
+
lineSawComment = true;
|
|
38528
38733
|
state = "block-comment";
|
|
38529
38734
|
i++;
|
|
38530
38735
|
}
|
|
@@ -38619,6 +38824,8 @@ function getCommentLines(content) {
|
|
|
38619
38824
|
}
|
|
38620
38825
|
if (lineStartedInBlockComment && state === "block-comment") {
|
|
38621
38826
|
commentLines.add(lineNo);
|
|
38827
|
+
} else if (!lineHasCode && lineSawComment && state !== "block-comment") {
|
|
38828
|
+
commentLines.add(lineNo);
|
|
38622
38829
|
} else if (!lineHasCode && state === "block-comment") {
|
|
38623
38830
|
commentLines.add(lineNo);
|
|
38624
38831
|
}
|
|
@@ -38635,6 +38842,10 @@ function scanContentOptimized(filePath, content, cfg, suppress, commentLines) {
|
|
|
38635
38842
|
const quotesDisabled = quotesRuleSetting === "off";
|
|
38636
38843
|
const skipQuotesCheck = quotesDisabled || fileExt === "json" || fileExt === "jsonc" || fileExt === "lock" || isMd || fileExt === "yaml" || fileExt === "yml" || fileExt === "stx" || fileExt === "html" || fileExt === "htm" || fileExt === "vue" || isShell || filePath.endsWith("bun.lock");
|
|
38637
38844
|
const skipCodeRules = isMd || fileExt === "yaml" || fileExt === "yml" || fileExt === "json" || fileExt === "jsonc" || isShell;
|
|
38845
|
+
const indentRuleSetting = cfg.rules?.indent ?? cfg.pluginRules?.indent ?? cfg.pluginRules?.["style/indent"];
|
|
38846
|
+
const indentDisabled = indentRuleSetting === "off";
|
|
38847
|
+
const isTemplate = fileExt === "stx" || fileExt === "html" || fileExt === "htm" || fileExt === "vue";
|
|
38848
|
+
const shouldCheckIndent = !indentDisabled && !isMd && !isTemplate;
|
|
38638
38849
|
let quotesReported = false;
|
|
38639
38850
|
const sevMap = (s) => s === "warn" ? "warning" : s === "error" ? "error" : undefined;
|
|
38640
38851
|
const wantDebugger = sevMap(cfg.rules.noDebugger);
|
|
@@ -38656,33 +38867,34 @@ function scanContentOptimized(filePath, content, cfg, suppress, commentLines) {
|
|
|
38656
38867
|
}
|
|
38657
38868
|
}
|
|
38658
38869
|
const linesInTemplate = new Set;
|
|
38659
|
-
|
|
38660
|
-
|
|
38661
|
-
|
|
38662
|
-
|
|
38663
|
-
|
|
38664
|
-
|
|
38665
|
-
escaped
|
|
38666
|
-
|
|
38870
|
+
if (content.includes("`")) {
|
|
38871
|
+
let inTemplate = false;
|
|
38872
|
+
let escaped = false;
|
|
38873
|
+
let currentLine = 1;
|
|
38874
|
+
for (let i = 0;i < content.length; i++) {
|
|
38875
|
+
const ch = content[i];
|
|
38876
|
+
if (escaped) {
|
|
38877
|
+
escaped = false;
|
|
38878
|
+
if (ch === `
|
|
38667
38879
|
`)
|
|
38668
|
-
|
|
38669
|
-
|
|
38670
|
-
|
|
38671
|
-
|
|
38672
|
-
|
|
38673
|
-
|
|
38674
|
-
|
|
38675
|
-
|
|
38880
|
+
currentLine++;
|
|
38881
|
+
continue;
|
|
38882
|
+
}
|
|
38883
|
+
if (ch === "\\") {
|
|
38884
|
+
escaped = true;
|
|
38885
|
+
continue;
|
|
38886
|
+
}
|
|
38887
|
+
if (ch === `
|
|
38676
38888
|
`) {
|
|
38677
|
-
|
|
38678
|
-
|
|
38679
|
-
|
|
38680
|
-
|
|
38681
|
-
|
|
38682
|
-
|
|
38683
|
-
|
|
38684
|
-
|
|
38685
|
-
|
|
38889
|
+
currentLine++;
|
|
38890
|
+
continue;
|
|
38891
|
+
}
|
|
38892
|
+
if (ch === "`") {
|
|
38893
|
+
inTemplate = !inTemplate;
|
|
38894
|
+
continue;
|
|
38895
|
+
}
|
|
38896
|
+
if (inTemplate)
|
|
38897
|
+
linesInTemplate.add(currentLine);
|
|
38686
38898
|
}
|
|
38687
38899
|
}
|
|
38688
38900
|
for (let i = 0;i < lines.length; i++) {
|
|
@@ -38701,12 +38913,11 @@ function scanContentOptimized(filePath, content, cfg, suppress, commentLines) {
|
|
|
38701
38913
|
quotesReported = true;
|
|
38702
38914
|
}
|
|
38703
38915
|
}
|
|
38704
|
-
|
|
38705
|
-
|
|
38706
|
-
|
|
38707
|
-
const
|
|
38708
|
-
|
|
38709
|
-
if (!indentDisabled && !isMd && !isTemplate && leading.length > 0 && !linesInFencedCodeBlock.has(lineNo) && hasIndentIssue(leading, cfg.format.indent, cfg.format.indentStyle, line)) {
|
|
38916
|
+
let wsEnd = 0;
|
|
38917
|
+
while (wsEnd < line.length && (line.charCodeAt(wsEnd) === 32 || line.charCodeAt(wsEnd) === 9))
|
|
38918
|
+
wsEnd++;
|
|
38919
|
+
const leading = wsEnd > 0 ? line.slice(0, wsEnd) : "";
|
|
38920
|
+
if (shouldCheckIndent && leading.length > 0 && !linesInFencedCodeBlock.has(lineNo) && hasIndentIssue(leading, cfg.format.indent, cfg.format.indentStyle, line)) {
|
|
38710
38921
|
if (!isSuppressed("indent", lineNo, suppress))
|
|
38711
38922
|
issues.push({ filePath, line: lineNo, column: 1, ruleId: "indent", message: "Incorrect indentation detected", severity: "warning", help: `Use ${cfg.format.indentStyle === "spaces" ? `${cfg.format.indent} spaces` : "tabs"} for indentation. Configure with format.indent and format.indentStyle in your config` });
|
|
38712
38923
|
}
|
|
@@ -38811,24 +39022,43 @@ function scanContentOptimized(filePath, content, cfg, suppress, commentLines) {
|
|
|
38811
39022
|
}
|
|
38812
39023
|
if (!skipCodeRules && wantNoCondAssign && !linesInTemplate.has(lineNo)) {
|
|
38813
39024
|
const strippedLine = stripComments2(stripRegexLiterals(line));
|
|
38814
|
-
const
|
|
38815
|
-
const
|
|
39025
|
+
const conditionLine = strippedLine.replace(/'[^']*'|"[^"]*"/g, '""');
|
|
39026
|
+
const checkCond = (cond) => /[^=!<>]=(?![=>])/.test(cond);
|
|
39027
|
+
const m1 = conditionLine.match(/\b(?:if|while)\s*\(([^)]*)\)/);
|
|
38816
39028
|
if (m1) {
|
|
38817
39029
|
const cond = m1[1];
|
|
38818
39030
|
if (checkCond(cond)) {
|
|
38819
|
-
if (!isSuppressed("no-cond-assign", lineNo, suppress))
|
|
38820
|
-
issues.push({
|
|
39031
|
+
if (!isSuppressed("no-cond-assign", lineNo, suppress)) {
|
|
39032
|
+
issues.push({
|
|
39033
|
+
filePath,
|
|
39034
|
+
line: lineNo,
|
|
39035
|
+
column: Math.max(1, line.indexOf("(") + 1),
|
|
39036
|
+
ruleId: "no-cond-assign",
|
|
39037
|
+
message: "Unexpected assignment within a conditional expression",
|
|
39038
|
+
severity: wantNoCondAssign,
|
|
39039
|
+
help: "Use === or == for comparison instead of = (assignment). Wrap intentional assignments in extra parentheses."
|
|
39040
|
+
});
|
|
39041
|
+
}
|
|
38821
39042
|
}
|
|
38822
39043
|
}
|
|
38823
|
-
const mFor =
|
|
39044
|
+
const mFor = conditionLine.match(/\bfor\s*\(([^)]*)\)/);
|
|
38824
39045
|
if (mFor) {
|
|
38825
39046
|
const inside = mFor[1];
|
|
38826
39047
|
const parts = inside.split(";");
|
|
38827
39048
|
if (parts.length >= 2) {
|
|
38828
39049
|
const cond = parts[1];
|
|
38829
39050
|
if (checkCond(cond)) {
|
|
38830
|
-
if (!isSuppressed("no-cond-assign", lineNo, suppress))
|
|
38831
|
-
issues.push({
|
|
39051
|
+
if (!isSuppressed("no-cond-assign", lineNo, suppress)) {
|
|
39052
|
+
issues.push({
|
|
39053
|
+
filePath,
|
|
39054
|
+
line: lineNo,
|
|
39055
|
+
column: Math.max(1, line.indexOf("(") + 1),
|
|
39056
|
+
ruleId: "no-cond-assign",
|
|
39057
|
+
message: "Unexpected assignment within a conditional expression",
|
|
39058
|
+
severity: wantNoCondAssign,
|
|
39059
|
+
help: "Use === or == for comparison instead of = (assignment). Wrap intentional assignments in extra parentheses."
|
|
39060
|
+
});
|
|
39061
|
+
}
|
|
38832
39062
|
}
|
|
38833
39063
|
}
|
|
38834
39064
|
}
|
|
@@ -38840,67 +39070,25 @@ function scanContent(filePath, content, cfg) {
|
|
|
38840
39070
|
const suppress = parseDisableDirectives(content);
|
|
38841
39071
|
const commentLines = getCommentLines(content);
|
|
38842
39072
|
const issues = scanContentOptimized(filePath, content, cfg, suppress, commentLines);
|
|
38843
|
-
|
|
38844
|
-
|
|
38845
|
-
|
|
38846
|
-
|
|
38847
|
-
|
|
38848
|
-
|
|
38849
|
-
|
|
38850
|
-
|
|
38851
|
-
|
|
38852
|
-
|
|
38853
|
-
|
|
38854
|
-
|
|
38855
|
-
|
|
38856
|
-
|
|
38857
|
-
|
|
38858
|
-
|
|
38859
|
-
for (const p of pluginDefs) {
|
|
38860
|
-
if (p.rules && Object.prototype.hasOwnProperty.call(p.rules, key))
|
|
38861
|
-
rulesConfig[`${p.name}/${key}`] = cfg.pluginRules[key];
|
|
38862
|
-
}
|
|
38863
|
-
}
|
|
38864
|
-
}
|
|
38865
|
-
const isRuleEnabled = (ruleId) => {
|
|
38866
|
-
const raw = rulesConfig[ruleId];
|
|
38867
|
-
const setting = typeof raw === "string" ? raw : undefined;
|
|
38868
|
-
return setting === "error" || setting === "warn" || setting === "warning";
|
|
38869
|
-
};
|
|
38870
|
-
const getRuleSeverity = (ruleId) => {
|
|
38871
|
-
const raw = rulesConfig[ruleId];
|
|
38872
|
-
const setting = typeof raw === "string" ? raw : undefined;
|
|
38873
|
-
if (setting === "error")
|
|
38874
|
-
return "error";
|
|
38875
|
-
if (setting === "warn" || setting === "warning")
|
|
38876
|
-
return "warning";
|
|
38877
|
-
return;
|
|
38878
|
-
};
|
|
38879
|
-
const ctx = { filePath, config: cfg };
|
|
38880
|
-
const executedRulesInScan = new Set;
|
|
38881
|
-
for (const plugin of pluginDefs) {
|
|
38882
|
-
const r = plugin.rules;
|
|
38883
|
-
for (const ruleName in r) {
|
|
38884
|
-
const fullRuleId = `${plugin.name}/${ruleName}`;
|
|
38885
|
-
if (!isRuleEnabled(fullRuleId))
|
|
38886
|
-
continue;
|
|
38887
|
-
if (executedRulesInScan.has(ruleName))
|
|
38888
|
-
continue;
|
|
38889
|
-
executedRulesInScan.add(ruleName);
|
|
38890
|
-
const rule = r[ruleName];
|
|
38891
|
-
if (!rule || typeof rule.check !== "function")
|
|
38892
|
-
continue;
|
|
38893
|
-
const out = rule.check(content, ctx);
|
|
38894
|
-
for (const i of out) {
|
|
38895
|
-
if (!isSuppressed(i.ruleId, i.line, suppress)) {
|
|
38896
|
-
const sev = getRuleSeverity(fullRuleId);
|
|
38897
|
-
issues.push(sev ? { ...i, severity: sev } : i);
|
|
38898
|
-
}
|
|
38899
|
-
}
|
|
38900
|
-
}
|
|
39073
|
+
try {
|
|
39074
|
+
const plan = getPluginPlan(cfg);
|
|
39075
|
+
const ctx = { filePath, config: cfg };
|
|
39076
|
+
for (const planned of plan.checkRules) {
|
|
39077
|
+
if (!shouldRunPlannedRule(planned, filePath, content))
|
|
39078
|
+
continue;
|
|
39079
|
+
if (!planned.rule || typeof planned.rule.check !== "function")
|
|
39080
|
+
continue;
|
|
39081
|
+
const out = planned.rule.check(content, { ...ctx, options: planned.options });
|
|
39082
|
+
for (const i of out) {
|
|
39083
|
+
if (isSuppressed(i.ruleId, i.line, suppress))
|
|
39084
|
+
continue;
|
|
39085
|
+
if (commentLines.has(i.line) && shouldSkipCommentOnlyPluginIssue(i.ruleId))
|
|
39086
|
+
continue;
|
|
39087
|
+
const issueWithHelp = ensureHelpText(i, planned.fullRuleId);
|
|
39088
|
+
issues.push(planned.severity ? { ...issueWithHelp, severity: planned.severity } : issueWithHelp);
|
|
38901
39089
|
}
|
|
38902
|
-
}
|
|
38903
|
-
}
|
|
39090
|
+
}
|
|
39091
|
+
} catch {}
|
|
38904
39092
|
return issues;
|
|
38905
39093
|
}
|
|
38906
39094
|
async function runLint(globs, options) {
|
|
@@ -38934,6 +39122,7 @@ async function runLint(globs, options) {
|
|
|
38934
39122
|
return !absBase.startsWith(process25.cwd());
|
|
38935
39123
|
});
|
|
38936
39124
|
const globIgnores = isGlobbingOutsideProject ? [...UNIVERSAL_IGNORES] : cfg.ignores;
|
|
39125
|
+
const ignoreMatcher = createIgnoreMatcher(globIgnores);
|
|
38937
39126
|
if (enableDiagnostics) {
|
|
38938
39127
|
getLogger2().info(`[pickier:diagnostics] Globbing outside project: ${isGlobbingOutsideProject}, ignore patterns: ${globIgnores.length}`);
|
|
38939
39128
|
if (isGlobbingOutsideProject)
|
|
@@ -38970,7 +39159,7 @@ async function runLint(globs, options) {
|
|
|
38970
39159
|
for (const it of items) {
|
|
38971
39160
|
const full = join11(dir, it);
|
|
38972
39161
|
const st = statSync6(full);
|
|
38973
|
-
if (
|
|
39162
|
+
if (ignoreMatcher(full))
|
|
38974
39163
|
continue;
|
|
38975
39164
|
if (st.isDirectory())
|
|
38976
39165
|
stack.push(full);
|
|
@@ -39032,7 +39221,7 @@ async function runLint(globs, options) {
|
|
|
39032
39221
|
cntNodeModules++;
|
|
39033
39222
|
continue;
|
|
39034
39223
|
}
|
|
39035
|
-
if (
|
|
39224
|
+
if (ignoreMatcher(f)) {
|
|
39036
39225
|
cntIgnored++;
|
|
39037
39226
|
continue;
|
|
39038
39227
|
}
|
|
@@ -39063,7 +39252,6 @@ async function runLint(globs, options) {
|
|
|
39063
39252
|
}
|
|
39064
39253
|
}
|
|
39065
39254
|
const concurrency = ENV.CONCURRENCY;
|
|
39066
|
-
const limit = createLimiter(concurrency);
|
|
39067
39255
|
if (enableDiagnostics)
|
|
39068
39256
|
getLogger2().info(`[pickier:diagnostics] Starting to process ${files.length} files with concurrency ${concurrency}...`);
|
|
39069
39257
|
let processedCount = 0;
|
|
@@ -39077,23 +39265,33 @@ async function runLint(globs, options) {
|
|
|
39077
39265
|
const src = readFileSync10(file, "utf8");
|
|
39078
39266
|
if (formatOnly) {
|
|
39079
39267
|
const fixed = formatCode(src, cfg, file);
|
|
39080
|
-
if (fixed !== src
|
|
39081
|
-
|
|
39268
|
+
if (fixed !== src) {
|
|
39269
|
+
if (!options.dryRun) {
|
|
39270
|
+
writeFileSync11(file, fixed, "utf8");
|
|
39271
|
+
} else {
|
|
39272
|
+
return [{
|
|
39273
|
+
filePath: file,
|
|
39274
|
+
line: 1,
|
|
39275
|
+
column: 1,
|
|
39276
|
+
ruleId: "format",
|
|
39277
|
+
message: "File is not formatted",
|
|
39278
|
+
severity: "error",
|
|
39279
|
+
help: "Run pickier format with --write to apply formatting."
|
|
39280
|
+
}];
|
|
39281
|
+
}
|
|
39082
39282
|
}
|
|
39083
39283
|
return [];
|
|
39084
39284
|
}
|
|
39085
39285
|
const suppress = parseDisableDirectives(src);
|
|
39086
39286
|
const isCodeFileForComments = /\.(?:ts|js|tsx|jsx|mts|mjs|cts|cjs)$/.test(file);
|
|
39087
39287
|
const commentLines = isCodeFileForComments ? getCommentLines(src) : new Set;
|
|
39088
|
-
const cfgAny = cfg;
|
|
39089
|
-
cfgAny._internalSkipPluginRulesInScan = true;
|
|
39090
39288
|
let issues = scanContentOptimized(file, src, cfg, suppress, commentLines);
|
|
39091
39289
|
try {
|
|
39092
39290
|
const pluginIssues = await applyPlugins(file, src, cfg);
|
|
39093
39291
|
for (const i of pluginIssues) {
|
|
39094
39292
|
if (isSuppressed(i.ruleId, i.line, suppress))
|
|
39095
39293
|
continue;
|
|
39096
|
-
if (commentLines.has(i.line))
|
|
39294
|
+
if (commentLines.has(i.line) && shouldSkipCommentOnlyPluginIssue(i.ruleId))
|
|
39097
39295
|
continue;
|
|
39098
39296
|
issues.push({
|
|
39099
39297
|
filePath: i.filePath,
|
|
@@ -39152,7 +39350,7 @@ async function runLint(globs, options) {
|
|
|
39152
39350
|
trace2("scan done", relative7(process25.cwd(), file), issues.length);
|
|
39153
39351
|
return issues;
|
|
39154
39352
|
};
|
|
39155
|
-
const issueArrays = await
|
|
39353
|
+
const issueArrays = await processWithConcurrency(files, concurrency, processFile);
|
|
39156
39354
|
const allIssues = issueArrays.flat();
|
|
39157
39355
|
if (enableDiagnostics)
|
|
39158
39356
|
getLogger2().info(`[pickier:diagnostics] Processing complete! Found ${allIssues.length} issues total`);
|
|
@@ -39177,22 +39375,12 @@ async function runLint(globs, options) {
|
|
|
39177
39375
|
const problemsText = total === 1 ? "problem" : "problems";
|
|
39178
39376
|
const errorsText = errors === 1 ? "error" : "errors";
|
|
39179
39377
|
const warningsText = warnings === 1 ? "warning" : "warnings";
|
|
39180
|
-
const
|
|
39181
|
-
const fixableRuleIds = new Set;
|
|
39182
|
-
fixableRuleIds.add("no-debugger");
|
|
39183
|
-
for (const plugin of pluginDefs) {
|
|
39184
|
-
for (const ruleName in plugin.rules) {
|
|
39185
|
-
const rule = plugin.rules[ruleName];
|
|
39186
|
-
if (rule && typeof rule.fix === "function") {
|
|
39187
|
-
fixableRuleIds.add(`${plugin.name}/${ruleName}`);
|
|
39188
|
-
}
|
|
39189
|
-
}
|
|
39190
|
-
}
|
|
39378
|
+
const pluginPlan = getPluginPlan(cfg);
|
|
39191
39379
|
let fixableErrors = 0;
|
|
39192
39380
|
let fixableWarnings = 0;
|
|
39193
39381
|
for (const issue of allIssues) {
|
|
39194
39382
|
const ruleId = issue.ruleId;
|
|
39195
|
-
const isFixable = fixableRuleIds.has(ruleId) ||
|
|
39383
|
+
const isFixable = pluginPlan.fixableRuleIds.has(ruleId) || pluginPlan.fixableBareRuleNames.has(ruleId);
|
|
39196
39384
|
if (isFixable) {
|
|
39197
39385
|
if (issue.severity === "error")
|
|
39198
39386
|
fixableErrors++;
|
|
@@ -39233,13 +39421,14 @@ async function runLint(globs, options) {
|
|
|
39233
39421
|
return 1;
|
|
39234
39422
|
}
|
|
39235
39423
|
}
|
|
39236
|
-
var _logger2 = null;
|
|
39424
|
+
var _logger2 = null, pluginPlanCache;
|
|
39237
39425
|
var init_linter = __esm(() => {
|
|
39238
39426
|
init_src();
|
|
39239
39427
|
init_format();
|
|
39240
39428
|
init_formatter();
|
|
39241
39429
|
init_plugins();
|
|
39242
39430
|
init_utils3();
|
|
39431
|
+
pluginPlanCache = new WeakMap;
|
|
39243
39432
|
});
|
|
39244
39433
|
|
|
39245
39434
|
// src/run.ts
|
|
@@ -39261,6 +39450,8 @@ async function runUnified(globs, options) {
|
|
|
39261
39450
|
const cfg = await loadConfigFromPath(options.config);
|
|
39262
39451
|
const src = readFileSync11(filePath, "utf8");
|
|
39263
39452
|
const fmt = formatCode(src, cfg, filePath);
|
|
39453
|
+
if (options.check && fmt !== src)
|
|
39454
|
+
return 1;
|
|
39264
39455
|
if (options.write && fmt !== src) {
|
|
39265
39456
|
writeFileSync12(filePath, fmt, "utf8");
|
|
39266
39457
|
}
|
|
@@ -39327,6 +39518,7 @@ export {
|
|
|
39327
39518
|
detectQuoteIssues,
|
|
39328
39519
|
defaultConfig4 as defaultConfig,
|
|
39329
39520
|
createLimiter,
|
|
39521
|
+
createIgnoreMatcher,
|
|
39330
39522
|
config5 as config,
|
|
39331
39523
|
colors,
|
|
39332
39524
|
colorize,
|