oxlint-plugin-react-doctor 0.5.3-dev.eacdcf2 → 0.5.4-dev.e90eb7a
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 +11 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22559,9 +22559,10 @@ const TANSTACK_ROUTE_CREATION_FUNCTIONS = new Set([
|
|
|
22559
22559
|
"createRootRouteWithContext"
|
|
22560
22560
|
]);
|
|
22561
22561
|
const TANSTACK_SERVER_FN_NAMES = new Set(["createServerFn"]);
|
|
22562
|
+
const TANSTACK_INPUT_VALIDATOR_METHOD_NAMES = new Set(["validator", "inputValidator"]);
|
|
22562
22563
|
const TANSTACK_MIDDLEWARE_METHOD_ORDER = [
|
|
22563
22564
|
"middleware",
|
|
22564
|
-
"
|
|
22565
|
+
"validator",
|
|
22565
22566
|
"client",
|
|
22566
22567
|
"server",
|
|
22567
22568
|
"handler"
|
|
@@ -35200,7 +35201,7 @@ const walkServerFnChain = (outerNode) => {
|
|
|
35200
35201
|
const result = {
|
|
35201
35202
|
isServerFnChain: false,
|
|
35202
35203
|
specifiedMethod: null,
|
|
35203
|
-
|
|
35204
|
+
hasInputValidation: false
|
|
35204
35205
|
};
|
|
35205
35206
|
if (!isNodeOfType(outerNode, "CallExpression")) return result;
|
|
35206
35207
|
if (!isNodeOfType(outerNode.callee, "MemberExpression")) return result;
|
|
@@ -35214,7 +35215,7 @@ const walkServerFnChain = (outerNode) => {
|
|
|
35214
35215
|
for (const property of optionsArgument.properties ?? []) if (isNodeOfType(property, "Property") && isNodeOfType(property.key, "Identifier") && property.key.name === "method" && isNodeOfType(property.value, "Literal") && typeof property.value.value === "string") result.specifiedMethod = property.value.value;
|
|
35215
35216
|
}
|
|
35216
35217
|
}
|
|
35217
|
-
if (calleeName
|
|
35218
|
+
if (calleeName && TANSTACK_INPUT_VALIDATOR_METHOD_NAMES.has(calleeName)) result.hasInputValidation = true;
|
|
35218
35219
|
if (isNodeOfType(currentNode.callee, "MemberExpression")) currentNode = currentNode.callee.object;
|
|
35219
35220
|
else break;
|
|
35220
35221
|
}
|
|
@@ -35768,13 +35769,14 @@ const tanstackStartRoutePropertyOrder = defineRule({
|
|
|
35768
35769
|
});
|
|
35769
35770
|
//#endregion
|
|
35770
35771
|
//#region src/plugin/rules/tanstack-start/tanstack-start-server-fn-method-order.ts
|
|
35772
|
+
const toMethodOrderToken = (methodName) => TANSTACK_INPUT_VALIDATOR_METHOD_NAMES.has(methodName) ? "validator" : methodName;
|
|
35771
35773
|
const tanstackStartServerFnMethodOrder = defineRule({
|
|
35772
35774
|
id: "tanstack-start-server-fn-method-order",
|
|
35773
35775
|
title: "Server function method order breaks type inference",
|
|
35774
35776
|
tags: ["test-noise"],
|
|
35775
35777
|
requires: ["tanstack-start"],
|
|
35776
35778
|
severity: "error",
|
|
35777
|
-
recommendation: "Chain methods in order: .middleware() → .
|
|
35779
|
+
recommendation: "Chain methods in order: .middleware() → .validator() → .client() → .server() → .handler(). Types depend on this sequence.",
|
|
35778
35780
|
create: (context) => ({ CallExpression(node) {
|
|
35779
35781
|
if (!isNodeOfType(node.callee, "MemberExpression")) return;
|
|
35780
35782
|
const methodNames = [];
|
|
@@ -35789,10 +35791,10 @@ const tanstackStartServerFnMethodOrder = defineRule({
|
|
|
35789
35791
|
} else return;
|
|
35790
35792
|
const ownMethodName = isNodeOfType(node.callee.property, "Identifier") ? node.callee.property.name : null;
|
|
35791
35793
|
if (methodNames[methodNames.length - 1] !== ownMethodName) return;
|
|
35792
|
-
const orderSensitiveMethods = methodNames.filter((name) => TANSTACK_MIDDLEWARE_METHOD_ORDER.includes(name));
|
|
35794
|
+
const orderSensitiveMethods = methodNames.filter((name) => TANSTACK_MIDDLEWARE_METHOD_ORDER.includes(toMethodOrderToken(name)));
|
|
35793
35795
|
let lastIndex = -1;
|
|
35794
35796
|
for (const methodName of orderSensitiveMethods) {
|
|
35795
|
-
const currentIndex = TANSTACK_MIDDLEWARE_METHOD_ORDER.indexOf(methodName);
|
|
35797
|
+
const currentIndex = TANSTACK_MIDDLEWARE_METHOD_ORDER.indexOf(toMethodOrderToken(methodName));
|
|
35796
35798
|
if (currentIndex < lastIndex) {
|
|
35797
35799
|
const expectedBefore = TANSTACK_MIDDLEWARE_METHOD_ORDER[lastIndex];
|
|
35798
35800
|
context.report({
|
|
@@ -35813,7 +35815,7 @@ const tanstackStartServerFnValidateInput = defineRule({
|
|
|
35813
35815
|
tags: ["test-noise"],
|
|
35814
35816
|
requires: ["tanstack-start"],
|
|
35815
35817
|
severity: "warn",
|
|
35816
|
-
recommendation: "Add `.
|
|
35818
|
+
recommendation: "Add `.validator(schema)` before `.handler()`. This data crosses the network and must be validated at runtime.",
|
|
35817
35819
|
create: (context) => ({ CallExpression(node) {
|
|
35818
35820
|
if (!isNodeOfType(node.callee, "MemberExpression")) return;
|
|
35819
35821
|
if (!isNodeOfType(node.callee.property, "Identifier")) return;
|
|
@@ -35827,9 +35829,9 @@ const tanstackStartServerFnValidateInput = defineRule({
|
|
|
35827
35829
|
if (isNodeOfType(child, "MemberExpression") && isNodeOfType(child.property, "Identifier") && child.property.name === "data") accessesData = true;
|
|
35828
35830
|
if (isNodeOfType(child, "ObjectPattern") && child.properties?.some((property) => isNodeOfType(property, "Property") && isNodeOfType(property.key, "Identifier") && property.key.name === "data")) accessesData = true;
|
|
35829
35831
|
});
|
|
35830
|
-
if (accessesData && !chainInfo.
|
|
35832
|
+
if (accessesData && !chainInfo.hasInputValidation) context.report({
|
|
35831
35833
|
node,
|
|
35832
|
-
message: "This server function reads network data with no
|
|
35834
|
+
message: "This server function reads network data with no validator(), so anyone can send unvalidated input."
|
|
35833
35835
|
});
|
|
35834
35836
|
} })
|
|
35835
35837
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oxlint-plugin-react-doctor",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4-dev.e90eb7a",
|
|
4
4
|
"description": "oxlint plugin for React Doctor: diagnose React codebases for security, performance, correctness, accessibility, bundle-size, and architecture issues",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"accessibility",
|