react-doctor 0.7.7-dev.ec144d9 → 0.7.7-dev.ed241c3
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/cli.js +427 -69
- package/dist/index.js +424 -66
- package/dist/lsp.js +424 -66
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="4096a0e2-9712-5e2f-b602-5ff55d3994a3")}catch(e){}}();
|
|
3
3
|
import { r as __toESM$1, t as __commonJSMin$1 } from "./chunk-N93fKeF6.js";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import reactDoctorPlugin, { ALL_REACT_DOCTOR_RULE_KEYS, CROSS_FILE_DEPENDENCY_COLLECTORS, CROSS_FILE_RULE_IDS, FRAMEWORK_SPECIFIC_RULE_KEYS, FRAMEWORK_TOKENS, MOTION_LIBRARY_PACKAGES, REACT_COMPILER_RULES, REACT_DOCTOR_RULES, classifySecurityScanFile, collectCrossFileDependencyProbes, resetManifestCaches, shouldReadSecurityScanContent } from "oxlint-plugin-react-doctor";
|
|
@@ -37182,18 +37182,45 @@ const checkReactServerComponentsAdvisory = (scanDirectory, project) => {
|
|
|
37182
37182
|
}
|
|
37183
37183
|
return diagnostics;
|
|
37184
37184
|
};
|
|
37185
|
-
const
|
|
37186
|
-
|
|
37187
|
-
|
|
37185
|
+
const getTypescriptScriptKind = (fileName) => {
|
|
37186
|
+
if (fileName.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
37187
|
+
if (fileName.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
37188
|
+
if (fileName.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
37189
|
+
return ts.ScriptKind.JS;
|
|
37190
|
+
};
|
|
37191
|
+
const unwrapTypescriptExpression = (expression) => {
|
|
37192
|
+
let currentExpression = expression;
|
|
37193
|
+
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
37194
|
+
return currentExpression;
|
|
37195
|
+
};
|
|
37196
|
+
const EMPTY_MOTION_EXPRESSION_EVIDENCE = {
|
|
37197
|
+
isAnimationFunction: false,
|
|
37198
|
+
isMotionComponent: false,
|
|
37199
|
+
isMotionComponentFactory: false,
|
|
37200
|
+
isMotionComponentNamespace: false,
|
|
37201
|
+
isMotionConfig: false,
|
|
37202
|
+
isMotionNamespace: false,
|
|
37203
|
+
isReducedMotionHook: false
|
|
37204
|
+
};
|
|
37205
|
+
const MOTION_COMPONENT_FACTORY_EXPORT_NAMES = new Set(["m", "motion"]);
|
|
37206
|
+
const MOTION_COMPONENT_NAMESPACE_EXPORT_NAMES = new Set(["Reorder"]);
|
|
37207
|
+
const MOTION_COMPONENT_NAMESPACE_MEMBER_NAMES = new Set(["Item"]);
|
|
37208
|
+
const MOTION_ANIMATION_FUNCTION_EXPORT_NAMES = new Set(["animate"]);
|
|
37209
|
+
const REDUCED_MOTION_HOOK_EXPORT_NAME = "useReducedMotion";
|
|
37210
|
+
const MOTION_CONFIG_EXPORT_NAME = "MotionConfig";
|
|
37211
|
+
const REDUCED_MOTION_PROP_NAME = "reducedMotion";
|
|
37212
|
+
const REDUCED_MOTION_CONFIG_VALUES = new Set(["always", "user"]);
|
|
37213
|
+
const SCRIPT_MODULE_EXTENSIONS = [
|
|
37188
37214
|
".ts",
|
|
37189
37215
|
".tsx",
|
|
37190
37216
|
".js",
|
|
37191
|
-
".jsx"
|
|
37192
|
-
|
|
37193
|
-
|
|
37194
|
-
]);
|
|
37195
|
-
const
|
|
37196
|
-
const
|
|
37217
|
+
".jsx"
|
|
37218
|
+
];
|
|
37219
|
+
const SCRIPT_FILE_EXTENSIONS = new Set(SCRIPT_MODULE_EXTENSIONS);
|
|
37220
|
+
const STYLE_FILE_EXTENSIONS = new Set([".css", ".scss"]);
|
|
37221
|
+
const MOTION_SOURCE_PREFILTER = /framer-motion|["']motion(?:\/[A-Za-z0-9_./-]+)?["']|MotionConfig|useReducedMotion/;
|
|
37222
|
+
const REDUCED_MOTION_MEDIA_QUERY_PATTERN = /@media\s+([^{}]*\(\s*prefers-reduced-motion\s*:\s*reduce\s*\)[^{}]*)\{/gi;
|
|
37223
|
+
const CSS_DECLARATION_PATTERN = /(?:^|[;{])\s*[-_A-Za-z][-_A-Za-z0-9]*\s*:/;
|
|
37197
37224
|
const MISSING_REDUCED_MOTION_DIAGNOSTIC = {
|
|
37198
37225
|
filePath: "package.json",
|
|
37199
37226
|
plugin: "react-doctor",
|
|
@@ -37205,52 +37232,406 @@ const MISSING_REDUCED_MOTION_DIAGNOSTIC = {
|
|
|
37205
37232
|
column: 0,
|
|
37206
37233
|
category: "Accessibility"
|
|
37207
37234
|
};
|
|
37208
|
-
const
|
|
37235
|
+
const isMotionModuleSource = (moduleSource) => {
|
|
37236
|
+
for (const packageName of MOTION_LIBRARY_PACKAGES) if (moduleSource === packageName || moduleSource.startsWith(`${packageName}/`)) return true;
|
|
37237
|
+
return false;
|
|
37238
|
+
};
|
|
37239
|
+
const classifyMotionExport = (exportName) => ({
|
|
37240
|
+
isAnimationFunction: MOTION_ANIMATION_FUNCTION_EXPORT_NAMES.has(exportName),
|
|
37241
|
+
isMotionComponent: false,
|
|
37242
|
+
isMotionComponentFactory: MOTION_COMPONENT_FACTORY_EXPORT_NAMES.has(exportName),
|
|
37243
|
+
isMotionComponentNamespace: MOTION_COMPONENT_NAMESPACE_EXPORT_NAMES.has(exportName),
|
|
37244
|
+
isMotionConfig: exportName === MOTION_CONFIG_EXPORT_NAME,
|
|
37245
|
+
isMotionNamespace: false,
|
|
37246
|
+
isReducedMotionHook: exportName === REDUCED_MOTION_HOOK_EXPORT_NAME
|
|
37247
|
+
});
|
|
37248
|
+
const getImportModuleSource = (node) => {
|
|
37249
|
+
let currentNode = node;
|
|
37250
|
+
while (currentNode) {
|
|
37251
|
+
if (ts.isImportDeclaration(currentNode) && ts.isStringLiteral(currentNode.moduleSpecifier)) return currentNode.moduleSpecifier.text;
|
|
37252
|
+
currentNode = currentNode.parent;
|
|
37253
|
+
}
|
|
37254
|
+
return null;
|
|
37255
|
+
};
|
|
37256
|
+
const getImportedBindingEvidence = (declaration, typeChecker, program, visitedSymbols) => {
|
|
37257
|
+
const moduleSource = getImportModuleSource(declaration);
|
|
37258
|
+
if (!moduleSource) return null;
|
|
37259
|
+
if (isMotionModuleSource(moduleSource) && ts.isNamespaceImport(declaration)) return {
|
|
37260
|
+
...EMPTY_MOTION_EXPRESSION_EVIDENCE,
|
|
37261
|
+
isMotionNamespace: true
|
|
37262
|
+
};
|
|
37263
|
+
if (isMotionModuleSource(moduleSource) && ts.isImportSpecifier(declaration)) {
|
|
37264
|
+
if (declaration.isTypeOnly) return null;
|
|
37265
|
+
return classifyMotionExport(declaration.propertyName?.text ?? declaration.name.text);
|
|
37266
|
+
}
|
|
37267
|
+
if (isMotionModuleSource(moduleSource) && ts.isImportClause(declaration)) {
|
|
37268
|
+
if (declaration.isTypeOnly) return null;
|
|
37269
|
+
return EMPTY_MOTION_EXPRESSION_EVIDENCE;
|
|
37270
|
+
}
|
|
37271
|
+
if (ts.isImportSpecifier(declaration) && !declaration.isTypeOnly || ts.isImportClause(declaration) && !declaration.isTypeOnly && declaration.name) {
|
|
37272
|
+
const importedName = ts.isImportSpecifier(declaration) ? declaration.propertyName?.text ?? declaration.name.text : "default";
|
|
37273
|
+
const moduleSourceFile = getLocalModuleSourceFile(moduleSource, declaration.getSourceFile().fileName, program);
|
|
37274
|
+
if (!moduleSourceFile) return null;
|
|
37275
|
+
return resolveModuleExportEvidence(moduleSourceFile, importedName, typeChecker, program, visitedSymbols);
|
|
37276
|
+
}
|
|
37277
|
+
return null;
|
|
37278
|
+
};
|
|
37279
|
+
const getLocalModuleSourceFile = (moduleSource, importingFileName, program) => {
|
|
37280
|
+
if (!moduleSource.startsWith(".")) return null;
|
|
37281
|
+
const moduleBasePath = Path.resolve(Path.dirname(importingFileName), moduleSource);
|
|
37282
|
+
const moduleBaseExtension = Path.extname(moduleBasePath);
|
|
37283
|
+
const typescriptModuleBasePath = moduleBaseExtension === ".js" || moduleBaseExtension === ".jsx" ? moduleBasePath.slice(0, -moduleBaseExtension.length) : null;
|
|
37284
|
+
const candidates = [
|
|
37285
|
+
moduleBasePath,
|
|
37286
|
+
...typescriptModuleBasePath ? [
|
|
37287
|
+
`${typescriptModuleBasePath}.ts`,
|
|
37288
|
+
`${typescriptModuleBasePath}.tsx`,
|
|
37289
|
+
Path.join(typescriptModuleBasePath, "index.ts"),
|
|
37290
|
+
Path.join(typescriptModuleBasePath, "index.tsx")
|
|
37291
|
+
] : [],
|
|
37292
|
+
...SCRIPT_MODULE_EXTENSIONS.map((extension) => `${moduleBasePath}${extension}`),
|
|
37293
|
+
...SCRIPT_MODULE_EXTENSIONS.map((extension) => Path.join(moduleBasePath, `index${extension}`))
|
|
37294
|
+
];
|
|
37295
|
+
for (const candidate of candidates) {
|
|
37296
|
+
const sourceFile = program.getSourceFile(candidate);
|
|
37297
|
+
if (sourceFile) return sourceFile;
|
|
37298
|
+
}
|
|
37299
|
+
return null;
|
|
37300
|
+
};
|
|
37301
|
+
const resolveModuleExportEvidence = (sourceFile, exportName, typeChecker, program, visitedSymbols) => {
|
|
37302
|
+
const moduleSymbol = typeChecker.getSymbolAtLocation(sourceFile);
|
|
37303
|
+
if (moduleSymbol && visitedSymbols.has(moduleSymbol)) return EMPTY_MOTION_EXPRESSION_EVIDENCE;
|
|
37304
|
+
const nextVisitedSymbols = new Set(visitedSymbols);
|
|
37305
|
+
if (moduleSymbol) nextVisitedSymbols.add(moduleSymbol);
|
|
37306
|
+
for (const statement of sourceFile.statements) {
|
|
37307
|
+
if (exportName === "default" && ts.isExportAssignment(statement) && !statement.isExportEquals) {
|
|
37308
|
+
const evidence = resolveMotionExpressionEvidence(statement.expression, typeChecker, program, nextVisitedSymbols);
|
|
37309
|
+
if (hasMotionExpressionEvidence(evidence)) return evidence;
|
|
37310
|
+
continue;
|
|
37311
|
+
}
|
|
37312
|
+
if (!ts.isExportDeclaration(statement) || !statement.moduleSpecifier) continue;
|
|
37313
|
+
if (statement.isTypeOnly) continue;
|
|
37314
|
+
if (!ts.isStringLiteral(statement.moduleSpecifier)) continue;
|
|
37315
|
+
const moduleSource = statement.moduleSpecifier.text;
|
|
37316
|
+
if (!statement.exportClause) {
|
|
37317
|
+
if (isMotionModuleSource(moduleSource)) {
|
|
37318
|
+
const evidence = classifyMotionExport(exportName);
|
|
37319
|
+
if (hasMotionExpressionEvidence(evidence)) return evidence;
|
|
37320
|
+
continue;
|
|
37321
|
+
}
|
|
37322
|
+
const moduleSourceFile = getLocalModuleSourceFile(moduleSource, sourceFile.fileName, program);
|
|
37323
|
+
if (moduleSourceFile) {
|
|
37324
|
+
const evidence = resolveModuleExportEvidence(moduleSourceFile, exportName, typeChecker, program, nextVisitedSymbols);
|
|
37325
|
+
if (hasMotionExpressionEvidence(evidence)) return evidence;
|
|
37326
|
+
}
|
|
37327
|
+
continue;
|
|
37328
|
+
}
|
|
37329
|
+
if (!ts.isNamedExports(statement.exportClause)) continue;
|
|
37330
|
+
for (const exportSpecifier of statement.exportClause.elements) {
|
|
37331
|
+
if (exportSpecifier.name.text !== exportName || exportSpecifier.isTypeOnly) continue;
|
|
37332
|
+
const sourceExportName = exportSpecifier.propertyName?.text ?? exportSpecifier.name.text;
|
|
37333
|
+
if (isMotionModuleSource(moduleSource)) return classifyMotionExport(sourceExportName);
|
|
37334
|
+
const moduleSourceFile = getLocalModuleSourceFile(moduleSource, sourceFile.fileName, program);
|
|
37335
|
+
if (!moduleSourceFile) continue;
|
|
37336
|
+
return resolveModuleExportEvidence(moduleSourceFile, sourceExportName, typeChecker, program, nextVisitedSymbols);
|
|
37337
|
+
}
|
|
37338
|
+
}
|
|
37339
|
+
if (!moduleSymbol) return EMPTY_MOTION_EXPRESSION_EVIDENCE;
|
|
37340
|
+
const exportedSymbol = typeChecker.getExportsOfModule(moduleSymbol).find((candidateSymbol) => candidateSymbol.name === exportName);
|
|
37341
|
+
if (!exportedSymbol || nextVisitedSymbols.has(exportedSymbol)) return EMPTY_MOTION_EXPRESSION_EVIDENCE;
|
|
37342
|
+
nextVisitedSymbols.add(exportedSymbol);
|
|
37343
|
+
let resolvedEvidence = EMPTY_MOTION_EXPRESSION_EVIDENCE;
|
|
37344
|
+
for (const declaration of exportedSymbol.declarations ?? []) {
|
|
37345
|
+
if (ts.isExportSpecifier(declaration)) {
|
|
37346
|
+
const targetSymbol = typeChecker.getExportSpecifierLocalTargetSymbol(declaration);
|
|
37347
|
+
for (const targetDeclaration of targetSymbol?.declarations ?? []) {
|
|
37348
|
+
const importedEvidence = getImportedBindingEvidence(targetDeclaration, typeChecker, program, nextVisitedSymbols);
|
|
37349
|
+
if (importedEvidence) resolvedEvidence = mergeMotionExpressionEvidence(resolvedEvidence, importedEvidence);
|
|
37350
|
+
if (ts.isVariableDeclaration(targetDeclaration) && targetDeclaration.initializer) resolvedEvidence = mergeMotionExpressionEvidence(resolvedEvidence, resolveMotionExpressionEvidence(targetDeclaration.initializer, typeChecker, program, nextVisitedSymbols));
|
|
37351
|
+
}
|
|
37352
|
+
}
|
|
37353
|
+
if (ts.isVariableDeclaration(declaration) && declaration.initializer) resolvedEvidence = mergeMotionExpressionEvidence(resolvedEvidence, resolveMotionExpressionEvidence(declaration.initializer, typeChecker, program, nextVisitedSymbols));
|
|
37354
|
+
}
|
|
37355
|
+
return resolvedEvidence;
|
|
37356
|
+
};
|
|
37357
|
+
const mergeMotionExpressionEvidence = (leftEvidence, rightEvidence) => ({
|
|
37358
|
+
isAnimationFunction: leftEvidence.isAnimationFunction || rightEvidence.isAnimationFunction,
|
|
37359
|
+
isMotionComponent: leftEvidence.isMotionComponent || rightEvidence.isMotionComponent,
|
|
37360
|
+
isMotionComponentFactory: leftEvidence.isMotionComponentFactory || rightEvidence.isMotionComponentFactory,
|
|
37361
|
+
isMotionComponentNamespace: leftEvidence.isMotionComponentNamespace || rightEvidence.isMotionComponentNamespace,
|
|
37362
|
+
isMotionConfig: leftEvidence.isMotionConfig || rightEvidence.isMotionConfig,
|
|
37363
|
+
isMotionNamespace: leftEvidence.isMotionNamespace || rightEvidence.isMotionNamespace,
|
|
37364
|
+
isReducedMotionHook: leftEvidence.isReducedMotionHook || rightEvidence.isReducedMotionHook
|
|
37365
|
+
});
|
|
37366
|
+
const hasMotionExpressionEvidence = (evidence) => evidence.isAnimationFunction || evidence.isMotionComponent || evidence.isMotionComponentFactory || evidence.isMotionComponentNamespace || evidence.isMotionConfig || evidence.isMotionNamespace || evidence.isReducedMotionHook;
|
|
37367
|
+
const classifyMotionMember = (receiverEvidence, memberName) => {
|
|
37368
|
+
if (receiverEvidence.isMotionNamespace) return classifyMotionExport(memberName);
|
|
37369
|
+
if (receiverEvidence.isMotionComponentFactory) return {
|
|
37370
|
+
...EMPTY_MOTION_EXPRESSION_EVIDENCE,
|
|
37371
|
+
isMotionComponent: true
|
|
37372
|
+
};
|
|
37373
|
+
if (receiverEvidence.isMotionComponentNamespace && MOTION_COMPONENT_NAMESPACE_MEMBER_NAMES.has(memberName)) return {
|
|
37374
|
+
...EMPTY_MOTION_EXPRESSION_EVIDENCE,
|
|
37375
|
+
isMotionComponent: true
|
|
37376
|
+
};
|
|
37377
|
+
return EMPTY_MOTION_EXPRESSION_EVIDENCE;
|
|
37378
|
+
};
|
|
37379
|
+
const resolveMotionExpressionEvidence = (expression, typeChecker, program, visitedSymbols = /* @__PURE__ */ new Set()) => {
|
|
37380
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
37381
|
+
if (ts.isIdentifier(unwrappedExpression)) {
|
|
37382
|
+
const symbol = typeChecker.getSymbolAtLocation(unwrappedExpression);
|
|
37383
|
+
if (!symbol || visitedSymbols.has(symbol)) return EMPTY_MOTION_EXPRESSION_EVIDENCE;
|
|
37384
|
+
const nextVisitedSymbols = new Set(visitedSymbols);
|
|
37385
|
+
nextVisitedSymbols.add(symbol);
|
|
37386
|
+
let resolvedEvidence = EMPTY_MOTION_EXPRESSION_EVIDENCE;
|
|
37387
|
+
for (const declaration of symbol.declarations ?? []) {
|
|
37388
|
+
const importedEvidence = getImportedBindingEvidence(declaration, typeChecker, program, nextVisitedSymbols);
|
|
37389
|
+
if (importedEvidence) {
|
|
37390
|
+
resolvedEvidence = mergeMotionExpressionEvidence(resolvedEvidence, importedEvidence);
|
|
37391
|
+
continue;
|
|
37392
|
+
}
|
|
37393
|
+
if (ts.isVariableDeclaration(declaration) && declaration.initializer) resolvedEvidence = mergeMotionExpressionEvidence(resolvedEvidence, resolveMotionExpressionEvidence(declaration.initializer, typeChecker, program, nextVisitedSymbols));
|
|
37394
|
+
if (ts.isBindingElement(declaration) && ts.isObjectBindingPattern(declaration.parent) && ts.isVariableDeclaration(declaration.parent.parent) && declaration.parent.parent.initializer) {
|
|
37395
|
+
const propertyName = declaration.propertyName ?? declaration.name;
|
|
37396
|
+
if (ts.isIdentifier(propertyName) || ts.isStringLiteral(propertyName)) {
|
|
37397
|
+
const receiverEvidence = resolveMotionExpressionEvidence(declaration.parent.parent.initializer, typeChecker, program, nextVisitedSymbols);
|
|
37398
|
+
resolvedEvidence = mergeMotionExpressionEvidence(resolvedEvidence, classifyMotionMember(receiverEvidence, propertyName.text));
|
|
37399
|
+
}
|
|
37400
|
+
}
|
|
37401
|
+
}
|
|
37402
|
+
return resolvedEvidence;
|
|
37403
|
+
}
|
|
37404
|
+
if (ts.isPropertyAccessExpression(unwrappedExpression)) return classifyMotionMember(resolveMotionExpressionEvidence(unwrappedExpression.expression, typeChecker, program, visitedSymbols), unwrappedExpression.name.text);
|
|
37405
|
+
if (ts.isElementAccessExpression(unwrappedExpression) && unwrappedExpression.argumentExpression && (ts.isStringLiteral(unwrappedExpression.argumentExpression) || ts.isNoSubstitutionTemplateLiteral(unwrappedExpression.argumentExpression))) return classifyMotionMember(resolveMotionExpressionEvidence(unwrappedExpression.expression, typeChecker, program, visitedSymbols), unwrappedExpression.argumentExpression.text);
|
|
37406
|
+
if (ts.isCallExpression(unwrappedExpression)) {
|
|
37407
|
+
if (ts.isIdentifier(unwrappedExpression.expression) && unwrappedExpression.expression.text === "require" && !typeChecker.getSymbolAtLocation(unwrappedExpression.expression) && unwrappedExpression.arguments.length === 1 && ts.isStringLiteral(unwrappedExpression.arguments[0]) && isMotionModuleSource(unwrappedExpression.arguments[0].text)) return {
|
|
37408
|
+
...EMPTY_MOTION_EXPRESSION_EVIDENCE,
|
|
37409
|
+
isMotionNamespace: true
|
|
37410
|
+
};
|
|
37411
|
+
if (ts.isPropertyAccessExpression(unwrappedExpression.expression) && unwrappedExpression.expression.name.text === "bind") {
|
|
37412
|
+
const boundReceiverEvidence = resolveMotionExpressionEvidence(unwrappedExpression.expression.expression, typeChecker, program, visitedSymbols);
|
|
37413
|
+
if (boundReceiverEvidence.isAnimationFunction) return boundReceiverEvidence;
|
|
37414
|
+
}
|
|
37415
|
+
const calleeEvidence = resolveMotionExpressionEvidence(unwrappedExpression.expression, typeChecker, program, visitedSymbols);
|
|
37416
|
+
if (calleeEvidence.isMotionComponentFactory) return {
|
|
37417
|
+
...EMPTY_MOTION_EXPRESSION_EVIDENCE,
|
|
37418
|
+
isMotionComponent: true
|
|
37419
|
+
};
|
|
37420
|
+
return calleeEvidence;
|
|
37421
|
+
}
|
|
37422
|
+
return EMPTY_MOTION_EXPRESSION_EVIDENCE;
|
|
37423
|
+
};
|
|
37424
|
+
const getStaticStringExpressionValue = (expression, typeChecker, visitedSymbols = /* @__PURE__ */ new Set()) => {
|
|
37425
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
37426
|
+
if (ts.isStringLiteral(unwrappedExpression) || ts.isNoSubstitutionTemplateLiteral(unwrappedExpression)) return unwrappedExpression.text;
|
|
37427
|
+
if (!ts.isIdentifier(unwrappedExpression)) return null;
|
|
37428
|
+
const symbol = typeChecker.getSymbolAtLocation(unwrappedExpression);
|
|
37429
|
+
if (!symbol || visitedSymbols.has(symbol)) return null;
|
|
37430
|
+
const nextVisitedSymbols = new Set(visitedSymbols);
|
|
37431
|
+
nextVisitedSymbols.add(symbol);
|
|
37432
|
+
for (const declaration of symbol.declarations ?? []) {
|
|
37433
|
+
if (!ts.isVariableDeclaration(declaration) || !declaration.initializer) continue;
|
|
37434
|
+
if (!ts.isVariableDeclarationList(declaration.parent)) continue;
|
|
37435
|
+
if (!(declaration.parent.flags & ts.NodeFlags.Const)) continue;
|
|
37436
|
+
const value = getStaticStringExpressionValue(declaration.initializer, typeChecker, nextVisitedSymbols);
|
|
37437
|
+
if (value !== null) return value;
|
|
37438
|
+
}
|
|
37439
|
+
return null;
|
|
37440
|
+
};
|
|
37441
|
+
const getStaticJsxAttributeValue = (attribute, typeChecker) => {
|
|
37442
|
+
if (!attribute.initializer) return null;
|
|
37443
|
+
if (ts.isStringLiteral(attribute.initializer)) return attribute.initializer.text;
|
|
37444
|
+
if (!ts.isJsxExpression(attribute.initializer) || !attribute.initializer.expression) return null;
|
|
37445
|
+
return getStaticStringExpressionValue(attribute.initializer.expression, typeChecker);
|
|
37446
|
+
};
|
|
37447
|
+
const isExpressionValueConsumed = (expression) => {
|
|
37448
|
+
let currentExpression = expression;
|
|
37449
|
+
while (ts.isParenthesizedExpression(currentExpression.parent) || ts.isAsExpression(currentExpression.parent) || ts.isSatisfiesExpression(currentExpression.parent) || ts.isNonNullExpression(currentExpression.parent) || ts.isTypeAssertionExpression(currentExpression.parent)) currentExpression = currentExpression.parent;
|
|
37450
|
+
return !ts.isExpressionStatement(currentExpression.parent) && !ts.isVoidExpression(currentExpression.parent);
|
|
37451
|
+
};
|
|
37452
|
+
const jsxElementHasReducedMotionConfiguration = (attributes, typeChecker) => attributes.properties.some((attribute) => ts.isJsxAttribute(attribute) && ts.isIdentifier(attribute.name) && attribute.name.text === REDUCED_MOTION_PROP_NAME && REDUCED_MOTION_CONFIG_VALUES.has(getStaticJsxAttributeValue(attribute, typeChecker) ?? ""));
|
|
37453
|
+
const collectScriptMotionEvidence = (sourceFile, typeChecker, program) => {
|
|
37454
|
+
const evidence = {
|
|
37455
|
+
hasMotionUse: false,
|
|
37456
|
+
hasReducedMotionHandling: false
|
|
37457
|
+
};
|
|
37458
|
+
const visitNode = (node) => {
|
|
37459
|
+
if (ts.isCallExpression(node)) {
|
|
37460
|
+
const calleeEvidence = resolveMotionExpressionEvidence(node.expression, typeChecker, program);
|
|
37461
|
+
const isAnimationFunctionCallViaCallOrApply = (ts.isPropertyAccessExpression(node.expression) && (node.expression.name.text === "call" || node.expression.name.text === "apply") || ts.isElementAccessExpression(node.expression) && node.expression.argumentExpression && (ts.isStringLiteral(node.expression.argumentExpression) || ts.isNoSubstitutionTemplateLiteral(node.expression.argumentExpression)) && (node.expression.argumentExpression.text === "call" || node.expression.argumentExpression.text === "apply")) && resolveMotionExpressionEvidence(node.expression.expression, typeChecker, program).isAnimationFunction;
|
|
37462
|
+
if (calleeEvidence.isAnimationFunction || isAnimationFunctionCallViaCallOrApply) evidence.hasMotionUse = true;
|
|
37463
|
+
if (calleeEvidence.isReducedMotionHook && isExpressionValueConsumed(node)) evidence.hasReducedMotionHandling = true;
|
|
37464
|
+
}
|
|
37465
|
+
if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
|
|
37466
|
+
const tagEvidence = ts.isJsxNamespacedName(node.tagName) ? EMPTY_MOTION_EXPRESSION_EVIDENCE : resolveMotionExpressionEvidence(node.tagName, typeChecker, program);
|
|
37467
|
+
if (tagEvidence.isMotionComponent || tagEvidence.isMotionComponentFactory) evidence.hasMotionUse = true;
|
|
37468
|
+
if (tagEvidence.isMotionConfig && jsxElementHasReducedMotionConfiguration(node.attributes, typeChecker)) evidence.hasReducedMotionHandling = true;
|
|
37469
|
+
}
|
|
37470
|
+
ts.forEachChild(node, visitNode);
|
|
37471
|
+
};
|
|
37472
|
+
visitNode(sourceFile);
|
|
37473
|
+
return evidence;
|
|
37474
|
+
};
|
|
37475
|
+
const analyzeReducedMotionSources = (sources) => {
|
|
37476
|
+
if (!sources.some(({ sourceText }) => MOTION_SOURCE_PREFILTER.test(sourceText))) return {
|
|
37477
|
+
hasMotionUse: false,
|
|
37478
|
+
hasReducedMotionHandling: false
|
|
37479
|
+
};
|
|
37480
|
+
const compilerOptions = {
|
|
37481
|
+
allowJs: true,
|
|
37482
|
+
checkJs: false,
|
|
37483
|
+
jsx: ts.JsxEmit.Preserve,
|
|
37484
|
+
module: ts.ModuleKind.ESNext,
|
|
37485
|
+
moduleResolution: ts.ModuleResolutionKind.Bundler,
|
|
37486
|
+
noEmit: true,
|
|
37487
|
+
noLib: true,
|
|
37488
|
+
noResolve: true,
|
|
37489
|
+
skipLibCheck: true,
|
|
37490
|
+
target: ts.ScriptTarget.Latest
|
|
37491
|
+
};
|
|
37492
|
+
const sourceTextByFileName = new Map(sources.map(({ fileName: sourceFileName, sourceText: content }) => [Path.resolve(sourceFileName), content]));
|
|
37493
|
+
const compilerHost = ts.createCompilerHost(compilerOptions);
|
|
37494
|
+
const getDefaultSourceFile = compilerHost.getSourceFile.bind(compilerHost);
|
|
37495
|
+
compilerHost.getSourceFile = (requestedFileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile) => sourceTextByFileName.has(Path.resolve(requestedFileName)) ? ts.createSourceFile(Path.resolve(requestedFileName), sourceTextByFileName.get(Path.resolve(requestedFileName)) ?? "", languageVersionOrOptions, true, getTypescriptScriptKind(requestedFileName)) : getDefaultSourceFile(requestedFileName, languageVersionOrOptions, onError, shouldCreateNewSourceFile);
|
|
37496
|
+
const program = ts.createProgram([...sourceTextByFileName.keys()], compilerOptions, compilerHost);
|
|
37497
|
+
const typeChecker = program.getTypeChecker();
|
|
37498
|
+
const evidence = {
|
|
37499
|
+
hasMotionUse: false,
|
|
37500
|
+
hasReducedMotionHandling: false
|
|
37501
|
+
};
|
|
37502
|
+
for (const sourceFileName of sourceTextByFileName.keys()) {
|
|
37503
|
+
const sourceFile = program.getSourceFile(sourceFileName);
|
|
37504
|
+
if (!sourceFile) continue;
|
|
37505
|
+
const fileEvidence = collectScriptMotionEvidence(sourceFile, typeChecker, program);
|
|
37506
|
+
evidence.hasMotionUse ||= fileEvidence.hasMotionUse;
|
|
37507
|
+
evidence.hasReducedMotionHandling ||= fileEvidence.hasReducedMotionHandling;
|
|
37508
|
+
}
|
|
37509
|
+
return evidence;
|
|
37510
|
+
};
|
|
37511
|
+
const removeCssCommentsAndStrings = (content) => {
|
|
37512
|
+
let sanitizedContent = "";
|
|
37513
|
+
let quote = null;
|
|
37514
|
+
let isInsideComment = false;
|
|
37515
|
+
let isInsideLineComment = false;
|
|
37516
|
+
for (let characterIndex = 0; characterIndex < content.length; characterIndex += 1) {
|
|
37517
|
+
const character = content[characterIndex];
|
|
37518
|
+
const nextCharacter = content[characterIndex + 1];
|
|
37519
|
+
if (isInsideLineComment) {
|
|
37520
|
+
sanitizedContent += character === "\n" ? "\n" : " ";
|
|
37521
|
+
if (character === "\n") isInsideLineComment = false;
|
|
37522
|
+
continue;
|
|
37523
|
+
}
|
|
37524
|
+
if (isInsideComment) {
|
|
37525
|
+
if (character === "*" && nextCharacter === "/") {
|
|
37526
|
+
sanitizedContent += " ";
|
|
37527
|
+
characterIndex += 1;
|
|
37528
|
+
isInsideComment = false;
|
|
37529
|
+
} else sanitizedContent += character === "\n" ? "\n" : " ";
|
|
37530
|
+
continue;
|
|
37531
|
+
}
|
|
37532
|
+
if (quote) {
|
|
37533
|
+
if (character === "\\") {
|
|
37534
|
+
sanitizedContent += " ";
|
|
37535
|
+
characterIndex += 1;
|
|
37536
|
+
continue;
|
|
37537
|
+
}
|
|
37538
|
+
if (character === quote) quote = null;
|
|
37539
|
+
sanitizedContent += character === "\n" ? "\n" : " ";
|
|
37540
|
+
continue;
|
|
37541
|
+
}
|
|
37542
|
+
if (character === "/" && nextCharacter === "*") {
|
|
37543
|
+
sanitizedContent += " ";
|
|
37544
|
+
characterIndex += 1;
|
|
37545
|
+
isInsideComment = true;
|
|
37546
|
+
continue;
|
|
37547
|
+
}
|
|
37548
|
+
if (character === "/" && nextCharacter === "/") {
|
|
37549
|
+
sanitizedContent += " ";
|
|
37550
|
+
characterIndex += 1;
|
|
37551
|
+
isInsideLineComment = true;
|
|
37552
|
+
continue;
|
|
37553
|
+
}
|
|
37554
|
+
if (character === "\"" || character === "'") {
|
|
37555
|
+
sanitizedContent += " ";
|
|
37556
|
+
quote = character;
|
|
37557
|
+
continue;
|
|
37558
|
+
}
|
|
37559
|
+
sanitizedContent += character;
|
|
37560
|
+
}
|
|
37561
|
+
return sanitizedContent;
|
|
37562
|
+
};
|
|
37563
|
+
const findMatchingClosingBrace = (content, openingBraceIndex) => {
|
|
37564
|
+
let depth = 0;
|
|
37565
|
+
for (let characterIndex = openingBraceIndex; characterIndex < content.length; characterIndex += 1) {
|
|
37566
|
+
if (content[characterIndex] === "{") depth += 1;
|
|
37567
|
+
if (content[characterIndex] !== "}") continue;
|
|
37568
|
+
depth -= 1;
|
|
37569
|
+
if (depth === 0) return characterIndex;
|
|
37570
|
+
}
|
|
37571
|
+
return -1;
|
|
37572
|
+
};
|
|
37573
|
+
const hasReducedMotionMediaQuery = (content) => {
|
|
37574
|
+
const sanitizedContent = removeCssCommentsAndStrings(content);
|
|
37575
|
+
REDUCED_MOTION_MEDIA_QUERY_PATTERN.lastIndex = 0;
|
|
37576
|
+
for (const match of sanitizedContent.matchAll(REDUCED_MOTION_MEDIA_QUERY_PATTERN)) {
|
|
37577
|
+
const mediaPrelude = match[1];
|
|
37578
|
+
if (/\bnot\b/i.test(mediaPrelude)) continue;
|
|
37579
|
+
const openingBraceIndex = (match.index ?? 0) + match[0].lastIndexOf("{");
|
|
37580
|
+
const closingBraceIndex = findMatchingClosingBrace(sanitizedContent, openingBraceIndex);
|
|
37581
|
+
if (closingBraceIndex === -1) continue;
|
|
37582
|
+
const body = sanitizedContent.slice(openingBraceIndex + 1, closingBraceIndex);
|
|
37583
|
+
if (CSS_DECLARATION_PATTERN.test(body)) return true;
|
|
37584
|
+
}
|
|
37585
|
+
return false;
|
|
37586
|
+
};
|
|
37587
|
+
const collectProjectMotionEvidence = (rootDirectory) => {
|
|
37588
|
+
const scriptSources = [];
|
|
37589
|
+
let hasReducedMotionHandling = false;
|
|
37209
37590
|
for (const { absolutePath, name } of walkSourceTreeFiles(rootDirectory)) {
|
|
37210
|
-
|
|
37591
|
+
const extension = Path.extname(name);
|
|
37592
|
+
if (!SCRIPT_FILE_EXTENSIONS.has(extension) && !STYLE_FILE_EXTENSIONS.has(extension)) continue;
|
|
37211
37593
|
let content;
|
|
37212
37594
|
try {
|
|
37213
37595
|
content = NFS.readFileSync(absolutePath, "utf-8");
|
|
37214
37596
|
} catch {
|
|
37215
37597
|
continue;
|
|
37216
37598
|
}
|
|
37217
|
-
if (
|
|
37599
|
+
if (STYLE_FILE_EXTENSIONS.has(extension)) {
|
|
37600
|
+
if (hasReducedMotionMediaQuery(content)) hasReducedMotionHandling = true;
|
|
37601
|
+
continue;
|
|
37602
|
+
}
|
|
37603
|
+
scriptSources.push({
|
|
37604
|
+
fileName: absolutePath,
|
|
37605
|
+
sourceText: content
|
|
37606
|
+
});
|
|
37218
37607
|
}
|
|
37219
|
-
return
|
|
37608
|
+
if (scriptSources.length === 0) return {
|
|
37609
|
+
hasMotionUse: false,
|
|
37610
|
+
hasReducedMotionHandling
|
|
37611
|
+
};
|
|
37612
|
+
const scriptEvidence = analyzeReducedMotionSources(scriptSources);
|
|
37613
|
+
const hasMotionUse = scriptEvidence.hasMotionUse;
|
|
37614
|
+
hasReducedMotionHandling ||= scriptEvidence.hasReducedMotionHandling;
|
|
37615
|
+
return {
|
|
37616
|
+
hasMotionUse,
|
|
37617
|
+
hasReducedMotionHandling
|
|
37618
|
+
};
|
|
37220
37619
|
};
|
|
37221
37620
|
const checkReducedMotion = (rootDirectory) => {
|
|
37222
37621
|
const packageJsonPath = Path.join(rootDirectory, "package.json");
|
|
37223
37622
|
if (!isFile(packageJsonPath)) return [];
|
|
37224
|
-
let hasMotionLibrary = false;
|
|
37225
37623
|
try {
|
|
37226
37624
|
const packageJson = readPackageJson(packageJsonPath);
|
|
37227
37625
|
const allDependencies = {
|
|
37228
37626
|
...packageJson.dependencies,
|
|
37229
37627
|
...packageJson.devDependencies
|
|
37230
37628
|
};
|
|
37231
|
-
|
|
37629
|
+
if (!Object.keys(allDependencies).some((packageName) => MOTION_LIBRARY_PACKAGES.has(packageName))) return [];
|
|
37232
37630
|
} catch {
|
|
37233
37631
|
return [];
|
|
37234
37632
|
}
|
|
37235
|
-
|
|
37236
|
-
|
|
37237
|
-
"grep",
|
|
37238
|
-
"--untracked",
|
|
37239
|
-
"-lE",
|
|
37240
|
-
REDUCED_MOTION_GREP_PATTERN,
|
|
37241
|
-
"--",
|
|
37242
|
-
...REDUCED_MOTION_FILE_GLOBS
|
|
37243
|
-
], {
|
|
37244
|
-
cwd: rootDirectory,
|
|
37245
|
-
encoding: "utf-8",
|
|
37246
|
-
stdio: [
|
|
37247
|
-
"ignore",
|
|
37248
|
-
"pipe",
|
|
37249
|
-
"pipe"
|
|
37250
|
-
]
|
|
37251
|
-
});
|
|
37252
|
-
if (!(!result.error && (result.status === 0 || result.status === GIT_GREP_NO_MATCH_STATUS))) return hasReducedMotionHandlingViaFilesystem(rootDirectory) ? [] : [MISSING_REDUCED_MOTION_DIAGNOSTIC];
|
|
37253
|
-
return result.status === 0 && result.stdout.split("\n").some((filePath) => filePath.length > 0 && !hasIgnoredPathSegment(filePath)) ? [] : [MISSING_REDUCED_MOTION_DIAGNOSTIC];
|
|
37633
|
+
const evidence = collectProjectMotionEvidence(rootDirectory);
|
|
37634
|
+
return evidence.hasMotionUse && !evidence.hasReducedMotionHandling ? [MISSING_REDUCED_MOTION_DIAGNOSTIC] : [];
|
|
37254
37635
|
};
|
|
37255
37636
|
const buildSecurityScanDiagnostic = (finding, entry, relativePath) => ({
|
|
37256
37637
|
filePath: relativePath,
|
|
@@ -39853,23 +40234,12 @@ const REACT_USE_BINDING_RESOLUTION = {
|
|
|
39853
40234
|
isReactUseBinding: true,
|
|
39854
40235
|
isReactNamespaceBinding: false
|
|
39855
40236
|
};
|
|
39856
|
-
const getScriptKind$2 = (filename) => {
|
|
39857
|
-
if (filename.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
39858
|
-
if (filename.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
39859
|
-
if (filename.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
39860
|
-
return ts.ScriptKind.JS;
|
|
39861
|
-
};
|
|
39862
40237
|
const getUtf16Offset$1 = (sourceText, utf8Offset) => Buffer.from(sourceText).subarray(0, utf8Offset).toString("utf8").length;
|
|
39863
|
-
const unwrapExpression = (expression) => {
|
|
39864
|
-
let currentExpression = expression;
|
|
39865
|
-
while (ts.isParenthesizedExpression(currentExpression) || ts.isAsExpression(currentExpression) || ts.isSatisfiesExpression(currentExpression) || ts.isNonNullExpression(currentExpression) || ts.isTypeAssertionExpression(currentExpression)) currentExpression = currentExpression.expression;
|
|
39866
|
-
return currentExpression;
|
|
39867
|
-
};
|
|
39868
40238
|
const getStaticPropertyName = (node) => {
|
|
39869
40239
|
if (!node) return null;
|
|
39870
40240
|
if (ts.isIdentifier(node) || ts.isStringLiteral(node) || ts.isNumericLiteral(node)) return node.text;
|
|
39871
40241
|
if (ts.isComputedPropertyName(node)) {
|
|
39872
|
-
const expression =
|
|
40242
|
+
const expression = unwrapTypescriptExpression(node.expression);
|
|
39873
40243
|
if (ts.isStringLiteral(expression) || ts.isNoSubstitutionTemplateLiteral(expression)) return expression.text;
|
|
39874
40244
|
}
|
|
39875
40245
|
return null;
|
|
@@ -39898,7 +40268,7 @@ const isReactUseObjectBindingElement = (bindingElement) => {
|
|
|
39898
40268
|
return getStaticPropertyName(bindingElement.propertyName) === USE_IDENTIFIER;
|
|
39899
40269
|
};
|
|
39900
40270
|
const isReactRequireCall = (expression) => {
|
|
39901
|
-
const unwrappedExpression =
|
|
40271
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
39902
40272
|
return ts.isCallExpression(unwrappedExpression) && ts.isIdentifier(unwrappedExpression.expression) && unwrappedExpression.expression.text === REQUIRE_IDENTIFIER && unwrappedExpression.arguments.length === 1 && ts.isStringLiteral(unwrappedExpression.arguments[0]) && unwrappedExpression.arguments[0].text === REACT_MODULE_SOURCE;
|
|
39903
40273
|
};
|
|
39904
40274
|
const getModuleSource = (node) => {
|
|
@@ -40000,7 +40370,7 @@ const isIdentifierShadowedByLocalBinding = (identifier, sourceFile) => {
|
|
|
40000
40370
|
return false;
|
|
40001
40371
|
};
|
|
40002
40372
|
const isReactNamespaceExpression = (expression, reactImportBindings, sourceFile, visitedDeclarations) => {
|
|
40003
|
-
const unwrappedExpression =
|
|
40373
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
40004
40374
|
if (isReactRequireCall(unwrappedExpression)) return true;
|
|
40005
40375
|
if (!ts.isIdentifier(unwrappedExpression)) return false;
|
|
40006
40376
|
if (reactImportBindings.namespaceNames.has(unwrappedExpression.text) && !isIdentifierShadowedByLocalBinding(unwrappedExpression, sourceFile)) return true;
|
|
@@ -40008,7 +40378,7 @@ const isReactNamespaceExpression = (expression, reactImportBindings, sourceFile,
|
|
|
40008
40378
|
};
|
|
40009
40379
|
const isReactUseExpression = (expression, reactImportBindings, sourceFile, visitedDeclarations) => {
|
|
40010
40380
|
if (!expression) return false;
|
|
40011
|
-
const unwrappedExpression =
|
|
40381
|
+
const unwrappedExpression = unwrapTypescriptExpression(expression);
|
|
40012
40382
|
if (ts.isIdentifier(unwrappedExpression)) {
|
|
40013
40383
|
if (reactImportBindings.useImportNames.has(unwrappedExpression.text) && !isIdentifierShadowedByLocalBinding(unwrappedExpression, sourceFile)) return true;
|
|
40014
40384
|
if (unwrappedExpression.text === USE_IDENTIFIER) return false;
|
|
@@ -40108,7 +40478,7 @@ const findUseCallIdentifier = (sourceFile, useOffset) => {
|
|
|
40108
40478
|
return matchedIdentifier;
|
|
40109
40479
|
};
|
|
40110
40480
|
const resolveUseCallBinding = (sourceText, filename, utf8Offset) => {
|
|
40111
|
-
const sourceFile = ts.createSourceFile(filename, sourceText, ts.ScriptTarget.Latest, true,
|
|
40481
|
+
const sourceFile = ts.createSourceFile(filename, sourceText, ts.ScriptTarget.Latest, true, getTypescriptScriptKind(filename));
|
|
40112
40482
|
const useIdentifier = findUseCallIdentifier(sourceFile, getUtf16Offset$1(sourceText, utf8Offset));
|
|
40113
40483
|
if (!useIdentifier) return null;
|
|
40114
40484
|
return resolveIdentifierBinding(useIdentifier, collectReactImportBindings(sourceFile), sourceFile);
|
|
@@ -40144,12 +40514,6 @@ const WORKLET_ACCEPTING_CALLEES = new Set([
|
|
|
40144
40514
|
"executeOnUIRuntimeSync"
|
|
40145
40515
|
]);
|
|
40146
40516
|
const GESTURE_ROOT_IDENTIFIER = "Gesture";
|
|
40147
|
-
const getScriptKind$1 = (filename) => {
|
|
40148
|
-
if (filename.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
40149
|
-
if (filename.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
40150
|
-
if (filename.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
40151
|
-
return ts.ScriptKind.JS;
|
|
40152
|
-
};
|
|
40153
40517
|
const getUtf16Offset = (sourceText, utf8Offset) => Buffer.from(sourceText).subarray(0, utf8Offset).toString("utf8").length;
|
|
40154
40518
|
const hasWorkletDirective = (node) => {
|
|
40155
40519
|
if (!ts.isFunctionDeclaration(node) && !ts.isFunctionExpression(node) && !ts.isArrowFunction(node) && !ts.isMethodDeclaration(node)) return false;
|
|
@@ -40221,17 +40585,11 @@ const shouldSuppressCompilerFindingInWorklet = (diagnostic, project, rootDirecto
|
|
|
40221
40585
|
} catch {
|
|
40222
40586
|
return false;
|
|
40223
40587
|
}
|
|
40224
|
-
return isOffsetInsideWorklet(ts.createSourceFile(absolutePath, sourceText, ts.ScriptTarget.Latest, true,
|
|
40588
|
+
return isOffsetInsideWorklet(ts.createSourceFile(absolutePath, sourceText, ts.ScriptTarget.Latest, true, getTypescriptScriptKind(absolutePath)), getUtf16Offset(sourceText, primaryLabel.span.offset));
|
|
40225
40589
|
};
|
|
40226
40590
|
const MANUAL_MEMOIZATION_PLUGIN = "react-doctor";
|
|
40227
40591
|
const MANUAL_MEMOIZATION_RULE = "react-compiler-no-manual-memoization";
|
|
40228
40592
|
const REACT_COMPILER_PLUGIN = "react-hooks-js";
|
|
40229
|
-
const getScriptKind = (filename) => {
|
|
40230
|
-
if (filename.endsWith(".tsx")) return ts.ScriptKind.TSX;
|
|
40231
|
-
if (filename.endsWith(".jsx")) return ts.ScriptKind.JSX;
|
|
40232
|
-
if (filename.endsWith(".ts")) return ts.ScriptKind.TS;
|
|
40233
|
-
return ts.ScriptKind.JS;
|
|
40234
|
-
};
|
|
40235
40593
|
const isManualMemoizationDiagnostic = (diagnostic) => diagnostic.plugin === MANUAL_MEMOIZATION_PLUGIN && diagnostic.rule === MANUAL_MEMOIZATION_RULE;
|
|
40236
40594
|
const nodeLineRange = (sourceFile, node) => ({
|
|
40237
40595
|
startLine: sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1,
|
|
@@ -40293,7 +40651,7 @@ const suppressMemoizationInBailedOutFunctions = (diagnostics, rootDirectory) =>
|
|
|
40293
40651
|
try {
|
|
40294
40652
|
const buffer = NFS.readFileSync(absolutePath);
|
|
40295
40653
|
parsed = {
|
|
40296
|
-
sourceFile: ts.createSourceFile(absolutePath, buffer.toString("utf8"), ts.ScriptTarget.Latest, true,
|
|
40654
|
+
sourceFile: ts.createSourceFile(absolutePath, buffer.toString("utf8"), ts.ScriptTarget.Latest, true, getTypescriptScriptKind(absolutePath)),
|
|
40297
40655
|
buffer
|
|
40298
40656
|
};
|
|
40299
40657
|
} catch {
|
|
@@ -43278,4 +43636,4 @@ const toJsonReport = (result, options) => buildJsonReport({
|
|
|
43278
43636
|
export { AmbiguousProjectError, NoReactDependencyError, NotADirectoryError, PackageJsonNotFoundError, ProjectNotFoundError, ReactDoctorError, buildJsonReport, buildJsonReportError, clearCaches, defineConfig, diagnose, filterSourceFiles, getDiffInfo, hasReactRuntime, isProjectDiscoveryError, isReactDoctorError, summarizeDiagnostics, toJsonReport };
|
|
43279
43637
|
|
|
43280
43638
|
//# sourceMappingURL=index.js.map
|
|
43281
|
-
//# debugId=
|
|
43639
|
+
//# debugId=4096a0e2-9712-5e2f-b602-5ff55d3994a3
|