@sarj/eslint-plugin 19.7.0 → 19.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/catalog.js +54 -5
- package/dist/{chunk-OX5DMK42.js → chunk-MFL7OATV.js} +339 -134
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -22008,8 +22008,179 @@ var prefer_coded_error_result_default = defineRule({
|
|
|
22008
22008
|
}
|
|
22009
22009
|
});
|
|
22010
22010
|
|
|
22011
|
+
// src/rules/prefer-configured-cloud-scope.ts
|
|
22012
|
+
var NAME92 = "prefer-configured-cloud-scope";
|
|
22013
|
+
var ACCOUNT_PREFIX = "https://api.cloudflare.com/client/v4/accounts/";
|
|
22014
|
+
var ACCOUNT_URL = /^https:\/\/api\.cloudflare\.com\/client\/v4\/accounts\/[a-fA-F\d]{32}(?=\/|[?#]|$)/u;
|
|
22015
|
+
var GLOBAL_RECEIVERS5 = /* @__PURE__ */ new Set(["globalThis", "global", "self", "window"]);
|
|
22016
|
+
var UNKNOWN = [{ text: "\0", source: null }];
|
|
22017
|
+
function accountSource(parts) {
|
|
22018
|
+
if (!ACCOUNT_URL.test(parts.map((part) => part.text).join(""))) return null;
|
|
22019
|
+
let offset = 0;
|
|
22020
|
+
for (const part of parts) {
|
|
22021
|
+
if (offset + part.text.length > ACCOUNT_PREFIX.length) return part.source;
|
|
22022
|
+
offset += part.text.length;
|
|
22023
|
+
}
|
|
22024
|
+
return null;
|
|
22025
|
+
}
|
|
22026
|
+
function boundedParts(parts) {
|
|
22027
|
+
return parts.length <= 128 && parts.reduce((size, part) => size + part.text.length, 0) <= 8192 ? parts : UNKNOWN;
|
|
22028
|
+
}
|
|
22029
|
+
var prefer_configured_cloud_scope_default = defineRule({
|
|
22030
|
+
meta: {
|
|
22031
|
+
type: "suggestion",
|
|
22032
|
+
docs: {
|
|
22033
|
+
description: "Prefer validated deployment configuration for account scope in outgoing cloud management requests.",
|
|
22034
|
+
url: docsUrl(NAME92)
|
|
22035
|
+
},
|
|
22036
|
+
schema: [],
|
|
22037
|
+
messages: {
|
|
22038
|
+
configuredScope: "This outgoing Cloudflare management request uses a source-literal account scope. Read and validate the account ID from deployment configuration or environment variables at the boundary; keep independent security allowlists intact."
|
|
22039
|
+
}
|
|
22040
|
+
},
|
|
22041
|
+
createOnce(context) {
|
|
22042
|
+
let sourceCode2;
|
|
22043
|
+
const reported = /* @__PURE__ */ new Set();
|
|
22044
|
+
const requests = [];
|
|
22045
|
+
let fetchOverridden = false;
|
|
22046
|
+
let nodesRemaining = 0;
|
|
22047
|
+
function bindingOf(node) {
|
|
22048
|
+
return findVariable(sourceCode2.getScope(node), node.name);
|
|
22049
|
+
}
|
|
22050
|
+
function unshadowed(node) {
|
|
22051
|
+
const binding3 = bindingOf(node);
|
|
22052
|
+
return binding3 === null || binding3.defs.length === 0;
|
|
22053
|
+
}
|
|
22054
|
+
function globalReceiver2(node) {
|
|
22055
|
+
return node.type === "Identifier" && GLOBAL_RECEIVERS5.has(node.name) && unshadowed(node);
|
|
22056
|
+
}
|
|
22057
|
+
function outgoingFetch(node, seen = /* @__PURE__ */ new Set()) {
|
|
22058
|
+
const callee = unwrapExpression(node);
|
|
22059
|
+
if (callee.type === "MemberExpression") {
|
|
22060
|
+
return globalReceiver2(callee.object) && staticPropertyName(callee, sourceCode2) === "fetch";
|
|
22061
|
+
}
|
|
22062
|
+
if (callee.type !== "Identifier") return false;
|
|
22063
|
+
const binding3 = bindingOf(callee);
|
|
22064
|
+
if (binding3 === null || binding3.defs.length === 0) return callee.name === "fetch";
|
|
22065
|
+
if (seen.has(binding3) || seen.size >= 16 || binding3.defs.length !== 1 || binding3.references.some((ref) => ref.isWrite() && ref.init !== true)) return false;
|
|
22066
|
+
const next = /* @__PURE__ */ new Set([...seen, binding3]);
|
|
22067
|
+
const [definition] = binding3.defs;
|
|
22068
|
+
if (definition?.type === "Parameter") {
|
|
22069
|
+
const parameter = parentOf(definition.name);
|
|
22070
|
+
return parameter?.type === "AssignmentPattern" && parameter.left === definition.name && outgoingFetch(parameter.right, next);
|
|
22071
|
+
}
|
|
22072
|
+
if (definition?.type !== "Variable" || definition.parent?.type !== "VariableDeclaration" || definition.parent.kind !== "const") return false;
|
|
22073
|
+
const declarator = definition.node;
|
|
22074
|
+
return declarator.id.type === "Identifier" && declarator.init !== null && outgoingFetch(declarator.init, next);
|
|
22075
|
+
}
|
|
22076
|
+
function checkWrite(target, depth = 0) {
|
|
22077
|
+
if (depth >= 16) {
|
|
22078
|
+
fetchOverridden = true;
|
|
22079
|
+
return;
|
|
22080
|
+
}
|
|
22081
|
+
const value = unwrapExpression(target);
|
|
22082
|
+
switch (value.type) {
|
|
22083
|
+
case "Identifier":
|
|
22084
|
+
fetchOverridden ||= (value.name === "fetch" || GLOBAL_RECEIVERS5.has(value.name)) && unshadowed(value);
|
|
22085
|
+
return;
|
|
22086
|
+
case "MemberExpression":
|
|
22087
|
+
if (globalReceiver2(value.object)) {
|
|
22088
|
+
const name = staticPropertyName(value, sourceCode2);
|
|
22089
|
+
fetchOverridden ||= name === null || name === "fetch" || GLOBAL_RECEIVERS5.has(name);
|
|
22090
|
+
}
|
|
22091
|
+
return;
|
|
22092
|
+
case "ObjectPattern":
|
|
22093
|
+
for (const property of value.properties) checkWrite(property.type === "RestElement" ? property.argument : property.value, depth + 1);
|
|
22094
|
+
return;
|
|
22095
|
+
case "ArrayPattern":
|
|
22096
|
+
for (const element of value.elements) if (element !== null) checkWrite(element, depth + 1);
|
|
22097
|
+
return;
|
|
22098
|
+
case "AssignmentPattern":
|
|
22099
|
+
checkWrite(value.left, depth + 1);
|
|
22100
|
+
return;
|
|
22101
|
+
case "RestElement":
|
|
22102
|
+
checkWrite(value.argument, depth + 1);
|
|
22103
|
+
return;
|
|
22104
|
+
}
|
|
22105
|
+
}
|
|
22106
|
+
function urlParts(node, seen = /* @__PURE__ */ new Set(), depth = 0) {
|
|
22107
|
+
if (depth >= 16 || nodesRemaining-- <= 0) return UNKNOWN;
|
|
22108
|
+
const value = unwrapExpression(node);
|
|
22109
|
+
if (value.type === "Literal" && typeof value.value === "string") {
|
|
22110
|
+
return boundedParts([{ text: value.value, source: value }]);
|
|
22111
|
+
}
|
|
22112
|
+
if (value.type === "Identifier") {
|
|
22113
|
+
const binding3 = bindingOf(value);
|
|
22114
|
+
if (binding3 === null || seen.has(binding3) || binding3.defs.length !== 1 || binding3.references.some((ref) => ref.isWrite() && ref.init !== true)) return UNKNOWN;
|
|
22115
|
+
const [definition] = binding3.defs;
|
|
22116
|
+
if (definition?.type !== "Variable" || definition.parent?.type !== "VariableDeclaration" || definition.parent.kind !== "const") return UNKNOWN;
|
|
22117
|
+
const declarator = definition.node;
|
|
22118
|
+
if (declarator.id.type !== "Identifier" || declarator.init === null) return UNKNOWN;
|
|
22119
|
+
return urlParts(declarator.init, /* @__PURE__ */ new Set([...seen, binding3]), depth + 1);
|
|
22120
|
+
}
|
|
22121
|
+
if (value.type === "BinaryExpression" && value.operator === "+") {
|
|
22122
|
+
return boundedParts([...urlParts(value.left, seen, depth + 1), ...urlParts(value.right, seen, depth + 1)]);
|
|
22123
|
+
}
|
|
22124
|
+
if (value.type === "TemplateLiteral") return templateParts(value, seen, depth);
|
|
22125
|
+
return UNKNOWN;
|
|
22126
|
+
}
|
|
22127
|
+
function templateParts(value, seen, depth) {
|
|
22128
|
+
const parts = [];
|
|
22129
|
+
for (let index = 0; index < value.quasis.length; index++) {
|
|
22130
|
+
if (parts.length >= 128) return UNKNOWN;
|
|
22131
|
+
const quasi = value.quasis[index];
|
|
22132
|
+
if (quasi === void 0 || quasi.value.cooked === null) return UNKNOWN;
|
|
22133
|
+
parts.push({ text: quasi.value.cooked, source: quasi });
|
|
22134
|
+
const expression = value.expressions[index];
|
|
22135
|
+
if (expression !== void 0) parts.push(...urlParts(expression, seen, depth + 1));
|
|
22136
|
+
}
|
|
22137
|
+
return boundedParts(parts);
|
|
22138
|
+
}
|
|
22139
|
+
return {
|
|
22140
|
+
before() {
|
|
22141
|
+
sourceCode2 = context.sourceCode;
|
|
22142
|
+
reported.clear();
|
|
22143
|
+
requests.length = 0;
|
|
22144
|
+
fetchOverridden = false;
|
|
22145
|
+
const file = { filename: context.filename, cwd: context.cwd };
|
|
22146
|
+
return !isTestFile(file) && !isGeneratedFile(file, sourceCode2.text);
|
|
22147
|
+
},
|
|
22148
|
+
CallExpression(node) {
|
|
22149
|
+
if (outgoingFetch(node.callee)) requests.push(node);
|
|
22150
|
+
},
|
|
22151
|
+
AssignmentExpression(node) {
|
|
22152
|
+
checkWrite(node.left);
|
|
22153
|
+
},
|
|
22154
|
+
UpdateExpression(node) {
|
|
22155
|
+
checkWrite(node.argument);
|
|
22156
|
+
},
|
|
22157
|
+
UnaryExpression(node) {
|
|
22158
|
+
if (node.operator === "delete") checkWrite(node.argument);
|
|
22159
|
+
},
|
|
22160
|
+
ForInStatement(node) {
|
|
22161
|
+
if (node.left.type !== "VariableDeclaration") checkWrite(node.left);
|
|
22162
|
+
},
|
|
22163
|
+
ForOfStatement(node) {
|
|
22164
|
+
if (node.left.type !== "VariableDeclaration") checkWrite(node.left);
|
|
22165
|
+
},
|
|
22166
|
+
"Program:exit"() {
|
|
22167
|
+
if (fetchOverridden) return;
|
|
22168
|
+
for (const request of requests) {
|
|
22169
|
+
const [url] = request.arguments;
|
|
22170
|
+
if (url === void 0 || url.type === "SpreadElement") continue;
|
|
22171
|
+
nodesRemaining = 256;
|
|
22172
|
+
const literal2 = accountSource(urlParts(url));
|
|
22173
|
+
if (literal2 === null || reported.has(literal2)) continue;
|
|
22174
|
+
reported.add(literal2);
|
|
22175
|
+
context.report({ node: literal2, messageId: "configuredScope" });
|
|
22176
|
+
}
|
|
22177
|
+
}
|
|
22178
|
+
};
|
|
22179
|
+
}
|
|
22180
|
+
});
|
|
22181
|
+
|
|
22011
22182
|
// src/rules/prefer-constant-time-secret-compare.ts
|
|
22012
|
-
var
|
|
22183
|
+
var NAME93 = "prefer-constant-time-secret-compare";
|
|
22013
22184
|
var EQUALITY_OPERATORS3 = /* @__PURE__ */ new Set(["===", "!==", "==", "!="]);
|
|
22014
22185
|
var AUTH_TOKEN_QUALIFIERS = /* @__PURE__ */ new Set(["access", "refresh", "session", "admin", "csrf", "xsrf", "auth", "authentication", "signing", "api"]);
|
|
22015
22186
|
var SENTINEL_IDENTIFIERS = /* @__PURE__ */ new Set(["undefined", "NaN"]);
|
|
@@ -22073,7 +22244,7 @@ var prefer_constant_time_secret_compare_default = defineRule({
|
|
|
22073
22244
|
type: "problem",
|
|
22074
22245
|
docs: {
|
|
22075
22246
|
description: "Prefer a supported constant-time comparison primitive for secret-like values.",
|
|
22076
|
-
url: docsUrl(
|
|
22247
|
+
url: docsUrl(NAME93)
|
|
22077
22248
|
},
|
|
22078
22249
|
schema: [],
|
|
22079
22250
|
messages: {
|
|
@@ -22161,7 +22332,7 @@ function constInitializer4(definition) {
|
|
|
22161
22332
|
}
|
|
22162
22333
|
|
|
22163
22334
|
// src/rules/prefer-dependency-interface.ts
|
|
22164
|
-
var
|
|
22335
|
+
var NAME94 = "prefer-dependency-interface";
|
|
22165
22336
|
function readsInterfaceMember(use, members2) {
|
|
22166
22337
|
const parent = parentOf(use);
|
|
22167
22338
|
if (parent?.type !== "MemberExpression" || parent.object !== use || !members2.has(getPropertyName(parent) ?? "")) return false;
|
|
@@ -22191,7 +22362,7 @@ var prefer_dependency_interface_default = defineRule({
|
|
|
22191
22362
|
type: "suggestion",
|
|
22192
22363
|
docs: {
|
|
22193
22364
|
description: "Annotate retained collaborators with their existing interface when the consumer uses only that contract.",
|
|
22194
|
-
url: docsUrl(
|
|
22365
|
+
url: docsUrl(NAME94)
|
|
22195
22366
|
},
|
|
22196
22367
|
schema: [],
|
|
22197
22368
|
messages: { interface: "Use the existing `{{contract}}` interface for this dependency; its consumer uses only that contract." }
|
|
@@ -22278,14 +22449,19 @@ function discriminatedUnionReturns(node, sourceCode2) {
|
|
|
22278
22449
|
if (shape === void 0) return void 0;
|
|
22279
22450
|
const returned2 = returnedProperties(paths.objects, shape);
|
|
22280
22451
|
if (returned2 === void 0) return void 0;
|
|
22452
|
+
if (node.async && returned2.some((properties2) => {
|
|
22453
|
+
const then = properties2.get("then");
|
|
22454
|
+
return then !== void 0 && (then.type !== "Literal" || typeof then.value === "object" && then.value !== null);
|
|
22455
|
+
})) return void 0;
|
|
22456
|
+
const emptyPayload = returned2.some((properties2) => hasEmptyPayload(properties2, shape.optional));
|
|
22281
22457
|
for (const [name, member3] of shape.members) {
|
|
22282
|
-
if (member3.optional) continue;
|
|
22283
|
-
const domain = tagDomain(member3.typeAnnotation?.typeAnnotation);
|
|
22458
|
+
if (member3.optional || emptyPayload) continue;
|
|
22459
|
+
const domain = tagDomain(member3.typeAnnotation?.typeAnnotation, sourceCode2);
|
|
22284
22460
|
if (domain !== void 0 && hasTagSpecificPayload(name, domain, shape.optional, returned2)) {
|
|
22285
22461
|
return { reportNode: contract.reportNode, relationship: { kind: "presence", tag: name }, members: shape.members, returned: returned2 };
|
|
22286
22462
|
}
|
|
22287
22463
|
}
|
|
22288
|
-
const fields2 = correlatedBooleanFields(shape, returned2);
|
|
22464
|
+
const fields2 = correlatedBooleanFields(shape, returned2, sourceCode2);
|
|
22289
22465
|
return fields2 === void 0 ? void 0 : {
|
|
22290
22466
|
reportNode: contract.reportNode,
|
|
22291
22467
|
relationship: { kind: "boolean-pair", fields: fields2 },
|
|
@@ -22293,8 +22469,8 @@ function discriminatedUnionReturns(node, sourceCode2) {
|
|
|
22293
22469
|
returned: returned2
|
|
22294
22470
|
};
|
|
22295
22471
|
}
|
|
22296
|
-
function correlatedBooleanFields(shape, returned2) {
|
|
22297
|
-
const fields2 = [...shape.members].filter(([, member3]) => !member3.optional && member3.typeAnnotation?.typeAnnotation
|
|
22472
|
+
function correlatedBooleanFields(shape, returned2, sourceCode2) {
|
|
22473
|
+
const fields2 = [...shape.members].filter(([, member3]) => !member3.optional && booleanType(member3.typeAnnotation?.typeAnnotation, sourceCode2)).map(([name]) => name);
|
|
22298
22474
|
if (fields2.length > 8) return void 0;
|
|
22299
22475
|
for (const [index, left] of fields2.entries()) {
|
|
22300
22476
|
for (const right of fields2.slice(index + 1)) {
|
|
@@ -22304,6 +22480,10 @@ function correlatedBooleanFields(shape, returned2) {
|
|
|
22304
22480
|
}
|
|
22305
22481
|
return void 0;
|
|
22306
22482
|
}
|
|
22483
|
+
function booleanType(type, sourceCode2) {
|
|
22484
|
+
const domain = tagDomain(type, sourceCode2);
|
|
22485
|
+
return domain?.size === 2 && domain.has(true) && domain.has(false);
|
|
22486
|
+
}
|
|
22307
22487
|
function booleanCombinations(left, right, returned2) {
|
|
22308
22488
|
const combinations = /* @__PURE__ */ new Set();
|
|
22309
22489
|
for (const properties2 of returned2) {
|
|
@@ -22343,15 +22523,7 @@ function returnContract(node, sourceCode2) {
|
|
|
22343
22523
|
}
|
|
22344
22524
|
function definitions(reference, sourceCode2) {
|
|
22345
22525
|
if (reference.typeName.type !== "Identifier") return [];
|
|
22346
|
-
|
|
22347
|
-
while (scope !== null) {
|
|
22348
|
-
const found = scope.set.get(reference.typeName.name);
|
|
22349
|
-
const binding3 = found === void 0 ? void 0 : tsVariable(found);
|
|
22350
|
-
const typeDefinitions2 = binding3?.defs.filter((definition) => definition.isTypeDefinition) ?? [];
|
|
22351
|
-
if (typeDefinitions2.length > 0 || binding3?.isTypeVariable === true) return typeDefinitions2;
|
|
22352
|
-
scope = scope.upper;
|
|
22353
|
-
}
|
|
22354
|
-
return [];
|
|
22526
|
+
return typeBinding(sourceCode2, reference.typeName)?.defs.filter((definition) => definition.isTypeDefinition) ?? [];
|
|
22355
22527
|
}
|
|
22356
22528
|
function objectContract(elements) {
|
|
22357
22529
|
const members2 = /* @__PURE__ */ new Map();
|
|
@@ -22372,7 +22544,6 @@ function returnedProperties(objects, contract) {
|
|
|
22372
22544
|
if (properties2 === void 0) return void 0;
|
|
22373
22545
|
if ([...properties2.keys()].some((name) => !contract.members.has(name))) return void 0;
|
|
22374
22546
|
if ([...contract.members].some(([name, member3]) => !member3.optional && !properties2.has(name))) return void 0;
|
|
22375
|
-
if (hasEmptyPayload(properties2, contract.optional)) return void 0;
|
|
22376
22547
|
returned2.push(properties2);
|
|
22377
22548
|
}
|
|
22378
22549
|
return returned2;
|
|
@@ -22397,7 +22568,13 @@ function hasEmptyPayload(properties2, optional) {
|
|
|
22397
22568
|
}
|
|
22398
22569
|
return false;
|
|
22399
22570
|
}
|
|
22400
|
-
function tagDomain(node) {
|
|
22571
|
+
function tagDomain(node, sourceCode2) {
|
|
22572
|
+
if (node?.type === "TSTypeReference" && !isPresent(node.typeArguments)) {
|
|
22573
|
+
const bindings = definitions(node, sourceCode2);
|
|
22574
|
+
const declaration = bindings.length === 1 ? bindings[0]?.node : void 0;
|
|
22575
|
+
if (declaration?.type !== "TSTypeAliasDeclaration" || isPresent(declaration.typeParameters)) return void 0;
|
|
22576
|
+
node = declaration.typeAnnotation;
|
|
22577
|
+
}
|
|
22401
22578
|
if (node?.type === "TSBooleanKeyword") return /* @__PURE__ */ new Set([true, false]);
|
|
22402
22579
|
if (node?.type !== "TSUnionType") return void 0;
|
|
22403
22580
|
const values = /* @__PURE__ */ new Set();
|
|
@@ -22477,6 +22654,7 @@ function reachableSwitch(statement, sourceCode2) {
|
|
|
22477
22654
|
return kind !== void 0 && reachableSwitchLabels(statement, kind);
|
|
22478
22655
|
}
|
|
22479
22656
|
function broadSwitchInput(statement, sourceCode2) {
|
|
22657
|
+
if (hasIdentifierNamed(sourceCode2, "eval")) return void 0;
|
|
22480
22658
|
const body3 = statement.parent;
|
|
22481
22659
|
if (body3.type !== "BlockStatement" || body3.body.length !== 1) return void 0;
|
|
22482
22660
|
const owner = body3.parent;
|
|
@@ -22528,6 +22706,13 @@ function statementsPaths(statements, budget, depth) {
|
|
|
22528
22706
|
}
|
|
22529
22707
|
function returnedObjects(expression, budget, depth) {
|
|
22530
22708
|
if (!budget.within(depth)) return void 0;
|
|
22709
|
+
if (isErasedExpression(expression)) {
|
|
22710
|
+
return returnedObjects(expression.expression, budget, depth + 1);
|
|
22711
|
+
}
|
|
22712
|
+
if (expression.type === "Identifier") {
|
|
22713
|
+
const initializer = closedReturnInitializer(expression, budget.sourceCode);
|
|
22714
|
+
return initializer === void 0 ? void 0 : returnedObjects(initializer, budget, depth + 1);
|
|
22715
|
+
}
|
|
22531
22716
|
if (expression.type === "ObjectExpression") {
|
|
22532
22717
|
return budget.recordObject() ? [expression] : void 0;
|
|
22533
22718
|
}
|
|
@@ -22536,10 +22721,21 @@ function returnedObjects(expression, budget, depth) {
|
|
|
22536
22721
|
const alternate = returnedObjects(expression.alternate, budget, depth + 1);
|
|
22537
22722
|
return consequent === void 0 || alternate === void 0 ? void 0 : [...consequent, ...alternate];
|
|
22538
22723
|
}
|
|
22724
|
+
function closedReturnInitializer(identifier, sourceCode2) {
|
|
22725
|
+
const returned2 = identifier.parent;
|
|
22726
|
+
if (returned2.type !== "ReturnStatement" || returned2.argument !== identifier || returned2.parent.type !== "BlockStatement" || hasIdentifierNamed(sourceCode2, "eval")) return void 0;
|
|
22727
|
+
const block = returned2.parent;
|
|
22728
|
+
const declaration = block.body[block.body.indexOf(returned2) - 1];
|
|
22729
|
+
if (declaration?.type !== "VariableDeclaration" || declaration.kind !== "const" || declaration.declarations.length !== 1) return void 0;
|
|
22730
|
+
const value = declaration.declarations[0];
|
|
22731
|
+
if (value?.id.type !== "Identifier" || value.id.name !== identifier.name || value.init === null) return void 0;
|
|
22732
|
+
const binding3 = findVariable(sourceCode2.getScope(identifier), identifier.name);
|
|
22733
|
+
if (binding3?.defs.length !== 1 || binding3.defs[0]?.node !== value || binding3.eslintUsed || !binding3.references.some((reference) => reference.identifier === identifier && reference.isRead()) || binding3.references.some((reference) => reference.isWrite() ? reference.init !== true : reference.identifier !== identifier)) return void 0;
|
|
22734
|
+
return value.init;
|
|
22735
|
+
}
|
|
22539
22736
|
function propertyName(node) {
|
|
22540
|
-
if (node.computed) return void 0;
|
|
22541
|
-
if (node.key.type === "Identifier") return node.key.name;
|
|
22542
22737
|
if (node.key.type === "Literal" && typeof node.key.value === "string") return node.key.value;
|
|
22738
|
+
if (!node.computed && node.key.type === "Identifier") return node.key.name;
|
|
22543
22739
|
return void 0;
|
|
22544
22740
|
}
|
|
22545
22741
|
function literalTag(node) {
|
|
@@ -22548,14 +22744,14 @@ function literalTag(node) {
|
|
|
22548
22744
|
}
|
|
22549
22745
|
|
|
22550
22746
|
// src/rules/prefer-discriminated-union.ts
|
|
22551
|
-
var
|
|
22747
|
+
var NAME95 = "prefer-discriminated-union";
|
|
22552
22748
|
var prefer_discriminated_union_default = defineRule({
|
|
22553
22749
|
meta: {
|
|
22554
22750
|
type: "suggestion",
|
|
22555
22751
|
fixable: "code",
|
|
22556
22752
|
docs: {
|
|
22557
22753
|
description: "Preserve producer-proven tag/payload and Boolean state relationships in return types.",
|
|
22558
|
-
url: docsUrl(
|
|
22754
|
+
url: docsUrl(NAME95)
|
|
22559
22755
|
},
|
|
22560
22756
|
schema: [],
|
|
22561
22757
|
messages: {
|
|
@@ -22610,25 +22806,33 @@ function returnsOnlyConditionalObject(fn) {
|
|
|
22610
22806
|
if (fn.async || fn.generator || isPresent(fn.typeParameters)) return false;
|
|
22611
22807
|
const statements = fn.body?.body ?? [];
|
|
22612
22808
|
const [returned2] = statements;
|
|
22613
|
-
return statements.length === 1 && returned2?.type === "ReturnStatement" && returned2.argument?.type === "ConditionalExpression";
|
|
22809
|
+
return statements.length === 1 && returned2?.type === "ReturnStatement" && returned2.argument?.type === "ConditionalExpression" && bareConditionalObjects(returned2.argument);
|
|
22810
|
+
}
|
|
22811
|
+
function bareConditionalObjects(expression) {
|
|
22812
|
+
return expression.type === "ObjectExpression" || expression.type === "ConditionalExpression" && bareConditionalObjects(expression.consequent) && bareConditionalObjects(expression.alternate);
|
|
22614
22813
|
}
|
|
22615
22814
|
function privateVariantType(properties2, result, sourceCode2) {
|
|
22616
22815
|
if ([...properties2.values()].some((value) => value.type !== "Literal" || typeof value.value === "object" && value.value !== null || typeof value.value === "number" && !Number.isFinite(value.value))) return null;
|
|
22617
22816
|
const fields2 = [];
|
|
22618
22817
|
for (const [name, member3] of result.members) {
|
|
22619
22818
|
const value = properties2.get(name);
|
|
22620
|
-
if (value === void 0) continue;
|
|
22819
|
+
if (value === void 0 && result.relationship.kind === "presence") continue;
|
|
22621
22820
|
const annotation = member3.typeAnnotation?.typeAnnotation;
|
|
22622
22821
|
if (annotation === void 0) return null;
|
|
22623
22822
|
const narrow = result.relationship.kind === "presence" ? name === result.relationship.tag : name === result.relationship.fields.left || name === result.relationship.fields.right;
|
|
22624
|
-
|
|
22625
|
-
|
|
22823
|
+
let type = sourceCode2.getText(annotation);
|
|
22824
|
+
if (narrow) {
|
|
22825
|
+
if (value === void 0) return null;
|
|
22826
|
+
type = sourceCode2.getText(value);
|
|
22827
|
+
}
|
|
22828
|
+
const optional = result.relationship.kind === "boolean-pair" && !narrow && member3.optional;
|
|
22829
|
+
fields2.push(`${member3.readonly ? "readonly " : ""}${sourceCode2.getText(member3.key)}${optional ? "?" : ""}: ${type}`);
|
|
22626
22830
|
}
|
|
22627
22831
|
return `{ ${fields2.join("; ")} }`;
|
|
22628
22832
|
}
|
|
22629
22833
|
|
|
22630
22834
|
// src/rules/prefer-ecmascript-private-members.ts
|
|
22631
|
-
var
|
|
22835
|
+
var NAME96 = "prefer-ecmascript-private-members";
|
|
22632
22836
|
function isConvertible(member3) {
|
|
22633
22837
|
return member3.accessibility === "private" && !(member3.type === "MethodDefinition" && member3.kind === "constructor") && !member3.computed && member3.key.type === "Identifier" && (member3.decorators?.length ?? 0) === 0 && !("declare" in member3 && member3.declare) && !member3.override && !(member3.type === "MethodDefinition" && (member3.value.body ?? null) === null);
|
|
22634
22838
|
}
|
|
@@ -22638,7 +22842,7 @@ var prefer_ecmascript_private_members_default = defineRule({
|
|
|
22638
22842
|
fixable: "code",
|
|
22639
22843
|
docs: {
|
|
22640
22844
|
description: "Prefer ECMAScript `#private` class members over TypeScript-only `private` members.",
|
|
22641
|
-
url: docsUrl(
|
|
22845
|
+
url: docsUrl(NAME96)
|
|
22642
22846
|
},
|
|
22643
22847
|
schema: [],
|
|
22644
22848
|
messages: {
|
|
@@ -22692,7 +22896,7 @@ var prefer_ecmascript_private_members_default = defineRule({
|
|
|
22692
22896
|
});
|
|
22693
22897
|
|
|
22694
22898
|
// src/rules/prefer-immutable-module-constant.ts
|
|
22695
|
-
var
|
|
22899
|
+
var NAME97 = "prefer-immutable-module-constant";
|
|
22696
22900
|
var CONSTANT_NAME = /^_?[A-Z][A-Z0-9_]*$/;
|
|
22697
22901
|
var JAVASCRIPT_FILE_RE = /\.[cm]?jsx?$/i;
|
|
22698
22902
|
var MUTATING_METHODS = /* @__PURE__ */ new Set([
|
|
@@ -22865,7 +23069,7 @@ var prefer_immutable_module_constant_default = defineRule({
|
|
|
22865
23069
|
fixable: "code",
|
|
22866
23070
|
docs: {
|
|
22867
23071
|
description: "Require module-level constant collections to expose readonly state.",
|
|
22868
|
-
url: docsUrl(
|
|
23072
|
+
url: docsUrl(NAME97)
|
|
22869
23073
|
},
|
|
22870
23074
|
schema: [],
|
|
22871
23075
|
defaultOptions: [],
|
|
@@ -22971,7 +23175,7 @@ function unwrapTransparentExport(node) {
|
|
|
22971
23175
|
}
|
|
22972
23176
|
|
|
22973
23177
|
// src/rules/prefer-input-group-search.ts
|
|
22974
|
-
var
|
|
23178
|
+
var NAME98 = "prefer-input-group-search";
|
|
22975
23179
|
var INPUT_MODULE = /(?:^|\/)components\/ui\/input$/u;
|
|
22976
23180
|
var INPUT_GROUP_MODULE = /(?:^|\/)components\/ui\/input-group$/u;
|
|
22977
23181
|
var MAX_JSX_DISTANCE = 2;
|
|
@@ -23042,7 +23246,7 @@ var prefer_input_group_search_default = defineRule({
|
|
|
23042
23246
|
type: "suggestion",
|
|
23043
23247
|
docs: {
|
|
23044
23248
|
description: "Require search icons and shared Input controls in the same visual wrapper to use InputGroup.",
|
|
23045
|
-
url: docsUrl(
|
|
23249
|
+
url: docsUrl(NAME98)
|
|
23046
23250
|
},
|
|
23047
23251
|
schema: [],
|
|
23048
23252
|
messages: {
|
|
@@ -23126,7 +23330,7 @@ var prefer_input_group_search_default = defineRule({
|
|
|
23126
23330
|
});
|
|
23127
23331
|
|
|
23128
23332
|
// src/rules/prefer-logical-tailwind-utilities.ts
|
|
23129
|
-
var
|
|
23333
|
+
var NAME99 = "prefer-logical-tailwind-utilities";
|
|
23130
23334
|
var PREFIXES = {
|
|
23131
23335
|
ml: "ms",
|
|
23132
23336
|
mr: "me",
|
|
@@ -23180,7 +23384,7 @@ var prefer_logical_tailwind_utilities_default = defineRule({
|
|
|
23180
23384
|
type: "suggestion",
|
|
23181
23385
|
docs: {
|
|
23182
23386
|
description: "Prefer logical Tailwind utilities in explicitly opted-in bidirectional interfaces.",
|
|
23183
|
-
url: docsUrl(
|
|
23387
|
+
url: docsUrl(NAME99)
|
|
23184
23388
|
},
|
|
23185
23389
|
schema: [
|
|
23186
23390
|
{
|
|
@@ -23247,7 +23451,7 @@ var prefer_logical_tailwind_utilities_default = defineRule({
|
|
|
23247
23451
|
});
|
|
23248
23452
|
|
|
23249
23453
|
// src/rules/prefer-millisecond-control-duration-schema.ts
|
|
23250
|
-
var
|
|
23454
|
+
var NAME100 = "prefer-millisecond-control-duration-schema";
|
|
23251
23455
|
var CONTROL_SECONDS_RE = /(?:^|_)(?:timeout|delay|interval|backoff|ttl|lease|heartbeat|debounce|throttle)_seconds$/i;
|
|
23252
23456
|
var CONTROL_SECONDS_CAMEL_RE = /(?:timeout|delay|interval|backoff|ttl|lease|heartbeat|debounce|throttle)Seconds$/i;
|
|
23253
23457
|
var NUMERIC_REFINEMENTS = /* @__PURE__ */ new Set(["int", "min", "max", "positive", "nonnegative", "finite", "multipleOf", "optional", "nullable", "nullish", "default", "describe", "brand", "readonly"]);
|
|
@@ -23259,7 +23463,7 @@ var prefer_millisecond_control_duration_schema_default = defineRule({
|
|
|
23259
23463
|
type: "suggestion",
|
|
23260
23464
|
docs: {
|
|
23261
23465
|
description: "Require application-owned Zod control-duration fields to use millisecond granularity.",
|
|
23262
|
-
url: docsUrl(
|
|
23466
|
+
url: docsUrl(NAME100)
|
|
23263
23467
|
},
|
|
23264
23468
|
schema: [],
|
|
23265
23469
|
messages: {
|
|
@@ -23345,7 +23549,7 @@ var prefer_millisecond_control_duration_schema_default = defineRule({
|
|
|
23345
23549
|
});
|
|
23346
23550
|
|
|
23347
23551
|
// src/rules/prefer-minimal-parameter-contract.ts
|
|
23348
|
-
var
|
|
23552
|
+
var NAME101 = "prefer-minimal-parameter-contract";
|
|
23349
23553
|
function inlineFields(ast, node, reads) {
|
|
23350
23554
|
const fields2 = /* @__PURE__ */ new Map();
|
|
23351
23555
|
for (const member3 of node.members) {
|
|
@@ -23364,7 +23568,7 @@ var prefer_minimal_parameter_contract_default = defineRule({
|
|
|
23364
23568
|
meta: {
|
|
23365
23569
|
type: "suggestion",
|
|
23366
23570
|
fixable: "code",
|
|
23367
|
-
docs: { description: "Prefer the proven read-only subset for a private consumer parameter.", url: docsUrl(
|
|
23571
|
+
docs: { description: "Prefer the proven read-only subset for a private consumer parameter.", url: docsUrl(NAME101) },
|
|
23368
23572
|
schema: [],
|
|
23369
23573
|
messages: {
|
|
23370
23574
|
minimal: "This private consumer reads only {{used}} but also requires {{unused}}. Review a smaller consumer contract; preserve the original runtime object and producer type."
|
|
@@ -23763,7 +23967,7 @@ var prefer_module_level_constant_default = defineRule({
|
|
|
23763
23967
|
});
|
|
23764
23968
|
|
|
23765
23969
|
// src/rules/prefer-module-level-schema.ts
|
|
23766
|
-
var
|
|
23970
|
+
var NAME102 = "prefer-module-level-schema";
|
|
23767
23971
|
var DEFAULT_FACTORIES = [
|
|
23768
23972
|
"discriminatedUnion",
|
|
23769
23973
|
"intersection",
|
|
@@ -23945,7 +24149,7 @@ var prefer_module_level_schema_default = defineRule({
|
|
|
23945
24149
|
type: "problem",
|
|
23946
24150
|
docs: {
|
|
23947
24151
|
description: "Declare a Zod schema at module scope when it closes over nothing in the enclosing function",
|
|
23948
|
-
url: docsUrl(
|
|
24152
|
+
url: docsUrl(NAME102)
|
|
23949
24153
|
},
|
|
23950
24154
|
schema: [
|
|
23951
24155
|
{
|
|
@@ -24095,7 +24299,7 @@ var prefer_module_level_schema_default = defineRule({
|
|
|
24095
24299
|
});
|
|
24096
24300
|
|
|
24097
24301
|
// src/rules/prefer-module-level-refined-schema.ts
|
|
24098
|
-
var
|
|
24302
|
+
var NAME103 = "prefer-module-level-refined-schema";
|
|
24099
24303
|
var BENCHMARK_PATH_RE = /(^|[/\\])(?:benchmarks?|bench)[/\\]/;
|
|
24100
24304
|
var FACTORIES = /* @__PURE__ */ new Set([
|
|
24101
24305
|
"array",
|
|
@@ -24245,7 +24449,7 @@ var prefer_module_level_refined_schema_default = defineRule({
|
|
|
24245
24449
|
type: "suggestion",
|
|
24246
24450
|
docs: {
|
|
24247
24451
|
description: "Declare closed Zod scalar, format, and wrapper schemas at module scope.",
|
|
24248
|
-
url: docsUrl(
|
|
24452
|
+
url: docsUrl(NAME103)
|
|
24249
24453
|
},
|
|
24250
24454
|
schema: [],
|
|
24251
24455
|
messages: {
|
|
@@ -24343,7 +24547,7 @@ var prefer_module_level_refined_schema_default = defineRule({
|
|
|
24343
24547
|
});
|
|
24344
24548
|
|
|
24345
24549
|
// src/rules/prefer-multi-value-zod-literal.ts
|
|
24346
|
-
var
|
|
24550
|
+
var NAME104 = "prefer-multi-value-zod-literal";
|
|
24347
24551
|
function isStaticPrimitive(node, sourceCode2) {
|
|
24348
24552
|
node = unwrapExpression(node);
|
|
24349
24553
|
if (node.type === "Literal") {
|
|
@@ -24370,7 +24574,7 @@ var prefer_multi_value_zod_literal_default = defineRule({
|
|
|
24370
24574
|
type: "suggestion",
|
|
24371
24575
|
docs: {
|
|
24372
24576
|
description: "Use the Zod 4 multi-value literal API instead of a union of literal schemas.",
|
|
24373
|
-
url: docsUrl(
|
|
24577
|
+
url: docsUrl(NAME104)
|
|
24374
24578
|
},
|
|
24375
24579
|
schema: [
|
|
24376
24580
|
{
|
|
@@ -24533,7 +24737,7 @@ function closedType(node) {
|
|
|
24533
24737
|
}
|
|
24534
24738
|
|
|
24535
24739
|
// src/rules/prefer-named-callback-domain.ts
|
|
24536
|
-
var
|
|
24740
|
+
var NAME105 = "prefer-named-callback-domain";
|
|
24537
24741
|
function isLiteralUnion(node) {
|
|
24538
24742
|
return node.type === "TSUnionType" && node.types.length >= 2 && node.types.every((part) => part.type === "TSLiteralType");
|
|
24539
24743
|
}
|
|
@@ -24553,7 +24757,7 @@ var prefer_named_callback_domain_default = defineRule({
|
|
|
24553
24757
|
fixable: "code",
|
|
24554
24758
|
docs: {
|
|
24555
24759
|
description: "Name literal-union domains used by callbacks in exported contracts.",
|
|
24556
|
-
url: docsUrl(
|
|
24760
|
+
url: docsUrl(NAME105)
|
|
24557
24761
|
},
|
|
24558
24762
|
schema: [],
|
|
24559
24763
|
messages: {
|
|
@@ -24592,7 +24796,7 @@ var prefer_named_callback_domain_default = defineRule({
|
|
|
24592
24796
|
});
|
|
24593
24797
|
|
|
24594
24798
|
// src/rules/prefer-named-complex-return-type.ts
|
|
24595
|
-
var
|
|
24799
|
+
var NAME106 = "prefer-named-complex-return-type";
|
|
24596
24800
|
function unwrap5(node) {
|
|
24597
24801
|
if (node.type === "TSTypeReference" && node.typeArguments?.params.length === 1) {
|
|
24598
24802
|
const [inner] = node.typeArguments.params;
|
|
@@ -24630,7 +24834,7 @@ var prefer_named_complex_return_type_default = defineRule({
|
|
|
24630
24834
|
fixable: "code",
|
|
24631
24835
|
docs: {
|
|
24632
24836
|
description: "Prefer a named contract for structurally complex function return types.",
|
|
24633
|
-
url: docsUrl(
|
|
24837
|
+
url: docsUrl(NAME106)
|
|
24634
24838
|
},
|
|
24635
24839
|
schema: [],
|
|
24636
24840
|
messages: {
|
|
@@ -24653,14 +24857,14 @@ var prefer_named_complex_return_type_default = defineRule({
|
|
|
24653
24857
|
});
|
|
24654
24858
|
|
|
24655
24859
|
// src/rules/prefer-native-fetch-in-server-actions.ts
|
|
24656
|
-
var
|
|
24860
|
+
var NAME107 = "prefer-native-fetch-in-server-actions";
|
|
24657
24861
|
var KY_MODULE = /^ky(?:\/.*)?$/u;
|
|
24658
24862
|
var prefer_native_fetch_in_server_actions_default = defineRule({
|
|
24659
24863
|
meta: {
|
|
24660
24864
|
type: "problem",
|
|
24661
24865
|
docs: {
|
|
24662
24866
|
description: "Server action modules should call native fetch instead of importing ky.",
|
|
24663
|
-
url: docsUrl(
|
|
24867
|
+
url: docsUrl(NAME107)
|
|
24664
24868
|
},
|
|
24665
24869
|
schema: [],
|
|
24666
24870
|
defaultOptions: [],
|
|
@@ -24696,7 +24900,7 @@ function isTypeOnly(node) {
|
|
|
24696
24900
|
}
|
|
24697
24901
|
|
|
24698
24902
|
// src/rules/prefer-native-random-uuid.ts
|
|
24699
|
-
var
|
|
24903
|
+
var NAME108 = "prefer-native-random-uuid";
|
|
24700
24904
|
function requireUuidCallee(node) {
|
|
24701
24905
|
return node?.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === "require" && node.arguments.length === 1 && node.arguments[0]?.type === "Literal" && node.arguments[0].value === "uuid" ? node.callee : null;
|
|
24702
24906
|
}
|
|
@@ -24709,7 +24913,7 @@ var prefer_native_random_uuid_default = defineRule({
|
|
|
24709
24913
|
type: "suggestion",
|
|
24710
24914
|
docs: {
|
|
24711
24915
|
description: "Prefer `globalThis.crypto.randomUUID()` over resolved zero-argument UUID v4 bindings from the `uuid` package.",
|
|
24712
|
-
url: docsUrl(
|
|
24916
|
+
url: docsUrl(NAME108)
|
|
24713
24917
|
},
|
|
24714
24918
|
hasSuggestions: true,
|
|
24715
24919
|
fixable: "code",
|
|
@@ -24797,7 +25001,7 @@ var prefer_native_random_uuid_default = defineRule({
|
|
|
24797
25001
|
});
|
|
24798
25002
|
|
|
24799
25003
|
// src/rules/prefer-node-crypto-hash.ts
|
|
24800
|
-
var
|
|
25004
|
+
var NAME109 = "prefer-node-crypto-hash";
|
|
24801
25005
|
var UNSAFE_NAMESPACE_METHODS = /* @__PURE__ */ new Set(["__defineGetter__", "__defineSetter__", "valueOf"]);
|
|
24802
25006
|
var UNSAFE_AUTHORITY_IDENTIFIERS = [
|
|
24803
25007
|
"eval",
|
|
@@ -24901,7 +25105,7 @@ var prefer_node_crypto_hash_default = defineRule({
|
|
|
24901
25105
|
fixable: "code",
|
|
24902
25106
|
docs: {
|
|
24903
25107
|
description: "Prefer the modern one-shot node:crypto hash API when streaming state is unnecessary.",
|
|
24904
|
-
url: docsUrl(
|
|
25108
|
+
url: docsUrl(NAME109)
|
|
24905
25109
|
},
|
|
24906
25110
|
schema: [],
|
|
24907
25111
|
messages: { preferNodeCryptoHash: "Prefer the modern one-shot node:crypto hash API when streaming state is unnecessary." }
|
|
@@ -25131,7 +25335,7 @@ function hasRetainedFactoryCall(binding3, removed) {
|
|
|
25131
25335
|
}
|
|
25132
25336
|
|
|
25133
25337
|
// src/rules/prefer-node-fs-promises.ts
|
|
25134
|
-
var
|
|
25338
|
+
var NAME110 = "prefer-node-fs-promises";
|
|
25135
25339
|
function memberName3(node) {
|
|
25136
25340
|
if (!node.computed && node.property.type === "Identifier") return node.property.name;
|
|
25137
25341
|
if (node.computed && node.property.type === "Literal" && typeof node.property.value === "string") {
|
|
@@ -25164,7 +25368,7 @@ var prefer_node_fs_promises_default = defineRule({
|
|
|
25164
25368
|
type: "suggestion",
|
|
25165
25369
|
docs: {
|
|
25166
25370
|
description: "Prefer promise-based Node.js filesystem APIs over synchronous calls in production modules.",
|
|
25167
|
-
url: docsUrl(
|
|
25371
|
+
url: docsUrl(NAME110)
|
|
25168
25372
|
},
|
|
25169
25373
|
schema: [],
|
|
25170
25374
|
messages: {
|
|
@@ -25307,7 +25511,7 @@ function sameTypeBinding(sourceCode2, alias, annotation, parameter) {
|
|
|
25307
25511
|
}
|
|
25308
25512
|
|
|
25309
25513
|
// src/rules/prefer-nominal-id-types.ts
|
|
25310
|
-
var
|
|
25514
|
+
var NAME111 = "prefer-nominal-id-types";
|
|
25311
25515
|
var OPERATIONAL_ROLES = /* @__PURE__ */ new Set([
|
|
25312
25516
|
"request",
|
|
25313
25517
|
"trace",
|
|
@@ -25423,7 +25627,7 @@ var prefer_nominal_id_types_default = defineRule({
|
|
|
25423
25627
|
fixable: "code",
|
|
25424
25628
|
docs: {
|
|
25425
25629
|
description: "Distinguish identifier roles sharing primitive types at callable boundaries.",
|
|
25426
|
-
url: docsUrl(
|
|
25630
|
+
url: docsUrl(NAME111)
|
|
25427
25631
|
},
|
|
25428
25632
|
schema: [],
|
|
25429
25633
|
messages: {
|
|
@@ -25452,7 +25656,7 @@ var prefer_nominal_id_types_default = defineRule({
|
|
|
25452
25656
|
});
|
|
25453
25657
|
|
|
25454
25658
|
// src/rules/prefer-non-nullable-collection.ts
|
|
25455
|
-
var
|
|
25659
|
+
var NAME112 = "prefer-non-nullable-collection";
|
|
25456
25660
|
var ARRAY_TYPE_NAMES2 = /* @__PURE__ */ new Set(["Array", "ReadonlyArray"]);
|
|
25457
25661
|
var NULL_GUARD_OPERATORS = /* @__PURE__ */ new Set(["==", "==="]);
|
|
25458
25662
|
var EMPTY_GUARD_OPERATORS = /* @__PURE__ */ new Set(["==", "===", "<="]);
|
|
@@ -25807,7 +26011,7 @@ var prefer_non_nullable_collection_default = defineRule({
|
|
|
25807
26011
|
fixable: "code",
|
|
25808
26012
|
docs: {
|
|
25809
26013
|
description: "Suggest reviewing nullish arrays that use local empty-array defaults or a shared null-or-empty guard.",
|
|
25810
|
-
url: docsUrl(
|
|
26014
|
+
url: docsUrl(NAME112)
|
|
25811
26015
|
},
|
|
25812
26016
|
schema: [],
|
|
25813
26017
|
messages: {
|
|
@@ -25918,7 +26122,7 @@ var prefer_non_nullable_collection_default = defineRule({
|
|
|
25918
26122
|
});
|
|
25919
26123
|
|
|
25920
26124
|
// src/rules/prefer-nullish-filter-predicate.ts
|
|
25921
|
-
var
|
|
26125
|
+
var NAME113 = "prefer-nullish-filter-predicate";
|
|
25922
26126
|
var SUMMARY = "Prefer an explicit nullish predicate when `filter(Boolean)` removes only nullish values but does not narrow the result type.";
|
|
25923
26127
|
function isBuiltinArrayFilter(native, symbol) {
|
|
25924
26128
|
const kinds2 = native.ast.SyntaxKind;
|
|
@@ -25975,7 +26179,7 @@ function isLiteralValue(node) {
|
|
|
25975
26179
|
var prefer_nullish_filter_predicate_default = defineRule({
|
|
25976
26180
|
meta: {
|
|
25977
26181
|
type: "suggestion",
|
|
25978
|
-
docs: { description: SUMMARY, url: docsUrl(
|
|
26182
|
+
docs: { description: SUMMARY, url: docsUrl(NAME113) },
|
|
25979
26183
|
hasSuggestions: true,
|
|
25980
26184
|
fixable: "code",
|
|
25981
26185
|
schema: [],
|
|
@@ -26068,7 +26272,7 @@ var prefer_nullish_filter_predicate_default = defineRule({
|
|
|
26068
26272
|
});
|
|
26069
26273
|
|
|
26070
26274
|
// src/rules/prefer-schema-for-api-payload.ts
|
|
26071
|
-
var
|
|
26275
|
+
var NAME114 = "prefer-schema-for-api-payload";
|
|
26072
26276
|
var unwrap6 = (node) => {
|
|
26073
26277
|
let current = node ?? null;
|
|
26074
26278
|
while (current !== null && (isErasedExpression(current) || current.type === "ChainExpression")) current = current.expression;
|
|
@@ -26351,7 +26555,7 @@ var prefer_schema_for_api_payload_default = defineRule({
|
|
|
26351
26555
|
type: "problem",
|
|
26352
26556
|
docs: {
|
|
26353
26557
|
description: "Require Zod (or similar) schema validation on `response.json()` / `JSON.parse()` results before property access.",
|
|
26354
|
-
url: docsUrl(
|
|
26558
|
+
url: docsUrl(NAME114)
|
|
26355
26559
|
},
|
|
26356
26560
|
schema: [],
|
|
26357
26561
|
messages: {
|
|
@@ -26534,7 +26738,7 @@ var prefer_schema_for_api_payload_default = defineRule({
|
|
|
26534
26738
|
// src/rules/prefer-semantic-colors.ts
|
|
26535
26739
|
import { existsSync as existsSync3, lstatSync, readdirSync as readdirSync2, readFileSync as readFileSync2 } from "fs";
|
|
26536
26740
|
import { dirname as dirname3, join as join3, parse } from "path";
|
|
26537
|
-
var
|
|
26741
|
+
var NAME115 = "prefer-semantic-colors";
|
|
26538
26742
|
var COLOR_PREFIXES = "text|bg|border(?:-[trblxyse])?|ring(?:-offset)?|fill|stroke|from|via|to|divide|decoration|placeholder|accent|caret|shadow|outline";
|
|
26539
26743
|
var PALETTE = "red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|slate|gray|zinc|neutral|stone";
|
|
26540
26744
|
var COLOR_FN = "rgba?|hsla?|hwb|oklch|oklab|lab|lch|color";
|
|
@@ -26866,7 +27070,7 @@ var prefer_semantic_colors_default = defineRule({
|
|
|
26866
27070
|
type: "suggestion",
|
|
26867
27071
|
docs: {
|
|
26868
27072
|
description: "Enforce semantic color tokens over raw Tailwind palette classes, arbitrary color values, and inline color literals.",
|
|
26869
|
-
url: docsUrl(
|
|
27073
|
+
url: docsUrl(NAME115)
|
|
26870
27074
|
},
|
|
26871
27075
|
schema: [
|
|
26872
27076
|
{
|
|
@@ -27053,7 +27257,7 @@ function packageWorkspaceGlobs(parsed) {
|
|
|
27053
27257
|
}
|
|
27054
27258
|
|
|
27055
27259
|
// src/rules/prefer-server-actions.ts
|
|
27056
|
-
var
|
|
27260
|
+
var NAME116 = "prefer-server-actions";
|
|
27057
27261
|
var MUTATION_METHODS = /* @__PURE__ */ new Set(["POST", "PUT", "DELETE", "PATCH"]);
|
|
27058
27262
|
var AXIOS_MUTATION_METHODS = /* @__PURE__ */ new Set(["post", "put", "delete", "patch"]);
|
|
27059
27263
|
var SKIP_FILE_REGEX = /(?:\.test\.[jt]sx?$|\.spec\.[jt]sx?$|-(?:test|spec)\.[jt]sx?$|\/tests?\/|\/__tests__\/|\/__testfixtures__\/|\/scripts?\/|(?:^|\/)app(?:\/.*)?\/route\.[jt]sx?$|(?:^|\/)middleware\.[jt]sx?$|\/pages\/api\/)/;
|
|
@@ -27192,7 +27396,7 @@ var prefer_server_actions_default = defineRule({
|
|
|
27192
27396
|
type: "suggestion",
|
|
27193
27397
|
docs: {
|
|
27194
27398
|
description: "Prefer Next.js Server Actions over same-origin API mutations.",
|
|
27195
|
-
url: docsUrl(
|
|
27399
|
+
url: docsUrl(NAME116)
|
|
27196
27400
|
},
|
|
27197
27401
|
schema: [
|
|
27198
27402
|
{
|
|
@@ -27278,7 +27482,7 @@ var prefer_server_actions_default = defineRule({
|
|
|
27278
27482
|
});
|
|
27279
27483
|
|
|
27280
27484
|
// src/rules/prefer-server-data-preparation.ts
|
|
27281
|
-
var
|
|
27485
|
+
var NAME117 = "prefer-server-data-preparation";
|
|
27282
27486
|
var METHODS = /* @__PURE__ */ new Set(["map", "filter", "flatMap"]);
|
|
27283
27487
|
var DOM_EVENTS = /* @__PURE__ */ new Set(["onClick", "onChange", "onInput", "onSubmit"]);
|
|
27284
27488
|
var BINARY = /* @__PURE__ */ new Set(["===", "!==", "==", "!=", ">", ">=", "<", "<=", "+", "-", "*", "/", "%"]);
|
|
@@ -27410,7 +27614,7 @@ function typedProofs(native) {
|
|
|
27410
27614
|
var prefer_server_data_preparation_default = defineRule({
|
|
27411
27615
|
meta: {
|
|
27412
27616
|
type: "suggestion",
|
|
27413
|
-
docs: { description: "Prepare data-only input collections before an interactive client view when possible.", url: docsUrl(
|
|
27617
|
+
docs: { description: "Prepare data-only input collections before an interactive client view when possible.", url: docsUrl(NAME117) },
|
|
27414
27618
|
schema: [],
|
|
27415
27619
|
messages: {
|
|
27416
27620
|
prepareData: "Review preparing this prop-only collection in its producer or Server Component when the inputs are available there. Keep operations depending on unsaved edits or browser interaction reactive in the client."
|
|
@@ -28328,7 +28532,7 @@ var ParseErrorCode;
|
|
|
28328
28532
|
})(ParseErrorCode || (ParseErrorCode = {}));
|
|
28329
28533
|
|
|
28330
28534
|
// src/rules/prefer-shadcn-primitives.ts
|
|
28331
|
-
var
|
|
28535
|
+
var NAME118 = "prefer-shadcn-primitives";
|
|
28332
28536
|
var RAW_PRIMITIVES = {
|
|
28333
28537
|
button: { capability: "Button", replacement: "Button" },
|
|
28334
28538
|
dialog: { capability: "Dialog", replacement: "Dialog or AlertDialog family" },
|
|
@@ -28630,7 +28834,7 @@ var prefer_shadcn_primitives_default = defineRule({
|
|
|
28630
28834
|
type: "suggestion",
|
|
28631
28835
|
docs: {
|
|
28632
28836
|
description: "Require visible raw JSX controls to use the corresponding shared shadcn primitive.",
|
|
28633
|
-
url: docsUrl(
|
|
28837
|
+
url: docsUrl(NAME118)
|
|
28634
28838
|
},
|
|
28635
28839
|
schema: [
|
|
28636
28840
|
{
|
|
@@ -28737,7 +28941,7 @@ function matchingAliasTargets(paths, alias) {
|
|
|
28737
28941
|
}
|
|
28738
28942
|
|
|
28739
28943
|
// src/rules/prefer-shared-zod-enum.ts
|
|
28740
|
-
var
|
|
28944
|
+
var NAME119 = "prefer-shared-zod-enum";
|
|
28741
28945
|
function literalDomain(node) {
|
|
28742
28946
|
if (node.arguments.length !== 1) return null;
|
|
28743
28947
|
const first = node.arguments[0];
|
|
@@ -28776,7 +28980,7 @@ var prefer_shared_zod_enum_default = defineRule({
|
|
|
28776
28980
|
type: "suggestion",
|
|
28777
28981
|
docs: {
|
|
28778
28982
|
description: "Give repeated literal Zod enum domains one reusable module-level schema.",
|
|
28779
|
-
url: docsUrl(
|
|
28983
|
+
url: docsUrl(NAME119)
|
|
28780
28984
|
},
|
|
28781
28985
|
schema: [],
|
|
28782
28986
|
messages: {
|
|
@@ -28833,7 +29037,7 @@ var prefer_shared_zod_enum_default = defineRule({
|
|
|
28833
29037
|
});
|
|
28834
29038
|
|
|
28835
29039
|
// src/rules/prefer-switch-for-repeated-equality.ts
|
|
28836
|
-
var
|
|
29040
|
+
var NAME120 = "prefer-switch-for-repeated-equality";
|
|
28837
29041
|
function discriminantName(test) {
|
|
28838
29042
|
if (test.type !== "BinaryExpression" || test.operator !== "===") return null;
|
|
28839
29043
|
const leftIsCase = isCaseValue(test.left);
|
|
@@ -28910,7 +29114,7 @@ var prefer_switch_for_repeated_equality_default = defineRule({
|
|
|
28910
29114
|
fixable: "code",
|
|
28911
29115
|
docs: {
|
|
28912
29116
|
description: "Prefer switch over long if/else-if chains that compare one value for strict equality.",
|
|
28913
|
-
url: docsUrl(
|
|
29117
|
+
url: docsUrl(NAME120)
|
|
28914
29118
|
},
|
|
28915
29119
|
schema: [],
|
|
28916
29120
|
messages: {
|
|
@@ -28960,7 +29164,7 @@ var prefer_switch_for_repeated_equality_default = defineRule({
|
|
|
28960
29164
|
});
|
|
28961
29165
|
|
|
28962
29166
|
// src/rules/prefer-test-fixture-reuse.ts
|
|
28963
|
-
var
|
|
29167
|
+
var NAME121 = "prefer-test-fixture-reuse";
|
|
28964
29168
|
var MAX_DEPTH2 = 8;
|
|
28965
29169
|
var FRAMEWORKS = /* @__PURE__ */ new Set(["vitest", "@playwright/test"]);
|
|
28966
29170
|
var TEST_MODIFIERS4 = /* @__PURE__ */ new Set(["only", "skip", "concurrent", "sequential"]);
|
|
@@ -29089,7 +29293,7 @@ var prefer_test_fixture_reuse_default = defineRule({
|
|
|
29089
29293
|
type: "suggestion",
|
|
29090
29294
|
docs: {
|
|
29091
29295
|
description: "Reuse a requested test fixture instead of constructing another instance of its class.",
|
|
29092
|
-
url: docsUrl(
|
|
29296
|
+
url: docsUrl(NAME121)
|
|
29093
29297
|
},
|
|
29094
29298
|
schema: [],
|
|
29095
29299
|
messages: { reuseFixture: "This class is already supplied by the requested `{{fixture}}` fixture; reuse it or request a typed factory for independent instances." }
|
|
@@ -29123,7 +29327,7 @@ var prefer_test_fixture_reuse_default = defineRule({
|
|
|
29123
29327
|
});
|
|
29124
29328
|
|
|
29125
29329
|
// src/rules/prefer-typed-reflection.ts
|
|
29126
|
-
var
|
|
29330
|
+
var NAME122 = "prefer-typed-reflection";
|
|
29127
29331
|
function knownType(native, type) {
|
|
29128
29332
|
if (type.isUnionType()) return type.getTypes().every((part) => knownType(native, part));
|
|
29129
29333
|
const flags = native.sync.TypeFlags;
|
|
@@ -29153,7 +29357,7 @@ var prefer_typed_reflection_default = defineRule({
|
|
|
29153
29357
|
fixable: "code",
|
|
29154
29358
|
docs: {
|
|
29155
29359
|
description: "Prefer typed access when Reflect.get or Reflect.apply discards a known contract.",
|
|
29156
|
-
url: docsUrl(
|
|
29360
|
+
url: docsUrl(NAME122)
|
|
29157
29361
|
},
|
|
29158
29362
|
schema: [],
|
|
29159
29363
|
messages: {
|
|
@@ -29319,7 +29523,7 @@ var prefer_typed_reflection_default = defineRule({
|
|
|
29319
29523
|
});
|
|
29320
29524
|
|
|
29321
29525
|
// src/rules/prefer-whole-object-assertion.ts
|
|
29322
|
-
var
|
|
29526
|
+
var NAME123 = "prefer-whole-object-assertion";
|
|
29323
29527
|
var MERGEABLE_MATCHERS = /* @__PURE__ */ new Set(["toBe", "toEqual", "toStrictEqual"]);
|
|
29324
29528
|
var SYNTHETIC_LITERAL_MATCHERS = /* @__PURE__ */ new Map([
|
|
29325
29529
|
["toBeNull", "null"]
|
|
@@ -29409,7 +29613,7 @@ var prefer_whole_object_assertion_default = defineRule({
|
|
|
29409
29613
|
type: "suggestion",
|
|
29410
29614
|
docs: {
|
|
29411
29615
|
description: "Collapse consecutive assertions on one object into a whole-object assertion so related mismatches are reported together.",
|
|
29412
|
-
url: docsUrl(
|
|
29616
|
+
url: docsUrl(NAME123)
|
|
29413
29617
|
},
|
|
29414
29618
|
messages: {
|
|
29415
29619
|
combineAssertions: "Consider combining these {{count}} assertions on `{{receiver}}` with `toMatchObject` when structural matching preserves property presence and getter or proxy behavior.",
|
|
@@ -29556,7 +29760,7 @@ var prefer_whole_object_assertion_default = defineRule({
|
|
|
29556
29760
|
});
|
|
29557
29761
|
|
|
29558
29762
|
// src/rules/prefer-zod-enum-validator.ts
|
|
29559
|
-
var
|
|
29763
|
+
var NAME124 = "prefer-zod-enum-validator";
|
|
29560
29764
|
function isInput(node, name) {
|
|
29561
29765
|
if (node == null) return false;
|
|
29562
29766
|
const value = unwrapExpression(node);
|
|
@@ -29647,7 +29851,7 @@ var prefer_zod_enum_validator_default = defineRule({
|
|
|
29647
29851
|
type: "suggestion",
|
|
29648
29852
|
docs: {
|
|
29649
29853
|
description: "Express closed string validators with a reusable Zod enum schema.",
|
|
29650
|
-
url: docsUrl(
|
|
29854
|
+
url: docsUrl(NAME124)
|
|
29651
29855
|
},
|
|
29652
29856
|
schema: [],
|
|
29653
29857
|
messages: { useEnumSchema: "Replace this closed string validator with a named z.enum([\u2026]) schema and derive its type with z.infer. Use parse for parsing or safeParse for a boolean check; preserve intentional failure behavior." }
|
|
@@ -29675,7 +29879,7 @@ var prefer_zod_enum_validator_default = defineRule({
|
|
|
29675
29879
|
});
|
|
29676
29880
|
|
|
29677
29881
|
// src/rules/prefer-zod-infer.ts
|
|
29678
|
-
var
|
|
29882
|
+
var NAME125 = "prefer-zod-infer";
|
|
29679
29883
|
function absent(value) {
|
|
29680
29884
|
return value === void 0 || value === null;
|
|
29681
29885
|
}
|
|
@@ -30051,7 +30255,7 @@ var prefer_zod_infer_default = defineRule({
|
|
|
30051
30255
|
fixable: "code",
|
|
30052
30256
|
docs: {
|
|
30053
30257
|
description: "Derive a type from its Zod schema with `z.infer` instead of hand-writing a twin declaration beside it.",
|
|
30054
|
-
url: docsUrl(
|
|
30258
|
+
url: docsUrl(NAME125)
|
|
30055
30259
|
},
|
|
30056
30260
|
schema: [
|
|
30057
30261
|
{
|
|
@@ -30501,7 +30705,7 @@ function returnsContract(authority, returned2) {
|
|
|
30501
30705
|
}
|
|
30502
30706
|
|
|
30503
30707
|
// src/rules/prefer-zod-parse-output-type.ts
|
|
30504
|
-
var
|
|
30708
|
+
var NAME126 = "prefer-zod-parse-output-type";
|
|
30505
30709
|
function isLocalZodObjectSchema(node, namespaces) {
|
|
30506
30710
|
let current = node;
|
|
30507
30711
|
while (current.type === "CallExpression") {
|
|
@@ -30647,7 +30851,7 @@ var prefer_zod_parse_output_type_default = defineRule({
|
|
|
30647
30851
|
fixable: "code",
|
|
30648
30852
|
docs: {
|
|
30649
30853
|
description: "Consider deriving validated return contracts from the Zod schema when the schema owns the contract.",
|
|
30650
|
-
url: docsUrl(
|
|
30854
|
+
url: docsUrl(NAME126)
|
|
30651
30855
|
},
|
|
30652
30856
|
schema: [],
|
|
30653
30857
|
messages: {
|
|
@@ -30935,7 +31139,7 @@ var production_derived_test_cases_default = defineRule({
|
|
|
30935
31139
|
});
|
|
30936
31140
|
|
|
30937
31141
|
// src/rules/repeated-static-call-cases.ts
|
|
30938
|
-
var
|
|
31142
|
+
var NAME127 = "repeated-static-call-cases";
|
|
30939
31143
|
var TEST_MODULES2 = /* @__PURE__ */ new Set(["@jest/globals", "@playwright/test", "bun:test", "node:test", "vitest"]);
|
|
30940
31144
|
var TEST_NAMES3 = /* @__PURE__ */ new Set(["it", "test"]);
|
|
30941
31145
|
var TEST_MODIFIERS5 = /* @__PURE__ */ new Set(["concurrent", "fails", "only", "sequential", "skip"]);
|
|
@@ -31059,7 +31263,7 @@ var repeated_static_call_cases_default = defineRule({
|
|
|
31059
31263
|
type: "suggestion",
|
|
31060
31264
|
docs: {
|
|
31061
31265
|
description: "Review three or more consecutive static-input call assertions as potential named cases.",
|
|
31062
|
-
url: docsUrl(
|
|
31266
|
+
url: docsUrl(NAME127)
|
|
31063
31267
|
},
|
|
31064
31268
|
schema: [],
|
|
31065
31269
|
messages: { repeatedStaticCallCases: "These {{count}} consecutive assertions repeat a call with static inputs. If independent, use named parameterized cases or subtests; preserve ordered scenarios as one test." }
|
|
@@ -31201,7 +31405,7 @@ function isPrimitiveReturn(node, annotation) {
|
|
|
31201
31405
|
}
|
|
31202
31406
|
|
|
31203
31407
|
// src/rules/require-assert-never.ts
|
|
31204
|
-
var
|
|
31408
|
+
var NAME128 = "require-assert-never";
|
|
31205
31409
|
function isRuntimeHandlingStatement(statement) {
|
|
31206
31410
|
if (statement.type === "EmptyStatement") return false;
|
|
31207
31411
|
if (statement.type === "BreakStatement") return statement.label !== null;
|
|
@@ -31261,7 +31465,7 @@ var require_assert_never_default = defineRule({
|
|
|
31261
31465
|
fixable: "code",
|
|
31262
31466
|
docs: {
|
|
31263
31467
|
description: "Require an empty switch default to call `assertNever` so discriminated unions remain exhaustive at compile time.",
|
|
31264
|
-
url: docsUrl(
|
|
31468
|
+
url: docsUrl(NAME128)
|
|
31265
31469
|
},
|
|
31266
31470
|
schema: [],
|
|
31267
31471
|
messages: {
|
|
@@ -31305,7 +31509,7 @@ var require_assert_never_default = defineRule({
|
|
|
31305
31509
|
});
|
|
31306
31510
|
|
|
31307
31511
|
// src/rules/require-button-accessible-name.ts
|
|
31308
|
-
var
|
|
31512
|
+
var NAME129 = "require-button-accessible-name";
|
|
31309
31513
|
var DELEGATING_PROPS = /* @__PURE__ */ new Set(["render", "asChild"]);
|
|
31310
31514
|
function delegatesRendering(opening) {
|
|
31311
31515
|
return opening.attributes.some(
|
|
@@ -31318,7 +31522,7 @@ var require_button_accessible_name_default = defineRule({
|
|
|
31318
31522
|
type: "problem",
|
|
31319
31523
|
docs: {
|
|
31320
31524
|
description: "Require an accessible name on statically unnamed native or configured JSX buttons.",
|
|
31321
|
-
url: docsUrl(
|
|
31525
|
+
url: docsUrl(NAME129)
|
|
31322
31526
|
},
|
|
31323
31527
|
schema: [
|
|
31324
31528
|
{
|
|
@@ -31372,7 +31576,7 @@ var require_button_accessible_name_default = defineRule({
|
|
|
31372
31576
|
});
|
|
31373
31577
|
|
|
31374
31578
|
// src/rules/require-camelcase-properties.ts
|
|
31375
|
-
var
|
|
31579
|
+
var NAME130 = "require-camelcase-properties";
|
|
31376
31580
|
var SNAKE_CASE_RE2 = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)+$/u;
|
|
31377
31581
|
function blocksRename(member3, name) {
|
|
31378
31582
|
if (member3.type === "TSIndexSignature" || "computed" in member3 && member3.computed) return true;
|
|
@@ -31386,7 +31590,7 @@ var require_camelcase_properties_default = defineRule({
|
|
|
31386
31590
|
fixable: "code",
|
|
31387
31591
|
docs: {
|
|
31388
31592
|
description: "Require unquoted lower snake_case TypeScript properties and dot access to use camelCase.",
|
|
31389
|
-
url: docsUrl(
|
|
31593
|
+
url: docsUrl(NAME130)
|
|
31390
31594
|
},
|
|
31391
31595
|
schema: [],
|
|
31392
31596
|
defaultOptions: [],
|
|
@@ -31450,7 +31654,7 @@ var require_camelcase_properties_default = defineRule({
|
|
|
31450
31654
|
});
|
|
31451
31655
|
|
|
31452
31656
|
// src/rules/require-constrained-schema-integer.ts
|
|
31453
|
-
var
|
|
31657
|
+
var NAME131 = "require-constrained-schema-integer";
|
|
31454
31658
|
var FIELD_MINIMUMS = /* @__PURE__ */ new Map([["limit", 1], ["version", 0]]);
|
|
31455
31659
|
var NUMBER_FACTORIES = /* @__PURE__ */ new Set(["number", "int", "int32", "uint32"]);
|
|
31456
31660
|
var OBJECT_FACTORIES = /* @__PURE__ */ new Set(["object", "strictObject", "looseObject"]);
|
|
@@ -31492,7 +31696,7 @@ var require_constrained_schema_integer_default = defineRule({
|
|
|
31492
31696
|
type: "suggestion",
|
|
31493
31697
|
docs: {
|
|
31494
31698
|
description: "Declare integer and lower-bound validation for numeric limit and version schema fields.",
|
|
31495
|
-
url: docsUrl(
|
|
31699
|
+
url: docsUrl(NAME131)
|
|
31496
31700
|
},
|
|
31497
31701
|
schema: [],
|
|
31498
31702
|
messages: { constrainInteger: "Declare `{{field}}` as an integer with a lower bound of {{minimum}} or greater, or reuse its named domain schema." }
|
|
@@ -31971,14 +32175,14 @@ function closedNominalInheritanceFix(sourceCode2, file, call, consumer, implemen
|
|
|
31971
32175
|
}
|
|
31972
32176
|
|
|
31973
32177
|
// src/rules/require-explicit-contract-implementation.ts
|
|
31974
|
-
var
|
|
32178
|
+
var NAME132 = "require-explicit-contract-implementation";
|
|
31975
32179
|
var require_explicit_contract_implementation_default = defineRule({
|
|
31976
32180
|
meta: {
|
|
31977
32181
|
type: "problem",
|
|
31978
32182
|
fixable: "code",
|
|
31979
32183
|
docs: {
|
|
31980
32184
|
description: "Require nominal inheritance when an injected abstract class is rejected by an instanceof guard.",
|
|
31981
|
-
url: docsUrl(
|
|
32185
|
+
url: docsUrl(NAME132)
|
|
31982
32186
|
},
|
|
31983
32187
|
schema: [],
|
|
31984
32188
|
messages: {
|
|
@@ -32669,7 +32873,7 @@ function abstractContractOperations(node, functionAliases) {
|
|
|
32669
32873
|
}
|
|
32670
32874
|
|
|
32671
32875
|
// src/rules/require-explicit-service-contract.ts
|
|
32672
|
-
var
|
|
32876
|
+
var NAME133 = "require-explicit-service-contract";
|
|
32673
32877
|
var JAVASCRIPT_FILE_RE2 = /\.(?:js|jsx|mjs|cjs)$/iu;
|
|
32674
32878
|
var BOUNDARY_SUFFIX = /(?:Service|ServiceImpl|Store|Repository|Provider|Executor|Enqueuer|Runner|Platform|Manager|ManagerImpl|Detector|Control|Refresher|Reader|Settlement|Retry|Stop|Catalog|DAO)$/u;
|
|
32675
32879
|
var NON_SERVICE_SUFFIX = /(?:Router|Middleware|Builder)$/u;
|
|
@@ -32685,7 +32889,7 @@ var require_explicit_service_contract_default = defineRule({
|
|
|
32685
32889
|
type: "problem",
|
|
32686
32890
|
docs: {
|
|
32687
32891
|
description: "Require explicit contracts for classes that invoke retained collaborators.",
|
|
32688
|
-
url: docsUrl(
|
|
32892
|
+
url: docsUrl(NAME133)
|
|
32689
32893
|
},
|
|
32690
32894
|
schema: [],
|
|
32691
32895
|
fixable: "code",
|
|
@@ -32721,7 +32925,7 @@ var require_explicit_service_contract_default = defineRule({
|
|
|
32721
32925
|
});
|
|
32722
32926
|
|
|
32723
32927
|
// src/rules/require-fetch-timeout.ts
|
|
32724
|
-
var
|
|
32928
|
+
var NAME134 = "require-fetch-timeout";
|
|
32725
32929
|
function emptySignal(expression, resolvesToGlobal) {
|
|
32726
32930
|
const value = unwrapExpression(expression);
|
|
32727
32931
|
if (value.type === "Literal" && value.value === null)
|
|
@@ -32783,7 +32987,7 @@ var require_fetch_timeout_default = defineRule({
|
|
|
32783
32987
|
type: "problem",
|
|
32784
32988
|
docs: {
|
|
32785
32989
|
description: "Require an explicit abort signal on locally analyzable global fetch calls.",
|
|
32786
|
-
url: docsUrl(
|
|
32990
|
+
url: docsUrl(NAME134)
|
|
32787
32991
|
},
|
|
32788
32992
|
schema: [
|
|
32789
32993
|
{
|
|
@@ -32875,7 +33079,7 @@ var require_fetch_timeout_default = defineRule({
|
|
|
32875
33079
|
});
|
|
32876
33080
|
|
|
32877
33081
|
// src/rules/require-interface-for-exported-class.ts
|
|
32878
|
-
var
|
|
33082
|
+
var NAME135 = "require-interface-for-exported-class";
|
|
32879
33083
|
var JAVASCRIPT_FILE_RE3 = /\.(?:js|jsx|mjs|cjs)$/iu;
|
|
32880
33084
|
function isPublicInstanceMember2(member3) {
|
|
32881
33085
|
return !member3.static && member3.accessibility !== "private" && member3.accessibility !== "protected" && member3.key.type !== "PrivateIdentifier";
|
|
@@ -32936,7 +33140,7 @@ var require_interface_for_exported_class_default = defineRule({
|
|
|
32936
33140
|
type: "suggestion",
|
|
32937
33141
|
docs: {
|
|
32938
33142
|
description: "Require exported concrete classes with public behavior to declare a contract.",
|
|
32939
|
-
url: docsUrl(
|
|
33143
|
+
url: docsUrl(NAME135)
|
|
32940
33144
|
},
|
|
32941
33145
|
schema: [],
|
|
32942
33146
|
fixable: "code",
|
|
@@ -32978,7 +33182,7 @@ var require_interface_for_exported_class_default = defineRule({
|
|
|
32978
33182
|
});
|
|
32979
33183
|
|
|
32980
33184
|
// src/rules/require-jwt-lifetime.ts
|
|
32981
|
-
var
|
|
33185
|
+
var NAME136 = "require-jwt-lifetime";
|
|
32982
33186
|
function isJoseValueImport(declaration) {
|
|
32983
33187
|
return declaration.type === "ImportDeclaration" && declaration.importKind !== "type" && declaration.source.value === "jose";
|
|
32984
33188
|
}
|
|
@@ -32987,7 +33191,7 @@ var require_jwt_lifetime_default = defineRule({
|
|
|
32987
33191
|
type: "problem",
|
|
32988
33192
|
docs: {
|
|
32989
33193
|
description: "Require an expiration claim or a maximum token age when returning a verified JWT.",
|
|
32990
|
-
url: docsUrl(
|
|
33194
|
+
url: docsUrl(NAME136)
|
|
32991
33195
|
},
|
|
32992
33196
|
schema: [],
|
|
32993
33197
|
messages: { lifetime: "Require the JWT exp claim or set maxTokenAge before returning this verification result." }
|
|
@@ -33046,7 +33250,7 @@ var require_jwt_lifetime_default = defineRule({
|
|
|
33046
33250
|
});
|
|
33047
33251
|
|
|
33048
33252
|
// src/rules/require-pascal-case-zod-schema-name.ts
|
|
33049
|
-
var
|
|
33253
|
+
var NAME137 = "require-pascal-case-zod-schema-name";
|
|
33050
33254
|
var PASCAL_SCHEMA_NAME_RE = /^[A-Z][A-Za-z0-9]*Schema$/;
|
|
33051
33255
|
var BENCHMARK_PATH_RE2 = /(^|[\\/])(?:benchmarks?|bench)[\\/]/;
|
|
33052
33256
|
var NON_SCHEMA_TERMINALS2 = /* @__PURE__ */ new Set([
|
|
@@ -33217,7 +33421,7 @@ var require_pascal_case_zod_schema_name_default = defineRule({
|
|
|
33217
33421
|
fixable: "code",
|
|
33218
33422
|
docs: {
|
|
33219
33423
|
description: "Require confirmed module-level Zod schema contracts to use PascalCase with a `Schema` suffix.",
|
|
33220
|
-
url: docsUrl(
|
|
33424
|
+
url: docsUrl(NAME137)
|
|
33221
33425
|
},
|
|
33222
33426
|
schema: [],
|
|
33223
33427
|
defaultOptions: [],
|
|
@@ -33327,7 +33531,7 @@ var require_pascal_case_zod_schema_name_default = defineRule({
|
|
|
33327
33531
|
});
|
|
33328
33532
|
|
|
33329
33533
|
// src/rules/require-port-for-service.ts
|
|
33330
|
-
var
|
|
33534
|
+
var NAME138 = "require-port-for-service";
|
|
33331
33535
|
var HTTP_TRANSPORT_TYPE_RE = /^(?:KyInstance|AxiosInstance|Session)$/;
|
|
33332
33536
|
var TRANSPORT_WRAPPER_NAME_RE = /(?:Client$|^Http[A-Z])/;
|
|
33333
33537
|
var ERROR_VALUE_NAME_RE = /Error$/;
|
|
@@ -33461,7 +33665,7 @@ var require_port_for_service_default = defineRule({
|
|
|
33461
33665
|
type: "suggestion",
|
|
33462
33666
|
docs: {
|
|
33463
33667
|
description: "Advise when an exported service with injected collaborators has public methods not covered by its declared ports.",
|
|
33464
|
-
url: docsUrl(
|
|
33668
|
+
url: docsUrl(NAME138)
|
|
33465
33669
|
},
|
|
33466
33670
|
schema: [],
|
|
33467
33671
|
fixable: "code",
|
|
@@ -33501,7 +33705,7 @@ var require_port_for_service_default = defineRule({
|
|
|
33501
33705
|
});
|
|
33502
33706
|
|
|
33503
33707
|
// src/rules/require-sql-access-class.ts
|
|
33504
|
-
var
|
|
33708
|
+
var NAME139 = "require-sql-access-class";
|
|
33505
33709
|
var DIRECT_EXECUTION_METHODS = /* @__PURE__ */ new Set([
|
|
33506
33710
|
"all",
|
|
33507
33711
|
"batch",
|
|
@@ -33699,7 +33903,7 @@ var require_sql_access_class_default = defineRule({
|
|
|
33699
33903
|
type: "suggestion",
|
|
33700
33904
|
docs: {
|
|
33701
33905
|
description: "Keep SQL reads and writes inside a class that receives its database dependency.",
|
|
33702
|
-
url: docsUrl(
|
|
33906
|
+
url: docsUrl(NAME139)
|
|
33703
33907
|
},
|
|
33704
33908
|
schema: [],
|
|
33705
33909
|
messages: {
|
|
@@ -33771,7 +33975,7 @@ function staticMatcherFix(sourceCode2, property) {
|
|
|
33771
33975
|
}
|
|
33772
33976
|
|
|
33773
33977
|
// src/rules/require-static-next-matcher.ts
|
|
33774
|
-
var
|
|
33978
|
+
var NAME140 = "require-static-next-matcher";
|
|
33775
33979
|
var NEXT_ENTRY_FILE = /(?:^|[/\\])(?:middleware|proxy)\.[cm]?[jt]sx?$/u;
|
|
33776
33980
|
function isStaticValue(node) {
|
|
33777
33981
|
const value = unwrapExpression(node);
|
|
@@ -33803,7 +34007,7 @@ var require_static_next_matcher_default = defineRule({
|
|
|
33803
34007
|
fixable: "code",
|
|
33804
34008
|
docs: {
|
|
33805
34009
|
description: "Require Next.js middleware and proxy matcher configuration to contain only build-time literals.",
|
|
33806
|
-
url: docsUrl(
|
|
34010
|
+
url: docsUrl(NAME140)
|
|
33807
34011
|
},
|
|
33808
34012
|
schema: [],
|
|
33809
34013
|
messages: {
|
|
@@ -33847,7 +34051,7 @@ var require_static_next_matcher_default = defineRule({
|
|
|
33847
34051
|
});
|
|
33848
34052
|
|
|
33849
34053
|
// src/rules/require-svg-accessible-name.ts
|
|
33850
|
-
var
|
|
34054
|
+
var NAME141 = "require-svg-accessible-name";
|
|
33851
34055
|
var DECORATIVE_ROLES = /* @__PURE__ */ new Set(["none", "presentation"]);
|
|
33852
34056
|
var NAME_ATTRIBUTES = ["aria-label", "aria-labelledby"];
|
|
33853
34057
|
var NO_ICON_MODULES = [];
|
|
@@ -33856,7 +34060,7 @@ var require_svg_accessible_name_default = defineRule({
|
|
|
33856
34060
|
type: "problem",
|
|
33857
34061
|
docs: {
|
|
33858
34062
|
description: "Require a name or explicit decorative semantics on inline SVG elements.",
|
|
33859
|
-
url: docsUrl(
|
|
34063
|
+
url: docsUrl(NAME141)
|
|
33860
34064
|
},
|
|
33861
34065
|
schema: [],
|
|
33862
34066
|
messages: {
|
|
@@ -33888,7 +34092,7 @@ var require_svg_accessible_name_default = defineRule({
|
|
|
33888
34092
|
});
|
|
33889
34093
|
|
|
33890
34094
|
// src/rules/require-use-form-default-values.ts
|
|
33891
|
-
var
|
|
34095
|
+
var NAME142 = "require-use-form-default-values";
|
|
33892
34096
|
var UNSAFE_FORM_MEMBERS = /* @__PURE__ */ new Set(["__defineGetter__", "__defineSetter__", "__proto__", "valueOf"]);
|
|
33893
34097
|
function staticPropertyName2(property) {
|
|
33894
34098
|
return property.computed ? null : getPropertyName(property);
|
|
@@ -33931,7 +34135,7 @@ var require_use_form_default_values_default = defineRule({
|
|
|
33931
34135
|
type: "problem",
|
|
33932
34136
|
docs: {
|
|
33933
34137
|
description: "Require explicit form-level initialization or a field default for directly bound Controller fields.",
|
|
33934
|
-
url: docsUrl(
|
|
34138
|
+
url: docsUrl(NAME142)
|
|
33935
34139
|
},
|
|
33936
34140
|
schema: [],
|
|
33937
34141
|
messages: { requireUseFormDefaultValues: "Add non-undefined defaultValues/values to the associated useForm call or non-undefined defaultValue to this field." }
|
|
@@ -34070,7 +34274,7 @@ var require_use_form_default_values_default = defineRule({
|
|
|
34070
34274
|
});
|
|
34071
34275
|
|
|
34072
34276
|
// src/rules/require-use-server-in-actions-file.ts
|
|
34073
|
-
var
|
|
34277
|
+
var NAME143 = "require-use-server-in-actions-file";
|
|
34074
34278
|
var ACTION_MODULE_RE = /(?:^|\/)app\/.*\/(?:actions|[^/]+-actions)\.[cm]?[jt]s$/u;
|
|
34075
34279
|
function isUseServerDirective2(statement) {
|
|
34076
34280
|
return statement.type === "ExpressionStatement" && statement.directive === "use server";
|
|
@@ -34091,7 +34295,7 @@ var require_use_server_in_actions_file_default = defineRule({
|
|
|
34091
34295
|
type: "problem",
|
|
34092
34296
|
docs: {
|
|
34093
34297
|
description: "route action module missing the use server directive",
|
|
34094
|
-
url: docsUrl(
|
|
34298
|
+
url: docsUrl(NAME143)
|
|
34095
34299
|
},
|
|
34096
34300
|
schema: [],
|
|
34097
34301
|
messages: {
|
|
@@ -34117,7 +34321,7 @@ var require_use_server_in_actions_file_default = defineRule({
|
|
|
34117
34321
|
});
|
|
34118
34322
|
|
|
34119
34323
|
// src/rules/require-zod-form-validation.ts
|
|
34120
|
-
var
|
|
34324
|
+
var NAME144 = "require-zod-form-validation";
|
|
34121
34325
|
var ZOD_PARSE_METHODS = /* @__PURE__ */ new Set([
|
|
34122
34326
|
"parse",
|
|
34123
34327
|
"safeParse",
|
|
@@ -34176,7 +34380,7 @@ var require_zod_form_validation_default = defineRule({
|
|
|
34176
34380
|
type: "problem",
|
|
34177
34381
|
docs: {
|
|
34178
34382
|
description: "Require Zod validation (`Schema.parse(...)` / `Schema.safeParse(...)`) when reading values out of a `FormData` object.",
|
|
34179
|
-
url: docsUrl(
|
|
34383
|
+
url: docsUrl(NAME144)
|
|
34180
34384
|
},
|
|
34181
34385
|
schema: [],
|
|
34182
34386
|
messages: {
|
|
@@ -34464,7 +34668,7 @@ function declaresFramework(metadata, name) {
|
|
|
34464
34668
|
}
|
|
34465
34669
|
|
|
34466
34670
|
// src/rules/sole-export-matches-filename.ts
|
|
34467
|
-
var
|
|
34671
|
+
var NAME145 = "sole-export-matches-filename";
|
|
34468
34672
|
var EXCLUDED_STEMS = /* @__PURE__ */ new Set(["global", "index", "types"]);
|
|
34469
34673
|
function stem3(filename) {
|
|
34470
34674
|
const base = filename.replaceAll("\\", "/").split("/").at(-1) ?? "";
|
|
@@ -34478,7 +34682,7 @@ var sole_export_matches_filename_default = defineRule({
|
|
|
34478
34682
|
type: "suggestion",
|
|
34479
34683
|
docs: {
|
|
34480
34684
|
description: "Make a module filename reflect its sole named public runtime export.",
|
|
34481
|
-
url: docsUrl(
|
|
34685
|
+
url: docsUrl(NAME145)
|
|
34482
34686
|
},
|
|
34483
34687
|
schema: [],
|
|
34484
34688
|
messages: {
|
|
@@ -35221,7 +35425,7 @@ var stepdown_default = defineRule({
|
|
|
35221
35425
|
});
|
|
35222
35426
|
|
|
35223
35427
|
// src/rules/store-insert-requires-on-conflict.ts
|
|
35224
|
-
var
|
|
35428
|
+
var NAME146 = "store-insert-requires-on-conflict";
|
|
35225
35429
|
var INSERT_WRITE = /\bINSERT\s+(?:OR\s+\w+\s+)?INTO\s+[\w."'`?$:@-]+\s*(?:\([^)]*\)\s*)?(?:VALUES|SELECT|DEFAULT\s+VALUES)\b/i;
|
|
35226
35430
|
var CONFLICT_HANDLED = /\bON\s+CONFLICT\b|\bON\s+DUPLICATE\s+KEY\b|\bINSERT\s+OR\s+(?:IGNORE|REPLACE)\b|\bINSERT\b[\s\S]*?\bSELECT\b[\s\S]*?\bWHERE\s+NOT\s+EXISTS\b/i;
|
|
35227
35431
|
var REPLAY_CONTRACT_NAME = /(?:enqueue|ensure|migrate|recordOnce|schedule|seed|upsert|getOrCreate|createIfAbsent|insertIfAbsent)/i;
|
|
@@ -35250,7 +35454,7 @@ var store_insert_requires_on_conflict_default = defineRule({
|
|
|
35250
35454
|
type: "problem",
|
|
35251
35455
|
docs: {
|
|
35252
35456
|
description: "Review conflict handling for embedded inserts in replay-named callables.",
|
|
35253
|
-
url: docsUrl(
|
|
35457
|
+
url: docsUrl(NAME146)
|
|
35254
35458
|
},
|
|
35255
35459
|
schema: [],
|
|
35256
35460
|
messages: {
|
|
@@ -35275,7 +35479,7 @@ var store_insert_requires_on_conflict_default = defineRule({
|
|
|
35275
35479
|
});
|
|
35276
35480
|
|
|
35277
35481
|
// src/rules/test-loops-over-literal-cases.ts
|
|
35278
|
-
var
|
|
35482
|
+
var NAME147 = "test-loops-over-literal-cases";
|
|
35279
35483
|
var TEST_CALLERS3 = /* @__PURE__ */ new Set(["it", "test"]);
|
|
35280
35484
|
var TEST_MODIFIERS6 = /* @__PURE__ */ new Set(["concurrent", "fails", "only", "sequential", "skip"]);
|
|
35281
35485
|
var ASSERTION_ROOTS = /* @__PURE__ */ new Set([
|
|
@@ -35371,7 +35575,7 @@ var test_loops_over_literal_cases_default = defineRule({
|
|
|
35371
35575
|
type: "suggestion",
|
|
35372
35576
|
docs: {
|
|
35373
35577
|
description: "Disallow assertions over an inline literal case loop in a test; parameterization reports and names every case independently.",
|
|
35374
|
-
url: docsUrl(
|
|
35578
|
+
url: docsUrl(NAME147)
|
|
35375
35579
|
},
|
|
35376
35580
|
schema: [],
|
|
35377
35581
|
messages: {
|
|
@@ -35435,7 +35639,7 @@ var test_loops_over_literal_cases_default = defineRule({
|
|
|
35435
35639
|
});
|
|
35436
35640
|
|
|
35437
35641
|
// src/rules/test-phase-label-comment.ts
|
|
35438
|
-
var
|
|
35642
|
+
var NAME148 = "test-phase-label-comment";
|
|
35439
35643
|
var PHASE_WORD = String.raw`arrange|act|assert(?:ion)?s?|given|when|then|exercise|execute|verif(?:y|ication)|cleanup|prepare|sanity(?:\s+check)?`;
|
|
35440
35644
|
var PHASE_RE = new RegExp(
|
|
35441
35645
|
String.raw`^[-=~*_#.\s]{0,40}(?:${PHASE_WORD})(?:\s*(?:[/&+,|]|->|and)\s*(?:${PHASE_WORD}))*[-=~*_#.\s:;!–—]{0,40}$`,
|
|
@@ -35463,7 +35667,7 @@ var test_phase_label_comment_default = defineRule({
|
|
|
35463
35667
|
fixable: "code",
|
|
35464
35668
|
docs: {
|
|
35465
35669
|
description: "Tests must not use bare Arrange, Act, Assert, Given, When, or Then phase comments.",
|
|
35466
|
-
url: docsUrl(
|
|
35670
|
+
url: docsUrl(NAME148)
|
|
35467
35671
|
},
|
|
35468
35672
|
schema: [],
|
|
35469
35673
|
messages: { removeLabel: "Bare test phase label \u2014 delete it and let the test names and helpers carry the structure." }
|
|
@@ -35605,6 +35809,7 @@ var RULES = {
|
|
|
35605
35809
|
"no-zod-parse-typed-object": no_zod_parse_typed_object_default,
|
|
35606
35810
|
"prefer-await-in-async-return": prefer_await_in_async_return_default,
|
|
35607
35811
|
"prefer-coded-error-result": prefer_coded_error_result_default,
|
|
35812
|
+
"prefer-configured-cloud-scope": prefer_configured_cloud_scope_default,
|
|
35608
35813
|
"prefer-constant-time-secret-compare": prefer_constant_time_secret_compare_default,
|
|
35609
35814
|
"prefer-dependency-interface": prefer_dependency_interface_default,
|
|
35610
35815
|
"prefer-discriminated-union": prefer_discriminated_union_default,
|