oxlint-plugin-react-doctor 0.7.7-dev.287dff7 → 0.7.7-dev.30b7eeb
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 +234 -1148
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10558,7 +10558,7 @@ const getAssignedName = (node) => {
|
|
|
10558
10558
|
}
|
|
10559
10559
|
return null;
|
|
10560
10560
|
};
|
|
10561
|
-
const isModuleExportsAssignment
|
|
10561
|
+
const isModuleExportsAssignment = (node) => {
|
|
10562
10562
|
const parent = node.parent;
|
|
10563
10563
|
if (!parent || !isNodeOfType(parent, "AssignmentExpression")) return false;
|
|
10564
10564
|
const left = parent.left;
|
|
@@ -10717,7 +10717,7 @@ const displayName = defineRule({
|
|
|
10717
10717
|
}
|
|
10718
10718
|
const assignedName = getAssignedName(node);
|
|
10719
10719
|
if (assignedName && isReactComponentName(assignedName) && ignoreNamed) return;
|
|
10720
|
-
if (isModuleExportsAssignment
|
|
10720
|
+
if (isModuleExportsAssignment(node) && !node.id) {
|
|
10721
10721
|
reportAt(node);
|
|
10722
10722
|
return;
|
|
10723
10723
|
}
|
|
@@ -10739,7 +10739,7 @@ const displayName = defineRule({
|
|
|
10739
10739
|
reportAt(node);
|
|
10740
10740
|
return;
|
|
10741
10741
|
}
|
|
10742
|
-
if (isModuleExportsAssignment
|
|
10742
|
+
if (isModuleExportsAssignment(node)) {
|
|
10743
10743
|
reportAt(node);
|
|
10744
10744
|
return;
|
|
10745
10745
|
}
|
|
@@ -14368,22 +14368,6 @@ const isReactHocCallbackArgument = (functionNode) => {
|
|
|
14368
14368
|
return calleeName !== null && REACT_HOC_NAMES.has(calleeName);
|
|
14369
14369
|
};
|
|
14370
14370
|
//#endregion
|
|
14371
|
-
//#region src/plugin/utils/is-outside-all-functions.ts
|
|
14372
|
-
const FUNCTION_SCOPE_KINDS = new Set([
|
|
14373
|
-
"function",
|
|
14374
|
-
"arrow-function",
|
|
14375
|
-
"method"
|
|
14376
|
-
]);
|
|
14377
|
-
const isOutsideAllFunctions = (symbol) => {
|
|
14378
|
-
let scope = symbol.scope;
|
|
14379
|
-
while (scope) {
|
|
14380
|
-
if (FUNCTION_SCOPE_KINDS.has(scope.kind)) return false;
|
|
14381
|
-
if (scope.kind === "module") return true;
|
|
14382
|
-
scope = scope.parent;
|
|
14383
|
-
}
|
|
14384
|
-
return true;
|
|
14385
|
-
};
|
|
14386
|
-
//#endregion
|
|
14387
14371
|
//#region src/plugin/rules/react-builtins/exhaustive-deps-low-level.ts
|
|
14388
14372
|
/**
|
|
14389
14373
|
* Lowest-level helpers consumed by both the main `exhaustive-deps`
|
|
@@ -14436,6 +14420,25 @@ const getHookName = (callee, scopes) => {
|
|
|
14436
14420
|
if (isNodeOfType(strippedCallee, "MemberExpression") && !strippedCallee.computed && isNodeOfType(strippedCallee.property, "Identifier")) return strippedCallee.property.name;
|
|
14437
14421
|
return null;
|
|
14438
14422
|
};
|
|
14423
|
+
const FUNCTION_SCOPE_KINDS = new Set([
|
|
14424
|
+
"function",
|
|
14425
|
+
"arrow-function",
|
|
14426
|
+
"method"
|
|
14427
|
+
]);
|
|
14428
|
+
/**
|
|
14429
|
+
* True for symbols declared at module scope (outside any function
|
|
14430
|
+
* scope). Module-scope bindings don't change between renders so they
|
|
14431
|
+
* don't need to live in dependency arrays.
|
|
14432
|
+
*/
|
|
14433
|
+
const isOutsideAllFunctions = (symbol) => {
|
|
14434
|
+
let scope = symbol.scope;
|
|
14435
|
+
while (scope) {
|
|
14436
|
+
if (FUNCTION_SCOPE_KINDS.has(scope.kind)) return false;
|
|
14437
|
+
if (scope.kind === "module") return true;
|
|
14438
|
+
scope = scope.parent ?? null;
|
|
14439
|
+
}
|
|
14440
|
+
return true;
|
|
14441
|
+
};
|
|
14439
14442
|
//#endregion
|
|
14440
14443
|
//#region src/plugin/rules/react-builtins/exhaustive-deps-messages.ts
|
|
14441
14444
|
const buildMissingDepMessage = (hookName, depName) => `\`${hookName}\` can run with a stale \`${depName}\` & show your users old data.`;
|
|
@@ -29493,7 +29496,7 @@ const isNumericForLoopCounter = (attributeNode, indexName) => {
|
|
|
29493
29496
|
if (forStatement.test && forLoopTestReadsDataLength(forStatement.test)) return false;
|
|
29494
29497
|
return true;
|
|
29495
29498
|
};
|
|
29496
|
-
const EMPTY_NAME_SET
|
|
29499
|
+
const EMPTY_NAME_SET = /* @__PURE__ */ new Set();
|
|
29497
29500
|
const findIteratorItemNamesOfBinding = (binding) => {
|
|
29498
29501
|
const names = /* @__PURE__ */ new Set();
|
|
29499
29502
|
if (!binding.bindingFunction || !isFunctionLike$1(binding.bindingFunction)) return names;
|
|
@@ -29607,9 +29610,9 @@ const noArrayIndexAsKey = defineRule({
|
|
|
29607
29610
|
const jsxElement = openingElement.parent;
|
|
29608
29611
|
if (jsxElement && isNodeOfType(jsxElement, "JSXElement")) {
|
|
29609
29612
|
const isInlineTextRun = INLINE_TEXT_LEAF_TAGS.has(elementName.name);
|
|
29610
|
-
const primitiveItemNames = keyTemplate ? findBareItemNamesReferencedByTemplate(keyTemplate, itemNames) : EMPTY_NAME_SET
|
|
29613
|
+
const primitiveItemNames = keyTemplate ? findBareItemNamesReferencedByTemplate(keyTemplate, itemNames) : EMPTY_NAME_SET;
|
|
29611
29614
|
if (!containsStatefulDescendant(jsxElement, {
|
|
29612
|
-
memberRootNames: isInlineTextRun ? itemNames : EMPTY_NAME_SET
|
|
29615
|
+
memberRootNames: isInlineTextRun ? itemNames : EMPTY_NAME_SET,
|
|
29613
29616
|
bareIdentifierNames: primitiveItemNames.size > 0 ? new Set([...derivedNames, ...primitiveItemNames]) : derivedNames
|
|
29614
29617
|
})) return;
|
|
29615
29618
|
}
|
|
@@ -30110,9 +30113,6 @@ const findNearestPackageDirectory = (filename) => {
|
|
|
30110
30113
|
const readNearestPackageManifest = (filename) => {
|
|
30111
30114
|
const packageDirectory = findNearestPackageDirectory(filename);
|
|
30112
30115
|
if (!packageDirectory) return null;
|
|
30113
|
-
return readPackageManifest(packageDirectory);
|
|
30114
|
-
};
|
|
30115
|
-
const readPackageManifest = (packageDirectory) => {
|
|
30116
30116
|
const packageJsonPath = path.join(packageDirectory, "package.json");
|
|
30117
30117
|
recordContentProbe(packageJsonPath);
|
|
30118
30118
|
const cached = cachedManifestByPackageDirectory.get(packageDirectory);
|
|
@@ -30491,16 +30491,7 @@ const isRenderPreservingCallArgumentFunction = (node, scopes) => {
|
|
|
30491
30491
|
return parent.arguments.some((argumentNode) => argumentNode === node) && isProvenArrayMapCall(parent, scopes);
|
|
30492
30492
|
};
|
|
30493
30493
|
const isNestedRenderEvidenceBoundary = (node, scopes) => NESTED_RENDER_EVIDENCE_BOUNDARY_TYPES.has(node.type) && !isRenderPreservingCallArgumentFunction(node, scopes);
|
|
30494
|
-
const isRenderOutputExpression = (node, scopes) => node.type === "JSXElement" || node.type === "JSXFragment" || isReactApiCall(node, "createElement", scopes, REACT_CREATE_ELEMENT_OPTIONS)
|
|
30495
|
-
const isReactDomCreatePortalCall = (node, scopes) => {
|
|
30496
|
-
if (!isNodeOfType(node, "CallExpression")) return false;
|
|
30497
|
-
const callee = stripParenExpression(node.callee);
|
|
30498
|
-
if (isNodeOfType(callee, "Identifier")) return scopes.symbolFor(callee)?.kind === "import" && getImportedNameFromModule(callee, callee.name, "react-dom") === "createPortal";
|
|
30499
|
-
if (!isNodeOfType(callee, "MemberExpression") || callee.computed || !isNodeOfType(callee.object, "Identifier") || !isNodeOfType(callee.property, "Identifier") || callee.property.name !== "createPortal") return false;
|
|
30500
|
-
const symbol = scopes.symbolFor(callee.object);
|
|
30501
|
-
if (!symbol || symbol.kind !== "import") return false;
|
|
30502
|
-
return isDefaultImportFromModule(callee.object, callee.object.name, "react-dom") || isNamespaceImportFromModule(callee.object, callee.object.name, "react-dom");
|
|
30503
|
-
};
|
|
30494
|
+
const isRenderOutputExpression = (node, scopes) => node.type === "JSXElement" || node.type === "JSXFragment" || isReactApiCall(node, "createElement", scopes, REACT_CREATE_ELEMENT_OPTIONS);
|
|
30504
30495
|
const containsRenderOutput$1 = (rootNode, scopes) => {
|
|
30505
30496
|
let hasRenderOutput = false;
|
|
30506
30497
|
walkAst(rootNode, (node) => {
|
|
@@ -41892,107 +41883,18 @@ const getNodeText$1 = (node) => {
|
|
|
41892
41883
|
return value;
|
|
41893
41884
|
});
|
|
41894
41885
|
};
|
|
41895
|
-
const
|
|
41896
|
-
|
|
41897
|
-
|
|
41898
|
-
|
|
41899
|
-
|
|
41900
|
-
|
|
41901
|
-
|
|
41902
|
-
|
|
41903
|
-
|
|
41904
|
-
|
|
41905
|
-
if (isNodeOfType(expression, "Identifier")) {
|
|
41906
|
-
const reference = getRef(analysis, expression);
|
|
41907
|
-
const symbol = context.scopes.symbolFor(expression);
|
|
41908
|
-
if (!reference || !symbol) return null;
|
|
41909
|
-
if (isProp(analysis, reference)) return {
|
|
41910
|
-
propSymbolId: symbol.id,
|
|
41911
|
-
memberPath: [],
|
|
41912
|
-
booleanNormalization: "identity"
|
|
41913
|
-
};
|
|
41914
|
-
if (visitedSymbolIds.has(symbol.id) || symbol.kind !== "const") return null;
|
|
41915
|
-
visitedSymbolIds.add(symbol.id);
|
|
41916
|
-
const initializer = getDirectConstInitializer(symbol);
|
|
41917
|
-
if (initializer) return getLivePropExpressionIdentity(analysis, context, initializer, visitedSymbolIds);
|
|
41918
|
-
return getUpstreamRefs(analysis, reference).some((upstreamReference) => isProp(analysis, upstreamReference)) ? {
|
|
41919
|
-
propSymbolId: symbol.id,
|
|
41920
|
-
memberPath: [],
|
|
41921
|
-
booleanNormalization: "identity"
|
|
41922
|
-
} : null;
|
|
41923
|
-
}
|
|
41924
|
-
if (isNodeOfType(expression, "MemberExpression")) {
|
|
41925
|
-
const propertyName = getStaticMemberPropertyName(expression);
|
|
41926
|
-
if (!propertyName) return null;
|
|
41927
|
-
const objectIdentity = getLivePropExpressionIdentity(analysis, context, expression.object, visitedSymbolIds);
|
|
41928
|
-
if (!objectIdentity) return null;
|
|
41929
|
-
return {
|
|
41930
|
-
...objectIdentity,
|
|
41931
|
-
memberPath: [...objectIdentity.memberPath, propertyName]
|
|
41932
|
-
};
|
|
41933
|
-
}
|
|
41934
|
-
if (isNodeOfType(expression, "CallExpression") && isNodeOfType(expression.callee, "Identifier") && expression.callee.name === "Boolean" && context.scopes.isGlobalReference(expression.callee) && expression.arguments?.length === 1) {
|
|
41935
|
-
const argument = expression.arguments[0];
|
|
41936
|
-
const argumentIdentity = getLivePropExpressionIdentity(analysis, context, argument, visitedSymbolIds);
|
|
41937
|
-
return argumentIdentity ? normalizeAsBoolean(argumentIdentity) : null;
|
|
41938
|
-
}
|
|
41939
|
-
if (isNodeOfType(expression, "UnaryExpression") && expression.operator === "!") {
|
|
41940
|
-
const argumentIdentity = getLivePropExpressionIdentity(analysis, context, expression.argument, visitedSymbolIds);
|
|
41941
|
-
return argumentIdentity ? negateBoolean(argumentIdentity) : null;
|
|
41942
|
-
}
|
|
41943
|
-
return null;
|
|
41944
|
-
};
|
|
41945
|
-
const isMountSnapshotInitializer = (context, node) => {
|
|
41946
|
-
if (!isReactApiCall(node, "useMemo", context.scopes, { resolveNamedAliases: true }) || !isNodeOfType(node, "CallExpression")) return false;
|
|
41947
|
-
const dependencies = node.arguments?.[1];
|
|
41948
|
-
return isNodeOfType(dependencies, "ArrayExpression") && dependencies.elements.length === 0;
|
|
41949
|
-
};
|
|
41950
|
-
const isMountSnapshotBinding = (context, identifier, visitedSymbolIds = /* @__PURE__ */ new Set()) => {
|
|
41951
|
-
const symbol = context.scopes.symbolFor(identifier);
|
|
41952
|
-
if (!symbol || visitedSymbolIds.has(symbol.id)) return false;
|
|
41953
|
-
visitedSymbolIds.add(symbol.id);
|
|
41954
|
-
const initializer = getDirectConstInitializer(symbol);
|
|
41955
|
-
if (!initializer) return false;
|
|
41956
|
-
if (isMountSnapshotInitializer(context, initializer)) return true;
|
|
41957
|
-
const expression = stripParenExpression(initializer);
|
|
41958
|
-
return isNodeOfType(expression, "Identifier") && isMountSnapshotBinding(context, expression, visitedSymbolIds);
|
|
41959
|
-
};
|
|
41960
|
-
const isConstantBooleanExpression = (context, node, visitedSymbolIds = /* @__PURE__ */ new Set()) => {
|
|
41961
|
-
const expression = stripParenExpression(node);
|
|
41962
|
-
if (isNodeOfType(expression, "Literal")) return true;
|
|
41963
|
-
if (isNodeOfType(expression, "Identifier")) {
|
|
41964
|
-
const symbol = context.scopes.symbolFor(expression);
|
|
41965
|
-
if (!symbol || visitedSymbolIds.has(symbol.id)) return false;
|
|
41966
|
-
visitedSymbolIds.add(symbol.id);
|
|
41967
|
-
const initializer = getDirectConstInitializer(symbol);
|
|
41968
|
-
return Boolean(initializer && isConstantBooleanExpression(context, initializer, visitedSymbolIds));
|
|
41969
|
-
}
|
|
41970
|
-
if (isNodeOfType(expression, "UnaryExpression") && expression.operator === "!") return isConstantBooleanExpression(context, expression.argument, visitedSymbolIds);
|
|
41971
|
-
if (isNodeOfType(expression, "CallExpression") && isNodeOfType(expression.callee, "Identifier") && expression.callee.name === "Boolean" && context.scopes.isGlobalReference(expression.callee) && expression.arguments?.length === 1) return isConstantBooleanExpression(context, expression.arguments[0], visitedSymbolIds);
|
|
41972
|
-
return false;
|
|
41886
|
+
const isLiteralConstantIdentifier = (analysis, identifier) => {
|
|
41887
|
+
const definitions = getRef(analysis, identifier)?.resolved?.defs;
|
|
41888
|
+
if (!definitions || definitions.length !== 1) return false;
|
|
41889
|
+
const definition = definitions[0];
|
|
41890
|
+
if (definition.type !== "Variable") return false;
|
|
41891
|
+
const declarator = definition.node;
|
|
41892
|
+
if (!isNodeOfType(declarator, "VariableDeclarator")) return false;
|
|
41893
|
+
const declaration = declarator.parent;
|
|
41894
|
+
if (!isNodeOfType(declaration, "VariableDeclaration") || declaration.kind !== "const") return false;
|
|
41895
|
+
return isNodeOfType(declarator.init, "Literal");
|
|
41973
41896
|
};
|
|
41974
|
-
const
|
|
41975
|
-
const reference = getRef(analysis, identifier);
|
|
41976
|
-
const symbol = context.scopes.symbolFor(identifier);
|
|
41977
|
-
if (!reference || !symbol || symbol.kind !== "const" || isOutsideAllFunctions(symbol)) return false;
|
|
41978
|
-
const initializer = symbol.initializer;
|
|
41979
|
-
if (!initializer || isMountSnapshotBinding(context, identifier)) return false;
|
|
41980
|
-
if (getDownstreamRefs(analysis, initializer).some((initializerReference) => isRefCurrent(initializerReference))) return false;
|
|
41981
|
-
return !isConstantBooleanExpression(context, initializer);
|
|
41982
|
-
};
|
|
41983
|
-
const areSameProvenLiveBinding = (analysis, context, left, right) => {
|
|
41984
|
-
const leftExpression = stripParenExpression(left);
|
|
41985
|
-
const rightExpression = stripParenExpression(right);
|
|
41986
|
-
if (!isNodeOfType(leftExpression, "Identifier") || !isNodeOfType(rightExpression, "Identifier")) return false;
|
|
41987
|
-
const leftSymbol = context.scopes.symbolFor(leftExpression);
|
|
41988
|
-
const rightSymbol = context.scopes.symbolFor(rightExpression);
|
|
41989
|
-
return Boolean(leftSymbol && leftSymbol === rightSymbol && isProvenLiveBinding(analysis, context, leftExpression));
|
|
41990
|
-
};
|
|
41991
|
-
const haveSameLivePropExpressionIdentity = (left, right) => {
|
|
41992
|
-
if (left.propSymbolId !== right.propSymbolId || left.booleanNormalization !== right.booleanNormalization || left.memberPath.length !== right.memberPath.length) return false;
|
|
41993
|
-
return left.memberPath.every((propertyName, index) => propertyName === right.memberPath[index]);
|
|
41994
|
-
};
|
|
41995
|
-
const isSetStateToInitialValue = (analysis, context, setterRef) => {
|
|
41897
|
+
const isSetStateToInitialValue = (analysis, setterRef) => {
|
|
41996
41898
|
const callExpr = getCallExpr(setterRef);
|
|
41997
41899
|
if (!callExpr || !isNodeOfType(callExpr, "CallExpression")) return false;
|
|
41998
41900
|
const setStateToValue = callExpr.arguments?.[0];
|
|
@@ -42003,12 +41905,7 @@ const isSetStateToInitialValue = (analysis, context, setterRef) => {
|
|
|
42003
41905
|
if (isUndefinedNode(setStateToValue) && isUndefinedNode(stateInitialValue)) return true;
|
|
42004
41906
|
if (setStateToValue == null && stateInitialValue == null) return true;
|
|
42005
41907
|
if (setStateToValue && !stateInitialValue || !setStateToValue && stateInitialValue) return false;
|
|
42006
|
-
if (stateInitialValue &&
|
|
42007
|
-
const initialLivePropIdentity = getLivePropExpressionIdentity(analysis, context, stateInitialValue);
|
|
42008
|
-
const nextLivePropIdentity = getLivePropExpressionIdentity(analysis, context, setStateToValue);
|
|
42009
|
-
if (initialLivePropIdentity && nextLivePropIdentity && haveSameLivePropExpressionIdentity(initialLivePropIdentity, nextLivePropIdentity)) return false;
|
|
42010
|
-
if (areSameProvenLiveBinding(analysis, context, stateInitialValue, setStateToValue)) return false;
|
|
42011
|
-
}
|
|
41908
|
+
if (stateInitialValue && isNodeOfType(stateInitialValue, "Identifier") && stateInitialValue.name !== "undefined" && !isLiteralConstantIdentifier(analysis, stateInitialValue)) return false;
|
|
42012
41909
|
return getNodeText$1(setStateToValue) === getNodeText$1(stateInitialValue);
|
|
42013
41910
|
};
|
|
42014
41911
|
const countUseStates = (analysis, componentNode) => {
|
|
@@ -42017,10 +41914,10 @@ const countUseStates = (analysis, componentNode) => {
|
|
|
42017
41914
|
for (const ref of getDownstreamRefs(analysis, componentNode)) if (isState(analysis, ref)) stateVariables.add(ref.resolved);
|
|
42018
41915
|
return stateVariables.size;
|
|
42019
41916
|
};
|
|
42020
|
-
const findPropUsedToResetAllState = (analysis,
|
|
41917
|
+
const findPropUsedToResetAllState = (analysis, effectFnRefs, depsRefs, useEffectNode, effectFn) => {
|
|
42021
41918
|
const stateSetterRefs = effectFnRefs.filter((ref) => isSyncStateSetterCall(analysis, ref, effectFn));
|
|
42022
41919
|
if (stateSetterRefs.length === 0) return null;
|
|
42023
|
-
if (!stateSetterRefs.every((ref) => isSetStateToInitialValue(analysis,
|
|
41920
|
+
if (!stateSetterRefs.every((ref) => isSetStateToInitialValue(analysis, ref))) return null;
|
|
42024
41921
|
if (stateSetterRefs.every((setterRef) => effectFnRefs.some((otherRef) => otherRef !== setterRef && otherRef.resolved === setterRef.resolved && Boolean(getCallExpr(otherRef)) && !isSyncStateSetterCall(analysis, otherRef, effectFn)))) return null;
|
|
42025
41922
|
const containing = findContainingNode(analysis, useEffectNode);
|
|
42026
41923
|
if (new Set(stateSetterRefs.map((setterRef) => setterRef.resolved)).size !== countUseStates(analysis, containing)) return null;
|
|
@@ -42044,7 +41941,7 @@ const noResetAllStateOnPropChange = defineRule({
|
|
|
42044
41941
|
if (containing && isCustomHook(containing)) return;
|
|
42045
41942
|
const effectFn = getEffectFn(analysis, node);
|
|
42046
41943
|
if (!effectFn) return;
|
|
42047
|
-
if (!findPropUsedToResetAllState(analysis,
|
|
41944
|
+
if (!findPropUsedToResetAllState(analysis, effectFnRefs, depsRefs, node, effectFn)) return;
|
|
42048
41945
|
context.report({
|
|
42049
41946
|
node,
|
|
42050
41947
|
message: `Your users briefly see stale state when a prop changes because this useEffect clears all state.`
|
|
@@ -45847,726 +45744,19 @@ const nosqlInjectionRisk = defineRule({
|
|
|
45847
45744
|
})
|
|
45848
45745
|
});
|
|
45849
45746
|
//#endregion
|
|
45850
|
-
//#region src/plugin/utils/export-all-adds-runtime-values.ts
|
|
45851
|
-
const getExportedName = (node) => {
|
|
45852
|
-
if (!node) return null;
|
|
45853
|
-
if (isNodeOfType(node, "Identifier")) return node.name;
|
|
45854
|
-
if (isNodeOfType(node, "Literal") && typeof node.value === "string") return node.value;
|
|
45855
|
-
return null;
|
|
45856
|
-
};
|
|
45857
|
-
const programHasRuntimeNamedExports = (filePath, program, visitedFilePaths) => {
|
|
45858
|
-
if (!isNodeOfType(program, "Program")) return true;
|
|
45859
|
-
for (const statement of program.body) {
|
|
45860
|
-
if (isNodeOfType(statement, "ExportDefaultDeclaration")) continue;
|
|
45861
|
-
if (isNodeOfType(statement, "ExportAllDeclaration")) {
|
|
45862
|
-
if (statement.exportKind === "type") continue;
|
|
45863
|
-
if (statement.exported) return true;
|
|
45864
|
-
if (typeof statement.source.value !== "string") return true;
|
|
45865
|
-
if (exportAllAddsRuntimeValues(filePath, statement.source.value, visitedFilePaths)) return true;
|
|
45866
|
-
continue;
|
|
45867
|
-
}
|
|
45868
|
-
if (!isNodeOfType(statement, "ExportNamedDeclaration")) continue;
|
|
45869
|
-
if (statement.exportKind === "type") continue;
|
|
45870
|
-
if (statement.declaration) {
|
|
45871
|
-
if (statement.declaration.type !== "TSInterfaceDeclaration" && statement.declaration.type !== "TSTypeAliasDeclaration" && statement.declaration.type !== "TSDeclareFunction") return true;
|
|
45872
|
-
continue;
|
|
45873
|
-
}
|
|
45874
|
-
if (isEverySpecifierInlineType(statement.specifiers, "ExportSpecifier", "exportKind")) continue;
|
|
45875
|
-
for (const specifier of statement.specifiers) {
|
|
45876
|
-
if (!isNodeOfType(specifier, "ExportSpecifier") || specifier.exportKind === "type") continue;
|
|
45877
|
-
if (getExportedName(specifier.exported) !== "default") return true;
|
|
45878
|
-
}
|
|
45879
|
-
}
|
|
45880
|
-
return false;
|
|
45881
|
-
};
|
|
45882
|
-
const exportAllAddsRuntimeValues = (importerFilePath, source, visitedFilePaths = /* @__PURE__ */ new Set()) => {
|
|
45883
|
-
const resolvedFilePath = resolveRelativeImportPath(importerFilePath, source);
|
|
45884
|
-
if (!resolvedFilePath) return true;
|
|
45885
|
-
if (path.extname(resolvedFilePath) === ".cjs" || resolvedFilePath.endsWith(".cts")) return true;
|
|
45886
|
-
if (visitedFilePaths.has(resolvedFilePath)) return true;
|
|
45887
|
-
visitedFilePaths.add(resolvedFilePath);
|
|
45888
|
-
const program = parseSourceFile(resolvedFilePath);
|
|
45889
|
-
if (!program) return true;
|
|
45890
|
-
return programHasRuntimeNamedExports(resolvedFilePath, program, visitedFilePaths);
|
|
45891
|
-
};
|
|
45892
|
-
//#endregion
|
|
45893
45747
|
//#region src/plugin/utils/is-framework-route-or-special-filename.ts
|
|
45894
|
-
const
|
|
45895
|
-
const
|
|
45896
|
-
|
|
45897
|
-
|
|
45898
|
-
|
|
45899
|
-
|
|
45900
|
-
|
|
45901
|
-
|
|
45902
|
-
if (path.isAbsolute(filename)) return false;
|
|
45903
|
-
return filename.startsWith(`${directoryPath}/`) || filename.includes(`/${directoryPath}/`);
|
|
45904
|
-
};
|
|
45905
|
-
const isInExpoRouteDirectory = (context) => {
|
|
45906
|
-
const filename = normalizeFilename(context.filename ?? "");
|
|
45907
|
-
const configuredRootDirectory = getReactDoctorStringSetting(context.settings, "rootDirectory");
|
|
45908
|
-
const packageDirectory = path.isAbsolute(filename) ? findNearestPackageDirectory(filename) : null;
|
|
45909
|
-
const projectRelativeFilename = getProjectRelativeFilename(filename, configuredRootDirectory ?? packageDirectory ?? void 0);
|
|
45910
|
-
const relativeFilename = projectRelativeFilename === filename && path.isAbsolute(filename) ? filename.split("/").slice(2).join("/") : projectRelativeFilename;
|
|
45911
|
-
return relativeFilename.startsWith("app/") || relativeFilename.startsWith("src/app/");
|
|
45912
|
-
};
|
|
45913
|
-
const isFrameworkRouteOrSpecialFilename = (context, runtime) => {
|
|
45914
|
-
const rawFilename = context.filename;
|
|
45748
|
+
const sourceFileExtensionGroup = NEXTJS_SOURCE_FILE_EXTENSION_GROUP;
|
|
45749
|
+
const FRAMEWORK_ROUTE_FILE_PATTERNS = [
|
|
45750
|
+
new RegExp(`^(page|layout|loading|error|not-found|template|default|global-error|route|_app|_document|_error)\\.${sourceFileExtensionGroup}$`),
|
|
45751
|
+
new RegExp(`^(_layout|\\+html|\\+not-found|\\+native-intent)\\.${sourceFileExtensionGroup}$`),
|
|
45752
|
+
new RegExp(`(?:^__root|\\.lazy)\\.${sourceFileExtensionGroup}$`),
|
|
45753
|
+
new RegExp(`^(root|entry\\.client|entry\\.server)\\.${sourceFileExtensionGroup}$`)
|
|
45754
|
+
];
|
|
45755
|
+
const isFrameworkRouteOrSpecialFilename = (rawFilename) => {
|
|
45915
45756
|
if (!rawFilename) return false;
|
|
45757
|
+
if (isNextjsMetadataImageRouteFilename(rawFilename)) return true;
|
|
45916
45758
|
const basename = path.basename(rawFilename);
|
|
45917
|
-
|
|
45918
|
-
if (runtime === "expo") return isInExpoRouteDirectory(context) && EXPO_ROUTE_FILE_PATTERN.test(basename);
|
|
45919
|
-
if (runtime === "tanstack") return TANSTACK_ROUTE_FILE_PATTERN.test(basename);
|
|
45920
|
-
if (runtime === "react-router" || runtime === "remix") return REACT_ROUTER_FILE_PATTERN.test(basename);
|
|
45921
|
-
return false;
|
|
45922
|
-
};
|
|
45923
|
-
//#endregion
|
|
45924
|
-
//#region src/plugin/utils/function-has-react-element-return-type.ts
|
|
45925
|
-
const isReactNamespaceBinding = (node) => {
|
|
45926
|
-
if (!isNodeOfType(node, "Identifier")) return false;
|
|
45927
|
-
const binding = getImportBindingForName(node, node.name);
|
|
45928
|
-
return Boolean(binding && binding.source === "react" && (binding.isNamespace || binding.exportedName === "default"));
|
|
45929
|
-
};
|
|
45930
|
-
const hasLocalJsxNamespace = (node) => {
|
|
45931
|
-
const program = findProgramRoot(node);
|
|
45932
|
-
if (!program || !isNodeOfType(program, "Program")) return false;
|
|
45933
|
-
return program.body.some((statement) => isNodeOfType(statement, "TSModuleDeclaration") && isNodeOfType(statement.id, "Identifier") && statement.id.name === "JSX");
|
|
45934
|
-
};
|
|
45935
|
-
const isReactElementTypeReference = (node) => {
|
|
45936
|
-
if (!isNodeOfType(node, "TSTypeReference")) return false;
|
|
45937
|
-
const typeName = node.typeName;
|
|
45938
|
-
if (isNodeOfType(typeName, "Identifier")) return getImportedNameFromModule(typeName, typeName.name, "react") === "ReactElement";
|
|
45939
|
-
if (!isNodeOfType(typeName, "TSQualifiedName")) return false;
|
|
45940
|
-
if (!isNodeOfType(typeName.right, "Identifier")) return false;
|
|
45941
|
-
if (typeName.right.name === "ReactElement" && isReactNamespaceBinding(typeName.left)) return true;
|
|
45942
|
-
if (typeName.right.name !== "Element") return false;
|
|
45943
|
-
if (isNodeOfType(typeName.left, "Identifier")) {
|
|
45944
|
-
if (typeName.left.name !== "JSX") return false;
|
|
45945
|
-
const binding = getImportBindingForName(typeName.left, typeName.left.name);
|
|
45946
|
-
if (!binding) return !hasLocalJsxNamespace(typeName.left);
|
|
45947
|
-
return binding.source === "react" && binding.exportedName === "JSX";
|
|
45948
|
-
}
|
|
45949
|
-
return isNodeOfType(typeName.left, "TSQualifiedName") && isNodeOfType(typeName.left.right, "Identifier") && typeName.left.right.name === "JSX" && isReactNamespaceBinding(typeName.left.left);
|
|
45950
|
-
};
|
|
45951
|
-
const containsReactElementType = (node) => {
|
|
45952
|
-
if (isNodeOfType(node, "TSUnionType")) return node.types.some((member) => containsReactElementType(member));
|
|
45953
|
-
return isReactElementTypeReference(node);
|
|
45954
|
-
};
|
|
45955
|
-
const functionHasReactElementReturnType = (functionNode) => {
|
|
45956
|
-
const returnType = Reflect.get(functionNode, "returnType");
|
|
45957
|
-
if (!isNodeOfType(returnType, "TSTypeAnnotation")) return false;
|
|
45958
|
-
return containsReactElementType(returnType.typeAnnotation);
|
|
45959
|
-
};
|
|
45960
|
-
//#endregion
|
|
45961
|
-
//#region src/plugin/constants/fast-refresh.ts
|
|
45962
|
-
const FAST_REFRESH_CONFIG_FILENAMES = [
|
|
45963
|
-
"vite.config.ts",
|
|
45964
|
-
"vite.config.mts",
|
|
45965
|
-
"vite.config.cts",
|
|
45966
|
-
"vite.config.js",
|
|
45967
|
-
"vite.config.mjs",
|
|
45968
|
-
"vite.config.cjs",
|
|
45969
|
-
"webpack.config.ts",
|
|
45970
|
-
"webpack.config.js",
|
|
45971
|
-
"webpack.config.mjs",
|
|
45972
|
-
"webpack.config.cjs",
|
|
45973
|
-
"rsbuild.config.ts",
|
|
45974
|
-
"rsbuild.config.js",
|
|
45975
|
-
"rspack.config.ts",
|
|
45976
|
-
"rspack.config.js"
|
|
45977
|
-
];
|
|
45978
|
-
const MINIMUM_FAST_REFRESH_VERSIONS = {
|
|
45979
|
-
dumi: {
|
|
45980
|
-
major: 2,
|
|
45981
|
-
minor: 0
|
|
45982
|
-
},
|
|
45983
|
-
expo: {
|
|
45984
|
-
major: 36,
|
|
45985
|
-
minor: 0
|
|
45986
|
-
},
|
|
45987
|
-
gatsby: {
|
|
45988
|
-
major: 2,
|
|
45989
|
-
minor: 31
|
|
45990
|
-
},
|
|
45991
|
-
next: {
|
|
45992
|
-
major: 9,
|
|
45993
|
-
minor: 4
|
|
45994
|
-
},
|
|
45995
|
-
parcel: {
|
|
45996
|
-
major: 2,
|
|
45997
|
-
minor: 0
|
|
45998
|
-
},
|
|
45999
|
-
reactForGatsbyTwo: {
|
|
46000
|
-
major: 17,
|
|
46001
|
-
minor: 0
|
|
46002
|
-
},
|
|
46003
|
-
reactNative: {
|
|
46004
|
-
major: 0,
|
|
46005
|
-
minor: 61
|
|
46006
|
-
},
|
|
46007
|
-
reactScripts: {
|
|
46008
|
-
major: 4,
|
|
46009
|
-
minor: 0
|
|
46010
|
-
},
|
|
46011
|
-
storybookReact: {
|
|
46012
|
-
major: 6,
|
|
46013
|
-
minor: 1
|
|
46014
|
-
}
|
|
46015
|
-
};
|
|
46016
|
-
//#endregion
|
|
46017
|
-
//#region src/plugin/utils/get-fast-refresh-file-status.ts
|
|
46018
|
-
const INTEGRATION_IMPORTS = new Map([
|
|
46019
|
-
["@vitejs/plugin-react", {
|
|
46020
|
-
importedNames: null,
|
|
46021
|
-
requiresViteDevelopmentServer: true,
|
|
46022
|
-
runtime: "generic"
|
|
46023
|
-
}],
|
|
46024
|
-
["@vitejs/plugin-react-swc", {
|
|
46025
|
-
importedNames: null,
|
|
46026
|
-
requiresViteDevelopmentServer: true,
|
|
46027
|
-
runtime: "generic"
|
|
46028
|
-
}],
|
|
46029
|
-
["@pmmmwh/react-refresh-webpack-plugin", {
|
|
46030
|
-
importedNames: null,
|
|
46031
|
-
runtime: "generic"
|
|
46032
|
-
}],
|
|
46033
|
-
["@react-router/dev/vite", {
|
|
46034
|
-
importedNames: new Set(["reactRouter"]),
|
|
46035
|
-
requiresViteDevelopmentServer: true,
|
|
46036
|
-
runtime: "react-router"
|
|
46037
|
-
}],
|
|
46038
|
-
["@remix-run/dev", {
|
|
46039
|
-
importedNames: new Set(["vitePlugin"]),
|
|
46040
|
-
requiresViteDevelopmentServer: true,
|
|
46041
|
-
runtime: "remix"
|
|
46042
|
-
}],
|
|
46043
|
-
["@rsbuild/plugin-react", {
|
|
46044
|
-
importedNames: new Set(["pluginReact"]),
|
|
46045
|
-
runtime: "generic"
|
|
46046
|
-
}],
|
|
46047
|
-
["@rspack/plugin-react-refresh", {
|
|
46048
|
-
importedNames: null,
|
|
46049
|
-
runtime: "generic"
|
|
46050
|
-
}],
|
|
46051
|
-
["@rozenite/vite-plugin", {
|
|
46052
|
-
importedNames: new Set(["rozenitePlugin"]),
|
|
46053
|
-
requiresViteDevelopmentServer: true,
|
|
46054
|
-
runtime: "generic"
|
|
46055
|
-
}],
|
|
46056
|
-
["@tanstack/react-start/plugin/vite", {
|
|
46057
|
-
importedNames: new Set(["tanstackStart"]),
|
|
46058
|
-
requiresViteDevelopmentServer: true,
|
|
46059
|
-
runtime: "tanstack"
|
|
46060
|
-
}]
|
|
46061
|
-
]);
|
|
46062
|
-
const REGISTERED_INTEGRATION_RUNTIME_PRECEDENCE = [
|
|
46063
|
-
"tanstack",
|
|
46064
|
-
"remix",
|
|
46065
|
-
"react-router",
|
|
46066
|
-
"generic"
|
|
46067
|
-
];
|
|
46068
|
-
const cachedLocalStatusByManifest = /* @__PURE__ */ new WeakMap();
|
|
46069
|
-
const cachedWorkspaceIndexByManifest = /* @__PURE__ */ new WeakMap();
|
|
46070
|
-
const INACTIVE_STATUS = {
|
|
46071
|
-
isActive: false,
|
|
46072
|
-
runtime: "generic"
|
|
46073
|
-
};
|
|
46074
|
-
const WORKSPACE_IGNORED_DIRECTORY_NAMES = new Set([
|
|
46075
|
-
".git",
|
|
46076
|
-
".next",
|
|
46077
|
-
"build",
|
|
46078
|
-
"coverage",
|
|
46079
|
-
"dist",
|
|
46080
|
-
"node_modules",
|
|
46081
|
-
"out"
|
|
46082
|
-
]);
|
|
46083
|
-
const parseVersion = (version) => {
|
|
46084
|
-
if (typeof version !== "string") return null;
|
|
46085
|
-
const match = version.match(/(?:^|[^\d])(\d+)(?:\.(\d+))?/);
|
|
46086
|
-
if (!match) return null;
|
|
46087
|
-
return {
|
|
46088
|
-
major: Number(match[1]),
|
|
46089
|
-
minor: Number(match[2] ?? 0)
|
|
46090
|
-
};
|
|
46091
|
-
};
|
|
46092
|
-
const isVersionAtLeast = (version, minimum) => {
|
|
46093
|
-
const parsed = parseVersion(version);
|
|
46094
|
-
if (!parsed) return false;
|
|
46095
|
-
return parsed.major > minimum.major || parsed.major === minimum.major && parsed.minor >= minimum.minor;
|
|
46096
|
-
};
|
|
46097
|
-
const getDependencyVersion = (manifest, dependencyName) => manifest.dependencies?.[dependencyName] ?? manifest.devDependencies?.[dependencyName] ?? manifest.peerDependencies?.[dependencyName] ?? manifest.optionalDependencies?.[dependencyName];
|
|
46098
|
-
const getRuntimeDependencyVersion = (manifest, dependencyName) => manifest.dependencies?.[dependencyName] ?? manifest.optionalDependencies?.[dependencyName];
|
|
46099
|
-
const getOwnedDependencyVersion = (manifest, dependencyName, developmentCommandPattern) => {
|
|
46100
|
-
const runtimeVersion = getRuntimeDependencyVersion(manifest, dependencyName);
|
|
46101
|
-
if (runtimeVersion !== void 0) return runtimeVersion;
|
|
46102
|
-
return Object.values(manifest.scripts ?? {}).some((script) => typeof script === "string" && developmentCommandPattern.test(script)) ? manifest.devDependencies?.[dependencyName] : void 0;
|
|
46103
|
-
};
|
|
46104
|
-
const hasParcelBrowserEntry = (manifest) => {
|
|
46105
|
-
if (typeof manifest.source === "string" && manifest.source.endsWith(".html")) return true;
|
|
46106
|
-
return Object.values(manifest.scripts ?? {}).some((script) => typeof script === "string" && /(?:^|\s)parcel(?:\s+serve)?\s+[^\n]*\.html(?:\s|$)/.test(script));
|
|
46107
|
-
};
|
|
46108
|
-
const hasParcelDevelopmentCommand = (manifest) => Object.values(manifest.scripts ?? {}).some((script) => typeof script === "string" && /(?:^|[\s;&|'\\"])parcel(?=\s|$)(?!\s+(?:build|help|watch|--help|--version|-h|-V)(?:\s|$))/.test(script) && !/(?:^|\s)--no-hmr(?:\s|$)/.test(script));
|
|
46109
|
-
const hasOwnedDevelopmentCommand = (manifest, commandPattern) => Object.values(manifest.scripts ?? {}).some((script) => typeof script === "string" && commandPattern.test(script));
|
|
46110
|
-
const hasViteDevelopmentCommand = (manifest) => Object.values(manifest.scripts ?? {}).some((script) => {
|
|
46111
|
-
if (typeof script !== "string") return false;
|
|
46112
|
-
return [...script.matchAll(/(?:^|[\s;&|'\\"])vite(?:\s+(build|preview|test)\b)?/g)].some((match) => match[1] === void 0);
|
|
46113
|
-
});
|
|
46114
|
-
const hasViteBrowserEntry = (manifest, packageDirectory) => {
|
|
46115
|
-
if (typeof manifest.source === "string" && manifest.source.endsWith(".html")) return true;
|
|
46116
|
-
const browserEntryPath = path.join(packageDirectory, "index.html");
|
|
46117
|
-
recordExistenceProbe(browserEntryPath);
|
|
46118
|
-
return fs.existsSync(browserEntryPath);
|
|
46119
|
-
};
|
|
46120
|
-
const getBuiltInStatus = (manifest) => {
|
|
46121
|
-
if (isVersionAtLeast(getOwnedDependencyVersion(manifest, "next", /(?:^|\s)next\s+dev(?:\s|$)/), MINIMUM_FAST_REFRESH_VERSIONS.next)) return {
|
|
46122
|
-
isActive: true,
|
|
46123
|
-
runtime: "next"
|
|
46124
|
-
};
|
|
46125
|
-
const gatsbyDependency = getOwnedDependencyVersion(manifest, "gatsby", /(?:^|\s)gatsby\s+develop(?:\s|$)/);
|
|
46126
|
-
const gatsbyVersion = parseVersion(gatsbyDependency);
|
|
46127
|
-
const hasGatsbyFastRefresh = gatsbyVersion !== null && (gatsbyVersion.major >= 3 || isVersionAtLeast(gatsbyDependency, MINIMUM_FAST_REFRESH_VERSIONS.gatsby) && isVersionAtLeast(getDependencyVersion(manifest, "react"), MINIMUM_FAST_REFRESH_VERSIONS.reactForGatsbyTwo));
|
|
46128
|
-
if (isVersionAtLeast(getOwnedDependencyVersion(manifest, "react-scripts", /(?:^|\s)react-scripts\s+start(?:\s|$)/), MINIMUM_FAST_REFRESH_VERSIONS.reactScripts) || hasGatsbyFastRefresh || isVersionAtLeast(getDependencyVersion(manifest, "parcel"), MINIMUM_FAST_REFRESH_VERSIONS.parcel) && declaresDependency(manifest, "react") && hasParcelDevelopmentCommand(manifest) && hasParcelBrowserEntry(manifest)) return {
|
|
46129
|
-
isActive: true,
|
|
46130
|
-
runtime: "generic"
|
|
46131
|
-
};
|
|
46132
|
-
if (isVersionAtLeast(getOwnedDependencyVersion(manifest, "expo", /(?:^|\s)expo\s+start(?:\s|$)/), MINIMUM_FAST_REFRESH_VERSIONS.expo) || isVersionAtLeast(getOwnedDependencyVersion(manifest, "react-native", /(?:^|\s)react-native\s+start(?:\s|$)/), MINIMUM_FAST_REFRESH_VERSIONS.reactNative)) return {
|
|
46133
|
-
isActive: true,
|
|
46134
|
-
runtime: "expo"
|
|
46135
|
-
};
|
|
46136
|
-
if (isVersionAtLeast(getOwnedDependencyVersion(manifest, "dumi", /(?:^|\s)dumi\s+dev(?:\s|$)/), MINIMUM_FAST_REFRESH_VERSIONS.dumi)) return {
|
|
46137
|
-
isActive: true,
|
|
46138
|
-
runtime: "generic"
|
|
46139
|
-
};
|
|
46140
|
-
return null;
|
|
46141
|
-
};
|
|
46142
|
-
const getIntegrationLocalNames = (program, scopes) => {
|
|
46143
|
-
const localBindings = /* @__PURE__ */ new Map();
|
|
46144
|
-
const registerLocalName = (source, importedName, localIdentifier) => {
|
|
46145
|
-
const integration = INTEGRATION_IMPORTS.get(source);
|
|
46146
|
-
if (!integration) return;
|
|
46147
|
-
if (integration.importedNames === null ? importedName === null || importedName === "default" : importedName !== null && integration.importedNames.has(importedName)) {
|
|
46148
|
-
const symbol = scopes.symbolFor(localIdentifier);
|
|
46149
|
-
if (symbol) localBindings.set(symbol, integration);
|
|
46150
|
-
}
|
|
46151
|
-
};
|
|
46152
|
-
walkAst(program, (node) => {
|
|
46153
|
-
if (isNodeOfType(node, "ImportDeclaration")) {
|
|
46154
|
-
const source = node.source.value;
|
|
46155
|
-
if (typeof source !== "string") return;
|
|
46156
|
-
for (const specifier of node.specifiers) {
|
|
46157
|
-
if (isNodeOfType(specifier, "ImportDefaultSpecifier") || isNodeOfType(specifier, "ImportNamespaceSpecifier")) {
|
|
46158
|
-
registerLocalName(source, null, specifier.local);
|
|
46159
|
-
continue;
|
|
46160
|
-
}
|
|
46161
|
-
registerLocalName(source, getImportedName(specifier) ?? null, specifier.local);
|
|
46162
|
-
}
|
|
46163
|
-
return;
|
|
46164
|
-
}
|
|
46165
|
-
if (!isNodeOfType(node, "VariableDeclarator") || !node.init) return;
|
|
46166
|
-
const initializer = node.init;
|
|
46167
|
-
if (!isNodeOfType(initializer, "CallExpression") || !isNodeOfType(initializer.callee, "Identifier") || initializer.callee.name !== "require") return;
|
|
46168
|
-
const sourceArgument = initializer.arguments[0];
|
|
46169
|
-
if (!sourceArgument || !isNodeOfType(sourceArgument, "Literal")) return;
|
|
46170
|
-
const source = sourceArgument.value;
|
|
46171
|
-
if (typeof source !== "string") return;
|
|
46172
|
-
if (isNodeOfType(node.id, "Identifier")) {
|
|
46173
|
-
registerLocalName(source, null, node.id);
|
|
46174
|
-
return;
|
|
46175
|
-
}
|
|
46176
|
-
if (!isNodeOfType(node.id, "ObjectPattern")) return;
|
|
46177
|
-
for (const property of node.id.properties) {
|
|
46178
|
-
if (!isNodeOfType(property, "Property") || !isNodeOfType(property.value, "Identifier")) continue;
|
|
46179
|
-
registerLocalName(source, isNodeOfType(property.key, "Identifier") ? property.key.name : isNodeOfType(property.key, "Literal") && typeof property.key.value === "string" ? property.key.value : null, property.value);
|
|
46180
|
-
}
|
|
46181
|
-
});
|
|
46182
|
-
return localBindings;
|
|
46183
|
-
};
|
|
46184
|
-
const isModuleExportsAssignment = (node) => isNodeOfType(node, "AssignmentExpression") && isNodeOfType(node.left, "MemberExpression") && isNodeOfType(node.left.object, "Identifier") && node.left.object.name === "module" && isNodeOfType(node.left.property, "Identifier") && node.left.property.name === "exports";
|
|
46185
|
-
const getExportedBindings = (program, scopes) => {
|
|
46186
|
-
const exportedBindings = /* @__PURE__ */ new Set();
|
|
46187
|
-
walkAst(program, (node) => {
|
|
46188
|
-
let exportRoot = null;
|
|
46189
|
-
if (isNodeOfType(node, "ExportDefaultDeclaration")) exportRoot = node.declaration;
|
|
46190
|
-
else if (isNodeOfType(node, "AssignmentExpression") && isModuleExportsAssignment(node)) exportRoot = node.right;
|
|
46191
|
-
if (!exportRoot) return;
|
|
46192
|
-
if (isFunctionLike$1(exportRoot) || isNodeOfType(exportRoot, "ObjectExpression")) return;
|
|
46193
|
-
walkAst(exportRoot, (exportNode) => {
|
|
46194
|
-
if (isFunctionLike$1(exportNode) || isNodeOfType(exportNode, "ObjectExpression")) return false;
|
|
46195
|
-
if (!isNodeOfType(exportNode, "Identifier")) return;
|
|
46196
|
-
const symbol = scopes.symbolFor(exportNode);
|
|
46197
|
-
if (symbol) exportedBindings.add(symbol);
|
|
46198
|
-
});
|
|
46199
|
-
});
|
|
46200
|
-
return exportedBindings;
|
|
46201
|
-
};
|
|
46202
|
-
const isExportedConfigProperty = (property, exportedBindings, scopes) => {
|
|
46203
|
-
let ancestor = property.parent;
|
|
46204
|
-
let didFindContainingObject = false;
|
|
46205
|
-
let didCrossNestedProperty = false;
|
|
46206
|
-
let didCrossFunctionBoundary = false;
|
|
46207
|
-
let containingFunction = null;
|
|
46208
|
-
let containingReturn = null;
|
|
46209
|
-
while (ancestor) {
|
|
46210
|
-
if (isNodeOfType(ancestor, "ObjectExpression") && !didFindContainingObject) didFindContainingObject = true;
|
|
46211
|
-
else if (didFindContainingObject && isNodeOfType(ancestor, "Property")) didCrossNestedProperty = true;
|
|
46212
|
-
if (!containingReturn && isNodeOfType(ancestor, "ReturnStatement")) containingReturn = ancestor;
|
|
46213
|
-
if (isFunctionLike$1(ancestor)) if (containingFunction) didCrossFunctionBoundary = true;
|
|
46214
|
-
else containingFunction = ancestor;
|
|
46215
|
-
if (isNodeOfType(ancestor, "ExportDefaultDeclaration") || isModuleExportsAssignment(ancestor)) return !didCrossNestedProperty && !didCrossFunctionBoundary && (!containingFunction || Boolean(containingReturn) || !isNodeOfType(containingFunction.body, "BlockStatement"));
|
|
46216
|
-
if (isNodeOfType(ancestor, "VariableDeclarator") && isNodeOfType(ancestor.id, "Identifier")) {
|
|
46217
|
-
const binding = scopes.symbolFor(ancestor.id);
|
|
46218
|
-
if (binding && exportedBindings.has(binding)) return !didCrossNestedProperty && !containingFunction;
|
|
46219
|
-
}
|
|
46220
|
-
ancestor = ancestor.parent;
|
|
46221
|
-
}
|
|
46222
|
-
return false;
|
|
46223
|
-
};
|
|
46224
|
-
const getExplicitConfigPaths = (packageDirectory, manifest) => {
|
|
46225
|
-
const configPaths = new Set(FAST_REFRESH_CONFIG_FILENAMES.map((configFilename) => path.join(packageDirectory, configFilename)));
|
|
46226
|
-
for (const script of Object.values(manifest.scripts ?? {})) {
|
|
46227
|
-
if (typeof script !== "string") continue;
|
|
46228
|
-
for (const match of script.matchAll(/(?:^|\s)--config(?:=|\s+)(?:"([^"]+)"|'([^']+)'|([^\s;&|]+))/g)) {
|
|
46229
|
-
const relativeConfigPath = match[1] ?? match[2] ?? match[3];
|
|
46230
|
-
if (!relativeConfigPath) continue;
|
|
46231
|
-
const configPath = path.resolve(packageDirectory, relativeConfigPath);
|
|
46232
|
-
const relativePath = path.relative(packageDirectory, configPath);
|
|
46233
|
-
if (relativePath.startsWith("..") || path.isAbsolute(relativePath)) continue;
|
|
46234
|
-
configPaths.add(configPath);
|
|
46235
|
-
}
|
|
46236
|
-
}
|
|
46237
|
-
return [...configPaths];
|
|
46238
|
-
};
|
|
46239
|
-
const getRegisteredIntegration = (packageDirectory, manifest) => {
|
|
46240
|
-
for (const configPath of getExplicitConfigPaths(packageDirectory, manifest)) {
|
|
46241
|
-
const program = parseSourceFile(configPath);
|
|
46242
|
-
if (!program) continue;
|
|
46243
|
-
const scopes = analyzeScopes(program);
|
|
46244
|
-
const integrationLocalBindings = getIntegrationLocalNames(program, scopes);
|
|
46245
|
-
if (integrationLocalBindings.size === 0) continue;
|
|
46246
|
-
const exportedBindings = getExportedBindings(program, scopes);
|
|
46247
|
-
const registeredIntegrations = [];
|
|
46248
|
-
walkAst(program, (node) => {
|
|
46249
|
-
if (!isNodeOfType(node, "Property")) return;
|
|
46250
|
-
if (!(isNodeOfType(node.key, "Identifier") && node.key.name === "plugins" || isNodeOfType(node.key, "Literal") && node.key.value === "plugins")) return;
|
|
46251
|
-
if (!isExportedConfigProperty(node, exportedBindings, scopes)) return;
|
|
46252
|
-
const inspectedBindings = /* @__PURE__ */ new Set();
|
|
46253
|
-
const inspectValue = (value) => {
|
|
46254
|
-
walkAst(value, (valueNode) => {
|
|
46255
|
-
if (isNodeOfType(valueNode, "Identifier")) {
|
|
46256
|
-
const symbol = scopes.symbolFor(valueNode);
|
|
46257
|
-
const initializer = symbol ? getDirectUnreassignedInitializer(symbol) : null;
|
|
46258
|
-
if (symbol && initializer && !inspectedBindings.has(symbol.id)) {
|
|
46259
|
-
inspectedBindings.add(symbol.id);
|
|
46260
|
-
inspectValue(initializer);
|
|
46261
|
-
}
|
|
46262
|
-
}
|
|
46263
|
-
if (!isNodeOfType(valueNode, "CallExpression") && !isNodeOfType(valueNode, "NewExpression")) return;
|
|
46264
|
-
if (!isNodeOfType(valueNode.callee, "Identifier")) return;
|
|
46265
|
-
const symbol = scopes.symbolFor(valueNode.callee);
|
|
46266
|
-
const integration = symbol ? integrationLocalBindings.get(symbol) : null;
|
|
46267
|
-
if (integration) registeredIntegrations.push(integration);
|
|
46268
|
-
});
|
|
46269
|
-
};
|
|
46270
|
-
inspectValue(node.value);
|
|
46271
|
-
return false;
|
|
46272
|
-
});
|
|
46273
|
-
const hasViteDevelopmentRuntime = hasViteDevelopmentCommand(manifest) || hasViteBrowserEntry(manifest, packageDirectory);
|
|
46274
|
-
const registeredIntegration = REGISTERED_INTEGRATION_RUNTIME_PRECEDENCE.flatMap((runtime) => registeredIntegrations.filter((integration) => integration.runtime === runtime && (!integration.requiresViteDevelopmentServer || hasViteDevelopmentRuntime)))[0];
|
|
46275
|
-
if (registeredIntegration) return {
|
|
46276
|
-
isActive: true,
|
|
46277
|
-
runtime: registeredIntegration.runtime
|
|
46278
|
-
};
|
|
46279
|
-
}
|
|
46280
|
-
return null;
|
|
46281
|
-
};
|
|
46282
|
-
const hasStorybookReactViteConfig = (packageDirectory) => {
|
|
46283
|
-
for (const configFilename of [
|
|
46284
|
-
"main.ts",
|
|
46285
|
-
"main.js",
|
|
46286
|
-
"main.mjs",
|
|
46287
|
-
"main.cjs"
|
|
46288
|
-
]) {
|
|
46289
|
-
const program = parseSourceFile(path.join(packageDirectory, ".storybook", configFilename));
|
|
46290
|
-
if (!program) continue;
|
|
46291
|
-
const scopes = analyzeScopes(program);
|
|
46292
|
-
const exportedBindings = getExportedBindings(program, scopes);
|
|
46293
|
-
let hasReactViteFramework = false;
|
|
46294
|
-
walkAst(program, (node) => {
|
|
46295
|
-
if (!isNodeOfType(node, "Property")) return;
|
|
46296
|
-
if (!(isNodeOfType(node.key, "Identifier") && node.key.name === "framework" || isNodeOfType(node.key, "Literal") && node.key.value === "framework")) return;
|
|
46297
|
-
if (!isExportedConfigProperty(node, exportedBindings, scopes)) return;
|
|
46298
|
-
walkAst(node.value, (valueNode) => {
|
|
46299
|
-
if (isNodeOfType(valueNode, "Literal") && valueNode.value === "@storybook/react-vite") {
|
|
46300
|
-
hasReactViteFramework = true;
|
|
46301
|
-
return false;
|
|
46302
|
-
}
|
|
46303
|
-
});
|
|
46304
|
-
if (hasReactViteFramework) return false;
|
|
46305
|
-
});
|
|
46306
|
-
if (hasReactViteFramework) return true;
|
|
46307
|
-
}
|
|
46308
|
-
return false;
|
|
46309
|
-
};
|
|
46310
|
-
const resolveDirectUnreassignedValue = (value, scopes, visitedSymbolIds = /* @__PURE__ */ new Set()) => {
|
|
46311
|
-
const unwrappedValue = stripParenExpression(value);
|
|
46312
|
-
if (!isNodeOfType(unwrappedValue, "Identifier")) return unwrappedValue;
|
|
46313
|
-
const symbol = scopes.symbolFor(unwrappedValue);
|
|
46314
|
-
if (!symbol || visitedSymbolIds.has(symbol.id)) return unwrappedValue;
|
|
46315
|
-
const initializer = getDirectUnreassignedInitializer(symbol);
|
|
46316
|
-
if (!initializer) return unwrappedValue;
|
|
46317
|
-
visitedSymbolIds.add(symbol.id);
|
|
46318
|
-
return resolveDirectUnreassignedValue(initializer, scopes, visitedSymbolIds);
|
|
46319
|
-
};
|
|
46320
|
-
const isStaticPropertyNamed = (node, propertyName) => isNodeOfType(node, "Property") && (!node.computed && isNodeOfType(node.key, "Identifier") && node.key.name === propertyName || isNodeOfType(node.key, "Literal") && node.key.value === propertyName);
|
|
46321
|
-
const readLastStaticBooleanProperty = (value, propertyName, scopes) => {
|
|
46322
|
-
const resolvedValue = resolveDirectUnreassignedValue(value, scopes);
|
|
46323
|
-
if (!isNodeOfType(resolvedValue, "ObjectExpression")) return null;
|
|
46324
|
-
let propertyValue = null;
|
|
46325
|
-
for (const property of resolvedValue.properties) {
|
|
46326
|
-
if (isNodeOfType(property, "SpreadElement")) {
|
|
46327
|
-
propertyValue = null;
|
|
46328
|
-
continue;
|
|
46329
|
-
}
|
|
46330
|
-
if (!isStaticPropertyNamed(property, propertyName) || !isNodeOfType(property, "Property")) continue;
|
|
46331
|
-
propertyValue = readStaticBoolean(resolveDirectUnreassignedValue(property.value, scopes));
|
|
46332
|
-
}
|
|
46333
|
-
return propertyValue;
|
|
46334
|
-
};
|
|
46335
|
-
const isLastStaticPropertyInObject = (property, propertyName) => {
|
|
46336
|
-
if (!isNodeOfType(property.parent, "ObjectExpression")) return false;
|
|
46337
|
-
const propertyIndex = property.parent.properties.findIndex((objectProperty) => objectProperty === property);
|
|
46338
|
-
return property.parent.properties.slice(propertyIndex + 1).every((laterProperty) => {
|
|
46339
|
-
if (isNodeOfType(laterProperty, "SpreadElement")) return false;
|
|
46340
|
-
return !isStaticPropertyNamed(laterProperty, propertyName);
|
|
46341
|
-
});
|
|
46342
|
-
};
|
|
46343
|
-
const hasStorybookReactWebpackFastRefreshConfig = (packageDirectory) => {
|
|
46344
|
-
for (const configFilename of [
|
|
46345
|
-
"main.ts",
|
|
46346
|
-
"main.js",
|
|
46347
|
-
"main.mjs",
|
|
46348
|
-
"main.cjs"
|
|
46349
|
-
]) {
|
|
46350
|
-
const program = parseSourceFile(path.join(packageDirectory, ".storybook", configFilename));
|
|
46351
|
-
if (!program) continue;
|
|
46352
|
-
const scopes = analyzeScopes(program);
|
|
46353
|
-
const exportedBindings = getExportedBindings(program, scopes);
|
|
46354
|
-
let hasFastRefresh = false;
|
|
46355
|
-
walkAst(program, (node) => {
|
|
46356
|
-
if (!isStaticPropertyNamed(node, "reactOptions") || !isNodeOfType(node, "Property")) return;
|
|
46357
|
-
if (!isExportedConfigProperty(node, exportedBindings, scopes)) return;
|
|
46358
|
-
if (!isLastStaticPropertyInObject(node, "reactOptions")) return;
|
|
46359
|
-
if (readLastStaticBooleanProperty(node.value, "fastRefresh", scopes) === true) {
|
|
46360
|
-
hasFastRefresh = true;
|
|
46361
|
-
return false;
|
|
46362
|
-
}
|
|
46363
|
-
});
|
|
46364
|
-
if (hasFastRefresh) return true;
|
|
46365
|
-
}
|
|
46366
|
-
return false;
|
|
46367
|
-
};
|
|
46368
|
-
const hasStorybookReactViteIntegration = (packageDirectory, manifest) => hasOwnedDevelopmentCommand(manifest, /(?:^|\s)(?:storybook\s+dev|start-storybook)(?:\s|$)/) && hasStorybookReactViteConfig(packageDirectory);
|
|
46369
|
-
const hasStorybookReactWebpackFastRefreshIntegration = (packageDirectory, manifest) => {
|
|
46370
|
-
const developmentCommandPattern = /(?:^|\s)(?:storybook\s+dev|start-storybook)(?:\s|$)/;
|
|
46371
|
-
if (!hasOwnedDevelopmentCommand(manifest, developmentCommandPattern)) return false;
|
|
46372
|
-
return isVersionAtLeast(getOwnedDependencyVersion(manifest, "@storybook/react", developmentCommandPattern) ?? getOwnedDependencyVersion(manifest, "@storybook/react-webpack5", developmentCommandPattern), MINIMUM_FAST_REFRESH_VERSIONS.storybookReact) && hasStorybookReactWebpackFastRefreshConfig(packageDirectory);
|
|
46373
|
-
};
|
|
46374
|
-
const hasNxStorybookReactViteIntegration = (packageDirectory) => {
|
|
46375
|
-
if (!hasStorybookReactViteConfig(packageDirectory)) return false;
|
|
46376
|
-
try {
|
|
46377
|
-
const project = JSON.parse(fs.readFileSync(path.join(packageDirectory, "project.json"), "utf8"));
|
|
46378
|
-
if (typeof project !== "object" || project === null) return false;
|
|
46379
|
-
const targets = Reflect.get(project, "targets");
|
|
46380
|
-
if (typeof targets !== "object" || targets === null) return false;
|
|
46381
|
-
return Object.keys(targets).some((targetName) => targetName === "storybook:serve:dev");
|
|
46382
|
-
} catch {
|
|
46383
|
-
return false;
|
|
46384
|
-
}
|
|
46385
|
-
};
|
|
46386
|
-
const getLocalFastRefreshStatus = (packageDirectory, manifest) => {
|
|
46387
|
-
const cachedStatus = cachedLocalStatusByManifest.get(manifest);
|
|
46388
|
-
if (cachedStatus) return cachedStatus;
|
|
46389
|
-
const status = getBuiltInStatus(manifest) ?? (hasStorybookReactViteIntegration(packageDirectory, manifest) || hasNxStorybookReactViteIntegration(packageDirectory) || hasStorybookReactWebpackFastRefreshIntegration(packageDirectory, manifest) ? {
|
|
46390
|
-
isActive: true,
|
|
46391
|
-
runtime: "generic"
|
|
46392
|
-
} : null) ?? getRegisteredIntegration(packageDirectory, manifest) ?? INACTIVE_STATUS;
|
|
46393
|
-
cachedLocalStatusByManifest.set(manifest, status);
|
|
46394
|
-
return status;
|
|
46395
|
-
};
|
|
46396
|
-
const isWorkspaceRoot = (directory, manifest) => {
|
|
46397
|
-
if (manifest?.workspaces !== void 0) return true;
|
|
46398
|
-
return [
|
|
46399
|
-
"pnpm-workspace.yaml",
|
|
46400
|
-
"pnpm-workspace.yml",
|
|
46401
|
-
"nx.json"
|
|
46402
|
-
].some((filename) => fs.existsSync(path.join(directory, filename)));
|
|
46403
|
-
};
|
|
46404
|
-
const findWorkspaceRoot = (packageDirectory) => {
|
|
46405
|
-
let currentDirectory = packageDirectory;
|
|
46406
|
-
let workspaceRoot = null;
|
|
46407
|
-
while (true) {
|
|
46408
|
-
const manifest = readPackageManifest(currentDirectory);
|
|
46409
|
-
if (isWorkspaceRoot(currentDirectory, manifest)) workspaceRoot = currentDirectory;
|
|
46410
|
-
const parentDirectory = path.dirname(currentDirectory);
|
|
46411
|
-
if (parentDirectory === currentDirectory) return workspaceRoot;
|
|
46412
|
-
currentDirectory = parentDirectory;
|
|
46413
|
-
}
|
|
46414
|
-
};
|
|
46415
|
-
const collectWorkspacePackages = (workspaceRoot) => {
|
|
46416
|
-
const packages = [];
|
|
46417
|
-
const pendingDirectories = [workspaceRoot];
|
|
46418
|
-
while (pendingDirectories.length > 0) {
|
|
46419
|
-
const directory = pendingDirectories.pop();
|
|
46420
|
-
if (!directory) continue;
|
|
46421
|
-
const manifest = readPackageManifest(directory);
|
|
46422
|
-
if (manifest) packages.push({
|
|
46423
|
-
directory,
|
|
46424
|
-
manifest,
|
|
46425
|
-
status: getLocalFastRefreshStatus(directory, manifest)
|
|
46426
|
-
});
|
|
46427
|
-
let entries;
|
|
46428
|
-
try {
|
|
46429
|
-
entries = fs.readdirSync(directory, { withFileTypes: true });
|
|
46430
|
-
} catch {
|
|
46431
|
-
continue;
|
|
46432
|
-
}
|
|
46433
|
-
for (const entry of entries) {
|
|
46434
|
-
if (!entry.isDirectory()) continue;
|
|
46435
|
-
if (entry.name.startsWith(".") || WORKSPACE_IGNORED_DIRECTORY_NAMES.has(entry.name)) continue;
|
|
46436
|
-
pendingDirectories.push(path.join(directory, entry.name));
|
|
46437
|
-
}
|
|
46438
|
-
}
|
|
46439
|
-
return packages;
|
|
46440
|
-
};
|
|
46441
|
-
const isPropertyNamed = (node, name) => isNodeOfType(node, "Property") && (isNodeOfType(node.key, "Identifier") && node.key.name === name || isNodeOfType(node.key, "Literal") && node.key.value === name);
|
|
46442
|
-
const normalizeAliasRoot = (configDirectory, aliasPath) => {
|
|
46443
|
-
if (!aliasPath.startsWith(".") && !path.isAbsolute(aliasPath)) return null;
|
|
46444
|
-
const withoutPlaceholder = aliasPath.replace(/(?:\/)?(?:\*|\$\d+).*$/, "");
|
|
46445
|
-
return path.resolve(configDirectory, withoutPlaceholder);
|
|
46446
|
-
};
|
|
46447
|
-
const collectAliasRootsFromValue = (value, configDirectory, aliasRoots) => {
|
|
46448
|
-
walkAst(value, (node) => {
|
|
46449
|
-
if (!isPropertyNamed(node, "alias")) return;
|
|
46450
|
-
if (!isNodeOfType(node, "Property")) return;
|
|
46451
|
-
walkAst(node.value, (aliasNode) => {
|
|
46452
|
-
if (!isNodeOfType(aliasNode, "Literal") || typeof aliasNode.value !== "string") return;
|
|
46453
|
-
const aliasRoot = normalizeAliasRoot(configDirectory, aliasNode.value);
|
|
46454
|
-
if (aliasRoot) aliasRoots.add(aliasRoot);
|
|
46455
|
-
});
|
|
46456
|
-
return false;
|
|
46457
|
-
});
|
|
46458
|
-
};
|
|
46459
|
-
const getActivePackageAliasRoots = (packageDirectory, manifest) => {
|
|
46460
|
-
const aliasRoots = /* @__PURE__ */ new Set();
|
|
46461
|
-
const configPaths = [...getExplicitConfigPaths(packageDirectory, manifest), ...[
|
|
46462
|
-
"main.ts",
|
|
46463
|
-
"main.js",
|
|
46464
|
-
"main.mjs",
|
|
46465
|
-
"main.cjs"
|
|
46466
|
-
].map((filename) => path.join(packageDirectory, ".storybook", filename))];
|
|
46467
|
-
for (const configPath of configPaths) {
|
|
46468
|
-
const program = parseSourceFile(configPath);
|
|
46469
|
-
if (!program) continue;
|
|
46470
|
-
const scopes = analyzeScopes(program);
|
|
46471
|
-
const exportedBindings = getExportedBindings(program, scopes);
|
|
46472
|
-
walkAst(program, (node) => {
|
|
46473
|
-
if (!isPropertyNamed(node, "resolve") && !isPropertyNamed(node, "viteFinal")) return;
|
|
46474
|
-
if (!isNodeOfType(node, "Property")) return;
|
|
46475
|
-
if (!isExportedConfigProperty(node, exportedBindings, scopes)) return;
|
|
46476
|
-
collectAliasRootsFromValue(node.value, path.dirname(configPath), aliasRoots);
|
|
46477
|
-
return false;
|
|
46478
|
-
});
|
|
46479
|
-
}
|
|
46480
|
-
return aliasRoots;
|
|
46481
|
-
};
|
|
46482
|
-
const collectStringValues = (value, values) => {
|
|
46483
|
-
if (typeof value === "string") {
|
|
46484
|
-
values.push(value);
|
|
46485
|
-
return;
|
|
46486
|
-
}
|
|
46487
|
-
if (Array.isArray(value)) {
|
|
46488
|
-
for (const entry of value) collectStringValues(entry, values);
|
|
46489
|
-
return;
|
|
46490
|
-
}
|
|
46491
|
-
if (typeof value !== "object" || value === null) return;
|
|
46492
|
-
for (const entry of Object.values(value)) collectStringValues(entry, values);
|
|
46493
|
-
};
|
|
46494
|
-
const hasSourceRuntimeEntry = (manifest) => {
|
|
46495
|
-
const entryValues = [];
|
|
46496
|
-
collectStringValues(manifest.exports, entryValues);
|
|
46497
|
-
collectStringValues(manifest.main, entryValues);
|
|
46498
|
-
collectStringValues(manifest.module, entryValues);
|
|
46499
|
-
return entryValues.some((entry) => /^\.\/?src(?:\/|\.|$)/.test(entry));
|
|
46500
|
-
};
|
|
46501
|
-
const getWorkspaceDependencyVersion = (manifest, dependencyName) => manifest.dependencies?.[dependencyName] ?? manifest.optionalDependencies?.[dependencyName];
|
|
46502
|
-
const buildWorkspaceFastRefreshIndex = (workspaceRoot, rootManifest) => {
|
|
46503
|
-
const cached = cachedWorkspaceIndexByManifest.get(rootManifest);
|
|
46504
|
-
if (cached) return cached;
|
|
46505
|
-
const workspacePackages = collectWorkspacePackages(workspaceRoot);
|
|
46506
|
-
const activePackages = workspacePackages.filter((workspacePackage) => workspacePackage.status.isActive);
|
|
46507
|
-
const aliasOwners = [];
|
|
46508
|
-
for (const activePackage of activePackages) for (const rootDirectory of getActivePackageAliasRoots(activePackage.directory, activePackage.manifest)) aliasOwners.push({
|
|
46509
|
-
rootDirectory,
|
|
46510
|
-
status: activePackage.status
|
|
46511
|
-
});
|
|
46512
|
-
const sourceEntryOwners = /* @__PURE__ */ new Map();
|
|
46513
|
-
for (const producerPackage of workspacePackages) {
|
|
46514
|
-
const packageName = producerPackage.manifest.name;
|
|
46515
|
-
if (typeof packageName !== "string" || !hasSourceRuntimeEntry(producerPackage.manifest)) continue;
|
|
46516
|
-
const owner = activePackages.find((activePackage) => {
|
|
46517
|
-
const dependencyVersion = getWorkspaceDependencyVersion(activePackage.manifest, packageName);
|
|
46518
|
-
return typeof dependencyVersion === "string" && dependencyVersion.startsWith("workspace:");
|
|
46519
|
-
});
|
|
46520
|
-
if (owner) sourceEntryOwners.set(producerPackage.directory, owner.status);
|
|
46521
|
-
}
|
|
46522
|
-
const index = {
|
|
46523
|
-
aliasOwners,
|
|
46524
|
-
sourceEntryOwners
|
|
46525
|
-
};
|
|
46526
|
-
cachedWorkspaceIndexByManifest.set(rootManifest, index);
|
|
46527
|
-
return index;
|
|
46528
|
-
};
|
|
46529
|
-
const isPathInside = (filePath, directory) => {
|
|
46530
|
-
const relativePath = path.relative(directory, filePath);
|
|
46531
|
-
return relativePath === "" || !relativePath.startsWith(`..${path.sep}`) && relativePath !== ".." && !path.isAbsolute(relativePath);
|
|
46532
|
-
};
|
|
46533
|
-
const getWorkspaceOwnedStatus = (filename, packageDirectory) => {
|
|
46534
|
-
const workspaceRoot = findWorkspaceRoot(packageDirectory);
|
|
46535
|
-
if (!workspaceRoot) return null;
|
|
46536
|
-
const rootManifest = readPackageManifest(workspaceRoot);
|
|
46537
|
-
if (!rootManifest) return null;
|
|
46538
|
-
const index = buildWorkspaceFastRefreshIndex(workspaceRoot, rootManifest);
|
|
46539
|
-
const aliasOwner = index.aliasOwners.find((owner) => isPathInside(filename, owner.rootDirectory));
|
|
46540
|
-
if (aliasOwner) return aliasOwner.status;
|
|
46541
|
-
for (const [producerDirectory, status] of index.sourceEntryOwners) if (isPathInside(filename, producerDirectory)) return status;
|
|
46542
|
-
return null;
|
|
46543
|
-
};
|
|
46544
|
-
const resolveFastRefreshFileStatus = (filename) => {
|
|
46545
|
-
const manifest = readNearestPackageManifest(filename);
|
|
46546
|
-
if (!manifest) return INACTIVE_STATUS;
|
|
46547
|
-
const packageDirectory = findNearestPackageDirectory(filename);
|
|
46548
|
-
if (!packageDirectory) return INACTIVE_STATUS;
|
|
46549
|
-
const localStatus = getLocalFastRefreshStatus(packageDirectory, manifest);
|
|
46550
|
-
if (localStatus.isActive) return localStatus;
|
|
46551
|
-
return getWorkspaceOwnedStatus(filename, packageDirectory) ?? INACTIVE_STATUS;
|
|
46552
|
-
};
|
|
46553
|
-
const getConfiguredFallbackStatus = (context) => {
|
|
46554
|
-
const framework = getReactDoctorStringSetting(context.settings, "framework");
|
|
46555
|
-
return {
|
|
46556
|
-
isActive: true,
|
|
46557
|
-
runtime: framework === "nextjs" ? "next" : framework === "expo" || framework === "react-native" ? "expo" : framework === "remix" ? "remix" : framework === "tanstack-start" ? "tanstack" : "generic"
|
|
46558
|
-
};
|
|
46559
|
-
};
|
|
46560
|
-
const getFastRefreshFileStatus = (context) => {
|
|
46561
|
-
let filename = context.filename;
|
|
46562
|
-
if (!filename) return getConfiguredFallbackStatus(context);
|
|
46563
|
-
if (!path.isAbsolute(filename)) {
|
|
46564
|
-
const absoluteFilename = path.resolve(filename);
|
|
46565
|
-
if (!fs.existsSync(absoluteFilename)) return getConfiguredFallbackStatus(context);
|
|
46566
|
-
filename = absoluteFilename;
|
|
46567
|
-
}
|
|
46568
|
-
if (!readNearestPackageManifest(filename)) return INACTIVE_STATUS;
|
|
46569
|
-
return resolveFastRefreshFileStatus(filename);
|
|
45759
|
+
return FRAMEWORK_ROUTE_FILE_PATTERNS.some((pattern) => pattern.test(basename));
|
|
46570
45760
|
};
|
|
46571
45761
|
//#endregion
|
|
46572
45762
|
//#region src/plugin/rules/react-builtins/only-export-components-tables.ts
|
|
@@ -46578,7 +45768,6 @@ const NOT_REACT_COMPONENT_EXPRESSION_TYPES = new Set([
|
|
|
46578
45768
|
"ConditionalExpression",
|
|
46579
45769
|
"Literal",
|
|
46580
45770
|
"LogicalExpression",
|
|
46581
|
-
"NewExpression",
|
|
46582
45771
|
"ObjectExpression",
|
|
46583
45772
|
"TemplateLiteral",
|
|
46584
45773
|
"ThisExpression",
|
|
@@ -46597,25 +45786,124 @@ const NON_FAST_REFRESH_PATH_SEGMENTS = [
|
|
|
46597
45786
|
"/cypress/",
|
|
46598
45787
|
"/.storybook/",
|
|
46599
45788
|
"/stories/",
|
|
46600
|
-
"/__stories__/"
|
|
45789
|
+
"/__stories__/",
|
|
45790
|
+
"/playground/",
|
|
45791
|
+
"/playgrounds/",
|
|
45792
|
+
"/examples/",
|
|
45793
|
+
"/example/",
|
|
45794
|
+
"/demo/",
|
|
45795
|
+
"/demos/",
|
|
45796
|
+
"/sandbox/",
|
|
45797
|
+
"/sandboxes/"
|
|
46601
45798
|
];
|
|
46602
|
-
const
|
|
45799
|
+
const ENTRY_POINT_BASENAMES = new Set([
|
|
45800
|
+
"main.tsx",
|
|
45801
|
+
"main.jsx",
|
|
45802
|
+
"main.js",
|
|
45803
|
+
"index.tsx",
|
|
45804
|
+
"index.jsx",
|
|
45805
|
+
"entry.tsx",
|
|
45806
|
+
"entry.jsx",
|
|
45807
|
+
"bootstrap.tsx",
|
|
45808
|
+
"bootstrap.jsx",
|
|
45809
|
+
"client.tsx",
|
|
45810
|
+
"client.jsx",
|
|
45811
|
+
"server.tsx",
|
|
45812
|
+
"server.jsx",
|
|
45813
|
+
"app.tsx",
|
|
45814
|
+
"app.jsx",
|
|
45815
|
+
"App.tsx",
|
|
45816
|
+
"App.jsx"
|
|
45817
|
+
]);
|
|
45818
|
+
const UTILITY_FILE_BASENAMES = new Set([
|
|
45819
|
+
"utils.tsx",
|
|
45820
|
+
"utils.jsx",
|
|
45821
|
+
"util.tsx",
|
|
45822
|
+
"util.jsx",
|
|
45823
|
+
"helpers.tsx",
|
|
45824
|
+
"helpers.jsx",
|
|
45825
|
+
"helper.tsx",
|
|
45826
|
+
"helper.jsx",
|
|
45827
|
+
"shared.tsx",
|
|
45828
|
+
"shared.jsx",
|
|
45829
|
+
"common.tsx",
|
|
45830
|
+
"common.jsx",
|
|
45831
|
+
"lib.tsx",
|
|
45832
|
+
"lib.jsx",
|
|
45833
|
+
"nodeTypes.tsx",
|
|
45834
|
+
"nodeTypes.jsx",
|
|
45835
|
+
"node-types.tsx",
|
|
45836
|
+
"node-types.jsx",
|
|
45837
|
+
"edgeTypes.tsx",
|
|
45838
|
+
"edgeTypes.jsx",
|
|
45839
|
+
"edge-types.tsx",
|
|
45840
|
+
"edge-types.jsx",
|
|
45841
|
+
"cellTypes.tsx",
|
|
45842
|
+
"cellTypes.jsx",
|
|
45843
|
+
"columnTypes.tsx",
|
|
45844
|
+
"columnTypes.jsx",
|
|
45845
|
+
"columnDefs.tsx",
|
|
45846
|
+
"columnDefs.jsx",
|
|
45847
|
+
"columnRenderers.tsx",
|
|
45848
|
+
"columnRenderers.jsx",
|
|
45849
|
+
"columns.tsx",
|
|
45850
|
+
"columns.jsx",
|
|
45851
|
+
"mappings.tsx",
|
|
45852
|
+
"mappings.jsx",
|
|
45853
|
+
"mapping.tsx",
|
|
45854
|
+
"mapping.jsx",
|
|
45855
|
+
"lookups.tsx",
|
|
45856
|
+
"lookups.jsx",
|
|
45857
|
+
"lookup.tsx",
|
|
45858
|
+
"lookup.jsx",
|
|
45859
|
+
"registry.tsx",
|
|
45860
|
+
"registry.jsx",
|
|
45861
|
+
"toast.tsx",
|
|
45862
|
+
"toast.jsx",
|
|
45863
|
+
"toaster.tsx",
|
|
45864
|
+
"toaster.jsx",
|
|
45865
|
+
"theme.tsx",
|
|
45866
|
+
"theme.jsx",
|
|
45867
|
+
"tokens.tsx",
|
|
45868
|
+
"tokens.jsx",
|
|
45869
|
+
"palette.tsx",
|
|
45870
|
+
"palette.jsx",
|
|
45871
|
+
"colors.tsx",
|
|
45872
|
+
"colors.jsx",
|
|
45873
|
+
"colours.tsx",
|
|
45874
|
+
"colours.jsx",
|
|
45875
|
+
"constants.tsx",
|
|
45876
|
+
"constants.jsx",
|
|
45877
|
+
"enums.tsx",
|
|
45878
|
+
"enums.jsx",
|
|
45879
|
+
"types.tsx",
|
|
45880
|
+
"types.jsx",
|
|
45881
|
+
"schemas.tsx",
|
|
45882
|
+
"schemas.jsx",
|
|
45883
|
+
"schema.tsx",
|
|
45884
|
+
"schema.jsx",
|
|
45885
|
+
"definitions.tsx",
|
|
45886
|
+
"definitions.jsx",
|
|
45887
|
+
"config.tsx",
|
|
45888
|
+
"config.jsx",
|
|
45889
|
+
"defaults.tsx",
|
|
45890
|
+
"defaults.jsx"
|
|
45891
|
+
]);
|
|
45892
|
+
const ROUTE_FACTORY_CALLEE_NAMES = new Set([
|
|
46603
45893
|
...TANSTACK_ROUTE_CREATION_FUNCTIONS,
|
|
46604
45894
|
"createLazyFileRoute",
|
|
46605
45895
|
"createLazyRoute",
|
|
46606
45896
|
"createAPIFileRoute",
|
|
46607
45897
|
"createServerFileRoute",
|
|
46608
45898
|
"createServerRootRoute",
|
|
46609
|
-
"createServerRoute"
|
|
46610
|
-
]);
|
|
46611
|
-
const REACT_ROUTER_FACTORY_CALLEE_NAMES = new Set([
|
|
45899
|
+
"createServerRoute",
|
|
46612
45900
|
"createBrowserRouter",
|
|
46613
45901
|
"createHashRouter",
|
|
46614
45902
|
"createMemoryRouter",
|
|
46615
45903
|
"createStaticRouter",
|
|
46616
45904
|
"createRouter"
|
|
46617
45905
|
]);
|
|
46618
|
-
const
|
|
45906
|
+
const ROUTE_MODULE_ALLOWED_EXPORT_NAMES = new Set([
|
|
46619
45907
|
"loader",
|
|
46620
45908
|
"clientLoader",
|
|
46621
45909
|
"action",
|
|
@@ -46626,9 +45914,7 @@ const REACT_ROUTER_ALLOWED_EXPORT_NAMES = new Set([
|
|
|
46626
45914
|
"handle",
|
|
46627
45915
|
"shouldRevalidate",
|
|
46628
45916
|
"middleware",
|
|
46629
|
-
"unstable_middleware"
|
|
46630
|
-
]);
|
|
46631
|
-
const NEXT_ALLOWED_EXPORT_NAMES = new Set([
|
|
45917
|
+
"unstable_middleware",
|
|
46632
45918
|
"getServerSideProps",
|
|
46633
45919
|
"getStaticProps",
|
|
46634
45920
|
"getStaticPaths",
|
|
@@ -46648,9 +45934,9 @@ const NEXT_ALLOWED_EXPORT_NAMES = new Set([
|
|
|
46648
45934
|
"runtime",
|
|
46649
45935
|
"preferredRegion",
|
|
46650
45936
|
"maxDuration",
|
|
46651
|
-
"experimental_ppr"
|
|
45937
|
+
"experimental_ppr",
|
|
45938
|
+
"unstable_settings"
|
|
46652
45939
|
]);
|
|
46653
|
-
const EXPO_ALLOWED_EXPORT_NAMES = new Set(["unstable_settings"]);
|
|
46654
45940
|
//#endregion
|
|
46655
45941
|
//#region src/plugin/rules/react-builtins/only-export-components.ts
|
|
46656
45942
|
const NAMED_EXPORT_MESSAGE = "This file exports non-components, so Fast Refresh can't safely preserve component state.";
|
|
@@ -46663,8 +45949,6 @@ const DEFAULT_REACT_HOCS = [
|
|
|
46663
45949
|
"forwardRef",
|
|
46664
45950
|
"lazy"
|
|
46665
45951
|
];
|
|
46666
|
-
const EMPTY_NAME_SET = /* @__PURE__ */ new Set();
|
|
46667
|
-
const TEST_SUPPORT_FILE_PATTERN = /(?:^|\/)(?:test|spec)(?:[-_.]?(?:utils?|helpers?|setup|fixtures?))?\.(?:jsx?|tsx?)$/i;
|
|
46668
45952
|
const resolveSettings$6 = (settings) => {
|
|
46669
45953
|
const reactDoctor = settings?.["react-doctor"];
|
|
46670
45954
|
const ruleSettings = typeof reactDoctor === "object" && reactDoctor !== null ? reactDoctor.onlyExportComponents ?? {} : {};
|
|
@@ -46688,12 +45972,13 @@ const isReactCreateContext = (initializer) => {
|
|
|
46688
45972
|
if (isNodeOfType(callee, "MemberExpression") && isNodeOfType(callee.property, "Identifier") && callee.property.name === "createContext") return true;
|
|
46689
45973
|
return false;
|
|
46690
45974
|
};
|
|
46691
|
-
const
|
|
45975
|
+
const isRouteFactoryName = (name) => ROUTE_FACTORY_CALLEE_NAMES.has(name);
|
|
45976
|
+
const isRouteFactoryCall = (expression) => {
|
|
46692
45977
|
let currentCall = expression;
|
|
46693
45978
|
while (isNodeOfType(currentCall, "CallExpression")) {
|
|
46694
45979
|
const callee = currentCall.callee;
|
|
46695
|
-
if (isNodeOfType(callee, "Identifier") &&
|
|
46696
|
-
if (isNodeOfType(callee, "MemberExpression") && isNodeOfType(callee.
|
|
45980
|
+
if (isNodeOfType(callee, "Identifier") && isRouteFactoryName(callee.name)) return true;
|
|
45981
|
+
if (isNodeOfType(callee, "MemberExpression") && isNodeOfType(callee.property, "Identifier") && isRouteFactoryName(callee.property.name)) return true;
|
|
46697
45982
|
if (!isNodeOfType(callee, "CallExpression")) return false;
|
|
46698
45983
|
currentCall = callee;
|
|
46699
45984
|
}
|
|
@@ -46721,11 +46006,10 @@ const isHocCallee = (callee, state) => {
|
|
|
46721
46006
|
const canBeReactFunctionComponent = (initializer, state) => {
|
|
46722
46007
|
if (!initializer) return false;
|
|
46723
46008
|
const expression = skipTsExpression(initializer);
|
|
46724
|
-
if (isNodeOfType(expression, "ArrowFunctionExpression") || isNodeOfType(expression, "FunctionExpression")) return
|
|
46009
|
+
if (isNodeOfType(expression, "ArrowFunctionExpression") || isNodeOfType(expression, "FunctionExpression")) return true;
|
|
46725
46010
|
if (isNodeOfType(expression, "CallExpression")) return isHocCallee(expression.callee, state);
|
|
46726
46011
|
return false;
|
|
46727
46012
|
};
|
|
46728
|
-
const functionHasReactRenderSemantics = (functionNode, state) => functionContainsReactRenderOutput(functionNode, state.scopes, state.controlFlow) || functionHasReactElementReturnType(functionNode) || functionReturnsOnlyNull(functionNode);
|
|
46729
46013
|
const isReactComponentInitializer = (expression, state) => {
|
|
46730
46014
|
const stripped = skipTsExpression(expression);
|
|
46731
46015
|
if (isNodeOfType(stripped, "ArrowFunctionExpression")) return true;
|
|
@@ -46734,60 +46018,6 @@ const isReactComponentInitializer = (expression, state) => {
|
|
|
46734
46018
|
if (isNodeOfType(stripped, "CallExpression") && isHocCallee(stripped.callee, state) && stripped.arguments.length > 0) return true;
|
|
46735
46019
|
return false;
|
|
46736
46020
|
};
|
|
46737
|
-
const isNextDynamicCall = (expression, nextDynamicImportSymbolIds, scopes) => {
|
|
46738
|
-
const stripped = skipTsExpression(expression);
|
|
46739
|
-
if (!isNodeOfType(stripped, "CallExpression")) return false;
|
|
46740
|
-
const callee = skipTsExpression(stripped.callee);
|
|
46741
|
-
if (!isNodeOfType(callee, "Identifier")) return false;
|
|
46742
|
-
const symbol = scopes.symbolFor(callee);
|
|
46743
|
-
return symbol !== null && nextDynamicImportSymbolIds.has(symbol.id);
|
|
46744
|
-
};
|
|
46745
|
-
const functionReturnsNextDynamicComponent = (expression, nextDynamicImportSymbolIds, scopes) => {
|
|
46746
|
-
const stripped = skipTsExpression(expression);
|
|
46747
|
-
if (!isNodeOfType(stripped, "ArrowFunctionExpression") && !isNodeOfType(stripped, "FunctionExpression") && !isNodeOfType(stripped, "FunctionDeclaration")) return false;
|
|
46748
|
-
const body = stripped.body;
|
|
46749
|
-
if (!isNodeOfType(body, "BlockStatement")) return isNextDynamicCall(body, nextDynamicImportSymbolIds, scopes);
|
|
46750
|
-
if (body.body.length !== 1) return false;
|
|
46751
|
-
const statement = body.body[0];
|
|
46752
|
-
return Boolean(statement) && isNodeOfType(statement, "ReturnStatement") && Boolean(statement.argument) && isNextDynamicCall(statement.argument, nextDynamicImportSymbolIds, scopes);
|
|
46753
|
-
};
|
|
46754
|
-
const isComponentFactoryCall = (expression, state) => {
|
|
46755
|
-
const stripped = skipTsExpression(expression);
|
|
46756
|
-
if (!isNodeOfType(stripped, "CallExpression")) return false;
|
|
46757
|
-
const callee = skipTsExpression(stripped.callee);
|
|
46758
|
-
if (!isNodeOfType(callee, "Identifier")) return false;
|
|
46759
|
-
const symbol = state.scopes.symbolFor(callee);
|
|
46760
|
-
return symbol !== null && state.componentFactorySymbolIds.has(symbol.id);
|
|
46761
|
-
};
|
|
46762
|
-
const isProvenComponentValue = (expression, state, inspectedSymbolIds = /* @__PURE__ */ new Set()) => {
|
|
46763
|
-
const stripped = skipTsExpression(expression);
|
|
46764
|
-
if (isNodeOfType(stripped, "Identifier")) {
|
|
46765
|
-
const symbol = state.scopes.symbolFor(stripped);
|
|
46766
|
-
if (!symbol) return false;
|
|
46767
|
-
if (state.localComponentNames.has(stripped.name)) return symbol.references.every((reference) => reference.flag === "read");
|
|
46768
|
-
if (isReactComponentName(stripped.name) && symbol.kind === "import") return true;
|
|
46769
|
-
if (inspectedSymbolIds.has(symbol.id)) return false;
|
|
46770
|
-
const initializer = getDirectUnreassignedInitializer(symbol);
|
|
46771
|
-
if (!initializer) return false;
|
|
46772
|
-
const strippedInitializer = skipTsExpression(initializer);
|
|
46773
|
-
if (isNodeOfType(strippedInitializer, "ArrowFunctionExpression") || isNodeOfType(strippedInitializer, "FunctionExpression")) return false;
|
|
46774
|
-
return isProvenComponentValue(initializer, state, new Set([...inspectedSymbolIds, symbol.id]));
|
|
46775
|
-
}
|
|
46776
|
-
if (isNodeOfType(stripped, "MemberExpression") && !stripped.computed && isNodeOfType(stripped.object, "Identifier") && isNodeOfType(stripped.property, "Identifier") && isReactComponentName(stripped.property.name)) {
|
|
46777
|
-
const objectSymbol = state.scopes.symbolFor(stripped.object);
|
|
46778
|
-
return objectSymbol !== null && state.importSymbolIds.has(objectSymbol.id);
|
|
46779
|
-
}
|
|
46780
|
-
if (isNodeOfType(stripped, "ArrowFunctionExpression") || isNodeOfType(stripped, "FunctionExpression")) return functionHasReactRenderSemantics(stripped, state);
|
|
46781
|
-
if (!isNodeOfType(stripped, "CallExpression")) return false;
|
|
46782
|
-
if (!isHocCallee(stripped.callee, state)) return false;
|
|
46783
|
-
return stripped.arguments.some((argument) => isProvenComponentValue(argument, state));
|
|
46784
|
-
};
|
|
46785
|
-
const isDirectRefreshWrapperCall = (call, state) => {
|
|
46786
|
-
const callee = skipTsExpression(call.callee);
|
|
46787
|
-
if (isHocCallee(callee, state)) return call.arguments.length > 0;
|
|
46788
|
-
if (!isNodeOfType(callee, "Identifier") && !isNodeOfType(callee, "MemberExpression")) return false;
|
|
46789
|
-
return call.arguments.some((argument) => isProvenComponentValue(argument, state));
|
|
46790
|
-
};
|
|
46791
46021
|
const objectExpressionBundlesComponents = (objectExpression, state) => {
|
|
46792
46022
|
for (const property of objectExpression.properties ?? []) {
|
|
46793
46023
|
if (!isNodeOfType(property, "Property")) continue;
|
|
@@ -46797,22 +46027,20 @@ const objectExpressionBundlesComponents = (objectExpression, state) => {
|
|
|
46797
46027
|
continue;
|
|
46798
46028
|
}
|
|
46799
46029
|
if (!(!property.computed && isNodeOfType(property.key, "Identifier") && isReactComponentName(property.key.name))) continue;
|
|
46800
|
-
if ((isNodeOfType(value, "ArrowFunctionExpression") || isNodeOfType(value, "FunctionExpression")) &&
|
|
46030
|
+
if ((isNodeOfType(value, "ArrowFunctionExpression") || isNodeOfType(value, "FunctionExpression")) && functionContainsReactRenderOutput(value, state.scopes, state.controlFlow)) return true;
|
|
46801
46031
|
if (isNodeOfType(value, "CallExpression") && isHocCallee(value.callee, state) && value.arguments.length > 0) return true;
|
|
46802
46032
|
}
|
|
46803
46033
|
return false;
|
|
46804
46034
|
};
|
|
46805
46035
|
const classifyExport = (name, reportNode, isFunction, initializer, state) => {
|
|
46806
|
-
if (isNodeOfType(reportNode, "Identifier") && isProvenComponentValue(reportNode, state)) return { kind: "react-component" };
|
|
46807
46036
|
if (initializer) {
|
|
46808
46037
|
const expression = skipTsExpression(initializer);
|
|
46809
|
-
if (
|
|
46810
|
-
if (isRouteFactoryCall(expression, state.routeFactoryBindings)) return { kind: "react-component" };
|
|
46038
|
+
if (isRouteFactoryCall(expression)) return { kind: "react-component" };
|
|
46811
46039
|
if (isNodeOfType(expression, "CallExpression") && isHocCallee(expression.callee, state) && expression.arguments.length > 0 && isReactComponentName(name)) return { kind: "react-component" };
|
|
46812
46040
|
if (isNodeOfType(expression, "ConditionalExpression") && isReactComponentName(name) && isReactComponentInitializer(expression.consequent, state) && isReactComponentInitializer(expression.alternate, state)) return { kind: "react-component" };
|
|
46813
46041
|
}
|
|
46814
46042
|
if (state.allowExportNames.has(name)) return { kind: "allowed" };
|
|
46815
|
-
if (
|
|
46043
|
+
if (ROUTE_MODULE_ALLOWED_EXPORT_NAMES.has(name)) return { kind: "allowed" };
|
|
46816
46044
|
if (/^use[A-Z]/.test(name)) return { kind: "allowed" };
|
|
46817
46045
|
if (state.allowConstantExport && initializer) {
|
|
46818
46046
|
const expression = skipTsExpression(initializer);
|
|
@@ -46838,33 +46066,42 @@ const classifyExport = (name, reportNode, isFunction, initializer, state) => {
|
|
|
46838
46066
|
kind: "namespace-object",
|
|
46839
46067
|
reportNode
|
|
46840
46068
|
};
|
|
46841
|
-
if (isNodeOfType(stripped, "MemberExpression")) return isProvenComponentValue(stripped, state) ? { kind: "react-component" } : {
|
|
46842
|
-
kind: "non-component",
|
|
46843
|
-
reportNode
|
|
46844
|
-
};
|
|
46845
|
-
if (isNodeOfType(stripped, "Identifier")) return isProvenComponentValue(stripped, state) ? { kind: "react-component" } : {
|
|
46846
|
-
kind: "non-component",
|
|
46847
|
-
reportNode
|
|
46848
|
-
};
|
|
46849
46069
|
if (NOT_REACT_COMPONENT_EXPRESSION_TYPES.has(stripped.type)) return {
|
|
46850
46070
|
kind: "non-component",
|
|
46851
46071
|
reportNode
|
|
46852
46072
|
};
|
|
46853
|
-
if (isNodeOfType(stripped, "ArrowFunctionExpression") || isNodeOfType(stripped, "FunctionExpression")) return {
|
|
46854
|
-
kind: "non-component",
|
|
46855
|
-
reportNode
|
|
46856
|
-
};
|
|
46857
46073
|
}
|
|
46858
46074
|
return isReactComponentName(name) ? { kind: "react-component" } : {
|
|
46859
46075
|
kind: "non-component",
|
|
46860
46076
|
reportNode
|
|
46861
46077
|
};
|
|
46862
46078
|
};
|
|
46079
|
+
const isEntryPointFile = (filename) => {
|
|
46080
|
+
const lastSlash = Math.max(filename.lastIndexOf("/"), filename.lastIndexOf("\\"));
|
|
46081
|
+
const basename = lastSlash === -1 ? filename : filename.slice(lastSlash + 1);
|
|
46082
|
+
return ENTRY_POINT_BASENAMES.has(basename);
|
|
46083
|
+
};
|
|
46084
|
+
const ASSET_FILE_BASENAME_PATTERN = /^([A-Za-z][\w-]*[-._])?(icons?|svgs?|svg[-_]?sprites?|sprites?|emojis?|flags?|logos?|lockups?|illustrations?|glyphs?|stickers?|emotes?|avatars?|backgrounds?|patterns?|assets?|gradients?|countryVectors?|paymentVectors?|brandVectors?|brandLogos?)\.(t|j)sx?$/;
|
|
46085
|
+
const UTILITY_BASENAME_SUFFIX_PATTERN = /^[A-Za-z][\w-]*(Utils|Util|Helpers|Helper|Shared|Constants|Constant|Types|Type|Mappings|Mapping|Lookups|Lookup|Registry|Renderers|Renderer|NodeTypes|EdgeTypes|CellTypes|ColumnDefs|ColumnTypes|ColumnRenderers|Schemas|Schema|Definitions|Definition|Config|Configuration|Defaults|Default|Tokens|Palette|Context|Provider|Providers|Logic|Scene|Page|Layout)\.(t|j)sx?$/;
|
|
46086
|
+
const HOOK_FILE_BASENAME_PATTERN = /^use[A-Z][\w-]*\.(t|j)sx?$/;
|
|
46087
|
+
const NODE_DEFINITION_BASENAME_PATTERN = /^[A-Z][\w-]*(NodeUtil|ShapeUtil|EdgeUtil|BindingUtil|InlineNode|BlockNode|NotebookNode)\.(t|j)sx?$/;
|
|
46088
|
+
const isAssetOrUtilityFile = (filename) => {
|
|
46089
|
+
const lastSlash = Math.max(filename.lastIndexOf("/"), filename.lastIndexOf("\\"));
|
|
46090
|
+
const basename = lastSlash === -1 ? filename : filename.slice(lastSlash + 1);
|
|
46091
|
+
if (ASSET_FILE_BASENAME_PATTERN.test(basename)) return true;
|
|
46092
|
+
if (UTILITY_FILE_BASENAMES.has(basename)) return true;
|
|
46093
|
+
if (UTILITY_BASENAME_SUFFIX_PATTERN.test(basename)) return true;
|
|
46094
|
+
if (HOOK_FILE_BASENAME_PATTERN.test(basename)) return true;
|
|
46095
|
+
if (NODE_DEFINITION_BASENAME_PATTERN.test(basename)) return true;
|
|
46096
|
+
return false;
|
|
46097
|
+
};
|
|
46863
46098
|
const isFileNameAllowed = (filename, checkJS) => {
|
|
46864
46099
|
if (!filename) return true;
|
|
46865
|
-
if (TEST_SUPPORT_FILE_PATTERN.test(filename)) return false;
|
|
46866
46100
|
if (filename.includes(".test.") || filename.includes(".spec.") || filename.includes(".cy.") || filename.includes(".stories.")) return false;
|
|
46867
46101
|
for (const segment of NON_FAST_REFRESH_PATH_SEGMENTS) if (filename.includes(segment)) return false;
|
|
46102
|
+
if (isEntryPointFile(filename)) return false;
|
|
46103
|
+
if (isFrameworkRouteOrSpecialFilename(filename)) return false;
|
|
46104
|
+
if (isAssetOrUtilityFile(filename)) return false;
|
|
46868
46105
|
if (filename.endsWith(".tsx") || filename.endsWith(".jsx")) return true;
|
|
46869
46106
|
if (checkJS && filename.endsWith(".js")) return true;
|
|
46870
46107
|
return false;
|
|
@@ -46877,100 +46114,16 @@ const onlyExportComponents = defineRule({
|
|
|
46877
46114
|
category: "Architecture",
|
|
46878
46115
|
create: (context) => {
|
|
46879
46116
|
const settings = resolveSettings$6(context.settings);
|
|
46880
|
-
|
|
46881
|
-
const fastRefreshStatus = getFastRefreshFileStatus(context);
|
|
46882
|
-
if (!fastRefreshStatus.isActive) return {};
|
|
46883
|
-
if (isFrameworkRouteOrSpecialFilename(context, fastRefreshStatus.runtime)) return {};
|
|
46884
|
-
if (!isFileNameAllowed(filename, settings.checkJS)) return {};
|
|
46885
|
-
const allowedRouteExportNames = fastRefreshStatus.runtime === "next" ? NEXT_ALLOWED_EXPORT_NAMES : fastRefreshStatus.runtime === "expo" ? EXPO_ALLOWED_EXPORT_NAMES : fastRefreshStatus.runtime === "react-router" || fastRefreshStatus.runtime === "remix" ? REACT_ROUTER_ALLOWED_EXPORT_NAMES : EMPTY_NAME_SET;
|
|
46886
|
-
const routeFactoryMemberNames = fastRefreshStatus.runtime === "tanstack" ? TANSTACK_ROUTE_FACTORY_CALLEE_NAMES : fastRefreshStatus.runtime === "react-router" || fastRefreshStatus.runtime === "remix" ? REACT_ROUTER_FACTORY_CALLEE_NAMES : EMPTY_NAME_SET;
|
|
46887
|
-
const routeFactoryLocalNames = /* @__PURE__ */ new Set();
|
|
46888
|
-
const routeFactoryNamespaceNames = /* @__PURE__ */ new Set();
|
|
46889
|
-
const nextDynamicImportSymbolIds = /* @__PURE__ */ new Set();
|
|
46890
|
-
const importSymbolIds = /* @__PURE__ */ new Set();
|
|
46891
|
-
const routeFactoryBindings = {
|
|
46892
|
-
localNames: routeFactoryLocalNames,
|
|
46893
|
-
memberNames: routeFactoryMemberNames,
|
|
46894
|
-
namespaceNames: routeFactoryNamespaceNames
|
|
46895
|
-
};
|
|
46117
|
+
if (!isFileNameAllowed(normalizeFilename(context.filename ?? ""), settings.checkJS)) return {};
|
|
46896
46118
|
const exportNodes = [];
|
|
46897
46119
|
const componentCandidates = [];
|
|
46898
|
-
const createRootNames = /* @__PURE__ */ new Set();
|
|
46899
|
-
const hydrateRootNames = /* @__PURE__ */ new Set();
|
|
46900
|
-
const legacyRenderNames = /* @__PURE__ */ new Set();
|
|
46901
|
-
const reactDomNamespaceNames = /* @__PURE__ */ new Set();
|
|
46902
|
-
const rootNames = /* @__PURE__ */ new Set();
|
|
46903
|
-
let hasRootMount = false;
|
|
46904
|
-
const isCreateRootCall = (node) => {
|
|
46905
|
-
if (!isNodeOfType(node, "CallExpression")) return false;
|
|
46906
|
-
if (isNodeOfType(node.callee, "Identifier")) return createRootNames.has(node.callee.name);
|
|
46907
|
-
return isNodeOfType(node.callee, "MemberExpression") && isNodeOfType(node.callee.object, "Identifier") && reactDomNamespaceNames.has(node.callee.object.name) && isNodeOfType(node.callee.property, "Identifier") && node.callee.property.name === "createRoot";
|
|
46908
|
-
};
|
|
46909
|
-
const visitImportDeclaration = (node) => {
|
|
46910
|
-
if (!isNodeOfType(node, "ImportDeclaration")) return;
|
|
46911
|
-
const source = node.source.value;
|
|
46912
|
-
for (const specifier of node.specifiers) {
|
|
46913
|
-
const symbol = context.scopes.symbolFor(specifier.local);
|
|
46914
|
-
if (symbol) importSymbolIds.add(symbol.id);
|
|
46915
|
-
}
|
|
46916
|
-
if (typeof source === "string" && (fastRefreshStatus.runtime === "tanstack" && (source.startsWith("@tanstack/react-router") || source.startsWith("@tanstack/react-start")) || (fastRefreshStatus.runtime === "react-router" || fastRefreshStatus.runtime === "remix") && (source === "react-router" || source === "react-router-dom" || source === "@remix-run/react"))) for (const specifier of node.specifiers) {
|
|
46917
|
-
if (isNodeOfType(specifier, "ImportNamespaceSpecifier")) {
|
|
46918
|
-
routeFactoryNamespaceNames.add(specifier.local.name);
|
|
46919
|
-
continue;
|
|
46920
|
-
}
|
|
46921
|
-
const importedName = getImportedName(specifier);
|
|
46922
|
-
if (importedName && routeFactoryMemberNames.has(importedName)) routeFactoryLocalNames.add(specifier.local.name);
|
|
46923
|
-
}
|
|
46924
|
-
if (source === "next/dynamic") for (const specifier of node.specifiers) {
|
|
46925
|
-
if (!isNodeOfType(specifier, "ImportDefaultSpecifier")) continue;
|
|
46926
|
-
const symbol = context.scopes.symbolFor(specifier.local);
|
|
46927
|
-
if (symbol) nextDynamicImportSymbolIds.add(symbol.id);
|
|
46928
|
-
}
|
|
46929
|
-
if (source !== "react-dom" && source !== "react-dom/client") return;
|
|
46930
|
-
for (const specifier of node.specifiers) {
|
|
46931
|
-
if (isNodeOfType(specifier, "ImportDefaultSpecifier") || isNodeOfType(specifier, "ImportNamespaceSpecifier")) {
|
|
46932
|
-
reactDomNamespaceNames.add(specifier.local.name);
|
|
46933
|
-
continue;
|
|
46934
|
-
}
|
|
46935
|
-
const importedName = getImportedName(specifier);
|
|
46936
|
-
if (importedName === "createRoot") createRootNames.add(specifier.local.name);
|
|
46937
|
-
if (importedName === "hydrateRoot") hydrateRootNames.add(specifier.local.name);
|
|
46938
|
-
if (source === "react-dom" && (importedName === "render" || importedName === "hydrate")) legacyRenderNames.add(specifier.local.name);
|
|
46939
|
-
}
|
|
46940
|
-
};
|
|
46941
|
-
const visitCallExpression = (node) => {
|
|
46942
|
-
if (!isNodeOfType(node, "CallExpression")) return;
|
|
46943
|
-
if (isInsideFunctionScope(node)) return;
|
|
46944
|
-
if (isNodeOfType(node.callee, "Identifier")) {
|
|
46945
|
-
if (hydrateRootNames.has(node.callee.name) || legacyRenderNames.has(node.callee.name)) hasRootMount = true;
|
|
46946
|
-
return;
|
|
46947
|
-
}
|
|
46948
|
-
if (!isNodeOfType(node.callee, "MemberExpression") || !isNodeOfType(node.callee.property, "Identifier")) return;
|
|
46949
|
-
const methodName = node.callee.property.name;
|
|
46950
|
-
if (isNodeOfType(node.callee.object, "Identifier") && reactDomNamespaceNames.has(node.callee.object.name) && (methodName === "render" || methodName === "hydrate" || methodName === "hydrateRoot")) {
|
|
46951
|
-
hasRootMount = true;
|
|
46952
|
-
return;
|
|
46953
|
-
}
|
|
46954
|
-
if (methodName !== "render") return;
|
|
46955
|
-
if (isCreateRootCall(node.callee.object)) {
|
|
46956
|
-
hasRootMount = true;
|
|
46957
|
-
return;
|
|
46958
|
-
}
|
|
46959
|
-
if (isNodeOfType(node.callee.object, "Identifier") && rootNames.has(node.callee.object.name)) hasRootMount = true;
|
|
46960
|
-
};
|
|
46961
46120
|
const pushExportNode = (node) => {
|
|
46962
46121
|
exportNodes.push(node);
|
|
46963
46122
|
};
|
|
46964
46123
|
const pushComponentCandidate = (node) => {
|
|
46965
46124
|
componentCandidates.push(node);
|
|
46966
|
-
if (isNodeOfType(node, "VariableDeclarator") && isNodeOfType(node.id, "Identifier") && node.init && isCreateRootCall(node.init) && !isInsideFunctionScope(node)) rootNames.add(node.id.name);
|
|
46967
46125
|
};
|
|
46968
46126
|
return {
|
|
46969
|
-
ImportDeclaration: visitImportDeclaration,
|
|
46970
|
-
CallExpression: visitCallExpression,
|
|
46971
|
-
AssignmentExpression(node) {
|
|
46972
|
-
if (isNodeOfType(node.left, "Identifier") && rootNames.has(node.left.name)) rootNames.delete(node.left.name);
|
|
46973
|
-
},
|
|
46974
46127
|
ExportAllDeclaration: pushExportNode,
|
|
46975
46128
|
ExportDefaultDeclaration: pushExportNode,
|
|
46976
46129
|
ExportNamedDeclaration: pushExportNode,
|
|
@@ -46978,53 +46131,31 @@ const onlyExportComponents = defineRule({
|
|
|
46978
46131
|
VariableDeclarator: pushComponentCandidate,
|
|
46979
46132
|
ClassDeclaration: pushComponentCandidate,
|
|
46980
46133
|
"Program:exit"() {
|
|
46981
|
-
if (hasRootMount) return;
|
|
46982
46134
|
const localComponentNames = /* @__PURE__ */ new Set();
|
|
46983
|
-
const componentFactorySymbolIds = /* @__PURE__ */ new Set();
|
|
46984
|
-
for (const child of componentCandidates) {
|
|
46985
|
-
if (isInsideFunctionScope(child)) continue;
|
|
46986
|
-
if (isNodeOfType(child, "FunctionDeclaration") && child.id) {
|
|
46987
|
-
if (functionReturnsNextDynamicComponent(child, nextDynamicImportSymbolIds, context.scopes)) {
|
|
46988
|
-
const symbol = context.scopes.symbolFor(child.id);
|
|
46989
|
-
if (symbol?.references.every((reference) => reference.flag === "read")) componentFactorySymbolIds.add(symbol.id);
|
|
46990
|
-
}
|
|
46991
|
-
continue;
|
|
46992
|
-
}
|
|
46993
|
-
if (isNodeOfType(child, "VariableDeclarator") && isNodeOfType(child.id, "Identifier") && child.init && functionReturnsNextDynamicComponent(child.init, nextDynamicImportSymbolIds, context.scopes)) {
|
|
46994
|
-
const symbol = context.scopes.symbolFor(child.id);
|
|
46995
|
-
if (symbol?.references.every((reference) => reference.flag === "read")) componentFactorySymbolIds.add(symbol.id);
|
|
46996
|
-
}
|
|
46997
|
-
}
|
|
46998
46135
|
const state = {
|
|
46999
46136
|
customHocs: new Set([...DEFAULT_REACT_HOCS, ...settings.customHOCs]),
|
|
47000
46137
|
allowExportNames: new Set(settings.allowExportNames),
|
|
47001
46138
|
allowConstantExport: settings.allowConstantExport,
|
|
47002
|
-
allowedRouteExportNames,
|
|
47003
|
-
routeFactoryBindings,
|
|
47004
|
-
componentFactorySymbolIds,
|
|
47005
|
-
importSymbolIds,
|
|
47006
46139
|
localComponentNames,
|
|
47007
46140
|
scopes: context.scopes,
|
|
47008
46141
|
controlFlow: context.cfg
|
|
47009
46142
|
};
|
|
47010
46143
|
for (const child of componentCandidates) {
|
|
47011
46144
|
if (isNodeOfType(child, "FunctionDeclaration") && child.id) {
|
|
47012
|
-
if (isReactComponentName(child.id.name) && !isInsideFunctionScope(child) &&
|
|
46145
|
+
if (isReactComponentName(child.id.name) && !isInsideFunctionScope(child) && functionContainsReactRenderOutput(child, context.scopes, context.cfg)) localComponentNames.add(child.id.name);
|
|
47013
46146
|
}
|
|
47014
46147
|
if (isNodeOfType(child, "ClassDeclaration") && child.id) {
|
|
47015
46148
|
if (isReactComponentName(child.id.name) && isEs6Component(child) && !isInsideFunctionScope(child)) localComponentNames.add(child.id.name);
|
|
47016
46149
|
}
|
|
47017
46150
|
if (isNodeOfType(child, "VariableDeclarator") && isNodeOfType(child.id, "Identifier")) {
|
|
47018
46151
|
const initializer = child.init;
|
|
47019
|
-
|
|
47020
|
-
|
|
47021
|
-
|
|
47022
|
-
if (!isDirectFunction || functionHasReactRenderSemantics(expression, state)) localComponentNames.add(child.id.name);
|
|
46152
|
+
if (isReactComponentName(child.id.name) && (canBeReactFunctionComponent(initializer, state) || (initializer ? isEs6Component(skipTsExpression(initializer)) : false)) && !isInsideFunctionScope(child)) {
|
|
46153
|
+
const expression = initializer ? skipTsExpression(initializer) : null;
|
|
46154
|
+
if (!(expression !== null && (isNodeOfType(expression, "ArrowFunctionExpression") || isNodeOfType(expression, "FunctionExpression"))) || functionContainsReactRenderOutput(expression, context.scopes, context.cfg)) localComponentNames.add(child.id.name);
|
|
47023
46155
|
}
|
|
47024
46156
|
}
|
|
47025
46157
|
}
|
|
47026
46158
|
const exports = [];
|
|
47027
|
-
const exportAllNodes = [];
|
|
47028
46159
|
let hasReactExport = false;
|
|
47029
46160
|
let hasAnyExports = false;
|
|
47030
46161
|
const isExportedNodeIds = /* @__PURE__ */ new WeakSet();
|
|
@@ -47032,8 +46163,10 @@ const onlyExportComponents = defineRule({
|
|
|
47032
46163
|
if (isNodeOfType(child, "ExportAllDeclaration")) {
|
|
47033
46164
|
if (child.exportKind === "type") continue;
|
|
47034
46165
|
hasAnyExports = true;
|
|
47035
|
-
|
|
47036
|
-
|
|
46166
|
+
context.report({
|
|
46167
|
+
node: child,
|
|
46168
|
+
message: EXPORT_ALL_MESSAGE
|
|
46169
|
+
});
|
|
47037
46170
|
continue;
|
|
47038
46171
|
}
|
|
47039
46172
|
if (isNodeOfType(child, "ExportDefaultDeclaration")) {
|
|
@@ -47041,24 +46174,17 @@ const onlyExportComponents = defineRule({
|
|
|
47041
46174
|
const declaration = child.declaration;
|
|
47042
46175
|
const stripped = skipTsExpression(declaration);
|
|
47043
46176
|
if (isNodeOfType(stripped, "FunctionDeclaration") || isNodeOfType(stripped, "FunctionExpression")) {
|
|
47044
|
-
const hasRenderOutput = functionHasReactRenderSemantics(stripped, state);
|
|
47045
46177
|
if (stripped.id) {
|
|
47046
46178
|
const idNode = stripped.id;
|
|
47047
46179
|
isExportedNodeIds.add(stripped);
|
|
47048
|
-
exports.push(
|
|
47049
|
-
|
|
47050
|
-
reportNode: idNode
|
|
47051
|
-
});
|
|
47052
|
-
} else if (hasRenderOutput) {
|
|
46180
|
+
exports.push(classifyExport(idNode.name, idNode, true, null, state));
|
|
46181
|
+
} else {
|
|
47053
46182
|
context.report({
|
|
47054
46183
|
node: stripped,
|
|
47055
46184
|
message: ANONYMOUS_MESSAGE
|
|
47056
46185
|
});
|
|
47057
46186
|
hasReactExport = true;
|
|
47058
|
-
}
|
|
47059
|
-
kind: "non-component",
|
|
47060
|
-
reportNode: stripped
|
|
47061
|
-
});
|
|
46187
|
+
}
|
|
47062
46188
|
continue;
|
|
47063
46189
|
}
|
|
47064
46190
|
if (isNodeOfType(stripped, "ClassDeclaration") || isNodeOfType(stripped, "ClassExpression")) {
|
|
@@ -47077,34 +46203,26 @@ const onlyExportComponents = defineRule({
|
|
|
47077
46203
|
continue;
|
|
47078
46204
|
}
|
|
47079
46205
|
if (isNodeOfType(stripped, "Identifier")) {
|
|
47080
|
-
exports.push(
|
|
47081
|
-
kind: "non-component",
|
|
47082
|
-
reportNode: stripped
|
|
47083
|
-
});
|
|
47084
|
-
continue;
|
|
47085
|
-
}
|
|
47086
|
-
if (isNodeOfType(stripped, "MemberExpression")) {
|
|
47087
|
-
if (isProvenComponentValue(stripped, state)) hasReactExport = true;
|
|
47088
|
-
else exports.push({
|
|
47089
|
-
kind: "non-component",
|
|
47090
|
-
reportNode: stripped
|
|
47091
|
-
});
|
|
46206
|
+
exports.push(classifyExport(stripped.name, stripped, false, null, state));
|
|
47092
46207
|
continue;
|
|
47093
46208
|
}
|
|
47094
46209
|
if (isNodeOfType(stripped, "CallExpression")) {
|
|
47095
|
-
if (isRouteFactoryCall(stripped
|
|
46210
|
+
if (isRouteFactoryCall(stripped)) {
|
|
47096
46211
|
hasReactExport = true;
|
|
47097
46212
|
continue;
|
|
47098
46213
|
}
|
|
47099
|
-
|
|
47100
|
-
|
|
47101
|
-
|
|
47102
|
-
|
|
47103
|
-
|
|
47104
|
-
|
|
47105
|
-
|
|
47106
|
-
|
|
47107
|
-
|
|
46214
|
+
const isHoc = isHocCallee(stripped.callee, state);
|
|
46215
|
+
const firstArg = stripped.arguments[0];
|
|
46216
|
+
const firstArgIsValid = Boolean(firstArg) && (() => {
|
|
46217
|
+
if (!firstArg) return false;
|
|
46218
|
+
const expression = skipTsExpression(firstArg);
|
|
46219
|
+
if (isNodeOfType(expression, "Identifier")) return true;
|
|
46220
|
+
if (isNodeOfType(expression, "FunctionExpression") && expression.id) return true;
|
|
46221
|
+
if (isNodeOfType(expression, "CallExpression") && isHocCallee(expression.callee, state)) return true;
|
|
46222
|
+
return false;
|
|
46223
|
+
})();
|
|
46224
|
+
if (isHoc && firstArgIsValid) hasReactExport = true;
|
|
46225
|
+
else if (!isHoc && isConfigOnlyFactoryCall(stripped)) exports.push({
|
|
47108
46226
|
kind: "non-component",
|
|
47109
46227
|
reportNode: stripped
|
|
47110
46228
|
});
|
|
@@ -47115,32 +46233,16 @@ const onlyExportComponents = defineRule({
|
|
|
47115
46233
|
continue;
|
|
47116
46234
|
}
|
|
47117
46235
|
if (isNodeOfType(stripped, "ObjectExpression")) {
|
|
47118
|
-
|
|
47119
|
-
|
|
47120
|
-
|
|
47121
|
-
} : {
|
|
47122
|
-
kind: "non-component",
|
|
47123
|
-
reportNode: stripped
|
|
47124
|
-
});
|
|
47125
|
-
continue;
|
|
47126
|
-
}
|
|
47127
|
-
if (isNodeOfType(stripped, "ArrowFunctionExpression")) {
|
|
47128
|
-
if (functionHasReactRenderSemantics(stripped, state)) {
|
|
47129
|
-
context.report({
|
|
47130
|
-
node: stripped,
|
|
47131
|
-
message: ANONYMOUS_MESSAGE
|
|
47132
|
-
});
|
|
47133
|
-
hasReactExport = true;
|
|
47134
|
-
} else exports.push({
|
|
47135
|
-
kind: "non-component",
|
|
47136
|
-
reportNode: stripped
|
|
46236
|
+
context.report({
|
|
46237
|
+
node: stripped,
|
|
46238
|
+
message: objectExpressionBundlesComponents(stripped, state) ? NAMESPACE_OBJECT_MESSAGE : ANONYMOUS_MESSAGE
|
|
47137
46239
|
});
|
|
47138
46240
|
continue;
|
|
47139
46241
|
}
|
|
47140
|
-
if (isNodeOfType(stripped, "
|
|
47141
|
-
|
|
47142
|
-
|
|
47143
|
-
|
|
46242
|
+
if (isNodeOfType(stripped, "ArrowFunctionExpression") || isNodeOfType(stripped, "Literal")) {
|
|
46243
|
+
context.report({
|
|
46244
|
+
node: stripped,
|
|
46245
|
+
message: ANONYMOUS_MESSAGE
|
|
47144
46246
|
});
|
|
47145
46247
|
continue;
|
|
47146
46248
|
}
|
|
@@ -47157,10 +46259,7 @@ const onlyExportComponents = defineRule({
|
|
|
47157
46259
|
const declaration = child.declaration;
|
|
47158
46260
|
if (isNodeOfType(declaration, "FunctionDeclaration") && declaration.id) {
|
|
47159
46261
|
isExportedNodeIds.add(declaration);
|
|
47160
|
-
exports.push(
|
|
47161
|
-
kind: "non-component",
|
|
47162
|
-
reportNode: declaration.id
|
|
47163
|
-
});
|
|
46262
|
+
exports.push(classifyExport(declaration.id.name, declaration.id, true, null, state));
|
|
47164
46263
|
} else if (isNodeOfType(declaration, "ClassDeclaration") && declaration.id) {
|
|
47165
46264
|
isExportedNodeIds.add(declaration);
|
|
47166
46265
|
if (isReactComponentName(declaration.id.name) && isEs6Component(declaration)) exports.push({ kind: "react-component" });
|
|
@@ -47184,7 +46283,6 @@ const onlyExportComponents = defineRule({
|
|
|
47184
46283
|
const isReExportFromSource = Boolean(child.source);
|
|
47185
46284
|
for (const specifier of child.specifiers ?? []) {
|
|
47186
46285
|
if (!isNodeOfType(specifier, "ExportSpecifier")) continue;
|
|
47187
|
-
if (specifier.exportKind === "type") continue;
|
|
47188
46286
|
const exported = specifier.exported;
|
|
47189
46287
|
const local = specifier.local;
|
|
47190
46288
|
let exportedName = null;
|
|
@@ -47192,13 +46290,8 @@ const onlyExportComponents = defineRule({
|
|
|
47192
46290
|
const localName = local && isNodeOfType(local, "Identifier") ? local.name : null;
|
|
47193
46291
|
const reportNode = specifier;
|
|
47194
46292
|
let entry;
|
|
47195
|
-
if (
|
|
47196
|
-
else if (
|
|
47197
|
-
else if (exportedName === "default" && localName && local) entry = isProvenComponentValue(local, state) ? { kind: "react-component" } : {
|
|
47198
|
-
kind: "non-component",
|
|
47199
|
-
reportNode
|
|
47200
|
-
};
|
|
47201
|
-
else if (exportedName) entry = classifyExport(exportedName, reportNode, false, isReExportFromSource ? null : local, state);
|
|
46293
|
+
if (exportedName === "default" && localName) entry = classifyExport(localName, reportNode, false, null, state);
|
|
46294
|
+
else if (exportedName) entry = classifyExport(exportedName, reportNode, false, null, state);
|
|
47202
46295
|
else {
|
|
47203
46296
|
entry = {
|
|
47204
46297
|
kind: "non-component",
|
|
@@ -47216,21 +46309,15 @@ const onlyExportComponents = defineRule({
|
|
|
47216
46309
|
node: entry.reportNode,
|
|
47217
46310
|
message: NAMESPACE_OBJECT_MESSAGE
|
|
47218
46311
|
});
|
|
47219
|
-
if (hasAnyExports && hasReactExport) {
|
|
47220
|
-
|
|
47221
|
-
node:
|
|
47222
|
-
message:
|
|
46312
|
+
if (hasAnyExports && hasReactExport) for (const entry of exports) {
|
|
46313
|
+
if (entry.kind === "non-component") context.report({
|
|
46314
|
+
node: entry.reportNode,
|
|
46315
|
+
message: NAMED_EXPORT_MESSAGE
|
|
46316
|
+
});
|
|
46317
|
+
if (entry.kind === "react-context") context.report({
|
|
46318
|
+
node: entry.reportNode,
|
|
46319
|
+
message: REACT_CONTEXT_MESSAGE
|
|
47223
46320
|
});
|
|
47224
|
-
for (const entry of exports) {
|
|
47225
|
-
if (entry.kind === "non-component") context.report({
|
|
47226
|
-
node: entry.reportNode,
|
|
47227
|
-
message: NAMED_EXPORT_MESSAGE
|
|
47228
|
-
});
|
|
47229
|
-
if (entry.kind === "react-context") context.report({
|
|
47230
|
-
node: entry.reportNode,
|
|
47231
|
-
message: REACT_CONTEXT_MESSAGE
|
|
47232
|
-
});
|
|
47233
|
-
}
|
|
47234
46321
|
}
|
|
47235
46322
|
}
|
|
47236
46323
|
};
|
|
@@ -67327,7 +66414,6 @@ const CROSS_FILE_RULE_IDS = new Set([
|
|
|
67327
66414
|
"no-effect-with-fresh-deps",
|
|
67328
66415
|
"no-initialize-state",
|
|
67329
66416
|
"no-mutating-reducer-state",
|
|
67330
|
-
"only-export-components",
|
|
67331
66417
|
"no-unguarded-browser-global-in-render-or-hook-init",
|
|
67332
66418
|
"prefer-dynamic-import",
|
|
67333
66419
|
"rendering-hydration-mismatch-time",
|
|
@@ -67535,7 +66621,7 @@ const CROSS_FILE_DEPENDENCY_COLLECTORS = new Map([
|
|
|
67535
66621
|
* `CROSS_FILE_DEPENDENCY_COLLECTORS` (the core guard test enforces the
|
|
67536
66622
|
* partition), forcing a conscious classification.
|
|
67537
66623
|
*/
|
|
67538
|
-
const UNBOUNDED_CROSS_FILE_RULE_IDS = new Set(
|
|
66624
|
+
const UNBOUNDED_CROSS_FILE_RULE_IDS = /* @__PURE__ */ new Set();
|
|
67539
66625
|
/**
|
|
67540
66626
|
* Runs the collectors for `ruleIds` over one file and returns every
|
|
67541
66627
|
* filesystem probe they made — the file's cross-file dependency set.
|