@sarj/eslint-plugin 15.17.1 → 15.17.2
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/index.cjs +420 -115
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +459 -148
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12019,100 +12019,371 @@ var prefer_module_level_schema_default = createRule({
|
|
|
12019
12019
|
});
|
|
12020
12020
|
|
|
12021
12021
|
// src/rules/prefer-module-level-refined-schema.ts
|
|
12022
|
-
import {
|
|
12022
|
+
import {
|
|
12023
|
+
AST_NODE_TYPES as AST_NODE_TYPES53,
|
|
12024
|
+
ASTUtils as ASTUtils15
|
|
12025
|
+
} from "@typescript-eslint/utils";
|
|
12026
|
+
var BENCHMARK_PATH_RE = /(^|[/\\])(?:benchmarks?|bench)[/\\]/;
|
|
12023
12027
|
var FACTORIES = /* @__PURE__ */ new Set([
|
|
12024
12028
|
"array",
|
|
12029
|
+
"base64",
|
|
12030
|
+
"base64url",
|
|
12025
12031
|
"bigint",
|
|
12026
12032
|
"boolean",
|
|
12033
|
+
"cidrv4",
|
|
12034
|
+
"cidrv6",
|
|
12035
|
+
"codec",
|
|
12036
|
+
"custom",
|
|
12027
12037
|
"date",
|
|
12028
|
-
"
|
|
12029
|
-
"
|
|
12030
|
-
]);
|
|
12031
|
-
var REFINEMENTS = /* @__PURE__ */ new Set([
|
|
12032
|
-
"brand",
|
|
12033
|
-
"check",
|
|
12038
|
+
"datetime",
|
|
12039
|
+
"duration",
|
|
12034
12040
|
"email",
|
|
12035
|
-
"
|
|
12036
|
-
"
|
|
12037
|
-
"
|
|
12038
|
-
"
|
|
12039
|
-
"
|
|
12040
|
-
"
|
|
12041
|
-
"
|
|
12042
|
-
"
|
|
12043
|
-
"
|
|
12044
|
-
"
|
|
12045
|
-
"
|
|
12046
|
-
"
|
|
12047
|
-
"
|
|
12048
|
-
"
|
|
12041
|
+
"emoji",
|
|
12042
|
+
"enum",
|
|
12043
|
+
"file",
|
|
12044
|
+
"function",
|
|
12045
|
+
"hash",
|
|
12046
|
+
"hex",
|
|
12047
|
+
"hostname",
|
|
12048
|
+
"instanceof",
|
|
12049
|
+
"ipv4",
|
|
12050
|
+
"ipv6",
|
|
12051
|
+
"json",
|
|
12052
|
+
"jwt",
|
|
12053
|
+
"literal",
|
|
12054
|
+
"map",
|
|
12055
|
+
"nan",
|
|
12056
|
+
"nativeEnum",
|
|
12057
|
+
"never",
|
|
12058
|
+
"null",
|
|
12059
|
+
"nullable",
|
|
12060
|
+
"nullish",
|
|
12061
|
+
"number",
|
|
12062
|
+
"optional",
|
|
12063
|
+
"partialRecord",
|
|
12064
|
+
"preprocess",
|
|
12065
|
+
"promise",
|
|
12066
|
+
"set",
|
|
12067
|
+
"string",
|
|
12068
|
+
"stringbool",
|
|
12069
|
+
"symbol",
|
|
12070
|
+
"templateLiteral",
|
|
12071
|
+
"time",
|
|
12072
|
+
"undefined",
|
|
12049
12073
|
"url",
|
|
12050
|
-
"uuid"
|
|
12074
|
+
"uuid",
|
|
12075
|
+
"void"
|
|
12076
|
+
]);
|
|
12077
|
+
var COMPOSITE_FACTORIES = /* @__PURE__ */ new Set([
|
|
12078
|
+
"discriminatedUnion",
|
|
12079
|
+
"intersection",
|
|
12080
|
+
"looseObject",
|
|
12081
|
+
"object",
|
|
12082
|
+
"record",
|
|
12083
|
+
"strictObject",
|
|
12084
|
+
"tuple",
|
|
12085
|
+
"union"
|
|
12086
|
+
]);
|
|
12087
|
+
var FACTORY_NAMESPACES = /* @__PURE__ */ new Set(["coerce", "iso"]);
|
|
12088
|
+
var NON_SCHEMA_TERMINALS = /* @__PURE__ */ new Set([
|
|
12089
|
+
"decode",
|
|
12090
|
+
"decodeAsync",
|
|
12091
|
+
"encode",
|
|
12092
|
+
"encodeAsync",
|
|
12093
|
+
"flattenError",
|
|
12094
|
+
"formatError",
|
|
12095
|
+
"implement",
|
|
12096
|
+
"isNullable",
|
|
12097
|
+
"isOptional",
|
|
12098
|
+
"parse",
|
|
12099
|
+
"parseAsync",
|
|
12100
|
+
"prettifyError",
|
|
12101
|
+
"registry",
|
|
12102
|
+
"safeDecode",
|
|
12103
|
+
"safeDecodeAsync",
|
|
12104
|
+
"safeEncode",
|
|
12105
|
+
"safeEncodeAsync",
|
|
12106
|
+
"safeParse",
|
|
12107
|
+
"safeParseAsync",
|
|
12108
|
+
"spa",
|
|
12109
|
+
"toJSONSchema",
|
|
12110
|
+
"treeifyError"
|
|
12111
|
+
]);
|
|
12112
|
+
var MEMO_CALLEES2 = /* @__PURE__ */ new Set([
|
|
12113
|
+
"lazy",
|
|
12114
|
+
"memo",
|
|
12115
|
+
"once",
|
|
12116
|
+
"useMemo"
|
|
12117
|
+
]);
|
|
12118
|
+
var I18N_CALLEE_NAMES2 = /* @__PURE__ */ new Set([
|
|
12119
|
+
"$t",
|
|
12120
|
+
"defineMessage",
|
|
12121
|
+
"gettext",
|
|
12122
|
+
"msg",
|
|
12123
|
+
"ngettext",
|
|
12124
|
+
"t",
|
|
12125
|
+
"translate"
|
|
12126
|
+
]);
|
|
12127
|
+
var I18N_RECEIVER_NAMES2 = /* @__PURE__ */ new Set([
|
|
12128
|
+
"$i18n",
|
|
12129
|
+
"i18n",
|
|
12130
|
+
"intl"
|
|
12131
|
+
]);
|
|
12132
|
+
var FUNCTION_TYPES9 = /* @__PURE__ */ new Set([
|
|
12133
|
+
AST_NODE_TYPES53.ArrowFunctionExpression,
|
|
12134
|
+
AST_NODE_TYPES53.FunctionDeclaration,
|
|
12135
|
+
AST_NODE_TYPES53.FunctionExpression
|
|
12051
12136
|
]);
|
|
12052
12137
|
var PREFER_MODULE_LEVEL_REFINED_SCHEMA_DOCUMENTATION = {
|
|
12053
|
-
summary: "Declare closed
|
|
12138
|
+
summary: "Declare closed Zod scalar, format, and wrapper schemas at module scope.",
|
|
12054
12139
|
rationale: "A closed validation pipeline created inside a function is rebuilt on every invocation and obscures a reusable constraint.",
|
|
12055
|
-
remediation: "Move the validation schema to module scope and call parse on the shared schema.",
|
|
12140
|
+
remediation: "Move the validation schema to module scope, name it with a PascalCase Schema suffix, and call parse on the shared schema.",
|
|
12056
12141
|
category: "performance",
|
|
12057
|
-
limitations: [
|
|
12142
|
+
limitations: [
|
|
12143
|
+
"Composite object/record/tuple/union schemas are owned by prefer-module-level-schema.",
|
|
12144
|
+
"Schemas that depend on function-local or mutable state, localized text, receiver state, lazy construction, or recognized memoization are excluded.",
|
|
12145
|
+
"Literal string z.enum domains are owned by prefer-shared-zod-enum."
|
|
12146
|
+
],
|
|
12058
12147
|
examples: [
|
|
12059
|
-
{
|
|
12060
|
-
|
|
12148
|
+
{
|
|
12149
|
+
id: "module-refinement",
|
|
12150
|
+
title: "Share the validation schema",
|
|
12151
|
+
outcome: "no-match",
|
|
12152
|
+
files: [{
|
|
12153
|
+
path: "src/options.ts",
|
|
12154
|
+
source: "import { z } from 'zod'; const BatchSizeSchema = z.number().int().min(1).max(1000); export function parse(value: unknown) { return BatchSizeSchema.parse(value); }"
|
|
12155
|
+
}],
|
|
12156
|
+
focusPath: "src/options.ts",
|
|
12157
|
+
expectedCount: 0,
|
|
12158
|
+
public: true
|
|
12159
|
+
},
|
|
12160
|
+
{
|
|
12161
|
+
id: "local-refinement",
|
|
12162
|
+
title: "Do not rebuild a closed validation chain",
|
|
12163
|
+
outcome: "match",
|
|
12164
|
+
files: [{
|
|
12165
|
+
path: "src/options.ts",
|
|
12166
|
+
source: "import { z } from 'zod'; export function parse(value: unknown) { return z.string().trim().min(1).max(128).parse(value); }"
|
|
12167
|
+
}],
|
|
12168
|
+
focusPath: "src/options.ts",
|
|
12169
|
+
expectedCount: 1,
|
|
12170
|
+
public: true
|
|
12171
|
+
}
|
|
12061
12172
|
]
|
|
12062
12173
|
};
|
|
12063
|
-
function
|
|
12174
|
+
function outermostEnclosingFunction2(node) {
|
|
12175
|
+
let outermost;
|
|
12064
12176
|
let current = node.parent ?? void 0;
|
|
12065
12177
|
while (current !== void 0) {
|
|
12066
|
-
if (
|
|
12178
|
+
if (FUNCTION_TYPES9.has(current.type)) outermost = current;
|
|
12067
12179
|
current = current.parent ?? void 0;
|
|
12068
12180
|
}
|
|
12069
|
-
return
|
|
12181
|
+
return outermost;
|
|
12070
12182
|
}
|
|
12071
12183
|
function collectReferences2(scope, output) {
|
|
12072
12184
|
output.push(...scope.references);
|
|
12073
12185
|
for (const child of scope.childScopes) collectReferences2(child, output);
|
|
12074
12186
|
}
|
|
12187
|
+
function subtreeSome2(root, predicate) {
|
|
12188
|
+
let found = false;
|
|
12189
|
+
const visit = (value) => {
|
|
12190
|
+
if (found || value === null || typeof value !== "object") return;
|
|
12191
|
+
if (Array.isArray(value)) {
|
|
12192
|
+
for (const item of value) visit(item);
|
|
12193
|
+
return;
|
|
12194
|
+
}
|
|
12195
|
+
const candidate2 = value;
|
|
12196
|
+
if (typeof candidate2.type !== "string") return;
|
|
12197
|
+
if (predicate(candidate2)) {
|
|
12198
|
+
found = true;
|
|
12199
|
+
return;
|
|
12200
|
+
}
|
|
12201
|
+
for (const key of Object.keys(candidate2)) {
|
|
12202
|
+
if (key === "parent" || key === "loc" || key === "range") continue;
|
|
12203
|
+
visit(candidate2[key]);
|
|
12204
|
+
}
|
|
12205
|
+
};
|
|
12206
|
+
visit(root);
|
|
12207
|
+
return found;
|
|
12208
|
+
}
|
|
12209
|
+
function readsReceiver2(node) {
|
|
12210
|
+
return subtreeSome2(
|
|
12211
|
+
node,
|
|
12212
|
+
(inner) => inner.type === AST_NODE_TYPES53.ThisExpression || inner.type === AST_NODE_TYPES53.Super || inner.type === AST_NODE_TYPES53.Identifier && inner.name === "arguments"
|
|
12213
|
+
);
|
|
12214
|
+
}
|
|
12215
|
+
function buildsLocalizedText2(node) {
|
|
12216
|
+
return subtreeSome2(node, (inner) => {
|
|
12217
|
+
if (inner.type === AST_NODE_TYPES53.TaggedTemplateExpression) return true;
|
|
12218
|
+
if (inner.type !== AST_NODE_TYPES53.CallExpression) return false;
|
|
12219
|
+
const { callee } = inner;
|
|
12220
|
+
if (callee.type === AST_NODE_TYPES53.Identifier)
|
|
12221
|
+
return I18N_CALLEE_NAMES2.has(callee.name);
|
|
12222
|
+
return callee.type === AST_NODE_TYPES53.MemberExpression && !callee.computed && callee.object.type === AST_NODE_TYPES53.Identifier && I18N_RECEIVER_NAMES2.has(callee.object.name);
|
|
12223
|
+
});
|
|
12224
|
+
}
|
|
12225
|
+
function calleeChainRoot(node) {
|
|
12226
|
+
let current = node;
|
|
12227
|
+
for (; ; ) {
|
|
12228
|
+
if (current.type === AST_NODE_TYPES53.Identifier) return current;
|
|
12229
|
+
if (current.type === AST_NODE_TYPES53.MemberExpression) {
|
|
12230
|
+
current = current.object;
|
|
12231
|
+
continue;
|
|
12232
|
+
}
|
|
12233
|
+
if (current.type === AST_NODE_TYPES53.CallExpression) {
|
|
12234
|
+
current = current.callee;
|
|
12235
|
+
continue;
|
|
12236
|
+
}
|
|
12237
|
+
return null;
|
|
12238
|
+
}
|
|
12239
|
+
}
|
|
12240
|
+
function chainMemberNames(node) {
|
|
12241
|
+
const names = [];
|
|
12242
|
+
let current = node;
|
|
12243
|
+
for (; ; ) {
|
|
12244
|
+
if (current.type === AST_NODE_TYPES53.MemberExpression) {
|
|
12245
|
+
if (current.computed || current.property.type !== AST_NODE_TYPES53.Identifier)
|
|
12246
|
+
return [];
|
|
12247
|
+
names.push(current.property.name);
|
|
12248
|
+
current = current.object;
|
|
12249
|
+
continue;
|
|
12250
|
+
}
|
|
12251
|
+
if (current.type === AST_NODE_TYPES53.CallExpression) {
|
|
12252
|
+
current = current.callee;
|
|
12253
|
+
continue;
|
|
12254
|
+
}
|
|
12255
|
+
break;
|
|
12256
|
+
}
|
|
12257
|
+
names.reverse();
|
|
12258
|
+
return names;
|
|
12259
|
+
}
|
|
12260
|
+
function schemaExpression2(node) {
|
|
12261
|
+
let current = node;
|
|
12262
|
+
for (; ; ) {
|
|
12263
|
+
const parent = current.parent ?? void 0;
|
|
12264
|
+
if (parent?.type === AST_NODE_TYPES53.MemberExpression && parent.object === current && !parent.computed && parent.property.type === AST_NODE_TYPES53.Identifier && parent.parent?.type === AST_NODE_TYPES53.CallExpression && parent.parent.callee === parent) {
|
|
12265
|
+
if (NON_SCHEMA_TERMINALS.has(parent.property.name)) return current;
|
|
12266
|
+
current = parent.parent;
|
|
12267
|
+
continue;
|
|
12268
|
+
}
|
|
12269
|
+
if (parent?.type === AST_NODE_TYPES53.TSAsExpression || parent?.type === AST_NODE_TYPES53.TSNonNullExpression || parent?.type === AST_NODE_TYPES53.TSSatisfiesExpression || parent?.type === AST_NODE_TYPES53.TSTypeAssertion) {
|
|
12270
|
+
current = parent;
|
|
12271
|
+
continue;
|
|
12272
|
+
}
|
|
12273
|
+
return current;
|
|
12274
|
+
}
|
|
12275
|
+
}
|
|
12075
12276
|
var prefer_module_level_refined_schema_default = createRule({
|
|
12076
12277
|
name: "prefer-module-level-refined-schema",
|
|
12077
12278
|
documentation: PREFER_MODULE_LEVEL_REFINED_SCHEMA_DOCUMENTATION,
|
|
12078
|
-
meta: {
|
|
12279
|
+
meta: {
|
|
12280
|
+
type: "suggestion",
|
|
12281
|
+
docs: {
|
|
12282
|
+
description: "Declare closed Zod scalar, format, and wrapper schemas at module scope."
|
|
12283
|
+
},
|
|
12284
|
+
schema: [],
|
|
12285
|
+
messages: {
|
|
12286
|
+
hoistRefinedSchema: "Move this closed Zod schema to module scope, give it a PascalCase Schema name, and reuse it for parsing."
|
|
12287
|
+
}
|
|
12288
|
+
},
|
|
12079
12289
|
defaultOptions: [],
|
|
12080
12290
|
create(context) {
|
|
12081
|
-
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text))
|
|
12082
|
-
|
|
12291
|
+
if (isTestFile(context.filename) || BENCHMARK_PATH_RE.test(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text))
|
|
12292
|
+
return {};
|
|
12293
|
+
const zodBindings = /* @__PURE__ */ new Set();
|
|
12294
|
+
function resolvedBinding(identifier) {
|
|
12295
|
+
return ASTUtils15.findVariable(
|
|
12296
|
+
context.sourceCode.getScope(identifier),
|
|
12297
|
+
identifier.name
|
|
12298
|
+
);
|
|
12299
|
+
}
|
|
12300
|
+
function recordZodBinding(identifier) {
|
|
12301
|
+
const binding = resolvedBinding(identifier);
|
|
12302
|
+
if (binding !== null) zodBindings.add(binding);
|
|
12303
|
+
}
|
|
12304
|
+
function factoryName(node, allowed) {
|
|
12305
|
+
if (node.callee.type !== AST_NODE_TYPES53.MemberExpression) return null;
|
|
12306
|
+
const root = calleeChainRoot(node.callee);
|
|
12307
|
+
if (root === null) return null;
|
|
12308
|
+
const binding = resolvedBinding(root);
|
|
12309
|
+
if (binding === null || !zodBindings.has(binding)) return null;
|
|
12310
|
+
const names = chainMemberNames(node.callee);
|
|
12311
|
+
if (names.length === 1 && allowed.has(names[0] ?? ""))
|
|
12312
|
+
return names[0] ?? null;
|
|
12313
|
+
if (names.length === 2 && FACTORY_NAMESPACES.has(names[0] ?? "") && allowed.has(names[1] ?? ""))
|
|
12314
|
+
return names[1] ?? null;
|
|
12315
|
+
return null;
|
|
12316
|
+
}
|
|
12317
|
+
function isSharedEnumDomain(node, factory) {
|
|
12318
|
+
if (factory !== "enum") return false;
|
|
12319
|
+
const [argument] = node.arguments;
|
|
12320
|
+
return argument?.type === AST_NODE_TYPES53.ArrayExpression && argument.elements.length >= 2 && argument.elements.every(
|
|
12321
|
+
(element) => element?.type === AST_NODE_TYPES53.Literal && typeof element.value === "string"
|
|
12322
|
+
);
|
|
12323
|
+
}
|
|
12324
|
+
function isNestedInOwnedFactory(node) {
|
|
12325
|
+
let current = node;
|
|
12326
|
+
while (current.parent != null) {
|
|
12327
|
+
current = current.parent;
|
|
12328
|
+
if (FUNCTION_TYPES9.has(current.type)) return false;
|
|
12329
|
+
if (current.type === AST_NODE_TYPES53.CallExpression && (factoryName(current, FACTORIES) !== null || factoryName(current, COMPOSITE_FACTORIES) !== null))
|
|
12330
|
+
return true;
|
|
12331
|
+
}
|
|
12332
|
+
return false;
|
|
12333
|
+
}
|
|
12334
|
+
function isMemoized(node) {
|
|
12335
|
+
let current = node.parent ?? void 0;
|
|
12336
|
+
while (current !== void 0) {
|
|
12337
|
+
if (current.type === AST_NODE_TYPES53.CallExpression && (current.callee.type === AST_NODE_TYPES53.Identifier && MEMO_CALLEES2.has(current.callee.name) || current.callee.type === AST_NODE_TYPES53.MemberExpression && !current.callee.computed && current.callee.property.type === AST_NODE_TYPES53.Identifier && MEMO_CALLEES2.has(current.callee.property.name)))
|
|
12338
|
+
return true;
|
|
12339
|
+
current = current.parent ?? void 0;
|
|
12340
|
+
}
|
|
12341
|
+
return false;
|
|
12342
|
+
}
|
|
12343
|
+
function closesOverNothing(node, enclosing) {
|
|
12344
|
+
const references = [];
|
|
12345
|
+
collectReferences2(context.sourceCode.getScope(node), references);
|
|
12346
|
+
const [start, end] = node.range;
|
|
12347
|
+
const [functionStart, functionEnd] = enclosing.range;
|
|
12348
|
+
for (const reference of references) {
|
|
12349
|
+
const [referenceStart] = reference.identifier.range;
|
|
12350
|
+
if (referenceStart < start || referenceStart >= end) continue;
|
|
12351
|
+
const resolved = reference.resolved;
|
|
12352
|
+
if (resolved === null) continue;
|
|
12353
|
+
for (const definition of resolved.defs) {
|
|
12354
|
+
if (definition.type === "ImportBinding") {
|
|
12355
|
+
const parent = reference.identifier.parent;
|
|
12356
|
+
if (parent?.type === AST_NODE_TYPES53.CallExpression && parent.callee === reference.identifier && !zodBindings.has(resolved))
|
|
12357
|
+
return false;
|
|
12358
|
+
continue;
|
|
12359
|
+
}
|
|
12360
|
+
if (definition.node.type === AST_NODE_TYPES53.VariableDeclarator && definition.node.parent.type === AST_NODE_TYPES53.VariableDeclaration && definition.node.parent.kind !== "const")
|
|
12361
|
+
return false;
|
|
12362
|
+
const [definitionStart, definitionEnd] = definition.node.range;
|
|
12363
|
+
if (definitionStart >= start && definitionEnd <= end) continue;
|
|
12364
|
+
if (definitionStart >= functionStart && definitionEnd <= functionEnd)
|
|
12365
|
+
return false;
|
|
12366
|
+
}
|
|
12367
|
+
}
|
|
12368
|
+
return true;
|
|
12369
|
+
}
|
|
12083
12370
|
return {
|
|
12084
12371
|
ImportDeclaration(node) {
|
|
12085
12372
|
if (!isZodModule(node.source.value)) return;
|
|
12086
|
-
for (const specifier of node.specifiers)
|
|
12373
|
+
for (const specifier of node.specifiers) {
|
|
12374
|
+
if (specifier.type === AST_NODE_TYPES53.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES53.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES53.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES53.Identifier ? specifier.imported.name === "z" : specifier.imported.value === "z"))
|
|
12375
|
+
recordZodBinding(specifier.local);
|
|
12376
|
+
}
|
|
12087
12377
|
},
|
|
12088
12378
|
CallExpression(node) {
|
|
12089
|
-
const
|
|
12090
|
-
if (
|
|
12091
|
-
|
|
12092
|
-
|
|
12093
|
-
|
|
12094
|
-
|
|
12095
|
-
|
|
12096
|
-
|
|
12097
|
-
if (REFINEMENTS.has(current.parent.property.name)) refinements += 1;
|
|
12098
|
-
current = call;
|
|
12099
|
-
}
|
|
12100
|
-
if (refinements < 2) return;
|
|
12101
|
-
const references = [];
|
|
12102
|
-
collectReferences2(context.sourceCode.getScope(current), references);
|
|
12103
|
-
const [start, end] = current.range;
|
|
12104
|
-
const [functionStart, functionEnd] = enclosing.range;
|
|
12105
|
-
for (const reference of references) {
|
|
12106
|
-
const [referenceStart] = reference.identifier.range;
|
|
12107
|
-
if (referenceStart < start || referenceStart >= end || reference.resolved === null) continue;
|
|
12108
|
-
for (const definition of reference.resolved.defs) {
|
|
12109
|
-
if (definition.type === "ImportBinding") continue;
|
|
12110
|
-
if (definition.node.type === AST_NODE_TYPES53.VariableDeclarator && definition.node.parent.type === AST_NODE_TYPES53.VariableDeclaration && definition.node.parent.kind !== "const") return;
|
|
12111
|
-
const [definitionStart, definitionEnd] = definition.node.range;
|
|
12112
|
-
if (definitionStart >= start && definitionEnd <= end) continue;
|
|
12113
|
-
if (definitionStart >= functionStart && definitionEnd <= functionEnd) return;
|
|
12114
|
-
}
|
|
12115
|
-
}
|
|
12379
|
+
const factory = factoryName(node, FACTORIES);
|
|
12380
|
+
if (factory === null || isSharedEnumDomain(node, factory) || isNestedInOwnedFactory(node) || isMemoized(node))
|
|
12381
|
+
return;
|
|
12382
|
+
const enclosing = outermostEnclosingFunction2(node);
|
|
12383
|
+
if (enclosing === void 0) return;
|
|
12384
|
+
const expression = schemaExpression2(node);
|
|
12385
|
+
if (readsReceiver2(expression) || buildsLocalizedText2(expression) || !closesOverNothing(expression, enclosing))
|
|
12386
|
+
return;
|
|
12116
12387
|
context.report({ node, messageId: "hoistRefinedSchema" });
|
|
12117
12388
|
}
|
|
12118
12389
|
};
|
|
@@ -12120,26 +12391,30 @@ var prefer_module_level_refined_schema_default = createRule({
|
|
|
12120
12391
|
});
|
|
12121
12392
|
|
|
12122
12393
|
// src/rules/prefer-multi-value-zod-literal.ts
|
|
12123
|
-
import {
|
|
12394
|
+
import {
|
|
12395
|
+
AST_NODE_TYPES as AST_NODE_TYPES54,
|
|
12396
|
+
ASTUtils as ASTUtils16
|
|
12397
|
+
} from "@typescript-eslint/utils";
|
|
12124
12398
|
var PREFER_MULTI_VALUE_ZOD_LITERAL_DOCUMENTATION = {
|
|
12125
12399
|
summary: "Use the Zod 4 multi-value literal API instead of a union of literal schemas.",
|
|
12126
12400
|
rationale: "One multi-value literal expresses the same closed value domain without repeated schema wrappers.",
|
|
12127
12401
|
remediation: "Replace the union with z.literal([value1, value2, ...]).",
|
|
12128
12402
|
category: "maintainability",
|
|
12403
|
+
autofix: "safe",
|
|
12129
12404
|
limitations: [
|
|
12130
|
-
"Bare
|
|
12405
|
+
"Bare zod imports are analyzed only when the rule option explicitly declares zodMajorVersion: 4; explicit zod/v4 entrypoints are self-declaring.",
|
|
12406
|
+
"All-string domains are left to zod/prefer-enum-over-literal-union.",
|
|
12407
|
+
"A finding containing comments is not autofixed because moving its trivia is ambiguous."
|
|
12131
12408
|
],
|
|
12132
12409
|
examples: [
|
|
12133
12410
|
{
|
|
12134
12411
|
id: "multi-value",
|
|
12135
12412
|
title: "Use one multi-value literal",
|
|
12136
12413
|
outcome: "no-match",
|
|
12137
|
-
files: [
|
|
12138
|
-
|
|
12139
|
-
|
|
12140
|
-
|
|
12141
|
-
}
|
|
12142
|
-
],
|
|
12414
|
+
files: [{
|
|
12415
|
+
path: "src/schema.ts",
|
|
12416
|
+
source: "import { z } from 'zod'; export const Version = z.literal([1, 2, 3]);"
|
|
12417
|
+
}],
|
|
12143
12418
|
focusPath: "src/schema.ts",
|
|
12144
12419
|
expectedCount: 0,
|
|
12145
12420
|
public: true
|
|
@@ -12148,80 +12423,116 @@ var PREFER_MULTI_VALUE_ZOD_LITERAL_DOCUMENTATION = {
|
|
|
12148
12423
|
id: "literal-union",
|
|
12149
12424
|
title: "Avoid repeated literal wrappers",
|
|
12150
12425
|
outcome: "match",
|
|
12151
|
-
files: [
|
|
12152
|
-
|
|
12153
|
-
|
|
12154
|
-
|
|
12155
|
-
|
|
12156
|
-
|
|
12426
|
+
files: [{
|
|
12427
|
+
path: "src/schema.ts",
|
|
12428
|
+
source: "import { z } from 'zod'; export const Version = z.union([z.literal(1), z.literal(2), z.literal(3)]);"
|
|
12429
|
+
}],
|
|
12430
|
+
fixedFiles: [{
|
|
12431
|
+
path: "src/schema.ts",
|
|
12432
|
+
source: "import { z } from 'zod'; export const Version = z.literal([1, 2, 3]);"
|
|
12433
|
+
}],
|
|
12157
12434
|
focusPath: "src/schema.ts",
|
|
12158
12435
|
expectedCount: 1,
|
|
12159
12436
|
public: true
|
|
12160
12437
|
}
|
|
12161
12438
|
]
|
|
12162
12439
|
};
|
|
12163
|
-
function
|
|
12164
|
-
|
|
12440
|
+
function isStaticPrimitive(node, context) {
|
|
12441
|
+
if (node.type === AST_NODE_TYPES54.Literal) {
|
|
12442
|
+
return node.value === null || ["bigint", "boolean", "number", "string"].includes(typeof node.value);
|
|
12443
|
+
}
|
|
12444
|
+
if (node.type === AST_NODE_TYPES54.TemplateLiteral && node.expressions.length === 0)
|
|
12445
|
+
return true;
|
|
12446
|
+
if (node.type === AST_NODE_TYPES54.Identifier && node.name === "undefined") {
|
|
12447
|
+
const binding = ASTUtils16.findVariable(
|
|
12448
|
+
context.sourceCode.getScope(node),
|
|
12449
|
+
node.name
|
|
12450
|
+
);
|
|
12451
|
+
return binding === null || binding.defs.length === 0;
|
|
12452
|
+
}
|
|
12453
|
+
return node.type === AST_NODE_TYPES54.UnaryExpression && node.operator === "-" && node.argument.type === AST_NODE_TYPES54.Literal && ["bigint", "number"].includes(typeof node.argument.value);
|
|
12454
|
+
}
|
|
12455
|
+
function isStaticString(node) {
|
|
12456
|
+
return node.type === AST_NODE_TYPES54.Literal && typeof node.value === "string" || node.type === AST_NODE_TYPES54.TemplateLiteral && node.expressions.length === 0;
|
|
12165
12457
|
}
|
|
12166
12458
|
var prefer_multi_value_zod_literal_default = createRule({
|
|
12167
12459
|
name: "prefer-multi-value-zod-literal",
|
|
12168
12460
|
documentation: PREFER_MULTI_VALUE_ZOD_LITERAL_DOCUMENTATION,
|
|
12169
12461
|
meta: {
|
|
12170
12462
|
type: "suggestion",
|
|
12463
|
+
fixable: "code",
|
|
12171
12464
|
docs: {
|
|
12172
12465
|
description: "Use the Zod 4 multi-value literal API instead of a union of literal schemas."
|
|
12173
12466
|
},
|
|
12174
|
-
schema: [
|
|
12175
|
-
|
|
12176
|
-
|
|
12177
|
-
|
|
12178
|
-
|
|
12179
|
-
zodMajorVersion: { type: "integer", minimum: 4, maximum: 4 }
|
|
12180
|
-
}
|
|
12467
|
+
schema: [{
|
|
12468
|
+
type: "object",
|
|
12469
|
+
additionalProperties: false,
|
|
12470
|
+
properties: {
|
|
12471
|
+
zodMajorVersion: { type: "integer", minimum: 4, maximum: 4 }
|
|
12181
12472
|
}
|
|
12182
|
-
],
|
|
12473
|
+
}],
|
|
12183
12474
|
messages: {
|
|
12184
|
-
useMultiValueLiteral: "Replace this literal-schema union with
|
|
12475
|
+
useMultiValueLiteral: "Replace this literal-schema union with {{zod}}.literal([\u2026])."
|
|
12185
12476
|
}
|
|
12186
12477
|
},
|
|
12187
12478
|
defaultOptions: [{}],
|
|
12188
12479
|
create(context, [options]) {
|
|
12189
12480
|
if (isTestFile(context.filename) || isGeneratedFile(context.filename, context.sourceCode.text))
|
|
12190
12481
|
return {};
|
|
12191
|
-
const
|
|
12192
|
-
const
|
|
12482
|
+
const zodBindings = /* @__PURE__ */ new Set();
|
|
12483
|
+
const zod4Bindings = /* @__PURE__ */ new Set();
|
|
12484
|
+
function resolvedBinding(identifier) {
|
|
12485
|
+
return ASTUtils16.findVariable(
|
|
12486
|
+
context.sourceCode.getScope(identifier),
|
|
12487
|
+
identifier.name
|
|
12488
|
+
);
|
|
12489
|
+
}
|
|
12490
|
+
function directMemberCall(node, binding, method) {
|
|
12491
|
+
if (node.callee.type !== AST_NODE_TYPES54.MemberExpression || node.callee.computed || node.callee.object.type !== AST_NODE_TYPES54.Identifier || node.callee.property.type !== AST_NODE_TYPES54.Identifier || node.callee.property.name !== method)
|
|
12492
|
+
return false;
|
|
12493
|
+
return resolvedBinding(node.callee.object) === binding;
|
|
12494
|
+
}
|
|
12193
12495
|
return {
|
|
12194
12496
|
ImportDeclaration(node) {
|
|
12195
12497
|
if (!isZodModule(node.source.value)) return;
|
|
12498
|
+
const isExplicitV4 = /^zod\/v4(?:$|[-/])/.test(node.source.value);
|
|
12196
12499
|
for (const specifier of node.specifiers) {
|
|
12197
|
-
if (specifier.type === AST_NODE_TYPES54.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES54.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES54.ImportSpecifier && specifier.imported.type === AST_NODE_TYPES54.Identifier
|
|
12198
|
-
|
|
12199
|
-
if (
|
|
12200
|
-
|
|
12500
|
+
if (specifier.type === AST_NODE_TYPES54.ImportDefaultSpecifier || specifier.type === AST_NODE_TYPES54.ImportNamespaceSpecifier || specifier.type === AST_NODE_TYPES54.ImportSpecifier && (specifier.imported.type === AST_NODE_TYPES54.Identifier ? specifier.imported.name === "z" : specifier.imported.value === "z")) {
|
|
12501
|
+
const binding = resolvedBinding(specifier.local);
|
|
12502
|
+
if (binding === null) continue;
|
|
12503
|
+
zodBindings.add(binding);
|
|
12504
|
+
if (isExplicitV4) zod4Bindings.add(binding);
|
|
12201
12505
|
}
|
|
12202
12506
|
}
|
|
12203
12507
|
},
|
|
12204
12508
|
CallExpression(node) {
|
|
12205
|
-
|
|
12206
|
-
|
|
12207
|
-
);
|
|
12208
|
-
if (
|
|
12509
|
+
if (node.callee.type !== AST_NODE_TYPES54.MemberExpression || node.callee.object.type !== AST_NODE_TYPES54.Identifier)
|
|
12510
|
+
return;
|
|
12511
|
+
const binding = resolvedBinding(node.callee.object);
|
|
12512
|
+
if (binding === null || !zodBindings.has(binding) || !directMemberCall(node, binding, "union") || options?.zodMajorVersion !== 4 && !zod4Bindings.has(binding) || node.arguments.length !== 1)
|
|
12209
12513
|
return;
|
|
12210
12514
|
const [argument] = node.arguments;
|
|
12211
|
-
if (argument?.type !== AST_NODE_TYPES54.ArrayExpression || argument.elements.length <
|
|
12212
|
-
if (element === null || element.type !== AST_NODE_TYPES54.CallExpression || !memberCall(element, namespace, "literal") || element.arguments.length !== 1)
|
|
12213
|
-
return true;
|
|
12214
|
-
const [value] = element.arguments;
|
|
12215
|
-
return value === void 0 || value.type === AST_NODE_TYPES54.SpreadElement || ![
|
|
12216
|
-
AST_NODE_TYPES54.Literal,
|
|
12217
|
-
AST_NODE_TYPES54.TemplateLiteral
|
|
12218
|
-
].includes(value.type);
|
|
12219
|
-
}))
|
|
12515
|
+
if (argument?.type !== AST_NODE_TYPES54.ArrayExpression || argument.elements.length < 2)
|
|
12220
12516
|
return;
|
|
12517
|
+
const values = [];
|
|
12518
|
+
for (const element of argument.elements) {
|
|
12519
|
+
if (element === null || element.type !== AST_NODE_TYPES54.CallExpression || !directMemberCall(element, binding, "literal") || element.arguments.length !== 1)
|
|
12520
|
+
return;
|
|
12521
|
+
const [value] = element.arguments;
|
|
12522
|
+
if (value === void 0 || !isStaticPrimitive(value, context)) return;
|
|
12523
|
+
values.push(value);
|
|
12524
|
+
}
|
|
12525
|
+
if (values.every(isStaticString)) return;
|
|
12526
|
+
const namespace = node.callee.object.name;
|
|
12527
|
+
const hasComments = context.sourceCode.getCommentsInside(node).length > 0;
|
|
12221
12528
|
context.report({
|
|
12222
12529
|
node,
|
|
12223
12530
|
messageId: "useMultiValueLiteral",
|
|
12224
|
-
data: { zod: namespace }
|
|
12531
|
+
data: { zod: namespace },
|
|
12532
|
+
fix: hasComments ? null : (fixer) => fixer.replaceText(
|
|
12533
|
+
node,
|
|
12534
|
+
`${namespace}.literal([${values.map((value) => context.sourceCode.getText(value)).join(", ")}])`
|
|
12535
|
+
)
|
|
12225
12536
|
});
|
|
12226
12537
|
}
|
|
12227
12538
|
};
|
|
@@ -12338,7 +12649,7 @@ var prefer_named_complex_return_type_default = createRule({
|
|
|
12338
12649
|
});
|
|
12339
12650
|
|
|
12340
12651
|
// src/rules/prefer-native-random-uuid.ts
|
|
12341
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES57, ASTUtils as
|
|
12652
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES57, ASTUtils as ASTUtils17 } from "@typescript-eslint/utils";
|
|
12342
12653
|
var PREFER_NATIVE_RANDOM_UUID_DOCUMENTATION = {
|
|
12343
12654
|
summary: "Prefer `globalThis.crypto.randomUUID()` over resolved zero-argument UUID v4 bindings from the `uuid` package.",
|
|
12344
12655
|
rationale: "The platform implementation avoids an unnecessary dependency for standard random UUID generation.",
|
|
@@ -12374,7 +12685,7 @@ var prefer_native_random_uuid_default = createRule({
|
|
|
12374
12685
|
const directBindings = /* @__PURE__ */ new Set();
|
|
12375
12686
|
const namespaceBindings = /* @__PURE__ */ new Set();
|
|
12376
12687
|
function resolve(identifier) {
|
|
12377
|
-
return
|
|
12688
|
+
return ASTUtils17.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
12378
12689
|
}
|
|
12379
12690
|
function record(identifier, destination) {
|
|
12380
12691
|
const variable = resolve(identifier);
|
|
@@ -12437,7 +12748,7 @@ var prefer_native_random_uuid_default = createRule({
|
|
|
12437
12748
|
});
|
|
12438
12749
|
|
|
12439
12750
|
// src/rules/prefer-node-crypto-hash.ts
|
|
12440
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES58, ASTUtils as
|
|
12751
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES58, ASTUtils as ASTUtils18 } from "@typescript-eslint/utils";
|
|
12441
12752
|
var PREFER_NODE_CRYPTO_HASH_DOCUMENTATION = {
|
|
12442
12753
|
summary: "Prefer the modern one-shot node:crypto hash API when streaming state is unnecessary.",
|
|
12443
12754
|
rationale: "A createHash-update-digest chain allocates mutable streaming state for a single in-memory value; Node's built-in hash function expresses the one-shot operation directly and can use its optimized fast path.",
|
|
@@ -12493,7 +12804,7 @@ var prefer_node_crypto_hash_default = createRule({
|
|
|
12493
12804
|
const directBindings = /* @__PURE__ */ new Set();
|
|
12494
12805
|
const namespaceBindings = /* @__PURE__ */ new Set();
|
|
12495
12806
|
function resolve(identifier) {
|
|
12496
|
-
return
|
|
12807
|
+
return ASTUtils18.findVariable(
|
|
12497
12808
|
context.sourceCode.getScope(identifier),
|
|
12498
12809
|
identifier.name
|
|
12499
12810
|
);
|
|
@@ -12680,7 +12991,7 @@ var prefer_node_fs_promises_default = createRule({
|
|
|
12680
12991
|
});
|
|
12681
12992
|
|
|
12682
12993
|
// src/rules/prefer-non-nullable-collection.ts
|
|
12683
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES60, ASTUtils as
|
|
12994
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES60, ASTUtils as ASTUtils19 } from "@typescript-eslint/utils";
|
|
12684
12995
|
var PREFER_NON_NULLABLE_COLLECTION_DOCUMENTATION = {
|
|
12685
12996
|
summary: "Suggest non-null arrays only when local control flow proves the nullish state is equivalent to an empty collection.",
|
|
12686
12997
|
rationale: "A redundant nullish collection state spreads defaults and guards through consumers without carrying information.",
|
|
@@ -12810,14 +13121,14 @@ function directlyCoalesced(node) {
|
|
|
12810
13121
|
return parent?.type === AST_NODE_TYPES60.LogicalExpression && parent.left === node && (parent.operator === "??" || parent.operator === "||") && emptyArray(parent.right);
|
|
12811
13122
|
}
|
|
12812
13123
|
function identifierIsOnlyCoalesced(context, binding, fn) {
|
|
12813
|
-
const variable =
|
|
13124
|
+
const variable = ASTUtils19.findVariable(context.sourceCode.getScope(binding), binding.name);
|
|
12814
13125
|
if (variable === null || variable.references.length === 0) return false;
|
|
12815
13126
|
return variable.references.every(
|
|
12816
13127
|
(reference) => belongsToFunction(reference.identifier, fn) && directlyCoalesced(reference.identifier)
|
|
12817
13128
|
);
|
|
12818
13129
|
}
|
|
12819
13130
|
function memberIsOnlyCoalesced(context, object, property, fn) {
|
|
12820
|
-
const variable =
|
|
13131
|
+
const variable = ASTUtils19.findVariable(context.sourceCode.getScope(object), object.name);
|
|
12821
13132
|
if (variable === null) return false;
|
|
12822
13133
|
const accesses = variable.references.flatMap((reference) => {
|
|
12823
13134
|
if (!belongsToFunction(reference.identifier, fn)) return [null];
|
|
@@ -12927,7 +13238,7 @@ var prefer_non_nullable_collection_default = createRule({
|
|
|
12927
13238
|
// src/rules/prefer-nullish-filter-predicate.ts
|
|
12928
13239
|
import {
|
|
12929
13240
|
AST_NODE_TYPES as AST_NODE_TYPES61,
|
|
12930
|
-
ASTUtils as
|
|
13241
|
+
ASTUtils as ASTUtils20,
|
|
12931
13242
|
ESLintUtils as ESLintUtils5
|
|
12932
13243
|
} from "@typescript-eslint/utils";
|
|
12933
13244
|
import ts3 from "typescript";
|
|
@@ -12973,7 +13284,7 @@ var PREFER_NULLISH_FILTER_PREDICATE_DOCUMENTATION = {
|
|
|
12973
13284
|
]
|
|
12974
13285
|
};
|
|
12975
13286
|
function isUnshadowedBoolean(node, context) {
|
|
12976
|
-
const variable =
|
|
13287
|
+
const variable = ASTUtils20.findVariable(context.sourceCode.getScope(node), node.name);
|
|
12977
13288
|
return variable === null || variable.defs.length === 0;
|
|
12978
13289
|
}
|
|
12979
13290
|
function isBuiltinArrayFilter(node, services) {
|
|
@@ -13032,7 +13343,7 @@ function isProvablyTruthy(type, checker) {
|
|
|
13032
13343
|
}
|
|
13033
13344
|
function availableParameterName(node, context) {
|
|
13034
13345
|
for (const name of ["value", "item", "element", "candidate"]) {
|
|
13035
|
-
if (
|
|
13346
|
+
if (ASTUtils20.findVariable(context.sourceCode.getScope(node), name) === null) return name;
|
|
13036
13347
|
}
|
|
13037
13348
|
return null;
|
|
13038
13349
|
}
|
|
@@ -13086,7 +13397,7 @@ var prefer_nullish_filter_predicate_default = createRule({
|
|
|
13086
13397
|
|
|
13087
13398
|
// src/rules/prefer-await-in-async-return.ts
|
|
13088
13399
|
import {
|
|
13089
|
-
ASTUtils as
|
|
13400
|
+
ASTUtils as ASTUtils21,
|
|
13090
13401
|
ESLintUtils as ESLintUtils6,
|
|
13091
13402
|
AST_NODE_TYPES as AST_NODE_TYPES62
|
|
13092
13403
|
} from "@typescript-eslint/utils";
|
|
@@ -13200,13 +13511,13 @@ var prefer_await_in_async_return_default = createRule({
|
|
|
13200
13511
|
if (services === null) return {};
|
|
13201
13512
|
const frameworkLoaders = /* @__PURE__ */ new Set();
|
|
13202
13513
|
const rememberFrameworkLoader = (identifier) => {
|
|
13203
|
-
const variable =
|
|
13514
|
+
const variable = ASTUtils21.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
13204
13515
|
if (variable !== null) frameworkLoaders.add(variable);
|
|
13205
13516
|
};
|
|
13206
13517
|
const isFrameworkLoaderCallback = (owner) => {
|
|
13207
13518
|
const parent = owner.parent;
|
|
13208
13519
|
if (parent.type !== AST_NODE_TYPES62.CallExpression || parent.arguments[0] !== owner || parent.callee.type !== AST_NODE_TYPES62.Identifier) return false;
|
|
13209
|
-
const variable =
|
|
13520
|
+
const variable = ASTUtils21.findVariable(context.sourceCode.getScope(parent.callee), parent.callee.name);
|
|
13210
13521
|
return variable !== null && frameworkLoaders.has(variable);
|
|
13211
13522
|
};
|
|
13212
13523
|
return {
|
|
@@ -14786,7 +15097,7 @@ var prefer_whole_object_assertion_default = createRule({
|
|
|
14786
15097
|
});
|
|
14787
15098
|
|
|
14788
15099
|
// src/rules/repeated-static-call-cases.ts
|
|
14789
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES68, ASTUtils as
|
|
15100
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES68, ASTUtils as ASTUtils22 } from "@typescript-eslint/utils";
|
|
14790
15101
|
var REPEATED_STATIC_CALL_CASES_DOCUMENTATION = {
|
|
14791
15102
|
summary: "Report three or more consecutive literal call assertions that should be independently named test cases.",
|
|
14792
15103
|
rationale: "Copy-pasted cases obscure the input table and stop later cases from being reported after the first failure.",
|
|
@@ -14812,7 +15123,7 @@ function staticMemberName5(node) {
|
|
|
14812
15123
|
return null;
|
|
14813
15124
|
}
|
|
14814
15125
|
function importedName6(identifier, context, modules) {
|
|
14815
|
-
const variable =
|
|
15126
|
+
const variable = ASTUtils22.findVariable(context.sourceCode.getScope(identifier), identifier.name);
|
|
14816
15127
|
if (variable === null || variable.defs.length === 0) return identifier.name;
|
|
14817
15128
|
for (const definition of variable.defs) {
|
|
14818
15129
|
if (definition.node.type !== AST_NODE_TYPES68.ImportSpecifier) continue;
|
|
@@ -15813,7 +16124,7 @@ var require_assert_never_default = createRule({
|
|
|
15813
16124
|
});
|
|
15814
16125
|
|
|
15815
16126
|
// src/rules/require-fetch-timeout.ts
|
|
15816
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES71, ASTUtils as
|
|
16127
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES71, ASTUtils as ASTUtils23 } from "@typescript-eslint/utils";
|
|
15817
16128
|
var REQUIRE_FETCH_TIMEOUT_DOCUMENTATION = {
|
|
15818
16129
|
summary: "Require an abort `signal` (e.g. `AbortSignal.timeout(ms)`) on global `fetch()` calls so stalled upstreams cannot hang the caller forever.",
|
|
15819
16130
|
rationale: "An unbounded request can occupy work indefinitely when an upstream stalls.",
|
|
@@ -15894,7 +16205,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
15894
16205
|
}
|
|
15895
16206
|
function resolvesToGlobal(identifier) {
|
|
15896
16207
|
const scope = context.sourceCode.getScope(identifier);
|
|
15897
|
-
const variable =
|
|
16208
|
+
const variable = ASTUtils23.findVariable(scope, identifier.name);
|
|
15898
16209
|
return variable === null || variable.defs.length === 0;
|
|
15899
16210
|
}
|
|
15900
16211
|
function isGlobalFetchCall2(callee) {
|
|
@@ -15904,7 +16215,7 @@ var require_fetch_timeout_default = createRule({
|
|
|
15904
16215
|
return callee.type === AST_NODE_TYPES71.MemberExpression && !callee.computed && callee.property.type === AST_NODE_TYPES71.Identifier && callee.property.name === "fetch" && callee.object.type === AST_NODE_TYPES71.Identifier && GLOBAL_OBJECTS2.has(callee.object.name) && resolvesToGlobal(callee.object);
|
|
15905
16216
|
}
|
|
15906
16217
|
function localConstInitProvablyLacksSignal(identifier) {
|
|
15907
|
-
const variable =
|
|
16218
|
+
const variable = ASTUtils23.findVariable(
|
|
15908
16219
|
context.sourceCode.getScope(identifier),
|
|
15909
16220
|
identifier.name
|
|
15910
16221
|
);
|
|
@@ -16993,7 +17304,7 @@ var require_static_next_matcher_default = createRule({
|
|
|
16993
17304
|
});
|
|
16994
17305
|
|
|
16995
17306
|
// src/rules/require-use-form-default-values.ts
|
|
16996
|
-
import { ASTUtils as
|
|
17307
|
+
import { ASTUtils as ASTUtils24 } from "@typescript-eslint/utils";
|
|
16997
17308
|
var REQUIRE_USE_FORM_DEFAULT_VALUES_DOCUMENTATION = {
|
|
16998
17309
|
summary: "react-hook-form useForm call without defaultValues",
|
|
16999
17310
|
rationale: "Without an explicit initial value, fields can change from uncontrolled to controlled as data arrives, reset behavior becomes ambiguous, and the form's initial shape no longer documents the values users can edit.",
|
|
@@ -17047,13 +17358,13 @@ var require_use_form_default_values_default = createRule({
|
|
|
17047
17358
|
if (node.source.value !== "react-hook-form") return;
|
|
17048
17359
|
for (const specifier of node.specifiers) {
|
|
17049
17360
|
if (specifier.type !== "ImportSpecifier" || (specifier.imported.type === "Identifier" ? specifier.imported.name : specifier.imported.value) !== "useForm") continue;
|
|
17050
|
-
const variable =
|
|
17361
|
+
const variable = ASTUtils24.findVariable(context.sourceCode.getScope(specifier.local), specifier.local.name);
|
|
17051
17362
|
if (variable) importedHooks.add(variable);
|
|
17052
17363
|
}
|
|
17053
17364
|
},
|
|
17054
17365
|
CallExpression(node) {
|
|
17055
17366
|
if (node.callee.type !== "Identifier") return;
|
|
17056
|
-
const variable =
|
|
17367
|
+
const variable = ASTUtils24.findVariable(context.sourceCode.getScope(node.callee), node.callee.name);
|
|
17057
17368
|
const options = node.arguments[0];
|
|
17058
17369
|
if (!variable || !importedHooks.has(variable) || options !== void 0 && options.type !== "ObjectExpression" || hasDefaultValues(options)) return;
|
|
17059
17370
|
context.report({ node, messageId: "requireUseFormDefaultValues" });
|
|
@@ -17131,7 +17442,7 @@ var require_use_server_in_actions_file_default = createRule({
|
|
|
17131
17442
|
// src/rules/require-zod-form-validation.ts
|
|
17132
17443
|
import {
|
|
17133
17444
|
AST_NODE_TYPES as AST_NODE_TYPES76,
|
|
17134
|
-
ASTUtils as
|
|
17445
|
+
ASTUtils as ASTUtils25
|
|
17135
17446
|
} from "@typescript-eslint/utils";
|
|
17136
17447
|
var REQUIRE_ZOD_FORM_VALIDATION_DOCUMENTATION = {
|
|
17137
17448
|
summary: "Require Zod validation (`Schema.parse(...)` / `Schema.safeParse(...)`) when reading values out of a `FormData` object.",
|
|
@@ -17199,7 +17510,7 @@ var require_zod_form_validation_default = createRule({
|
|
|
17199
17510
|
return {};
|
|
17200
17511
|
}
|
|
17201
17512
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
17202
|
-
const resolvedBinding = (identifier) =>
|
|
17513
|
+
const resolvedBinding = (identifier) => ASTUtils25.findVariable(
|
|
17203
17514
|
context.sourceCode.getScope(identifier),
|
|
17204
17515
|
identifier.name
|
|
17205
17516
|
);
|
|
@@ -17496,7 +17807,7 @@ var store_insert_requires_on_conflict_default = createRule({
|
|
|
17496
17807
|
});
|
|
17497
17808
|
|
|
17498
17809
|
// src/rules/stepdown.ts
|
|
17499
|
-
import { AST_NODE_TYPES as AST_NODE_TYPES77, ASTUtils as
|
|
17810
|
+
import { AST_NODE_TYPES as AST_NODE_TYPES77, ASTUtils as ASTUtils26 } from "@typescript-eslint/utils";
|
|
17500
17811
|
var STEPDOWN_DOCUMENTATION = {
|
|
17501
17812
|
summary: "Place a private helper below its sole direct same-scope caller.",
|
|
17502
17813
|
rationale: "Caller-first ordering lets a reader follow the main flow before descending into implementation details.",
|
|
@@ -17701,7 +18012,7 @@ function methodName(node) {
|
|
|
17701
18012
|
return !node.computed && node.key.type === AST_NODE_TYPES77.Identifier ? node.key.name : null;
|
|
17702
18013
|
}
|
|
17703
18014
|
function referencedMethod(context, node, classVariables) {
|
|
17704
|
-
const objectVariable = node.object.type === AST_NODE_TYPES77.Identifier ?
|
|
18015
|
+
const objectVariable = node.object.type === AST_NODE_TYPES77.Identifier ? ASTUtils26.findVariable(context.sourceCode.getScope(node.object), node.object.name) : null;
|
|
17705
18016
|
const isClassReference = objectVariable !== null && classVariables.has(objectVariable);
|
|
17706
18017
|
if (node.object.type !== AST_NODE_TYPES77.ThisExpression && !isClassReference) return null;
|
|
17707
18018
|
if (node.property.type === AST_NODE_TYPES77.PrivateIdentifier) return `#${node.property.name}`;
|
|
@@ -17754,11 +18065,11 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
17754
18065
|
const pinned = /* @__PURE__ */ new Set();
|
|
17755
18066
|
const classVariables = /* @__PURE__ */ new Set();
|
|
17756
18067
|
if (node.id !== null) {
|
|
17757
|
-
const internal =
|
|
18068
|
+
const internal = ASTUtils26.findVariable(context.sourceCode.getScope(node), node.id.name);
|
|
17758
18069
|
if (internal !== null) classVariables.add(internal);
|
|
17759
18070
|
}
|
|
17760
18071
|
if (node.type === AST_NODE_TYPES77.ClassExpression && node.parent.type === AST_NODE_TYPES77.VariableDeclarator && node.parent.id.type === AST_NODE_TYPES77.Identifier) {
|
|
17761
|
-
const outer =
|
|
18072
|
+
const outer = ASTUtils26.findVariable(context.sourceCode.getScope(node.parent), node.parent.id.name);
|
|
17762
18073
|
if (outer !== null) classVariables.add(outer);
|
|
17763
18074
|
}
|
|
17764
18075
|
for (const method of methods) {
|
|
@@ -17794,7 +18105,7 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
17794
18105
|
return;
|
|
17795
18106
|
}
|
|
17796
18107
|
if (binding.type !== AST_NODE_TYPES77.Identifier) return;
|
|
17797
|
-
const variable =
|
|
18108
|
+
const variable = ASTUtils26.findVariable(context.sourceCode.getScope(binding), binding.name);
|
|
17798
18109
|
if (variable !== null) {
|
|
17799
18110
|
methodClassVariables.add(variable);
|
|
17800
18111
|
methodAliases.add(variable);
|
|
@@ -17824,7 +18135,7 @@ function classScope(context, node, computedReferenceNames) {
|
|
|
17824
18135
|
return;
|
|
17825
18136
|
}
|
|
17826
18137
|
if (!privateNames.has(target)) return;
|
|
17827
|
-
const objectVariable = current.object.type === AST_NODE_TYPES77.Identifier ?
|
|
18138
|
+
const objectVariable = current.object.type === AST_NODE_TYPES77.Identifier ? ASTUtils26.findVariable(context.sourceCode.getScope(current.object), current.object.name) : null;
|
|
17828
18139
|
if (objectVariable !== null && methodAliases.has(objectVariable)) {
|
|
17829
18140
|
pinned.add(target);
|
|
17830
18141
|
return;
|
|
@@ -18405,7 +18716,7 @@ var iac_source_coupled_test_default = createSourceCoupledRule(
|
|
|
18405
18716
|
// src/rules/require-pascal-case-zod-schema-name.ts
|
|
18406
18717
|
import {
|
|
18407
18718
|
AST_NODE_TYPES as AST_NODE_TYPES80,
|
|
18408
|
-
ASTUtils as
|
|
18719
|
+
ASTUtils as ASTUtils27
|
|
18409
18720
|
} from "@typescript-eslint/utils";
|
|
18410
18721
|
var REQUIRE_PASCAL_CASE_ZOD_SCHEMA_NAME_DOCUMENTATION = {
|
|
18411
18722
|
summary: "Require confirmed module-level Zod schema contracts to use PascalCase with a `Schema` suffix.",
|
|
@@ -18425,8 +18736,8 @@ var REQUIRE_PASCAL_CASE_ZOD_SCHEMA_NAME_DOCUMENTATION = {
|
|
|
18425
18736
|
]
|
|
18426
18737
|
};
|
|
18427
18738
|
var PASCAL_SCHEMA_NAME_RE = /^[A-Z][A-Za-z0-9]*Schema$/;
|
|
18428
|
-
var
|
|
18429
|
-
var
|
|
18739
|
+
var BENCHMARK_PATH_RE2 = /(^|[\\/])(?:benchmarks?|bench)[\\/]/;
|
|
18740
|
+
var NON_SCHEMA_TERMINALS2 = /* @__PURE__ */ new Set([
|
|
18430
18741
|
"parse",
|
|
18431
18742
|
"parseAsync",
|
|
18432
18743
|
"safeParse",
|
|
@@ -18539,7 +18850,7 @@ var SCHEMA_RETURNING_METHODS = /* @__PURE__ */ new Set([
|
|
|
18539
18850
|
"transform"
|
|
18540
18851
|
]);
|
|
18541
18852
|
var terminalMethodName = (callee) => !callee.computed && callee.property.type === AST_NODE_TYPES80.Identifier ? callee.property.name : null;
|
|
18542
|
-
var
|
|
18853
|
+
var calleeChainRoot2 = (node) => {
|
|
18543
18854
|
let current = node;
|
|
18544
18855
|
for (; ; ) {
|
|
18545
18856
|
if (current.type === AST_NODE_TYPES80.Identifier) {
|
|
@@ -18556,7 +18867,7 @@ var calleeChainRoot = (node) => {
|
|
|
18556
18867
|
return null;
|
|
18557
18868
|
}
|
|
18558
18869
|
};
|
|
18559
|
-
var
|
|
18870
|
+
var chainMemberNames2 = (node) => {
|
|
18560
18871
|
const names = [];
|
|
18561
18872
|
let current = node;
|
|
18562
18873
|
for (; ; ) {
|
|
@@ -18606,7 +18917,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
18606
18917
|
const zodBindings = /* @__PURE__ */ new Set();
|
|
18607
18918
|
const schemaBindings = /* @__PURE__ */ new Set();
|
|
18608
18919
|
function resolvedBinding(identifier) {
|
|
18609
|
-
return
|
|
18920
|
+
return ASTUtils27.findVariable(
|
|
18610
18921
|
context.sourceCode.getScope(identifier),
|
|
18611
18922
|
identifier.name
|
|
18612
18923
|
);
|
|
@@ -18616,7 +18927,7 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
18616
18927
|
if (binding !== null) zodBindings.add(binding);
|
|
18617
18928
|
}
|
|
18618
18929
|
function isZodChain(node) {
|
|
18619
|
-
const root =
|
|
18930
|
+
const root = calleeChainRoot2(node);
|
|
18620
18931
|
if (root === null) return false;
|
|
18621
18932
|
const binding = resolvedBinding(root);
|
|
18622
18933
|
return binding !== null && zodBindings.has(binding);
|
|
@@ -18632,16 +18943,16 @@ var require_pascal_case_zod_schema_name_default = createRule({
|
|
|
18632
18943
|
return false;
|
|
18633
18944
|
}
|
|
18634
18945
|
const terminal = terminalMethodName(init.callee);
|
|
18635
|
-
if (terminal === null ||
|
|
18636
|
-
const names =
|
|
18946
|
+
if (terminal === null || NON_SCHEMA_TERMINALS2.has(terminal)) return false;
|
|
18947
|
+
const names = chainMemberNames2(init.callee);
|
|
18637
18948
|
if (names.length === 0) return false;
|
|
18638
18949
|
if (isZodChain(init.callee)) {
|
|
18639
18950
|
return ZOD_SCHEMA_FACTORIES.has(names[0] ?? "") || ZOD_FACTORY_NAMESPACES.has(names[0] ?? "") && ZOD_SCHEMA_FACTORIES.has(names[1] ?? "");
|
|
18640
18951
|
}
|
|
18641
|
-
const root =
|
|
18952
|
+
const root = calleeChainRoot2(init.callee);
|
|
18642
18953
|
return root !== null && isSchemaBinding(root) && SCHEMA_RETURNING_METHODS.has(terminal);
|
|
18643
18954
|
}
|
|
18644
|
-
if (isTestFile(context.filename) ||
|
|
18955
|
+
if (isTestFile(context.filename) || BENCHMARK_PATH_RE2.test(context.filename.replaceAll("\\", "/")) || isGeneratedFile(context.filename, context.sourceCode.text)) {
|
|
18645
18956
|
return {};
|
|
18646
18957
|
}
|
|
18647
18958
|
return {
|
|
@@ -18844,14 +19155,14 @@ var RULES = {
|
|
|
18844
19155
|
"require-static-next-matcher": require_static_next_matcher_default,
|
|
18845
19156
|
"require-zod-form-validation": require_zod_form_validation_default,
|
|
18846
19157
|
"store-insert-requires-on-conflict": store_insert_requires_on_conflict_default,
|
|
18847
|
-
stepdown: stepdown_default,
|
|
19158
|
+
"stepdown": stepdown_default,
|
|
18848
19159
|
"source-coupled-test": source_coupled_test_default,
|
|
18849
19160
|
"sole-export-matches-filename": sole_export_matches_filename_default,
|
|
18850
19161
|
"require-pascal-case-zod-schema-name": require_pascal_case_zod_schema_name_default
|
|
18851
19162
|
};
|
|
18852
19163
|
var meta = {
|
|
18853
19164
|
name: "@sarj/eslint-plugin",
|
|
18854
|
-
version: "15.17.
|
|
19165
|
+
version: "15.17.2"
|
|
18855
19166
|
};
|
|
18856
19167
|
var APPLICATION_ONLY_RULES = [
|
|
18857
19168
|
"no-restricted-library-load",
|