oxlint-plugin-react-doctor 0.7.5-dev.70eff9a → 0.7.5-dev.8fc5848
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.js +16 -161
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9070,30 +9070,6 @@ const doMatchingNodesCoverEveryPathAfterUsage = (usageNode, matchingNodes, conte
|
|
|
9070
9070
|
}
|
|
9071
9071
|
return matchingBlocks.size > 0;
|
|
9072
9072
|
};
|
|
9073
|
-
const doMatchingNodesCoverEveryPathFromFunctionEntry = (owner, matchingNodes, context) => {
|
|
9074
|
-
const functionCfg = context.cfg.cfgFor(owner);
|
|
9075
|
-
if (!functionCfg) return false;
|
|
9076
|
-
const matchingBlocks = new Set(matchingNodes.flatMap((matchingNode) => {
|
|
9077
|
-
if (context.cfg.enclosingFunction(matchingNode) !== owner) return [];
|
|
9078
|
-
const matchingBlock = functionCfg.blockOf(matchingNode);
|
|
9079
|
-
return matchingBlock ? [matchingBlock] : [];
|
|
9080
|
-
}));
|
|
9081
|
-
if (matchingBlocks.size === 0) return false;
|
|
9082
|
-
const visitedBlocks = new Set([functionCfg.entry]);
|
|
9083
|
-
const pendingBlocks = [functionCfg.entry];
|
|
9084
|
-
while (pendingBlocks.length > 0) {
|
|
9085
|
-
const currentBlock = pendingBlocks.pop();
|
|
9086
|
-
if (!currentBlock) break;
|
|
9087
|
-
if (matchingBlocks.has(currentBlock)) continue;
|
|
9088
|
-
for (const edge of currentBlock.successors) {
|
|
9089
|
-
if (edge.to === functionCfg.exit) return false;
|
|
9090
|
-
if (visitedBlocks.has(edge.to)) continue;
|
|
9091
|
-
visitedBlocks.add(edge.to);
|
|
9092
|
-
pendingBlocks.push(edge.to);
|
|
9093
|
-
}
|
|
9094
|
-
}
|
|
9095
|
-
return true;
|
|
9096
|
-
};
|
|
9097
9073
|
const removeSynchronouslyReleasedUsages = (callback, usages, context) => {
|
|
9098
9074
|
if (!isNodeOfType(callback, "ArrowFunctionExpression") && !isNodeOfType(callback, "FunctionExpression")) return usages;
|
|
9099
9075
|
if (!isNodeOfType(callback.body, "BlockStatement")) return usages;
|
|
@@ -9294,83 +9270,6 @@ const doesCleanupFunctionReleaseUsage = (cleanupFunction, usage, context, visite
|
|
|
9294
9270
|
});
|
|
9295
9271
|
return didCleanupFunctionMatch;
|
|
9296
9272
|
};
|
|
9297
|
-
const doesBoundCleanupReleaseUsage = (expression, usage, context) => {
|
|
9298
|
-
const callExpression = stripParenExpression(expression);
|
|
9299
|
-
if (!isNodeOfType(callExpression, "CallExpression")) return false;
|
|
9300
|
-
const bindCallee = stripParenExpression(callExpression.callee);
|
|
9301
|
-
if (!isNodeOfType(bindCallee, "MemberExpression") || bindCallee.computed || !isNodeOfType(bindCallee.property, "Identifier") || bindCallee.property.name !== "bind") return false;
|
|
9302
|
-
const releaseMember = stripParenExpression(bindCallee.object);
|
|
9303
|
-
if (!isNodeOfType(releaseMember, "MemberExpression") || releaseMember.computed || !isNodeOfType(releaseMember.property, "Identifier")) return false;
|
|
9304
|
-
const releaseReceiverKey = resolveExpressionKey$1(releaseMember.object, context);
|
|
9305
|
-
if (releaseReceiverKey === null || releaseReceiverKey !== resolveExpressionKey$1(callExpression.arguments?.[0], context)) return false;
|
|
9306
|
-
const releaseVerbName = releaseMember.property.name;
|
|
9307
|
-
if (usage.kind === "socket") return usage.handleKey === releaseReceiverKey && (SOCKET_RELEASE_VERB_NAMES.has(releaseVerbName) || UNIVERSAL_RELEASE_VERB_NAMES.has(releaseVerbName));
|
|
9308
|
-
return usage.kind === "subscribe" && usage.handleKey === releaseReceiverKey && (releaseVerbName === "unsubscribe" || releaseVerbName === "unsub" || releaseVerbName === "close" || releaseVerbName === "unwatch" || releaseVerbName === "unlisten" || BOUND_RESOURCE_RELEASE_METHOD_NAMES.has(releaseVerbName));
|
|
9309
|
-
};
|
|
9310
|
-
const callbackReturnsCleanupForUsage = (callback, usage, context) => {
|
|
9311
|
-
if (!isNodeOfType(callback, "ArrowFunctionExpression") && !isNodeOfType(callback, "FunctionExpression")) return false;
|
|
9312
|
-
const doesReturnedValueReleaseUsage = (returnedValue) => {
|
|
9313
|
-
if (doesBoundCleanupReleaseUsage(returnedValue, usage, context)) return true;
|
|
9314
|
-
const cleanupFunction = resolveStableValue(returnedValue, context);
|
|
9315
|
-
if (cleanupFunction && doesBoundCleanupReleaseUsage(cleanupFunction, usage, context)) return true;
|
|
9316
|
-
return Boolean(cleanupFunction && isFunctionLike$1(cleanupFunction) && doesCleanupFunctionReleaseUsage(cleanupFunction, usage, context));
|
|
9317
|
-
};
|
|
9318
|
-
if (!isNodeOfType(callback.body, "BlockStatement")) return doesReturnedValueReleaseUsage(stripParenExpression(callback.body));
|
|
9319
|
-
const matchingCleanupReturns = [];
|
|
9320
|
-
walkInsideStatementBlocks(callback.body, (child) => {
|
|
9321
|
-
if (isNodeOfType(child, "ReturnStatement") && child.argument && doesReturnedValueReleaseUsage(stripParenExpression(child.argument))) matchingCleanupReturns.push(child);
|
|
9322
|
-
});
|
|
9323
|
-
return doMatchingNodesCoverEveryPathFromFunctionEntry(callback, matchingCleanupReturns, context);
|
|
9324
|
-
};
|
|
9325
|
-
const hasRerunReleaseBeforeUsage = (callback, usage, context) => {
|
|
9326
|
-
if (!isNodeOfType(callback, "ArrowFunctionExpression") && !isNodeOfType(callback, "FunctionExpression") || !isNodeOfType(callback.body, "BlockStatement")) return false;
|
|
9327
|
-
const functionCfg = context.cfg.cfgFor(callback);
|
|
9328
|
-
const usageBlock = functionCfg?.blockOf(usage.node);
|
|
9329
|
-
const usageStart = getRangeStart(usage.node);
|
|
9330
|
-
if (!functionCfg || !usageBlock || usageStart === null) return false;
|
|
9331
|
-
const findHandleGuard = (releaseCall) => {
|
|
9332
|
-
if (usage.handleKey === null) return null;
|
|
9333
|
-
let ancestor = releaseCall.parent;
|
|
9334
|
-
while (ancestor && ancestor !== callback.body) {
|
|
9335
|
-
if (isNodeOfType(ancestor, "IfStatement")) return ancestor.alternate === null && resolveExpressionKey$1(ancestor.test, context) === usage.handleKey && getRangeStart(ancestor) !== null && (getRangeStart(ancestor) ?? usageStart) < usageStart ? ancestor : null;
|
|
9336
|
-
ancestor = ancestor.parent;
|
|
9337
|
-
}
|
|
9338
|
-
return null;
|
|
9339
|
-
};
|
|
9340
|
-
const matchingReleaseAnchors = [];
|
|
9341
|
-
walkInsideStatementBlocks(callback.body, (child) => {
|
|
9342
|
-
if (!isNodeOfType(child, "CallExpression")) return;
|
|
9343
|
-
const releaseStart = getRangeStart(child);
|
|
9344
|
-
const handleGuard = findHandleGuard(child);
|
|
9345
|
-
if (releaseStart === null || releaseStart >= usageStart || functionCfg.blockOf(child) !== usageBlock && !handleGuard) return;
|
|
9346
|
-
if (doesReleaseCallMatchUsage(child, usage, context)) {
|
|
9347
|
-
matchingReleaseAnchors.push(handleGuard ?? child);
|
|
9348
|
-
return;
|
|
9349
|
-
}
|
|
9350
|
-
const helperFunction = resolveStableValue(child.callee, context);
|
|
9351
|
-
if (helperFunction && isFunctionLike$1(helperFunction) && doesCleanupFunctionReleaseUsage(helperFunction, usage, context)) matchingReleaseAnchors.push(handleGuard ?? child);
|
|
9352
|
-
});
|
|
9353
|
-
return doMatchingNodesCoverEveryPathFromFunctionEntry(callback, matchingReleaseAnchors, context);
|
|
9354
|
-
};
|
|
9355
|
-
const hasStableUnmountCleanupForUsage = (callback, usage, context) => {
|
|
9356
|
-
const componentFunction = findEnclosingFunction(callback);
|
|
9357
|
-
if (!componentFunction || !isNodeOfType(componentFunction, "ArrowFunctionExpression") && !isNodeOfType(componentFunction, "FunctionExpression") && !isNodeOfType(componentFunction, "FunctionDeclaration")) return false;
|
|
9358
|
-
let didFindUnmountCleanup = false;
|
|
9359
|
-
walkAst(componentFunction.body, (child) => {
|
|
9360
|
-
if (didFindUnmountCleanup) return false;
|
|
9361
|
-
if (!isNodeOfType(child, "CallExpression") || findEnclosingFunction(child) !== componentFunction) return;
|
|
9362
|
-
if (!isHookCall$2(child, CLEANUP_EFFECT_HOOK_NAMES)) return;
|
|
9363
|
-
const dependencyList = child.arguments?.[1];
|
|
9364
|
-
if (!isNodeOfType(dependencyList, "ArrayExpression") || dependencyList.elements.length > 0) return;
|
|
9365
|
-
const cleanupCallback = getEffectCallback(child);
|
|
9366
|
-
if (cleanupCallback && cleanupCallback !== callback && callbackReturnsCleanupForUsage(cleanupCallback, usage, context)) {
|
|
9367
|
-
didFindUnmountCleanup = true;
|
|
9368
|
-
return false;
|
|
9369
|
-
}
|
|
9370
|
-
});
|
|
9371
|
-
return didFindUnmountCleanup;
|
|
9372
|
-
};
|
|
9373
|
-
const hasSplitLifecycleCleanup = (callback, usage, context) => usage.handleKey !== null && hasRerunReleaseBeforeUsage(callback, usage, context) && hasStableUnmountCleanupForUsage(callback, usage, context);
|
|
9374
9273
|
const effectHasCleanupForUsage = (callback, usage, context) => {
|
|
9375
9274
|
if (!isNodeOfType(callback, "ArrowFunctionExpression") && !isNodeOfType(callback, "FunctionExpression")) return false;
|
|
9376
9275
|
if (usage.kind === "subscribe" && findEnclosingFunction(usage.node) === callback && doesResourceResultEscape(usage.node, true) && isCleanupReturningSubscribeLikeCallExpression(usage.node)) return true;
|
|
@@ -9383,10 +9282,6 @@ const effectHasCleanupForUsage = (callback, usage, context) => {
|
|
|
9383
9282
|
if (returnStart !== null && usageStart !== null && returnStart < usageStart) return;
|
|
9384
9283
|
const returnedValue = child.argument ? stripParenExpression(child.argument) : null;
|
|
9385
9284
|
if (!returnedValue) return;
|
|
9386
|
-
if (doesBoundCleanupReleaseUsage(returnedValue, usage, context)) {
|
|
9387
|
-
matchingCleanupReturns.push(child);
|
|
9388
|
-
return;
|
|
9389
|
-
}
|
|
9390
9285
|
if (usage.kind === "subscribe" && (returnedValue === usage.node || getRangeStart(returnedValue) !== null && getRangeStart(returnedValue) === getRangeStart(usage.node)) && isCleanupReturningSubscribeLikeCallExpression(returnedValue)) {
|
|
9391
9286
|
matchingCleanupReturns.push(child);
|
|
9392
9287
|
return;
|
|
@@ -9402,17 +9297,13 @@ const effectHasCleanupForUsage = (callback, usage, context) => {
|
|
|
9402
9297
|
if (!context.scopes.symbolFor(returnedValue)?.initializer) return;
|
|
9403
9298
|
}
|
|
9404
9299
|
const cleanupFunction = resolveStableValue(returnedValue, context);
|
|
9405
|
-
if (cleanupFunction && doesBoundCleanupReleaseUsage(cleanupFunction, usage, context)) {
|
|
9406
|
-
matchingCleanupReturns.push(child);
|
|
9407
|
-
return;
|
|
9408
|
-
}
|
|
9409
9300
|
if (!cleanupFunction || !isFunctionLike$1(cleanupFunction)) return;
|
|
9410
9301
|
if (doesCleanupFunctionReleaseUsage(cleanupFunction, usage, context)) matchingCleanupReturns.push(child);
|
|
9411
9302
|
});
|
|
9412
9303
|
return doMatchingNodesCoverEveryPathAfterUsage(resolveCleanupPathAnchor(usage.node, callback, context), matchingCleanupReturns, context);
|
|
9413
9304
|
};
|
|
9414
9305
|
const findFirstUsageWithoutCleanup = (callback, usages, context) => {
|
|
9415
|
-
for (const usage of usages) if (!effectHasCleanupForUsage(callback, usage, context)
|
|
9306
|
+
for (const usage of usages) if (!effectHasCleanupForUsage(callback, usage, context)) return usage;
|
|
9416
9307
|
return null;
|
|
9417
9308
|
};
|
|
9418
9309
|
const isLocalAbortControllerExpression = (expression, context, visitedSymbolIds = /* @__PURE__ */ new Set()) => {
|
|
@@ -28483,31 +28374,20 @@ const noDocumentStartViewTransition = defineRule({
|
|
|
28483
28374
|
} })
|
|
28484
28375
|
});
|
|
28485
28376
|
//#endregion
|
|
28486
|
-
//#region src/plugin/utils/get-static-property-name.ts
|
|
28487
|
-
const getStaticPropertyName = (memberExpression) => {
|
|
28488
|
-
const property = memberExpression.property;
|
|
28489
|
-
if (!memberExpression.computed && isNodeOfType(property, "Identifier")) return property.name;
|
|
28490
|
-
if (memberExpression.computed && isNodeOfType(property, "Literal")) return typeof property.value === "string" ? property.value : null;
|
|
28491
|
-
if (memberExpression.computed && isNodeOfType(property, "TemplateLiteral") && property.expressions.length === 0) return property.quasis[0]?.value.cooked ?? property.quasis[0]?.value.raw ?? null;
|
|
28492
|
-
return null;
|
|
28493
|
-
};
|
|
28494
|
-
//#endregion
|
|
28495
28377
|
//#region src/plugin/rules/js-performance/no-document-write.ts
|
|
28496
28378
|
const MESSAGE$24 = "`document.write()` blocks parsing, is ignored (or wipes the page) after load, and is flagged by browsers as a performance anti-pattern. Build DOM nodes or set `innerHTML`/`textContent` on a target element instead.";
|
|
28497
28379
|
const WRITE_METHODS = new Set(["write", "writeln"]);
|
|
28498
|
-
const isGlobalDocumentReference = (node, context) => node.name === "document" && context.scopes.isGlobalReference(node);
|
|
28499
28380
|
const noDocumentWrite = defineRule({
|
|
28500
28381
|
id: "no-document-write",
|
|
28501
28382
|
title: "document.write/writeln",
|
|
28502
28383
|
severity: "warn",
|
|
28503
28384
|
recommendation: "Don't use `document.write()`/`document.writeln()`. Append DOM nodes or set `innerHTML`/`textContent` on a specific element instead.",
|
|
28504
28385
|
create: (context) => ({ CallExpression(node) {
|
|
28505
|
-
const callee =
|
|
28506
|
-
if (!isNodeOfType(callee, "MemberExpression")) return;
|
|
28386
|
+
const callee = node.callee;
|
|
28387
|
+
if (!isNodeOfType(callee, "MemberExpression") || callee.computed) return;
|
|
28507
28388
|
const receiver = stripParenExpression(callee.object);
|
|
28508
|
-
if (!isNodeOfType(receiver, "Identifier") ||
|
|
28509
|
-
|
|
28510
|
-
if (methodName === null || !WRITE_METHODS.has(methodName)) return;
|
|
28389
|
+
if (!isNodeOfType(receiver, "Identifier") || receiver.name !== "document") return;
|
|
28390
|
+
if (!isNodeOfType(callee.property, "Identifier") || !WRITE_METHODS.has(callee.property.name)) return;
|
|
28511
28391
|
context.report({
|
|
28512
28392
|
node,
|
|
28513
28393
|
message: MESSAGE$24
|
|
@@ -29314,14 +29194,6 @@ const noEffectWithFreshDeps = defineRule({
|
|
|
29314
29194
|
//#endregion
|
|
29315
29195
|
//#region src/plugin/rules/security/no-eval.ts
|
|
29316
29196
|
const SANDBOX_SURFACE_PATH_PATTERN = /(?:^|[/-])sandbox(?:$|[/-])|(?:^|\/)[\w.]+-sandbox(?:\/|\.[cm]?[jt]sx?$)/i;
|
|
29317
|
-
const getExecutableGlobalName = (node, context) => {
|
|
29318
|
-
const expression = stripParenExpression(node);
|
|
29319
|
-
if (isNodeOfType(expression, "Identifier")) return context.scopes.isGlobalReference(expression) ? expression.name : null;
|
|
29320
|
-
if (!isNodeOfType(expression, "MemberExpression")) return null;
|
|
29321
|
-
const receiver = stripParenExpression(expression.object);
|
|
29322
|
-
if (!isNodeOfType(receiver, "Identifier") || receiver.name !== "globalThis" || !context.scopes.isGlobalReference(receiver)) return null;
|
|
29323
|
-
return getStaticPropertyName(expression);
|
|
29324
|
-
};
|
|
29325
29197
|
const noEval = defineRule({
|
|
29326
29198
|
id: "no-eval",
|
|
29327
29199
|
title: "eval() runs untrusted code strings",
|
|
@@ -29331,21 +29203,20 @@ const noEval = defineRule({
|
|
|
29331
29203
|
if (SANDBOX_SURFACE_PATH_PATTERN.test(normalizeFilename(context.filename ?? ""))) return {};
|
|
29332
29204
|
return {
|
|
29333
29205
|
CallExpression(node) {
|
|
29334
|
-
|
|
29335
|
-
if (executableGlobalName === "eval") {
|
|
29206
|
+
if (isNodeOfType(node.callee, "Identifier") && node.callee.name === "eval") {
|
|
29336
29207
|
context.report({
|
|
29337
29208
|
node,
|
|
29338
29209
|
message: "eval() is a code-injection vulnerability: it runs any string as code."
|
|
29339
29210
|
});
|
|
29340
29211
|
return;
|
|
29341
29212
|
}
|
|
29342
|
-
if ((
|
|
29213
|
+
if (isNodeOfType(node.callee, "Identifier") && (node.callee.name === "setTimeout" || node.callee.name === "setInterval") && isNodeOfType(node.arguments?.[0], "Literal") && typeof node.arguments[0].value === "string") context.report({
|
|
29343
29214
|
node,
|
|
29344
|
-
message: `Passing a string to ${
|
|
29215
|
+
message: `Passing a string to ${node.callee.name}() is a code-injection vulnerability, since it runs that string as code.`
|
|
29345
29216
|
});
|
|
29346
29217
|
},
|
|
29347
29218
|
NewExpression(node) {
|
|
29348
|
-
if (
|
|
29219
|
+
if (isNodeOfType(node.callee, "Identifier") && node.callee.name === "Function") {
|
|
29349
29220
|
const onlyArgument = node.arguments.length === 1 ? node.arguments[0] : void 0;
|
|
29350
29221
|
if (isNodeOfType(onlyArgument, "Literal") && typeof onlyArgument.value === "string" && onlyArgument.value.trim() === "return this") return;
|
|
29351
29222
|
context.report({
|
|
@@ -35062,14 +34933,6 @@ const isHandlerBagArgument = (analysis, argument) => {
|
|
|
35062
34933
|
};
|
|
35063
34934
|
const getFunctionalUpdaterDataRefs = (analysis, updater) => getDownstreamRefs(analysis, updater).filter((updaterRef) => !updaterRef.resolved?.defs.some((def) => def.type === "Parameter" && def.node === updater));
|
|
35064
34935
|
const HOOK_NAME_PATTERN$1 = /^use[A-Z0-9]/;
|
|
35065
|
-
const EXTERNAL_SUBSCRIPTION_HOOK_NAMES = new Set([
|
|
35066
|
-
"useIntersectionObserver",
|
|
35067
|
-
"useMatchMedia",
|
|
35068
|
-
"useMediaQuery",
|
|
35069
|
-
"useResizeObserver",
|
|
35070
|
-
"useVisibility",
|
|
35071
|
-
"useWindowSize"
|
|
35072
|
-
]);
|
|
35073
34936
|
const isParentWiredHookResultRef = (analysis, ref) => Boolean(ref.resolved?.defs.some((def) => {
|
|
35074
34937
|
const node = def.node;
|
|
35075
34938
|
if (!isNodeOfType(node, "VariableDeclarator") || !node.init) return false;
|
|
@@ -35092,19 +34955,6 @@ const isParentWiredHookCalleeRef = (analysis, ref) => {
|
|
|
35092
34955
|
if (!parent || !isNodeOfType(parent, "CallExpression") || parent.callee !== identifier) return false;
|
|
35093
34956
|
return (parent.arguments ?? []).some((hookArgument) => getDownstreamRefs(analysis, hookArgument).some((downstreamRef) => isProp(analysis, downstreamRef)));
|
|
35094
34957
|
};
|
|
35095
|
-
const isExternalSubscriptionHookRef = (ref) => {
|
|
35096
|
-
const identifier = ref.identifier;
|
|
35097
|
-
if (!isNodeOfType(identifier, "Identifier")) return false;
|
|
35098
|
-
if (EXTERNAL_SUBSCRIPTION_HOOK_NAMES.has(identifier.name) && isCalleePosition(identifier)) return true;
|
|
35099
|
-
return Boolean(ref.resolved?.defs.some((def) => {
|
|
35100
|
-
const node = def.node;
|
|
35101
|
-
if (!isNodeOfType(node, "VariableDeclarator") || !node.init) return false;
|
|
35102
|
-
const initializer = stripParenExpression(node.init);
|
|
35103
|
-
if (!isNodeOfType(initializer, "CallExpression")) return false;
|
|
35104
|
-
const callee = stripParenExpression(initializer.callee);
|
|
35105
|
-
return isNodeOfType(callee, "Identifier") && EXTERNAL_SUBSCRIPTION_HOOK_NAMES.has(callee.name);
|
|
35106
|
-
}));
|
|
35107
|
-
};
|
|
35108
34958
|
const isImportBindingRef = (ref) => Boolean(ref.resolved?.defs.some((def) => def.type === "ImportBinding"));
|
|
35109
34959
|
const isCalleePosition = (identifier) => {
|
|
35110
34960
|
const parent = identifier.parent;
|
|
@@ -35166,11 +35016,10 @@ const noPassDataToParent = defineRule({
|
|
|
35166
35016
|
if (argumentRef && resolveToFunction(argumentRef)) return [];
|
|
35167
35017
|
}
|
|
35168
35018
|
return getDownstreamRefs(analysis, argument);
|
|
35169
|
-
}).flatMap((argumentRef) =>
|
|
35019
|
+
}).flatMap((argumentRef) => getUpstreamRefs(analysis, argumentRef)).filter(isLeafRef);
|
|
35170
35020
|
if (calleeNode === identifier && isWrapperHookCallbackRef(analysis, ref)) argsUpstreamRefs.push(...getArgsUpstreamRefs(analysis, ref).filter(isLeafRef));
|
|
35171
35021
|
if (!argsUpstreamRefs.some((argRef) => {
|
|
35172
35022
|
if (isUseStateIdentifier(argRef.identifier)) return false;
|
|
35173
|
-
if (isExternalSubscriptionHookRef(argRef)) return false;
|
|
35174
35023
|
if (isProp(analysis, argRef)) return false;
|
|
35175
35024
|
if (isUseRefIdentifier(argRef.identifier)) return false;
|
|
35176
35025
|
if (isRefCurrent(argRef)) return false;
|
|
@@ -54928,6 +54777,12 @@ const webhookSignatureRisk = defineRule({
|
|
|
54928
54777
|
//#region src/plugin/rules/zod/utils/zod-ast.ts
|
|
54929
54778
|
const ZOD_MODULE = "zod";
|
|
54930
54779
|
const ZOD_MODULE_SOURCES = [ZOD_MODULE];
|
|
54780
|
+
const getStaticPropertyName = (member) => {
|
|
54781
|
+
const property = member.property;
|
|
54782
|
+
if (!member.computed && isNodeOfType(property, "Identifier")) return property.name;
|
|
54783
|
+
if (member.computed && isNodeOfType(property, "Literal") && typeof property.value === "string") return property.value;
|
|
54784
|
+
return null;
|
|
54785
|
+
};
|
|
54931
54786
|
const importInfoCache = /* @__PURE__ */ new WeakMap();
|
|
54932
54787
|
const getImportInfoForIdentifier = (identifier) => {
|
|
54933
54788
|
if (importInfoCache.has(identifier)) return importInfoCache.get(identifier) ?? null;
|