@sarj/eslint-plugin 16.38.55 → 16.39.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/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 +570 -471
- package/dist/index.d.cts +34 -215
- package/dist/index.d.ts +34 -215
- package/dist/index.js +555 -456
- 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.cjs
CHANGED
|
@@ -1814,32 +1814,215 @@ var no_generic_json_parser_default = createRule({
|
|
|
1814
1814
|
});
|
|
1815
1815
|
|
|
1816
1816
|
// src/rules/no-redundant-local-alias.ts
|
|
1817
|
+
var import_utils20 = require("@typescript-eslint/utils");
|
|
1818
|
+
|
|
1819
|
+
// src/rules/_unused-private-binding.ts
|
|
1820
|
+
var import_utils19 = require("@typescript-eslint/utils");
|
|
1821
|
+
|
|
1822
|
+
// src/rules/_type-binding.ts
|
|
1817
1823
|
var import_utils18 = require("@typescript-eslint/utils");
|
|
1824
|
+
function typeBinding(source, identifier) {
|
|
1825
|
+
let scope = source.getScope(identifier);
|
|
1826
|
+
while (scope !== null) {
|
|
1827
|
+
const variable = scope.set.get(identifier.name);
|
|
1828
|
+
if (variable !== void 0 && (variable.isTypeVariable || variable.defs.some((definition) => definition.isTypeDefinition))) {
|
|
1829
|
+
return variable;
|
|
1830
|
+
}
|
|
1831
|
+
scope = scope.upper;
|
|
1832
|
+
}
|
|
1833
|
+
return null;
|
|
1834
|
+
}
|
|
1835
|
+
var REFERENCE_INDEXES = /* @__PURE__ */ new WeakMap();
|
|
1836
|
+
function retainsNamedTypeUses(source, removed) {
|
|
1837
|
+
const manager = source.scopeManager;
|
|
1838
|
+
if (manager === null) return false;
|
|
1839
|
+
const index = referenceIndex(source, manager);
|
|
1840
|
+
for (const reference of referencesWithin(index.references, removed)) {
|
|
1841
|
+
if (!reference.isRead()) continue;
|
|
1842
|
+
const binding3 = reference.resolved;
|
|
1843
|
+
if (!binding3 || !reference.isTypeReference && !reference.isValueReference) return false;
|
|
1844
|
+
if (binding3.defs.length === 0) continue;
|
|
1845
|
+
const reads = publicReadExtents(index, binding3);
|
|
1846
|
+
const extent = reference.isTypeReference ? reference.isValueReference ? reads.both : reads.type : reads.value;
|
|
1847
|
+
if (extent === null || extent.minStart >= removed.range[0] && extent.maxEnd <= removed.range[1]) return false;
|
|
1848
|
+
}
|
|
1849
|
+
return true;
|
|
1850
|
+
}
|
|
1851
|
+
function referenceIndex(source, manager) {
|
|
1852
|
+
const cached = REFERENCE_INDEXES.get(source);
|
|
1853
|
+
if (cached?.manager === manager) return cached;
|
|
1854
|
+
const references = manager.scopes.flatMap((scope) => scope.references);
|
|
1855
|
+
references.sort((left, right) => left.identifier.range[0] - right.identifier.range[0]);
|
|
1856
|
+
const index = { manager, references, publicReads: /* @__PURE__ */ new Map() };
|
|
1857
|
+
REFERENCE_INDEXES.set(source, index);
|
|
1858
|
+
return index;
|
|
1859
|
+
}
|
|
1860
|
+
function* referencesWithin(references, removed) {
|
|
1861
|
+
let low = 0;
|
|
1862
|
+
let high = references.length;
|
|
1863
|
+
while (low < high) {
|
|
1864
|
+
const middle = low + Math.floor((high - low) / 2);
|
|
1865
|
+
const reference = references[middle];
|
|
1866
|
+
if (reference === void 0 || reference.identifier.range[0] >= removed.range[0]) high = middle;
|
|
1867
|
+
else low = middle + 1;
|
|
1868
|
+
}
|
|
1869
|
+
for (let index = low; index < references.length; index++) {
|
|
1870
|
+
const reference = references[index];
|
|
1871
|
+
if (reference === void 0) continue;
|
|
1872
|
+
if (reference.identifier.range[0] > removed.range[1]) break;
|
|
1873
|
+
if (insideTypeRange(reference.identifier, removed)) yield reference;
|
|
1874
|
+
}
|
|
1875
|
+
}
|
|
1876
|
+
function publicReadExtents(index, binding3) {
|
|
1877
|
+
const cached = index.publicReads.get(binding3);
|
|
1878
|
+
if (cached !== void 0) return cached;
|
|
1879
|
+
let type = null;
|
|
1880
|
+
let value = null;
|
|
1881
|
+
let both = null;
|
|
1882
|
+
for (const retained of binding3.references) {
|
|
1883
|
+
if (!retained.isRead() || !retained.isTypeReference && !retained.isValueReference || binding3.defs.some((definition) => insideTypeRange(retained.identifier, definition.node)) || !publicTypeUse(retained.identifier)) continue;
|
|
1884
|
+
if (retained.isTypeReference) type = extendExtent(type, retained.identifier);
|
|
1885
|
+
if (retained.isValueReference) value = extendExtent(value, retained.identifier);
|
|
1886
|
+
if (retained.isTypeReference && retained.isValueReference) both = extendExtent(both, retained.identifier);
|
|
1887
|
+
}
|
|
1888
|
+
const result = { type, value, both };
|
|
1889
|
+
index.publicReads.set(binding3, result);
|
|
1890
|
+
return result;
|
|
1891
|
+
}
|
|
1892
|
+
function extendExtent(extent, identifier) {
|
|
1893
|
+
return {
|
|
1894
|
+
minStart: Math.min(extent?.minStart ?? identifier.range[0], identifier.range[0]),
|
|
1895
|
+
maxEnd: Math.max(extent?.maxEnd ?? identifier.range[1], identifier.range[1])
|
|
1896
|
+
};
|
|
1897
|
+
}
|
|
1898
|
+
function publicTypeUse(identifier) {
|
|
1899
|
+
let node = identifier;
|
|
1900
|
+
while (node.parent) {
|
|
1901
|
+
if (node.type === import_utils18.AST_NODE_TYPES.TSTypeAnnotation || node.type === import_utils18.AST_NODE_TYPES.TSTypePredicate || node.type === import_utils18.AST_NODE_TYPES.TSAsExpression || node.type === import_utils18.AST_NODE_TYPES.TSTypeAssertion) return false;
|
|
1902
|
+
if (node.type === import_utils18.AST_NODE_TYPES.TSTypeAliasDeclaration) {
|
|
1903
|
+
return node.parent.type === import_utils18.AST_NODE_TYPES.ExportNamedDeclaration && node.parent.declaration === node && node.parent.parent.type === import_utils18.AST_NODE_TYPES.Program;
|
|
1904
|
+
}
|
|
1905
|
+
if (node.type === import_utils18.AST_NODE_TYPES.ExportSpecifier) {
|
|
1906
|
+
return node.parent.type === import_utils18.AST_NODE_TYPES.ExportNamedDeclaration && node.parent.source === null && node.parent.parent.type === import_utils18.AST_NODE_TYPES.Program;
|
|
1907
|
+
}
|
|
1908
|
+
node = node.parent;
|
|
1909
|
+
}
|
|
1910
|
+
return false;
|
|
1911
|
+
}
|
|
1912
|
+
function insideTypeRange(node, range) {
|
|
1913
|
+
return node.range[0] >= range.range[0] && node.range[1] <= range.range[1];
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
// src/rules/_unused-private-binding.ts
|
|
1917
|
+
function isUnusedPrivateBinding(sourceCode, declaration, identifier, filename, allowedDeclarations = [declaration]) {
|
|
1918
|
+
if (/\.d\.[cm]?ts$/u.test(filename)) return false;
|
|
1919
|
+
const bindings = sourceCode.getDeclaredVariables(declaration).filter((binding3) => binding3.name === identifier.name);
|
|
1920
|
+
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;
|
|
1921
|
+
if (hasIdentifierNamed(sourceCode.ast, "eval")) return false;
|
|
1922
|
+
const statement = declaration.type === import_utils19.AST_NODE_TYPES.VariableDeclarator ? declaration.parent : declaration;
|
|
1923
|
+
if (statement.parent.type === import_utils19.AST_NODE_TYPES.ExportNamedDeclaration || statement.parent.type === import_utils19.AST_NODE_TYPES.ExportDefaultDeclaration) return false;
|
|
1924
|
+
if (statement.parent.type !== import_utils19.AST_NODE_TYPES.Program) return statement.parent.type === import_utils19.AST_NODE_TYPES.BlockStatement;
|
|
1925
|
+
return sourceCode.ast.body.some((node) => node.type === import_utils19.AST_NODE_TYPES.ImportDeclaration || node.type === import_utils19.AST_NODE_TYPES.ExportNamedDeclaration || node.type === import_utils19.AST_NODE_TYPES.ExportDefaultDeclaration || node.type === import_utils19.AST_NODE_TYPES.ExportAllDeclaration);
|
|
1926
|
+
}
|
|
1927
|
+
function hasOnlyDirectFactoryUses(variable) {
|
|
1928
|
+
return variable.references.every((reference) => {
|
|
1929
|
+
if (reference.isTypeReference && !reference.isValueReference) return true;
|
|
1930
|
+
const identifier = reference.identifier;
|
|
1931
|
+
const parent = identifier.parent;
|
|
1932
|
+
if (parent.type === import_utils19.AST_NODE_TYPES.CallExpression && parent.callee === identifier) return true;
|
|
1933
|
+
return parent.type === import_utils19.AST_NODE_TYPES.MemberExpression && parent.object === identifier && !parent.computed && parent.parent.type === import_utils19.AST_NODE_TYPES.CallExpression && parent.parent.callee === parent;
|
|
1934
|
+
});
|
|
1935
|
+
}
|
|
1936
|
+
var IDENTIFIER_NAMES = /* @__PURE__ */ new WeakMap();
|
|
1937
|
+
function hasIdentifierNamed(node, name) {
|
|
1938
|
+
let names = IDENTIFIER_NAMES.get(node);
|
|
1939
|
+
if (names === void 0) {
|
|
1940
|
+
const collected = /* @__PURE__ */ new Set();
|
|
1941
|
+
const pending = [node];
|
|
1942
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
1943
|
+
while (pending.length > 0) {
|
|
1944
|
+
const current = pending.pop();
|
|
1945
|
+
if (current === void 0 || seen.has(current)) continue;
|
|
1946
|
+
seen.add(current);
|
|
1947
|
+
if (current.type === import_utils19.AST_NODE_TYPES.Identifier || current.type === import_utils19.AST_NODE_TYPES.JSXIdentifier) collected.add(current.name);
|
|
1948
|
+
forEachOwnAstChild(current, (child) => {
|
|
1949
|
+
pending.push(child);
|
|
1950
|
+
}, (key) => key !== "tokens" && key !== "comments");
|
|
1951
|
+
}
|
|
1952
|
+
names = collected;
|
|
1953
|
+
IDENTIFIER_NAMES.set(node, names);
|
|
1954
|
+
}
|
|
1955
|
+
return names.has(name);
|
|
1956
|
+
}
|
|
1957
|
+
function privatePredicateBooleanFix(sourceCode, node, annotation, filename) {
|
|
1958
|
+
if (!annotation.typeAnnotation || !retainsNamedTypeUses(sourceCode, annotation.typeAnnotation) || node.type !== import_utils19.AST_NODE_TYPES.FunctionDeclaration || node.id === null || !isUnusedPrivateBinding(sourceCode, node, node.id, filename) || sourceCode.getCommentsInside(annotation).length > 0) return null;
|
|
1959
|
+
const text = `boolean${sourceCode.getText(annotation).replace(/[^\r\n\u2028\u2029]/gu, "")}`;
|
|
1960
|
+
const neighbor = Math.max(0, annotation.range[0] - 1);
|
|
1961
|
+
const before = sourceCode.text.slice(neighbor, annotation.range[1] + 1).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
1962
|
+
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) ?? [];
|
|
1963
|
+
if (before.length !== after.length || before.some((ending, index) => ending !== after[index])) return null;
|
|
1964
|
+
return (fixer) => fixer.replaceText(annotation, text);
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
// src/rules/no-redundant-local-alias.ts
|
|
1818
1968
|
var NO_REDUNDANT_LOCAL_ALIAS_DOCUMENTATION = {
|
|
1819
1969
|
defaultLevel: "warning",
|
|
1820
1970
|
summary: "Pass the original local into an object field instead of creating a single-use rename.",
|
|
1821
1971
|
rationale: "An unannotated alias used only by its matching object field adds a second name without adding a contract.",
|
|
1822
1972
|
remediation: "Write the object property with the original binding, then remove the redundant alias. Keep annotations, captured snapshots and independently useful names.",
|
|
1823
1973
|
category: "maintainability",
|
|
1974
|
+
autofix: "safe",
|
|
1824
1975
|
limitations: [
|
|
1825
1976
|
"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.",
|
|
1826
|
-
"
|
|
1977
|
+
"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."
|
|
1827
1978
|
],
|
|
1828
1979
|
examples: [
|
|
1829
1980
|
{ 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 },
|
|
1830
|
-
{ 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 }
|
|
1981
|
+
{ 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 },
|
|
1982
|
+
{ 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 },
|
|
1983
|
+
{ 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 }
|
|
1831
1984
|
]
|
|
1832
1985
|
};
|
|
1833
1986
|
function stableSource(variable, alias) {
|
|
1834
1987
|
const definition = variable.defs[0];
|
|
1835
1988
|
if (variable.defs.length !== 1 || definition === void 0 || variable.references.some((reference) => reference.isWrite() && !reference.init)) return false;
|
|
1836
|
-
return definition.type === "Parameter" || definition.node.type ===
|
|
1989
|
+
return definition.type === "Parameter" || definition.node.type === import_utils20.AST_NODE_TYPES.VariableDeclarator && definition.node.parent.kind === "const" && definition.node.init !== null && definition.node.range[1] < alias.range[0];
|
|
1990
|
+
}
|
|
1991
|
+
var PRIMITIVE_PARAMETERS = /* @__PURE__ */ new Set([
|
|
1992
|
+
import_utils20.AST_NODE_TYPES.TSStringKeyword,
|
|
1993
|
+
import_utils20.AST_NODE_TYPES.TSNumberKeyword,
|
|
1994
|
+
import_utils20.AST_NODE_TYPES.TSBooleanKeyword,
|
|
1995
|
+
import_utils20.AST_NODE_TYPES.TSBigIntKeyword,
|
|
1996
|
+
import_utils20.AST_NODE_TYPES.TSSymbolKeyword
|
|
1997
|
+
]);
|
|
1998
|
+
function closedPrimitiveReturnFix(sourceCode, node, property, source, target) {
|
|
1999
|
+
const statement = node.parent;
|
|
2000
|
+
const body3 = statement.parent;
|
|
2001
|
+
if (body3.type !== import_utils20.AST_NODE_TYPES.BlockStatement) return null;
|
|
2002
|
+
const owner = body3.parent;
|
|
2003
|
+
if (owner.type !== import_utils20.AST_NODE_TYPES.FunctionDeclaration || owner.parent.type !== import_utils20.AST_NODE_TYPES.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 !== import_utils20.AST_NODE_TYPES.Identifier || node.id.name === "__proto__" || node.init?.type !== import_utils20.AST_NODE_TYPES.Identifier || sourceCode.getCommentsInside(owner).length !== 0 || hasIdentifierNamed(sourceCode.ast, "eval")) return null;
|
|
2004
|
+
const parameter = owner.params[0];
|
|
2005
|
+
const returned2 = body3.body[1];
|
|
2006
|
+
if (parameter?.type !== import_utils20.AST_NODE_TYPES.Identifier || parameter.optional === true || parameter.typeAnnotation === void 0 || !PRIMITIVE_PARAMETERS.has(parameter.typeAnnotation.typeAnnotation.type) || returned2?.type !== import_utils20.AST_NODE_TYPES.ReturnStatement || returned2.argument !== property.parent || property.parent.type !== import_utils20.AST_NODE_TYPES.ObjectExpression || property.parent.properties.length !== 1 || import_utils20.ASTUtils.findVariable(sourceCode.getScope(parameter), parameter.name) !== source || import_utils20.ASTUtils.findVariable(sourceCode.getScope(property), node.init.name) !== source || source.references.some((reference) => reference.isTypeReference) || target.references.some((reference) => reference.isTypeReference)) return null;
|
|
2007
|
+
const name = owner.id.name;
|
|
2008
|
+
const bindings = sourceCode.getDeclaredVariables(owner).filter((binding3) => binding3.name === name);
|
|
2009
|
+
if (bindings.length !== 1 || bindings[0]?.defs.length !== 1 || bindings[0].defs[0]?.node !== owner || bindings[0].references.some((reference) => reference.isTypeReference)) return null;
|
|
2010
|
+
const span = [body3.range[0] + 1, statement.range[1]];
|
|
2011
|
+
const boundaries = sourceCode.text.slice(...span).replace(/[^\r\n\u2028\u2029]/gu, "");
|
|
2012
|
+
const neighbor = Math.max(0, span[0] - 1);
|
|
2013
|
+
const before = sourceCode.text.slice(neighbor, span[1] + 1).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
2014
|
+
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) ?? [];
|
|
2015
|
+
if (before.length !== after.length || before.some((ending, index) => ending !== after[index])) return null;
|
|
2016
|
+
const key = sourceCode.getText(property.key);
|
|
2017
|
+
const value = sourceCode.getText(node.init);
|
|
2018
|
+
return (fixer) => [fixer.replaceTextRange(span, boundaries), fixer.replaceText(property, `${key}: ${value}`)];
|
|
1837
2019
|
}
|
|
1838
2020
|
var no_redundant_local_alias_default = createRule({
|
|
1839
2021
|
name: "no-redundant-local-alias",
|
|
1840
2022
|
documentation: NO_REDUNDANT_LOCAL_ALIAS_DOCUMENTATION,
|
|
1841
2023
|
meta: {
|
|
1842
2024
|
type: "suggestion",
|
|
2025
|
+
fixable: "code",
|
|
1843
2026
|
docs: { description: NO_REDUNDANT_LOCAL_ALIAS_DOCUMENTATION.summary },
|
|
1844
2027
|
schema: [],
|
|
1845
2028
|
messages: { redundantAlias: "This alias is read only by its matching object field; pass `{{source}}` directly as `{{target}}: {{source}}`." }
|
|
@@ -1847,31 +2030,32 @@ var no_redundant_local_alias_default = createRule({
|
|
|
1847
2030
|
defaultOptions: [],
|
|
1848
2031
|
create(context) {
|
|
1849
2032
|
if (isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
2033
|
+
const hasModuleSyntax = context.sourceCode.ast.body.some((candidate2) => candidate2.type === import_utils20.AST_NODE_TYPES.ImportDeclaration || candidate2.type === import_utils20.AST_NODE_TYPES.ExportNamedDeclaration || candidate2.type === import_utils20.AST_NODE_TYPES.ExportDefaultDeclaration || candidate2.type === import_utils20.AST_NODE_TYPES.ExportAllDeclaration);
|
|
1850
2034
|
return {
|
|
1851
2035
|
VariableDeclarator(node) {
|
|
1852
|
-
if (node.parent.kind !== "const" || node.parent.declarations.length !== 1 || node.id.type !==
|
|
2036
|
+
if (node.parent.kind !== "const" || node.parent.declarations.length !== 1 || node.id.type !== import_utils20.AST_NODE_TYPES.Identifier || node.id.typeAnnotation !== void 0 || node.init?.type !== import_utils20.AST_NODE_TYPES.Identifier) return;
|
|
1853
2037
|
const scope = context.sourceCode.getScope(node);
|
|
1854
2038
|
if (scope.variableScope.type !== "function") return;
|
|
1855
|
-
const target =
|
|
1856
|
-
const source =
|
|
2039
|
+
const target = import_utils20.ASTUtils.findVariable(scope, node.id.name);
|
|
2040
|
+
const source = import_utils20.ASTUtils.findVariable(scope, node.init.name);
|
|
1857
2041
|
if (target === null || source === null || !stableSource(source, node)) return;
|
|
1858
2042
|
const reads = target.references.filter((reference) => reference.isRead());
|
|
1859
2043
|
if (reads.length !== 1 || target.references.some((reference) => reference.isWrite() && !reference.init)) return;
|
|
1860
2044
|
const read = reads[0];
|
|
1861
2045
|
if (read === void 0 || read.from.variableScope !== scope.variableScope) return;
|
|
1862
2046
|
const property = read.identifier.parent;
|
|
1863
|
-
if (property.type !==
|
|
1864
|
-
context.report({ node, messageId: "redundantAlias", data: { source: node.init.name, target: node.id.name } });
|
|
2047
|
+
if (property.type !== import_utils20.AST_NODE_TYPES.Property || !property.shorthand || property.value !== read.identifier || property.parent.type !== import_utils20.AST_NODE_TYPES.ObjectExpression || property.computed || property.method || property.kind !== "init") return;
|
|
2048
|
+
context.report({ node, messageId: "redundantAlias", fix: hasModuleSyntax ? closedPrimitiveReturnFix(context.sourceCode, node, property, source, target) : null, data: { source: node.init.name, target: node.id.name } });
|
|
1865
2049
|
}
|
|
1866
2050
|
};
|
|
1867
2051
|
}
|
|
1868
2052
|
});
|
|
1869
2053
|
|
|
1870
2054
|
// src/rules/no-test-comments.ts
|
|
1871
|
-
var
|
|
2055
|
+
var import_utils23 = require("@typescript-eslint/utils");
|
|
1872
2056
|
|
|
1873
2057
|
// src/rules/_comments.ts
|
|
1874
|
-
var
|
|
2058
|
+
var import_utils21 = require("@typescript-eslint/utils");
|
|
1875
2059
|
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/;
|
|
1876
2060
|
var VERSION_RE = /(?:>=|<=|==|<|>)\s*v?\d+\.\d+|\bv\d+\.\d+|\b(?:since|until|as of)\s+(?:v?\d+\.\d+|Python\s*\d)/i;
|
|
1877
2061
|
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/;
|
|
@@ -1957,10 +2141,10 @@ var NARRATION_MAX_WORDS = 6;
|
|
|
1957
2141
|
var NARRATION_MIN_CONTENT = 1;
|
|
1958
2142
|
var TOKEN_PLURAL_MIN = 4;
|
|
1959
2143
|
var RESTATABLE_STATEMENTS = /* @__PURE__ */ new Set([
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
2144
|
+
import_utils21.AST_NODE_TYPES.ExpressionStatement,
|
|
2145
|
+
import_utils21.AST_NODE_TYPES.ReturnStatement,
|
|
2146
|
+
import_utils21.AST_NODE_TYPES.ThrowStatement,
|
|
2147
|
+
import_utils21.AST_NODE_TYPES.VariableDeclaration
|
|
1964
2148
|
]);
|
|
1965
2149
|
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;
|
|
1966
2150
|
var NARRATION_STOPWORDS = /* @__PURE__ */ new Set([
|
|
@@ -2019,12 +2203,12 @@ function restatableStatementBelow(comment, sourceCode) {
|
|
|
2019
2203
|
function restatableStatementNodeBelow(comment, sourceCode) {
|
|
2020
2204
|
const token = sourceCode.getTokenAfter(comment, { includeComments: false });
|
|
2021
2205
|
if (token === null || token.loc.start.line !== comment.loc.end.line + 1) return null;
|
|
2022
|
-
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !==
|
|
2206
|
+
for (let node = sourceCode.getNodeByRangeIndex(token.range[0]); node != null && node.type !== import_utils21.AST_NODE_TYPES.Program; node = node.parent) {
|
|
2023
2207
|
if (!RESTATABLE_STATEMENTS.has(node.type)) continue;
|
|
2024
2208
|
if (node.loc.start.line !== token.loc.start.line || node.loc.end.line !== node.loc.start.line) {
|
|
2025
2209
|
return null;
|
|
2026
2210
|
}
|
|
2027
|
-
if (node.type ===
|
|
2211
|
+
if (node.type === import_utils21.AST_NODE_TYPES.VariableDeclaration && isTrivialInitializer(node)) {
|
|
2028
2212
|
return null;
|
|
2029
2213
|
}
|
|
2030
2214
|
return node;
|
|
@@ -2034,8 +2218,8 @@ function restatableStatementNodeBelow(comment, sourceCode) {
|
|
|
2034
2218
|
function isTrivialInitializer(node) {
|
|
2035
2219
|
return node.declarations.every((declarator) => {
|
|
2036
2220
|
const init = declarator.init;
|
|
2037
|
-
if (init == null || init.type ===
|
|
2038
|
-
return init.type ===
|
|
2221
|
+
if (init == null || init.type === import_utils21.AST_NODE_TYPES.Literal) return true;
|
|
2222
|
+
return init.type === import_utils21.AST_NODE_TYPES.ArrayExpression && init.elements.length === 0 || init.type === import_utils21.AST_NODE_TYPES.ObjectExpression && init.properties.length === 0;
|
|
2039
2223
|
});
|
|
2040
2224
|
}
|
|
2041
2225
|
function restatesStatementHead(body3, statement) {
|
|
@@ -2062,7 +2246,7 @@ function headTokens(source) {
|
|
|
2062
2246
|
}
|
|
2063
2247
|
|
|
2064
2248
|
// src/rules/_comment-edits.ts
|
|
2065
|
-
var
|
|
2249
|
+
var import_utils22 = require("@typescript-eslint/utils");
|
|
2066
2250
|
function physicalLineEnd(text, offset) {
|
|
2067
2251
|
const newline = text.indexOf("\n", offset);
|
|
2068
2252
|
return newline < 0 ? text.length : newline;
|
|
@@ -2096,7 +2280,11 @@ function trailingCommentRemovalRange(text, comment) {
|
|
|
2096
2280
|
return { range: [start, contentEnd] };
|
|
2097
2281
|
}
|
|
2098
2282
|
function commentLineEndings(text, removal) {
|
|
2099
|
-
|
|
2283
|
+
const replacement = text.slice(...removal.range).replace(/[^\r\n\u2028\u2029]/gu, "");
|
|
2284
|
+
const neighbor = Math.max(0, removal.range[0] - 1);
|
|
2285
|
+
const original = text.slice(neighbor, removal.range[1] + 1).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
2286
|
+
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) ?? [];
|
|
2287
|
+
return original.length === rendered.length && original.every((ending, index) => ending === rendered[index]) ? replacement : null;
|
|
2100
2288
|
}
|
|
2101
2289
|
function exactMemberCommentRemovalRange(text, comment, key) {
|
|
2102
2290
|
if (key.type !== "Identifier") return null;
|
|
@@ -2126,6 +2314,7 @@ var NO_TEST_COMMENTS_DOCUMENTATION = {
|
|
|
2126
2314
|
]
|
|
2127
2315
|
};
|
|
2128
2316
|
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;
|
|
2317
|
+
var BEHAVIORAL_DIRECTIVE = /(?:[@#]__(?:PURE|NO_SIDE_EFFECTS)__|@vite-ignore\b|\bwebpack(?:ChunkName|Mode|Exports|FetchPriority|Include|Exclude|Prefetch|Preload|Ignore)\s*:)/u;
|
|
2129
2318
|
var LEGAL = /(?:^|\n)\s*\*?\s*(?:Copyright\b|SPDX-License-Identifier:|Licensed under\b|@license\b|@preserve\b)/iu;
|
|
2130
2319
|
var TYPE_CONTRACT = /@(?:type|typedef|template|param|returns?|satisfies|callback|overload|implements|extends|augments|enum|this|import)\b/u;
|
|
2131
2320
|
var DETECT_SECRETS_COMMENT_MARKERS = [
|
|
@@ -2145,12 +2334,13 @@ var PYTHON_EXTRA_WHITESPACE = /* @__PURE__ */ new Set(["", "", "", ""]);
|
|
|
2145
2334
|
function hasDetectSecretsPragma(comment, text) {
|
|
2146
2335
|
if (!comment.value.includes("pragma:")) return false;
|
|
2147
2336
|
let lineStart = Math.max(text.lastIndexOf("\r", comment.range[0] - 1), text.lastIndexOf("\n", comment.range[0] - 1)) + 1;
|
|
2337
|
+
const readerLineEndings = /\r\n?|\n/gu;
|
|
2338
|
+
readerLineEndings.lastIndex = lineStart;
|
|
2148
2339
|
while (lineStart < comment.range[1]) {
|
|
2149
|
-
const
|
|
2150
|
-
const
|
|
2151
|
-
const lineEnd = Math.min(nextCr < 0 ? text.length : nextCr, nextLf < 0 ? text.length : nextLf);
|
|
2340
|
+
const ending = readerLineEndings.exec(text);
|
|
2341
|
+
const lineEnd = ending?.index ?? text.length;
|
|
2152
2342
|
if (hasPragmaInReaderLine(comment, text.slice(lineStart, lineEnd), lineStart)) return true;
|
|
2153
|
-
lineStart = lineEnd + (
|
|
2343
|
+
lineStart = lineEnd + (ending?.[0].length ?? 1);
|
|
2154
2344
|
}
|
|
2155
2345
|
return false;
|
|
2156
2346
|
}
|
|
@@ -2189,7 +2379,7 @@ var no_test_comments_default = createRule({
|
|
|
2189
2379
|
if (!isTestFile(context) || isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
2190
2380
|
const filename = scopedFilename(context);
|
|
2191
2381
|
const unambiguous = /(?:^|\/)(?:tests?|__tests__|fixtures|__fixtures__|__mocks__)\//u.test(filename) || /\.(?:test|spec|e2e|integration)\.[cm]?[jt]sx?$/u.test(filename);
|
|
2192
|
-
const framework = context.sourceCode.ast.body.some((statement) => statement.type ===
|
|
2382
|
+
const framework = context.sourceCode.ast.body.some((statement) => statement.type === import_utils23.AST_NODE_TYPES.ImportDeclaration && statement.importKind !== "type" && (statement.specifiers.length === 0 || statement.specifiers.some((specifier) => specifier.type !== import_utils23.AST_NODE_TYPES.ImportSpecifier || specifier.importKind !== "type")) && ["vitest", "@jest/globals", "@playwright/test", "bun:test", "node:test"].includes(statement.source.value));
|
|
2193
2383
|
if (!unambiguous && !framework) return {};
|
|
2194
2384
|
return {
|
|
2195
2385
|
Program() {
|
|
@@ -2210,26 +2400,35 @@ var no_test_comments_default = createRule({
|
|
|
2210
2400
|
}
|
|
2211
2401
|
for (const [index, comment] of comments.entries()) {
|
|
2212
2402
|
const body3 = comment.value.trim().replace(/^\*\s*/u, "");
|
|
2213
|
-
if (DIRECTIVE.test(body3) || LEGAL.test(comment.value) || legalLines.has(index) || TYPE_CONTRACT.test(comment.value) || hasDetectSecretsPragma(comment, context.sourceCode.text)) continue;
|
|
2403
|
+
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;
|
|
2214
2404
|
context.report({
|
|
2215
2405
|
node: comment,
|
|
2216
2406
|
messageId: "testComment",
|
|
2217
2407
|
fix: (fixer) => {
|
|
2218
2408
|
const text = context.sourceCode.text;
|
|
2409
|
+
const preserveLineTerminators = (edit) => {
|
|
2410
|
+
const neighbor = Math.max(0, edit.range[0] - 1);
|
|
2411
|
+
const original = text.slice(neighbor, edit.range[1] + 1).match(/\r\n|[\r\n\u2028\u2029]/gu) ?? [];
|
|
2412
|
+
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) ?? [];
|
|
2413
|
+
return original.length === rendered.length && original.every((ending, position) => ending === rendered[position]) ? edit : null;
|
|
2414
|
+
};
|
|
2219
2415
|
const own = ownLineCommentRemovalRange(text, comment);
|
|
2220
|
-
if (own !== null)
|
|
2416
|
+
if (own !== null) {
|
|
2417
|
+
const ownEndings = commentLineEndings(text, own);
|
|
2418
|
+
return ownEndings === null ? null : preserveLineTerminators(fixer.replaceTextRange(own.range, ownEndings));
|
|
2419
|
+
}
|
|
2221
2420
|
const trailing = trailingCommentRemovalRange(text, comment);
|
|
2222
|
-
if (trailing !== null) return fixer.replaceTextRange(trailing.range, "");
|
|
2421
|
+
if (trailing !== null) return preserveLineTerminators(fixer.replaceTextRange(trailing.range, ""));
|
|
2223
2422
|
const endings = context.sourceCode.getText(comment).replace(/[^\r\n\u2028\u2029]/gu, "");
|
|
2224
2423
|
if (endings.length > 0) {
|
|
2225
2424
|
let start = comment.range[0];
|
|
2226
2425
|
while (start > 0 && /[\t ]/u.test(text[start - 1] ?? "")) start--;
|
|
2227
|
-
return fixer.replaceTextRange([start, comment.range[1]], endings);
|
|
2426
|
+
return preserveLineTerminators(fixer.replaceTextRange([start, comment.range[1]], endings));
|
|
2228
2427
|
}
|
|
2229
2428
|
const before = text[comment.range[0] - 1] ?? "";
|
|
2230
2429
|
const after = text[comment.range[1]] ?? "";
|
|
2231
2430
|
const separator = before.length > 0 && after.length > 0 && !/\s/u.test(before + after) ? " " : "";
|
|
2232
|
-
return fixer.replaceText(comment, separator);
|
|
2431
|
+
return preserveLineTerminators(fixer.replaceText(comment, separator));
|
|
2233
2432
|
}
|
|
2234
2433
|
});
|
|
2235
2434
|
}
|
|
@@ -2239,14 +2438,14 @@ var no_test_comments_default = createRule({
|
|
|
2239
2438
|
});
|
|
2240
2439
|
|
|
2241
2440
|
// src/rules/no-mutating-container-transform.ts
|
|
2242
|
-
var
|
|
2441
|
+
var import_utils24 = require("@typescript-eslint/utils");
|
|
2243
2442
|
var MUTATORS = /* @__PURE__ */ new Set(["copyWithin", "fill", "pop", "push", "reverse", "shift", "sort", "splice", "unshift"]);
|
|
2244
2443
|
var PRIMITIVES = /* @__PURE__ */ new Set([
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2444
|
+
import_utils24.AST_NODE_TYPES.TSStringKeyword,
|
|
2445
|
+
import_utils24.AST_NODE_TYPES.TSNumberKeyword,
|
|
2446
|
+
import_utils24.AST_NODE_TYPES.TSBooleanKeyword,
|
|
2447
|
+
import_utils24.AST_NODE_TYPES.TSBigIntKeyword,
|
|
2448
|
+
import_utils24.AST_NODE_TYPES.TSSymbolKeyword
|
|
2250
2449
|
]);
|
|
2251
2450
|
var NO_MUTATING_CONTAINER_TRANSFORM_DOCUMENTATION = {
|
|
2252
2451
|
defaultLevel: "warning",
|
|
@@ -2265,27 +2464,27 @@ var NO_MUTATING_CONTAINER_TRANSFORM_DOCUMENTATION = {
|
|
|
2265
2464
|
]
|
|
2266
2465
|
};
|
|
2267
2466
|
function arrayElement(node, sourceCode) {
|
|
2268
|
-
if (node.type ===
|
|
2269
|
-
if (node.type ===
|
|
2467
|
+
if (node.type === import_utils24.AST_NODE_TYPES.TSArrayType) return node.elementType;
|
|
2468
|
+
if (node.type === import_utils24.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils24.AST_NODE_TYPES.Identifier && (node.typeName.name === "Array" || node.typeName.name === "ReadonlyArray") && (import_utils24.ASTUtils.findVariable(sourceCode.getScope(node.typeName), node.typeName.name)?.defs.length ?? 0) === 0 && node.typeArguments?.params.length === 1) return node.typeArguments.params[0] ?? null;
|
|
2270
2469
|
return null;
|
|
2271
2470
|
}
|
|
2272
2471
|
function returnsArray(node, sourceCode) {
|
|
2273
2472
|
let annotation = node.returnType?.typeAnnotation;
|
|
2274
|
-
if (annotation?.type ===
|
|
2473
|
+
if (annotation?.type === import_utils24.AST_NODE_TYPES.TSTypeReference && annotation.typeName.type === import_utils24.AST_NODE_TYPES.Identifier && annotation.typeName.name === "Promise" && (import_utils24.ASTUtils.findVariable(sourceCode.getScope(annotation.typeName), "Promise")?.defs.length ?? 0) === 0 && annotation.typeArguments?.params.length === 1) annotation = annotation.typeArguments.params[0];
|
|
2275
2474
|
return annotation !== void 0 && arrayElement(annotation, sourceCode) !== null;
|
|
2276
2475
|
}
|
|
2277
2476
|
function supported(statements) {
|
|
2278
2477
|
return statements.every((statement) => {
|
|
2279
2478
|
switch (statement.type) {
|
|
2280
|
-
case
|
|
2281
|
-
case
|
|
2282
|
-
case
|
|
2283
|
-
case
|
|
2284
|
-
case
|
|
2479
|
+
case import_utils24.AST_NODE_TYPES.ExpressionStatement:
|
|
2480
|
+
case import_utils24.AST_NODE_TYPES.VariableDeclaration:
|
|
2481
|
+
case import_utils24.AST_NODE_TYPES.ReturnStatement:
|
|
2482
|
+
case import_utils24.AST_NODE_TYPES.ThrowStatement:
|
|
2483
|
+
case import_utils24.AST_NODE_TYPES.EmptyStatement:
|
|
2285
2484
|
return true;
|
|
2286
|
-
case
|
|
2485
|
+
case import_utils24.AST_NODE_TYPES.BlockStatement:
|
|
2287
2486
|
return supported(statement.body);
|
|
2288
|
-
case
|
|
2487
|
+
case import_utils24.AST_NODE_TYPES.IfStatement:
|
|
2289
2488
|
return supported([statement.consequent]) && (statement.alternate === null || supported([statement.alternate]));
|
|
2290
2489
|
default:
|
|
2291
2490
|
return false;
|
|
@@ -2306,13 +2505,13 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2306
2505
|
if (isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
2307
2506
|
const sourceCode = context.sourceCode;
|
|
2308
2507
|
function binding3(node) {
|
|
2309
|
-
return node.type ===
|
|
2508
|
+
return node.type === import_utils24.AST_NODE_TYPES.Identifier ? import_utils24.ASTUtils.findVariable(sourceCode.getScope(node), node.name) : null;
|
|
2310
2509
|
}
|
|
2311
2510
|
function inspect(node) {
|
|
2312
|
-
if (node.body?.type !==
|
|
2511
|
+
if (node.body?.type !== import_utils24.AST_NODE_TYPES.BlockStatement || !returnsArray(node, sourceCode) || !supported(node.body.body)) return;
|
|
2313
2512
|
const initial = /* @__PURE__ */ new Map();
|
|
2314
2513
|
for (const parameter of node.params) {
|
|
2315
|
-
if (parameter.type !==
|
|
2514
|
+
if (parameter.type !== import_utils24.AST_NODE_TYPES.Identifier || parameter.typeAnnotation === void 0) continue;
|
|
2316
2515
|
const element = arrayElement(parameter.typeAnnotation.typeAnnotation, sourceCode);
|
|
2317
2516
|
const variable = binding3(parameter);
|
|
2318
2517
|
if (element !== null && PRIMITIVES.has(element.type) && variable !== null) initial.set(variable, parameter.name);
|
|
@@ -2325,26 +2524,26 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2325
2524
|
}
|
|
2326
2525
|
function expression(current, state) {
|
|
2327
2526
|
switch (current.type) {
|
|
2328
|
-
case
|
|
2329
|
-
case
|
|
2330
|
-
case
|
|
2527
|
+
case import_utils24.AST_NODE_TYPES.FunctionExpression:
|
|
2528
|
+
case import_utils24.AST_NODE_TYPES.ArrowFunctionExpression:
|
|
2529
|
+
case import_utils24.AST_NODE_TYPES.ClassExpression:
|
|
2331
2530
|
return;
|
|
2332
|
-
case
|
|
2531
|
+
case import_utils24.AST_NODE_TYPES.AssignmentExpression:
|
|
2333
2532
|
assignment(current, state);
|
|
2334
2533
|
return;
|
|
2335
|
-
case
|
|
2534
|
+
case import_utils24.AST_NODE_TYPES.LogicalExpression:
|
|
2336
2535
|
logical(current, state);
|
|
2337
2536
|
return;
|
|
2338
|
-
case
|
|
2537
|
+
case import_utils24.AST_NODE_TYPES.ConditionalExpression:
|
|
2339
2538
|
conditional(current, state);
|
|
2340
2539
|
return;
|
|
2341
|
-
case
|
|
2540
|
+
case import_utils24.AST_NODE_TYPES.UpdateExpression:
|
|
2342
2541
|
write(current.argument, state);
|
|
2343
2542
|
break;
|
|
2344
|
-
case
|
|
2543
|
+
case import_utils24.AST_NODE_TYPES.UnaryExpression:
|
|
2345
2544
|
if (current.operator === "delete") write(current.argument, state);
|
|
2346
2545
|
break;
|
|
2347
|
-
case
|
|
2546
|
+
case import_utils24.AST_NODE_TYPES.CallExpression:
|
|
2348
2547
|
mutationCall(current, state);
|
|
2349
2548
|
break;
|
|
2350
2549
|
default:
|
|
@@ -2364,13 +2563,13 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2364
2563
|
function logical(current, state) {
|
|
2365
2564
|
expression(current.left, state);
|
|
2366
2565
|
const left = unwrapExpression(current.left);
|
|
2367
|
-
if (left.type ===
|
|
2566
|
+
if (left.type === import_utils24.AST_NODE_TYPES.Literal && (current.operator === "&&" && !left.value || current.operator === "||" && !!left.value || current.operator === "??" && left.value !== null)) return;
|
|
2368
2567
|
expression(current.right, state);
|
|
2369
2568
|
}
|
|
2370
2569
|
function conditional(current, state) {
|
|
2371
2570
|
expression(current.test, state);
|
|
2372
2571
|
const test = unwrapExpression(current.test);
|
|
2373
|
-
if (test.type ===
|
|
2572
|
+
if (test.type === import_utils24.AST_NODE_TYPES.Literal) {
|
|
2374
2573
|
expression(test.value ? current.consequent : current.alternate, state);
|
|
2375
2574
|
return;
|
|
2376
2575
|
}
|
|
@@ -2378,13 +2577,13 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2378
2577
|
expression(current.alternate, state);
|
|
2379
2578
|
}
|
|
2380
2579
|
function mutationCall(current, state) {
|
|
2381
|
-
if (current.callee.type !==
|
|
2580
|
+
if (current.callee.type !== import_utils24.AST_NODE_TYPES.MemberExpression || !MUTATORS.has(import_utils24.ASTUtils.getPropertyName(current.callee) ?? "")) return;
|
|
2382
2581
|
const parameter = origin(current.callee.object, state);
|
|
2383
2582
|
if (parameter !== void 0 && first === null) first = { node: current, parameter };
|
|
2384
2583
|
}
|
|
2385
2584
|
function write(target, state) {
|
|
2386
2585
|
target = unwrapExpression(target);
|
|
2387
|
-
if (target.type !==
|
|
2586
|
+
if (target.type !== import_utils24.AST_NODE_TYPES.MemberExpression || !target.computed && import_utils24.ASTUtils.getPropertyName(target) !== "length") return;
|
|
2388
2587
|
const parameter = origin(target.object, state);
|
|
2389
2588
|
if (parameter !== void 0 && first === null) first = { node: target, parameter };
|
|
2390
2589
|
}
|
|
@@ -2394,18 +2593,18 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2394
2593
|
}
|
|
2395
2594
|
function statement(current, state) {
|
|
2396
2595
|
switch (current.type) {
|
|
2397
|
-
case
|
|
2596
|
+
case import_utils24.AST_NODE_TYPES.BlockStatement:
|
|
2398
2597
|
return statements(current.body, state);
|
|
2399
|
-
case
|
|
2598
|
+
case import_utils24.AST_NODE_TYPES.IfStatement:
|
|
2400
2599
|
return branch(current, state);
|
|
2401
|
-
case
|
|
2600
|
+
case import_utils24.AST_NODE_TYPES.VariableDeclaration:
|
|
2402
2601
|
declarations(current, state);
|
|
2403
2602
|
return false;
|
|
2404
|
-
case
|
|
2405
|
-
case
|
|
2603
|
+
case import_utils24.AST_NODE_TYPES.ReturnStatement:
|
|
2604
|
+
case import_utils24.AST_NODE_TYPES.ThrowStatement:
|
|
2406
2605
|
if (current.argument !== null) expression(current.argument, state);
|
|
2407
2606
|
return true;
|
|
2408
|
-
case
|
|
2607
|
+
case import_utils24.AST_NODE_TYPES.ExpressionStatement:
|
|
2409
2608
|
expression(current.expression, state);
|
|
2410
2609
|
return false;
|
|
2411
2610
|
default:
|
|
@@ -2414,7 +2613,7 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2414
2613
|
}
|
|
2415
2614
|
function branch(current, state) {
|
|
2416
2615
|
expression(current.test, state);
|
|
2417
|
-
if (current.test.type ===
|
|
2616
|
+
if (current.test.type === import_utils24.AST_NODE_TYPES.Literal) return current.test.value ? statements([current.consequent], state) : current.alternate !== null && statements([current.alternate], state);
|
|
2418
2617
|
const left = new Map(state);
|
|
2419
2618
|
const right = new Map(state);
|
|
2420
2619
|
const leftEnds = statements([current.consequent], left);
|
|
@@ -2446,7 +2645,7 @@ var no_mutating_container_transform_default = createRule({
|
|
|
2446
2645
|
});
|
|
2447
2646
|
|
|
2448
2647
|
// src/rules/no-redundant-consumer-union.ts
|
|
2449
|
-
var
|
|
2648
|
+
var import_utils27 = require("@typescript-eslint/utils");
|
|
2450
2649
|
var import_typescript7 = __toESM(require("typescript"), 1);
|
|
2451
2650
|
|
|
2452
2651
|
// src/rules/_checked-native-source.ts
|
|
@@ -2557,109 +2756,13 @@ function finiteMember(member3, checker) {
|
|
|
2557
2756
|
}
|
|
2558
2757
|
|
|
2559
2758
|
// src/rules/_private-consumer-fix.ts
|
|
2560
|
-
var
|
|
2759
|
+
var import_utils25 = require("@typescript-eslint/utils");
|
|
2561
2760
|
var import_typescript3 = __toESM(require("typescript"), 1);
|
|
2562
|
-
|
|
2563
|
-
// src/rules/_type-binding.ts
|
|
2564
|
-
var import_utils23 = require("@typescript-eslint/utils");
|
|
2565
|
-
function typeBinding(source, identifier) {
|
|
2566
|
-
let scope = source.getScope(identifier);
|
|
2567
|
-
while (scope !== null) {
|
|
2568
|
-
const variable = scope.set.get(identifier.name);
|
|
2569
|
-
if (variable !== void 0 && (variable.isTypeVariable || variable.defs.some((definition) => definition.isTypeDefinition))) {
|
|
2570
|
-
return variable;
|
|
2571
|
-
}
|
|
2572
|
-
scope = scope.upper;
|
|
2573
|
-
}
|
|
2574
|
-
return null;
|
|
2575
|
-
}
|
|
2576
|
-
var REFERENCE_INDEXES = /* @__PURE__ */ new WeakMap();
|
|
2577
|
-
function retainsNamedTypeUses(source, removed) {
|
|
2578
|
-
const manager = source.scopeManager;
|
|
2579
|
-
if (manager === null) return false;
|
|
2580
|
-
const index = referenceIndex(source, manager);
|
|
2581
|
-
for (const reference of referencesWithin(index.references, removed)) {
|
|
2582
|
-
if (!reference.isRead()) continue;
|
|
2583
|
-
const binding3 = reference.resolved;
|
|
2584
|
-
if (!binding3 || !reference.isTypeReference && !reference.isValueReference) return false;
|
|
2585
|
-
if (binding3.defs.length === 0) continue;
|
|
2586
|
-
const reads = publicReadExtents(index, binding3);
|
|
2587
|
-
const extent = reference.isTypeReference ? reference.isValueReference ? reads.both : reads.type : reads.value;
|
|
2588
|
-
if (extent === null || extent.minStart >= removed.range[0] && extent.maxEnd <= removed.range[1]) return false;
|
|
2589
|
-
}
|
|
2590
|
-
return true;
|
|
2591
|
-
}
|
|
2592
|
-
function referenceIndex(source, manager) {
|
|
2593
|
-
const cached = REFERENCE_INDEXES.get(source);
|
|
2594
|
-
if (cached?.manager === manager) return cached;
|
|
2595
|
-
const references = manager.scopes.flatMap((scope) => scope.references);
|
|
2596
|
-
references.sort((left, right) => left.identifier.range[0] - right.identifier.range[0]);
|
|
2597
|
-
const index = { manager, references, publicReads: /* @__PURE__ */ new Map() };
|
|
2598
|
-
REFERENCE_INDEXES.set(source, index);
|
|
2599
|
-
return index;
|
|
2600
|
-
}
|
|
2601
|
-
function* referencesWithin(references, removed) {
|
|
2602
|
-
let low = 0;
|
|
2603
|
-
let high = references.length;
|
|
2604
|
-
while (low < high) {
|
|
2605
|
-
const middle = low + Math.floor((high - low) / 2);
|
|
2606
|
-
const reference = references[middle];
|
|
2607
|
-
if (reference === void 0 || reference.identifier.range[0] >= removed.range[0]) high = middle;
|
|
2608
|
-
else low = middle + 1;
|
|
2609
|
-
}
|
|
2610
|
-
for (let index = low; index < references.length; index++) {
|
|
2611
|
-
const reference = references[index];
|
|
2612
|
-
if (reference === void 0) continue;
|
|
2613
|
-
if (reference.identifier.range[0] > removed.range[1]) break;
|
|
2614
|
-
if (insideTypeRange(reference.identifier, removed)) yield reference;
|
|
2615
|
-
}
|
|
2616
|
-
}
|
|
2617
|
-
function publicReadExtents(index, binding3) {
|
|
2618
|
-
const cached = index.publicReads.get(binding3);
|
|
2619
|
-
if (cached !== void 0) return cached;
|
|
2620
|
-
let type = null;
|
|
2621
|
-
let value = null;
|
|
2622
|
-
let both = null;
|
|
2623
|
-
for (const retained of binding3.references) {
|
|
2624
|
-
if (!retained.isRead() || !retained.isTypeReference && !retained.isValueReference || binding3.defs.some((definition) => insideTypeRange(retained.identifier, definition.node)) || !publicTypeUse(retained.identifier)) continue;
|
|
2625
|
-
if (retained.isTypeReference) type = extendExtent(type, retained.identifier);
|
|
2626
|
-
if (retained.isValueReference) value = extendExtent(value, retained.identifier);
|
|
2627
|
-
if (retained.isTypeReference && retained.isValueReference) both = extendExtent(both, retained.identifier);
|
|
2628
|
-
}
|
|
2629
|
-
const result = { type, value, both };
|
|
2630
|
-
index.publicReads.set(binding3, result);
|
|
2631
|
-
return result;
|
|
2632
|
-
}
|
|
2633
|
-
function extendExtent(extent, identifier) {
|
|
2634
|
-
return {
|
|
2635
|
-
minStart: Math.min(extent?.minStart ?? identifier.range[0], identifier.range[0]),
|
|
2636
|
-
maxEnd: Math.max(extent?.maxEnd ?? identifier.range[1], identifier.range[1])
|
|
2637
|
-
};
|
|
2638
|
-
}
|
|
2639
|
-
function publicTypeUse(identifier) {
|
|
2640
|
-
let node = identifier;
|
|
2641
|
-
while (node.parent) {
|
|
2642
|
-
if (node.type === import_utils23.AST_NODE_TYPES.TSTypeAnnotation || node.type === import_utils23.AST_NODE_TYPES.TSTypePredicate || node.type === import_utils23.AST_NODE_TYPES.TSAsExpression || node.type === import_utils23.AST_NODE_TYPES.TSTypeAssertion) return false;
|
|
2643
|
-
if (node.type === import_utils23.AST_NODE_TYPES.TSTypeAliasDeclaration) {
|
|
2644
|
-
return node.parent.type === import_utils23.AST_NODE_TYPES.ExportNamedDeclaration && node.parent.declaration === node && node.parent.parent.type === import_utils23.AST_NODE_TYPES.Program;
|
|
2645
|
-
}
|
|
2646
|
-
if (node.type === import_utils23.AST_NODE_TYPES.ExportSpecifier) {
|
|
2647
|
-
return node.parent.type === import_utils23.AST_NODE_TYPES.ExportNamedDeclaration && node.parent.source === null && node.parent.parent.type === import_utils23.AST_NODE_TYPES.Program;
|
|
2648
|
-
}
|
|
2649
|
-
node = node.parent;
|
|
2650
|
-
}
|
|
2651
|
-
return false;
|
|
2652
|
-
}
|
|
2653
|
-
function insideTypeRange(node, range) {
|
|
2654
|
-
return node.range[0] >= range.range[0] && node.range[1] <= range.range[1];
|
|
2655
|
-
}
|
|
2656
|
-
|
|
2657
|
-
// src/rules/_private-consumer-fix.ts
|
|
2658
2761
|
var UNSAFE = import_typescript3.default.TypeFlags.Any | import_typescript3.default.TypeFlags.Unknown | import_typescript3.default.TypeFlags.Never | import_typescript3.default.TypeFlags.TypeParameter | import_typescript3.default.TypeFlags.Conditional | import_typescript3.default.TypeFlags.IndexedAccess | import_typescript3.default.TypeFlags.Substitution;
|
|
2659
2762
|
function validConsumerFixCalls(node, parameter, sourceCode, services) {
|
|
2660
2763
|
if (sourceCode.getAllComments().some((comment) => /@ts-(?:expect-error|ignore|nocheck)\b/u.test(comment.value))) return false;
|
|
2661
|
-
const owner = node.type ===
|
|
2662
|
-
if (owner.type !==
|
|
2764
|
+
const owner = node.type === import_utils25.AST_NODE_TYPES.FunctionDeclaration ? node : node.parent;
|
|
2765
|
+
if (owner.type !== import_utils25.AST_NODE_TYPES.FunctionDeclaration && owner.type !== import_utils25.AST_NODE_TYPES.VariableDeclarator) return false;
|
|
2663
2766
|
const binding3 = sourceCode.getDeclaredVariables(owner).find((variable) => variable.defs.some((definition) => definition.node === owner && (definition.type === "FunctionName" || definition.type === "Variable")));
|
|
2664
2767
|
if (!binding3) return false;
|
|
2665
2768
|
const declaration = services.esTreeNodeToTSNodeMap.get(node);
|
|
@@ -2695,7 +2798,7 @@ function validConsumerFixCalls(node, parameter, sourceCode, services) {
|
|
|
2695
2798
|
continue;
|
|
2696
2799
|
}
|
|
2697
2800
|
const call = reference.identifier.parent;
|
|
2698
|
-
if (reference.isTypeReference || !reference.isReadOnly() || call.type !==
|
|
2801
|
+
if (reference.isTypeReference || !reference.isReadOnly() || call.type !== import_utils25.AST_NODE_TYPES.CallExpression || call.callee !== reference.identifier || call.optional || call.typeArguments || call.arguments.length !== declaration.parameters.length || !call.arguments.every((argument) => argument.type === import_utils25.AST_NODE_TYPES.Identifier) || !validArguments(call)) return false;
|
|
2699
2802
|
calls += 1;
|
|
2700
2803
|
}
|
|
2701
2804
|
return calls > 0;
|
|
@@ -2747,7 +2850,7 @@ function minimalConsumerFix(sourceCode, annotation, removed) {
|
|
|
2747
2850
|
}
|
|
2748
2851
|
|
|
2749
2852
|
// src/rules/_private-scalar-consumer.ts
|
|
2750
|
-
var
|
|
2853
|
+
var import_utils26 = require("@typescript-eslint/utils");
|
|
2751
2854
|
var import_typescript6 = __toESM(require("typescript"), 1);
|
|
2752
2855
|
|
|
2753
2856
|
// src/rules/_scalar-parameter-view.ts
|
|
@@ -2897,8 +3000,8 @@ function intrinsicAttribute(attribute, view) {
|
|
|
2897
3000
|
// src/rules/_private-scalar-consumer.ts
|
|
2898
3001
|
function directEval(node) {
|
|
2899
3002
|
let callee = unwrapExpression(node.callee);
|
|
2900
|
-
while (callee.type ===
|
|
2901
|
-
return callee.type ===
|
|
3003
|
+
while (callee.type === import_utils26.AST_NODE_TYPES.TSInstantiationExpression) callee = unwrapExpression(callee.expression);
|
|
3004
|
+
return callee.type === import_utils26.AST_NODE_TYPES.Identifier && callee.name === "eval";
|
|
2902
3005
|
}
|
|
2903
3006
|
function primitiveKeyword(node) {
|
|
2904
3007
|
return node !== void 0 && (node.kind === import_typescript6.default.SyntaxKind.StringKeyword || node.kind === import_typescript6.default.SyntaxKind.NumberKeyword || node.kind === import_typescript6.default.SyntaxKind.BooleanKeyword || node.kind === import_typescript6.default.SyntaxKind.BigIntKeyword);
|
|
@@ -2911,16 +3014,16 @@ function consumerAnnotation(node, auxiliaryScalars = false) {
|
|
|
2911
3014
|
if (!auxiliaryScalars) return void 0;
|
|
2912
3015
|
let annotation;
|
|
2913
3016
|
for (const parameter2 of node.params) {
|
|
2914
|
-
if (parameter2.type !==
|
|
3017
|
+
if (parameter2.type !== import_utils26.AST_NODE_TYPES.Identifier && parameter2.type !== import_utils26.AST_NODE_TYPES.ObjectPattern) continue;
|
|
2915
3018
|
const current = parameter2.typeAnnotation?.typeAnnotation;
|
|
2916
|
-
if (current?.type !==
|
|
3019
|
+
if (current?.type !== import_utils26.AST_NODE_TYPES.TSTypeLiteral) continue;
|
|
2917
3020
|
if (annotation) return void 0;
|
|
2918
3021
|
annotation = current;
|
|
2919
3022
|
}
|
|
2920
3023
|
return annotation;
|
|
2921
3024
|
}
|
|
2922
3025
|
const parameter = node.params[0];
|
|
2923
|
-
return parameter?.type ===
|
|
3026
|
+
return parameter?.type === import_utils26.AST_NODE_TYPES.Identifier || parameter?.type === import_utils26.AST_NODE_TYPES.ObjectPattern ? parameter.typeAnnotation?.typeAnnotation : void 0;
|
|
2924
3027
|
}
|
|
2925
3028
|
function exportedSymbols(source, checker) {
|
|
2926
3029
|
const symbol = checker.getSymbolAtLocation(source);
|
|
@@ -2970,12 +3073,12 @@ function auxiliaryBindings(native, selected, checker) {
|
|
|
2970
3073
|
return bindings;
|
|
2971
3074
|
}
|
|
2972
3075
|
function callableBinding(node, sourceCode) {
|
|
2973
|
-
if (node.type ===
|
|
2974
|
-
if (node.parent.type !==
|
|
3076
|
+
if (node.type === import_utils26.AST_NODE_TYPES.FunctionDeclaration) {
|
|
3077
|
+
if (node.parent.type !== import_utils26.AST_NODE_TYPES.Program) return void 0;
|
|
2975
3078
|
return sourceCode.getDeclaredVariables(node).find((variable) => variable.defs.some((definition) => definition.type === "FunctionName" && definition.node === node));
|
|
2976
3079
|
}
|
|
2977
3080
|
const declaration = node.parent;
|
|
2978
|
-
if (declaration.type !==
|
|
3081
|
+
if (declaration.type !== import_utils26.AST_NODE_TYPES.VariableDeclarator || declaration.init !== node || declaration.id.type !== import_utils26.AST_NODE_TYPES.Identifier || declaration.id.typeAnnotation || declaration.parent.kind !== "const" || declaration.parent.parent.type !== import_utils26.AST_NODE_TYPES.Program) return void 0;
|
|
2979
3082
|
return sourceCode.getDeclaredVariables(declaration).find((variable) => variable.defs.some((definition) => definition.type === "Variable" && definition.node === declaration));
|
|
2980
3083
|
}
|
|
2981
3084
|
function directCalls(binding3, arity) {
|
|
@@ -2983,7 +3086,7 @@ function directCalls(binding3, arity) {
|
|
|
2983
3086
|
const stable2 = stableValueBinding(binding3, (reference) => {
|
|
2984
3087
|
const identifier = reference.identifier;
|
|
2985
3088
|
const call = identifier.parent;
|
|
2986
|
-
if (reference.isTypeReference || !reference.isReadOnly() || call.type !==
|
|
3089
|
+
if (reference.isTypeReference || !reference.isReadOnly() || call.type !== import_utils26.AST_NODE_TYPES.CallExpression || call.callee !== identifier || call.optional || call.typeArguments || call.arguments.length !== arity || !call.arguments.every((argument) => argument.type === import_utils26.AST_NODE_TYPES.Identifier)) return false;
|
|
2987
3090
|
calls += 1;
|
|
2988
3091
|
return true;
|
|
2989
3092
|
});
|
|
@@ -2995,6 +3098,8 @@ var CONFIG = { path: "tsconfig.json", source: '{"compilerOptions":{"strict":true
|
|
|
2995
3098
|
var EXAMPLE = 'export {}; interface Animal {readonly name: string} interface Dog extends Animal {readonly breed: string} export type KeptDog = Dog; const dog: Dog = {name: "Ada", breed: "Collie"}; function label(value: Dog | Animal): string {return value.name;} label(dog);';
|
|
2996
3099
|
var NULLABLE_EXAMPLE = EXAMPLE.replace("readonly name: string", "readonly name: string | null").replace("return value.name;", "return value.name ?? '';");
|
|
2997
3100
|
var OPTIONAL_EXAMPLE = EXAMPLE.replace("readonly breed: string", "readonly breed?: string");
|
|
3101
|
+
var SCALAR_HELPER_EXAMPLE = EXAMPLE.replace("return value.name;", "return formatName(value.name);").replace("function label", "function formatName(value: string): string {return '[' + value + ']';} function label");
|
|
3102
|
+
var WHOLE_OBJECT_HELPER_EXAMPLE = EXAMPLE.replace("return value.name;", "return formatAnimal(value);").replace("function label", "function formatAnimal(value: Animal): string {return value.name;} function label");
|
|
2998
3103
|
var NO_REDUNDANT_CONSUMER_UNION_DOCUMENTATION = {
|
|
2999
3104
|
defaultLevel: "warning",
|
|
3000
3105
|
summary: "Keep the covering object contract in a private scalar consumer union.",
|
|
@@ -3004,12 +3109,15 @@ var NO_REDUNDANT_CONSUMER_UNION_DOCUMENTATION = {
|
|
|
3004
3109
|
autofix: "safe",
|
|
3005
3110
|
limitations: [
|
|
3006
3111
|
"Automatic fixes additionally require every existing identifier caller to be natively assignable to the original contract, without Any, unknown, error or unresolved types on the relevant surface. Comments inside the annotation and TypeScript suppression directives keep the finding manual. Removed named types/imports must retain an independent top-level exported type-alias or direct type-export read. Other removable annotations/assertions, the covering annotation and own-definition/self references cannot keep one another live; otherwise simultaneous fixes can introduce unused-type errors. The exact authored covering type and terminator token sequence are retained; edits that would merge distinct CR and LF terminators remain manual; no producer, call or function body is rewritten.",
|
|
3007
|
-
"Only an inline binary parameter union in a strict module's top-level private scalar consumer is supported. Exactly one parameter, an explicit broad primitive return annotation, a single
|
|
3112
|
+
"Only an inline binary parameter union in a strict module's top-level private scalar consumer is supported. Exactly one parameter, an explicit broad primitive return annotation, a single supported returned scalar expression and direct identifier-argument callers are required. Type queries or type-only exports of the callable, public APIs, callbacks, contextual signatures, overloads, generics, decorators, async functions, direct eval and fresh-object callers prevent findings.",
|
|
3113
|
+
"Scalar values may pass through one implemented same-file top-level function or raw const-arrow helper with an explicit scalar return annotation and the exact native resolved signature. Every argument must already satisfy the scalar read view; the containing source must pass the existing native checked-source proof. Imported, ambient, aliased, overloaded, generic or contextually typed helpers, member calls, optional calls, spread arguments and whole-object arguments remain unsupported. Helper permission does not add auxiliary consumer parameters or replace the required object-field read anchor. Helper bodies need not be pure because no call or body is rewritten.",
|
|
3008
3114
|
"Both alternatives must have complete ordinary finite structural surfaces consisting only of explicitly readonly broad string, number, boolean or bigint properties, optionally paired directly with null or undefined in an exact two-part union. Required and optional nullable fields may be read under the same native coverage proof. Every field must have one actual declaration origin throughout each alternative's inheritance/intersection graph. Shared ancestors retain that origin; repeated merged fields, explicit overrides and independently declared overlapping fields abstain, including valid compatible declarations. This excludes recovered conflicting properties without claiming whole-source health. Aliases, imports, re-exports and ordinary inheritance are resolved by the parser-owned TypeScript checker. Any, unknown, missing imports, open/generic/mapped/indexed types, classes, brands, literal discriminants, methods, properties with scalar type aliases, parenthesized or more complex property unions, callbacks and recursive or nested object fields are unsupported.",
|
|
3009
3115
|
"Reports proper native assignability, where covered is assignable to covering and the reverse is false, or mutual native assignability with a strict smaller declared covering surface and only optional covered-only members. Every covering member, including optional members, must exist in the covered type's enumerated declared surface. Otherwise an existing identifier may carry an incompatible extra field and be rejected after simplification; implicit Object members containing Any cannot replace explicit declared coverage or the native Optional requirement. The covering type must declare every read field and a read required field; an all-optional reduced contract can reject existing callers. Identical alternatives and primitive/top/bottom redundancy remain upstream-owned; equal-key and incomparable mutually assignable structures are excluded. The mutual case additionally requires inline contracts or locally bound interfaces/type aliases whose alias and heritage references can be traced through the parser-owned type scope. Merged interface fragments must all resolve to the reference's same native symbol; mixed exported/local recovery abstains. Imported, global and qualified-namespace references in that path abstain; proper one-way coverage retains its existing alias/import support.",
|
|
3010
|
-
"General union simplification can change Extract, conditional types, in-narrowing, fresh-literal checking and public presentation. Those contexts are excluded even when ordinary assignment succeeds. Flat destructuring counts every bound field as read; whole-object escape, mutation,
|
|
3116
|
+
"General union simplification can change Extract, conditional types, in-narrowing, fresh-literal checking and public presentation. Those contexts are excluded even when ordinary assignment succeeds. Flat destructuring counts every bound field as read; whole-object escape, mutation, unproved helper calls, closures, reflection, serialization, dynamic reads, implicit Object capabilities and JSX prevent findings. Imported Python protocol assignability is not approximated by this rule."
|
|
3011
3117
|
],
|
|
3012
3118
|
examples: [
|
|
3119
|
+
{ id: "local-scalar-helper", scenarioId: "local-scalar-helper", title: "A local helper receives only the required name", outcome: "match", files: [{ path: "src/case.ts", source: SCALAR_HELPER_EXAMPLE }, CONFIG], focusPath: "src/case.ts", expectedCount: 1, public: true, fixedFiles: [{ path: "src/case.ts", source: SCALAR_HELPER_EXAMPLE.replace("Dog | Animal", "Animal") }] },
|
|
3120
|
+
{ id: "whole-object-helper", scenarioId: "local-scalar-helper", title: "Passing the whole object remains outside the scalar helper proof", outcome: "no-match", files: [{ path: "src/case.ts", source: WHOLE_OBJECT_HELPER_EXAMPLE }, CONFIG], focusPath: "src/case.ts", expectedCount: 0, public: true },
|
|
3013
3121
|
{ id: "covered-alternative", title: "The private consumer needs the covering Animal contract", outcome: "match", files: [{ path: "src/case.ts", source: EXAMPLE }, CONFIG], focusPath: "src/case.ts", expectedCount: 1, public: true, fixedFiles: [{ path: "src/case.ts", source: EXAMPLE.replace("Dog | Animal", "Animal") }] },
|
|
3014
3122
|
{ id: "public-contract", title: "A public union retains its observable alternatives", outcome: "no-match", files: [{ path: "src/case.ts", source: EXAMPLE.replace("function label", "export function label") }, CONFIG], focusPath: "src/case.ts", expectedCount: 0, public: true },
|
|
3015
3123
|
{ id: "optional-covered-alternative", scenarioId: "optional-readonly-contract", title: "An unread optional breed retains the smaller Animal surface", outcome: "match", files: [{ path: "src/case.ts", source: OPTIONAL_EXAMPLE }, CONFIG], focusPath: "src/case.ts", expectedCount: 1, public: true, fixedFiles: [{ path: "src/case.ts", source: OPTIONAL_EXAMPLE.replace("Dog | Animal", "Animal") }] },
|
|
@@ -3043,13 +3151,13 @@ function localContractBindings(roots, source, services) {
|
|
|
3043
3151
|
}
|
|
3044
3152
|
function localContractReferences(node, source, services) {
|
|
3045
3153
|
switch (node.type) {
|
|
3046
|
-
case
|
|
3154
|
+
case import_utils27.AST_NODE_TYPES.TSTypeLiteral:
|
|
3047
3155
|
return [];
|
|
3048
|
-
case
|
|
3156
|
+
case import_utils27.AST_NODE_TYPES.TSIntersectionType:
|
|
3049
3157
|
return node.types;
|
|
3050
|
-
case
|
|
3051
|
-
return !node.typeArguments && node.typeName.type ===
|
|
3052
|
-
case
|
|
3158
|
+
case import_utils27.AST_NODE_TYPES.TSTypeReference:
|
|
3159
|
+
return !node.typeArguments && node.typeName.type === import_utils27.AST_NODE_TYPES.Identifier ? [node.typeName] : null;
|
|
3160
|
+
case import_utils27.AST_NODE_TYPES.Identifier:
|
|
3053
3161
|
return localBindingReferences(node, source, services);
|
|
3054
3162
|
default:
|
|
3055
3163
|
return null;
|
|
@@ -3059,8 +3167,8 @@ function localBindingReferences(identifier, source, services) {
|
|
|
3059
3167
|
const definitions2 = typeBinding(source, identifier)?.defs.filter((definition) => definition.isTypeDefinition).map((definition) => definition.node);
|
|
3060
3168
|
if (!definitions2?.length || !definitions2.every(moduleTypeDeclaration)) return null;
|
|
3061
3169
|
const first = definitions2[0];
|
|
3062
|
-
if (definitions2.length === 1 && first?.type ===
|
|
3063
|
-
const interfaces = definitions2.filter((definition) => definition.type ===
|
|
3170
|
+
if (definitions2.length === 1 && first?.type === import_utils27.AST_NODE_TYPES.TSTypeAliasDeclaration && !first.typeParameters) return [first.typeAnnotation];
|
|
3171
|
+
const interfaces = definitions2.filter((definition) => definition.type === import_utils27.AST_NODE_TYPES.TSInterfaceDeclaration);
|
|
3064
3172
|
if (interfaces.length !== definitions2.length || interfaces.some((declaration) => declaration.typeParameters)) return null;
|
|
3065
3173
|
if (interfaces.length > 1) {
|
|
3066
3174
|
const checker = services.program.getTypeChecker();
|
|
@@ -3068,13 +3176,13 @@ function localBindingReferences(identifier, source, services) {
|
|
|
3068
3176
|
if (!symbol || interfaces.some((declaration) => checker.getSymbolAtLocation(services.esTreeNodeToTSNodeMap.get(declaration.id)) !== symbol)) return null;
|
|
3069
3177
|
}
|
|
3070
3178
|
const bases = interfaces.flatMap((declaration) => declaration.extends.map((base) => base.expression));
|
|
3071
|
-
return bases.every((base) => base.type ===
|
|
3179
|
+
return bases.every((base) => base.type === import_utils27.AST_NODE_TYPES.Identifier) ? bases : null;
|
|
3072
3180
|
}
|
|
3073
3181
|
function moduleTypeDeclaration(node) {
|
|
3074
3182
|
const parent = node.parent;
|
|
3075
|
-
if (parent?.type ===
|
|
3076
|
-
if (parent?.type !==
|
|
3077
|
-
return parent.parent.type ===
|
|
3183
|
+
if (parent?.type === import_utils27.AST_NODE_TYPES.Program) return true;
|
|
3184
|
+
if (parent?.type !== import_utils27.AST_NODE_TYPES.ExportNamedDeclaration && parent?.type !== import_utils27.AST_NODE_TYPES.ExportDefaultDeclaration) return false;
|
|
3185
|
+
return parent.parent.type === import_utils27.AST_NODE_TYPES.Program;
|
|
3078
3186
|
}
|
|
3079
3187
|
function coveringAlternative(leftNode, rightNode, checker, fieldsOf, reads) {
|
|
3080
3188
|
const left = checker.getTypeFromTypeNode(leftNode);
|
|
@@ -3109,7 +3217,7 @@ var no_redundant_consumer_union_default = createRule({
|
|
|
3109
3217
|
let dynamic = false;
|
|
3110
3218
|
const remember = (node) => {
|
|
3111
3219
|
const annotation = consumerAnnotation(node);
|
|
3112
|
-
if (annotation?.type ===
|
|
3220
|
+
if (annotation?.type === import_utils27.AST_NODE_TYPES.TSUnionType && annotation.types.length === 2) candidates.push(node);
|
|
3113
3221
|
};
|
|
3114
3222
|
return {
|
|
3115
3223
|
FunctionDeclaration: remember,
|
|
@@ -3119,7 +3227,7 @@ var no_redundant_consumer_union_default = createRule({
|
|
|
3119
3227
|
},
|
|
3120
3228
|
"Program:exit"() {
|
|
3121
3229
|
if (dynamic || !candidates.length) return;
|
|
3122
|
-
const services =
|
|
3230
|
+
const services = import_utils27.ESLintUtils.getParserServices(context);
|
|
3123
3231
|
const source = currentNativeSource(context.sourceCode, services);
|
|
3124
3232
|
if (!source) return;
|
|
3125
3233
|
const checker = services.program.getTypeChecker();
|
|
@@ -3134,7 +3242,7 @@ var no_redundant_consumer_union_default = createRule({
|
|
|
3134
3242
|
return surfaces.get(type) ?? null;
|
|
3135
3243
|
};
|
|
3136
3244
|
for (const candidate2 of candidates) {
|
|
3137
|
-
const consumer = privateScalarConsumer(candidate2, context.sourceCode, services, exports2);
|
|
3245
|
+
const consumer = privateScalarConsumer(candidate2, context.sourceCode, services, exports2, { scalarCalls: true });
|
|
3138
3246
|
const annotation = consumer?.parameter.type;
|
|
3139
3247
|
if (!consumer || !annotation || !import_typescript7.default.isUnionTypeNode(annotation) || annotation.types.length !== 2) continue;
|
|
3140
3248
|
const leftNode = annotation.types[0];
|
|
@@ -3143,7 +3251,7 @@ var no_redundant_consumer_union_default = createRule({
|
|
|
3143
3251
|
const coverage = coveringAlternative(leftNode, rightNode, checker, fieldsOf, consumer.reads);
|
|
3144
3252
|
if (!coverage) continue;
|
|
3145
3253
|
const reportNode = services.tsNodeToESTreeNodeMap.get(annotation);
|
|
3146
|
-
if (coverage.mutual && (reportNode.type !==
|
|
3254
|
+
if (coverage.mutual && (reportNode.type !== import_utils27.AST_NODE_TYPES.TSUnionType || !localContractBindings(reportNode.types, context.sourceCode, services))) continue;
|
|
3147
3255
|
const { covered: coveredNode, covering: coveringNode } = coverage;
|
|
3148
3256
|
const fix = privateUnionFix(context.sourceCode, services, {
|
|
3149
3257
|
candidate: candidate2,
|
|
@@ -3161,7 +3269,7 @@ var no_redundant_consumer_union_default = createRule({
|
|
|
3161
3269
|
});
|
|
3162
3270
|
|
|
3163
3271
|
// src/rules/prefer-minimal-parameter-contract.ts
|
|
3164
|
-
var
|
|
3272
|
+
var import_utils28 = require("@typescript-eslint/utils");
|
|
3165
3273
|
var import_typescript8 = __toESM(require("typescript"), 1);
|
|
3166
3274
|
var CONFIG2 = { path: "tsconfig.json", source: '{"compilerOptions":{"strict":true,"target":"ESNext","module":"ESNext","moduleResolution":"Bundler"}}' };
|
|
3167
3275
|
var EXAMPLE2 = 'export {}; const account = {name: "Ada", email: "a"}; function label(user: {readonly email: string; readonly name: string}): string {return user.name;} label(account);';
|
|
@@ -3218,7 +3326,7 @@ var prefer_minimal_parameter_contract_default = createRule({
|
|
|
3218
3326
|
const candidates = [];
|
|
3219
3327
|
let dynamic = false;
|
|
3220
3328
|
const remember = (node) => {
|
|
3221
|
-
if (consumerAnnotation(node, true)?.type ===
|
|
3329
|
+
if (consumerAnnotation(node, true)?.type === import_utils28.AST_NODE_TYPES.TSTypeLiteral) candidates.push(node);
|
|
3222
3330
|
};
|
|
3223
3331
|
return {
|
|
3224
3332
|
FunctionDeclaration: remember,
|
|
@@ -3228,7 +3336,7 @@ var prefer_minimal_parameter_contract_default = createRule({
|
|
|
3228
3336
|
},
|
|
3229
3337
|
"Program:exit"() {
|
|
3230
3338
|
if (dynamic || !candidates.length) return;
|
|
3231
|
-
const services =
|
|
3339
|
+
const services = import_utils28.ESLintUtils.getParserServices(context);
|
|
3232
3340
|
const source = currentNativeSource(context.sourceCode, services);
|
|
3233
3341
|
if (!source) return;
|
|
3234
3342
|
const checker = services.program.getTypeChecker();
|
|
@@ -3252,7 +3360,7 @@ var prefer_minimal_parameter_contract_default = createRule({
|
|
|
3252
3360
|
});
|
|
3253
3361
|
|
|
3254
3362
|
// src/rules/no-excess-jsx-props.ts
|
|
3255
|
-
var
|
|
3363
|
+
var import_utils29 = require("@typescript-eslint/utils");
|
|
3256
3364
|
var import_typescript10 = __toESM(require("typescript"), 1);
|
|
3257
3365
|
|
|
3258
3366
|
// src/rules/_ordinary-object-effects.ts
|
|
@@ -3594,11 +3702,11 @@ var PRIMITIVE_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
3594
3702
|
function plainLiteralFields(node) {
|
|
3595
3703
|
const fields2 = /* @__PURE__ */ new Map();
|
|
3596
3704
|
for (const property of node.properties) {
|
|
3597
|
-
if (property.type !==
|
|
3705
|
+
if (property.type !== import_utils29.AST_NODE_TYPES.Property || property.kind !== "init") return null;
|
|
3598
3706
|
const key = property.key;
|
|
3599
3707
|
let name;
|
|
3600
|
-
if (!property.computed && key.type ===
|
|
3601
|
-
else if (key.type ===
|
|
3708
|
+
if (!property.computed && key.type === import_utils29.AST_NODE_TYPES.Identifier) name = key.name;
|
|
3709
|
+
else if (key.type === import_utils29.AST_NODE_TYPES.Literal && (typeof key.value === "string" || typeof key.value === "number")) name = String(key.value);
|
|
3602
3710
|
else return null;
|
|
3603
3711
|
if (name === "__proto__") return null;
|
|
3604
3712
|
fields2.set(name, property);
|
|
@@ -3710,35 +3818,35 @@ function localObjectFields(symbol, source, proof) {
|
|
|
3710
3818
|
if (!native || native.getSourceFile() !== source || !initializer || !import_typescript10.default.isObjectLiteralExpression(initializer)) return null;
|
|
3711
3819
|
const declaration = proof.services.tsNodeToESTreeNodeMap.get(native);
|
|
3712
3820
|
const literal2 = proof.services.tsNodeToESTreeNodeMap.get(initializer);
|
|
3713
|
-
if (declaration.type !==
|
|
3821
|
+
if (declaration.type !== import_utils29.AST_NODE_TYPES.VariableDeclarator || declaration.parent.kind !== "const" || declaration.id.type !== import_utils29.AST_NODE_TYPES.Identifier || literal2.type !== import_utils29.AST_NODE_TYPES.ObjectExpression || declaration.parent.parent.type === import_utils29.AST_NODE_TYPES.ExportNamedDeclaration) return null;
|
|
3714
3822
|
const fields2 = plainLiteralFields(literal2);
|
|
3715
3823
|
const binding3 = proof.sourceCode.getDeclaredVariables(declaration).find((variable) => variable.defs.some((definition) => definition.type === "Variable" && definition.node === declaration));
|
|
3716
3824
|
if (!fields2 || !binding3 || binding3.defs.length !== 1 || !stableValueBinding(binding3, (reference) => {
|
|
3717
3825
|
if (!reference.isReadOnly() || reference.isTypeReference) return false;
|
|
3718
3826
|
const member3 = reference.identifier.parent;
|
|
3719
|
-
return member3.type ===
|
|
3827
|
+
return member3.type === import_utils29.AST_NODE_TYPES.MemberExpression && member3.object === reference.identifier && readonlyFieldValue(member3, fields2);
|
|
3720
3828
|
})) return null;
|
|
3721
3829
|
return fields2;
|
|
3722
3830
|
}
|
|
3723
3831
|
function staticMemberKey(member3) {
|
|
3724
3832
|
const property = member3.property;
|
|
3725
|
-
return !member3.computed && property.type ===
|
|
3833
|
+
return !member3.computed && property.type === import_utils29.AST_NODE_TYPES.Identifier ? property.name : property.type === import_utils29.AST_NODE_TYPES.Literal && (typeof property.value === "string" || typeof property.value === "number") ? String(property.value) : void 0;
|
|
3726
3834
|
}
|
|
3727
3835
|
function readonlyFieldValue(member3, fields2) {
|
|
3728
3836
|
const key = staticMemberKey(member3);
|
|
3729
3837
|
if (key === void 0 || !fields2.has(key)) return false;
|
|
3730
3838
|
const parent = member3.parent;
|
|
3731
|
-
if (parent.type ===
|
|
3839
|
+
if (parent.type === import_utils29.AST_NODE_TYPES.Property && parent.value === member3 && parent.parent.type === import_utils29.AST_NODE_TYPES.ObjectExpression) {
|
|
3732
3840
|
const object = parent.parent;
|
|
3733
3841
|
const owner = object.parent;
|
|
3734
|
-
return owner.type ===
|
|
3842
|
+
return owner.type === import_utils29.AST_NODE_TYPES.JSXSpreadAttribute && owner.argument === object || owner.type === import_utils29.AST_NODE_TYPES.VariableDeclarator && owner.init === object;
|
|
3735
3843
|
}
|
|
3736
|
-
return parent.type ===
|
|
3844
|
+
return parent.type === import_utils29.AST_NODE_TYPES.JSXExpressionContainer && parent.expression === member3 || parent.type === import_utils29.AST_NODE_TYPES.VariableDeclarator && parent.init === member3;
|
|
3737
3845
|
}
|
|
3738
3846
|
function privateElementDeclaration(opening) {
|
|
3739
3847
|
const value = outerExpression(opening.parent);
|
|
3740
3848
|
const declaration = value.parent;
|
|
3741
|
-
return declaration.type ===
|
|
3849
|
+
return declaration.type === import_utils29.AST_NODE_TYPES.VariableDeclarator && declaration.init === value && declaration.id.type === import_utils29.AST_NODE_TYPES.Identifier && declaration.parent.kind === "const" && declaration.parent.parent.type !== import_utils29.AST_NODE_TYPES.ExportNamedDeclaration ? declaration : null;
|
|
3742
3850
|
}
|
|
3743
3851
|
function closedElementValue(opening, declaration, fields2, reads, proof) {
|
|
3744
3852
|
if (!closedInvocation(opening, proof) || !constInitializer(proof.services.esTreeNodeToTSNodeMap.get(declaration))) return false;
|
|
@@ -3764,10 +3872,10 @@ function closedInvocation(node, proof) {
|
|
|
3764
3872
|
}
|
|
3765
3873
|
function independentInvocation(scope, proof) {
|
|
3766
3874
|
const block = scope.block;
|
|
3767
|
-
if (block.type !==
|
|
3875
|
+
if (block.type !== import_utils29.AST_NODE_TYPES.ArrowFunctionExpression && block.type !== import_utils29.AST_NODE_TYPES.FunctionDeclaration && block.type !== import_utils29.AST_NODE_TYPES.FunctionExpression) return false;
|
|
3768
3876
|
if (block.async || block.generator || scope.set.get("arguments")?.references.some((reference) => !typeOnlyReference(reference))) return false;
|
|
3769
3877
|
for (const parameter of block.params) {
|
|
3770
|
-
if (parameter.type !==
|
|
3878
|
+
if (parameter.type !== import_utils29.AST_NODE_TYPES.Identifier || parameter.name === "this") return false;
|
|
3771
3879
|
const binding3 = scope.set.get(parameter.name);
|
|
3772
3880
|
if (!binding3 || binding3.references.some((reference) => !typeOnlyReference(reference))) return false;
|
|
3773
3881
|
}
|
|
@@ -3775,16 +3883,16 @@ function independentInvocation(scope, proof) {
|
|
|
3775
3883
|
if (typeOnlyReference(reference)) return true;
|
|
3776
3884
|
const value = outerExpression(reference.identifier);
|
|
3777
3885
|
const parent = value.parent;
|
|
3778
|
-
const read = parent?.type ===
|
|
3886
|
+
const read = parent?.type === import_utils29.AST_NODE_TYPES.MemberExpression && parent.object === value ? parent : value;
|
|
3779
3887
|
return primitiveValue(proof.services.esTreeNodeToTSNodeMap.get(read), proof, /* @__PURE__ */ new Set());
|
|
3780
3888
|
});
|
|
3781
3889
|
}
|
|
3782
3890
|
function consumedElementRead(node, fields2, reads) {
|
|
3783
3891
|
const identifier = outerExpression(node);
|
|
3784
3892
|
const props = identifier.parent;
|
|
3785
|
-
if (!props || props.type !==
|
|
3893
|
+
if (!props || props.type !== import_utils29.AST_NODE_TYPES.MemberExpression || props.object !== identifier || props.optional || staticMemberKey(props) !== "props") return false;
|
|
3786
3894
|
const member3 = props.parent;
|
|
3787
|
-
if (member3.type !==
|
|
3895
|
+
if (member3.type !== import_utils29.AST_NODE_TYPES.MemberExpression || member3.object !== props || member3.optional) return false;
|
|
3788
3896
|
const key = staticMemberKey(member3);
|
|
3789
3897
|
return key !== void 0 && reads.has(key) && readonlyFieldValue(member3, fields2);
|
|
3790
3898
|
}
|
|
@@ -3812,7 +3920,7 @@ var no_excess_jsx_props_default = createRule({
|
|
|
3812
3920
|
const evaluate = (node, declaration, fields2) => {
|
|
3813
3921
|
const keys = [...fields2.keys()];
|
|
3814
3922
|
const opening = node.parent;
|
|
3815
|
-
services ??=
|
|
3923
|
+
services ??= import_utils29.ESLintUtils.getParserServices(context);
|
|
3816
3924
|
standardJSX ??= supportedJSX(services.program.getCompilerOptions(), context.sourceCode.getAllComments());
|
|
3817
3925
|
if (!standardJSX) return;
|
|
3818
3926
|
const checker = services.program.getTypeChecker();
|
|
@@ -3844,9 +3952,9 @@ var no_excess_jsx_props_default = createRule({
|
|
|
3844
3952
|
};
|
|
3845
3953
|
return {
|
|
3846
3954
|
JSXSpreadAttribute(node) {
|
|
3847
|
-
if (node.argument.type !==
|
|
3955
|
+
if (node.argument.type !== import_utils29.AST_NODE_TYPES.ObjectExpression) return;
|
|
3848
3956
|
const opening = node.parent;
|
|
3849
|
-
if (!opening.selfClosing || opening.attributes.length !== 1 || opening.name.type !==
|
|
3957
|
+
if (!opening.selfClosing || opening.attributes.length !== 1 || opening.name.type !== import_utils29.AST_NODE_TYPES.JSXIdentifier || /^[a-z]/u.test(opening.name.name)) return;
|
|
3850
3958
|
const declaration = privateElementDeclaration(opening);
|
|
3851
3959
|
if (!declaration) return;
|
|
3852
3960
|
const fields2 = literalFields(node.argument);
|
|
@@ -3858,7 +3966,7 @@ var no_excess_jsx_props_default = createRule({
|
|
|
3858
3966
|
},
|
|
3859
3967
|
"Program:exit"() {
|
|
3860
3968
|
if (!candidates.length || dynamic) return;
|
|
3861
|
-
services =
|
|
3969
|
+
services = import_utils29.ESLintUtils.getParserServices(context);
|
|
3862
3970
|
if (!currentNativeSource(context.sourceCode, services)) return;
|
|
3863
3971
|
for (const { node, declaration, fields: fields2 } of candidates) evaluate(node, declaration, fields2);
|
|
3864
3972
|
}
|
|
@@ -3867,7 +3975,7 @@ var no_excess_jsx_props_default = createRule({
|
|
|
3867
3975
|
});
|
|
3868
3976
|
|
|
3869
3977
|
// src/rules/prefer-native-fetch-in-server-actions.ts
|
|
3870
|
-
var
|
|
3978
|
+
var import_utils30 = require("@typescript-eslint/utils");
|
|
3871
3979
|
var KY_MODULE = /^ky(?:\/.*)?$/u;
|
|
3872
3980
|
var PREFER_NATIVE_FETCH_IN_SERVER_ACTIONS_DOCUMENTATION = {
|
|
3873
3981
|
defaultLevel: "warning",
|
|
@@ -3931,19 +4039,19 @@ var prefer_native_fetch_in_server_actions_default = createRule({
|
|
|
3931
4039
|
});
|
|
3932
4040
|
function hasUseServerDirective(program) {
|
|
3933
4041
|
for (const statement of program.body) {
|
|
3934
|
-
if (statement.type !==
|
|
4042
|
+
if (statement.type !== import_utils30.AST_NODE_TYPES.ExpressionStatement || statement.directive === void 0) return false;
|
|
3935
4043
|
if (statement.directive === "use server") return true;
|
|
3936
4044
|
}
|
|
3937
4045
|
return false;
|
|
3938
4046
|
}
|
|
3939
4047
|
function isTypeOnly(node) {
|
|
3940
4048
|
return node.importKind === "type" || node.specifiers.length > 0 && node.specifiers.every(
|
|
3941
|
-
(specifier) => specifier.type ===
|
|
4049
|
+
(specifier) => specifier.type === import_utils30.AST_NODE_TYPES.ImportSpecifier && specifier.importKind === "type"
|
|
3942
4050
|
);
|
|
3943
4051
|
}
|
|
3944
4052
|
|
|
3945
4053
|
// src/rules/no-credential-in-browser-storage.ts
|
|
3946
|
-
var
|
|
4054
|
+
var import_utils31 = require("@typescript-eslint/utils");
|
|
3947
4055
|
|
|
3948
4056
|
// src/rules/_secret-names.ts
|
|
3949
4057
|
var SECRET_WORDS = /* @__PURE__ */ new Set([
|
|
@@ -4148,7 +4256,7 @@ var no_credential_in_browser_storage_default = createRule({
|
|
|
4148
4256
|
return {
|
|
4149
4257
|
CallExpression(node) {
|
|
4150
4258
|
const callee = unwrapExpression(node.callee);
|
|
4151
|
-
if (callee.type !==
|
|
4259
|
+
if (callee.type !== import_utils31.AST_NODE_TYPES.MemberExpression || callee.computed || callee.property.type !== import_utils31.AST_NODE_TYPES.Identifier || callee.property.name !== "setItem" || !isStorage(sourceCode, callee.object)) {
|
|
4152
4260
|
return;
|
|
4153
4261
|
}
|
|
4154
4262
|
const [key] = node.arguments;
|
|
@@ -4156,12 +4264,12 @@ var no_credential_in_browser_storage_default = createRule({
|
|
|
4156
4264
|
},
|
|
4157
4265
|
AssignmentExpression(node) {
|
|
4158
4266
|
const target = node.left;
|
|
4159
|
-
if (target.type !==
|
|
4267
|
+
if (target.type !== import_utils31.AST_NODE_TYPES.MemberExpression) return;
|
|
4160
4268
|
if (isStorage(sourceCode, target.object)) {
|
|
4161
4269
|
report2(node, storedPropertyKey(sourceCode, target));
|
|
4162
4270
|
return;
|
|
4163
4271
|
}
|
|
4164
|
-
if (!target.computed && target.property.type ===
|
|
4272
|
+
if (!target.computed && target.property.type === import_utils31.AST_NODE_TYPES.Identifier && target.property.name === "cookie" && globalMemberName(sourceCode, target.object) === "document") {
|
|
4165
4273
|
report2(node, cookieName(node.right));
|
|
4166
4274
|
}
|
|
4167
4275
|
}
|
|
@@ -4174,34 +4282,34 @@ function isStorage(sourceCode, node) {
|
|
|
4174
4282
|
}
|
|
4175
4283
|
function globalMemberName(sourceCode, node) {
|
|
4176
4284
|
const value = unwrapExpression(node);
|
|
4177
|
-
if (value.type ===
|
|
4178
|
-
if (value.type ===
|
|
4285
|
+
if (value.type === import_utils31.AST_NODE_TYPES.Identifier) return isUnshadowed(sourceCode, value) ? value.name : null;
|
|
4286
|
+
if (value.type === import_utils31.AST_NODE_TYPES.MemberExpression && !value.computed && value.object.type === import_utils31.AST_NODE_TYPES.Identifier && GLOBAL_OBJECTS2.has(value.object.name) && value.property.type === import_utils31.AST_NODE_TYPES.Identifier && isUnshadowed(sourceCode, value.object)) {
|
|
4179
4287
|
return value.property.name;
|
|
4180
4288
|
}
|
|
4181
4289
|
return null;
|
|
4182
4290
|
}
|
|
4183
4291
|
function isUnshadowed(sourceCode, node) {
|
|
4184
|
-
const variable =
|
|
4292
|
+
const variable = import_utils31.ASTUtils.findVariable(sourceCode.getScope(node), node.name);
|
|
4185
4293
|
return variable === null || variable.defs.length === 0;
|
|
4186
4294
|
}
|
|
4187
4295
|
function storedPropertyKey(sourceCode, target) {
|
|
4188
|
-
if (!target.computed) return target.property.type ===
|
|
4296
|
+
if (!target.computed) return target.property.type === import_utils31.AST_NODE_TYPES.Identifier ? target.property.name : null;
|
|
4189
4297
|
return scopedStaticString(target.property, sourceCode);
|
|
4190
4298
|
}
|
|
4191
4299
|
function cookieName(value) {
|
|
4192
4300
|
let expression = unwrapExpression(value);
|
|
4193
|
-
while (expression.type ===
|
|
4301
|
+
while (expression.type === import_utils31.AST_NODE_TYPES.BinaryExpression && expression.operator === "+") {
|
|
4194
4302
|
expression = unwrapExpression(expression.left);
|
|
4195
4303
|
}
|
|
4196
4304
|
let text = null;
|
|
4197
|
-
if (expression.type ===
|
|
4198
|
-
if (expression.type ===
|
|
4305
|
+
if (expression.type === import_utils31.AST_NODE_TYPES.Literal && typeof expression.value === "string") text = expression.value;
|
|
4306
|
+
if (expression.type === import_utils31.AST_NODE_TYPES.TemplateLiteral) text = expression.quasis[0]?.value.cooked ?? null;
|
|
4199
4307
|
if (text === null || !text.includes("=")) return null;
|
|
4200
4308
|
return text.slice(0, text.indexOf("=")).trim();
|
|
4201
4309
|
}
|
|
4202
4310
|
|
|
4203
4311
|
// src/rules/no-numeric-search-param-coercion.ts
|
|
4204
|
-
var
|
|
4312
|
+
var import_utils32 = require("@typescript-eslint/utils");
|
|
4205
4313
|
var GLOBAL_PARSERS = /* @__PURE__ */ new Set(["parseInt", "parseFloat", "Number"]);
|
|
4206
4314
|
var NUMBER_PARSERS = /* @__PURE__ */ new Set(["parseInt", "parseFloat"]);
|
|
4207
4315
|
var SEARCH_PARAM_TYPES = /* @__PURE__ */ new Set(["URLSearchParams", "ReadonlyURLSearchParams"]);
|
|
@@ -4258,7 +4366,7 @@ var no_numeric_search_param_coercion_default = createRule({
|
|
|
4258
4366
|
if (isGeneratedFile(context, context.sourceCode.text) || isTestFile(context)) return {};
|
|
4259
4367
|
let services;
|
|
4260
4368
|
try {
|
|
4261
|
-
services =
|
|
4369
|
+
services = import_utils32.ESLintUtils.getParserServices(context);
|
|
4262
4370
|
} catch {
|
|
4263
4371
|
services = null;
|
|
4264
4372
|
}
|
|
@@ -4280,27 +4388,27 @@ var no_numeric_search_param_coercion_default = createRule({
|
|
|
4280
4388
|
}
|
|
4281
4389
|
});
|
|
4282
4390
|
function isNumericParser(sourceCode, callee) {
|
|
4283
|
-
if (callee.type ===
|
|
4391
|
+
if (callee.type === import_utils32.AST_NODE_TYPES.Identifier) {
|
|
4284
4392
|
return GLOBAL_PARSERS.has(callee.name) && isUnshadowedGlobal(sourceCode, callee);
|
|
4285
4393
|
}
|
|
4286
|
-
return callee.type ===
|
|
4394
|
+
return callee.type === import_utils32.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.object.type === import_utils32.AST_NODE_TYPES.Identifier && callee.object.name === "Number" && callee.property.type === import_utils32.AST_NODE_TYPES.Identifier && NUMBER_PARSERS.has(callee.property.name) && isUnshadowedGlobal(sourceCode, callee.object);
|
|
4287
4395
|
}
|
|
4288
4396
|
function isUnshadowedGlobal(sourceCode, node) {
|
|
4289
|
-
const variable =
|
|
4397
|
+
const variable = import_utils32.ASTUtils.findVariable(sourceCode.getScope(node), node.name);
|
|
4290
4398
|
return variable === null || variable.defs.length === 0;
|
|
4291
4399
|
}
|
|
4292
4400
|
function searchParamGetCall(argument) {
|
|
4293
4401
|
let value = unwrapExpression(argument);
|
|
4294
|
-
if (value.type ===
|
|
4295
|
-
if (value.type ===
|
|
4296
|
-
if (value.type ===
|
|
4297
|
-
if (value.type !==
|
|
4402
|
+
if (value.type === import_utils32.AST_NODE_TYPES.AwaitExpression) value = unwrapExpression(value.argument);
|
|
4403
|
+
if (value.type === import_utils32.AST_NODE_TYPES.LogicalExpression && value.operator === "??") value = unwrapExpression(value.left);
|
|
4404
|
+
if (value.type === import_utils32.AST_NODE_TYPES.ChainExpression) value = value.expression;
|
|
4405
|
+
if (value.type !== import_utils32.AST_NODE_TYPES.CallExpression || value.callee.type !== import_utils32.AST_NODE_TYPES.MemberExpression || value.callee.computed || value.callee.property.type !== import_utils32.AST_NODE_TYPES.Identifier || value.callee.property.name !== "get") {
|
|
4298
4406
|
return null;
|
|
4299
4407
|
}
|
|
4300
4408
|
return value;
|
|
4301
4409
|
}
|
|
4302
4410
|
function isSearchParamReceiver(call, services) {
|
|
4303
|
-
if (call.callee.type !==
|
|
4411
|
+
if (call.callee.type !== import_utils32.AST_NODE_TYPES.MemberExpression) return false;
|
|
4304
4412
|
const checker = services.program.getTypeChecker();
|
|
4305
4413
|
const type = checker.getNonNullableType(
|
|
4306
4414
|
checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(call.callee.object))
|
|
@@ -4312,7 +4420,7 @@ function isSearchParamReceiver(call, services) {
|
|
|
4312
4420
|
// package.json
|
|
4313
4421
|
var package_default = {
|
|
4314
4422
|
name: "@sarj/eslint-plugin",
|
|
4315
|
-
version: "16.
|
|
4423
|
+
version: "16.39.1",
|
|
4316
4424
|
packageManager: "npm@12.2.1",
|
|
4317
4425
|
description: "Custom ESLint rules for hypermodern TypeScript / React / Next.js projects",
|
|
4318
4426
|
type: "module",
|
|
@@ -4400,6 +4508,7 @@ var package_default = {
|
|
|
4400
4508
|
"eslint-plugin-zod": "^5.2.2",
|
|
4401
4509
|
globals: "17.13.0",
|
|
4402
4510
|
jiti: "2.7.0",
|
|
4511
|
+
prettier: "3.9.10",
|
|
4403
4512
|
tsup: "9.0.0",
|
|
4404
4513
|
typescript: "npm:@typescript/typescript6@6.0.2",
|
|
4405
4514
|
"typescript-eslint": "^8.72.0",
|
|
@@ -4434,11 +4543,11 @@ var package_default = {
|
|
|
4434
4543
|
};
|
|
4435
4544
|
|
|
4436
4545
|
// src/rules/require-explicit-contract-implementation.ts
|
|
4437
|
-
var
|
|
4546
|
+
var import_utils34 = require("@typescript-eslint/utils");
|
|
4438
4547
|
var ts12 = __toESM(require("typescript"), 1);
|
|
4439
4548
|
|
|
4440
4549
|
// src/rules/_closed-nominal-inheritance-fix.ts
|
|
4441
|
-
var
|
|
4550
|
+
var import_utils33 = require("@typescript-eslint/utils");
|
|
4442
4551
|
var import_typescript11 = __toESM(require("typescript"), 1);
|
|
4443
4552
|
function closedNominalInheritanceFix(sourceCode, call, consumer, implementation, contract) {
|
|
4444
4553
|
const source = call.getSourceFile();
|
|
@@ -4512,7 +4621,7 @@ function exactRejection(sourceCode, statement) {
|
|
|
4512
4621
|
const identifier = sourceCode.getNodeByRangeIndex(
|
|
4513
4622
|
rejected.expression.expression.getStart()
|
|
4514
4623
|
);
|
|
4515
|
-
return identifier?.type ===
|
|
4624
|
+
return identifier?.type === import_utils33.AST_NODE_TYPES.Identifier && identifier.name === "TypeError" && (import_utils33.ASTUtils.findVariable(sourceCode.getScope(identifier), identifier.name)?.defs.length ?? 0) === 0;
|
|
4516
4625
|
}
|
|
4517
4626
|
function exactConstruction(node, consumer, implementation) {
|
|
4518
4627
|
if (!import_typescript11.default.isIdentifier(node.expression) || node.expression.text !== consumer || node.typeArguments !== void 0 || node.arguments?.length !== 1)
|
|
@@ -4878,7 +4987,7 @@ var require_explicit_contract_implementation_default = createRule({
|
|
|
4878
4987
|
if (isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
4879
4988
|
if (!context.sourceCode.parserServices?.program || !context.sourceCode.parserServices.esTreeNodeToTSNodeMap)
|
|
4880
4989
|
return {};
|
|
4881
|
-
const services =
|
|
4990
|
+
const services = import_utils34.ESLintUtils.getParserServices(context);
|
|
4882
4991
|
const checker = services.program.getTypeChecker();
|
|
4883
4992
|
function inspect(node) {
|
|
4884
4993
|
const tsNode = services.esTreeNodeToTSNodeMap.get(node);
|
|
@@ -4893,7 +5002,7 @@ var require_explicit_contract_implementation_default = createRule({
|
|
|
4893
5002
|
return;
|
|
4894
5003
|
const parameters = signature.getParameters();
|
|
4895
5004
|
for (const [index, argument] of node.arguments.entries()) {
|
|
4896
|
-
if (argument.type !==
|
|
5005
|
+
if (argument.type !== import_utils34.AST_NODE_TYPES.NewExpression) continue;
|
|
4897
5006
|
const parameter = parameters[index];
|
|
4898
5007
|
if (parameter === void 0) continue;
|
|
4899
5008
|
const tsArgument = services.esTreeNodeToTSNodeMap.get(argument);
|
|
@@ -4940,18 +5049,18 @@ var require_explicit_contract_implementation_default = createRule({
|
|
|
4940
5049
|
});
|
|
4941
5050
|
|
|
4942
5051
|
// src/rules/require-explicit-service-contract.ts
|
|
4943
|
-
var
|
|
5052
|
+
var import_utils37 = require("@typescript-eslint/utils");
|
|
4944
5053
|
|
|
4945
5054
|
// src/rules/_existing-factory-contract-fix.ts
|
|
4946
|
-
var
|
|
5055
|
+
var import_utils35 = require("@typescript-eslint/utils");
|
|
4947
5056
|
function existingFactoryContractFix(sourceCode, candidate2) {
|
|
4948
5057
|
if (sourceCode.ast.body.length !== 4 || sourceCode.getAllComments().length !== 0)
|
|
4949
5058
|
return null;
|
|
4950
5059
|
const [contractStatement, worker, classStatement, factoryStatement] = sourceCode.ast.body;
|
|
4951
|
-
const contract = contractStatement?.type ===
|
|
4952
|
-
const implementation = classStatement?.type ===
|
|
4953
|
-
const factory = factoryStatement?.type ===
|
|
4954
|
-
if (contract?.type !==
|
|
5060
|
+
const contract = contractStatement?.type === import_utils35.AST_NODE_TYPES.ExportNamedDeclaration ? contractStatement.declaration : null;
|
|
5061
|
+
const implementation = classStatement?.type === import_utils35.AST_NODE_TYPES.ExportNamedDeclaration ? classStatement.declaration : classStatement;
|
|
5062
|
+
const factory = factoryStatement?.type === import_utils35.AST_NODE_TYPES.ExportNamedDeclaration ? factoryStatement.declaration : null;
|
|
5063
|
+
if (contract?.type !== import_utils35.AST_NODE_TYPES.TSTypeAliasDeclaration || worker?.type !== import_utils35.AST_NODE_TYPES.TSInterfaceDeclaration || implementation?.type !== import_utils35.AST_NODE_TYPES.ClassDeclaration || implementation !== candidate2 || !ordinaryClass(implementation) || !ordinaryFactory(factory))
|
|
4955
5064
|
return null;
|
|
4956
5065
|
const operation2 = contractOperation(contract);
|
|
4957
5066
|
if (operation2 === null || interfaceOperation(worker) !== operation2)
|
|
@@ -4970,17 +5079,17 @@ function ordinaryClass(node) {
|
|
|
4970
5079
|
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;
|
|
4971
5080
|
}
|
|
4972
5081
|
function ordinaryFactory(node) {
|
|
4973
|
-
return node?.type ===
|
|
5082
|
+
return node?.type === import_utils35.AST_NODE_TYPES.FunctionDeclaration && node.id !== null && !node.declare && !node.async && !node.generator && node.typeParameters === void 0 && node.params.length === 1 && node.body.body.length === 1;
|
|
4974
5083
|
}
|
|
4975
5084
|
function interfaceOperation(node) {
|
|
4976
5085
|
return !node.declare && node.extends.length === 0 && node.typeParameters === void 0 ? singletonOperation(node.body.body) : null;
|
|
4977
5086
|
}
|
|
4978
5087
|
function contractOperation(node) {
|
|
4979
|
-
return !node.declare && node.typeParameters === void 0 && node.typeAnnotation.type ===
|
|
5088
|
+
return !node.declare && node.typeParameters === void 0 && node.typeAnnotation.type === import_utils35.AST_NODE_TYPES.TSTypeLiteral ? singletonOperation(node.typeAnnotation.members) : null;
|
|
4980
5089
|
}
|
|
4981
5090
|
function singletonOperation(members) {
|
|
4982
5091
|
const member3 = members[0];
|
|
4983
|
-
return members.length === 1 && member3?.type ===
|
|
5092
|
+
return members.length === 1 && member3?.type === import_utils35.AST_NODE_TYPES.TSMethodSignature && member3.kind === "method" && !member3.computed && !member3.optional && member3.key.type === import_utils35.AST_NODE_TYPES.Identifier && member3.params.length === 0 && member3.typeParameters === void 0 && member3.returnType?.typeAnnotation.type === import_utils35.AST_NODE_TYPES.TSVoidKeyword ? member3.key.name : null;
|
|
4984
5093
|
}
|
|
4985
5094
|
function uniqueDeclarations(sourceCode, declarations) {
|
|
4986
5095
|
const names = declarations.flatMap(
|
|
@@ -4991,7 +5100,7 @@ function uniqueDeclarations(sourceCode, declarations) {
|
|
|
4991
5100
|
);
|
|
4992
5101
|
}
|
|
4993
5102
|
function sameBinding(sourceCode, reference, declaration) {
|
|
4994
|
-
const binding3 =
|
|
5103
|
+
const binding3 = import_utils35.ASTUtils.findVariable(
|
|
4995
5104
|
sourceCode.getScope(reference),
|
|
4996
5105
|
reference.name
|
|
4997
5106
|
);
|
|
@@ -4999,45 +5108,45 @@ function sameBinding(sourceCode, reference, declaration) {
|
|
|
4999
5108
|
}
|
|
5000
5109
|
function retainedWorker(sourceCode, implementation, worker) {
|
|
5001
5110
|
const constructor = implementation.body.body[0];
|
|
5002
|
-
if (constructor?.type !==
|
|
5111
|
+
if (constructor?.type !== import_utils35.AST_NODE_TYPES.MethodDefinition || constructor.value.type !== import_utils35.AST_NODE_TYPES.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)
|
|
5003
5112
|
return null;
|
|
5004
5113
|
const property = constructor.value.params[0];
|
|
5005
|
-
if (property?.type !==
|
|
5114
|
+
if (property?.type !== import_utils35.AST_NODE_TYPES.TSParameterProperty || property.accessibility !== "private" || !property.readonly || property.override || property.decorators.length !== 0 || property.parameter.type !== import_utils35.AST_NODE_TYPES.Identifier || property.parameter.optional || !typeReference(sourceCode, property.parameter.typeAnnotation, worker))
|
|
5006
5115
|
return null;
|
|
5007
5116
|
return property.parameter.name;
|
|
5008
5117
|
}
|
|
5009
5118
|
function typeReference(sourceCode, annotation, declaration) {
|
|
5010
5119
|
const type = annotation?.typeAnnotation;
|
|
5011
|
-
return type?.type ===
|
|
5120
|
+
return type?.type === import_utils35.AST_NODE_TYPES.TSTypeReference && type.typeArguments === void 0 && type.typeName.type === import_utils35.AST_NODE_TYPES.Identifier && sameBinding(sourceCode, type.typeName, declaration);
|
|
5012
5121
|
}
|
|
5013
5122
|
function forwardsOperation(implementation, field, operation2) {
|
|
5014
5123
|
const method = implementation.body.body[1];
|
|
5015
|
-
if (method?.type !==
|
|
5124
|
+
if (method?.type !== import_utils35.AST_NODE_TYPES.MethodDefinition || method.kind !== "method" || method.value.type !== import_utils35.AST_NODE_TYPES.FunctionExpression || method.computed || method.static || method.optional || method.override || method.decorators.length !== 0 || method.accessibility !== void 0 && method.accessibility !== "public" || method.key.type !== import_utils35.AST_NODE_TYPES.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 !== import_utils35.AST_NODE_TYPES.TSVoidKeyword)
|
|
5016
5125
|
return false;
|
|
5017
5126
|
const statement = method.value.body.body[0];
|
|
5018
|
-
const call = statement?.type ===
|
|
5019
|
-
return call?.type ===
|
|
5127
|
+
const call = statement?.type === import_utils35.AST_NODE_TYPES.ExpressionStatement ? statement.expression : null;
|
|
5128
|
+
return call?.type === import_utils35.AST_NODE_TYPES.CallExpression && !call.optional && call.typeArguments === void 0 && call.arguments.length === 0 && forwardedMember(call.callee, field, operation2);
|
|
5020
5129
|
}
|
|
5021
5130
|
function forwardedMember(node, field, operation2) {
|
|
5022
|
-
if (node.type !==
|
|
5131
|
+
if (node.type !== import_utils35.AST_NODE_TYPES.MemberExpression || node.computed || node.optional || node.property.type !== import_utils35.AST_NODE_TYPES.Identifier || node.property.name !== operation2)
|
|
5023
5132
|
return false;
|
|
5024
5133
|
const receiver = node.object;
|
|
5025
|
-
return receiver.type ===
|
|
5134
|
+
return receiver.type === import_utils35.AST_NODE_TYPES.MemberExpression && !receiver.computed && !receiver.optional && receiver.object.type === import_utils35.AST_NODE_TYPES.ThisExpression && receiver.property.type === import_utils35.AST_NODE_TYPES.Identifier && receiver.property.name === field;
|
|
5026
5135
|
}
|
|
5027
5136
|
function factoryAuthority(sourceCode, factory, contract, worker, implementation) {
|
|
5028
5137
|
const parameter = factory.params[0];
|
|
5029
|
-
if (parameter?.type !==
|
|
5138
|
+
if (parameter?.type !== import_utils35.AST_NODE_TYPES.Identifier || parameter.optional || !typeReference(sourceCode, parameter.typeAnnotation, worker) || !typeReference(sourceCode, factory.returnType, contract))
|
|
5030
5139
|
return false;
|
|
5031
5140
|
const statement = factory.body.body[0];
|
|
5032
|
-
const constructed = statement?.type ===
|
|
5033
|
-
if (constructed?.type !==
|
|
5141
|
+
const constructed = statement?.type === import_utils35.AST_NODE_TYPES.ReturnStatement ? statement.argument : null;
|
|
5142
|
+
if (constructed?.type !== import_utils35.AST_NODE_TYPES.NewExpression || constructed.typeArguments !== void 0 || constructed.callee.type !== import_utils35.AST_NODE_TYPES.Identifier || !sameBinding(sourceCode, constructed.callee, implementation) || constructed.arguments.length !== 1)
|
|
5034
5143
|
return false;
|
|
5035
5144
|
const argument = constructed.arguments[0];
|
|
5036
|
-
return argument?.type ===
|
|
5145
|
+
return argument?.type === import_utils35.AST_NODE_TYPES.Identifier && argument.name === parameter.name && sameBinding(sourceCode, argument, factory);
|
|
5037
5146
|
}
|
|
5038
5147
|
|
|
5039
5148
|
// src/rules/require-port-for-service.ts
|
|
5040
|
-
var
|
|
5149
|
+
var import_utils36 = require("@typescript-eslint/utils");
|
|
5041
5150
|
var REQUIRE_PORT_FOR_SERVICE_DOCUMENTATION = {
|
|
5042
5151
|
summary: "Advise when an exported service with injected collaborators has public methods not covered by its declared ports.",
|
|
5043
5152
|
rationale: "A declared port keeps consumers coupled to the service capability instead of its concrete implementation.",
|
|
@@ -5121,50 +5230,50 @@ var STORAGE_ASSIGNMENT_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
5121
5230
|
"||="
|
|
5122
5231
|
]);
|
|
5123
5232
|
var staticMemberName = (member3) => {
|
|
5124
|
-
if (member3.property.type ===
|
|
5233
|
+
if (member3.property.type === import_utils36.AST_NODE_TYPES.PrivateIdentifier)
|
|
5125
5234
|
return `#${member3.property.name}`;
|
|
5126
|
-
return
|
|
5235
|
+
return import_utils36.ASTUtils.getPropertyName(member3);
|
|
5127
5236
|
};
|
|
5128
5237
|
var detachedValueExports = (program) => {
|
|
5129
5238
|
const names = /* @__PURE__ */ new Set();
|
|
5130
5239
|
for (const statement of program.body) {
|
|
5131
|
-
if (statement.type ===
|
|
5240
|
+
if (statement.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration && statement.declaration === null && statement.source === null && statement.exportKind !== "type") {
|
|
5132
5241
|
for (const specifier of statement.specifiers) {
|
|
5133
5242
|
if (specifier.exportKind !== "type") names.add(specifier.local.name);
|
|
5134
5243
|
}
|
|
5135
|
-
} else if (statement.type ===
|
|
5244
|
+
} else if (statement.type === import_utils36.AST_NODE_TYPES.ExportDefaultDeclaration && statement.declaration.type === import_utils36.AST_NODE_TYPES.Identifier) {
|
|
5136
5245
|
names.add(statement.declaration.name);
|
|
5137
|
-
} else if (statement.type ===
|
|
5246
|
+
} else if (statement.type === import_utils36.AST_NODE_TYPES.TSExportAssignment && statement.expression.type === import_utils36.AST_NODE_TYPES.Identifier) {
|
|
5138
5247
|
names.add(statement.expression.name);
|
|
5139
5248
|
}
|
|
5140
5249
|
}
|
|
5141
5250
|
return names;
|
|
5142
5251
|
};
|
|
5143
|
-
var isExportedClass = (node, detached) => node.parent.type ===
|
|
5252
|
+
var isExportedClass = (node, detached) => node.parent.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration || node.parent.type === import_utils36.AST_NODE_TYPES.ExportDefaultDeclaration || node.id !== null && detached.has(node.id.name);
|
|
5144
5253
|
var createExportedServiceClassResolver = (program) => {
|
|
5145
5254
|
const detached = detachedValueExports(program);
|
|
5146
5255
|
return (node) => isExportedClass(node, detached);
|
|
5147
5256
|
};
|
|
5148
5257
|
var readTypeReference = (annotation) => {
|
|
5149
|
-
if (annotation?.type ===
|
|
5258
|
+
if (annotation?.type === import_utils36.AST_NODE_TYPES.TSUnionType) {
|
|
5150
5259
|
const members = annotation.types.filter(
|
|
5151
|
-
(member3) => member3.type !==
|
|
5260
|
+
(member3) => member3.type !== import_utils36.AST_NODE_TYPES.TSUndefinedKeyword && member3.type !== import_utils36.AST_NODE_TYPES.TSNullKeyword
|
|
5152
5261
|
);
|
|
5153
5262
|
annotation = members.length === 1 ? members[0] : void 0;
|
|
5154
5263
|
}
|
|
5155
|
-
if (annotation === void 0 || annotation.type !==
|
|
5264
|
+
if (annotation === void 0 || annotation.type !== import_utils36.AST_NODE_TYPES.TSTypeReference)
|
|
5156
5265
|
return null;
|
|
5157
5266
|
const { typeName } = annotation;
|
|
5158
|
-
const rightmost = typeName.type ===
|
|
5267
|
+
const rightmost = typeName.type === import_utils36.AST_NODE_TYPES.Identifier ? typeName.name : typeName.type === import_utils36.AST_NODE_TYPES.TSQualifiedName ? typeName.right.name : null;
|
|
5159
5268
|
if (rightmost === null) return null;
|
|
5160
5269
|
return { typeName: rightmost, display: qualifiedName(typeName) };
|
|
5161
5270
|
};
|
|
5162
|
-
var qualifiedName = (name) => name.type ===
|
|
5271
|
+
var qualifiedName = (name) => name.type === import_utils36.AST_NODE_TYPES.Identifier ? name.name : name.type === import_utils36.AST_NODE_TYPES.TSQualifiedName ? `${qualifiedName(name.left)}.${name.right.name}` : "";
|
|
5163
5272
|
var propertySignatureTypes = (members) => {
|
|
5164
5273
|
const types = /* @__PURE__ */ new Map();
|
|
5165
5274
|
for (const member3 of members) {
|
|
5166
|
-
if (member3.type !==
|
|
5167
|
-
if (member3.computed || member3.key.type !==
|
|
5275
|
+
if (member3.type !== import_utils36.AST_NODE_TYPES.TSPropertySignature) continue;
|
|
5276
|
+
if (member3.computed || member3.key.type !== import_utils36.AST_NODE_TYPES.Identifier)
|
|
5168
5277
|
continue;
|
|
5169
5278
|
const reference = readTypeReference(member3.typeAnnotation?.typeAnnotation);
|
|
5170
5279
|
if (reference === null) continue;
|
|
@@ -5176,18 +5285,18 @@ var fileTypeIndex = (program) => {
|
|
|
5176
5285
|
const objects = /* @__PURE__ */ new Map();
|
|
5177
5286
|
const functionAliases = localFunctionAliases(program);
|
|
5178
5287
|
function collectDeclaredType(statement) {
|
|
5179
|
-
const declaration = statement.type ===
|
|
5180
|
-
if (declaration?.type ===
|
|
5288
|
+
const declaration = statement.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
|
|
5289
|
+
if (declaration?.type === import_utils36.AST_NODE_TYPES.TSInterfaceDeclaration) {
|
|
5181
5290
|
objects.set(
|
|
5182
5291
|
declaration.id.name,
|
|
5183
5292
|
propertySignatureTypes(declaration.body.body)
|
|
5184
5293
|
);
|
|
5185
5294
|
return;
|
|
5186
5295
|
}
|
|
5187
|
-
if (declaration?.type !==
|
|
5296
|
+
if (declaration?.type !== import_utils36.AST_NODE_TYPES.TSTypeAliasDeclaration) return;
|
|
5188
5297
|
const aliased = declaration.typeAnnotation;
|
|
5189
|
-
const literals = aliased.type ===
|
|
5190
|
-
(part) => part.type ===
|
|
5298
|
+
const literals = aliased.type === import_utils36.AST_NODE_TYPES.TSTypeLiteral ? [aliased] : aliased.type === import_utils36.AST_NODE_TYPES.TSIntersectionType ? aliased.types.filter(
|
|
5299
|
+
(part) => part.type === import_utils36.AST_NODE_TYPES.TSTypeLiteral
|
|
5191
5300
|
) : [];
|
|
5192
5301
|
if (literals.length === 0) return;
|
|
5193
5302
|
const merged = /* @__PURE__ */ new Map();
|
|
@@ -5207,12 +5316,12 @@ function localFunctionAliases(program) {
|
|
|
5207
5316
|
const names = /* @__PURE__ */ new Set();
|
|
5208
5317
|
const parents = /* @__PURE__ */ new Map();
|
|
5209
5318
|
for (const statement of program.body) {
|
|
5210
|
-
const declaration = statement.type ===
|
|
5211
|
-
if (declaration?.type !==
|
|
5319
|
+
const declaration = statement.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
|
|
5320
|
+
if (declaration?.type !== import_utils36.AST_NODE_TYPES.TSTypeAliasDeclaration) continue;
|
|
5212
5321
|
const annotation = declaration.typeAnnotation;
|
|
5213
|
-
if (annotation.type ===
|
|
5322
|
+
if (annotation.type === import_utils36.AST_NODE_TYPES.TSFunctionType || annotation.type === import_utils36.AST_NODE_TYPES.TSConstructorType)
|
|
5214
5323
|
names.add(declaration.id.name);
|
|
5215
|
-
if (annotation.type ===
|
|
5324
|
+
if (annotation.type === import_utils36.AST_NODE_TYPES.TSTypeReference && annotation.typeName.type === import_utils36.AST_NODE_TYPES.Identifier)
|
|
5216
5325
|
parents.set(declaration.id.name, annotation.typeName.name);
|
|
5217
5326
|
}
|
|
5218
5327
|
for (let pass = 0; pass < parents.size; pass += 1) {
|
|
@@ -5248,32 +5357,32 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
5248
5357
|
function scanStoredFields(body4) {
|
|
5249
5358
|
const pending = [...body4.body];
|
|
5250
5359
|
function recordStoredField(current) {
|
|
5251
|
-
if (current.type ===
|
|
5360
|
+
if (current.type === import_utils36.AST_NODE_TYPES.ArrowFunctionExpression || current.type === import_utils36.AST_NODE_TYPES.FunctionExpression || current.type === import_utils36.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils36.AST_NODE_TYPES.ClassExpression || current.type === import_utils36.AST_NODE_TYPES.ClassDeclaration)
|
|
5252
5361
|
return;
|
|
5253
|
-
if (current.type ===
|
|
5362
|
+
if (current.type === import_utils36.AST_NODE_TYPES.VariableDeclarator && current.id.type === import_utils36.AST_NODE_TYPES.Identifier)
|
|
5254
5363
|
localBindings2.add(current.id.name);
|
|
5255
|
-
const expression = current.type ===
|
|
5364
|
+
const expression = current.type === import_utils36.AST_NODE_TYPES.AssignmentExpression ? current : null;
|
|
5256
5365
|
const storedField = writtenInstanceField(current);
|
|
5257
5366
|
if (storedField !== null) {
|
|
5258
5367
|
if (writtenFieldNames.has(storedField))
|
|
5259
5368
|
unstableFieldNames.add(storedField);
|
|
5260
5369
|
writtenFieldNames.add(storedField);
|
|
5261
|
-
if (expression?.operator !== "=" || expression.parent.type !==
|
|
5370
|
+
if (expression?.operator !== "=" || expression.parent.type !== import_utils36.AST_NODE_TYPES.ExpressionStatement || expression.parent.parent !== body4)
|
|
5262
5371
|
unstableFieldNames.add(storedField);
|
|
5263
5372
|
}
|
|
5264
|
-
if (expression?.type !==
|
|
5373
|
+
if (expression?.type !== import_utils36.AST_NODE_TYPES.AssignmentExpression || !STORAGE_ASSIGNMENT_OPERATORS.has(expression.operator) || expression.left.type !== import_utils36.AST_NODE_TYPES.MemberExpression || expression.left.object.type !== import_utils36.AST_NODE_TYPES.ThisExpression || storedField === null) {
|
|
5265
5374
|
enqueueChildren(current);
|
|
5266
5375
|
return;
|
|
5267
5376
|
}
|
|
5268
5377
|
const source = unwrapExpression(expression.right);
|
|
5269
|
-
if (source.type ===
|
|
5378
|
+
if (source.type === import_utils36.AST_NODE_TYPES.NewExpression) {
|
|
5270
5379
|
constructedFields += 1;
|
|
5271
5380
|
constructedFieldNames.add(storedField);
|
|
5272
|
-
} else if (source.type ===
|
|
5381
|
+
} else if (source.type === import_utils36.AST_NODE_TYPES.Identifier) {
|
|
5273
5382
|
const fields2 = storedFieldsFrom.get(source.name) ?? /* @__PURE__ */ new Set();
|
|
5274
5383
|
fields2.add(storedField);
|
|
5275
5384
|
storedFieldsFrom.set(source.name, fields2);
|
|
5276
|
-
} else if (source.type ===
|
|
5385
|
+
} else if (source.type === import_utils36.AST_NODE_TYPES.MemberExpression && source.object.type === import_utils36.AST_NODE_TYPES.Identifier) {
|
|
5277
5386
|
const fields2 = storedFieldsFrom.get(source.object.name) ?? /* @__PURE__ */ new Set();
|
|
5278
5387
|
fields2.add(storedField);
|
|
5279
5388
|
storedFieldsFrom.set(source.object.name, fields2);
|
|
@@ -5308,7 +5417,7 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
5308
5417
|
)) {
|
|
5309
5418
|
if (localBindings2.has(reference.name)) continue;
|
|
5310
5419
|
let fields2 = reference.fields;
|
|
5311
|
-
if (parameter.type ===
|
|
5420
|
+
if (parameter.type === import_utils36.AST_NODE_TYPES.TSParameterProperty) {
|
|
5312
5421
|
if (writtenFieldNames.has(reference.name)) continue;
|
|
5313
5422
|
fields2 = [reference.name];
|
|
5314
5423
|
} else if (fields2.length === 0)
|
|
@@ -5331,8 +5440,8 @@ var readConstructor = (ctor, declared, typeParameters) => {
|
|
|
5331
5440
|
};
|
|
5332
5441
|
var parameterCollaborators = (parameter, declared, storedMemberFieldsFrom) => {
|
|
5333
5442
|
let target = parameter;
|
|
5334
|
-
if (target.type ===
|
|
5335
|
-
if (target.type ===
|
|
5443
|
+
if (target.type === import_utils36.AST_NODE_TYPES.AssignmentPattern) target = target.left;
|
|
5444
|
+
if (target.type === import_utils36.AST_NODE_TYPES.ObjectPattern) {
|
|
5336
5445
|
return objectPatternCollaborators(target, declared);
|
|
5337
5446
|
}
|
|
5338
5447
|
const named3 = namedParameterCollaborator(parameter);
|
|
@@ -5342,10 +5451,10 @@ var parameterCollaborators = (parameter, declared, storedMemberFieldsFrom) => {
|
|
|
5342
5451
|
};
|
|
5343
5452
|
var namedBagCollaborators = (annotated, declared, storedMemberFieldsFrom) => {
|
|
5344
5453
|
let target = annotated;
|
|
5345
|
-
if (target.type ===
|
|
5454
|
+
if (target.type === import_utils36.AST_NODE_TYPES.TSParameterProperty)
|
|
5346
5455
|
target = target.parameter;
|
|
5347
|
-
if (target.type ===
|
|
5348
|
-
if (target.type !==
|
|
5456
|
+
if (target.type === import_utils36.AST_NODE_TYPES.AssignmentPattern) target = target.left;
|
|
5457
|
+
if (target.type !== import_utils36.AST_NODE_TYPES.Identifier) return [];
|
|
5349
5458
|
const members = bagMemberTypes(
|
|
5350
5459
|
target.typeAnnotation?.typeAnnotation,
|
|
5351
5460
|
declared
|
|
@@ -5364,10 +5473,10 @@ var namedBagCollaborators = (annotated, declared, storedMemberFieldsFrom) => {
|
|
|
5364
5473
|
};
|
|
5365
5474
|
var namedParameterCollaborator = (annotated) => {
|
|
5366
5475
|
let target = annotated;
|
|
5367
|
-
if (target.type ===
|
|
5476
|
+
if (target.type === import_utils36.AST_NODE_TYPES.TSParameterProperty)
|
|
5368
5477
|
target = target.parameter;
|
|
5369
|
-
if (target.type ===
|
|
5370
|
-
if (target.type !==
|
|
5478
|
+
if (target.type === import_utils36.AST_NODE_TYPES.AssignmentPattern) target = target.left;
|
|
5479
|
+
if (target.type !== import_utils36.AST_NODE_TYPES.Identifier) return null;
|
|
5371
5480
|
const reference = readTypeReference(target.typeAnnotation?.typeAnnotation);
|
|
5372
5481
|
if (reference === null) return null;
|
|
5373
5482
|
return { name: target.name, ...reference, fields: [] };
|
|
@@ -5379,12 +5488,12 @@ var objectPatternCollaborators = (pattern, declared) => {
|
|
|
5379
5488
|
if (members === null) return [];
|
|
5380
5489
|
const collaborators = [];
|
|
5381
5490
|
for (const property of pattern.properties) {
|
|
5382
|
-
if (property.type !==
|
|
5491
|
+
if (property.type !== import_utils36.AST_NODE_TYPES.Property || property.computed)
|
|
5383
5492
|
continue;
|
|
5384
|
-
if (property.key.type !==
|
|
5493
|
+
if (property.key.type !== import_utils36.AST_NODE_TYPES.Identifier) continue;
|
|
5385
5494
|
const key = property.key.name;
|
|
5386
|
-
const bound = property.value.type ===
|
|
5387
|
-
if (bound.type !==
|
|
5495
|
+
const bound = property.value.type === import_utils36.AST_NODE_TYPES.AssignmentPattern ? property.value.left : property.value;
|
|
5496
|
+
if (bound.type !== import_utils36.AST_NODE_TYPES.Identifier) continue;
|
|
5388
5497
|
if (CONFIGISH_NAME_RE.test(key)) continue;
|
|
5389
5498
|
const reference = members.get(key);
|
|
5390
5499
|
if (reference === void 0) continue;
|
|
@@ -5394,22 +5503,22 @@ var objectPatternCollaborators = (pattern, declared) => {
|
|
|
5394
5503
|
};
|
|
5395
5504
|
var bagMemberTypes = (annotation, declared) => {
|
|
5396
5505
|
if (annotation === void 0) return null;
|
|
5397
|
-
if (annotation.type ===
|
|
5506
|
+
if (annotation.type === import_utils36.AST_NODE_TYPES.TSTypeLiteral) {
|
|
5398
5507
|
return propertySignatureTypes(annotation.members);
|
|
5399
5508
|
}
|
|
5400
|
-
if (annotation.type !==
|
|
5509
|
+
if (annotation.type !== import_utils36.AST_NODE_TYPES.TSTypeReference || annotation.typeName.type !== import_utils36.AST_NODE_TYPES.Identifier) {
|
|
5401
5510
|
return null;
|
|
5402
5511
|
}
|
|
5403
5512
|
return declared().objects.get(annotation.typeName.name) ?? null;
|
|
5404
5513
|
};
|
|
5405
5514
|
var isFrameworkWiring = (body3) => subtreeHas(body3, (node) => {
|
|
5406
|
-
if (node.type ===
|
|
5515
|
+
if (node.type === import_utils36.AST_NODE_TYPES.CallExpression) {
|
|
5407
5516
|
const { callee } = node;
|
|
5408
|
-
if (callee.type ===
|
|
5517
|
+
if (callee.type === import_utils36.AST_NODE_TYPES.Identifier)
|
|
5409
5518
|
return callee.name === ROUTER_FACTORY_NAME;
|
|
5410
|
-
return callee.type ===
|
|
5519
|
+
return callee.type === import_utils36.AST_NODE_TYPES.MemberExpression && !callee.computed && callee.property.type === import_utils36.AST_NODE_TYPES.Identifier && callee.property.name === ROUTER_FACTORY_NAME;
|
|
5411
5520
|
}
|
|
5412
|
-
return node.type ===
|
|
5521
|
+
return node.type === import_utils36.AST_NODE_TYPES.TSTypeReference && node.typeName.type === import_utils36.AST_NODE_TYPES.TSQualifiedName && FRAMEWORK_HTTP_TYPES.has(node.typeName.right.name);
|
|
5413
5522
|
});
|
|
5414
5523
|
var subtreeHas = (root, found) => {
|
|
5415
5524
|
let hit = false;
|
|
@@ -5429,26 +5538,26 @@ var subtreeHas = (root, found) => {
|
|
|
5429
5538
|
};
|
|
5430
5539
|
var invokedInstanceField = (call) => {
|
|
5431
5540
|
let callee = unwrapExpression(call.callee);
|
|
5432
|
-
while (callee.type ===
|
|
5541
|
+
while (callee.type === import_utils36.AST_NODE_TYPES.ChainExpression)
|
|
5433
5542
|
callee = unwrapExpression(callee.expression);
|
|
5434
5543
|
const direct = instanceField(callee);
|
|
5435
5544
|
if (direct !== null) return direct;
|
|
5436
|
-
return callee.type ===
|
|
5545
|
+
return callee.type === import_utils36.AST_NODE_TYPES.MemberExpression ? instanceField(unwrapExpression(callee.object)) : null;
|
|
5437
5546
|
};
|
|
5438
5547
|
var instanceField = (candidate2) => {
|
|
5439
5548
|
let node = candidate2;
|
|
5440
|
-
while (node.type ===
|
|
5549
|
+
while (node.type === import_utils36.AST_NODE_TYPES.ChainExpression || node.type === import_utils36.AST_NODE_TYPES.TSAsExpression || node.type === import_utils36.AST_NODE_TYPES.TSNonNullExpression || node.type === import_utils36.AST_NODE_TYPES.TSSatisfiesExpression || node.type === import_utils36.AST_NODE_TYPES.TSTypeAssertion)
|
|
5441
5550
|
node = node.expression;
|
|
5442
|
-
return node.type ===
|
|
5551
|
+
return node.type === import_utils36.AST_NODE_TYPES.MemberExpression && node.object.type === import_utils36.AST_NODE_TYPES.ThisExpression ? staticMemberName(node) : null;
|
|
5443
5552
|
};
|
|
5444
5553
|
function writtenInstanceField(node) {
|
|
5445
|
-
if (node.type ===
|
|
5554
|
+
if (node.type === import_utils36.AST_NODE_TYPES.AssignmentExpression || node.type === import_utils36.AST_NODE_TYPES.ForOfStatement || node.type === import_utils36.AST_NODE_TYPES.ForInStatement)
|
|
5446
5555
|
return instanceField(node.left);
|
|
5447
|
-
if (node.type ===
|
|
5556
|
+
if (node.type === import_utils36.AST_NODE_TYPES.UpdateExpression)
|
|
5448
5557
|
return instanceField(node.argument);
|
|
5449
|
-
if (node.type ===
|
|
5558
|
+
if (node.type === import_utils36.AST_NODE_TYPES.UnaryExpression && node.operator === "delete")
|
|
5450
5559
|
return instanceField(node.argument);
|
|
5451
|
-
if (node.type ===
|
|
5560
|
+
if (node.type === import_utils36.AST_NODE_TYPES.MemberExpression && isDestructuredWriteTarget(node))
|
|
5452
5561
|
return instanceField(node);
|
|
5453
5562
|
return null;
|
|
5454
5563
|
}
|
|
@@ -5457,39 +5566,39 @@ function isDestructuredWriteTarget(node) {
|
|
|
5457
5566
|
let target = access;
|
|
5458
5567
|
for (; ; ) {
|
|
5459
5568
|
const parent = target.parent;
|
|
5460
|
-
if (parent.type ===
|
|
5569
|
+
if (parent.type === import_utils36.AST_NODE_TYPES.Property && parent.value === target && parent.parent.type === import_utils36.AST_NODE_TYPES.ObjectPattern) {
|
|
5461
5570
|
target = parent.parent;
|
|
5462
5571
|
continue;
|
|
5463
5572
|
}
|
|
5464
|
-
if (parent.type ===
|
|
5573
|
+
if (parent.type === import_utils36.AST_NODE_TYPES.ArrayPattern || parent.type === import_utils36.AST_NODE_TYPES.ObjectPattern || parent.type === import_utils36.AST_NODE_TYPES.RestElement && parent.argument === target || parent.type === import_utils36.AST_NODE_TYPES.AssignmentPattern && parent.left === target) {
|
|
5465
5574
|
target = parent;
|
|
5466
5575
|
continue;
|
|
5467
5576
|
}
|
|
5468
|
-
return target !== access && (parent.type ===
|
|
5577
|
+
return target !== access && (parent.type === import_utils36.AST_NODE_TYPES.AssignmentExpression || parent.type === import_utils36.AST_NODE_TYPES.ForOfStatement || parent.type === import_utils36.AST_NODE_TYPES.ForInStatement) && parent.left === target;
|
|
5469
5578
|
}
|
|
5470
5579
|
}
|
|
5471
5580
|
var behaviorallyInvokedFields = (body3) => {
|
|
5472
5581
|
const invoked = /* @__PURE__ */ new Set();
|
|
5473
5582
|
const visit = (current) => {
|
|
5474
|
-
if (current.type ===
|
|
5583
|
+
if (current.type === import_utils36.AST_NODE_TYPES.ClassDeclaration || current.type === import_utils36.AST_NODE_TYPES.ClassExpression || current.type === import_utils36.AST_NODE_TYPES.FunctionDeclaration || current.type === import_utils36.AST_NODE_TYPES.FunctionExpression)
|
|
5475
5584
|
return;
|
|
5476
|
-
if (current.type ===
|
|
5585
|
+
if (current.type === import_utils36.AST_NODE_TYPES.CallExpression) {
|
|
5477
5586
|
const field = invokedInstanceField(current);
|
|
5478
5587
|
if (field !== null) invoked.add(field);
|
|
5479
5588
|
}
|
|
5480
5589
|
forEachOwnAstChild(current, visit);
|
|
5481
5590
|
};
|
|
5482
5591
|
for (const member3 of body3.body) {
|
|
5483
|
-
if (member3.type ===
|
|
5484
|
-
if (member3.type ===
|
|
5592
|
+
if (member3.type === import_utils36.AST_NODE_TYPES.StaticBlock || member3.static) continue;
|
|
5593
|
+
if (member3.type === import_utils36.AST_NODE_TYPES.MethodDefinition) {
|
|
5485
5594
|
if (member3.value.body !== null && member3.value.body !== void 0)
|
|
5486
5595
|
visit(member3.value.body);
|
|
5487
5596
|
continue;
|
|
5488
5597
|
}
|
|
5489
|
-
if (member3.type !==
|
|
5598
|
+
if (member3.type !== import_utils36.AST_NODE_TYPES.PropertyDefinition || member3.value === null)
|
|
5490
5599
|
continue;
|
|
5491
5600
|
visit(
|
|
5492
|
-
member3.value.type ===
|
|
5601
|
+
member3.value.type === import_utils36.AST_NODE_TYPES.ArrowFunctionExpression ? member3.value.body : member3.value
|
|
5493
5602
|
);
|
|
5494
5603
|
}
|
|
5495
5604
|
return invoked;
|
|
@@ -5509,8 +5618,8 @@ var isTransportWrapper = (className, collaborators, program) => {
|
|
|
5509
5618
|
var fileInterfaceNames = (program) => {
|
|
5510
5619
|
const names = [];
|
|
5511
5620
|
for (const statement of program.body) {
|
|
5512
|
-
const declaration = statement.type ===
|
|
5513
|
-
if (declaration?.type ===
|
|
5621
|
+
const declaration = statement.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
|
|
5622
|
+
if (declaration?.type === import_utils36.AST_NODE_TYPES.TSInterfaceDeclaration)
|
|
5514
5623
|
names.push(declaration.id.name);
|
|
5515
5624
|
}
|
|
5516
5625
|
return names;
|
|
@@ -5518,22 +5627,22 @@ var fileInterfaceNames = (program) => {
|
|
|
5518
5627
|
var publicMethodNames = (body3, functionAliases) => {
|
|
5519
5628
|
const names = [];
|
|
5520
5629
|
function collectPublicCallable(member3) {
|
|
5521
|
-
if (member3.type ===
|
|
5630
|
+
if (member3.type === import_utils36.AST_NODE_TYPES.PropertyDefinition) {
|
|
5522
5631
|
if (member3.static || member3.accessibility === "private" || member3.accessibility === "protected")
|
|
5523
5632
|
return;
|
|
5524
|
-
if (member3.key.type ===
|
|
5525
|
-
if (member3.value?.type !==
|
|
5633
|
+
if (member3.key.type === import_utils36.AST_NODE_TYPES.PrivateIdentifier) return;
|
|
5634
|
+
if (member3.value?.type !== import_utils36.AST_NODE_TYPES.ArrowFunctionExpression && member3.value?.type !== import_utils36.AST_NODE_TYPES.FunctionExpression && member3.typeAnnotation?.typeAnnotation.type !== import_utils36.AST_NODE_TYPES.TSFunctionType && !(member3.typeAnnotation?.typeAnnotation.type === import_utils36.AST_NODE_TYPES.TSTypeReference && member3.typeAnnotation.typeAnnotation.typeName.type === import_utils36.AST_NODE_TYPES.Identifier && functionAliases.has(
|
|
5526
5635
|
member3.typeAnnotation.typeAnnotation.typeName.name
|
|
5527
5636
|
)))
|
|
5528
5637
|
return;
|
|
5529
5638
|
names.push(declaredMemberName(member3) ?? "\u2026");
|
|
5530
5639
|
return;
|
|
5531
5640
|
}
|
|
5532
|
-
if (member3.type !==
|
|
5641
|
+
if (member3.type !== import_utils36.AST_NODE_TYPES.MethodDefinition) return;
|
|
5533
5642
|
if (member3.kind !== "method" || member3.static) return;
|
|
5534
5643
|
if (member3.accessibility === "private" || member3.accessibility === "protected")
|
|
5535
5644
|
return;
|
|
5536
|
-
if (member3.key.type ===
|
|
5645
|
+
if (member3.key.type === import_utils36.AST_NODE_TYPES.PrivateIdentifier) return;
|
|
5537
5646
|
names.push(declaredMemberName(member3) ?? "\u2026");
|
|
5538
5647
|
}
|
|
5539
5648
|
for (const member3 of body3.body) {
|
|
@@ -5544,13 +5653,13 @@ var publicMethodNames = (body3, functionAliases) => {
|
|
|
5544
5653
|
var isFluentConstructionObject = (node, getText) => {
|
|
5545
5654
|
if (node.id === null) return false;
|
|
5546
5655
|
const methods = node.body.body.filter(
|
|
5547
|
-
(member3) => member3.type ===
|
|
5656
|
+
(member3) => member3.type === import_utils36.AST_NODE_TYPES.MethodDefinition && member3.kind === "method" && !member3.static && member3.accessibility !== "private" && member3.accessibility !== "protected" && member3.value.body !== null
|
|
5548
5657
|
);
|
|
5549
5658
|
if (methods.length === 0) return false;
|
|
5550
5659
|
return methods.every((member3) => {
|
|
5551
5660
|
const result = member3.value.returnType?.typeAnnotation;
|
|
5552
5661
|
if (result === void 0) return false;
|
|
5553
|
-
const returnsOwnType = result.type ===
|
|
5662
|
+
const returnsOwnType = result.type === import_utils36.AST_NODE_TYPES.TSTypeReference && result.typeName.type === import_utils36.AST_NODE_TYPES.Identifier && result.typeName.name === node.id?.name;
|
|
5554
5663
|
return returnsOwnType || FLUENT_BUILDER_NAME_RE.test(node.id?.name ?? "") && FLUENT_RESULT_TYPE_RE.test(getText(result));
|
|
5555
5664
|
});
|
|
5556
5665
|
};
|
|
@@ -5558,10 +5667,10 @@ function localClassAbstractness(program) {
|
|
|
5558
5667
|
const classes = /* @__PURE__ */ new Map();
|
|
5559
5668
|
const parents = /* @__PURE__ */ new Map();
|
|
5560
5669
|
for (const statement of program.body) {
|
|
5561
|
-
const declaration = statement.type ===
|
|
5562
|
-
if (declaration?.type ===
|
|
5670
|
+
const declaration = statement.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration || statement.type === import_utils36.AST_NODE_TYPES.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
5671
|
+
if (declaration?.type === import_utils36.AST_NODE_TYPES.ClassDeclaration && declaration.id !== null) {
|
|
5563
5672
|
classes.set(declaration.id.name, declaration.abstract === true);
|
|
5564
|
-
if (declaration.superClass?.type ===
|
|
5673
|
+
if (declaration.superClass?.type === import_utils36.AST_NODE_TYPES.Identifier) {
|
|
5565
5674
|
parents.set(declaration.id.name, declaration.superClass.name);
|
|
5566
5675
|
}
|
|
5567
5676
|
}
|
|
@@ -5579,9 +5688,9 @@ function localClassAbstractness(program) {
|
|
|
5579
5688
|
return classes;
|
|
5580
5689
|
}
|
|
5581
5690
|
function declaredMemberName(member3) {
|
|
5582
|
-
if (!member3.computed && member3.key.type ===
|
|
5691
|
+
if (!member3.computed && member3.key.type === import_utils36.AST_NODE_TYPES.Identifier)
|
|
5583
5692
|
return member3.key.name;
|
|
5584
|
-
if (member3.key.type ===
|
|
5693
|
+
if (member3.key.type === import_utils36.AST_NODE_TYPES.Literal && typeof member3.key.value === "string")
|
|
5585
5694
|
return member3.key.value;
|
|
5586
5695
|
return null;
|
|
5587
5696
|
}
|
|
@@ -5590,35 +5699,35 @@ function localInterfaceSurfaces(program) {
|
|
|
5590
5699
|
const parents = /* @__PURE__ */ new Map();
|
|
5591
5700
|
const functionAliases = localFunctionAliases(program);
|
|
5592
5701
|
function collectInterfaceSurface(statement) {
|
|
5593
|
-
const declaration = statement.type ===
|
|
5594
|
-
if (declaration?.type ===
|
|
5702
|
+
const declaration = statement.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration ? statement.declaration : statement;
|
|
5703
|
+
if (declaration?.type === import_utils36.AST_NODE_TYPES.TSTypeAliasDeclaration) {
|
|
5595
5704
|
const callables2 = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
|
|
5596
|
-
const parts = declaration.typeAnnotation.type ===
|
|
5705
|
+
const parts = declaration.typeAnnotation.type === import_utils36.AST_NODE_TYPES.TSIntersectionType ? declaration.typeAnnotation.types : [declaration.typeAnnotation];
|
|
5597
5706
|
const inherited = parents.get(declaration.id.name) ?? [];
|
|
5598
5707
|
for (const part of parts) {
|
|
5599
|
-
if (part.type ===
|
|
5708
|
+
if (part.type === import_utils36.AST_NODE_TYPES.TSTypeReference && part.typeName.type === import_utils36.AST_NODE_TYPES.Identifier) {
|
|
5600
5709
|
inherited.push(part.typeName.name);
|
|
5601
5710
|
continue;
|
|
5602
5711
|
}
|
|
5603
|
-
if (part.type ===
|
|
5712
|
+
if (part.type === import_utils36.AST_NODE_TYPES.TSTypeReference) {
|
|
5604
5713
|
inherited.push("*");
|
|
5605
5714
|
continue;
|
|
5606
5715
|
}
|
|
5607
|
-
if (part.type !==
|
|
5716
|
+
if (part.type !== import_utils36.AST_NODE_TYPES.TSTypeLiteral) continue;
|
|
5608
5717
|
addCallableMembers(part.members, callables2);
|
|
5609
5718
|
}
|
|
5610
5719
|
interfaces.set(declaration.id.name, callables2);
|
|
5611
5720
|
parents.set(declaration.id.name, inherited);
|
|
5612
5721
|
return;
|
|
5613
5722
|
}
|
|
5614
|
-
if (declaration?.type !==
|
|
5723
|
+
if (declaration?.type !== import_utils36.AST_NODE_TYPES.TSInterfaceDeclaration) return;
|
|
5615
5724
|
const callables = interfaces.get(declaration.id.name) ?? /* @__PURE__ */ new Set();
|
|
5616
5725
|
addCallableMembers(declaration.body.body, callables);
|
|
5617
5726
|
interfaces.set(declaration.id.name, callables);
|
|
5618
5727
|
parents.set(declaration.id.name, [
|
|
5619
5728
|
...parents.get(declaration.id.name) ?? [],
|
|
5620
5729
|
...declaration.extends.flatMap(
|
|
5621
|
-
(heritage) => heritage.expression.type ===
|
|
5730
|
+
(heritage) => heritage.expression.type === import_utils36.AST_NODE_TYPES.Identifier ? [heritage.expression.name] : ["*"]
|
|
5622
5731
|
)
|
|
5623
5732
|
]);
|
|
5624
5733
|
}
|
|
@@ -5627,17 +5736,17 @@ function localInterfaceSurfaces(program) {
|
|
|
5627
5736
|
}
|
|
5628
5737
|
function addCallableMembers(members, callables) {
|
|
5629
5738
|
for (const member3 of members) {
|
|
5630
|
-
if (member3.type !==
|
|
5739
|
+
if (member3.type !== import_utils36.AST_NODE_TYPES.TSMethodSignature && member3.type !== import_utils36.AST_NODE_TYPES.TSPropertySignature)
|
|
5631
5740
|
continue;
|
|
5632
5741
|
const name = declaredMemberName(member3);
|
|
5633
5742
|
if (name === null) continue;
|
|
5634
|
-
if (member3.type ===
|
|
5743
|
+
if (member3.type === import_utils36.AST_NODE_TYPES.TSMethodSignature) {
|
|
5635
5744
|
callables.add(name);
|
|
5636
5745
|
continue;
|
|
5637
5746
|
}
|
|
5638
|
-
if (member3.type !==
|
|
5747
|
+
if (member3.type !== import_utils36.AST_NODE_TYPES.TSPropertySignature) continue;
|
|
5639
5748
|
const annotation = member3.typeAnnotation?.typeAnnotation;
|
|
5640
|
-
if (annotation?.type ===
|
|
5749
|
+
if (annotation?.type === import_utils36.AST_NODE_TYPES.TSFunctionType || annotation?.type === import_utils36.AST_NODE_TYPES.TSTypeReference && annotation.typeName.type === import_utils36.AST_NODE_TYPES.Identifier && functionAliases.has(annotation.typeName.name))
|
|
5641
5750
|
callables.add(name);
|
|
5642
5751
|
}
|
|
5643
5752
|
}
|
|
@@ -5667,7 +5776,7 @@ function localInterfaceSurfaces(program) {
|
|
|
5667
5776
|
}
|
|
5668
5777
|
function hasServicePort(node, methods, classes, interfaces) {
|
|
5669
5778
|
if (node.superClass !== null) {
|
|
5670
|
-
if (node.superClass.type !==
|
|
5779
|
+
if (node.superClass.type !== import_utils36.AST_NODE_TYPES.Identifier) return true;
|
|
5671
5780
|
const localAbstract = classes.get(node.superClass.name);
|
|
5672
5781
|
if (localAbstract === void 0 || localAbstract) return true;
|
|
5673
5782
|
}
|
|
@@ -5706,7 +5815,7 @@ var require_port_for_service_default = createRule({
|
|
|
5706
5815
|
if (node.abstract === true) return;
|
|
5707
5816
|
if (node.decorators.length > 0) return;
|
|
5708
5817
|
const ctor = node.body.body.find(
|
|
5709
|
-
(member3) => member3.type ===
|
|
5818
|
+
(member3) => member3.type === import_utils36.AST_NODE_TYPES.MethodDefinition && member3.kind === "constructor" && member3.value.body !== null && member3.value.body !== void 0
|
|
5710
5819
|
);
|
|
5711
5820
|
if (ctor === void 0) return;
|
|
5712
5821
|
const constructorFacts = readConstructor(
|
|
@@ -5756,7 +5865,7 @@ var require_port_for_service_default = createRule({
|
|
|
5756
5865
|
function implementedSurfaceCovers(node, methods, classes, interfaces) {
|
|
5757
5866
|
const combined = /* @__PURE__ */ new Set();
|
|
5758
5867
|
for (const implementation of node.implements) {
|
|
5759
|
-
if (implementation.expression.type !==
|
|
5868
|
+
if (implementation.expression.type !== import_utils36.AST_NODE_TYPES.Identifier)
|
|
5760
5869
|
return true;
|
|
5761
5870
|
const name = implementation.expression.name;
|
|
5762
5871
|
const localAbstract = classes.get(name);
|
|
@@ -5773,7 +5882,7 @@ function createServiceOperationResolver(program) {
|
|
|
5773
5882
|
let declaredTypes = null;
|
|
5774
5883
|
return (node) => {
|
|
5775
5884
|
const ctor = node.body.body.find(
|
|
5776
|
-
(member3) => member3.type ===
|
|
5885
|
+
(member3) => member3.type === import_utils36.AST_NODE_TYPES.MethodDefinition && member3.kind === "constructor" && member3.value.body !== null
|
|
5777
5886
|
);
|
|
5778
5887
|
if (ctor === void 0) return [];
|
|
5779
5888
|
const declared = () => declaredTypes ??= fileTypeIndex(program);
|
|
@@ -5791,7 +5900,7 @@ function createServiceOperationResolver(program) {
|
|
|
5791
5900
|
for (const [name, body3] of serviceOperationBodies(node)) {
|
|
5792
5901
|
forEachServiceCall(body3, (call) => {
|
|
5793
5902
|
if (retained.has(invokedInstanceField(call) ?? "")) active.add(name);
|
|
5794
|
-
if (call.callee.type ===
|
|
5903
|
+
if (call.callee.type === import_utils36.AST_NODE_TYPES.MemberExpression && call.callee.object.type === import_utils36.AST_NODE_TYPES.ThisExpression) {
|
|
5795
5904
|
const callee = staticMemberName(call.callee);
|
|
5796
5905
|
if (callee !== null) {
|
|
5797
5906
|
const linked = callers.get(callee) ?? /* @__PURE__ */ new Set();
|
|
@@ -5830,11 +5939,11 @@ function serviceOperationBodies(node) {
|
|
|
5830
5939
|
});
|
|
5831
5940
|
}
|
|
5832
5941
|
for (const member3 of node.body.body) {
|
|
5833
|
-
if (member3.type !==
|
|
5942
|
+
if (member3.type !== import_utils36.AST_NODE_TYPES.MethodDefinition && member3.type !== import_utils36.AST_NODE_TYPES.PropertyDefinition)
|
|
5834
5943
|
continue;
|
|
5835
|
-
if (member3.static || member3.decorators.length > 0 || member3.type ===
|
|
5944
|
+
if (member3.static || member3.decorators.length > 0 || member3.type === import_utils36.AST_NODE_TYPES.MethodDefinition && member3.kind !== "method")
|
|
5836
5945
|
continue;
|
|
5837
|
-
if (member3.value?.type !==
|
|
5946
|
+
if (member3.value?.type !== import_utils36.AST_NODE_TYPES.FunctionExpression && member3.value?.type !== import_utils36.AST_NODE_TYPES.ArrowFunctionExpression)
|
|
5838
5947
|
continue;
|
|
5839
5948
|
const name = declaredMemberName(member3);
|
|
5840
5949
|
if (name !== null && !written.has(name) && member3.value.body !== null)
|
|
@@ -5843,9 +5952,9 @@ function serviceOperationBodies(node) {
|
|
|
5843
5952
|
return bodies;
|
|
5844
5953
|
}
|
|
5845
5954
|
function forEachServiceCall(node, onCall) {
|
|
5846
|
-
if (node.type ===
|
|
5955
|
+
if (node.type === import_utils36.AST_NODE_TYPES.FunctionDeclaration || node.type === import_utils36.AST_NODE_TYPES.FunctionExpression || node.type === import_utils36.AST_NODE_TYPES.ArrowFunctionExpression || node.type === import_utils36.AST_NODE_TYPES.ClassDeclaration || node.type === import_utils36.AST_NODE_TYPES.ClassExpression)
|
|
5847
5956
|
return;
|
|
5848
|
-
if (node.type ===
|
|
5957
|
+
if (node.type === import_utils36.AST_NODE_TYPES.BlockStatement) {
|
|
5849
5958
|
for (const statement of node.body) {
|
|
5850
5959
|
forEachServiceCall(statement, onCall);
|
|
5851
5960
|
if (terminatesOperation(statement)) break;
|
|
@@ -5857,29 +5966,29 @@ function forEachServiceCall(node, onCall) {
|
|
|
5857
5966
|
forEachServiceCall(branch, onCall);
|
|
5858
5967
|
return;
|
|
5859
5968
|
}
|
|
5860
|
-
if (node.type ===
|
|
5969
|
+
if (node.type === import_utils36.AST_NODE_TYPES.CallExpression) onCall(node);
|
|
5861
5970
|
forEachOwnAstChild(node, (child) => {
|
|
5862
5971
|
forEachServiceCall(child, onCall);
|
|
5863
5972
|
});
|
|
5864
5973
|
}
|
|
5865
5974
|
function literalExecutionBranch(node) {
|
|
5866
|
-
if (node.type ===
|
|
5975
|
+
if (node.type === import_utils36.AST_NODE_TYPES.WhileStatement && node.test.type === import_utils36.AST_NODE_TYPES.Literal && node.test.value === false)
|
|
5867
5976
|
return node.test;
|
|
5868
|
-
if ((node.type ===
|
|
5977
|
+
if ((node.type === import_utils36.AST_NODE_TYPES.IfStatement || node.type === import_utils36.AST_NODE_TYPES.ConditionalExpression) && node.test.type === import_utils36.AST_NODE_TYPES.Literal && typeof node.test.value === "boolean") {
|
|
5869
5978
|
return node.test.value ? node.consequent : node.alternate ?? node.test;
|
|
5870
5979
|
}
|
|
5871
|
-
if (node.type !==
|
|
5980
|
+
if (node.type !== import_utils36.AST_NODE_TYPES.LogicalExpression || node.left.type !== import_utils36.AST_NODE_TYPES.Literal || typeof node.left.value !== "boolean")
|
|
5872
5981
|
return null;
|
|
5873
5982
|
if (node.operator === "&&") return node.left.value ? node.right : node.left;
|
|
5874
5983
|
if (node.operator === "||") return node.left.value ? node.left : node.right;
|
|
5875
5984
|
return node.left;
|
|
5876
5985
|
}
|
|
5877
5986
|
function terminatesOperation(node) {
|
|
5878
|
-
if (node.type ===
|
|
5987
|
+
if (node.type === import_utils36.AST_NODE_TYPES.ReturnStatement || node.type === import_utils36.AST_NODE_TYPES.ThrowStatement)
|
|
5879
5988
|
return true;
|
|
5880
|
-
if (node.type ===
|
|
5989
|
+
if (node.type === import_utils36.AST_NODE_TYPES.BlockStatement)
|
|
5881
5990
|
return node.body.some(terminatesOperation);
|
|
5882
|
-
if (node.type !==
|
|
5991
|
+
if (node.type !== import_utils36.AST_NODE_TYPES.IfStatement) return false;
|
|
5883
5992
|
const branch = literalExecutionBranch(node);
|
|
5884
5993
|
if (branch !== null) return terminatesOperation(branch);
|
|
5885
5994
|
return node.alternate !== null && terminatesOperation(node.consequent) && terminatesOperation(node.alternate);
|
|
@@ -5893,7 +6002,7 @@ function hasDeclaredServiceContract(node, operations, program) {
|
|
|
5893
6002
|
const seen = /* @__PURE__ */ new Set();
|
|
5894
6003
|
function addImplementedContracts(current) {
|
|
5895
6004
|
for (const implementation of current.implements) {
|
|
5896
|
-
if (implementation.expression.type !==
|
|
6005
|
+
if (implementation.expression.type !== import_utils36.AST_NODE_TYPES.Identifier)
|
|
5897
6006
|
return false;
|
|
5898
6007
|
const name = implementation.expression.name;
|
|
5899
6008
|
const surface = interfaces.get(name);
|
|
@@ -5916,7 +6025,7 @@ function hasDeclaredServiceContract(node, operations, program) {
|
|
|
5916
6025
|
}
|
|
5917
6026
|
if (!addImplementedContracts(current)) return null;
|
|
5918
6027
|
if (current.superClass === null) continue;
|
|
5919
|
-
if (current.superClass.type !==
|
|
6028
|
+
if (current.superClass.type !== import_utils36.AST_NODE_TYPES.Identifier) return null;
|
|
5920
6029
|
const base = classes.get(current.superClass.name);
|
|
5921
6030
|
if (base === void 0) return null;
|
|
5922
6031
|
pending.push(base);
|
|
@@ -5926,8 +6035,8 @@ function hasDeclaredServiceContract(node, operations, program) {
|
|
|
5926
6035
|
function localClassDeclarations(program) {
|
|
5927
6036
|
const classes = /* @__PURE__ */ new Map();
|
|
5928
6037
|
for (const statement of program.body) {
|
|
5929
|
-
const declaration = statement.type ===
|
|
5930
|
-
if (declaration?.type ===
|
|
6038
|
+
const declaration = statement.type === import_utils36.AST_NODE_TYPES.ExportNamedDeclaration || statement.type === import_utils36.AST_NODE_TYPES.ExportDefaultDeclaration ? statement.declaration : statement;
|
|
6039
|
+
if (declaration?.type === import_utils36.AST_NODE_TYPES.ClassDeclaration && declaration.id !== null)
|
|
5931
6040
|
classes.set(declaration.id.name, declaration);
|
|
5932
6041
|
}
|
|
5933
6042
|
return classes;
|
|
@@ -5935,13 +6044,13 @@ function localClassDeclarations(program) {
|
|
|
5935
6044
|
function abstractContractOperations(node, functionAliases) {
|
|
5936
6045
|
const methods = new Set(publicMethodNames(node.body, functionAliases));
|
|
5937
6046
|
for (const member3 of node.body.body) {
|
|
5938
|
-
if (member3.type !==
|
|
6047
|
+
if (member3.type !== import_utils36.AST_NODE_TYPES.TSAbstractMethodDefinition && member3.type !== import_utils36.AST_NODE_TYPES.TSAbstractPropertyDefinition)
|
|
5939
6048
|
continue;
|
|
5940
6049
|
if (member3.static || member3.accessibility === "private" || member3.accessibility === "protected")
|
|
5941
6050
|
continue;
|
|
5942
|
-
if (member3.type ===
|
|
6051
|
+
if (member3.type === import_utils36.AST_NODE_TYPES.TSAbstractPropertyDefinition) {
|
|
5943
6052
|
const annotation = member3.typeAnnotation?.typeAnnotation;
|
|
5944
|
-
if (annotation?.type !==
|
|
6053
|
+
if (annotation?.type !== import_utils36.AST_NODE_TYPES.TSFunctionType && !(annotation?.type === import_utils36.AST_NODE_TYPES.TSTypeReference && annotation.typeName.type === import_utils36.AST_NODE_TYPES.Identifier && functionAliases.has(annotation.typeName.name)))
|
|
5945
6054
|
continue;
|
|
5946
6055
|
}
|
|
5947
6056
|
const name = declaredMemberName(member3);
|
|
@@ -6077,7 +6186,7 @@ function isServiceRole(name, filename) {
|
|
|
6077
6186
|
}
|
|
6078
6187
|
|
|
6079
6188
|
// src/rules/no-conditional-empty-object-spread.ts
|
|
6080
|
-
var
|
|
6189
|
+
var import_utils38 = require("@typescript-eslint/utils");
|
|
6081
6190
|
var NO_CONDITIONAL_EMPTY_OBJECT_SPREAD_DOCUMENTATION = {
|
|
6082
6191
|
summary: "Build conditional properties explicitly instead of spreading an empty-object branch.",
|
|
6083
6192
|
rationale: "An empty-object conditional spread hides whether a property is omitted, which differs from assigning undefined.",
|
|
@@ -6129,7 +6238,7 @@ var NO_CONDITIONAL_EMPTY_OBJECT_SPREAD_DOCUMENTATION = {
|
|
|
6129
6238
|
]
|
|
6130
6239
|
};
|
|
6131
6240
|
function isEmptyObject(node) {
|
|
6132
|
-
return node.type ===
|
|
6241
|
+
return node.type === import_utils38.AST_NODE_TYPES.ObjectExpression && node.properties.length === 0;
|
|
6133
6242
|
}
|
|
6134
6243
|
var no_conditional_empty_object_spread_default = createRule({
|
|
6135
6244
|
name: "no-conditional-empty-object-spread",
|
|
@@ -6150,13 +6259,13 @@ var no_conditional_empty_object_spread_default = createRule({
|
|
|
6150
6259
|
if (isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
6151
6260
|
return {
|
|
6152
6261
|
SpreadElement(node) {
|
|
6153
|
-
if (node.parent.type !==
|
|
6262
|
+
if (node.parent.type !== import_utils38.AST_NODE_TYPES.ObjectExpression || node.argument.type !== import_utils38.AST_NODE_TYPES.ConditionalExpression)
|
|
6154
6263
|
return;
|
|
6155
6264
|
if (isEmptyObject(node.argument.consequent) || isEmptyObject(node.argument.alternate)) {
|
|
6156
6265
|
const conditional = node.argument;
|
|
6157
6266
|
const emptyConsequent = isEmptyObject(conditional.consequent);
|
|
6158
6267
|
const populated = emptyConsequent ? conditional.alternate : conditional.consequent;
|
|
6159
|
-
const canFix = populated.type ===
|
|
6268
|
+
const canFix = populated.type === import_utils38.AST_NODE_TYPES.ObjectExpression && populated.properties.length > 0 && context.sourceCode.getCommentsInside(conditional).length === 0;
|
|
6160
6269
|
context.report({
|
|
6161
6270
|
node,
|
|
6162
6271
|
messageId: "avoid",
|
|
@@ -6172,7 +6281,7 @@ var no_conditional_empty_object_spread_default = createRule({
|
|
|
6172
6281
|
});
|
|
6173
6282
|
|
|
6174
6283
|
// src/rules/prefer-typed-reflection.ts
|
|
6175
|
-
var
|
|
6284
|
+
var import_utils39 = require("@typescript-eslint/utils");
|
|
6176
6285
|
var import_typescript12 = __toESM(require("typescript"), 1);
|
|
6177
6286
|
var PREFER_TYPED_REFLECTION_DOCUMENTATION = {
|
|
6178
6287
|
summary: "Prefer typed access when Reflect.get or Reflect.apply discards a known contract.",
|
|
@@ -6245,20 +6354,20 @@ var prefer_typed_reflection_default = createRule({
|
|
|
6245
6354
|
if (isGeneratedFile(context, context.sourceCode.text)) return {};
|
|
6246
6355
|
if (!context.sourceCode.parserServices?.program || !context.sourceCode.parserServices.esTreeNodeToTSNodeMap)
|
|
6247
6356
|
return {};
|
|
6248
|
-
const services =
|
|
6357
|
+
const services = import_utils39.ESLintUtils.getParserServices(context);
|
|
6249
6358
|
if (!services.program) return {};
|
|
6250
6359
|
const checker = services.program.getTypeChecker();
|
|
6251
|
-
const isReflect = (node) => globalName(node, "Reflect") || node.type ===
|
|
6252
|
-
const globalName = (node, name) => node.type ===
|
|
6360
|
+
const isReflect = (node) => globalName(node, "Reflect") || node.type === import_utils39.AST_NODE_TYPES.MemberExpression && import_utils39.ASTUtils.getPropertyName(node) === "Reflect" && globalName(node.object, "globalThis");
|
|
6361
|
+
const globalName = (node, name) => node.type === import_utils39.AST_NODE_TYPES.Identifier && node.name === name && !import_utils39.ASTUtils.findVariable(context.sourceCode.getScope(node), name)?.defs.length;
|
|
6253
6362
|
const closedObject = (type) => {
|
|
6254
6363
|
if (type.isUnion()) return type.types.every(closedObject);
|
|
6255
6364
|
return knownType(type) && type.getProperties().length > 0 && checker.getIndexInfosOfType(type).length === 0;
|
|
6256
6365
|
};
|
|
6257
6366
|
const inspectGet = (node, type) => {
|
|
6258
6367
|
const key = node.arguments[1] === void 0 ? void 0 : unwrapExpression(node.arguments[1]);
|
|
6259
|
-
return node.arguments.length === 2 && (staticString(key) !== null || key?.type ===
|
|
6368
|
+
return node.arguments.length === 2 && (staticString(key) !== null || key?.type === import_utils39.AST_NODE_TYPES.Literal && typeof key.value === "number") && closedObject(type);
|
|
6260
6369
|
};
|
|
6261
|
-
const inspectApply = (node, type) => node.arguments.length === 3 && node.arguments[2]?.type ===
|
|
6370
|
+
const inspectApply = (node, type) => node.arguments.length === 3 && node.arguments[2]?.type === import_utils39.AST_NODE_TYPES.ArrayExpression && knownType(type) && type.getCallSignatures().some(
|
|
6262
6371
|
(signature) => signature.typeParameters === void 0 && signature.parameters.every(
|
|
6263
6372
|
(parameter) => knownType(
|
|
6264
6373
|
checker.getTypeOfSymbolAtLocation(
|
|
@@ -6269,25 +6378,25 @@ var prefer_typed_reflection_default = createRule({
|
|
|
6269
6378
|
)
|
|
6270
6379
|
);
|
|
6271
6380
|
const getReplacement = (node, type, target) => {
|
|
6272
|
-
if (node.optional || node.callee.type !==
|
|
6381
|
+
if (node.optional || node.callee.type !== import_utils39.AST_NODE_TYPES.MemberExpression || node.callee.optional || context.sourceCode.getCommentsInside(node).length > 0) return null;
|
|
6273
6382
|
let outer = node;
|
|
6274
|
-
while (outer.parent.type ===
|
|
6275
|
-
if (outer.parent.type ===
|
|
6383
|
+
while (outer.parent.type === import_utils39.AST_NODE_TYPES.TSAsExpression || outer.parent.type === import_utils39.AST_NODE_TYPES.TSTypeAssertion || outer.parent.type === import_utils39.AST_NODE_TYPES.TSSatisfiesExpression || outer.parent.type === import_utils39.AST_NODE_TYPES.TSNonNullExpression || outer.parent.type === import_utils39.AST_NODE_TYPES.ChainExpression) outer = outer.parent;
|
|
6384
|
+
if (outer.parent.type === import_utils39.AST_NODE_TYPES.UnaryExpression && outer.parent.operator === "delete" || outer.parent.type === import_utils39.AST_NODE_TYPES.CallExpression && outer.parent.callee === outer || outer.parent.type === import_utils39.AST_NODE_TYPES.TaggedTemplateExpression && outer.parent.tag === outer) return null;
|
|
6276
6385
|
const writtenKey = node.arguments[1];
|
|
6277
|
-
if (writtenKey === void 0 || writtenKey.type ===
|
|
6386
|
+
if (writtenKey === void 0 || writtenKey.type === import_utils39.AST_NODE_TYPES.SpreadElement) return null;
|
|
6278
6387
|
const key = unwrapExpression(writtenKey);
|
|
6279
|
-
const name = staticString(key) ?? (key.type ===
|
|
6388
|
+
const name = staticString(key) ?? (key.type === import_utils39.AST_NODE_TYPES.Literal && typeof key.value === "number" ? String(key.value) : null);
|
|
6280
6389
|
const members = type.isUnion() ? type.types : [type];
|
|
6281
6390
|
if (name === null || !members.every((member3) => (member3.flags & import_typescript12.default.TypeFlags.Object) !== 0 && checker.getPropertyOfType(member3, name) !== void 0)) return null;
|
|
6282
6391
|
return `(${context.sourceCode.getText(target)})[${context.sourceCode.getText(writtenKey)}]`;
|
|
6283
6392
|
};
|
|
6284
6393
|
return {
|
|
6285
6394
|
CallExpression(node) {
|
|
6286
|
-
if (node.callee.type !==
|
|
6395
|
+
if (node.callee.type !== import_utils39.AST_NODE_TYPES.MemberExpression || !isReflect(node.callee.object))
|
|
6287
6396
|
return;
|
|
6288
|
-
const method =
|
|
6397
|
+
const method = import_utils39.ASTUtils.getPropertyName(node.callee);
|
|
6289
6398
|
const target = node.arguments[0];
|
|
6290
|
-
if (!target || target.type ===
|
|
6399
|
+
if (!target || target.type === import_utils39.AST_NODE_TYPES.SpreadElement || method !== "get" && method !== "apply")
|
|
6291
6400
|
return;
|
|
6292
6401
|
const type = checker.getTypeAtLocation(
|
|
6293
6402
|
services.esTreeNodeToTSNodeMap.get(target)
|
|
@@ -6304,55 +6413,6 @@ var prefer_typed_reflection_default = createRule({
|
|
|
6304
6413
|
// src/rules/no-broad-return-type.ts
|
|
6305
6414
|
var import_utils40 = require("@typescript-eslint/utils");
|
|
6306
6415
|
var import_typescript13 = __toESM(require("typescript"), 1);
|
|
6307
|
-
|
|
6308
|
-
// src/rules/_unused-private-binding.ts
|
|
6309
|
-
var import_utils39 = require("@typescript-eslint/utils");
|
|
6310
|
-
function isUnusedPrivateBinding(sourceCode, declaration, identifier, filename, allowedDeclarations = [declaration]) {
|
|
6311
|
-
if (/\.d\.[cm]?ts$/u.test(filename)) return false;
|
|
6312
|
-
const bindings = sourceCode.getDeclaredVariables(declaration).filter((binding3) => binding3.name === identifier.name);
|
|
6313
|
-
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;
|
|
6314
|
-
if (hasIdentifierNamed(sourceCode.ast, "eval")) return false;
|
|
6315
|
-
const statement = declaration.type === import_utils39.AST_NODE_TYPES.VariableDeclarator ? declaration.parent : declaration;
|
|
6316
|
-
if (statement.parent.type === import_utils39.AST_NODE_TYPES.ExportNamedDeclaration || statement.parent.type === import_utils39.AST_NODE_TYPES.ExportDefaultDeclaration) return false;
|
|
6317
|
-
if (statement.parent.type !== import_utils39.AST_NODE_TYPES.Program) return statement.parent.type === import_utils39.AST_NODE_TYPES.BlockStatement;
|
|
6318
|
-
return sourceCode.ast.body.some((node) => node.type === import_utils39.AST_NODE_TYPES.ImportDeclaration || node.type === import_utils39.AST_NODE_TYPES.ExportNamedDeclaration || node.type === import_utils39.AST_NODE_TYPES.ExportDefaultDeclaration || node.type === import_utils39.AST_NODE_TYPES.ExportAllDeclaration);
|
|
6319
|
-
}
|
|
6320
|
-
function hasOnlyDirectFactoryUses(variable) {
|
|
6321
|
-
return variable.references.every((reference) => {
|
|
6322
|
-
if (reference.isTypeReference && !reference.isValueReference) return true;
|
|
6323
|
-
const identifier = reference.identifier;
|
|
6324
|
-
const parent = identifier.parent;
|
|
6325
|
-
if (parent.type === import_utils39.AST_NODE_TYPES.CallExpression && parent.callee === identifier) return true;
|
|
6326
|
-
return parent.type === import_utils39.AST_NODE_TYPES.MemberExpression && parent.object === identifier && !parent.computed && parent.parent.type === import_utils39.AST_NODE_TYPES.CallExpression && parent.parent.callee === parent;
|
|
6327
|
-
});
|
|
6328
|
-
}
|
|
6329
|
-
var IDENTIFIER_NAMES = /* @__PURE__ */ new WeakMap();
|
|
6330
|
-
function hasIdentifierNamed(node, name) {
|
|
6331
|
-
let names = IDENTIFIER_NAMES.get(node);
|
|
6332
|
-
if (names === void 0) {
|
|
6333
|
-
const collected = /* @__PURE__ */ new Set();
|
|
6334
|
-
const pending = [node];
|
|
6335
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
6336
|
-
while (pending.length > 0) {
|
|
6337
|
-
const current = pending.pop();
|
|
6338
|
-
if (current === void 0 || seen.has(current)) continue;
|
|
6339
|
-
seen.add(current);
|
|
6340
|
-
if (current.type === import_utils39.AST_NODE_TYPES.Identifier || current.type === import_utils39.AST_NODE_TYPES.JSXIdentifier) collected.add(current.name);
|
|
6341
|
-
forEachOwnAstChild(current, (child) => {
|
|
6342
|
-
pending.push(child);
|
|
6343
|
-
}, (key) => key !== "tokens" && key !== "comments");
|
|
6344
|
-
}
|
|
6345
|
-
names = collected;
|
|
6346
|
-
IDENTIFIER_NAMES.set(node, names);
|
|
6347
|
-
}
|
|
6348
|
-
return names.has(name);
|
|
6349
|
-
}
|
|
6350
|
-
function privatePredicateBooleanFix(sourceCode, node, annotation, filename) {
|
|
6351
|
-
if (!annotation.typeAnnotation || !retainsNamedTypeUses(sourceCode, annotation.typeAnnotation) || node.type !== import_utils39.AST_NODE_TYPES.FunctionDeclaration || node.id === null || !isUnusedPrivateBinding(sourceCode, node, node.id, filename) || sourceCode.getCommentsInside(annotation).length > 0) return null;
|
|
6352
|
-
return (fixer) => fixer.replaceText(annotation, `boolean${sourceCode.getText(annotation).replace(/[^\r\n]/gu, "")}`);
|
|
6353
|
-
}
|
|
6354
|
-
|
|
6355
|
-
// src/rules/no-broad-return-type.ts
|
|
6356
6416
|
var NO_BROAD_RETURN_TYPE_DOCUMENTATION = {
|
|
6357
6417
|
summary: "Report explicit broad return annotations that erase a known return value.",
|
|
6358
6418
|
rationale: "An unknown, object, or unknown-valued dictionary return hides fields that the implementation already knows.",
|
|
@@ -7196,7 +7256,7 @@ var NO_CONTRADICTORY_TYPE_PREDICATE_DOCUMENTATION = {
|
|
|
7196
7256
|
"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.",
|
|
7197
7257
|
"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.",
|
|
7198
7258
|
"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.",
|
|
7199
|
-
"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;
|
|
7259
|
+
"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."
|
|
7200
7260
|
],
|
|
7201
7261
|
references: ["https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-5.html#inferred-type-predicates"],
|
|
7202
7262
|
examples: [
|
|
@@ -7260,7 +7320,7 @@ var no_contradictory_type_predicate_default = createRule({
|
|
|
7260
7320
|
const target = checker.getTypeAtLocation(services.esTreeNodeToTSNodeMap.get(annotation.typeAnnotation.typeAnnotation));
|
|
7261
7321
|
if (!checker.isTypeAssignableTo(target, input)) return;
|
|
7262
7322
|
if (shallowRecordCheck(expression, parameter, input, target, context.sourceCode, checker, services.esTreeNodeToTSNodeMap.get(node).getSourceFile())) {
|
|
7263
|
-
context.report({ node: annotation, messageId: "uncheckedRecordFields", data: { promised: checker.typeToString(target) } });
|
|
7323
|
+
context.report({ node: annotation, messageId: "uncheckedRecordFields", fix: privatePredicateBooleanFix(context.sourceCode, node, annotation, context.filename), data: { promised: checker.typeToString(target) } });
|
|
7264
7324
|
return;
|
|
7265
7325
|
}
|
|
7266
7326
|
if (check === void 0) {
|
|
@@ -7486,7 +7546,7 @@ var NO_PARTIAL_TYPE_PREDICATE_DOCUMENTATION = {
|
|
|
7486
7546
|
"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.",
|
|
7487
7547
|
"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.",
|
|
7488
7548
|
"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.",
|
|
7489
|
-
"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.
|
|
7549
|
+
"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.",
|
|
7490
7550
|
"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."
|
|
7491
7551
|
],
|
|
7492
7552
|
references: ["https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-5.html#inferred-type-predicates"],
|
|
@@ -7525,7 +7585,7 @@ var no_partial_type_predicate_default = createRule({
|
|
|
7525
7585
|
if (predicate === void 0) return;
|
|
7526
7586
|
const uuidWitness = predicate.kind === "string" ? uuidPredicateWitness(predicate.expression, predicate.parameter, context.sourceCode, services) : void 0;
|
|
7527
7587
|
if (uuidWitness !== void 0) {
|
|
7528
|
-
context.report({ node: predicate.annotation, messageId: "partialPredicate", data: { witness: showWitness(uuidWitness), target: "string" } });
|
|
7588
|
+
context.report({ node: predicate.annotation, messageId: "partialPredicate", fix: privatePredicateBooleanFix(context.sourceCode, node, predicate.annotation, context.filename), data: { witness: showWitness(uuidWitness), target: "string" } });
|
|
7529
7589
|
return;
|
|
7530
7590
|
}
|
|
7531
7591
|
const refinement = refinementExpression(predicate, context.sourceCode);
|
|
@@ -11005,7 +11065,16 @@ var no_comment_cruft_default = createRule({
|
|
|
11005
11065
|
while (end + 1 < comments.length && areAdjacentLineComments(comments[end], comments[end + 1])) end += 1;
|
|
11006
11066
|
const removals = comments.slice(start, end + 1).filter(pure).map((candidate2) => ownLineCommentRemovalRange(sourceCode.text, candidate2));
|
|
11007
11067
|
if (removals.some((removal) => removal === null)) return null;
|
|
11008
|
-
return (fixer) =>
|
|
11068
|
+
return (fixer) => {
|
|
11069
|
+
const fixes = [];
|
|
11070
|
+
for (const removal of removals) {
|
|
11071
|
+
if (removal === null) return null;
|
|
11072
|
+
const endings = commentLineEndings(sourceCode.text, removal);
|
|
11073
|
+
if (endings === null) return null;
|
|
11074
|
+
fixes.push(fixer.replaceTextRange(removal.range, endings));
|
|
11075
|
+
}
|
|
11076
|
+
return fixes;
|
|
11077
|
+
};
|
|
11009
11078
|
}
|
|
11010
11079
|
function isSectionJsDoc(comment) {
|
|
11011
11080
|
const texts = comment.value.split("\n").map(stripCommentMarker).filter((line) => line.length > 0 && !isDirective(line));
|
|
@@ -18884,7 +18953,10 @@ var no_restated_comment_default = createRule({
|
|
|
18884
18953
|
context.report({
|
|
18885
18954
|
node: comment,
|
|
18886
18955
|
messageId: "restatesLineBelow",
|
|
18887
|
-
fix: removal === null ? null : (fixer) =>
|
|
18956
|
+
fix: removal === null ? null : (fixer) => {
|
|
18957
|
+
const endings = commentLineEndings(sourceCode.text, removal);
|
|
18958
|
+
return endings === null ? null : fixer.replaceTextRange(removal.range, endings);
|
|
18959
|
+
},
|
|
18888
18960
|
suggest: removal === null ? null : [
|
|
18889
18961
|
{
|
|
18890
18962
|
messageId: "deleteComment",
|
|
@@ -19043,7 +19115,10 @@ var no_restated_jsdoc_default = createRule({
|
|
|
19043
19115
|
context.report({
|
|
19044
19116
|
node: comment,
|
|
19045
19117
|
messageId: "restatesSignature",
|
|
19046
|
-
fix: removal === null ? null : (fixer) =>
|
|
19118
|
+
fix: removal === null ? null : (fixer) => {
|
|
19119
|
+
const endings = commentLineEndings(sourceCode.text, removal);
|
|
19120
|
+
return endings === null ? null : fixer.replaceTextRange(removal.range, endings);
|
|
19121
|
+
},
|
|
19047
19122
|
suggest: removal === null ? [] : [
|
|
19048
19123
|
{
|
|
19049
19124
|
messageId: "deleteBlock",
|
|
@@ -21862,7 +21937,10 @@ function typedTagEdit(comment, signature, sourceCode) {
|
|
|
21862
21937
|
if (!removed) return null;
|
|
21863
21938
|
while (retained[0]?.trim() === "") retained.shift();
|
|
21864
21939
|
while (retained.at(-1)?.trim() === "") retained.pop();
|
|
21865
|
-
if (retained.length === 0)
|
|
21940
|
+
if (retained.length === 0) {
|
|
21941
|
+
const endings = commentLineEndings(sourceCode.text, removal);
|
|
21942
|
+
return endings === null ? null : { range: removal.range, text: endings };
|
|
21943
|
+
}
|
|
21866
21944
|
const eol = sourceCode.text.includes("\r\n") ? "\r\n" : "\n";
|
|
21867
21945
|
const indent = " ".repeat(comment.loc.start.column);
|
|
21868
21946
|
return {
|
|
@@ -22465,7 +22543,15 @@ var no_declaration_comment_wall_default = createRule({
|
|
|
22465
22543
|
},
|
|
22466
22544
|
messageId: "commentWall",
|
|
22467
22545
|
data: { restated: String(restated), commented: String(commented) },
|
|
22468
|
-
fix: removals.length === 0 ? null : (fixer) =>
|
|
22546
|
+
fix: removals.length === 0 ? null : (fixer) => {
|
|
22547
|
+
const fixes = [];
|
|
22548
|
+
for (const removal of removals) {
|
|
22549
|
+
const endings = commentLineEndings(sourceCode.text, removal);
|
|
22550
|
+
if (endings === null) return null;
|
|
22551
|
+
fixes.push(fixer.replaceTextRange(removal.range, endings));
|
|
22552
|
+
}
|
|
22553
|
+
return fixes;
|
|
22554
|
+
}
|
|
22469
22555
|
});
|
|
22470
22556
|
}
|
|
22471
22557
|
function isGroupLabel(comment, member3, headsRun) {
|
|
@@ -22816,7 +22902,15 @@ var no_type_member_comment_wall_default = createRule({
|
|
|
22816
22902
|
},
|
|
22817
22903
|
messageId: "commentWall",
|
|
22818
22904
|
data: { restated: String(restated), commented: String(commented) },
|
|
22819
|
-
fix: removals.length === 0 ? null : (fixer) =>
|
|
22905
|
+
fix: removals.length === 0 ? null : (fixer) => {
|
|
22906
|
+
const fixes = [];
|
|
22907
|
+
for (const removal of removals) {
|
|
22908
|
+
const endings = commentLineEndings(sourceCode.text, removal);
|
|
22909
|
+
if (endings === null) return null;
|
|
22910
|
+
fixes.push(fixer.replaceTextRange(removal.range, endings));
|
|
22911
|
+
}
|
|
22912
|
+
return fixes;
|
|
22913
|
+
}
|
|
22820
22914
|
});
|
|
22821
22915
|
}
|
|
22822
22916
|
function isGroupLabel(comment, member3, headsRun) {
|
|
@@ -23825,7 +23919,10 @@ var test_phase_label_comment_default = createRule({
|
|
|
23825
23919
|
context.report({
|
|
23826
23920
|
node: comment,
|
|
23827
23921
|
messageId: "removeLabel",
|
|
23828
|
-
fix: (fixer) =>
|
|
23922
|
+
fix: (fixer) => {
|
|
23923
|
+
const endings = commentLineEndings(context.sourceCode.text, removal);
|
|
23924
|
+
return endings === null ? null : fixer.replaceTextRange(removal.range, endings);
|
|
23925
|
+
}
|
|
23829
23926
|
});
|
|
23830
23927
|
}
|
|
23831
23928
|
}
|
|
@@ -36492,8 +36589,10 @@ var RULE_POLICY = {
|
|
|
36492
36589
|
"@sarj/require-pascal-case-zod-schema-name": ["error", "both"]
|
|
36493
36590
|
};
|
|
36494
36591
|
var ADVISORY_RULES = Object.keys(RULE_POLICY).filter(isAdvisoryRuleName).toSorted();
|
|
36495
|
-
var
|
|
36496
|
-
var
|
|
36592
|
+
var FLAT_RECOMMENDED_RULES = presetRules("recommended");
|
|
36593
|
+
var FLAT_STRICT_RULES = presetRules("strict");
|
|
36594
|
+
var RECOMMENDED_RULES = FLAT_RECOMMENDED_RULES;
|
|
36595
|
+
var STRICT_RULES = FLAT_STRICT_RULES;
|
|
36497
36596
|
function isAdvisoryRuleName(name) {
|
|
36498
36597
|
return isPolicyName(name) && RULE_POLICY[name][0] === "warn";
|
|
36499
36598
|
}
|
|
@@ -36528,12 +36627,12 @@ var PLUGIN = {
|
|
|
36528
36627
|
recommended: {
|
|
36529
36628
|
name: "@sarj/recommended",
|
|
36530
36629
|
plugins: { "@sarj": PLUGIN },
|
|
36531
|
-
rules:
|
|
36630
|
+
rules: FLAT_RECOMMENDED_RULES
|
|
36532
36631
|
},
|
|
36533
36632
|
strict: {
|
|
36534
36633
|
name: "@sarj/strict",
|
|
36535
36634
|
plugins: { "@sarj": PLUGIN },
|
|
36536
|
-
rules:
|
|
36635
|
+
rules: FLAT_STRICT_RULES
|
|
36537
36636
|
}
|
|
36538
36637
|
};
|
|
36539
36638
|
}
|