@sarj/eslint-plugin 16.38.55 → 16.39.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/dist/{_docs-IZjowAEc.d.cts → _docs-_eXGTNOq.d.cts} +1 -1
- package/dist/{_docs-IZjowAEc.d.ts → _docs-_eXGTNOq.d.ts} +1 -1
- package/dist/index.cjs +562 -468
- package/dist/index.d.cts +34 -215
- package/dist/index.d.ts +34 -215
- package/dist/index.js +547 -453
- package/dist/rule-examples.cjs +6 -3
- package/dist/rule-examples.d.cts +5 -1
- package/dist/rule-examples.d.ts +5 -1
- package/dist/rule-examples.js +6 -3
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -1763,32 +1763,215 @@ var no_generic_json_parser_default = createRule({
|
|
|
1763
1763
|
});
|
|
1764
1764
|
|
|
1765
1765
|
// src/rules/no-redundant-local-alias.ts
|
|
1766
|
-
import { AST_NODE_TYPES as
|
|
1766
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES19, ASTUtils as ASTUtils15 } from "@typescript-eslint/utils";
|
|
1767
|
+
|
|
1768
|
+
// src/rules/_unused-private-binding.ts
|
|
1769
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES18 } from "@typescript-eslint/utils";
|
|
1770
|
+
|
|
1771
|
+
// src/rules/_type-binding.ts
|
|
1772
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES17 } from "@typescript-eslint/utils";
|
|
1773
|
+
function typeBinding(source, identifier) {
|
|
1774
|
+
let scope = source.getScope(identifier);
|
|
1775
|
+
while (scope !== null) {
|
|
1776
|
+
const variable = scope.set.get(identifier.name);
|
|
1777
|
+
if (variable !== void 0 && (variable.isTypeVariable || variable.defs.some((definition) => definition.isTypeDefinition))) {
|
|
1778
|
+
return variable;
|
|
1779
|
+
}
|
|
1780
|
+
scope = scope.upper;
|
|
1781
|
+
}
|
|
1782
|
+
return null;
|
|
1783
|
+
}
|
|
1784
|
+
var REFERENCE_INDEXES = /* @__PURE__ */ new WeakMap();
|
|
1785
|
+
function retainsNamedTypeUses(source, removed) {
|
|
1786
|
+
const manager = source.scopeManager;
|
|
1787
|
+
if (manager === null) return false;
|
|
1788
|
+
const index = referenceIndex(source, manager);
|
|
1789
|
+
for (const reference of referencesWithin(index.references, removed)) {
|
|
1790
|
+
if (!reference.isRead()) continue;
|
|
1791
|
+
const binding3 = reference.resolved;
|
|
1792
|
+
if (!binding3 || !reference.isTypeReference && !reference.isValueReference) return false;
|
|
1793
|
+
if (binding3.defs.length === 0) continue;
|
|
1794
|
+
const reads = publicReadExtents(index, binding3);
|
|
1795
|
+
const extent = reference.isTypeReference ? reference.isValueReference ? reads.both : reads.type : reads.value;
|
|
1796
|
+
if (extent === null || extent.minStart >= removed.range[0] && extent.maxEnd <= removed.range[1]) return false;
|
|
1797
|
+
}
|
|
1798
|
+
return true;
|
|
1799
|
+
}
|
|
1800
|
+
function referenceIndex(source, manager) {
|
|
1801
|
+
const cached = REFERENCE_INDEXES.get(source);
|
|
1802
|
+
if (cached?.manager === manager) return cached;
|
|
1803
|
+
const references = manager.scopes.flatMap((scope) => scope.references);
|
|
1804
|
+
references.sort((left, right) => left.identifier.range[0] - right.identifier.range[0]);
|
|
1805
|
+
const index = { manager, references, publicReads: /* @__PURE__ */ new Map() };
|
|
1806
|
+
REFERENCE_INDEXES.set(source, index);
|
|
1807
|
+
return index;
|
|
1808
|
+
}
|
|
1809
|
+
function* referencesWithin(references, removed) {
|
|
1810
|
+
let low = 0;
|
|
1811
|
+
let high = references.length;
|
|
1812
|
+
while (low < high) {
|
|
1813
|
+
const middle = low + Math.floor((high - low) / 2);
|
|
1814
|
+
const reference = references[middle];
|
|
1815
|
+
if (reference === void 0 || reference.identifier.range[0] >= removed.range[0]) high = middle;
|
|
1816
|
+
else low = middle + 1;
|
|
1817
|
+
}
|
|
1818
|
+
for (let index = low; index < references.length; index++) {
|
|
1819
|
+
const reference = references[index];
|
|
1820
|
+
if (reference === void 0) continue;
|
|
1821
|
+
if (reference.identifier.range[0] > removed.range[1]) break;
|
|
1822
|
+
if (insideTypeRange(reference.identifier, removed)) yield reference;
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
function publicReadExtents(index, binding3) {
|
|
1826
|
+
const cached = index.publicReads.get(binding3);
|
|
1827
|
+
if (cached !== void 0) return cached;
|
|
1828
|
+
let type = null;
|
|
1829
|
+
let value = null;
|
|
1830
|
+
let both = null;
|
|
1831
|
+
for (const retained of binding3.references) {
|
|
1832
|
+
if (!retained.isRead() || !retained.isTypeReference && !retained.isValueReference || binding3.defs.some((definition) => insideTypeRange(retained.identifier, definition.node)) || !publicTypeUse(retained.identifier)) continue;
|
|
1833
|
+
if (retained.isTypeReference) type = extendExtent(type, retained.identifier);
|
|
1834
|
+
if (retained.isValueReference) value = extendExtent(value, retained.identifier);
|
|
1835
|
+
if (retained.isTypeReference && retained.isValueReference) both = extendExtent(both, retained.identifier);
|
|
1836
|
+
}
|
|
1837
|
+
const result = { type, value, both };
|
|
1838
|
+
index.publicReads.set(binding3, result);
|
|
1839
|
+
return result;
|
|
1840
|
+
}
|
|
1841
|
+
function extendExtent(extent, identifier) {
|
|
1842
|
+
return {
|
|
1843
|
+
minStart: Math.min(extent?.minStart ?? identifier.range[0], identifier.range[0]),
|
|
1844
|
+
maxEnd: Math.max(extent?.maxEnd ?? identifier.range[1], identifier.range[1])
|
|
1845
|
+
};
|
|
1846
|
+
}
|
|
1847
|
+
function publicTypeUse(identifier) {
|
|
1848
|
+
let node = identifier;
|
|
1849
|
+
while (node.parent) {
|
|
1850
|
+
if (node.type === AST_NODE_TYPES17.TSTypeAnnotation || node.type === AST_NODE_TYPES17.TSTypePredicate || node.type === AST_NODE_TYPES17.TSAsExpression || node.type === AST_NODE_TYPES17.TSTypeAssertion) return false;
|
|
1851
|
+
if (node.type === AST_NODE_TYPES17.TSTypeAliasDeclaration) {
|
|
1852
|
+
return node.parent.type === AST_NODE_TYPES17.ExportNamedDeclaration && node.parent.declaration === node && node.parent.parent.type === AST_NODE_TYPES17.Program;
|
|
1853
|
+
}
|
|
1854
|
+
if (node.type === AST_NODE_TYPES17.ExportSpecifier) {
|
|
1855
|
+
return node.parent.type === AST_NODE_TYPES17.ExportNamedDeclaration && node.parent.source === null && node.parent.parent.type === AST_NODE_TYPES17.Program;
|
|
1856
|
+
}
|
|
1857
|
+
node = node.parent;
|
|
1858
|
+
}
|
|
1859
|
+
return false;
|
|
1860
|
+
}
|
|
1861
|
+
function insideTypeRange(node, range) {
|
|
1862
|
+
return node.range[0] >= range.range[0] && node.range[1] <= range.range[1];
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
// src/rules/_unused-private-binding.ts
|
|
1866
|
+
function isUnusedPrivateBinding(sourceCode, declaration, identifier, filename, allowedDeclarations = [declaration]) {
|
|
1867
|
+
if (/\.d\.[cm]?ts$/u.test(filename)) return false;
|
|
1868
|
+
const bindings = sourceCode.getDeclaredVariables(declaration).filter((binding3) => binding3.name === identifier.name);
|
|
1869
|
+
if (bindings.length === 0 || bindings.some((binding3) => binding3.defs.length !== allowedDeclarations.length || binding3.defs.some((definition) => !allowedDeclarations.includes(definition.node)) || binding3.eslintUsed || binding3.references.some((reference) => reference.isRead() || reference.init !== true))) return false;
|
|
1870
|
+
if (hasIdentifierNamed(sourceCode.ast, "eval")) return false;
|
|
1871
|
+
const statement = declaration.type === AST_NODE_TYPES18.VariableDeclarator ? declaration.parent : declaration;
|
|
1872
|
+
if (statement.parent.type === AST_NODE_TYPES18.ExportNamedDeclaration || statement.parent.type === AST_NODE_TYPES18.ExportDefaultDeclaration) return false;
|
|
1873
|
+
if (statement.parent.type !== AST_NODE_TYPES18.Program) return statement.parent.type === AST_NODE_TYPES18.BlockStatement;
|
|
1874
|
+
return sourceCode.ast.body.some((node) => node.type === AST_NODE_TYPES18.ImportDeclaration || node.type === AST_NODE_TYPES18.ExportNamedDeclaration || node.type === AST_NODE_TYPES18.ExportDefaultDeclaration || node.type === AST_NODE_TYPES18.ExportAllDeclaration);
|
|
1875
|
+
}
|
|
1876
|
+
function hasOnlyDirectFactoryUses(variable) {
|
|
1877
|
+
return variable.references.every((reference) => {
|
|
1878
|
+
if (reference.isTypeReference && !reference.isValueReference) return true;
|
|
1879
|
+
const identifier = reference.identifier;
|
|
1880
|
+
const parent = identifier.parent;
|
|
1881
|
+
if (parent.type === AST_NODE_TYPES18.CallExpression && parent.callee === identifier) return true;
|
|
1882
|
+
return parent.type === AST_NODE_TYPES18.MemberExpression && parent.object === identifier && !parent.computed && parent.parent.type === AST_NODE_TYPES18.CallExpression && parent.parent.callee === parent;
|
|
1883
|
+
});
|
|
1884
|
+
}
|
|
1885
|
+
var IDENTIFIER_NAMES = /* @__PURE__ */ new WeakMap();
|
|
1886
|
+
function hasIdentifierNamed(node, name) {
|
|
1887
|
+
let names = IDENTIFIER_NAMES.get(node);
|
|
1888
|
+
if (names === void 0) {
|
|
1889
|
+
const collected = /* @__PURE__ */ new Set();
|
|
1890
|
+
const pending = [node];
|
|
1891
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
1892
|
+
while (pending.length > 0) {
|
|
1893
|
+
const current = pending.pop();
|
|
1894
|
+
if (current === void 0 || seen.has(current)) continue;
|
|
1895
|
+
seen.add(current);
|
|
1896
|
+
if (current.type === AST_NODE_TYPES18.Identifier || current.type === AST_NODE_TYPES18.JSXIdentifier) collected.add(current.name);
|
|
1897
|
+
forEachOwnAstChild(current, (child) => {
|
|
1898
|
+
pending.push(child);
|
|
1899
|
+
}, (key) => key !== "tokens" && key !== "comments");
|
|
1900
|
+
}
|
|
1901
|
+
names = collected;
|
|
1902
|
+
IDENTIFIER_NAMES.set(node, names);
|
|
1903
|
+
}
|
|
1904
|
+
return names.has(name);
|
|
1905
|
+
}
|
|
1906
|
+
function privatePredicateBooleanFix(sourceCode, node, annotation, filename) {
|
|
1907
|
+
if (!annotation.typeAnnotation || !retainsNamedTypeUses(sourceCode, annotation.typeAnnotation) || node.type !== AST_NODE_TYPES18.FunctionDeclaration || node.id === null || !isUnusedPrivateBinding(sourceCode, node, node.id, filename) || sourceCode.getCommentsInside(annotation).length > 0) return null;
|
|
1908
|
+
const text = `boolean${sourceCode.getText(annotation).replace(/[^\r\n\u2028\u2029]/gu, "")}`;
|
|
1909
|
+
const neighbor = Math.max(0, annotation.range[0] - 1);
|
|
1910
|
+
const before = sourceCode.text.slice(neighbor, annotation.range[1] + 1).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
1911
|
+
const after = (sourceCode.text.slice(neighbor, annotation.range[0]) + text + sourceCode.text.slice(annotation.range[1], annotation.range[1] + 1)).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
1912
|
+
if (before.length !== after.length || before.some((ending, index) => ending !== after[index])) return null;
|
|
1913
|
+
return (fixer) => fixer.replaceText(annotation, text);
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
// src/rules/no-redundant-local-alias.ts
|
|
1767
1917
|
var NO_REDUNDANT_LOCAL_ALIAS_DOCUMENTATION = {
|
|
1768
1918
|
defaultLevel: "warning",
|
|
1769
1919
|
summary: "Pass the original local into an object field instead of creating a single-use rename.",
|
|
1770
1920
|
rationale: "An unannotated alias used only by its matching object field adds a second name without adding a contract.",
|
|
1771
1921
|
remediation: "Write the object property with the original binding, then remove the redundant alias. Keep annotations, captured snapshots and independently useful names.",
|
|
1772
1922
|
category: "maintainability",
|
|
1923
|
+
autofix: "safe",
|
|
1773
1924
|
limitations: [
|
|
1774
1925
|
"Checks an unannotated local const alias of a stable parameter or earlier const. Its single read must be a shorthand property in the same function scope. Module exports, imported bindings, captures, reassignment, positional uses and typed aliases are preserved.",
|
|
1775
|
-
"
|
|
1926
|
+
"Safe fixes are limited to a plain module-scope function with one explicitly intrinsic-primitive parameter and exactly a const alias followed by a returned object containing that sole shorthand field. The source binding must remain the same at the returned field. Generics, return annotations, optional/default parameters, destructuring, overloads, comments, eval, async/generator functions and the special __proto__ key remain manual. Other diagnostics require review."
|
|
1776
1927
|
],
|
|
1777
1928
|
examples: [
|
|
1778
1929
|
{ id: "redundant-alias", title: "The property already supplies the name", outcome: "match", files: [{ path: "src/request.ts", source: "function request(value: string) { const accountId = value; return { accountId }; }" }], focusPath: "src/request.ts", expectedCount: 1, public: true },
|
|
1779
|
-
{ id: "direct-property", title: "Use the original binding", outcome: "no-match", files: [{ path: "src/request.ts", source: "function request(value: string) { return { accountId: value }; }" }], focusPath: "src/request.ts", expectedCount: 0, public: true }
|
|
1930
|
+
{ id: "direct-property", title: "Use the original binding", outcome: "no-match", files: [{ path: "src/request.ts", source: "function request(value: string) { return { accountId: value }; }" }], focusPath: "src/request.ts", expectedCount: 0, public: true },
|
|
1931
|
+
{ id: "closed-primitive-parameter-alias", scenarioId: "closed-primitive-parameter-alias", title: "The closed primitive return preserves the data-field contract", outcome: "match", files: [{ path: "src/request.ts", source: "export {};\nfunction request(value: string) {\n const accountId = value;\n return { accountId };\n}\n" }], fixedFiles: [{ path: "src/request.ts", source: "export {};\nfunction request(value: string) {\n\n return { accountId: value };\n}\n" }], focusPath: "src/request.ts", expectedCount: 1, public: true },
|
|
1932
|
+
{ id: "closed-primitive-parameter-alias-fixed", scenarioId: "closed-primitive-parameter-alias", title: "The direct data field needs no local alias", outcome: "no-match", files: [{ path: "src/request.ts", source: "export {};\nfunction request(value: string) {\n\n return { accountId: value };\n}\n" }], focusPath: "src/request.ts", expectedCount: 0, public: true }
|
|
1780
1933
|
]
|
|
1781
1934
|
};
|
|
1782
1935
|
function stableSource(variable, alias) {
|
|
1783
1936
|
const definition = variable.defs[0];
|
|
1784
1937
|
if (variable.defs.length !== 1 || definition === void 0 || variable.references.some((reference) => reference.isWrite() && !reference.init)) return false;
|
|
1785
|
-
return definition.type === "Parameter" || definition.node.type ===
|
|
1938
|
+
return definition.type === "Parameter" || definition.node.type === AST_NODE_TYPES19.VariableDeclarator && definition.node.parent.kind === "const" && definition.node.init !== null && definition.node.range[1] < alias.range[0];
|
|
1939
|
+
}
|
|
1940
|
+
var PRIMITIVE_PARAMETERS = /* @__PURE__ */ new Set([
|
|
1941
|
+
AST_NODE_TYPES19.TSStringKeyword,
|
|
1942
|
+
AST_NODE_TYPES19.TSNumberKeyword,
|
|
1943
|
+
AST_NODE_TYPES19.TSBooleanKeyword,
|
|
1944
|
+
AST_NODE_TYPES19.TSBigIntKeyword,
|
|
1945
|
+
AST_NODE_TYPES19.TSSymbolKeyword
|
|
1946
|
+
]);
|
|
1947
|
+
function closedPrimitiveReturnFix(sourceCode, node, property, source, target) {
|
|
1948
|
+
const statement = node.parent;
|
|
1949
|
+
const body3 = statement.parent;
|
|
1950
|
+
if (body3.type !== AST_NODE_TYPES19.BlockStatement) return null;
|
|
1951
|
+
const owner = body3.parent;
|
|
1952
|
+
if (owner.type !== AST_NODE_TYPES19.FunctionDeclaration || owner.parent.type !== AST_NODE_TYPES19.Program || owner.id === null || owner.async || owner.generator || owner.typeParameters !== void 0 || owner.returnType !== void 0 || owner.params.length !== 1 || body3.body.length !== 2 || body3.body[0] !== statement || node.id.type !== AST_NODE_TYPES19.Identifier || node.id.name === "__proto__" || node.init?.type !== AST_NODE_TYPES19.Identifier || sourceCode.getCommentsInside(owner).length !== 0 || hasIdentifierNamed(sourceCode.ast, "eval")) return null;
|
|
1953
|
+
const parameter = owner.params[0];
|
|
1954
|
+
const returned2 = body3.body[1];
|
|
1955
|
+
if (parameter?.type !== AST_NODE_TYPES19.Identifier || parameter.optional === true || parameter.typeAnnotation === void 0 || !PRIMITIVE_PARAMETERS.has(parameter.typeAnnotation.typeAnnotation.type) || returned2?.type !== AST_NODE_TYPES19.ReturnStatement || returned2.argument !== property.parent || property.parent.type !== AST_NODE_TYPES19.ObjectExpression || property.parent.properties.length !== 1 || ASTUtils15.findVariable(sourceCode.getScope(parameter), parameter.name) !== source || ASTUtils15.findVariable(sourceCode.getScope(property), node.init.name) !== source || source.references.some((reference) => reference.isTypeReference) || target.references.some((reference) => reference.isTypeReference)) return null;
|
|
1956
|
+
const name = owner.id.name;
|
|
1957
|
+
const bindings = sourceCode.getDeclaredVariables(owner).filter((binding3) => binding3.name === name);
|
|
1958
|
+
if (bindings.length !== 1 || bindings[0]?.defs.length !== 1 || bindings[0].defs[0]?.node !== owner || bindings[0].references.some((reference) => reference.isTypeReference)) return null;
|
|
1959
|
+
const span = [body3.range[0] + 1, statement.range[1]];
|
|
1960
|
+
const boundaries = sourceCode.text.slice(...span).replace(/[^\r\n\u2028\u2029]/gu, "");
|
|
1961
|
+
const neighbor = Math.max(0, span[0] - 1);
|
|
1962
|
+
const before = sourceCode.text.slice(neighbor, span[1] + 1).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
1963
|
+
const after = (sourceCode.text.slice(neighbor, span[0]) + boundaries + sourceCode.text.slice(span[1], span[1] + 1)).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
1964
|
+
if (before.length !== after.length || before.some((ending, index) => ending !== after[index])) return null;
|
|
1965
|
+
const key = sourceCode.getText(property.key);
|
|
1966
|
+
const value = sourceCode.getText(node.init);
|
|
1967
|
+
return (fixer) => [fixer.replaceTextRange(span, boundaries), fixer.replaceText(property, `${key}: ${value}`)];
|
|
1786
1968
|
}
|
|
1787
1969
|
var no_redundant_local_alias_default = createRule({
|
|
1788
1970
|
name: "no-redundant-local-alias",
|
|
1789
1971
|
documentation: NO_REDUNDANT_LOCAL_ALIAS_DOCUMENTATION,
|
|
1790
1972
|
meta: {
|
|
1791
1973
|
type: "suggestion",
|
|
1974
|
+
fixable: "code",
|
|
1792
1975
|
docs: { description: NO_REDUNDANT_LOCAL_ALIAS_DOCUMENTATION.summary },
|
|
1793
1976
|
schema: [],
|
|
1794
1977
|
messages: { redundantAlias: "This alias is read only by its matching object field; pass `{{source}}` directly as `{{target}}: {{source}}`." }
|
|
@@ -1796,9 +1979,10 @@ var no_redundant_local_alias_default = createRule({
|
|
|
1796
1979
|
defaultOptions: [],
|
|
1797
1980
|
create(context) {
|
|
1798
1981
|
if (isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
1982
|
+
const hasModuleSyntax = context.sourceCode.ast.body.some((candidate2) => candidate2.type === AST_NODE_TYPES19.ImportDeclaration || candidate2.type === AST_NODE_TYPES19.ExportNamedDeclaration || candidate2.type === AST_NODE_TYPES19.ExportDefaultDeclaration || candidate2.type === AST_NODE_TYPES19.ExportAllDeclaration);
|
|
1799
1983
|
return {
|
|
1800
1984
|
VariableDeclarator(node) {
|
|
1801
|
-
if (node.parent.kind !== "const" || node.parent.declarations.length !== 1 || node.id.type !==
|
|
1985
|
+
if (node.parent.kind !== "const" || node.parent.declarations.length !== 1 || node.id.type !== AST_NODE_TYPES19.Identifier || node.id.typeAnnotation !== void 0 || node.init?.type !== AST_NODE_TYPES19.Identifier) return;
|
|
1802
1986
|
const scope = context.sourceCode.getScope(node);
|
|
1803
1987
|
if (scope.variableScope.type !== "function") return;
|
|
1804
1988
|
const target = ASTUtils15.findVariable(scope, node.id.name);
|
|
@@ -1809,18 +1993,18 @@ var no_redundant_local_alias_default = createRule({
|
|
|
1809
1993
|
const read = reads[0];
|
|
1810
1994
|
if (read === void 0 || read.from.variableScope !== scope.variableScope) return;
|
|
1811
1995
|
const property = read.identifier.parent;
|
|
1812
|
-
if (property.type !==
|
|
1813
|
-
context.report({ node, messageId: "redundantAlias", data: { source: node.init.name, target: node.id.name } });
|
|
1996
|
+
if (property.type !== AST_NODE_TYPES19.Property || !property.shorthand || property.value !== read.identifier || property.parent.type !== AST_NODE_TYPES19.ObjectExpression || property.computed || property.method || property.kind !== "init") return;
|
|
1997
|
+
context.report({ node, messageId: "redundantAlias", fix: hasModuleSyntax ? closedPrimitiveReturnFix(context.sourceCode, node, property, source, target) : null, data: { source: node.init.name, target: node.id.name } });
|
|
1814
1998
|
}
|
|
1815
1999
|
};
|
|
1816
2000
|
}
|
|
1817
2001
|
});
|
|
1818
2002
|
|
|
1819
2003
|
// src/rules/no-test-comments.ts
|
|
1820
|
-
import { AST_NODE_TYPES as
|
|
2004
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES21 } from "@typescript-eslint/utils";
|
|
1821
2005
|
|
|
1822
2006
|
// src/rules/_comments.ts
|
|
1823
|
-
import { AST_NODE_TYPES as
|
|
2007
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES20 } from "@typescript-eslint/utils";
|
|
1824
2008
|
var REF_RE = /https?:\/\/|\bRFC[- ]?\d+|\bPEP[- ]?\d+|\bCVE-\d{4}|\b(?!UTF-|SHA-|ISO-|AES-|CRC-|MD-|PCM-|EOF-|API-|BASE-)[A-Z][A-Z0-9]{1,9}-\d[A-Z0-9]{0,5}\b|(?<![&\w])#\d{2,6}\b|@[a-z][\w.-]*\.(?:us|com|ai|io|net|org|dev)\b/;
|
|
1825
2009
|
var VERSION_RE = /(?:>=|<=|==|<|>)\s*v?\d+\.\d+|\bv\d+\.\d+|\b(?:since|until|as of)\s+(?:v?\d+\.\d+|Python\s*\d)/i;
|
|
1826
2010
|
var UNITS_RE = /[~<>]?\d+(?:\.\d+)?\s?(?:ms|s\b|sec\b|seconds?\b|min\b|minutes?\b|hours?\b|days?\b|KB|MB|MiB|GiB|kHz|Hz|bytes?\b|bit\b|-bit\b|%|px\b|rps\b|qps\b)|\b[1-5]xx\b|\b(?:301|302|304|307|308|400|401|403|404|405|409|410|412|422|425|429|500|501|502|503|504)\b/;
|
|
@@ -1906,10 +2090,10 @@ var NARRATION_MAX_WORDS = 6;
|
|
|
1906
2090
|
var NARRATION_MIN_CONTENT = 1;
|
|
1907
2091
|
var TOKEN_PLURAL_MIN = 4;
|
|
1908
2092
|
var RESTATABLE_STATEMENTS = /* @__PURE__ */ new Set([
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
2093
|
+
AST_NODE_TYPES20.ExpressionStatement,
|
|
2094
|
+
AST_NODE_TYPES20.ReturnStatement,
|
|
2095
|
+
AST_NODE_TYPES20.ThrowStatement,
|
|
2096
|
+
AST_NODE_TYPES20.VariableDeclaration
|
|
1913
2097
|
]);
|
|
1914
2098
|
var NARRATION_VERB_RE = /^(?:add|append|assign|build|calculate|call|check|clear|close|compute|convert|copy|count|create|declare|decrement|define|delete|extract|fetch|filter|find|format|generate|get|handle|increment|init|initialise|initialize|insert|iterate|join|load|log|loop|make|map|merge|open|parse|print|process|push|read|remove|render|reset|return|save|send|set|setup|sort|split|start|stop|store|update|validate|wrap|write)(?:s|es|d|ed|ing)?$/i;
|
|
1915
2099
|
var NARRATION_STOPWORDS = /* @__PURE__ */ new Set([
|
|
@@ -1968,12 +2152,12 @@ function restatableStatementBelow(comment, sourceCode) {
|
|
|
1968
2152
|
function restatableStatementNodeBelow(comment, sourceCode) {
|
|
1969
2153
|
const token = sourceCode.getTokenAfter(comment, { includeComments: false });
|
|
1970
2154
|
if (token === null || token.loc.start.line !== comment.loc.end.line + 1) return null;
|
|
1971
|
-
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !==
|
|
2155
|
+
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== AST_NODE_TYPES20.Program; node = node.parent) {
|
|
1972
2156
|
if (!RESTATABLE_STATEMENTS.has(node.type)) continue;
|
|
1973
2157
|
if (node.loc.start.line !== token.loc.start.line || node.loc.end.line !== node.loc.start.line) {
|
|
1974
2158
|
return null;
|
|
1975
2159
|
}
|
|
1976
|
-
if (node.type ===
|
|
2160
|
+
if (node.type === AST_NODE_TYPES20.VariableDeclaration && isTrivialInitializer(node)) {
|
|
1977
2161
|
return null;
|
|
1978
2162
|
}
|
|
1979
2163
|
return node;
|
|
@@ -1983,8 +2167,8 @@ function restatableStatementNodeBelow(comment, sourceCode) {
|
|
|
1983
2167
|
function isTrivialInitializer(node) {
|
|
1984
2168
|
return node.declarations.every((declarator) => {
|
|
1985
2169
|
const init = declarator.init;
|
|
1986
|
-
if (init == null || init.type ===
|
|
1987
|
-
return init.type ===
|
|
2170
|
+
if (init == null || init.type === AST_NODE_TYPES20.Literal) return true;
|
|
2171
|
+
return init.type === AST_NODE_TYPES20.ArrayExpression && init.elements.length === 0 || init.type === AST_NODE_TYPES20.ObjectExpression && init.properties.length === 0;
|
|
1988
2172
|
});
|
|
1989
2173
|
}
|
|
1990
2174
|
function restatesStatementHead(body3, statement) {
|
|
@@ -2045,7 +2229,11 @@ function trailingCommentRemovalRange(text, comment) {
|
|
|
2045
2229
|
return { range: [start, contentEnd] };
|
|
2046
2230
|
}
|
|
2047
2231
|
function commentLineEndings(text, removal) {
|
|
2048
|
-
|
|
2232
|
+
const replacement = text.slice(...removal.range).replace(/[^\r\n\u2028\u2029]/gu, "");
|
|
2233
|
+
const neighbor = Math.max(0, removal.range[0] - 1);
|
|
2234
|
+
const original = text.slice(neighbor, removal.range[1] + 1).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
2235
|
+
const rendered = (text.slice(neighbor, removal.range[0]) + replacement + text.slice(removal.range[1], removal.range[1] + 1)).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
2236
|
+
return original.length === rendered.length && original.every((ending, index) => ending === rendered[index]) ? replacement : null;
|
|
2049
2237
|
}
|
|
2050
2238
|
function exactMemberCommentRemovalRange(text, comment, key) {
|
|
2051
2239
|
if (key.type !== "Identifier") return null;
|
|
@@ -2075,6 +2263,7 @@ var NO_TEST_COMMENTS_DOCUMENTATION = {
|
|
|
2075
2263
|
]
|
|
2076
2264
|
};
|
|
2077
2265
|
var DIRECTIVE = /^(?:eslint(?:-\S+)?\b|(?:biome|oxlint|jshint|jslint|c8|v8|istanbul|vitest|prettier|dprint)\b|@(?:ts-(?:check|nocheck|expect-error|ignore)|vitest-environment|jest-environment|jsx\w*|license|preserve)\b|[#!]\s*__(?:PURE|NO_SIDE_EFFECTS)__|\/\s*<(?:reference|amd-module|amd-dependency)\b)/u;
|
|
2266
|
+
var BEHAVIORAL_DIRECTIVE = /(?:[@#]__(?:PURE|NO_SIDE_EFFECTS)__|@vite-ignore\b|\bwebpack(?:ChunkName|Mode|Exports|FetchPriority|Include|Exclude|Prefetch|Preload|Ignore)\s*:)/u;
|
|
2078
2267
|
var LEGAL = /(?:^|\n)\s*\*?\s*(?:Copyright\b|SPDX-License-Identifier:|Licensed under\b|@license\b|@preserve\b)/iu;
|
|
2079
2268
|
var TYPE_CONTRACT = /@(?:type|typedef|template|param|returns?|satisfies|callback|overload|implements|extends|augments|enum|this|import)\b/u;
|
|
2080
2269
|
var DETECT_SECRETS_COMMENT_MARKERS = [
|
|
@@ -2094,12 +2283,13 @@ var PYTHON_EXTRA_WHITESPACE = /* @__PURE__ */ new Set(["", "", "", ""]);
|
|
|
2094
2283
|
function hasDetectSecretsPragma(comment, text) {
|
|
2095
2284
|
if (!comment.value.includes("pragma:")) return false;
|
|
2096
2285
|
let lineStart = Math.max(text.lastIndexOf("\r", comment.range[0] - 1), text.lastIndexOf("\n", comment.range[0] - 1)) + 1;
|
|
2286
|
+
const readerLineEndings = /\r\n?|\n/gu;
|
|
2287
|
+
readerLineEndings.lastIndex = lineStart;
|
|
2097
2288
|
while (lineStart < comment.range[1]) {
|
|
2098
|
-
const
|
|
2099
|
-
const
|
|
2100
|
-
const lineEnd = Math.min(nextCr < 0 ? text.length : nextCr, nextLf < 0 ? text.length : nextLf);
|
|
2289
|
+
const ending = readerLineEndings.exec(text);
|
|
2290
|
+
const lineEnd = ending?.index ?? text.length;
|
|
2101
2291
|
if (hasPragmaInReaderLine(comment, text.slice(lineStart, lineEnd), lineStart)) return true;
|
|
2102
|
-
lineStart = lineEnd + (
|
|
2292
|
+
lineStart = lineEnd + (ending?.[0].length ?? 1);
|
|
2103
2293
|
}
|
|
2104
2294
|
return false;
|
|
2105
2295
|
}
|
|
@@ -2138,7 +2328,7 @@ var no_test_comments_default = createRule({
|
|
|
2138
2328
|
if (!isTestFile(context) || isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
2139
2329
|
const filename = scopedFilename(context);
|
|
2140
2330
|
const unambiguous = /(?:^|\/)(?:tests?|__tests__|fixtures|__fixtures__|__mocks__)\//u.test(filename) || /\.(?:test|spec|e2e|integration)\.[cm]?[jt]sx?$/u.test(filename);
|
|
2141
|
-
const framework = context.sourceCode.ast.body.some((statement) => statement.type ===
|
|
2331
|
+
const framework = context.sourceCode.ast.body.some((statement) => statement.type === AST_NODE_TYPES21.ImportDeclaration && statement.importKind !== "type" && (statement.specifiers.length === 0 || statement.specifiers.some((specifier) => specifier.type !== AST_NODE_TYPES21.ImportSpecifier || specifier.importKind !== "type")) && ["vitest", "@jest/globals", "@playwright/test", "bun:test", "node:test"].includes(statement.source.value));
|
|
2142
2332
|
if (!unambiguous && !framework) return {};
|
|
2143
2333
|
return {
|
|
2144
2334
|
Program() {
|
|
@@ -2159,26 +2349,35 @@ var no_test_comments_default = createRule({
|
|
|
2159
2349
|
}
|
|
2160
2350
|
for (const [index, comment] of comments.entries()) {
|
|
2161
2351
|
const body3 = comment.value.trim().replace(/^\*\s*/u, "");
|
|
2162
|
-
if (DIRECTIVE.test(body3) || LEGAL.test(comment.value) || legalLines.has(index) || TYPE_CONTRACT.test(comment.value) || hasDetectSecretsPragma(comment, context.sourceCode.text)) continue;
|
|
2352
|
+
if (DIRECTIVE.test(body3) || BEHAVIORAL_DIRECTIVE.test(comment.value) || LEGAL.test(comment.value) || legalLines.has(index) || TYPE_CONTRACT.test(comment.value) || hasDetectSecretsPragma(comment, context.sourceCode.text)) continue;
|
|
2163
2353
|
context.report({
|
|
2164
2354
|
node: comment,
|
|
2165
2355
|
messageId: "testComment",
|
|
2166
2356
|
fix: (fixer) => {
|
|
2167
2357
|
const text = context.sourceCode.text;
|
|
2358
|
+
const preserveLineTerminators = (edit) => {
|
|
2359
|
+
const neighbor = Math.max(0, edit.range[0] - 1);
|
|
2360
|
+
const original = text.slice(neighbor, edit.range[1] + 1).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
2361
|
+
const rendered = (text.slice(neighbor, edit.range[0]) + edit.text + text.slice(edit.range[1], edit.range[1] + 1)).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
2362
|
+
return original.length === rendered.length && original.every((ending, position) => ending === rendered[position]) ? edit : null;
|
|
2363
|
+
};
|
|
2168
2364
|
const own = ownLineCommentRemovalRange(text, comment);
|
|
2169
|
-
if (own !== null)
|
|
2365
|
+
if (own !== null) {
|
|
2366
|
+
const ownEndings = commentLineEndings(text, own);
|
|
2367
|
+
return ownEndings === null ? null : preserveLineTerminators(fixer.replaceTextRange(own.range, ownEndings));
|
|
2368
|
+
}
|
|
2170
2369
|
const trailing = trailingCommentRemovalRange(text, comment);
|
|
2171
|
-
if (trailing !== null) return fixer.replaceTextRange(trailing.range, "");
|
|
2370
|
+
if (trailing !== null) return preserveLineTerminators(fixer.replaceTextRange(trailing.range, ""));
|
|
2172
2371
|
const endings = context.sourceCode.getText(comment).replace(/[^\r\n\u2028\u2029]/gu, "");
|
|
2173
2372
|
if (endings.length > 0) {
|
|
2174
2373
|
let start = comment.range[0];
|
|
2175
2374
|
while (start > 0 && /[\t ]/u.test(text[start - 1] ?? "")) start--;
|
|
2176
|
-
return fixer.replaceTextRange([start, comment.range[1]], endings);
|
|
2375
|
+
return preserveLineTerminators(fixer.replaceTextRange([start, comment.range[1]], endings));
|
|
2177
2376
|
}
|
|
2178
2377
|
const before = text[comment.range[0] - 1] ?? "";
|
|
2179
2378
|
const after = text[comment.range[1]] ?? "";
|
|
2180
2379
|
const separator = before.length > 0 && after.length > 0 && !/\s/u.test(before + after) ? " " : "";
|
|
2181
|
-
return fixer.replaceText(comment, separator);
|
|
2380
|
+
return preserveLineTerminators(fixer.replaceText(comment, separator));
|
|
2182
2381
|
}
|
|
2183
2382
|
});
|
|
2184
2383
|
}
|
|
@@ -2188,14 +2387,14 @@ var no_test_comments_default = createRule({
|
|
|
2188
2387
|
});
|
|
2189
2388
|
|
|
2190
2389
|
// src/rules/no-mutating-container-transform.ts
|
|
2191
|
-
import { AST_NODE_TYPES as
|
|
2390
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES22, ASTUtils as ASTUtils16 } from "@typescript-eslint/utils";
|
|
2192
2391
|
var MUTATORS = /* @__PURE__ */ new Set(["copyWithin", "fill", "pop", "push", "reverse", "shift", "sort", "splice", "unshift"]);
|
|
2193
2392
|
var PRIMITIVES = /* @__PURE__ */ new Set([
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2393
|
+
AST_NODE_TYPES22.TSStringKeyword,
|
|
2394
|
+
AST_NODE_TYPES22.TSNumberKeyword,
|
|
2395
|
+
AST_NODE_TYPES22.TSBooleanKeyword,
|
|
2396
|
+
AST_NODE_TYPES22.TSBigIntKeyword,
|
|
2397
|
+
AST_NODE_TYPES22.TSSymbolKeyword
|
|
2199
2398
|
]);
|
|
2200
2399
|
var NO_MUTATING_CONTAINER_TRANSFORM_DOCUMENTATION = {
|
|
2201
2400
|
defaultLevel: "warning",
|
|
@@ -2214,27 +2413,27 @@ var NO_MUTATING_CONTAINER_TRANSFORM_DOCUMENTATION = {
|
|
|
2214
2413
|
]
|
|
2215
2414
|
};
|
|
2216
2415
|
function arrayElement(node, sourceCode) {
|
|
2217
|
-
if (node.type ===
|
|
2218
|
-
if (node.type ===
|
|
2416
|
+
if (node.type === AST_NODE_TYPES22.TSArrayType) return node.elementType;
|
|
2417
|
+
if (node.type === AST_NODE_TYPES22.TSTypeReference && node.typeName.type === AST_NODE_TYPES22.Identifier && (node.typeName.name === "Array" || node.typeName.name === "ReadonlyArray") && (ASTUtils16.findVariable(sourceCode.getScope(node.typeName), node.typeName.name)?.defs.length ?? 0) === 0 && node.typeArguments?.params.length === 1) return node.typeArguments.params[0] ?? null;
|
|
2219
2418
|
return null;
|
|
2220
2419
|
}
|
|
2221
2420
|
function returnsArray(node, sourceCode) {
|
|
2222
2421
|
let annotation = node.returnType?.typeAnnotation;
|
|
2223
|
-
if (annotation?.type ===
|
|
2422
|
+
if (annotation?.type === AST_NODE_TYPES22.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES22.Identifier && annotation.typeName.name === "Promise" && (ASTUtils16.findVariable(sourceCode.getScope(annotation.typeName), "Promise")?.defs.length ?? 0) === 0 && annotation.typeArguments?.params.length === 1) annotation = annotation.typeArguments.params[0];
|
|
2224
2423
|
return annotation !== void 0 && arrayElement(annotation, sourceCode) !== null;
|
|
2225
2424
|
}
|
|
2226
2425
|
function supported(statements) {
|
|
2227
2426
|
return statements.every((statement) => {
|
|
2228
2427
|
switch (statement.type) {
|
|
2229
|
-
case
|
|
2230
|
-
case
|
|
2231
|
-
case
|
|
2232
|
-
case
|
|
2233
|
-
case
|
|
2428
|
+
case AST_NODE_TYPES22.ExpressionStatement:
|
|
2429
|
+
case AST_NODE_TYPES22.VariableDeclaration:
|
|
2430
|
+
case AST_NODE_TYPES22.ReturnStatement:
|
|
2431
|
+
case AST_NODE_TYPES22.ThrowStatement:
|
|
2432
|
+
case AST_NODE_TYPES22.EmptyStatement:
|
|
2234
2433
|
return true;
|
|
2235
|
-
case
|
|
2434
|
+
case AST_NODE_TYPES22.BlockStatement:
|
|
2236
2435
|
return supported(statement.body);
|
|
2237
|
-
case
|
|
2436
|
+
case AST_NODE_TYPES22.IfStatement:
|
|
2238
2437
|
return supported([statement.consequent]) && (statement.alternate === null || supported([statement.alternate]));
|
|
2239
2438
|
default:
|
|
2240
2439
|
return false;
|
|
@@ -2255,13 +2454,13 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2255
2454
|
if (isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
2256
2455
|
const sourceCode = context.sourceCode;
|
|
2257
2456
|
function binding3(node) {
|
|
2258
|
-
return node.type ===
|
|
2457
|
+
return node.type === AST_NODE_TYPES22.Identifier ? ASTUtils16.findVariable(sourceCode.getScope(node), node.name) : null;
|
|
2259
2458
|
}
|
|
2260
2459
|
function inspect(node) {
|
|
2261
|
-
if (node.body?.type !==
|
|
2460
|
+
if (node.body?.type !== AST_NODE_TYPES22.BlockStatement || !returnsArray(node, sourceCode) || !supported(node.body.body)) return;
|
|
2262
2461
|
const initial = /* @__PURE__ */ new Map();
|
|
2263
2462
|
for (const parameter of node.params) {
|
|
2264
|
-
if (parameter.type !==
|
|
2463
|
+
if (parameter.type !== AST_NODE_TYPES22.Identifier || parameter.typeAnnotation === void 0) continue;
|
|
2265
2464
|
const element = arrayElement(parameter.typeAnnotation.typeAnnotation, sourceCode);
|
|
2266
2465
|
const variable = binding3(parameter);
|
|
2267
2466
|
if (element !== null && PRIMITIVES.has(element.type) && variable !== null) initial.set(variable, parameter.name);
|
|
@@ -2274,26 +2473,26 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2274
2473
|
}
|
|
2275
2474
|
function expression(current, state) {
|
|
2276
2475
|
switch (current.type) {
|
|
2277
|
-
case
|
|
2278
|
-
case
|
|
2279
|
-
case
|
|
2476
|
+
case AST_NODE_TYPES22.FunctionExpression:
|
|
2477
|
+
case AST_NODE_TYPES22.ArrowFunctionExpression:
|
|
2478
|
+
case AST_NODE_TYPES22.ClassExpression:
|
|
2280
2479
|
return;
|
|
2281
|
-
case
|
|
2480
|
+
case AST_NODE_TYPES22.AssignmentExpression:
|
|
2282
2481
|
assignment(current, state);
|
|
2283
2482
|
return;
|
|
2284
|
-
case
|
|
2483
|
+
case AST_NODE_TYPES22.LogicalExpression:
|
|
2285
2484
|
logical(current, state);
|
|
2286
2485
|
return;
|
|
2287
|
-
case
|
|
2486
|
+
case AST_NODE_TYPES22.ConditionalExpression:
|
|
2288
2487
|
conditional(current, state);
|
|
2289
2488
|
return;
|
|
2290
|
-
case
|
|
2489
|
+
case AST_NODE_TYPES22.UpdateExpression:
|
|
2291
2490
|
write(current.argument, state);
|
|
2292
2491
|
break;
|
|
2293
|
-
case
|
|
2492
|
+
case AST_NODE_TYPES22.UnaryExpression:
|
|
2294
2493
|
if (current.operator === "delete") write(current.argument, state);
|
|
2295
2494
|
break;
|
|
2296
|
-
case
|
|
2495
|
+
case AST_NODE_TYPES22.CallExpression:
|
|
2297
2496
|
mutationCall(current, state);
|
|
2298
2497
|
break;
|
|
2299
2498
|
default:
|
|
@@ -2313,13 +2512,13 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2313
2512
|
function logical(current, state) {
|
|
2314
2513
|
expression(current.left, state);
|
|
2315
2514
|
const left = unwrapExpression(current.left);
|
|
2316
|
-
if (left.type ===
|
|
2515
|
+
if (left.type === AST_NODE_TYPES22.Literal && (current.operator === "&&" && !left.value || current.operator === "||" && !!left.value || current.operator === "??" && left.value !== null)) return;
|
|
2317
2516
|
expression(current.right, state);
|
|
2318
2517
|
}
|
|
2319
2518
|
function conditional(current, state) {
|
|
2320
2519
|
expression(current.test, state);
|
|
2321
2520
|
const test = unwrapExpression(current.test);
|
|
2322
|
-
if (test.type ===
|
|
2521
|
+
if (test.type === AST_NODE_TYPES22.Literal) {
|
|
2323
2522
|
expression(test.value ? current.consequent : current.alternate, state);
|
|
2324
2523
|
return;
|
|
2325
2524
|
}
|
|
@@ -2327,13 +2526,13 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2327
2526
|
expression(current.alternate, state);
|
|
2328
2527
|
}
|
|
2329
2528
|
function mutationCall(current, state) {
|
|
2330
|
-
if (current.callee.type !==
|
|
2529
|
+
if (current.callee.type !== AST_NODE_TYPES22.MemberExpression || !MUTATORS.has(ASTUtils16.getPropertyName(current.callee) ?? "")) return;
|
|
2331
2530
|
const parameter = origin(current.callee.object, state);
|
|
2332
2531
|
if (parameter !== void 0 && first === null) first = { node: current, parameter };
|
|
2333
2532
|
}
|
|
2334
2533
|
function write(target, state) {
|
|
2335
2534
|
target = unwrapExpression(target);
|
|
2336
|
-
if (target.type !==
|
|
2535
|
+
if (target.type !== AST_NODE_TYPES22.MemberExpression || !target.computed && ASTUtils16.getPropertyName(target) !== "length") return;
|
|
2337
2536
|
const parameter = origin(target.object, state);
|
|
2338
2537
|
if (parameter !== void 0 && first === null) first = { node: target, parameter };
|
|
2339
2538
|
}
|
|
@@ -2343,18 +2542,18 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2343
2542
|
}
|
|
2344
2543
|
function statement(current, state) {
|
|
2345
2544
|
switch (current.type) {
|
|
2346
|
-
case
|
|
2545
|
+
case AST_NODE_TYPES22.BlockStatement:
|
|
2347
2546
|
return statements(current.body, state);
|
|
2348
|
-
case
|
|
2547
|
+
case AST_NODE_TYPES22.IfStatement:
|
|
2349
2548
|
return branch(current, state);
|
|
2350
|
-
case
|
|
2549
|
+
case AST_NODE_TYPES22.VariableDeclaration:
|
|
2351
2550
|
declarations(current, state);
|
|
2352
2551
|
return false;
|
|
2353
|
-
case
|
|
2354
|
-
case
|
|
2552
|
+
case AST_NODE_TYPES22.ReturnStatement:
|
|
2553
|
+
case AST_NODE_TYPES22.ThrowStatement:
|
|
2355
2554
|
if (current.argument !== null) expression(current.argument, state);
|
|
2356
2555
|
return true;
|
|
2357
|
-
case
|
|
2556
|
+
case AST_NODE_TYPES22.ExpressionStatement:
|
|
2358
2557
|
expression(current.expression, state);
|
|
2359
2558
|
return false;
|
|
2360
2559
|
default:
|
|
@@ -2363,7 +2562,7 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2363
2562
|
}
|
|
2364
2563
|
function branch(current, state) {
|
|
2365
2564
|
expression(current.test, state);
|
|
2366
|
-
if (current.test.type ===
|
|
2565
|
+
if (current.test.type === AST_NODE_TYPES22.Literal) return current.test.value ? statements([current.consequent], state) : current.alternate !== null && statements([current.alternate], state);
|
|
2367
2566
|
const left = new Map(state);
|
|
2368
2567
|
const right = new Map(state);
|
|
2369
2568
|
const leftEnds = statements([current.consequent], left);
|
|
@@ -2395,7 +2594,7 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2395
2594
|
});
|
|
2396
2595
|
|
|
2397
2596
|
// src/rules/no-redundant-consumer-union.ts
|
|
2398
|
-
import { AST_NODE_TYPES as
|
|
2597
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES25, ESLintUtils as ESLintUtils2 } from "@typescript-eslint/utils";
|
|
2399
2598
|
import ts7 from "typescript";
|
|
2400
2599
|
|
|
2401
2600
|
// src/rules/_checked-native-source.ts
|
|
@@ -2506,109 +2705,13 @@ function finiteMember(member3, checker) {
|
|
|
2506
2705
|
}
|
|
2507
2706
|
|
|
2508
2707
|
// src/rules/_private-consumer-fix.ts
|
|
2509
|
-
import { AST_NODE_TYPES as
|
|
2708
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES23 } from "@typescript-eslint/utils";
|
|
2510
2709
|
import ts3 from "typescript";
|
|
2511
|
-
|
|
2512
|
-
// src/rules/_type-binding.ts
|
|
2513
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES21 } from "@typescript-eslint/utils";
|
|
2514
|
-
function typeBinding(source, identifier) {
|
|
2515
|
-
let scope = source.getScope(identifier);
|
|
2516
|
-
while (scope !== null) {
|
|
2517
|
-
const variable = scope.set.get(identifier.name);
|
|
2518
|
-
if (variable !== void 0 && (variable.isTypeVariable || variable.defs.some((definition) => definition.isTypeDefinition))) {
|
|
2519
|
-
return variable;
|
|
2520
|
-
}
|
|
2521
|
-
scope = scope.upper;
|
|
2522
|
-
}
|
|
2523
|
-
return null;
|
|
2524
|
-
}
|
|
2525
|
-
var REFERENCE_INDEXES = /* @__PURE__ */ new WeakMap();
|
|
2526
|
-
function retainsNamedTypeUses(source, removed) {
|
|
2527
|
-
const manager = source.scopeManager;
|
|
2528
|
-
if (manager === null) return false;
|
|
2529
|
-
const index = referenceIndex(source, manager);
|
|
2530
|
-
for (const reference of referencesWithin(index.references, removed)) {
|
|
2531
|
-
if (!reference.isRead()) continue;
|
|
2532
|
-
const binding3 = reference.resolved;
|
|
2533
|
-
if (!binding3 || !reference.isTypeReference && !reference.isValueReference) return false;
|
|
2534
|
-
if (binding3.defs.length === 0) continue;
|
|
2535
|
-
const reads = publicReadExtents(index, binding3);
|
|
2536
|
-
const extent = reference.isTypeReference ? reference.isValueReference ? reads.both : reads.type : reads.value;
|
|
2537
|
-
if (extent === null || extent.minStart >= removed.range[0] && extent.maxEnd <= removed.range[1]) return false;
|
|
2538
|
-
}
|
|
2539
|
-
return true;
|
|
2540
|
-
}
|
|
2541
|
-
function referenceIndex(source, manager) {
|
|
2542
|
-
const cached = REFERENCE_INDEXES.get(source);
|
|
2543
|
-
if (cached?.manager === manager) return cached;
|
|
2544
|
-
const references = manager.scopes.flatMap((scope) => scope.references);
|
|
2545
|
-
references.sort((left, right) => left.identifier.range[0] - right.identifier.range[0]);
|
|
2546
|
-
const index = { manager, references, publicReads: /* @__PURE__ */ new Map() };
|
|
2547
|
-
REFERENCE_INDEXES.set(source, index);
|
|
2548
|
-
return index;
|
|
2549
|
-
}
|
|
2550
|
-
function* referencesWithin(references, removed) {
|
|
2551
|
-
let low = 0;
|
|
2552
|
-
let high = references.length;
|
|
2553
|
-
while (low < high) {
|
|
2554
|
-
const middle = low + Math.floor((high - low) / 2);
|
|
2555
|
-
const reference = references[middle];
|
|
2556
|
-
if (reference === void 0 || reference.identifier.range[0] >= removed.range[0]) high = middle;
|
|
2557
|
-
else low = middle + 1;
|
|
2558
|
-
}
|
|
2559
|
-
for (let index = low; index < references.length; index++) {
|
|
2560
|
-
const reference = references[index];
|
|
2561
|
-
if (reference === void 0) continue;
|
|
2562
|
-
if (reference.identifier.range[0] > removed.range[1]) break;
|
|
2563
|
-
if (insideTypeRange(reference.identifier, removed)) yield reference;
|
|
2564
|
-
}
|
|
2565
|
-
}
|
|
2566
|
-
function publicReadExtents(index, binding3) {
|
|
2567
|
-
const cached = index.publicReads.get(binding3);
|
|
2568
|
-
if (cached !== void 0) return cached;
|
|
2569
|
-
let type = null;
|
|
2570
|
-
let value = null;
|
|
2571
|
-
let both = null;
|
|
2572
|
-
for (const retained of binding3.references) {
|
|
2573
|
-
if (!retained.isRead() || !retained.isTypeReference && !retained.isValueReference || binding3.defs.some((definition) => insideTypeRange(retained.identifier, definition.node)) || !publicTypeUse(retained.identifier)) continue;
|
|
2574
|
-
if (retained.isTypeReference) type = extendExtent(type, retained.identifier);
|
|
2575
|
-
if (retained.isValueReference) value = extendExtent(value, retained.identifier);
|
|
2576
|
-
if (retained.isTypeReference && retained.isValueReference) both = extendExtent(both, retained.identifier);
|
|
2577
|
-
}
|
|
2578
|
-
const result = { type, value, both };
|
|
2579
|
-
index.publicReads.set(binding3, result);
|
|
2580
|
-
return result;
|
|
2581
|
-
}
|
|
2582
|
-
function extendExtent(extent, identifier) {
|
|
2583
|
-
return {
|
|
2584
|
-
minStart: Math.min(extent?.minStart ?? identifier.range[0], identifier.range[0]),
|
|
2585
|
-
maxEnd: Math.max(extent?.maxEnd ?? identifier.range[1], identifier.range[1])
|
|
2586
|
-
};
|
|
2587
|
-
}
|
|
2588
|
-
function publicTypeUse(identifier) {
|
|
2589
|
-
let node = identifier;
|
|
2590
|
-
while (node.parent) {
|
|
2591
|
-
if (node.type === AST_NODE_TYPES21.TSTypeAnnotation || node.type === AST_NODE_TYPES21.TSTypePredicate || node.type === AST_NODE_TYPES21.TSAsExpression || node.type === AST_NODE_TYPES21.TSTypeAssertion) return false;
|
|
2592
|
-
if (node.type === AST_NODE_TYPES21.TSTypeAliasDeclaration) {
|
|
2593
|
-
return node.parent.type === AST_NODE_TYPES21.ExportNamedDeclaration && node.parent.declaration === node && node.parent.parent.type === AST_NODE_TYPES21.Program;
|
|
2594
|
-
}
|
|
2595
|
-
if (node.type === AST_NODE_TYPES21.ExportSpecifier) {
|
|
2596
|
-
return node.parent.type === AST_NODE_TYPES21.ExportNamedDeclaration && node.parent.source === null && node.parent.parent.type === AST_NODE_TYPES21.Program;
|
|
2597
|
-
}
|
|
2598
|
-
node = node.parent;
|
|
2599
|
-
}
|
|
2600
|
-
return false;
|
|
2601
|
-
}
|
|
2602
|
-
function insideTypeRange(node, range) {
|
|
2603
|
-
return node.range[0] >= range.range[0] && node.range[1] <= range.range[1];
|
|
2604
|
-
}
|
|
2605
|
-
|
|
2606
|
-
// src/rules/_private-consumer-fix.ts
|
|
2607
2710
|
var UNSAFE = ts3.TypeFlags.Any | ts3.TypeFlags.Unknown | ts3.TypeFlags.Never | ts3.TypeFlags.TypeParameter | ts3.TypeFlags.Conditional | ts3.TypeFlags.IndexedAccess | ts3.TypeFlags.Substitution;
|
|
2608
2711
|
function validConsumerFixCalls(node, parameter, sourceCode, services) {
|
|
2609
2712
|
if (sourceCode.getAllComments().some((comment) => /@ts-(?:expect-error|ignore|nocheck)\b/u.test(comment.value))) return false;
|
|
2610
|
-
const owner = node.type ===
|
|
2611
|
-
if (owner.type !==
|
|
2713
|
+
const owner = node.type === AST_NODE_TYPES23.FunctionDeclaration ? node : node.parent;
|
|
2714
|
+
if (owner.type !== AST_NODE_TYPES23.FunctionDeclaration && owner.type !== AST_NODE_TYPES23.VariableDeclarator) return false;
|
|
2612
2715
|
const binding3 = sourceCode.getDeclaredVariables(owner).find((variable) => variable.defs.some((definition) => definition.node === owner && (definition.type === "FunctionName" || definition.type === "Variable")));
|
|
2613
2716
|
if (!binding3) return false;
|
|
2614
2717
|
const declaration = services.esTreeNodeToTSNodeMap.get(node);
|
|
@@ -2644,7 +2747,7 @@ function validConsumerFixCalls(node, parameter, sourceCode, services) {
|
|
|
2644
2747
|
continue;
|
|
2645
2748
|
}
|
|
2646
2749
|
const call = reference.identifier.parent;
|
|
2647
|
-
if (reference.isTypeReference || !reference.isReadOnly() || call.type !==
|
|
2750
|
+
if (reference.isTypeReference || !reference.isReadOnly() || call.type !== AST_NODE_TYPES23.CallExpression || call.callee !== reference.identifier || call.optional || call.typeArguments || call.arguments.length !== declaration.parameters.length || !call.arguments.every((argument) => argument.type === AST_NODE_TYPES23.Identifier) || !validArguments(call)) return false;
|
|
2648
2751
|
calls += 1;
|
|
2649
2752
|
}
|
|
2650
2753
|
return calls > 0;
|
|
@@ -2696,7 +2799,7 @@ function minimalConsumerFix(sourceCode, annotation, removed) {
|
|
|
2696
2799
|
}
|
|
2697
2800
|
|
|
2698
2801
|
// src/rules/_private-scalar-consumer.ts
|
|
2699
|
-
import { AST_NODE_TYPES as
|
|
2802
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES24 } from "@typescript-eslint/utils";
|
|
2700
2803
|
import ts6 from "typescript";
|
|
2701
2804
|
|
|
2702
2805
|
// src/rules/_scalar-parameter-view.ts
|
|
@@ -2846,8 +2949,8 @@ function intrinsicAttribute(attribute, view) {
|
|
|
2846
2949
|
// src/rules/_private-scalar-consumer.ts
|
|
2847
2950
|
function directEval(node) {
|
|
2848
2951
|
let callee = unwrapExpression(node.callee);
|
|
2849
|
-
while (callee.type ===
|
|
2850
|
-
return callee.type ===
|
|
2952
|
+
while (callee.type === AST_NODE_TYPES24.TSInstantiationExpression) callee = unwrapExpression(callee.expression);
|
|
2953
|
+
return callee.type === AST_NODE_TYPES24.Identifier && callee.name === "eval";
|
|
2851
2954
|
}
|
|
2852
2955
|
function primitiveKeyword(node) {
|
|
2853
2956
|
return node !== void 0 && (node.kind === ts6.SyntaxKind.StringKeyword || node.kind === ts6.SyntaxKind.NumberKeyword || node.kind === ts6.SyntaxKind.BooleanKeyword || node.kind === ts6.SyntaxKind.BigIntKeyword);
|
|
@@ -2860,16 +2963,16 @@ function consumerAnnotation(node, auxiliaryScalars = false) {
|
|
|
2860
2963
|
if (!auxiliaryScalars) return void 0;
|
|
2861
2964
|
let annotation;
|
|
2862
2965
|
for (const parameter2 of node.params) {
|
|
2863
|
-
if (parameter2.type !==
|
|
2966
|
+
if (parameter2.type !== AST_NODE_TYPES24.Identifier && parameter2.type !== AST_NODE_TYPES24.ObjectPattern) continue;
|
|
2864
2967
|
const current = parameter2.typeAnnotation?.typeAnnotation;
|
|
2865
|
-
if (current?.type !==
|
|
2968
|
+
if (current?.type !== AST_NODE_TYPES24.TSTypeLiteral) continue;
|
|
2866
2969
|
if (annotation) return void 0;
|
|
2867
2970
|
annotation = current;
|
|
2868
2971
|
}
|
|
2869
2972
|
return annotation;
|
|
2870
2973
|
}
|
|
2871
2974
|
const parameter = node.params[0];
|
|
2872
|
-
return parameter?.type ===
|
|
2975
|
+
return parameter?.type === AST_NODE_TYPES24.Identifier || parameter?.type === AST_NODE_TYPES24.ObjectPattern ? parameter.typeAnnotation?.typeAnnotation : void 0;
|
|
2873
2976
|
}
|
|
2874
2977
|
function exportedSymbols(source, checker) {
|
|
2875
2978
|
const symbol = checker.getSymbolAtLocation(source);
|
|
@@ -2919,12 +3022,12 @@ function auxiliaryBindings(native, selected, checker) {
|
|
|
2919
3022
|
return bindings;
|
|
2920
3023
|
}
|
|
2921
3024
|
function callableBinding(node, sourceCode) {
|
|
2922
|
-
if (node.type ===
|
|
2923
|
-
if (node.parent.type !==
|
|
3025
|
+
if (node.type === AST_NODE_TYPES24.FunctionDeclaration) {
|
|
3026
|
+
if (node.parent.type !== AST_NODE_TYPES24.Program) return void 0;
|
|
2924
3027
|
return sourceCode.getDeclaredVariables(node).find((variable) => variable.defs.some((definition) => definition.type === "FunctionName" && definition.node === node));
|
|
2925
3028
|
}
|
|
2926
3029
|
const declaration = node.parent;
|
|
2927
|
-
if (declaration.type !==
|
|
3030
|
+
if (declaration.type !== AST_NODE_TYPES24.VariableDeclarator || declaration.init !== node || declaration.id.type !== AST_NODE_TYPES24.Identifier || declaration.id.typeAnnotation || declaration.parent.kind !== "const" || declaration.parent.parent.type !== AST_NODE_TYPES24.Program) return void 0;
|
|
2928
3031
|
return sourceCode.getDeclaredVariables(declaration).find((variable) => variable.defs.some((definition) => definition.type === "Variable" && definition.node === declaration));
|
|
2929
3032
|
}
|
|
2930
3033
|
function directCalls(binding3, arity) {
|
|
@@ -2932,7 +3035,7 @@ function directCalls(binding3, arity) {
|
|
|
2932
3035
|
const stable2 = stableValueBinding(binding3, (reference) => {
|
|
2933
3036
|
const identifier = reference.identifier;
|
|
2934
3037
|
const call = identifier.parent;
|
|
2935
|
-
if (reference.isTypeReference || !reference.isReadOnly() || call.type !==
|
|
3038
|
+
if (reference.isTypeReference || !reference.isReadOnly() || call.type !== AST_NODE_TYPES24.CallExpression || call.callee !== identifier || call.optional || call.typeArguments || call.arguments.length !== arity || !call.arguments.every((argument) => argument.type === AST_NODE_TYPES24.Identifier)) return false;
|
|
2936
3039
|
calls += 1;
|
|
2937
3040
|
return true;
|
|
2938
3041
|
});
|
|
@@ -2992,13 +3095,13 @@ function localContractBindings(roots, source, services) {
|
|
|
2992
3095
|
}
|
|
2993
3096
|
function localContractReferences(node, source, services) {
|
|
2994
3097
|
switch (node.type) {
|
|
2995
|
-
case
|
|
3098
|
+
case AST_NODE_TYPES25.TSTypeLiteral:
|
|
2996
3099
|
return [];
|
|
2997
|
-
case
|
|
3100
|
+
case AST_NODE_TYPES25.TSIntersectionType:
|
|
2998
3101
|
return node.types;
|
|
2999
|
-
case
|
|
3000
|
-
return !node.typeArguments && node.typeName.type ===
|
|
3001
|
-
case
|
|
3102
|
+
case AST_NODE_TYPES25.TSTypeReference:
|
|
3103
|
+
return !node.typeArguments && node.typeName.type === AST_NODE_TYPES25.Identifier ? [node.typeName] : null;
|
|
3104
|
+
case AST_NODE_TYPES25.Identifier:
|
|
3002
3105
|
return localBindingReferences(node, source, services);
|
|
3003
3106
|
default:
|
|
3004
3107
|
return null;
|
|
@@ -3008,8 +3111,8 @@ function localBindingReferences(identifier, source, services) {
|
|
|
3008
3111
|
const definitions2 = typeBinding(source, identifier)?.defs.filter((definition) => definition.isTypeDefinition).map((definition) => definition.node);
|
|
3009
3112
|
if (!definitions2?.length || !definitions2.every(moduleTypeDeclaration)) return null;
|
|
3010
3113
|
const first = definitions2[0];
|
|
3011
|
-
if (definitions2.length === 1 && first?.type ===
|
|
3012
|
-
const interfaces = definitions2.filter((definition) => definition.type ===
|
|
3114
|
+
if (definitions2.length === 1 && first?.type === AST_NODE_TYPES25.TSTypeAliasDeclaration && !first.typeParameters) return [first.typeAnnotation];
|
|
3115
|
+
const interfaces = definitions2.filter((definition) => definition.type === AST_NODE_TYPES25.TSInterfaceDeclaration);
|
|
3013
3116
|
if (interfaces.length !== definitions2.length || interfaces.some((declaration) => declaration.typeParameters)) return null;
|
|
3014
3117
|
if (interfaces.length > 1) {
|
|
3015
3118
|
const checker = services.program.getTypeChecker();
|
|
@@ -3017,13 +3120,13 @@ function localBindingReferences(identifier, source, services) {
|
|
|
3017
3120
|
if (!symbol || interfaces.some((declaration) => checker.getSymbolAtLocation(services.esTreeNodeToTSNodeMap.get(declaration.id)) !== symbol)) return null;
|
|
3018
3121
|
}
|
|
3019
3122
|
const bases = interfaces.flatMap((declaration) => declaration.extends.map((base) => base.expression));
|
|
3020
|
-
return bases.every((base) => base.type ===
|
|
3123
|
+
return bases.every((base) => base.type === AST_NODE_TYPES25.Identifier) ? bases : null;
|
|
3021
3124
|
}
|
|
3022
3125
|
function moduleTypeDeclaration(node) {
|
|
3023
3126
|
const parent = node.parent;
|
|
3024
|
-
if (parent?.type ===
|
|
3025
|
-
if (parent?.type !==
|
|
3026
|
-
return parent.parent.type ===
|
|
3127
|
+
if (parent?.type === AST_NODE_TYPES25.Program) return true;
|
|
3128
|
+
if (parent?.type !== AST_NODE_TYPES25.ExportNamedDeclaration && parent?.type !== AST_NODE_TYPES25.ExportDefaultDeclaration) return false;
|
|
3129
|
+
return parent.parent.type === AST_NODE_TYPES25.Program;
|
|
3027
3130
|
}
|
|
3028
3131
|
function coveringAlternative(leftNode, rightNode, checker, fieldsOf, reads) {
|
|
3029
3132
|
const left = checker.getTypeFromTypeNode(leftNode);
|
|
@@ -3058,7 +3161,7 @@ var no_redundant_consumer_union_default = createRule({
|
|
|
3058
3161
|
let dynamic = false;
|
|
3059
3162
|
const remember = (node) => {
|
|
3060
3163
|
const annotation = consumerAnnotation(node);
|
|
3061
|
-
if (annotation?.type ===
|
|
3164
|
+
if (annotation?.type === AST_NODE_TYPES25.TSUnionType && annotation.types.length === 2) candidates.push(node);
|
|
3062
3165
|
};
|
|
3063
3166
|
return {
|
|
3064
3167
|
FunctionDeclaration: remember,
|
|
@@ -3092,7 +3195,7 @@ var no_redundant_consumer_union_default = createRule({
|
|
|
3092
3195
|
const coverage = coveringAlternative(leftNode, rightNode, checker, fieldsOf, consumer.reads);
|
|
3093
3196
|
if (!coverage) continue;
|
|
3094
3197
|
const reportNode = services.tsNodeToESTreeNodeMap.get(annotation);
|
|
3095
|
-
if (coverage.mutual && (reportNode.type !==
|
|
3198
|
+
if (coverage.mutual && (reportNode.type !== AST_NODE_TYPES25.TSUnionType || !localContractBindings(reportNode.types, context.sourceCode, services))) continue;
|
|
3096
3199
|
const { covered: coveredNode, covering: coveringNode } = coverage;
|
|
3097
3200
|
const fix = privateUnionFix(context.sourceCode, services, {
|
|
3098
3201
|
candidate: candidate2,
|
|
@@ -3110,7 +3213,7 @@ var no_redundant_consumer_union_default = createRule({
|
|
|
3110
3213
|
});
|
|
3111
3214
|
|
|
3112
3215
|
// src/rules/prefer-minimal-parameter-contract.ts
|
|
3113
|
-
import { AST_NODE_TYPES as
|
|
3216
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES26, ESLintUtils as ESLintUtils3 } from "@typescript-eslint/utils";
|
|
3114
3217
|
import ts8 from "typescript";
|
|
3115
3218
|
var CONFIG2 = { path: "tsconfig.json", source: '{"compilerOptions":{"strict":true,"target":"ESNext","module":"ESNext","moduleResolution":"Bundler"}}' };
|
|
3116
3219
|
var EXAMPLE2 = 'export {}; const account = {name: "Ada", email: "a"}; function label(user: {readonly email: string; readonly name: string}): string {return user.name;} label(account);';
|
|
@@ -3167,7 +3270,7 @@ var prefer_minimal_parameter_contract_default = createRule({
|
|
|
3167
3270
|
const candidates = [];
|
|
3168
3271
|
let dynamic = false;
|
|
3169
3272
|
const remember = (node) => {
|
|
3170
|
-
if (consumerAnnotation(node, true)?.type ===
|
|
3273
|
+
if (consumerAnnotation(node, true)?.type === AST_NODE_TYPES26.TSTypeLiteral) candidates.push(node);
|
|
3171
3274
|
};
|
|
3172
3275
|
return {
|
|
3173
3276
|
FunctionDeclaration: remember,
|
|
@@ -3201,7 +3304,7 @@ var prefer_minimal_parameter_contract_default = createRule({
|
|
|
3201
3304
|
});
|
|
3202
3305
|
|
|
3203
3306
|
// src/rules/no-excess-jsx-props.ts
|
|
3204
|
-
import { AST_NODE_TYPES as
|
|
3307
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES27, ESLintUtils as ESLintUtils4 } from "@typescript-eslint/utils";
|
|
3205
3308
|
import ts10 from "typescript";
|
|
3206
3309
|
|
|
3207
3310
|
// src/rules/_ordinary-object-effects.ts
|
|
@@ -3543,11 +3646,11 @@ var PRIMITIVE_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
3543
3646
|
function plainLiteralFields(node) {
|
|
3544
3647
|
const fields2 = /* @__PURE__ */ new Map();
|
|
3545
3648
|
for (const property of node.properties) {
|
|
3546
|
-
if (property.type !==
|
|
3649
|
+
if (property.type !== AST_NODE_TYPES27.Property || property.kind !== "init") return null;
|
|
3547
3650
|
const key = property.key;
|
|
3548
3651
|
let name;
|
|
3549
|
-
if (!property.computed && key.type ===
|
|
3550
|
-
else if (key.type ===
|
|
3652
|
+
if (!property.computed && key.type === AST_NODE_TYPES27.Identifier) name = key.name;
|
|
3653
|
+
else if (key.type === AST_NODE_TYPES27.Literal && (typeof key.value === "string" || typeof key.value === "number")) name = String(key.value);
|
|
3551
3654
|
else return null;
|
|
3552
3655
|
if (name === "__proto__") return null;
|
|
3553
3656
|
fields2.set(name, property);
|
|
@@ -3659,35 +3762,35 @@ function localObjectFields(symbol, source, proof) {
|
|
|
3659
3762
|
if (!native || native.getSourceFile() !== source || !initializer || !ts10.isObjectLiteralExpression(initializer)) return null;
|
|
3660
3763
|
const declaration = proof.services.tsNodeToESTreeNodeMap.get(native);
|
|
3661
3764
|
const literal2 = proof.services.tsNodeToESTreeNodeMap.get(initializer);
|
|
3662
|
-
if (declaration.type !==
|
|
3765
|
+
if (declaration.type !== AST_NODE_TYPES27.VariableDeclarator || declaration.parent.kind !== "const" || declaration.id.type !== AST_NODE_TYPES27.Identifier || literal2.type !== AST_NODE_TYPES27.ObjectExpression || declaration.parent.parent.type === AST_NODE_TYPES27.ExportNamedDeclaration) return null;
|
|
3663
3766
|
const fields2 = plainLiteralFields(literal2);
|
|
3664
3767
|
const binding3 = proof.sourceCode.getDeclaredVariables(declaration).find((variable) => variable.defs.some((definition) => definition.type === "Variable" && definition.node === declaration));
|
|
3665
3768
|
if (!fields2 || !binding3 || binding3.defs.length !== 1 || !stableValueBinding(binding3, (reference) => {
|
|
3666
3769
|
if (!reference.isReadOnly() || reference.isTypeReference) return false;
|
|
3667
3770
|
const member3 = reference.identifier.parent;
|
|
3668
|
-
return member3.type ===
|
|
3771
|
+
return member3.type === AST_NODE_TYPES27.MemberExpression && member3.object === reference.identifier && readonlyFieldValue(member3, fields2);
|
|
3669
3772
|
})) return null;
|
|
3670
3773
|
return fields2;
|
|
3671
3774
|
}
|
|
3672
3775
|
function staticMemberKey(member3) {
|
|
3673
3776
|
const property = member3.property;
|
|
3674
|
-
return !member3.computed && property.type ===
|
|
3777
|
+
return !member3.computed && property.type === AST_NODE_TYPES27.Identifier ? property.name : property.type === AST_NODE_TYPES27.Literal && (typeof property.value === "string" || typeof property.value === "number") ? String(property.value) : void 0;
|
|
3675
3778
|
}
|
|
3676
3779
|
function readonlyFieldValue(member3, fields2) {
|
|
3677
3780
|
const key = staticMemberKey(member3);
|
|
3678
3781
|
if (key === void 0 || !fields2.has(key)) return false;
|
|
3679
3782
|
const parent = member3.parent;
|
|
3680
|
-
if (parent.type ===
|
|
3783
|
+
if (parent.type === AST_NODE_TYPES27.Property && parent.value === member3 && parent.parent.type === AST_NODE_TYPES27.ObjectExpression) {
|
|
3681
3784
|
const object = parent.parent;
|
|
3682
3785
|
const owner = object.parent;
|
|
3683
|
-
return owner.type ===
|
|
3786
|
+
return owner.type === AST_NODE_TYPES27.JSXSpreadAttribute && owner.argument === object || owner.type === AST_NODE_TYPES27.VariableDeclarator && owner.init === object;
|
|
3684
3787
|
}
|
|
3685
|
-
return parent.type ===
|
|
3788
|
+
return parent.type === AST_NODE_TYPES27.JSXExpressionContainer && parent.expression === member3 || parent.type === AST_NODE_TYPES27.VariableDeclarator && parent.init === member3;
|
|
3686
3789
|
}
|
|
3687
3790
|
function privateElementDeclaration(opening) {
|
|
3688
3791
|
const value = outerExpression(opening.parent);
|
|
3689
3792
|
const declaration = value.parent;
|
|
3690
|
-
return declaration.type ===
|
|
3793
|
+
return declaration.type === AST_NODE_TYPES27.VariableDeclarator && declaration.init === value && declaration.id.type === AST_NODE_TYPES27.Identifier && declaration.parent.kind === "const" && declaration.parent.parent.type !== AST_NODE_TYPES27.ExportNamedDeclaration ? declaration : null;
|
|
3691
3794
|
}
|
|
3692
3795
|
function closedElementValue(opening, declaration, fields2, reads, proof) {
|
|
3693
3796
|
if (!closedInvocation(opening, proof) || !constInitializer(proof.services.esTreeNodeToTSNodeMap.get(declaration))) return false;
|
|
@@ -3713,10 +3816,10 @@ function closedInvocation(node, proof) {
|
|
|
3713
3816
|
}
|
|
3714
3817
|
function independentInvocation(scope, proof) {
|
|
3715
3818
|
const block = scope.block;
|
|
3716
|
-
if (block.type !==
|
|
3819
|
+
if (block.type !== AST_NODE_TYPES27.ArrowFunctionExpression && block.type !== AST_NODE_TYPES27.FunctionDeclaration && block.type !== AST_NODE_TYPES27.FunctionExpression) return false;
|
|
3717
3820
|
if (block.async || block.generator || scope.set.get("arguments")?.references.some((reference) => !typeOnlyReference(reference))) return false;
|
|
3718
3821
|
for (const parameter of block.params) {
|
|
3719
|
-
if (parameter.type !==
|
|
3822
|
+
if (parameter.type !== AST_NODE_TYPES27.Identifier || parameter.name === "this") return false;
|
|
3720
3823
|
const binding3 = scope.set.get(parameter.name);
|
|
3721
3824
|
if (!binding3 || binding3.references.some((reference) => !typeOnlyReference(reference))) return false;
|
|
3722
3825
|
}
|
|
@@ -3724,16 +3827,16 @@ function independentInvocation(scope, proof) {
|
|
|
3724
3827
|
if (typeOnlyReference(reference)) return true;
|
|
3725
3828
|
const value = outerExpression(reference.identifier);
|
|
3726
3829
|
const parent = value.parent;
|
|
3727
|
-
const read = parent?.type ===
|
|
3830
|
+
const read = parent?.type === AST_NODE_TYPES27.MemberExpression && parent.object === value ? parent : value;
|
|
3728
3831
|
return primitiveValue(proof.services.esTreeNodeToTSNodeMap.get(read), proof, /* @__PURE__ */ new Set());
|
|
3729
3832
|
});
|
|
3730
3833
|
}
|
|
3731
3834
|
function consumedElementRead(node, fields2, reads) {
|
|
3732
3835
|
const identifier = outerExpression(node);
|
|
3733
3836
|
const props = identifier.parent;
|
|
3734
|
-
if (!props || props.type !==
|
|
3837
|
+
if (!props || props.type !== AST_NODE_TYPES27.MemberExpression || props.object !== identifier || props.optional || staticMemberKey(props) !== "props") return false;
|
|
3735
3838
|
const member3 = props.parent;
|
|
3736
|
-
if (member3.type !==
|
|
3839
|
+
if (member3.type !== AST_NODE_TYPES27.MemberExpression || member3.object !== props || member3.optional) return false;
|
|
3737
3840
|
const key = staticMemberKey(member3);
|
|
3738
3841
|
return key !== void 0 && reads.has(key) && readonlyFieldValue(member3, fields2);
|
|
3739
3842
|
}
|
|
@@ -3793,9 +3896,9 @@ var no_excess_jsx_props_default = createRule({
|
|
|
3793
3896
|
};
|
|
3794
3897
|
return {
|
|
3795
3898
|
JSXSpreadAttribute(node) {
|
|
3796
|
-
if (node.argument.type !==
|
|
3899
|
+
if (node.argument.type !== AST_NODE_TYPES27.ObjectExpression) return;
|
|
3797
3900
|
const opening = node.parent;
|
|
3798
|
-
if (!opening.selfClosing || opening.attributes.length !== 1 || opening.name.type !==
|
|
3901
|
+
if (!opening.selfClosing || opening.attributes.length !== 1 || opening.name.type !== AST_NODE_TYPES27.JSXIdentifier || /^[a-z]/u.test(opening.name.name)) return;
|
|
3799
3902
|
const declaration = privateElementDeclaration(opening);
|
|
3800
3903
|
if (!declaration) return;
|
|
3801
3904
|
const fields2 = literalFields(node.argument);
|
|
@@ -3816,7 +3919,7 @@ var no_excess_jsx_props_default = createRule({
|
|
|
3816
3919
|
});
|
|
3817
3920
|
|
|
3818
3921
|
// src/rules/prefer-native-fetch-in-server-actions.ts
|
|
3819
|
-
import { AST_NODE_TYPES as
|
|
3922
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES28 } from "@typescript-eslint/utils";
|
|
3820
3923
|
var KY_MODULE = /^ky(?:\/.*)?$/u;
|
|
3821
3924
|
var PREFER_NATIVE_FETCH_IN_SERVER_ACTIONS_DOCUMENTATION = {
|
|
3822
3925
|
defaultLevel: "warning",
|
|
@@ -3880,19 +3983,19 @@ var prefer_native_fetch_in_server_actions_default = createRule({
|
|
|
3880
3983
|
});
|
|
3881
3984
|
function hasUseServerDirective(program) {
|
|
3882
3985
|
for (const statement of program.body) {
|
|
3883
|
-
if (statement.type !==
|
|
3986
|
+
if (statement.type !== AST_NODE_TYPES28.ExpressionStatement || statement.directive === void 0) return false;
|
|
3884
3987
|
if (statement.directive === "use server") return true;
|
|
3885
3988
|
}
|
|
3886
3989
|
return false;
|
|
3887
3990
|
}
|
|
3888
3991
|
function isTypeOnly(node) {
|
|
3889
3992
|
return node.importKind === "type" || node.specifiers.length > 0 && node.specifiers.every(
|
|
3890
|
-
(specifier) => specifier.type ===
|
|
3993
|
+
(specifier) => specifier.type === AST_NODE_TYPES28.ImportSpecifier && specifier.importKind === "type"
|
|
3891
3994
|
);
|
|
3892
3995
|
}
|
|
3893
3996
|
|
|
3894
3997
|
// src/rules/no-credential-in-browser-storage.ts
|
|
3895
|
-
import { AST_NODE_TYPES as
|
|
3998
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES29, ASTUtils as ASTUtils17 } from "@typescript-eslint/utils";
|
|
3896
3999
|
|
|
3897
4000
|
// src/rules/_secret-names.ts
|
|
3898
4001
|
var SECRET_WORDS = /* @__PURE__ */ new Set([
|
|
@@ -4097,7 +4200,7 @@ var no_credential_in_browser_storage_default = createRule({
|
|
|
4097
4200
|
return {
|
|
4098
4201
|
CallExpression(node) {
|
|
4099
4202
|
const callee = unwrapExpression(node.callee);
|
|
4100
|
-
if (callee.type !==
|
|
4203
|
+
if (callee.type !== AST_NODE_TYPES29.MemberExpression || callee.computed || callee.property.type !== AST_NODE_TYPES29.Identifier || callee.property.name !== "setItem" || !isStorage(sourceCode, callee.object)) {
|
|
4101
4204
|
return;
|
|
4102
4205
|
}
|
|
4103
4206
|
const [key] = node.arguments;
|
|
@@ -4105,12 +4208,12 @@ var no_credential_in_browser_storage_default = createRule({
|
|
|
4105
4208
|
},
|
|
4106
4209
|
AssignmentExpression(node) {
|
|
4107
4210
|
const target = node.left;
|
|
4108
|
-
if (target.type !==
|
|
4211
|
+
if (target.type !== AST_NODE_TYPES29.MemberExpression) return;
|
|
4109
4212
|
if (isStorage(sourceCode, target.object)) {
|
|
4110
4213
|
report2(node, storedPropertyKey(sourceCode, target));
|
|
4111
4214
|
return;
|
|
4112
4215
|
}
|
|
4113
|
-
if (!target.computed && target.property.type ===
|
|
4216
|
+
if (!target.computed && target.property.type === AST_NODE_TYPES29.Identifier && target.property.name === "cookie" && globalMemberName(sourceCode, target.object) === "document") {
|
|
4114
4217
|
report2(node, cookieName(node.right));
|
|
4115
4218
|
}
|
|
4116
4219
|
}
|
|
@@ -4123,8 +4226,8 @@ function isStorage(sourceCode, node) {
|
|
|
4123
4226
|
}
|
|
4124
4227
|
function globalMemberName(sourceCode, node) {
|
|
4125
4228
|
const value = unwrapExpression(node);
|
|
4126
|
-
if (value.type ===
|
|
4127
|
-
if (value.type ===
|
|
4229
|
+
if (value.type === AST_NODE_TYPES29.Identifier) return isUnshadowed(sourceCode, value) ? value.name : null;
|
|
4230
|
+
if (value.type === AST_NODE_TYPES29.MemberExpression && !value.computed && value.object.type === AST_NODE_TYPES29.Identifier && GLOBAL_OBJECTS2.has(value.object.name) && value.property.type === AST_NODE_TYPES29.Identifier && isUnshadowed(sourceCode, value.object)) {
|
|
4128
4231
|
return value.property.name;
|
|
4129
4232
|
}
|
|
4130
4233
|
return null;
|
|
@@ -4134,24 +4237,24 @@ function isUnshadowed(sourceCode, node) {
|
|
|
4134
4237
|
return variable === null || variable.defs.length === 0;
|
|
4135
4238
|
}
|
|
4136
4239
|
function storedPropertyKey(sourceCode, target) {
|
|
4137
|
-
if (!target.computed) return target.property.type ===
|
|
4240
|
+
if (!target.computed) return target.property.type === AST_NODE_TYPES29.Identifier ? target.property.name : null;
|
|
4138
4241
|
return scopedStaticString(target.property, sourceCode);
|
|
4139
4242
|
}
|
|
4140
4243
|
function cookieName(value) {
|
|
4141
4244
|
let expression = unwrapExpression(value);
|
|
4142
|
-
while (expression.type ===
|
|
4245
|
+
while (expression.type === AST_NODE_TYPES29.BinaryExpression && expression.operator === "+") {
|
|
4143
4246
|
expression = unwrapExpression(expression.left);
|
|
4144
4247
|
}
|
|
4145
4248
|
let text = null;
|
|
4146
|
-
if (expression.type ===
|
|
4147
|
-
if (expression.type ===
|
|
4249
|
+
if (expression.type === AST_NODE_TYPES29.Literal && typeof expression.value === "string") text = expression.value;
|
|
4250
|
+
if (expression.type === AST_NODE_TYPES29.TemplateLiteral) text = expression.quasis[0]?.value.cooked ?? null;
|
|
4148
4251
|
if (text === null || !text.includes("=")) return null;
|
|
4149
4252
|
return text.slice(0, text.indexOf("=")).trim();
|
|
4150
4253
|
}
|
|
4151
4254
|
|
|
4152
4255
|
// src/rules/no-numeric-search-param-coercion.ts
|
|
4153
4256
|
import {
|
|
4154
|
-
AST_NODE_TYPES as
|
|
4257
|
+
AST_NODE_TYPES as AST_NODE_TYPES30,
|
|
4155
4258
|
ASTUtils as ASTUtils18,
|
|
4156
4259
|
ESLintUtils as ESLintUtils5
|
|
4157
4260
|
} from "@typescript-eslint/utils";
|
|
@@ -4233,10 +4336,10 @@ var no_numeric_search_param_coercion_default = createRule({
|
|
|
4233
4336
|
}
|
|
4234
4337
|
});
|
|
4235
4338
|
function isNumericParser(sourceCode, callee) {
|
|
4236
|
-
if (callee.type ===
|
|
4339
|
+
if (callee.type === AST_NODE_TYPES30.Identifier) {
|
|
4237
4340
|
return GLOBAL_PARSERS.has(callee.name) && isUnshadowedGlobal(sourceCode, callee);
|
|
4238
4341
|
}
|
|
4239
|
-
return callee.type ===
|
|
4342
|
+
return callee.type === AST_NODE_TYPES30.MemberExpression && !callee.computed && callee.object.type === AST_NODE_TYPES30.Identifier && callee.object.name === "Number" && callee.property.type === AST_NODE_TYPES30.Identifier && NUMBER_PARSERS.has(callee.property.name) && isUnshadowedGlobal(sourceCode, callee.object);
|
|
4240
4343
|
}
|
|
4241
4344
|
function isUnshadowedGlobal(sourceCode, node) {
|
|
4242
4345
|
const variable = ASTUtils18.findVariable(sourceCode.getScope(node), node.name);
|
|
@@ -4244,16 +4347,16 @@ function isUnshadowedGlobal(sourceCode, node) {
|
|
|
4244
4347
|
}
|
|
4245
4348
|
function searchParamGetCall(argument) {
|
|
4246
4349
|
let value = unwrapExpression(argument);
|
|
4247
|
-
if (value.type ===
|
|
4248
|
-
if (value.type ===
|
|
4249
|
-
if (value.type ===
|
|
4250
|
-
if (value.type !==
|
|
4350
|
+
if (value.type === AST_NODE_TYPES30.AwaitExpression) value = unwrapExpression(value.argument);
|
|
4351
|
+
if (value.type === AST_NODE_TYPES30.LogicalExpression && value.operator === "??") value = unwrapExpression(value.left);
|
|
4352
|
+
if (value.type === AST_NODE_TYPES30.ChainExpression) value = value.expression;
|
|
4353
|
+
if (value.type !== AST_NODE_TYPES30.CallExpression || value.callee.type !== AST_NODE_TYPES30.MemberExpression || value.callee.computed || value.callee.property.type !== AST_NODE_TYPES30.Identifier || value.callee.property.name !== "get") {
|
|
4251
4354
|
return null;
|
|
4252
4355
|
}
|
|
4253
4356
|
return value;
|
|
4254
4357
|
}
|
|
4255
4358
|
function isSearchParamReceiver(call, services) {
|
|
4256
|
-
if (call.callee.type !==
|
|
4359
|
+
if (call.callee.type !== AST_NODE_TYPES30.MemberExpression) return false;
|
|
4257
4360
|
const checker = services.program.getTypeChecker();
|
|
4258
4361
|
const type = checker.getNonNullableType(
|
|
4259
4362
|
checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(call.callee.object))
|
|
@@ -4265,7 +4368,7 @@ function isSearchParamReceiver(call, services) {
|
|
|
4265
4368
|
// package.json
|
|
4266
4369
|
var package_default = {
|
|
4267
4370
|
name: "@sarj/eslint-plugin",
|
|
4268
|
-
version: "16.
|
|
4371
|
+
version: "16.39.0",
|
|
4269
4372
|
packageManager: "npm@12.2.1",
|
|
4270
4373
|
description: "Custom ESLint rules for hypermodern TypeScript / React / Next.js projects",
|
|
4271
4374
|
type: "module",
|
|
@@ -4353,6 +4456,7 @@ var package_default = {
|
|
|
4353
4456
|
"eslint-plugin-zod": "^5.2.2",
|
|
4354
4457
|
globals: "17.13.0",
|
|
4355
4458
|
jiti: "2.7.0",
|
|
4459
|
+
prettier: "3.9.10",
|
|
4356
4460
|
tsup: "9.0.0",
|
|
4357
4461
|
typescript: "npm:@typescript/typescript6@6.0.2",
|
|
4358
4462
|
"typescript-eslint": "^8.72.0",
|
|
@@ -4388,14 +4492,14 @@ var package_default = {
|
|
|
4388
4492
|
|
|
4389
4493
|
// src/rules/require-explicit-contract-implementation.ts
|
|
4390
4494
|
import {
|
|
4391
|
-
AST_NODE_TYPES as
|
|
4495
|
+
AST_NODE_TYPES as AST_NODE_TYPES32,
|
|
4392
4496
|
ESLintUtils as ESLintUtils6
|
|
4393
4497
|
} from "@typescript-eslint/utils";
|
|
4394
4498
|
import * as ts12 from "typescript";
|
|
4395
4499
|
|
|
4396
4500
|
// src/rules/_closed-nominal-inheritance-fix.ts
|
|
4397
4501
|
import {
|
|
4398
|
-
AST_NODE_TYPES as
|
|
4502
|
+
AST_NODE_TYPES as AST_NODE_TYPES31,
|
|
4399
4503
|
ASTUtils as ASTUtils19
|
|
4400
4504
|
} from "@typescript-eslint/utils";
|
|
4401
4505
|
import ts11 from "typescript";
|
|
@@ -4471,7 +4575,7 @@ function exactRejection(sourceCode, statement) {
|
|
|
4471
4575
|
const identifier = sourceCode.getNodeByRangeIndex(
|
|
4472
4576
|
rejected.expression.expression.getStart()
|
|
4473
4577
|
);
|
|
4474
|
-
return identifier?.type ===
|
|
4578
|
+
return identifier?.type === AST_NODE_TYPES31.Identifier && identifier.name === "TypeError" && (ASTUtils19.findVariable(sourceCode.getScope(identifier), identifier.name)?.defs.length ?? 0) === 0;
|
|
4475
4579
|
}
|
|
4476
4580
|
function exactConstruction(node, consumer, implementation) {
|
|
4477
4581
|
if (!ts11.isIdentifier(node.expression) || node.expression.text !== consumer || node.typeArguments !== void 0 || node.arguments?.length !== 1)
|
|
@@ -4852,7 +4956,7 @@ var require_explicit_contract_implementation_default = createRule({
|
|
|
4852
4956
|
return;
|
|
4853
4957
|
const parameters = signature.getParameters();
|
|
4854
4958
|
for (const [index, argument] of node.arguments.entries()) {
|
|
4855
|
-
if (argument.type !==
|
|
4959
|
+
if (argument.type !== AST_NODE_TYPES32.NewExpression) continue;
|
|
4856
4960
|
const parameter = parameters[index];
|
|
4857
4961
|
if (parameter === void 0) continue;
|
|
4858
4962
|
const tsArgument = services.esTreeNodeToTSNodeMap.get(argument);
|
|
@@ -4903,17 +5007,17 @@ import "@typescript-eslint/utils";
|
|
|
4903
5007
|
|
|
4904
5008
|
// src/rules/_existing-factory-contract-fix.ts
|
|
4905
5009
|
import {
|
|
4906
|
-
AST_NODE_TYPES as
|
|
5010
|
+
AST_NODE_TYPES as AST_NODE_TYPES33,
|
|
4907
5011
|
ASTUtils as ASTUtils20
|
|
4908
5012
|
} from "@typescript-eslint/utils";
|
|
4909
5013
|
function existingFactoryContractFix(sourceCode, candidate2) {
|
|
4910
5014
|
if (sourceCode.ast.body.length !== 4 || sourceCode.getAllComments().length !== 0)
|
|
4911
5015
|
return null;
|
|
4912
5016
|
const [contractStatement, worker, classStatement, factoryStatement] = sourceCode.ast.body;
|
|
4913
|
-
const contract = contractStatement?.type ===
|
|
4914
|
-
const implementation = classStatement?.type ===
|
|
4915
|
-
const factory = factoryStatement?.type ===
|
|
4916
|
-
if (contract?.type !==
|
|
5017
|
+
const contract = contractStatement?.type === AST_NODE_TYPES33.ExportNamedDeclaration ? contractStatement.declaration : null;
|
|
5018
|
+
const implementation = classStatement?.type === AST_NODE_TYPES33.ExportNamedDeclaration ? classStatement.declaration : classStatement;
|
|
5019
|
+
const factory = factoryStatement?.type === AST_NODE_TYPES33.ExportNamedDeclaration ? factoryStatement.declaration : null;
|
|
5020
|
+
if (contract?.type !== AST_NODE_TYPES33.TSTypeAliasDeclaration || worker?.type !== AST_NODE_TYPES33.TSInterfaceDeclaration || implementation?.type !== AST_NODE_TYPES33.ClassDeclaration || implementation !== candidate2 || !ordinaryClass(implementation) || !ordinaryFactory(factory))
|
|
4917
5021
|
return null;
|
|
4918
5022
|
const operation2 = contractOperation(contract);
|
|
4919
5023
|
if (operation2 === null || interfaceOperation(worker) !== operation2)
|
|
@@ -4932,17 +5036,17 @@ function ordinaryClass(node) {
|
|
|
4932
5036
|
return node.id !== null && !node.declare && !node.abstract && node.decorators.length === 0 && node.superClass === null && node.implements.length === 0 && node.typeParameters === void 0 && node.body.body.length === 2;
|
|
4933
5037
|
}
|
|
4934
5038
|
function ordinaryFactory(node) {
|
|
4935
|
-
return node?.type ===
|
|
5039
|
+
return node?.type === AST_NODE_TYPES33.FunctionDeclaration && node.id !== null && !node.declare && !node.async && !node.generator && node.typeParameters === void 0 && node.params.length === 1 && node.body.body.length === 1;
|
|
4936
5040
|
}
|
|
4937
5041
|
function interfaceOperation(node) {
|
|
4938
5042
|
return !node.declare && node.extends.length === 0 && node.typeParameters === void 0 ? singletonOperation(node.body.body) : null;
|
|
4939
5043
|
}
|
|
4940
5044
|
function contractOperation(node) {
|
|
4941
|
-
return !node.declare && node.typeParameters === void 0 && node.typeAnnotation.type ===
|
|
5045
|
+
return !node.declare && node.typeParameters === void 0 && node.typeAnnotation.type === AST_NODE_TYPES33.TSTypeLiteral ? singletonOperation(node.typeAnnotation.members) : null;
|
|
4942
5046
|
}
|
|
4943
5047
|
function singletonOperation(members) {
|
|
4944
5048
|
const member3 = members[0];
|
|
4945
|
-
return members.length === 1 && member3?.type ===
|
|
5049
|
+
return members.length === 1 && member3?.type === AST_NODE_TYPES33.TSMethodSignature && member3.kind === "method" && !member3.computed && !member3.optional && member3.key.type === AST_NODE_TYPES33.Identifier && member3.params.length === 0 && member3.typeParameters === void 0 && member3.returnType?.typeAnnotation.type === AST_NODE_TYPES33.TSVoidKeyword ? member3.key.name : null;
|
|
4946
5050
|
}
|
|
4947
5051
|
function uniqueDeclarations(sourceCode, declarations) {
|
|
4948
5052
|
const names = declarations.flatMap(
|
|
@@ -4961,47 +5065,47 @@ function sameBinding(sourceCode, reference, declaration) {
|
|
|
4961
5065
|
}
|
|
4962
5066
|
function retainedWorker(sourceCode, implementation, worker) {
|
|
4963
5067
|
const constructor = implementation.body.body[0];
|
|
4964
|
-
if (constructor?.type !==
|
|
5068
|
+
if (constructor?.type !== AST_NODE_TYPES33.MethodDefinition || constructor.value.type !== AST_NODE_TYPES33.FunctionExpression || constructor.kind !== "constructor" || constructor.computed || constructor.static || constructor.decorators.length !== 0 || constructor.optional || constructor.accessibility !== void 0 && constructor.accessibility !== "public" || constructor.value.async || constructor.value.generator || constructor.value.typeParameters !== void 0 || constructor.value.returnType !== void 0 || constructor.value.body.body.length !== 0 || constructor.value.params.length !== 1)
|
|
4965
5069
|
return null;
|
|
4966
5070
|
const property = constructor.value.params[0];
|
|
4967
|
-
if (property?.type !==
|
|
5071
|
+
if (property?.type !== AST_NODE_TYPES33.TSParameterProperty || property.accessibility !== "private" || !property.readonly || property.override || property.decorators.length !== 0 || property.parameter.type !== AST_NODE_TYPES33.Identifier || property.parameter.optional || !typeReference(sourceCode, property.parameter.typeAnnotation, worker))
|
|
4968
5072
|
return null;
|
|
4969
5073
|
return property.parameter.name;
|
|
4970
5074
|
}
|
|
4971
5075
|
function typeReference(sourceCode, annotation, declaration) {
|
|
4972
5076
|
const type = annotation?.typeAnnotation;
|
|
4973
|
-
return type?.type ===
|
|
5077
|
+
return type?.type === AST_NODE_TYPES33.TSTypeReference && type.typeArguments === void 0 && type.typeName.type === AST_NODE_TYPES33.Identifier && sameBinding(sourceCode, type.typeName, declaration);
|
|
4974
5078
|
}
|
|
4975
5079
|
function forwardsOperation(implementation, field, operation2) {
|
|
4976
5080
|
const method = implementation.body.body[1];
|
|
4977
|
-
if (method?.type !==
|
|
5081
|
+
if (method?.type !== AST_NODE_TYPES33.MethodDefinition || method.kind !== "method" || method.value.type !== AST_NODE_TYPES33.FunctionExpression || method.computed || method.static || method.optional || method.override || method.decorators.length !== 0 || method.accessibility !== void 0 && method.accessibility !== "public" || method.key.type !== AST_NODE_TYPES33.Identifier || method.key.name !== operation2 || method.value.async || method.value.generator || method.value.typeParameters !== void 0 || method.value.params.length !== 0 || method.value.body.body.length !== 1 || method.value.returnType?.typeAnnotation.type !== AST_NODE_TYPES33.TSVoidKeyword)
|
|
4978
5082
|
return false;
|
|
4979
5083
|
const statement = method.value.body.body[0];
|
|
4980
|
-
const call = statement?.type ===
|
|
4981
|
-
return call?.type ===
|
|
5084
|
+
const call = statement?.type === AST_NODE_TYPES33.ExpressionStatement ? statement.expression : null;
|
|
5085
|
+
return call?.type === AST_NODE_TYPES33.CallExpression && !call.optional && call.typeArguments === void 0 && call.arguments.length === 0 && forwardedMember(call.callee, field, operation2);
|
|
4982
5086
|
}
|
|
4983
5087
|
function forwardedMember(node, field, operation2) {
|
|
4984
|
-
if (node.type !==
|
|
5088
|
+
if (node.type !== AST_NODE_TYPES33.MemberExpression || node.computed || node.optional || node.property.type !== AST_NODE_TYPES33.Identifier || node.property.name !== operation2)
|
|
4985
5089
|
return false;
|
|
4986
5090
|
const receiver = node.object;
|
|
4987
|
-
return receiver.type ===
|
|
5091
|
+
return receiver.type === AST_NODE_TYPES33.MemberExpression && !receiver.computed && !receiver.optional && receiver.object.type === AST_NODE_TYPES33.ThisExpression && receiver.property.type === AST_NODE_TYPES33.Identifier && receiver.property.name === field;
|
|
4988
5092
|
}
|
|
4989
5093
|
function factoryAuthority(sourceCode, factory, contract, worker, implementation) {
|
|
4990
5094
|
const parameter = factory.params[0];
|
|
4991
|
-
if (parameter?.type !==
|
|
5095
|
+
if (parameter?.type !== AST_NODE_TYPES33.Identifier || parameter.optional || !typeReference(sourceCode, parameter.typeAnnotation, worker) || !typeReference(sourceCode, factory.returnType, contract))
|
|
4992
5096
|
return false;
|
|
4993
5097
|
const statement = factory.body.body[0];
|
|
4994
|
-
const constructed = statement?.type ===
|
|
4995
|
-
if (constructed?.type !==
|
|
5098
|
+
const constructed = statement?.type === AST_NODE_TYPES33.ReturnStatement ? statement.argument : null;
|
|
5099
|
+
if (constructed?.type !== AST_NODE_TYPES33.NewExpression || constructed.typeArguments !== void 0 || constructed.callee.type !== AST_NODE_TYPES33.Identifier || !sameBinding(sourceCode, constructed.callee, implementation) || constructed.arguments.length !== 1)
|
|
4996
5100
|
return false;
|
|
4997
5101
|
const argument = constructed.arguments[0];
|
|
4998
|
-
return argument?.type ===
|
|
5102
|
+
return argument?.type === AST_NODE_TYPES33.Identifier && argument.name === parameter.name && sameBinding(sourceCode, argument, factory);
|
|
4999
5103
|
}
|
|
5000
5104
|
|
|
5001
5105
|
// src/rules/require-port-for-service.ts
|
|
5002
5106
|
import {
|
|
5003
5107
|
ASTUtils as ASTUtils21,
|
|
5004
|
-
AST_NODE_TYPES as
|
|
5108
|
+
AST_NODE_TYPES as AST_NODE_TYPES34
|
|
5005
5109
|
} from "@typescript-eslint/utils";
|
|
5006
5110
|
var REQUIRE_PORT_FOR_SERVICE_DOCUMENTATION = {
|
|
5007
5111
|
summary: "Advise when an exported service with injected collaborators has public methods not covered by its declared ports.",
|
|
@@ -5086,50 +5190,50 @@ var STORAGE_ASSIGNMENT_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
5086
5190
|
"||="
|
|
5087
5191
|
]);
|
|
5088
5192
|
var staticMemberName = (member3) => {
|
|
5089
|
-
if (member3.property.type ===
|
|
5193
|
+
if (member3.property.type === AST_NODE_TYPES34.PrivateIdentifier)
|
|
5090
5194
|
return `#${member3.property.name}`;
|
|
5091
5195
|
return ASTUtils21.getPropertyName(member3);
|
|
5092
5196
|
};
|
|
5093
5197
|
var detachedValueExports = (program) => {
|
|
5094
5198
|
const names = /* @__PURE__ */ new Set();
|
|
5095
5199
|
for (const statement of program.body) {
|
|
5096
|
-
if (statement.type ===
|
|
5200
|
+
if (statement.type === AST_NODE_TYPES34.ExportNamedDeclaration && statement.declaration === null && statement.source === null && statement.exportKind !== "type") {
|
|
5097
5201
|
for (const specifier of statement.specifiers) {
|
|
5098
5202
|
if (specifier.exportKind !== "type") names.add(specifier.local.name);
|
|
5099
5203
|
}
|
|
5100
|
-
} else if (statement.type ===
|
|
5204
|
+
} else if (statement.type === AST_NODE_TYPES34.ExportDefaultDeclaration && statement.declaration.type === AST_NODE_TYPES34.Identifier) {
|
|
5101
5205
|
names.add(statement.declaration.name);
|
|
5102
|
-
} else if (statement.type ===
|
|
5206
|
+
} else if (statement.type === AST_NODE_TYPES34.TSExportAssignment && statement.expression.type === AST_NODE_TYPES34.Identifier) {
|
|
5103
5207
|
names.add(statement.expression.name);
|
|
5104
5208
|
}
|
|
5105
5209
|
}
|
|
5106
5210
|
return names;
|
|
5107
5211
|
};
|
|
5108
|
-
var isExportedClass = (node, detached) => node.parent.type ===
|
|
5212
|
+
var isExportedClass = (node, detached) => node.parent.type === AST_NODE_TYPES34.ExportNamedDeclaration || node.parent.type === AST_NODE_TYPES34.ExportDefaultDeclaration || node.id !== null && detached.has(node.id.name);
|
|
5109
5213
|
var createExportedServiceClassResolver = (program) => {
|
|
5110
5214
|
const detached = detachedValueExports(program);
|
|
5111
5215
|
return (node) => isExportedClass(node, detached);
|
|
5112
5216
|
};
|
|
5113
5217
|
var readTypeReference = (annotation) => {
|
|
5114
|
-
if (annotation?.type ===
|
|
5218
|
+
if (annotation?.type === AST_NODE_TYPES34.TSUnionType) {
|
|
5115
5219
|
const members = annotation.types.filter(
|
|
5116
|
-
(member3) => member3.type !==
|
|
5220
|
+
(member3) => member3.type !== AST_NODE_TYPES34.TSUndefinedKeyword && member3.type !== AST_NODE_TYPES34.TSNullKeyword
|
|
5117
5221
|
);
|
|
5118
5222
|
annotation = members.length === 1 ? members[0] : void 0;
|
|
5119
5223
|
}
|
|
5120
|
-
if (annotation === void 0 || annotation.type !==
|
|
5224
|
+
if (annotation === void 0 || annotation.type !== AST_NODE_TYPES34.TSTypeReference)
|
|
5121
5225
|
return null;
|
|
5122
5226
|
const { typeName } = annotation;
|
|
5123
|
-
const rightmost = typeName.type ===
|
|
5227
|
+
const rightmost = typeName.type === AST_NODE_TYPES34.Identifier ? typeName.name : typeName.type === AST_NODE_TYPES34.TSQualifiedName ? typeName.right.name : null;
|
|
5124
5228
|
if (rightmost === null) return null;
|
|
5125
5229
|
return { typeName: rightmost, display: qualifiedName(typeName) };
|
|
5126
5230
|
};
|
|
5127
|
-
var qualifiedName = (name) => name.type ===
|
|
5231
|
+
var qualifiedName = (name) => name.type === AST_NODE_TYPES34.Identifier ? name.name : name.type === AST_NODE_TYPES34.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
|
|
5128
5232
|
var propertySignatureTypes = (members) => {
|
|
5129
5233
|
const types = /* @__PURE__ */ new Map();
|
|
5130
5234
|
for (const member3 of members) {
|
|
5131
|
-
if (member3.type !==
|
|
5132
|
-
if (member3.computed || member3.key.type !==
|
|
5235
|
+
if (member3.type !== AST_NODE_TYPES34.TSPropertySignature) continue;
|
|
5236
|
+
if (member3.computed || member3.key.type !== AST_NODE_TYPES34.Identifier)
|
|
5133
5237
|
continue;
|
|
5134
5238
|
const reference = readTypeReference(member3.typeAnnotation?.typeAnnotation);
|
|
5135
5239
|
if (reference === null) continue;
|
|
@@ -5141,18 +5245,18 @@ var fileTypeIndex = (program) => {
|
|
|
5141
5245
|
const objects = /* @__PURE__ */ new Map();
|
|
5142
5246
|
const functionAliases = localFunctionAliases(program);
|
|
5143
5247
|
function collectDeclaredType(statement) {
|
|
5144
|
-
const declaration = statement.type ===
|
|
5145
|
-
if (declaration?.type ===
|
|
5248
|
+
const declaration = statement.type === AST_NODE_TYPES34.ExportNamedDeclaration ? statement.declaration : statement;
|
|
5249
|
+
if (declaration?.type === AST_NODE_TYPES34.TSInterfaceDeclaration) {
|
|
5146
5250
|
objects.set(
|
|
5147
5251
|
declaration.id.name,
|
|
5148
5252
|
propertySignatureTypes(declaration.body.body)
|
|
5149
5253
|
);
|
|
5150
5254
|
return;
|
|
5151
5255
|
}
|
|
5152
|
-
if (declaration?.type !==
|
|
5256
|
+
if (declaration?.type !== AST_NODE_TYPES34.TSTypeAliasDeclaration) return;
|
|
5153
5257
|
const aliased = declaration.typeAnnotation;
|
|
5154
|
-
const literals = aliased.type ===
|
|
5155
|
-
(part) => part.type ===
|
|
5258
|
+
const literals = aliased.type === AST_NODE_TYPES34.TSTypeLiteral ? [aliased] : aliased.type === AST_NODE_TYPES34.TSIntersectionType ? aliased.types.filter(
|
|
5259
|
+
(part) => part.type === AST_NODE_TYPES34.TSTypeLiteral
|
|
5156
5260
|
) : [];
|
|
5157
5261
|
if (literals.length === 0) return;
|
|
5158
5262
|
const merged = /* @__PURE__ */ new Map();
|
|
@@ -5172,12 +5276,12 @@ function localFunctionAliases(program) {
|
|
|
5172
5276
|
const names = /* @__PURE__ */ new Set();
|
|
5173
5277
|
const parents = /* @__PURE__ */ new Map();
|
|
5174
5278
|
for (const statement of program.body) {
|
|
5175
|
-
const declaration = statement.type ===
|
|
5176
|
-
if (declaration?.type !==
|
|
5279
|
+
const declaration = statement.type === AST_NODE_TYPES34.ExportNamedDeclaration ? statement.declaration : statement;
|
|
5280
|
+
if (declaration?.type !== AST_NODE_TYPES34.TSTypeAliasDeclaration) continue;
|
|
5177
5281
|
const annotation = declaration.typeAnnotation;
|
|
5178
|
-
if (annotation.type ===
|
|
5282
|
+
if (annotation.type === AST_NODE_TYPES34.TSFunctionType || annotation.type === AST_NODE_TYPES34.TSConstructorType)
|
|
5179
5283
|
names.add(declaration.id.name);
|
|
5180
|
-
if (annotation.type ===
|
|
5284
|
+
if (annotation.type === AST_NODE_TYPES34.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES34.Identifier)
|
|
5181
5285
|
parents.set(declaration.id.name, annotation.typeName.name);
|
|
5182
5286
|
}
|
|
5183
5287
|
for (let pass = 0; pass < parents.size; pass += 1) {
|
|
@@ -5213,32 +5317,32 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
5213
5317
|
function scanStoredFields(body4) {
|
|
5214
5318
|
const pending = [...body4.body];
|
|
5215
5319
|
function recordStoredField(current) {
|
|
5216
|
-
if (current.type ===
|
|
5320
|
+
if (current.type === AST_NODE_TYPES34.ArrowFunctionExpression || current.type === AST_NODE_TYPES34.FunctionExpression || current.type === AST_NODE_TYPES34.FunctionDeclaration || current.type === AST_NODE_TYPES34.ClassExpression || current.type === AST_NODE_TYPES34.ClassDeclaration)
|
|
5217
5321
|
return;
|
|
5218
|
-
if (current.type ===
|
|
5322
|
+
if (current.type === AST_NODE_TYPES34.VariableDeclarator && current.id.type === AST_NODE_TYPES34.Identifier)
|
|
5219
5323
|
localBindings2.add(current.id.name);
|
|
5220
|
-
const expression = current.type ===
|
|
5324
|
+
const expression = current.type === AST_NODE_TYPES34.AssignmentExpression ? current : null;
|
|
5221
5325
|
const storedField = writtenInstanceField(current);
|
|
5222
5326
|
if (storedField !== null) {
|
|
5223
5327
|
if (writtenFieldNames.has(storedField))
|
|
5224
5328
|
unstableFieldNames.add(storedField);
|
|
5225
5329
|
writtenFieldNames.add(storedField);
|
|
5226
|
-
if (expression?.operator !== "=" || expression.parent.type !==
|
|
5330
|
+
if (expression?.operator !== "=" || expression.parent.type !== AST_NODE_TYPES34.ExpressionStatement || expression.parent.parent !== body4)
|
|
5227
5331
|
unstableFieldNames.add(storedField);
|
|
5228
5332
|
}
|
|
5229
|
-
if (expression?.type !==
|
|
5333
|
+
if (expression?.type !== AST_NODE_TYPES34.AssignmentExpression || !STORAGE_ASSIGNMENT_OPERATORS.has(expression.operator) || expression.left.type !== AST_NODE_TYPES34.MemberExpression || expression.left.object.type !== AST_NODE_TYPES34.ThisExpression || storedField === null) {
|
|
5230
5334
|
enqueueChildren(current);
|
|
5231
5335
|
return;
|
|
5232
5336
|
}
|
|
5233
5337
|
const source = unwrapExpression(expression.right);
|
|
5234
|
-
if (source.type ===
|
|
5338
|
+
if (source.type === AST_NODE_TYPES34.NewExpression) {
|
|
5235
5339
|
constructedFields += 1;
|
|
5236
5340
|
constructedFieldNames.add(storedField);
|
|
5237
|
-
} else if (source.type ===
|
|
5341
|
+
} else if (source.type === AST_NODE_TYPES34.Identifier) {
|
|
5238
5342
|
const fields2 = storedFieldsFrom.get(source.name) ?? /* @__PURE__ */ new Set();
|
|
5239
5343
|
fields2.add(storedField);
|
|
5240
5344
|
storedFieldsFrom.set(source.name, fields2);
|
|
5241
|
-
} else if (source.type ===
|
|
5345
|
+
} else if (source.type === AST_NODE_TYPES34.MemberExpression && source.object.type === AST_NODE_TYPES34.Identifier) {
|
|
5242
5346
|
const fields2 = storedFieldsFrom.get(source.object.name) ?? /* @__PURE__ */ new Set();
|
|
5243
5347
|
fields2.add(storedField);
|
|
5244
5348
|
storedFieldsFrom.set(source.object.name, fields2);
|
|
@@ -5273,7 +5377,7 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
5273
5377
|
)) {
|
|
5274
5378
|
if (localBindings2.has(reference.name)) continue;
|
|
5275
5379
|
let fields2 = reference.fields;
|
|
5276
|
-
if (parameter.type ===
|
|
5380
|
+
if (parameter.type === AST_NODE_TYPES34.TSParameterProperty) {
|
|
5277
5381
|
if (writtenFieldNames.has(reference.name)) continue;
|
|
5278
5382
|
fields2 = [reference.name];
|
|
5279
5383
|
} else if (fields2.length === 0)
|
|
@@ -5296,8 +5400,8 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
5296
5400
|
};
|
|
5297
5401
|
var parameterCollaborators = (parameter, declared, storedMemberFieldsFrom) => {
|
|
5298
5402
|
let target = parameter;
|
|
5299
|
-
if (target.type ===
|
|
5300
|
-
if (target.type ===
|
|
5403
|
+
if (target.type === AST_NODE_TYPES34.AssignmentPattern) target = target.left;
|
|
5404
|
+
if (target.type === AST_NODE_TYPES34.ObjectPattern) {
|
|
5301
5405
|
return objectPatternCollaborators(target, declared);
|
|
5302
5406
|
}
|
|
5303
5407
|
const named3 = namedParameterCollaborator(parameter);
|
|
@@ -5307,10 +5411,10 @@ var parameterCollaborators = (parameter, declared, storedMemberFieldsFrom) => {
|
|
|
5307
5411
|
};
|
|
5308
5412
|
var namedBagCollaborators = (annotated, declared, storedMemberFieldsFrom) => {
|
|
5309
5413
|
let target = annotated;
|
|
5310
|
-
if (target.type ===
|
|
5414
|
+
if (target.type === AST_NODE_TYPES34.TSParameterProperty)
|
|
5311
5415
|
target = target.parameter;
|
|
5312
|
-
if (target.type ===
|
|
5313
|
-
if (target.type !==
|
|
5416
|
+
if (target.type === AST_NODE_TYPES34.AssignmentPattern) target = target.left;
|
|
5417
|
+
if (target.type !== AST_NODE_TYPES34.Identifier) return [];
|
|
5314
5418
|
const members = bagMemberTypes(
|
|
5315
5419
|
target.typeAnnotation?.typeAnnotation,
|
|
5316
5420
|
declared
|
|
@@ -5329,10 +5433,10 @@ var namedBagCollaborators = (annotated, declared, storedMemberFieldsFrom) => {
|
|
|
5329
5433
|
};
|
|
5330
5434
|
var namedParameterCollaborator = (annotated) => {
|
|
5331
5435
|
let target = annotated;
|
|
5332
|
-
if (target.type ===
|
|
5436
|
+
if (target.type === AST_NODE_TYPES34.TSParameterProperty)
|
|
5333
5437
|
target = target.parameter;
|
|
5334
|
-
if (target.type ===
|
|
5335
|
-
if (target.type !==
|
|
5438
|
+
if (target.type === AST_NODE_TYPES34.AssignmentPattern) target = target.left;
|
|
5439
|
+
if (target.type !== AST_NODE_TYPES34.Identifier) return null;
|
|
5336
5440
|
const reference = readTypeReference(target.typeAnnotation?.typeAnnotation);
|
|
5337
5441
|
if (reference === null) return null;
|
|
5338
5442
|
return { name: target.name, ...reference, fields: [] };
|
|
@@ -5344,12 +5448,12 @@ var objectPatternCollaborators = (pattern, declared) => {
|
|
|
5344
5448
|
if (members === null) return [];
|
|
5345
5449
|
const collaborators = [];
|
|
5346
5450
|
for (const property of pattern.properties) {
|
|
5347
|
-
if (property.type !==
|
|
5451
|
+
if (property.type !== AST_NODE_TYPES34.Property || property.computed)
|
|
5348
5452
|
continue;
|
|
5349
|
-
if (property.key.type !==
|
|
5453
|
+
if (property.key.type !== AST_NODE_TYPES34.Identifier) continue;
|
|
5350
5454
|
const key = property.key.name;
|
|
5351
|
-
const bound = property.value.type ===
|
|
5352
|
-
if (bound.type !==
|
|
5455
|
+
const bound = property.value.type === AST_NODE_TYPES34.AssignmentPattern ? property.value.left : property.value;
|
|
5456
|
+
if (bound.type !== AST_NODE_TYPES34.Identifier) continue;
|
|
5353
5457
|
if (CONFIGISH_NAME_RE.test(key)) continue;
|
|
5354
5458
|
const reference = members.get(key);
|
|
5355
5459
|
if (reference === void 0) continue;
|
|
@@ -5359,22 +5463,22 @@ var objectPatternCollaborators = (pattern, declared) => {
|
|
|
5359
5463
|
};
|
|
5360
5464
|
var bagMemberTypes = (annotation, declared) => {
|
|
5361
5465
|
if (annotation === void 0) return null;
|
|
5362
|
-
if (annotation.type ===
|
|
5466
|
+
if (annotation.type === AST_NODE_TYPES34.TSTypeLiteral) {
|
|
5363
5467
|
return propertySignatureTypes(annotation.members);
|
|
5364
5468
|
}
|
|
5365
|
-
if (annotation.type !==
|
|
5469
|
+
if (annotation.type !== AST_NODE_TYPES34.TSTypeReference || annotation.typeName.type !== AST_NODE_TYPES34.Identifier) {
|
|
5366
5470
|
return null;
|
|
5367
5471
|
}
|
|
5368
5472
|
return declared().objects.get(annotation.typeName.name) ?? null;
|
|
5369
5473
|
};
|
|
5370
5474
|
var isFrameworkWiring = (body3) => subtreeHas(body3, (node) => {
|
|
5371
|
-
if (node.type ===
|
|
5475
|
+
if (node.type === AST_NODE_TYPES34.CallExpression) {
|
|
5372
5476
|
const { callee } = node;
|
|
5373
|
-
if (callee.type ===
|
|
5477
|
+
if (callee.type === AST_NODE_TYPES34.Identifier)
|
|
5374
5478
|
return callee.name === ROUTER_FACTORY_NAME;
|
|
5375
|
-
return callee.type ===
|
|
5479
|
+
return callee.type === AST_NODE_TYPES34.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES34.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
|
|
5376
5480
|
}
|
|
5377
|
-
return node.type ===
|
|
5481
|
+
return node.type === AST_NODE_TYPES34.TSTypeReference && node.typeName.type === AST_NODE_TYPES34.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
|
|
5378
5482
|
});
|
|
5379
5483
|
var subtreeHas = (root, found) => {
|
|
5380
5484
|
let hit = false;
|
|
@@ -5394,26 +5498,26 @@ var subtreeHas = (root, found) => {
|
|
|
5394
5498
|
};
|
|
5395
5499
|
var invokedInstanceField = (call) => {
|
|
5396
5500
|
let callee = unwrapExpression(call.callee);
|
|
5397
|
-
while (callee.type ===
|
|
5501
|
+
while (callee.type === AST_NODE_TYPES34.ChainExpression)
|
|
5398
5502
|
callee = unwrapExpression(callee.expression);
|
|
5399
5503
|
const direct = instanceField(callee);
|
|
5400
5504
|
if (direct !== null) return direct;
|
|
5401
|
-
return callee.type ===
|
|
5505
|
+
return callee.type === AST_NODE_TYPES34.MemberExpression ? instanceField(unwrapExpression(callee.object)) : null;
|
|
5402
5506
|
};
|
|
5403
5507
|
var instanceField = (candidate2) => {
|
|
5404
5508
|
let node = candidate2;
|
|
5405
|
-
while (node.type ===
|
|
5509
|
+
while (node.type === AST_NODE_TYPES34.ChainExpression || node.type === AST_NODE_TYPES34.TSAsExpression || node.type === AST_NODE_TYPES34.TSNonNullExpression || node.type === AST_NODE_TYPES34.TSSatisfiesExpression || node.type === AST_NODE_TYPES34.TSTypeAssertion)
|
|
5406
5510
|
node = node.expression;
|
|
5407
|
-
return node.type ===
|
|
5511
|
+
return node.type === AST_NODE_TYPES34.MemberExpression && node.object.type === AST_NODE_TYPES34.ThisExpression ? staticMemberName(node) : null;
|
|
5408
5512
|
};
|
|
5409
5513
|
function writtenInstanceField(node) {
|
|
5410
|
-
if (node.type ===
|
|
5514
|
+
if (node.type === AST_NODE_TYPES34.AssignmentExpression || node.type === AST_NODE_TYPES34.ForOfStatement || node.type === AST_NODE_TYPES34.ForInStatement)
|
|
5411
5515
|
return instanceField(node.left);
|
|
5412
|
-
if (node.type ===
|
|
5516
|
+
if (node.type === AST_NODE_TYPES34.UpdateExpression)
|
|
5413
5517
|
return instanceField(node.argument);
|
|
5414
|
-
if (node.type ===
|
|
5518
|
+
if (node.type === AST_NODE_TYPES34.UnaryExpression && node.operator === "delete")
|
|
5415
5519
|
return instanceField(node.argument);
|
|
5416
|
-
if (node.type ===
|
|
5520
|
+
if (node.type === AST_NODE_TYPES34.MemberExpression && isDestructuredWriteTarget(node))
|
|
5417
5521
|
return instanceField(node);
|
|
5418
5522
|
return null;
|
|
5419
5523
|
}
|
|
@@ -5422,39 +5526,39 @@ function isDestructuredWriteTarget(node) {
|
|
|
5422
5526
|
let target = access;
|
|
5423
5527
|
for (; ; ) {
|
|
5424
5528
|
const parent = target.parent;
|
|
5425
|
-
if (parent.type ===
|
|
5529
|
+
if (parent.type === AST_NODE_TYPES34.Property && parent.value === target && parent.parent.type === AST_NODE_TYPES34.ObjectPattern) {
|
|
5426
5530
|
target = parent.parent;
|
|
5427
5531
|
continue;
|
|
5428
5532
|
}
|
|
5429
|
-
if (parent.type ===
|
|
5533
|
+
if (parent.type === AST_NODE_TYPES34.ArrayPattern || parent.type === AST_NODE_TYPES34.ObjectPattern || parent.type === AST_NODE_TYPES34.RestElement && parent.argument === target || parent.type === AST_NODE_TYPES34.AssignmentPattern && parent.left === target) {
|
|
5430
5534
|
target = parent;
|
|
5431
5535
|
continue;
|
|
5432
5536
|
}
|
|
5433
|
-
return target !== access && (parent.type ===
|
|
5537
|
+
return target !== access && (parent.type === AST_NODE_TYPES34.AssignmentExpression || parent.type === AST_NODE_TYPES34.ForOfStatement || parent.type === AST_NODE_TYPES34.ForInStatement) && parent.left === target;
|
|
5434
5538
|
}
|
|
5435
5539
|
}
|
|
5436
5540
|
var behaviorallyInvokedFields = (body3) => {
|
|
5437
5541
|
const invoked = /* @__PURE__ */ new Set();
|
|
5438
5542
|
const visit = (current) => {
|
|
5439
|
-
if (current.type ===
|
|
5543
|
+
if (current.type === AST_NODE_TYPES34.ClassDeclaration || current.type === AST_NODE_TYPES34.ClassExpression || current.type === AST_NODE_TYPES34.FunctionDeclaration || current.type === AST_NODE_TYPES34.FunctionExpression)
|
|
5440
5544
|
return;
|
|
5441
|
-
if (current.type ===
|
|
5545
|
+
if (current.type === AST_NODE_TYPES34.CallExpression) {
|
|
5442
5546
|
const field = invokedInstanceField(current);
|
|
5443
5547
|
if (field !== null) invoked.add(field);
|
|
5444
5548
|
}
|
|
5445
5549
|
forEachOwnAstChild(current, visit);
|
|
5446
5550
|
};
|
|
5447
5551
|
for (const member3 of body3.body) {
|
|
5448
|
-
if (member3.type ===
|
|
5449
|
-
if (member3.type ===
|
|
5552
|
+
if (member3.type === AST_NODE_TYPES34.StaticBlock || member3.static) continue;
|
|
5553
|
+
if (member3.type === AST_NODE_TYPES34.MethodDefinition) {
|
|
5450
5554
|
if (member3.value.body !== null && member3.value.body !== void 0)
|
|
5451
5555
|
visit(member3.value.body);
|
|
5452
5556
|
continue;
|
|
5453
5557
|
}
|
|
5454
|
-
if (member3.type !==
|
|
5558
|
+
if (member3.type !== AST_NODE_TYPES34.PropertyDefinition || member3.value === null)
|
|
5455
5559
|
continue;
|
|
5456
5560
|
visit(
|
|
5457
|
-
member3.value.type ===
|
|
5561
|
+
member3.value.type === AST_NODE_TYPES34.ArrowFunctionExpression ? member3.value.body : member3.value
|
|
5458
5562
|
);
|
|
5459
5563
|
}
|
|
5460
5564
|
return invoked;
|
|
@@ -5474,8 +5578,8 @@ var isTransportWrapper = (className, collaborators, program) => {
|
|
|
5474
5578
|
var fileInterfaceNames = (program) => {
|
|
5475
5579
|
const names = [];
|
|
5476
5580
|
for (const statement of program.body) {
|
|
5477
|
-
const declaration = statement.type ===
|
|
5478
|
-
if (declaration?.type ===
|
|
5581
|
+
const declaration = statement.type === AST_NODE_TYPES34.ExportNamedDeclaration ? statement.declaration : statement;
|
|
5582
|
+
if (declaration?.type === AST_NODE_TYPES34.TSInterfaceDeclaration)
|
|
5479
5583
|
names.push(declaration.id.name);
|
|
5480
5584
|
}
|
|
5481
5585
|
return names;
|
|
@@ -5483,22 +5587,22 @@ var fileInterfaceNames = (program) => {
|
|
|
5483
5587
|
var publicMethodNames = (body3, functionAliases) => {
|
|
5484
5588
|
const names = [];
|
|
5485
5589
|
function collectPublicCallable(member3) {
|
|
5486
|
-
if (member3.type ===
|
|
5590
|
+
if (member3.type === AST_NODE_TYPES34.PropertyDefinition) {
|
|
5487
5591
|
if (member3.static || member3.accessibility === "private" || member3.accessibility === "protected")
|
|
5488
5592
|
return;
|
|
5489
|
-
if (member3.key.type ===
|
|
5490
|
-
if (member3.value?.type !==
|
|
5593
|
+
if (member3.key.type === AST_NODE_TYPES34.PrivateIdentifier) return;
|
|
5594
|
+
if (member3.value?.type !== AST_NODE_TYPES34.ArrowFunctionExpression && member3.value?.type !== AST_NODE_TYPES34.FunctionExpression && member3.typeAnnotation?.typeAnnotation.type !== AST_NODE_TYPES34.TSFunctionType && !(member3.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES34.TSTypeReference && member3.typeAnnotation.typeAnnotation.typeName.type === AST_NODE_TYPES34.Identifier && functionAliases.has(
|
|
5491
5595
|
member3.typeAnnotation.typeAnnotation.typeName.name
|
|
5492
5596
|
)))
|
|
5493
5597
|
return;
|
|
5494
5598
|
names.push(declaredMemberName(member3) ?? "\u2026");
|
|
5495
5599
|
return;
|
|
5496
5600
|
}
|
|
5497
|
-
if (member3.type !==
|
|
5601
|
+
if (member3.type !== AST_NODE_TYPES34.MethodDefinition) return;
|
|
5498
5602
|
if (member3.kind !== "method" || member3.static) return;
|
|
5499
5603
|
if (member3.accessibility === "private" || member3.accessibility === "protected")
|
|
5500
5604
|
return;
|
|
5501
|
-
if (member3.key.type ===
|
|
5605
|
+
if (member3.key.type === AST_NODE_TYPES34.PrivateIdentifier) return;
|
|
5502
5606
|
names.push(declaredMemberName(member3) ?? "\u2026");
|
|
5503
5607
|
}
|
|
5504
5608
|
for (const member3 of body3.body) {
|
|
@@ -5509,13 +5613,13 @@ var publicMethodNames = (body3, functionAliases) => {
|
|
|
5509
5613
|
var isFluentConstructionObject = (node, getText) => {
|
|
5510
5614
|
if (node.id === null) return false;
|
|
5511
5615
|
const methods = node.body.body.filter(
|
|
5512
|
-
(member3) => member3.type ===
|
|
5616
|
+
(member3) => member3.type === AST_NODE_TYPES34.MethodDefinition && member3.kind === "method" && !member3.static && member3.accessibility !== "private" && member3.accessibility !== "protected" && member3.value.body !== null
|
|
5513
5617
|
);
|
|
5514
5618
|
if (methods.length === 0) return false;
|
|
5515
5619
|
return methods.every((member3) => {
|
|
5516
5620
|
const result = member3.value.returnType?.typeAnnotation;
|
|
5517
5621
|
if (result === void 0) return false;
|
|
5518
|
-
const returnsOwnType = result.type ===
|
|
5622
|
+
const returnsOwnType = result.type === AST_NODE_TYPES34.TSTypeReference && result.typeName.type === AST_NODE_TYPES34.Identifier && result.typeName.name === node.id?.name;
|
|
5519
5623
|
return returnsOwnType || FLUENT_BUILDER_NAME_RE.test(node.id?.name ?? "") && FLUENT_RESULT_TYPE_RE.test(getText(result));
|
|
5520
5624
|
});
|
|
5521
5625
|
};
|
|
@@ -5523,10 +5627,10 @@ function localClassAbstractness(program) {
|
|
|
5523
5627
|
const classes = /* @__PURE__ */ new Map();
|
|
5524
5628
|
const parents = /* @__PURE__ */ new Map();
|
|
5525
5629
|
for (const statement of program.body) {
|
|
5526
|
-
const declaration = statement.type ===
|
|
5527
|
-
if (declaration?.type ===
|
|
5630
|
+
const declaration = statement.type === AST_NODE_TYPES34.ExportNamedDeclaration || statement.type === AST_NODE_TYPES34.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
5631
|
+
if (declaration?.type === AST_NODE_TYPES34.ClassDeclaration && declaration.id !== null) {
|
|
5528
5632
|
classes.set(declaration.id.name, declaration.abstract === true);
|
|
5529
|
-
if (declaration.superClass?.type ===
|
|
5633
|
+
if (declaration.superClass?.type === AST_NODE_TYPES34.Identifier) {
|
|
5530
5634
|
parents.set(declaration.id.name, declaration.superClass.name);
|
|
5531
5635
|
}
|
|
5532
5636
|
}
|
|
@@ -5544,9 +5648,9 @@ function localClassAbstractness(program) {
|
|
|
5544
5648
|
return classes;
|
|
5545
5649
|
}
|
|
5546
5650
|
function declaredMemberName(member3) {
|
|
5547
|
-
if (!member3.computed && member3.key.type ===
|
|
5651
|
+
if (!member3.computed && member3.key.type === AST_NODE_TYPES34.Identifier)
|
|
5548
5652
|
return member3.key.name;
|
|
5549
|
-
if (member3.key.type ===
|
|
5653
|
+
if (member3.key.type === AST_NODE_TYPES34.Literal && typeof member3.key.value === "string")
|
|
5550
5654
|
return member3.key.value;
|
|
5551
5655
|
return null;
|
|
5552
5656
|
}
|
|
@@ -5555,35 +5659,35 @@ function localInterfaceSurfaces(program) {
|
|
|
5555
5659
|
const parents = /* @__PURE__ */ new Map();
|
|
5556
5660
|
const functionAliases = localFunctionAliases(program);
|
|
5557
5661
|
function collectInterfaceSurface(statement) {
|
|
5558
|
-
const declaration = statement.type ===
|
|
5559
|
-
if (declaration?.type ===
|
|
5662
|
+
const declaration = statement.type === AST_NODE_TYPES34.ExportNamedDeclaration ? statement.declaration : statement;
|
|
5663
|
+
if (declaration?.type === AST_NODE_TYPES34.TSTypeAliasDeclaration) {
|
|
5560
5664
|
const callables2 = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
|
|
5561
|
-
const parts = declaration.typeAnnotation.type ===
|
|
5665
|
+
const parts = declaration.typeAnnotation.type === AST_NODE_TYPES34.TSIntersectionType ? declaration.typeAnnotation.types : [declaration.typeAnnotation];
|
|
5562
5666
|
const inherited = parents.get(declaration.id.name) ?? [];
|
|
5563
5667
|
for (const part of parts) {
|
|
5564
|
-
if (part.type ===
|
|
5668
|
+
if (part.type === AST_NODE_TYPES34.TSTypeReference && part.typeName.type === AST_NODE_TYPES34.Identifier) {
|
|
5565
5669
|
inherited.push(part.typeName.name);
|
|
5566
5670
|
continue;
|
|
5567
5671
|
}
|
|
5568
|
-
if (part.type ===
|
|
5672
|
+
if (part.type === AST_NODE_TYPES34.TSTypeReference) {
|
|
5569
5673
|
inherited.push("*");
|
|
5570
5674
|
continue;
|
|
5571
5675
|
}
|
|
5572
|
-
if (part.type !==
|
|
5676
|
+
if (part.type !== AST_NODE_TYPES34.TSTypeLiteral) continue;
|
|
5573
5677
|
addCallableMembers(part.members, callables2);
|
|
5574
5678
|
}
|
|
5575
5679
|
interfaces.set(declaration.id.name, callables2);
|
|
5576
5680
|
parents.set(declaration.id.name, inherited);
|
|
5577
5681
|
return;
|
|
5578
5682
|
}
|
|
5579
|
-
if (declaration?.type !==
|
|
5683
|
+
if (declaration?.type !== AST_NODE_TYPES34.TSInterfaceDeclaration) return;
|
|
5580
5684
|
const callables = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
|
|
5581
5685
|
addCallableMembers(declaration.body.body, callables);
|
|
5582
5686
|
interfaces.set(declaration.id.name, callables);
|
|
5583
5687
|
parents.set(declaration.id.name, [
|
|
5584
5688
|
...parents.get(declaration.id.name) ?? [],
|
|
5585
5689
|
...declaration.extends.flatMap(
|
|
5586
|
-
(heritage) => heritage.expression.type ===
|
|
5690
|
+
(heritage) => heritage.expression.type === AST_NODE_TYPES34.Identifier ? [heritage.expression.name] : ["*"]
|
|
5587
5691
|
)
|
|
5588
5692
|
]);
|
|
5589
5693
|
}
|
|
@@ -5592,17 +5696,17 @@ function localInterfaceSurfaces(program) {
|
|
|
5592
5696
|
}
|
|
5593
5697
|
function addCallableMembers(members, callables) {
|
|
5594
5698
|
for (const member3 of members) {
|
|
5595
|
-
if (member3.type !==
|
|
5699
|
+
if (member3.type !== AST_NODE_TYPES34.TSMethodSignature && member3.type !== AST_NODE_TYPES34.TSPropertySignature)
|
|
5596
5700
|
continue;
|
|
5597
5701
|
const name = declaredMemberName(member3);
|
|
5598
5702
|
if (name === null) continue;
|
|
5599
|
-
if (member3.type ===
|
|
5703
|
+
if (member3.type === AST_NODE_TYPES34.TSMethodSignature) {
|
|
5600
5704
|
callables.add(name);
|
|
5601
5705
|
continue;
|
|
5602
5706
|
}
|
|
5603
|
-
if (member3.type !==
|
|
5707
|
+
if (member3.type !== AST_NODE_TYPES34.TSPropertySignature) continue;
|
|
5604
5708
|
const annotation = member3.typeAnnotation?.typeAnnotation;
|
|
5605
|
-
if (annotation?.type ===
|
|
5709
|
+
if (annotation?.type === AST_NODE_TYPES34.TSFunctionType || annotation?.type === AST_NODE_TYPES34.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES34.Identifier && functionAliases.has(annotation.typeName.name))
|
|
5606
5710
|
callables.add(name);
|
|
5607
5711
|
}
|
|
5608
5712
|
}
|
|
@@ -5632,7 +5736,7 @@ function localInterfaceSurfaces(program) {
|
|
|
5632
5736
|
}
|
|
5633
5737
|
function hasServicePort(node, methods, classes, interfaces) {
|
|
5634
5738
|
if (node.superClass !== null) {
|
|
5635
|
-
if (node.superClass.type !==
|
|
5739
|
+
if (node.superClass.type !== AST_NODE_TYPES34.Identifier) return true;
|
|
5636
5740
|
const localAbstract = classes.get(node.superClass.name);
|
|
5637
5741
|
if (localAbstract === void 0 || localAbstract) return true;
|
|
5638
5742
|
}
|
|
@@ -5671,7 +5775,7 @@ var require_port_for_service_default = createRule({
|
|
|
5671
5775
|
if (node.abstract === true) return;
|
|
5672
5776
|
if (node.decorators.length > 0) return;
|
|
5673
5777
|
const ctor = node.body.body.find(
|
|
5674
|
-
(member3) => member3.type ===
|
|
5778
|
+
(member3) => member3.type === AST_NODE_TYPES34.MethodDefinition && member3.kind === "constructor" && member3.value.body !== null && member3.value.body !== void 0
|
|
5675
5779
|
);
|
|
5676
5780
|
if (ctor === void 0) return;
|
|
5677
5781
|
const constructorFacts = readConstructor(
|
|
@@ -5721,7 +5825,7 @@ var require_port_for_service_default = createRule({
|
|
|
5721
5825
|
function implementedSurfaceCovers(node, methods, classes, interfaces) {
|
|
5722
5826
|
const combined = /* @__PURE__ */ new Set();
|
|
5723
5827
|
for (const implementation of node.implements) {
|
|
5724
|
-
if (implementation.expression.type !==
|
|
5828
|
+
if (implementation.expression.type !== AST_NODE_TYPES34.Identifier)
|
|
5725
5829
|
return true;
|
|
5726
5830
|
const name = implementation.expression.name;
|
|
5727
5831
|
const localAbstract = classes.get(name);
|
|
@@ -5738,7 +5842,7 @@ function createServiceOperationResolver(program) {
|
|
|
5738
5842
|
let declaredTypes = null;
|
|
5739
5843
|
return (node) => {
|
|
5740
5844
|
const ctor = node.body.body.find(
|
|
5741
|
-
(member3) => member3.type ===
|
|
5845
|
+
(member3) => member3.type === AST_NODE_TYPES34.MethodDefinition && member3.kind === "constructor" && member3.value.body !== null
|
|
5742
5846
|
);
|
|
5743
5847
|
if (ctor === void 0) return [];
|
|
5744
5848
|
const declared = () => declaredTypes ??= fileTypeIndex(program);
|
|
@@ -5756,7 +5860,7 @@ function createServiceOperationResolver(program) {
|
|
|
5756
5860
|
for (const [name, body3] of serviceOperationBodies(node)) {
|
|
5757
5861
|
forEachServiceCall(body3, (call) => {
|
|
5758
5862
|
if (retained.has(invokedInstanceField(call) ?? "")) active.add(name);
|
|
5759
|
-
if (call.callee.type ===
|
|
5863
|
+
if (call.callee.type === AST_NODE_TYPES34.MemberExpression && call.callee.object.type === AST_NODE_TYPES34.ThisExpression) {
|
|
5760
5864
|
const callee = staticMemberName(call.callee);
|
|
5761
5865
|
if (callee !== null) {
|
|
5762
5866
|
const linked = callers.get(callee) ?? /* @__PURE__ */ new Set();
|
|
@@ -5795,11 +5899,11 @@ function serviceOperationBodies(node) {
|
|
|
5795
5899
|
});
|
|
5796
5900
|
}
|
|
5797
5901
|
for (const member3 of node.body.body) {
|
|
5798
|
-
if (member3.type !==
|
|
5902
|
+
if (member3.type !== AST_NODE_TYPES34.MethodDefinition && member3.type !== AST_NODE_TYPES34.PropertyDefinition)
|
|
5799
5903
|
continue;
|
|
5800
|
-
if (member3.static || member3.decorators.length > 0 || member3.type ===
|
|
5904
|
+
if (member3.static || member3.decorators.length > 0 || member3.type === AST_NODE_TYPES34.MethodDefinition && member3.kind !== "method")
|
|
5801
5905
|
continue;
|
|
5802
|
-
if (member3.value?.type !==
|
|
5906
|
+
if (member3.value?.type !== AST_NODE_TYPES34.FunctionExpression && member3.value?.type !== AST_NODE_TYPES34.ArrowFunctionExpression)
|
|
5803
5907
|
continue;
|
|
5804
5908
|
const name = declaredMemberName(member3);
|
|
5805
5909
|
if (name !== null && !written.has(name) && member3.value.body !== null)
|
|
@@ -5808,9 +5912,9 @@ function serviceOperationBodies(node) {
|
|
|
5808
5912
|
return bodies;
|
|
5809
5913
|
}
|
|
5810
5914
|
function forEachServiceCall(node, onCall) {
|
|
5811
|
-
if (node.type ===
|
|
5915
|
+
if (node.type === AST_NODE_TYPES34.FunctionDeclaration || node.type === AST_NODE_TYPES34.FunctionExpression || node.type === AST_NODE_TYPES34.ArrowFunctionExpression || node.type === AST_NODE_TYPES34.ClassDeclaration || node.type === AST_NODE_TYPES34.ClassExpression)
|
|
5812
5916
|
return;
|
|
5813
|
-
if (node.type ===
|
|
5917
|
+
if (node.type === AST_NODE_TYPES34.BlockStatement) {
|
|
5814
5918
|
for (const statement of node.body) {
|
|
5815
5919
|
forEachServiceCall(statement, onCall);
|
|
5816
5920
|
if (terminatesOperation(statement)) break;
|
|
@@ -5822,29 +5926,29 @@ function forEachServiceCall(node, onCall) {
|
|
|
5822
5926
|
forEachServiceCall(branch, onCall);
|
|
5823
5927
|
return;
|
|
5824
5928
|
}
|
|
5825
|
-
if (node.type ===
|
|
5929
|
+
if (node.type === AST_NODE_TYPES34.CallExpression) onCall(node);
|
|
5826
5930
|
forEachOwnAstChild(node, (child) => {
|
|
5827
5931
|
forEachServiceCall(child, onCall);
|
|
5828
5932
|
});
|
|
5829
5933
|
}
|
|
5830
5934
|
function literalExecutionBranch(node) {
|
|
5831
|
-
if (node.type ===
|
|
5935
|
+
if (node.type === AST_NODE_TYPES34.WhileStatement && node.test.type === AST_NODE_TYPES34.Literal && node.test.value === false)
|
|
5832
5936
|
return node.test;
|
|
5833
|
-
if ((node.type ===
|
|
5937
|
+
if ((node.type === AST_NODE_TYPES34.IfStatement || node.type === AST_NODE_TYPES34.ConditionalExpression) && node.test.type === AST_NODE_TYPES34.Literal && typeof node.test.value === "boolean") {
|
|
5834
5938
|
return node.test.value ? node.consequent : node.alternate ?? node.test;
|
|
5835
5939
|
}
|
|
5836
|
-
if (node.type !==
|
|
5940
|
+
if (node.type !== AST_NODE_TYPES34.LogicalExpression || node.left.type !== AST_NODE_TYPES34.Literal || typeof node.left.value !== "boolean")
|
|
5837
5941
|
return null;
|
|
5838
5942
|
if (node.operator === "&&") return node.left.value ? node.right : node.left;
|
|
5839
5943
|
if (node.operator === "||") return node.left.value ? node.left : node.right;
|
|
5840
5944
|
return node.left;
|
|
5841
5945
|
}
|
|
5842
5946
|
function terminatesOperation(node) {
|
|
5843
|
-
if (node.type ===
|
|
5947
|
+
if (node.type === AST_NODE_TYPES34.ReturnStatement || node.type === AST_NODE_TYPES34.ThrowStatement)
|
|
5844
5948
|
return true;
|
|
5845
|
-
if (node.type ===
|
|
5949
|
+
if (node.type === AST_NODE_TYPES34.BlockStatement)
|
|
5846
5950
|
return node.body.some(terminatesOperation);
|
|
5847
|
-
if (node.type !==
|
|
5951
|
+
if (node.type !== AST_NODE_TYPES34.IfStatement) return false;
|
|
5848
5952
|
const branch = literalExecutionBranch(node);
|
|
5849
5953
|
if (branch !== null) return terminatesOperation(branch);
|
|
5850
5954
|
return node.alternate !== null && terminatesOperation(node.consequent) && terminatesOperation(node.alternate);
|
|
@@ -5858,7 +5962,7 @@ function hasDeclaredServiceContract(node, operations, program) {
|
|
|
5858
5962
|
const seen = /* @__PURE__ */ new Set();
|
|
5859
5963
|
function addImplementedContracts(current) {
|
|
5860
5964
|
for (const implementation of current.implements) {
|
|
5861
|
-
if (implementation.expression.type !==
|
|
5965
|
+
if (implementation.expression.type !== AST_NODE_TYPES34.Identifier)
|
|
5862
5966
|
return false;
|
|
5863
5967
|
const name = implementation.expression.name;
|
|
5864
5968
|
const surface = interfaces.get(name);
|
|
@@ -5881,7 +5985,7 @@ function hasDeclaredServiceContract(node, operations, program) {
|
|
|
5881
5985
|
}
|
|
5882
5986
|
if (!addImplementedContracts(current)) return null;
|
|
5883
5987
|
if (current.superClass === null) continue;
|
|
5884
|
-
if (current.superClass.type !==
|
|
5988
|
+
if (current.superClass.type !== AST_NODE_TYPES34.Identifier) return null;
|
|
5885
5989
|
const base = classes.get(current.superClass.name);
|
|
5886
5990
|
if (base === void 0) return null;
|
|
5887
5991
|
pending.push(base);
|
|
@@ -5891,8 +5995,8 @@ function hasDeclaredServiceContract(node, operations, program) {
|
|
|
5891
5995
|
function localClassDeclarations(program) {
|
|
5892
5996
|
const classes = /* @__PURE__ */ new Map();
|
|
5893
5997
|
for (const statement of program.body) {
|
|
5894
|
-
const declaration = statement.type ===
|
|
5895
|
-
if (declaration?.type ===
|
|
5998
|
+
const declaration = statement.type === AST_NODE_TYPES34.ExportNamedDeclaration || statement.type === AST_NODE_TYPES34.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
5999
|
+
if (declaration?.type === AST_NODE_TYPES34.ClassDeclaration && declaration.id !== null)
|
|
5896
6000
|
classes.set(declaration.id.name, declaration);
|
|
5897
6001
|
}
|
|
5898
6002
|
return classes;
|
|
@@ -5900,13 +6004,13 @@ function localClassDeclarations(program) {
|
|
|
5900
6004
|
function abstractContractOperations(node, functionAliases) {
|
|
5901
6005
|
const methods = new Set(publicMethodNames(node.body, functionAliases));
|
|
5902
6006
|
for (const member3 of node.body.body) {
|
|
5903
|
-
if (member3.type !==
|
|
6007
|
+
if (member3.type !== AST_NODE_TYPES34.TSAbstractMethodDefinition && member3.type !== AST_NODE_TYPES34.TSAbstractPropertyDefinition)
|
|
5904
6008
|
continue;
|
|
5905
6009
|
if (member3.static || member3.accessibility === "private" || member3.accessibility === "protected")
|
|
5906
6010
|
continue;
|
|
5907
|
-
if (member3.type ===
|
|
6011
|
+
if (member3.type === AST_NODE_TYPES34.TSAbstractPropertyDefinition) {
|
|
5908
6012
|
const annotation = member3.typeAnnotation?.typeAnnotation;
|
|
5909
|
-
if (annotation?.type !==
|
|
6013
|
+
if (annotation?.type !== AST_NODE_TYPES34.TSFunctionType && !(annotation?.type === AST_NODE_TYPES34.TSTypeReference && annotation.typeName.type === AST_NODE_TYPES34.Identifier && functionAliases.has(annotation.typeName.name)))
|
|
5910
6014
|
continue;
|
|
5911
6015
|
}
|
|
5912
6016
|
const name = declaredMemberName(member3);
|
|
@@ -6042,7 +6146,7 @@ function isServiceRole(name, filename) {
|
|
|
6042
6146
|
}
|
|
6043
6147
|
|
|
6044
6148
|
// src/rules/no-conditional-empty-object-spread.ts
|
|
6045
|
-
import { AST_NODE_TYPES as
|
|
6149
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES35 } from "@typescript-eslint/utils";
|
|
6046
6150
|
var NO_CONDITIONAL_EMPTY_OBJECT_SPREAD_DOCUMENTATION = {
|
|
6047
6151
|
summary: "Build conditional properties explicitly instead of spreading an empty-object branch.",
|
|
6048
6152
|
rationale: "An empty-object conditional spread hides whether a property is omitted, which differs from assigning undefined.",
|
|
@@ -6094,7 +6198,7 @@ var NO_CONDITIONAL_EMPTY_OBJECT_SPREAD_DOCUMENTATION = {
|
|
|
6094
6198
|
]
|
|
6095
6199
|
};
|
|
6096
6200
|
function isEmptyObject(node) {
|
|
6097
|
-
return node.type ===
|
|
6201
|
+
return node.type === AST_NODE_TYPES35.ObjectExpression && node.properties.length === 0;
|
|
6098
6202
|
}
|
|
6099
6203
|
var no_conditional_empty_object_spread_default = createRule({
|
|
6100
6204
|
name: "no-conditional-empty-object-spread",
|
|
@@ -6115,13 +6219,13 @@ var no_conditional_empty_object_spread_default = createRule({
|
|
|
6115
6219
|
if (isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
6116
6220
|
return {
|
|
6117
6221
|
SpreadElement(node) {
|
|
6118
|
-
if (node.parent.type !==
|
|
6222
|
+
if (node.parent.type !== AST_NODE_TYPES35.ObjectExpression || node.argument.type !== AST_NODE_TYPES35.ConditionalExpression)
|
|
6119
6223
|
return;
|
|
6120
6224
|
if (isEmptyObject(node.argument.consequent) || isEmptyObject(node.argument.alternate)) {
|
|
6121
6225
|
const conditional = node.argument;
|
|
6122
6226
|
const emptyConsequent = isEmptyObject(conditional.consequent);
|
|
6123
6227
|
const populated = emptyConsequent ? conditional.alternate : conditional.consequent;
|
|
6124
|
-
const canFix = populated.type ===
|
|
6228
|
+
const canFix = populated.type === AST_NODE_TYPES35.ObjectExpression && populated.properties.length > 0 && context.sourceCode.getCommentsInside(conditional).length === 0;
|
|
6125
6229
|
context.report({
|
|
6126
6230
|
node,
|
|
6127
6231
|
messageId: "avoid",
|
|
@@ -6138,7 +6242,7 @@ var no_conditional_empty_object_spread_default = createRule({
|
|
|
6138
6242
|
|
|
6139
6243
|
// src/rules/prefer-typed-reflection.ts
|
|
6140
6244
|
import {
|
|
6141
|
-
AST_NODE_TYPES as
|
|
6245
|
+
AST_NODE_TYPES as AST_NODE_TYPES36,
|
|
6142
6246
|
ASTUtils as ASTUtils22,
|
|
6143
6247
|
ESLintUtils as ESLintUtils7
|
|
6144
6248
|
} from "@typescript-eslint/utils";
|
|
@@ -6217,17 +6321,17 @@ var prefer_typed_reflection_default = createRule({
|
|
|
6217
6321
|
const services = ESLintUtils7.getParserServices(context);
|
|
6218
6322
|
if (!services.program) return {};
|
|
6219
6323
|
const checker = services.program.getTypeChecker();
|
|
6220
|
-
const isReflect = (node) => globalName(node, "Reflect") || node.type ===
|
|
6221
|
-
const globalName = (node, name) => node.type ===
|
|
6324
|
+
const isReflect = (node) => globalName(node, "Reflect") || node.type === AST_NODE_TYPES36.MemberExpression && ASTUtils22.getPropertyName(node) === "Reflect" && globalName(node.object, "globalThis");
|
|
6325
|
+
const globalName = (node, name) => node.type === AST_NODE_TYPES36.Identifier && node.name === name && !ASTUtils22.findVariable(context.sourceCode.getScope(node), name)?.defs.length;
|
|
6222
6326
|
const closedObject = (type) => {
|
|
6223
6327
|
if (type.isUnion()) return type.types.every(closedObject);
|
|
6224
6328
|
return knownType(type) && type.getProperties().length > 0 && checker.getIndexInfosOfType(type).length === 0;
|
|
6225
6329
|
};
|
|
6226
6330
|
const inspectGet = (node, type) => {
|
|
6227
6331
|
const key = node.arguments[1] === void 0 ? void 0 : unwrapExpression(node.arguments[1]);
|
|
6228
|
-
return node.arguments.length === 2 && (staticString(key) !== null || key?.type ===
|
|
6332
|
+
return node.arguments.length === 2 && (staticString(key) !== null || key?.type === AST_NODE_TYPES36.Literal && typeof key.value === "number") && closedObject(type);
|
|
6229
6333
|
};
|
|
6230
|
-
const inspectApply = (node, type) => node.arguments.length === 3 && node.arguments[2]?.type ===
|
|
6334
|
+
const inspectApply = (node, type) => node.arguments.length === 3 && node.arguments[2]?.type === AST_NODE_TYPES36.ArrayExpression && knownType(type) && type.getCallSignatures().some(
|
|
6231
6335
|
(signature) => signature.typeParameters === void 0 && signature.parameters.every(
|
|
6232
6336
|
(parameter) => knownType(
|
|
6233
6337
|
checker.getTypeOfSymbolAtLocation(
|
|
@@ -6238,25 +6342,25 @@ var prefer_typed_reflection_default = createRule({
|
|
|
6238
6342
|
)
|
|
6239
6343
|
);
|
|
6240
6344
|
const getReplacement = (node, type, target) => {
|
|
6241
|
-
if (node.optional || node.callee.type !==
|
|
6345
|
+
if (node.optional || node.callee.type !== AST_NODE_TYPES36.MemberExpression || node.callee.optional || context.sourceCode.getCommentsInside(node).length > 0) return null;
|
|
6242
6346
|
let outer = node;
|
|
6243
|
-
while (outer.parent.type ===
|
|
6244
|
-
if (outer.parent.type ===
|
|
6347
|
+
while (outer.parent.type === AST_NODE_TYPES36.TSAsExpression || outer.parent.type === AST_NODE_TYPES36.TSTypeAssertion || outer.parent.type === AST_NODE_TYPES36.TSSatisfiesExpression || outer.parent.type === AST_NODE_TYPES36.TSNonNullExpression || outer.parent.type === AST_NODE_TYPES36.ChainExpression) outer = outer.parent;
|
|
6348
|
+
if (outer.parent.type === AST_NODE_TYPES36.UnaryExpression && outer.parent.operator === "delete" || outer.parent.type === AST_NODE_TYPES36.CallExpression && outer.parent.callee === outer || outer.parent.type === AST_NODE_TYPES36.TaggedTemplateExpression && outer.parent.tag === outer) return null;
|
|
6245
6349
|
const writtenKey = node.arguments[1];
|
|
6246
|
-
if (writtenKey === void 0 || writtenKey.type ===
|
|
6350
|
+
if (writtenKey === void 0 || writtenKey.type === AST_NODE_TYPES36.SpreadElement) return null;
|
|
6247
6351
|
const key = unwrapExpression(writtenKey);
|
|
6248
|
-
const name = staticString(key) ?? (key.type ===
|
|
6352
|
+
const name = staticString(key) ?? (key.type === AST_NODE_TYPES36.Literal && typeof key.value === "number" ? String(key.value) : null);
|
|
6249
6353
|
const members = type.isUnion() ? type.types : [type];
|
|
6250
6354
|
if (name === null || !members.every((member3) => (member3.flags & ts13.TypeFlags.Object) !== 0 && checker.getPropertyOfType(member3, name) !== void 0)) return null;
|
|
6251
6355
|
return `(${context.sourceCode.getText(target)})[${context.sourceCode.getText(writtenKey)}]`;
|
|
6252
6356
|
};
|
|
6253
6357
|
return {
|
|
6254
6358
|
CallExpression(node) {
|
|
6255
|
-
if (node.callee.type !==
|
|
6359
|
+
if (node.callee.type !== AST_NODE_TYPES36.MemberExpression || !isReflect(node.callee.object))
|
|
6256
6360
|
return;
|
|
6257
6361
|
const method = ASTUtils22.getPropertyName(node.callee);
|
|
6258
6362
|
const target = node.arguments[0];
|
|
6259
|
-
if (!target || target.type ===
|
|
6363
|
+
if (!target || target.type === AST_NODE_TYPES36.SpreadElement || method !== "get" && method !== "apply")
|
|
6260
6364
|
return;
|
|
6261
6365
|
const type = checker.getTypeAtLocation(
|
|
6262
6366
|
services.esTreeNodeToTSNodeMap.get(target)
|
|
@@ -6276,55 +6380,6 @@ import {
|
|
|
6276
6380
|
ESLintUtils as ESLintUtils8
|
|
6277
6381
|
} from "@typescript-eslint/utils";
|
|
6278
6382
|
import ts14 from "typescript";
|
|
6279
|
-
|
|
6280
|
-
// src/rules/_unused-private-binding.ts
|
|
6281
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES36 } from "@typescript-eslint/utils";
|
|
6282
|
-
function isUnusedPrivateBinding(sourceCode, declaration, identifier, filename, allowedDeclarations = [declaration]) {
|
|
6283
|
-
if (/\.d\.[cm]?ts$/u.test(filename)) return false;
|
|
6284
|
-
const bindings = sourceCode.getDeclaredVariables(declaration).filter((binding3) => binding3.name === identifier.name);
|
|
6285
|
-
if (bindings.length === 0 || bindings.some((binding3) => binding3.defs.length !== allowedDeclarations.length || binding3.defs.some((definition) => !allowedDeclarations.includes(definition.node)) || binding3.eslintUsed || binding3.references.some((reference) => reference.isRead() || reference.init !== true))) return false;
|
|
6286
|
-
if (hasIdentifierNamed(sourceCode.ast, "eval")) return false;
|
|
6287
|
-
const statement = declaration.type === AST_NODE_TYPES36.VariableDeclarator ? declaration.parent : declaration;
|
|
6288
|
-
if (statement.parent.type === AST_NODE_TYPES36.ExportNamedDeclaration || statement.parent.type === AST_NODE_TYPES36.ExportDefaultDeclaration) return false;
|
|
6289
|
-
if (statement.parent.type !== AST_NODE_TYPES36.Program) return statement.parent.type === AST_NODE_TYPES36.BlockStatement;
|
|
6290
|
-
return sourceCode.ast.body.some((node) => node.type === AST_NODE_TYPES36.ImportDeclaration || node.type === AST_NODE_TYPES36.ExportNamedDeclaration || node.type === AST_NODE_TYPES36.ExportDefaultDeclaration || node.type === AST_NODE_TYPES36.ExportAllDeclaration);
|
|
6291
|
-
}
|
|
6292
|
-
function hasOnlyDirectFactoryUses(variable) {
|
|
6293
|
-
return variable.references.every((reference) => {
|
|
6294
|
-
if (reference.isTypeReference && !reference.isValueReference) return true;
|
|
6295
|
-
const identifier = reference.identifier;
|
|
6296
|
-
const parent = identifier.parent;
|
|
6297
|
-
if (parent.type === AST_NODE_TYPES36.CallExpression && parent.callee === identifier) return true;
|
|
6298
|
-
return parent.type === AST_NODE_TYPES36.MemberExpression && parent.object === identifier && !parent.computed && parent.parent.type === AST_NODE_TYPES36.CallExpression && parent.parent.callee === parent;
|
|
6299
|
-
});
|
|
6300
|
-
}
|
|
6301
|
-
var IDENTIFIER_NAMES = /* @__PURE__ */ new WeakMap();
|
|
6302
|
-
function hasIdentifierNamed(node, name) {
|
|
6303
|
-
let names = IDENTIFIER_NAMES.get(node);
|
|
6304
|
-
if (names === void 0) {
|
|
6305
|
-
const collected = /* @__PURE__ */ new Set();
|
|
6306
|
-
const pending = [node];
|
|
6307
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
6308
|
-
while (pending.length > 0) {
|
|
6309
|
-
const current = pending.pop();
|
|
6310
|
-
if (current === void 0 || seen.has(current)) continue;
|
|
6311
|
-
seen.add(current);
|
|
6312
|
-
if (current.type === AST_NODE_TYPES36.Identifier || current.type === AST_NODE_TYPES36.JSXIdentifier) collected.add(current.name);
|
|
6313
|
-
forEachOwnAstChild(current, (child) => {
|
|
6314
|
-
pending.push(child);
|
|
6315
|
-
}, (key) => key !== "tokens" && key !== "comments");
|
|
6316
|
-
}
|
|
6317
|
-
names = collected;
|
|
6318
|
-
IDENTIFIER_NAMES.set(node, names);
|
|
6319
|
-
}
|
|
6320
|
-
return names.has(name);
|
|
6321
|
-
}
|
|
6322
|
-
function privatePredicateBooleanFix(sourceCode, node, annotation, filename) {
|
|
6323
|
-
if (!annotation.typeAnnotation || !retainsNamedTypeUses(sourceCode, annotation.typeAnnotation) || node.type !== AST_NODE_TYPES36.FunctionDeclaration || node.id === null || !isUnusedPrivateBinding(sourceCode, node, node.id, filename) || sourceCode.getCommentsInside(annotation).length > 0) return null;
|
|
6324
|
-
return (fixer) => fixer.replaceText(annotation, `boolean${sourceCode.getText(annotation).replace(/[^\r\n]/gu, "")}`);
|
|
6325
|
-
}
|
|
6326
|
-
|
|
6327
|
-
// src/rules/no-broad-return-type.ts
|
|
6328
6383
|
var NO_BROAD_RETURN_TYPE_DOCUMENTATION = {
|
|
6329
6384
|
summary: "Report explicit broad return annotations that erase a known return value.",
|
|
6330
6385
|
rationale: "An unknown, object, or unknown-valued dictionary return hides fields that the implementation already knows.",
|
|
@@ -7175,7 +7230,7 @@ var NO_CONTRADICTORY_TYPE_PREDICATE_DOCUMENTATION = {
|
|
|
7175
7230
|
"For the intrinsic object target, typeof-object also admits null only when the declared input admits null and strictNullChecks is enabled. This narrow check does not infer structural property validation or classify other object/function relationships. Overloaded implementations, contextually typed callbacks and methods with class heritage or contextual object contracts retain their separate callable domain.",
|
|
7176
7231
|
"Compiler-invalid predicate target/input relations and typeof comparisons impossible for the input remain with existing compiler and unnecessary-condition controls. This rule does not validate arbitrary predicates or runtime refinements. Generated files are excluded; tests remain checked.",
|
|
7177
7232
|
"A sole native Array.isArray call on unknown cannot establish a plain primitive-element array target. Standard-library call signatures and an unshadowed Array binding are required. Element validators, any/unknown elements, tuples, enums, branded or opaque elements and independent callable contracts abstain. Visible Array or host-global aliases, mutation, escapes, extracted methods, any value constructor or unresolved computed-property access and unrelated Array namespace uses disable this proof: structural receiver types cannot establish runtime constructor identity. Native Reflect value uses and Object prototype/descriptor reflection or namespace aliases also withdraw authority. Indirect opaque runtime replacements are not inferred.",
|
|
7178
|
-
"For a same-file nongeneric named record with a required data property, a sole typeof-object check, optionally conjoined with a null exclusion, cannot establish that property from unknown or object input. Optional-only records, dictionaries, classes, imported/generic contracts and implementations with field checks are excluded. A non-null object without the required own property supplies the contradiction;
|
|
7233
|
+
"For a same-file nongeneric named record with a required data property, a sole typeof-object check, optionally conjoined with a null exclusion, cannot establish that property from unknown or object input. Optional-only records, dictionaries, classes, imported/generic contracts and implementations with field checks are excluded. A non-null object without the required own property supplies the contradiction. The same unused-private predicate proof may remove its unobserved narrowing contract; observed callable contracts and sole named-type uses remain manual."
|
|
7179
7234
|
],
|
|
7180
7235
|
references: ["https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-5.html#inferred-type-predicates"],
|
|
7181
7236
|
examples: [
|
|
@@ -7239,7 +7294,7 @@ var no_contradictory_type_predicate_default = createRule({
|
|
|
7239
7294
|
const target = checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(annotation.typeAnnotation.typeAnnotation));
|
|
7240
7295
|
if (!checker.isTypeAssignableTo(target, input)) return;
|
|
7241
7296
|
if (shallowRecordCheck(expression, parameter, input, target, context.sourceCode, checker, services.esTreeNodeToTSNodeMap.get(node).getSourceFile())) {
|
|
7242
|
-
context.report({ node: annotation, messageId: "uncheckedRecordFields", data: { promised: checker.typeToString(target) } });
|
|
7297
|
+
context.report({ node: annotation, messageId: "uncheckedRecordFields", fix: privatePredicateBooleanFix(context.sourceCode, node, annotation, context.filename), data: { promised: checker.typeToString(target) } });
|
|
7243
7298
|
return;
|
|
7244
7299
|
}
|
|
7245
7300
|
if (check === void 0) {
|
|
@@ -7465,7 +7520,7 @@ var NO_PARTIAL_TYPE_PREDICATE_DOCUMENTATION = {
|
|
|
7465
7520
|
"Automatic fixes replace the unsound predicate with boolean only for an unused private function declaration without overloads, exports, eval, comments in the predicate, or declaration-file ownership. Runtime checks are preserved; observed callable contracts remain manual.",
|
|
7466
7521
|
"Requires type information and a non-generic, non-async function with one directly annotated parameter, an explicit broad string/number/bigint/boolean predicate and a single return. Literal, branded, structural, multi-primitive union, assertion, method and overloaded contracts are excluded; contextually typed callbacks are preserved.",
|
|
7467
7522
|
"Recognizes double-negation truthiness, a boolean parameter return or one same-kind literal comparison, optionally after a matching typeof equality. Without a typeof check, the input must already belong to the target primitive, except for double negation. String length comparisons use only concrete witnesses up to 256 characters. Arithmetic, dynamic bounds and complex boolean conditions are not inferred.",
|
|
7468
|
-
"A broad string predicate returning local Schema.safeParse(parameter).success is also checked for a locally unchanged official z.uuid() or z.string().uuid() schema. The checker must resolve the namespace to installed node_modules/zod declaration files; local path aliases and opaque module resolution abstain. The const schema permits local parse/type/direct-export reads; every safeParse call must have exactly one direct argument, without options or spreads. Local aliases, method writes and opaque consumers abstain. Direct export alone is not mutation, but external consumer monkey-patching is not proved absent. Other value uses of its imported Zod namespace cause abstention. Transforms, brands, custom schemas, imported schemas and dynamic parse calls are excluded. Visible RegExp capabilities, regex literals or dynamic evaluation invalidate this initial native-pattern proof; external runtime monkeypatches are not inferred.
|
|
7523
|
+
"A broad string predicate returning local Schema.safeParse(parameter).success is also checked for a locally unchanged official z.uuid() or z.string().uuid() schema. The checker must resolve the namespace to installed node_modules/zod declaration files; local path aliases and opaque module resolution abstain. The const schema permits local parse/type/direct-export reads; every safeParse call must have exactly one direct argument, without options or spreads. Local aliases, method writes and opaque consumers abstain. Direct export alone is not mutation, but external consumer monkey-patching is not proved absent. Other value uses of its imported Zod namespace cause abstention. Transforms, brands, custom schemas, imported schemas and dynamic parse calls are excluded. Visible RegExp capabilities, regex literals or dynamic evaluation invalidate this initial native-pattern proof; external runtime monkeypatches are not inferred. The same unused-private-declaration fix boundary applies; observed or exported predicates remain manual.",
|
|
7469
7524
|
"A concrete member of the promised broad primitive must demonstrably return false. Numeric witnesses must also be assignable as literals to the declared input: broad number assignability alone does not prove membership in a numeric enum. Compiler-invalid target/input relations, any/never/generic inputs and opaque implementations abstain. This rule does not discourage total boundary guards or infer branded refinements. Generated files are excluded; tests remain checked."
|
|
7470
7525
|
],
|
|
7471
7526
|
references: ["https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-5.html#inferred-type-predicates"],
|
|
@@ -7504,7 +7559,7 @@ var no_partial_type_predicate_default = createRule({
|
|
|
7504
7559
|
if (predicate === void 0) return;
|
|
7505
7560
|
const uuidWitness = predicate.kind === "string" ? uuidPredicateWitness(predicate.expression, predicate.parameter, context.sourceCode, services) : void 0;
|
|
7506
7561
|
if (uuidWitness !== void 0) {
|
|
7507
|
-
context.report({ node: predicate.annotation, messageId: "partialPredicate", data: { witness: showWitness(uuidWitness), target: "string" } });
|
|
7562
|
+
context.report({ node: predicate.annotation, messageId: "partialPredicate", fix: privatePredicateBooleanFix(context.sourceCode, node, predicate.annotation, context.filename), data: { witness: showWitness(uuidWitness), target: "string" } });
|
|
7508
7563
|
return;
|
|
7509
7564
|
}
|
|
7510
7565
|
const refinement = refinementExpression(predicate, context.sourceCode);
|
|
@@ -10992,7 +11047,16 @@ var no_comment_cruft_default = createRule({
|
|
|
10992
11047
|
while (end + 1 < comments.length && areAdjacentLineComments(comments[end], comments[end + 1])) end += 1;
|
|
10993
11048
|
const removals = comments.slice(start, end + 1).filter(pure).map((candidate2) => ownLineCommentRemovalRange(sourceCode.text, candidate2));
|
|
10994
11049
|
if (removals.some((removal) => removal === null)) return null;
|
|
10995
|
-
return (fixer) =>
|
|
11050
|
+
return (fixer) => {
|
|
11051
|
+
const fixes = [];
|
|
11052
|
+
for (const removal of removals) {
|
|
11053
|
+
if (removal === null) return null;
|
|
11054
|
+
const endings = commentLineEndings(sourceCode.text, removal);
|
|
11055
|
+
if (endings === null) return null;
|
|
11056
|
+
fixes.push(fixer.replaceTextRange(removal.range, endings));
|
|
11057
|
+
}
|
|
11058
|
+
return fixes;
|
|
11059
|
+
};
|
|
10996
11060
|
}
|
|
10997
11061
|
function isSectionJsDoc(comment) {
|
|
10998
11062
|
const texts = comment.value.split("\n").map(stripCommentMarker).filter((line) => line.length > 0 && !isDirective(line));
|
|
@@ -18915,7 +18979,10 @@ var no_restated_comment_default = createRule({
|
|
|
18915
18979
|
context.report({
|
|
18916
18980
|
node: comment,
|
|
18917
18981
|
messageId: "restatesLineBelow",
|
|
18918
|
-
fix: removal === null ? null : (fixer) =>
|
|
18982
|
+
fix: removal === null ? null : (fixer) => {
|
|
18983
|
+
const endings = commentLineEndings(sourceCode.text, removal);
|
|
18984
|
+
return endings === null ? null : fixer.replaceTextRange(removal.range, endings);
|
|
18985
|
+
},
|
|
18919
18986
|
suggest: removal === null ? null : [
|
|
18920
18987
|
{
|
|
18921
18988
|
messageId: "deleteComment",
|
|
@@ -19074,7 +19141,10 @@ var no_restated_jsdoc_default = createRule({
|
|
|
19074
19141
|
context.report({
|
|
19075
19142
|
node: comment,
|
|
19076
19143
|
messageId: "restatesSignature",
|
|
19077
|
-
fix: removal === null ? null : (fixer) =>
|
|
19144
|
+
fix: removal === null ? null : (fixer) => {
|
|
19145
|
+
const endings = commentLineEndings(sourceCode.text, removal);
|
|
19146
|
+
return endings === null ? null : fixer.replaceTextRange(removal.range, endings);
|
|
19147
|
+
},
|
|
19078
19148
|
suggest: removal === null ? [] : [
|
|
19079
19149
|
{
|
|
19080
19150
|
messageId: "deleteBlock",
|
|
@@ -21898,7 +21968,10 @@ function typedTagEdit(comment, signature, sourceCode) {
|
|
|
21898
21968
|
if (!removed) return null;
|
|
21899
21969
|
while (retained[0]?.trim() === "") retained.shift();
|
|
21900
21970
|
while (retained.at(-1)?.trim() === "") retained.pop();
|
|
21901
|
-
if (retained.length === 0)
|
|
21971
|
+
if (retained.length === 0) {
|
|
21972
|
+
const endings = commentLineEndings(sourceCode.text, removal);
|
|
21973
|
+
return endings === null ? null : { range: removal.range, text: endings };
|
|
21974
|
+
}
|
|
21902
21975
|
const eol = sourceCode.text.includes("\r\n") ? "\r\n" : "\n";
|
|
21903
21976
|
const indent = " ".repeat(comment.loc.start.column);
|
|
21904
21977
|
return {
|
|
@@ -22501,7 +22574,15 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
22501
22574
|
},
|
|
22502
22575
|
messageId: "commentWall",
|
|
22503
22576
|
data: { restated: String(restated), commented: String(commented) },
|
|
22504
|
-
fix: removals.length === 0 ? null : (fixer) =>
|
|
22577
|
+
fix: removals.length === 0 ? null : (fixer) => {
|
|
22578
|
+
const fixes = [];
|
|
22579
|
+
for (const removal of removals) {
|
|
22580
|
+
const endings = commentLineEndings(sourceCode.text, removal);
|
|
22581
|
+
if (endings === null) return null;
|
|
22582
|
+
fixes.push(fixer.replaceTextRange(removal.range, endings));
|
|
22583
|
+
}
|
|
22584
|
+
return fixes;
|
|
22585
|
+
}
|
|
22505
22586
|
});
|
|
22506
22587
|
}
|
|
22507
22588
|
function isGroupLabel(comment, member3, headsRun) {
|
|
@@ -22852,7 +22933,15 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
22852
22933
|
},
|
|
22853
22934
|
messageId: "commentWall",
|
|
22854
22935
|
data: { restated: String(restated), commented: String(commented) },
|
|
22855
|
-
fix: removals.length === 0 ? null : (fixer) =>
|
|
22936
|
+
fix: removals.length === 0 ? null : (fixer) => {
|
|
22937
|
+
const fixes = [];
|
|
22938
|
+
for (const removal of removals) {
|
|
22939
|
+
const endings = commentLineEndings(sourceCode.text, removal);
|
|
22940
|
+
if (endings === null) return null;
|
|
22941
|
+
fixes.push(fixer.replaceTextRange(removal.range, endings));
|
|
22942
|
+
}
|
|
22943
|
+
return fixes;
|
|
22944
|
+
}
|
|
22856
22945
|
});
|
|
22857
22946
|
}
|
|
22858
22947
|
function isGroupLabel(comment, member3, headsRun) {
|
|
@@ -23867,7 +23956,10 @@ var test_phase_label_comment_default = createRule({
|
|
|
23867
23956
|
context.report({
|
|
23868
23957
|
node: comment,
|
|
23869
23958
|
messageId: "removeLabel",
|
|
23870
|
-
fix: (fixer) =>
|
|
23959
|
+
fix: (fixer) => {
|
|
23960
|
+
const endings = commentLineEndings(context.sourceCode.text, removal);
|
|
23961
|
+
return endings === null ? null : fixer.replaceTextRange(removal.range, endings);
|
|
23962
|
+
}
|
|
23871
23963
|
});
|
|
23872
23964
|
}
|
|
23873
23965
|
}
|
|
@@ -36600,8 +36692,10 @@ var RULE_POLICY = {
|
|
|
36600
36692
|
"@sarj/require-pascal-case-zod-schema-name": ["error", "both"]
|
|
36601
36693
|
};
|
|
36602
36694
|
var ADVISORY_RULES = Object.keys(RULE_POLICY).filter(isAdvisoryRuleName).toSorted();
|
|
36603
|
-
var
|
|
36604
|
-
var
|
|
36695
|
+
var FLAT_RECOMMENDED_RULES = presetRules("recommended");
|
|
36696
|
+
var FLAT_STRICT_RULES = presetRules("strict");
|
|
36697
|
+
var RECOMMENDED_RULES = FLAT_RECOMMENDED_RULES;
|
|
36698
|
+
var STRICT_RULES = FLAT_STRICT_RULES;
|
|
36605
36699
|
function isAdvisoryRuleName(name) {
|
|
36606
36700
|
return isPolicyName(name) && RULE_POLICY[name][0] === "warn";
|
|
36607
36701
|
}
|
|
@@ -36636,12 +36730,12 @@ var PLUGIN = {
|
|
|
36636
36730
|
recommended: {
|
|
36637
36731
|
name: "@sarj/recommended",
|
|
36638
36732
|
plugins: { "@sarj": PLUGIN },
|
|
36639
|
-
rules:
|
|
36733
|
+
rules: FLAT_RECOMMENDED_RULES
|
|
36640
36734
|
},
|
|
36641
36735
|
strict: {
|
|
36642
36736
|
name: "@sarj/strict",
|
|
36643
36737
|
plugins: { "@sarj": PLUGIN },
|
|
36644
|
-
rules:
|
|
36738
|
+
rules: FLAT_STRICT_RULES
|
|
36645
36739
|
}
|
|
36646
36740
|
};
|
|
36647
36741
|
}
|