@stll/oxlint-plugin 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +11 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -1
- package/dist/index.d.mts +8 -1
- package/dist/index.mjs +8 -1
- package/dist/index.mjs.map +1 -1
- package/dist/no-partial-record-satisfies.mjs +1 -1
- package/dist/no-raw-route-query-client.cjs +203 -0
- package/dist/no-raw-route-query-client.cjs.map +1 -0
- package/dist/no-raw-route-query-client.d.cts +4 -0
- package/dist/no-raw-route-query-client.d.mts +5 -0
- package/dist/no-raw-route-query-client.mjs +199 -0
- package/dist/no-raw-route-query-client.mjs.map +1 -0
- package/dist/no-unsafe-inner-html.mjs +1 -1
- package/dist/require-loader-prefetch.cjs +187 -0
- package/dist/require-loader-prefetch.cjs.map +1 -0
- package/dist/require-loader-prefetch.d.cts +4 -0
- package/dist/require-loader-prefetch.d.mts +5 -0
- package/dist/require-loader-prefetch.mjs +160 -0
- package/dist/require-loader-prefetch.mjs.map +1 -0
- package/dist/utils.cjs +19 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.mjs +8 -1
- package/dist/utils.mjs.map +1 -1
- package/package.json +25 -2
package/dist/index.cjs
CHANGED
|
@@ -4,6 +4,8 @@ const noAnyCastsPluginSpecifier = "@stll/oxlint-plugin/no-any-casts";
|
|
|
4
4
|
const noDangerousTypeAssertionsPluginSpecifier = "@stll/oxlint-plugin/no-dangerous-type-assertions";
|
|
5
5
|
const noPartialRecordSatisfiesPluginSpecifier = "@stll/oxlint-plugin/no-partial-record-satisfies";
|
|
6
6
|
const noUnsafeInnerHtmlPluginSpecifier = "@stll/oxlint-plugin/no-unsafe-inner-html";
|
|
7
|
+
const noRawRouteQueryClientPluginSpecifier = "@stll/oxlint-plugin/no-raw-route-query-client";
|
|
8
|
+
const requireLoaderPrefetchPluginSpecifier = "@stll/oxlint-plugin/require-loader-prefetch";
|
|
7
9
|
const portableSafetyPluginSpecifiers = [
|
|
8
10
|
noAnyCastsPluginSpecifier,
|
|
9
11
|
noDangerousTypeAssertionsPluginSpecifier,
|
|
@@ -16,12 +18,21 @@ const portableSafetyRules = {
|
|
|
16
18
|
"no-partial-record-satisfies/no-partial-record-satisfies": "error",
|
|
17
19
|
"no-unsafe-inner-html/no-unsafe-inner-html": "error"
|
|
18
20
|
};
|
|
21
|
+
const routeQueryPluginSpecifiers = [noRawRouteQueryClientPluginSpecifier, requireLoaderPrefetchPluginSpecifier];
|
|
22
|
+
const routeQueryRules = {
|
|
23
|
+
"no-raw-route-query-client/no-raw-route-query-client": "error",
|
|
24
|
+
"require-loader-prefetch/require-loader-prefetch": "error"
|
|
25
|
+
};
|
|
19
26
|
//#endregion
|
|
20
27
|
exports.noAnyCastsPluginSpecifier = noAnyCastsPluginSpecifier;
|
|
21
28
|
exports.noDangerousTypeAssertionsPluginSpecifier = noDangerousTypeAssertionsPluginSpecifier;
|
|
22
29
|
exports.noPartialRecordSatisfiesPluginSpecifier = noPartialRecordSatisfiesPluginSpecifier;
|
|
30
|
+
exports.noRawRouteQueryClientPluginSpecifier = noRawRouteQueryClientPluginSpecifier;
|
|
23
31
|
exports.noUnsafeInnerHtmlPluginSpecifier = noUnsafeInnerHtmlPluginSpecifier;
|
|
24
32
|
exports.portableSafetyPluginSpecifiers = portableSafetyPluginSpecifiers;
|
|
25
33
|
exports.portableSafetyRules = portableSafetyRules;
|
|
34
|
+
exports.requireLoaderPrefetchPluginSpecifier = requireLoaderPrefetchPluginSpecifier;
|
|
35
|
+
exports.routeQueryPluginSpecifiers = routeQueryPluginSpecifiers;
|
|
36
|
+
exports.routeQueryRules = routeQueryRules;
|
|
26
37
|
|
|
27
38
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { OxlintConfig } from \"oxlint\";\n\ntype JsPlugins = NonNullable<OxlintConfig[\"jsPlugins\"]>;\ntype Rules = NonNullable<OxlintConfig[\"rules\"]>;\n\nexport const noAnyCastsPluginSpecifier = \"@stll/oxlint-plugin/no-any-casts\";\nexport const noDangerousTypeAssertionsPluginSpecifier =\n \"@stll/oxlint-plugin/no-dangerous-type-assertions\";\nexport const noPartialRecordSatisfiesPluginSpecifier =\n \"@stll/oxlint-plugin/no-partial-record-satisfies\";\nexport const noUnsafeInnerHtmlPluginSpecifier =\n \"@stll/oxlint-plugin/no-unsafe-inner-html\";\n\nexport const portableSafetyPluginSpecifiers = [\n noAnyCastsPluginSpecifier,\n noDangerousTypeAssertionsPluginSpecifier,\n noPartialRecordSatisfiesPluginSpecifier,\n noUnsafeInnerHtmlPluginSpecifier,\n] satisfies JsPlugins;\n\nexport const portableSafetyRules = {\n \"no-any-casts/no-any-casts\": \"error\",\n \"no-dangerous-type-assertions/no-dangerous-type-assertions\": \"error\",\n \"no-partial-record-satisfies/no-partial-record-satisfies\": \"error\",\n \"no-unsafe-inner-html/no-unsafe-inner-html\": \"error\",\n} satisfies Rules;\n"],"mappings":";;AAKA,MAAa,4BAA4B;AACzC,MAAa,2CACX;AACF,MAAa,0CACX;AACF,MAAa,mCACX;AAEF,MAAa,iCAAiC;CAC5C;CACA;CACA;CACA;AACF;AAEA,MAAa,sBAAsB;CACjC,6BAA6B;CAC7B,6DAA6D;CAC7D,2DAA2D;CAC3D,6CAA6C;AAC/C"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { OxlintConfig } from \"oxlint\";\n\ntype JsPlugins = NonNullable<OxlintConfig[\"jsPlugins\"]>;\ntype Rules = NonNullable<OxlintConfig[\"rules\"]>;\n\nexport const noAnyCastsPluginSpecifier = \"@stll/oxlint-plugin/no-any-casts\";\nexport const noDangerousTypeAssertionsPluginSpecifier =\n \"@stll/oxlint-plugin/no-dangerous-type-assertions\";\nexport const noPartialRecordSatisfiesPluginSpecifier =\n \"@stll/oxlint-plugin/no-partial-record-satisfies\";\nexport const noUnsafeInnerHtmlPluginSpecifier =\n \"@stll/oxlint-plugin/no-unsafe-inner-html\";\nexport const noRawRouteQueryClientPluginSpecifier =\n \"@stll/oxlint-plugin/no-raw-route-query-client\";\nexport const requireLoaderPrefetchPluginSpecifier =\n \"@stll/oxlint-plugin/require-loader-prefetch\";\n\nexport const portableSafetyPluginSpecifiers = [\n noAnyCastsPluginSpecifier,\n noDangerousTypeAssertionsPluginSpecifier,\n noPartialRecordSatisfiesPluginSpecifier,\n noUnsafeInnerHtmlPluginSpecifier,\n] satisfies JsPlugins;\n\nexport const portableSafetyRules = {\n \"no-any-casts/no-any-casts\": \"error\",\n \"no-dangerous-type-assertions/no-dangerous-type-assertions\": \"error\",\n \"no-partial-record-satisfies/no-partial-record-satisfies\": \"error\",\n \"no-unsafe-inner-html/no-unsafe-inner-html\": \"error\",\n} satisfies Rules;\n\nexport const routeQueryPluginSpecifiers = [\n noRawRouteQueryClientPluginSpecifier,\n requireLoaderPrefetchPluginSpecifier,\n] satisfies JsPlugins;\n\nexport const routeQueryRules = {\n \"no-raw-route-query-client/no-raw-route-query-client\": \"error\",\n \"require-loader-prefetch/require-loader-prefetch\": \"error\",\n} satisfies Rules;\n"],"mappings":";;AAKA,MAAa,4BAA4B;AACzC,MAAa,2CACX;AACF,MAAa,0CACX;AACF,MAAa,mCACX;AACF,MAAa,uCACX;AACF,MAAa,uCACX;AAEF,MAAa,iCAAiC;CAC5C;CACA;CACA;CACA;AACF;AAEA,MAAa,sBAAsB;CACjC,6BAA6B;CAC7B,6DAA6D;CAC7D,2DAA2D;CAC3D,6CAA6C;AAC/C;AAEA,MAAa,6BAA6B,CACxC,sCACA,oCACF;AAEA,MAAa,kBAAkB;CAC7B,uDAAuD;CACvD,mDAAmD;AACrD"}
|
package/dist/index.d.cts
CHANGED
|
@@ -3,6 +3,8 @@ declare const noAnyCastsPluginSpecifier = "@stll/oxlint-plugin/no-any-casts";
|
|
|
3
3
|
declare const noDangerousTypeAssertionsPluginSpecifier = "@stll/oxlint-plugin/no-dangerous-type-assertions";
|
|
4
4
|
declare const noPartialRecordSatisfiesPluginSpecifier = "@stll/oxlint-plugin/no-partial-record-satisfies";
|
|
5
5
|
declare const noUnsafeInnerHtmlPluginSpecifier = "@stll/oxlint-plugin/no-unsafe-inner-html";
|
|
6
|
+
declare const noRawRouteQueryClientPluginSpecifier = "@stll/oxlint-plugin/no-raw-route-query-client";
|
|
7
|
+
declare const requireLoaderPrefetchPluginSpecifier = "@stll/oxlint-plugin/require-loader-prefetch";
|
|
6
8
|
declare const portableSafetyPluginSpecifiers: string[];
|
|
7
9
|
declare const portableSafetyRules: {
|
|
8
10
|
"no-any-casts/no-any-casts": "error";
|
|
@@ -10,6 +12,11 @@ declare const portableSafetyRules: {
|
|
|
10
12
|
"no-partial-record-satisfies/no-partial-record-satisfies": "error";
|
|
11
13
|
"no-unsafe-inner-html/no-unsafe-inner-html": "error";
|
|
12
14
|
};
|
|
15
|
+
declare const routeQueryPluginSpecifiers: string[];
|
|
16
|
+
declare const routeQueryRules: {
|
|
17
|
+
"no-raw-route-query-client/no-raw-route-query-client": "error";
|
|
18
|
+
"require-loader-prefetch/require-loader-prefetch": "error";
|
|
19
|
+
};
|
|
13
20
|
//#endregion
|
|
14
|
-
export { noAnyCastsPluginSpecifier, noDangerousTypeAssertionsPluginSpecifier, noPartialRecordSatisfiesPluginSpecifier, noUnsafeInnerHtmlPluginSpecifier, portableSafetyPluginSpecifiers, portableSafetyRules };
|
|
21
|
+
export { noAnyCastsPluginSpecifier, noDangerousTypeAssertionsPluginSpecifier, noPartialRecordSatisfiesPluginSpecifier, noRawRouteQueryClientPluginSpecifier, noUnsafeInnerHtmlPluginSpecifier, portableSafetyPluginSpecifiers, portableSafetyRules, requireLoaderPrefetchPluginSpecifier, routeQueryPluginSpecifiers, routeQueryRules };
|
|
15
22
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -3,6 +3,8 @@ declare const noAnyCastsPluginSpecifier = "@stll/oxlint-plugin/no-any-casts";
|
|
|
3
3
|
declare const noDangerousTypeAssertionsPluginSpecifier = "@stll/oxlint-plugin/no-dangerous-type-assertions";
|
|
4
4
|
declare const noPartialRecordSatisfiesPluginSpecifier = "@stll/oxlint-plugin/no-partial-record-satisfies";
|
|
5
5
|
declare const noUnsafeInnerHtmlPluginSpecifier = "@stll/oxlint-plugin/no-unsafe-inner-html";
|
|
6
|
+
declare const noRawRouteQueryClientPluginSpecifier = "@stll/oxlint-plugin/no-raw-route-query-client";
|
|
7
|
+
declare const requireLoaderPrefetchPluginSpecifier = "@stll/oxlint-plugin/require-loader-prefetch";
|
|
6
8
|
declare const portableSafetyPluginSpecifiers: string[];
|
|
7
9
|
declare const portableSafetyRules: {
|
|
8
10
|
"no-any-casts/no-any-casts": "error";
|
|
@@ -10,6 +12,11 @@ declare const portableSafetyRules: {
|
|
|
10
12
|
"no-partial-record-satisfies/no-partial-record-satisfies": "error";
|
|
11
13
|
"no-unsafe-inner-html/no-unsafe-inner-html": "error";
|
|
12
14
|
};
|
|
15
|
+
declare const routeQueryPluginSpecifiers: string[];
|
|
16
|
+
declare const routeQueryRules: {
|
|
17
|
+
"no-raw-route-query-client/no-raw-route-query-client": "error";
|
|
18
|
+
"require-loader-prefetch/require-loader-prefetch": "error";
|
|
19
|
+
};
|
|
13
20
|
//#endregion
|
|
14
|
-
export { noAnyCastsPluginSpecifier, noDangerousTypeAssertionsPluginSpecifier, noPartialRecordSatisfiesPluginSpecifier, noUnsafeInnerHtmlPluginSpecifier, portableSafetyPluginSpecifiers, portableSafetyRules };
|
|
21
|
+
export { noAnyCastsPluginSpecifier, noDangerousTypeAssertionsPluginSpecifier, noPartialRecordSatisfiesPluginSpecifier, noRawRouteQueryClientPluginSpecifier, noUnsafeInnerHtmlPluginSpecifier, portableSafetyPluginSpecifiers, portableSafetyRules, requireLoaderPrefetchPluginSpecifier, routeQueryPluginSpecifiers, routeQueryRules };
|
|
15
22
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -3,6 +3,8 @@ const noAnyCastsPluginSpecifier = "@stll/oxlint-plugin/no-any-casts";
|
|
|
3
3
|
const noDangerousTypeAssertionsPluginSpecifier = "@stll/oxlint-plugin/no-dangerous-type-assertions";
|
|
4
4
|
const noPartialRecordSatisfiesPluginSpecifier = "@stll/oxlint-plugin/no-partial-record-satisfies";
|
|
5
5
|
const noUnsafeInnerHtmlPluginSpecifier = "@stll/oxlint-plugin/no-unsafe-inner-html";
|
|
6
|
+
const noRawRouteQueryClientPluginSpecifier = "@stll/oxlint-plugin/no-raw-route-query-client";
|
|
7
|
+
const requireLoaderPrefetchPluginSpecifier = "@stll/oxlint-plugin/require-loader-prefetch";
|
|
6
8
|
const portableSafetyPluginSpecifiers = [
|
|
7
9
|
noAnyCastsPluginSpecifier,
|
|
8
10
|
noDangerousTypeAssertionsPluginSpecifier,
|
|
@@ -15,7 +17,12 @@ const portableSafetyRules = {
|
|
|
15
17
|
"no-partial-record-satisfies/no-partial-record-satisfies": "error",
|
|
16
18
|
"no-unsafe-inner-html/no-unsafe-inner-html": "error"
|
|
17
19
|
};
|
|
20
|
+
const routeQueryPluginSpecifiers = [noRawRouteQueryClientPluginSpecifier, requireLoaderPrefetchPluginSpecifier];
|
|
21
|
+
const routeQueryRules = {
|
|
22
|
+
"no-raw-route-query-client/no-raw-route-query-client": "error",
|
|
23
|
+
"require-loader-prefetch/require-loader-prefetch": "error"
|
|
24
|
+
};
|
|
18
25
|
//#endregion
|
|
19
|
-
export { noAnyCastsPluginSpecifier, noDangerousTypeAssertionsPluginSpecifier, noPartialRecordSatisfiesPluginSpecifier, noUnsafeInnerHtmlPluginSpecifier, portableSafetyPluginSpecifiers, portableSafetyRules };
|
|
26
|
+
export { noAnyCastsPluginSpecifier, noDangerousTypeAssertionsPluginSpecifier, noPartialRecordSatisfiesPluginSpecifier, noRawRouteQueryClientPluginSpecifier, noUnsafeInnerHtmlPluginSpecifier, portableSafetyPluginSpecifiers, portableSafetyRules, requireLoaderPrefetchPluginSpecifier, routeQueryPluginSpecifiers, routeQueryRules };
|
|
20
27
|
|
|
21
28
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { OxlintConfig } from \"oxlint\";\n\ntype JsPlugins = NonNullable<OxlintConfig[\"jsPlugins\"]>;\ntype Rules = NonNullable<OxlintConfig[\"rules\"]>;\n\nexport const noAnyCastsPluginSpecifier = \"@stll/oxlint-plugin/no-any-casts\";\nexport const noDangerousTypeAssertionsPluginSpecifier =\n \"@stll/oxlint-plugin/no-dangerous-type-assertions\";\nexport const noPartialRecordSatisfiesPluginSpecifier =\n \"@stll/oxlint-plugin/no-partial-record-satisfies\";\nexport const noUnsafeInnerHtmlPluginSpecifier =\n \"@stll/oxlint-plugin/no-unsafe-inner-html\";\n\nexport const portableSafetyPluginSpecifiers = [\n noAnyCastsPluginSpecifier,\n noDangerousTypeAssertionsPluginSpecifier,\n noPartialRecordSatisfiesPluginSpecifier,\n noUnsafeInnerHtmlPluginSpecifier,\n] satisfies JsPlugins;\n\nexport const portableSafetyRules = {\n \"no-any-casts/no-any-casts\": \"error\",\n \"no-dangerous-type-assertions/no-dangerous-type-assertions\": \"error\",\n \"no-partial-record-satisfies/no-partial-record-satisfies\": \"error\",\n \"no-unsafe-inner-html/no-unsafe-inner-html\": \"error\",\n} satisfies Rules;\n"],"mappings":";AAKA,MAAa,4BAA4B;AACzC,MAAa,2CACX;AACF,MAAa,0CACX;AACF,MAAa,mCACX;AAEF,MAAa,iCAAiC;CAC5C;CACA;CACA;CACA;AACF;AAEA,MAAa,sBAAsB;CACjC,6BAA6B;CAC7B,6DAA6D;CAC7D,2DAA2D;CAC3D,6CAA6C;AAC/C"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { OxlintConfig } from \"oxlint\";\n\ntype JsPlugins = NonNullable<OxlintConfig[\"jsPlugins\"]>;\ntype Rules = NonNullable<OxlintConfig[\"rules\"]>;\n\nexport const noAnyCastsPluginSpecifier = \"@stll/oxlint-plugin/no-any-casts\";\nexport const noDangerousTypeAssertionsPluginSpecifier =\n \"@stll/oxlint-plugin/no-dangerous-type-assertions\";\nexport const noPartialRecordSatisfiesPluginSpecifier =\n \"@stll/oxlint-plugin/no-partial-record-satisfies\";\nexport const noUnsafeInnerHtmlPluginSpecifier =\n \"@stll/oxlint-plugin/no-unsafe-inner-html\";\nexport const noRawRouteQueryClientPluginSpecifier =\n \"@stll/oxlint-plugin/no-raw-route-query-client\";\nexport const requireLoaderPrefetchPluginSpecifier =\n \"@stll/oxlint-plugin/require-loader-prefetch\";\n\nexport const portableSafetyPluginSpecifiers = [\n noAnyCastsPluginSpecifier,\n noDangerousTypeAssertionsPluginSpecifier,\n noPartialRecordSatisfiesPluginSpecifier,\n noUnsafeInnerHtmlPluginSpecifier,\n] satisfies JsPlugins;\n\nexport const portableSafetyRules = {\n \"no-any-casts/no-any-casts\": \"error\",\n \"no-dangerous-type-assertions/no-dangerous-type-assertions\": \"error\",\n \"no-partial-record-satisfies/no-partial-record-satisfies\": \"error\",\n \"no-unsafe-inner-html/no-unsafe-inner-html\": \"error\",\n} satisfies Rules;\n\nexport const routeQueryPluginSpecifiers = [\n noRawRouteQueryClientPluginSpecifier,\n requireLoaderPrefetchPluginSpecifier,\n] satisfies JsPlugins;\n\nexport const routeQueryRules = {\n \"no-raw-route-query-client/no-raw-route-query-client\": \"error\",\n \"require-loader-prefetch/require-loader-prefetch\": \"error\",\n} satisfies Rules;\n"],"mappings":";AAKA,MAAa,4BAA4B;AACzC,MAAa,2CACX;AACF,MAAa,0CACX;AACF,MAAa,mCACX;AACF,MAAa,uCACX;AACF,MAAa,uCACX;AAEF,MAAa,iCAAiC;CAC5C;CACA;CACA;CACA;AACF;AAEA,MAAa,sBAAsB;CACjC,6BAA6B;CAC7B,6DAA6D;CAC7D,2DAA2D;CAC3D,6CAA6C;AAC/C;AAEA,MAAa,6BAA6B,CACxC,sCACA,oCACF;AAEA,MAAa,kBAAkB;CAC7B,uDAAuD;CACvD,mDAAmD;AACrD"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
const require_utils = require("./utils.cjs");
|
|
6
|
+
let _oxlint_plugins = require("@oxlint/plugins");
|
|
7
|
+
//#region src/no-raw-route-query-client.ts
|
|
8
|
+
const RAW_QUERY_CLIENT_METHODS = /* @__PURE__ */ new Map([
|
|
9
|
+
["ensureQueryData", "ensureRouteQueryData"],
|
|
10
|
+
["ensureInfiniteQueryData", "ensureRouteInfiniteQueryData"],
|
|
11
|
+
["fetchQuery", "fetchRouteQuery"],
|
|
12
|
+
["prefetchQuery", "prefetchRouteQuery"]
|
|
13
|
+
]);
|
|
14
|
+
const RAW_QUERY_CLIENT_RECEIVERS = /* @__PURE__ */ new Set(["qc", "queryClient"]);
|
|
15
|
+
const TANSTACK_QUERY_MODULE = "@tanstack/react-query";
|
|
16
|
+
const ROUTE_QUERY_HELPERS_MODULE = "@/lib/react-query";
|
|
17
|
+
const GENERIC_ROUTE_QUERY_HELPERS = /* @__PURE__ */ new Map([["ensureCriticalQueryData", "ensureRouteQueryData"], ["prefetchNonCriticalQuery", "prefetchRouteQuery"]]);
|
|
18
|
+
const QUERY_SUBSCRIPTION_HOOKS = /* @__PURE__ */ new Set([
|
|
19
|
+
"useInfiniteQuery",
|
|
20
|
+
"useQueries",
|
|
21
|
+
"useQuery",
|
|
22
|
+
"useSuspenseInfiniteQuery",
|
|
23
|
+
"useSuspenseQueries",
|
|
24
|
+
"useSuspenseQuery"
|
|
25
|
+
]);
|
|
26
|
+
const ROUTE_LOADER_HOOKS = /* @__PURE__ */ new Set(["beforeLoad", "loader"]);
|
|
27
|
+
const ROUTE_PENDING_COMPONENT_HOOK = "pendingComponent";
|
|
28
|
+
const isQueryClientReceiver = (node) => {
|
|
29
|
+
if (!node) return false;
|
|
30
|
+
if (node.type === "Identifier") return RAW_QUERY_CLIENT_RECEIVERS.has(node.name);
|
|
31
|
+
if (node.type !== "MemberExpression" || node.computed) return false;
|
|
32
|
+
return require_utils.getPropertyName(node.property) === "queryClient";
|
|
33
|
+
};
|
|
34
|
+
const findRouteLoaderHook = (node) => {
|
|
35
|
+
let current = node.parent;
|
|
36
|
+
while (current) {
|
|
37
|
+
if (current.type === "Property") {
|
|
38
|
+
const name = require_utils.getPropertyName(current.key);
|
|
39
|
+
if (name !== null && ROUTE_LOADER_HOOKS.has(name)) return name;
|
|
40
|
+
}
|
|
41
|
+
current = current.parent;
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
};
|
|
45
|
+
const findPendingComponentCandidate = (node) => {
|
|
46
|
+
let current = node.parent;
|
|
47
|
+
while (current) {
|
|
48
|
+
if (current.type === "Property") {
|
|
49
|
+
if (require_utils.getPropertyName(current.key) === ROUTE_PENDING_COMPONENT_HOOK) return ROUTE_PENDING_COMPONENT_HOOK;
|
|
50
|
+
}
|
|
51
|
+
if (current.type === "FunctionDeclaration" && require_utils.isIdentifier(current.id)) return current.id.name;
|
|
52
|
+
if (current.type === "VariableDeclarator" && require_utils.isIdentifier(current.id)) return current.id.name;
|
|
53
|
+
current = current.parent;
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
};
|
|
57
|
+
const getQuerySubscriptionHookName = (callee, queryHookAliases, tanstackQueryNamespaces) => {
|
|
58
|
+
if (require_utils.isIdentifier(callee) && queryHookAliases.has(callee.name)) return callee.name;
|
|
59
|
+
if (callee.type !== "MemberExpression" || callee.computed || !require_utils.isIdentifier(callee.object) || !tanstackQueryNamespaces.has(callee.object.name)) return null;
|
|
60
|
+
const hookName = require_utils.getPropertyName(callee.property);
|
|
61
|
+
return hookName !== null && QUERY_SUBSCRIPTION_HOOKS.has(hookName) ? hookName : null;
|
|
62
|
+
};
|
|
63
|
+
var no_raw_route_query_client_default = (0, _oxlint_plugins.eslintCompatPlugin)({
|
|
64
|
+
meta: { name: "no-raw-route-query-client" },
|
|
65
|
+
rules: { "no-raw-route-query-client": {
|
|
66
|
+
meta: {
|
|
67
|
+
type: "problem",
|
|
68
|
+
messages: {
|
|
69
|
+
noRawRouteQueryClient: "Raw queryClient.{{method}} inside route {{hook}} is forbidden. Use {{replacement}}(...), so route-seeded queries carry a freshness window.",
|
|
70
|
+
noGenericRouteQueryHelper: "Generic {{helper}} inside route {{hook}} is forbidden. Use {{replacement}}(...), so route-seeded queries carry a freshness window.",
|
|
71
|
+
noQueryHookInPendingComponent: "TanStack Query subscription hook {{hook}} is forbidden inside route pendingComponent {{component}}. Read cached data synchronously with useQueryClient().getQueryData(...) so abandoned pending renders cannot receive async state updates."
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
createOnce(context) {
|
|
75
|
+
const genericHelperAliases = /* @__PURE__ */ new Map();
|
|
76
|
+
const pendingComponentNames = /* @__PURE__ */ new Set();
|
|
77
|
+
const pendingQueryHookCalls = [];
|
|
78
|
+
const queryHookAliases = /* @__PURE__ */ new Set();
|
|
79
|
+
const routeQueryHelperNamespaces = /* @__PURE__ */ new Set();
|
|
80
|
+
const tanstackQueryNamespaces = /* @__PURE__ */ new Set();
|
|
81
|
+
return {
|
|
82
|
+
before() {
|
|
83
|
+
genericHelperAliases.clear();
|
|
84
|
+
pendingComponentNames.clear();
|
|
85
|
+
pendingQueryHookCalls.length = 0;
|
|
86
|
+
queryHookAliases.clear();
|
|
87
|
+
routeQueryHelperNamespaces.clear();
|
|
88
|
+
tanstackQueryNamespaces.clear();
|
|
89
|
+
},
|
|
90
|
+
ImportDeclaration(node) {
|
|
91
|
+
if (node.source?.value === TANSTACK_QUERY_MODULE) {
|
|
92
|
+
for (const specifier of node.specifiers) {
|
|
93
|
+
if (specifier.type === "ImportNamespaceSpecifier") {
|
|
94
|
+
tanstackQueryNamespaces.add(specifier.local.name);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
if (specifier.type !== "ImportSpecifier") continue;
|
|
98
|
+
const importedName = require_utils.getImportedName(specifier);
|
|
99
|
+
if (importedName !== null && QUERY_SUBSCRIPTION_HOOKS.has(importedName)) queryHookAliases.add(specifier.local.name);
|
|
100
|
+
}
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (node.source?.value !== ROUTE_QUERY_HELPERS_MODULE) return;
|
|
104
|
+
for (const specifier of node.specifiers) {
|
|
105
|
+
if (specifier.type === "ImportNamespaceSpecifier") {
|
|
106
|
+
routeQueryHelperNamespaces.add(specifier.local.name);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (specifier.type !== "ImportSpecifier") continue;
|
|
110
|
+
const importedName = require_utils.getImportedName(specifier);
|
|
111
|
+
const replacement = importedName === null ? void 0 : GENERIC_ROUTE_QUERY_HELPERS.get(importedName);
|
|
112
|
+
if (replacement === void 0) continue;
|
|
113
|
+
genericHelperAliases.set(specifier.local.name, {
|
|
114
|
+
helper: importedName,
|
|
115
|
+
replacement
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
Property(node) {
|
|
120
|
+
if (require_utils.getPropertyName(node.key) !== ROUTE_PENDING_COMPONENT_HOOK) return;
|
|
121
|
+
if (require_utils.isIdentifier(node.value)) pendingComponentNames.add(node.value.name);
|
|
122
|
+
},
|
|
123
|
+
CallExpression(node) {
|
|
124
|
+
const hook = findRouteLoaderHook(node);
|
|
125
|
+
const callee = node.callee;
|
|
126
|
+
if (hook !== null) {
|
|
127
|
+
if (require_utils.isIdentifier(callee)) {
|
|
128
|
+
const helper = genericHelperAliases.get(callee.name);
|
|
129
|
+
if (helper !== void 0) {
|
|
130
|
+
context.report({
|
|
131
|
+
node,
|
|
132
|
+
messageId: "noGenericRouteQueryHelper",
|
|
133
|
+
data: {
|
|
134
|
+
hook,
|
|
135
|
+
...helper
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (callee.type === "MemberExpression" && callee.computed === false && require_utils.isIdentifier(callee.object) && routeQueryHelperNamespaces.has(callee.object.name)) {
|
|
142
|
+
const helperName = require_utils.getPropertyName(callee.property);
|
|
143
|
+
const replacement = helperName === null ? void 0 : GENERIC_ROUTE_QUERY_HELPERS.get(helperName);
|
|
144
|
+
if (replacement !== void 0) {
|
|
145
|
+
context.report({
|
|
146
|
+
node,
|
|
147
|
+
messageId: "noGenericRouteQueryHelper",
|
|
148
|
+
data: {
|
|
149
|
+
helper: helperName,
|
|
150
|
+
hook,
|
|
151
|
+
replacement
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (callee.type === "MemberExpression" && !callee.computed && isQueryClientReceiver(callee.object)) {
|
|
158
|
+
const method = require_utils.getPropertyName(callee.property);
|
|
159
|
+
const replacement = method === null ? void 0 : RAW_QUERY_CLIENT_METHODS.get(method);
|
|
160
|
+
if (replacement === void 0) return;
|
|
161
|
+
context.report({
|
|
162
|
+
node,
|
|
163
|
+
messageId: "noRawRouteQueryClient",
|
|
164
|
+
data: {
|
|
165
|
+
method,
|
|
166
|
+
hook,
|
|
167
|
+
replacement
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const pendingComponent = findPendingComponentCandidate(node);
|
|
174
|
+
if (pendingComponent === null) return;
|
|
175
|
+
const queryHookName = getQuerySubscriptionHookName(callee, queryHookAliases, tanstackQueryNamespaces);
|
|
176
|
+
if (queryHookName === null) return;
|
|
177
|
+
pendingQueryHookCalls.push({
|
|
178
|
+
component: pendingComponent,
|
|
179
|
+
hook: queryHookName,
|
|
180
|
+
node
|
|
181
|
+
});
|
|
182
|
+
},
|
|
183
|
+
"Program:exit"() {
|
|
184
|
+
for (const { component, hook, node } of pendingQueryHookCalls) {
|
|
185
|
+
if (component !== ROUTE_PENDING_COMPONENT_HOOK && !pendingComponentNames.has(component)) continue;
|
|
186
|
+
context.report({
|
|
187
|
+
node,
|
|
188
|
+
messageId: "noQueryHookInPendingComponent",
|
|
189
|
+
data: {
|
|
190
|
+
component,
|
|
191
|
+
hook
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
} }
|
|
199
|
+
});
|
|
200
|
+
//#endregion
|
|
201
|
+
exports.default = no_raw_route_query_client_default;
|
|
202
|
+
|
|
203
|
+
//# sourceMappingURL=no-raw-route-query-client.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-raw-route-query-client.cjs","names":["getPropertyName","isIdentifier","getImportedName"],"sources":["../src/no-raw-route-query-client.ts"],"sourcesContent":["import { eslintCompatPlugin } from \"@oxlint/plugins\";\nimport type { Ranged } from \"@oxlint/plugins\";\n\nimport { getImportedName, getPropertyName, isIdentifier } from \"./utils.ts\";\n\nconst RAW_QUERY_CLIENT_METHODS = new Map([\n [\"ensureQueryData\", \"ensureRouteQueryData\"],\n [\"ensureInfiniteQueryData\", \"ensureRouteInfiniteQueryData\"],\n [\"fetchQuery\", \"fetchRouteQuery\"],\n [\"prefetchQuery\", \"prefetchRouteQuery\"],\n]);\nconst RAW_QUERY_CLIENT_RECEIVERS = new Set([\"qc\", \"queryClient\"]);\nconst TANSTACK_QUERY_MODULE = \"@tanstack/react-query\";\nconst ROUTE_QUERY_HELPERS_MODULE = \"@/lib/react-query\";\nconst GENERIC_ROUTE_QUERY_HELPERS = new Map([\n [\"ensureCriticalQueryData\", \"ensureRouteQueryData\"],\n [\"prefetchNonCriticalQuery\", \"prefetchRouteQuery\"],\n]);\nconst QUERY_SUBSCRIPTION_HOOKS = new Set([\n \"useInfiniteQuery\",\n \"useQueries\",\n \"useQuery\",\n \"useSuspenseInfiniteQuery\",\n \"useSuspenseQueries\",\n \"useSuspenseQuery\",\n]);\n\nconst ROUTE_LOADER_HOOKS = new Set([\"beforeLoad\", \"loader\"]);\nconst ROUTE_PENDING_COMPONENT_HOOK = \"pendingComponent\";\n\nconst isQueryClientReceiver = (node) => {\n if (!node) {\n return false;\n }\n\n if (node.type === \"Identifier\") {\n return RAW_QUERY_CLIENT_RECEIVERS.has(node.name);\n }\n\n if (node.type !== \"MemberExpression\" || node.computed) {\n return false;\n }\n\n const receiverName = getPropertyName(node.property);\n return receiverName === \"queryClient\";\n};\n\nconst findRouteLoaderHook = (node) => {\n let current = node.parent;\n\n while (current) {\n if (current.type === \"Property\") {\n const name = getPropertyName(current.key);\n\n if (name !== null && ROUTE_LOADER_HOOKS.has(name)) {\n return name;\n }\n }\n\n current = current.parent;\n }\n\n return null;\n};\n\nconst findPendingComponentCandidate = (node) => {\n let current = node.parent;\n\n while (current) {\n if (current.type === \"Property\") {\n const name = getPropertyName(current.key);\n\n if (name === ROUTE_PENDING_COMPONENT_HOOK) {\n return ROUTE_PENDING_COMPONENT_HOOK;\n }\n }\n\n if (current.type === \"FunctionDeclaration\" && isIdentifier(current.id)) {\n return current.id.name;\n }\n\n if (current.type === \"VariableDeclarator\" && isIdentifier(current.id)) {\n return current.id.name;\n }\n\n current = current.parent;\n }\n\n return null;\n};\n\nconst getQuerySubscriptionHookName = (\n callee,\n queryHookAliases,\n tanstackQueryNamespaces,\n) => {\n if (isIdentifier(callee) && queryHookAliases.has(callee.name)) {\n return callee.name;\n }\n\n if (\n callee.type !== \"MemberExpression\" ||\n callee.computed ||\n !isIdentifier(callee.object) ||\n !tanstackQueryNamespaces.has(callee.object.name)\n ) {\n return null;\n }\n\n const hookName = getPropertyName(callee.property);\n return hookName !== null && QUERY_SUBSCRIPTION_HOOKS.has(hookName)\n ? hookName\n : null;\n};\n\nexport default eslintCompatPlugin({\n meta: { name: \"no-raw-route-query-client\" },\n rules: {\n \"no-raw-route-query-client\": {\n meta: {\n type: \"problem\",\n messages: {\n noRawRouteQueryClient:\n \"Raw queryClient.{{method}} inside route {{hook}} \" +\n \"is forbidden. Use {{replacement}}(...), so route-seeded \" +\n \"queries carry a freshness window.\",\n noGenericRouteQueryHelper:\n \"Generic {{helper}} inside route {{hook}} is forbidden. \" +\n \"Use {{replacement}}(...), so route-seeded queries carry \" +\n \"a freshness window.\",\n noQueryHookInPendingComponent:\n \"TanStack Query subscription hook {{hook}} is forbidden \" +\n \"inside route pendingComponent {{component}}. Read cached \" +\n \"data synchronously with useQueryClient().getQueryData(...) \" +\n \"so abandoned pending renders cannot receive async state updates.\",\n },\n },\n createOnce(context) {\n const genericHelperAliases = new Map();\n const pendingComponentNames = new Set();\n const pendingQueryHookCalls: {\n component: string;\n hook: string;\n node: Ranged;\n }[] = [];\n const queryHookAliases = new Set();\n const routeQueryHelperNamespaces = new Set();\n const tanstackQueryNamespaces = new Set();\n\n return {\n before() {\n genericHelperAliases.clear();\n pendingComponentNames.clear();\n pendingQueryHookCalls.length = 0;\n queryHookAliases.clear();\n routeQueryHelperNamespaces.clear();\n tanstackQueryNamespaces.clear();\n },\n ImportDeclaration(node) {\n if (node.source?.value === TANSTACK_QUERY_MODULE) {\n for (const specifier of node.specifiers) {\n if (specifier.type === \"ImportNamespaceSpecifier\") {\n tanstackQueryNamespaces.add(specifier.local.name);\n continue;\n }\n if (specifier.type !== \"ImportSpecifier\") {\n continue;\n }\n\n const importedName = getImportedName(specifier);\n if (\n importedName !== null &&\n QUERY_SUBSCRIPTION_HOOKS.has(importedName)\n ) {\n queryHookAliases.add(specifier.local.name);\n }\n }\n return;\n }\n\n if (node.source?.value !== ROUTE_QUERY_HELPERS_MODULE) {\n return;\n }\n\n for (const specifier of node.specifiers) {\n if (specifier.type === \"ImportNamespaceSpecifier\") {\n routeQueryHelperNamespaces.add(specifier.local.name);\n continue;\n }\n if (specifier.type !== \"ImportSpecifier\") {\n continue;\n }\n\n const importedName = getImportedName(specifier);\n const replacement =\n importedName === null\n ? undefined\n : GENERIC_ROUTE_QUERY_HELPERS.get(importedName);\n if (replacement === undefined) {\n continue;\n }\n\n genericHelperAliases.set(specifier.local.name, {\n helper: importedName,\n replacement,\n });\n }\n },\n\n Property(node) {\n const name = getPropertyName(node.key);\n if (name !== ROUTE_PENDING_COMPONENT_HOOK) {\n return;\n }\n if (isIdentifier(node.value)) {\n pendingComponentNames.add(node.value.name);\n }\n },\n\n CallExpression(node) {\n const hook = findRouteLoaderHook(node);\n const callee = node.callee;\n\n if (hook !== null) {\n if (isIdentifier(callee)) {\n const helper = genericHelperAliases.get(callee.name);\n if (helper !== undefined) {\n context.report({\n node,\n messageId: \"noGenericRouteQueryHelper\",\n data: { hook, ...helper },\n });\n return;\n }\n }\n\n if (\n callee.type === \"MemberExpression\" &&\n callee.computed === false &&\n isIdentifier(callee.object) &&\n routeQueryHelperNamespaces.has(callee.object.name)\n ) {\n const helperName = getPropertyName(callee.property);\n const replacement =\n helperName === null\n ? undefined\n : GENERIC_ROUTE_QUERY_HELPERS.get(helperName);\n\n if (replacement !== undefined) {\n context.report({\n node,\n messageId: \"noGenericRouteQueryHelper\",\n data: { helper: helperName, hook, replacement },\n });\n return;\n }\n }\n\n if (\n callee.type === \"MemberExpression\" &&\n !callee.computed &&\n isQueryClientReceiver(callee.object)\n ) {\n const method = getPropertyName(callee.property);\n const replacement =\n method === null\n ? undefined\n : RAW_QUERY_CLIENT_METHODS.get(method);\n\n if (replacement === undefined) {\n return;\n }\n\n context.report({\n node,\n messageId: \"noRawRouteQueryClient\",\n data: { method, hook, replacement },\n });\n return;\n }\n }\n\n const pendingComponent = findPendingComponentCandidate(node);\n if (pendingComponent === null) {\n return;\n }\n\n const queryHookName = getQuerySubscriptionHookName(\n callee,\n queryHookAliases,\n tanstackQueryNamespaces,\n );\n if (queryHookName === null) {\n return;\n }\n\n pendingQueryHookCalls.push({\n component: pendingComponent,\n hook: queryHookName,\n node,\n });\n },\n\n \"Program:exit\"() {\n for (const { component, hook, node } of pendingQueryHookCalls) {\n if (\n component !== ROUTE_PENDING_COMPONENT_HOOK &&\n !pendingComponentNames.has(component)\n ) {\n continue;\n }\n\n context.report({\n node,\n messageId: \"noQueryHookInPendingComponent\",\n data: { component, hook },\n });\n }\n },\n };\n },\n },\n },\n});\n"],"mappings":"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"}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { i as isIdentifier, n as getImportedName, r as getPropertyName } from "./utils.mjs";
|
|
2
|
+
import { eslintCompatPlugin } from "@oxlint/plugins";
|
|
3
|
+
//#region src/no-raw-route-query-client.ts
|
|
4
|
+
const RAW_QUERY_CLIENT_METHODS = /* @__PURE__ */ new Map([
|
|
5
|
+
["ensureQueryData", "ensureRouteQueryData"],
|
|
6
|
+
["ensureInfiniteQueryData", "ensureRouteInfiniteQueryData"],
|
|
7
|
+
["fetchQuery", "fetchRouteQuery"],
|
|
8
|
+
["prefetchQuery", "prefetchRouteQuery"]
|
|
9
|
+
]);
|
|
10
|
+
const RAW_QUERY_CLIENT_RECEIVERS = /* @__PURE__ */ new Set(["qc", "queryClient"]);
|
|
11
|
+
const TANSTACK_QUERY_MODULE = "@tanstack/react-query";
|
|
12
|
+
const ROUTE_QUERY_HELPERS_MODULE = "@/lib/react-query";
|
|
13
|
+
const GENERIC_ROUTE_QUERY_HELPERS = /* @__PURE__ */ new Map([["ensureCriticalQueryData", "ensureRouteQueryData"], ["prefetchNonCriticalQuery", "prefetchRouteQuery"]]);
|
|
14
|
+
const QUERY_SUBSCRIPTION_HOOKS = /* @__PURE__ */ new Set([
|
|
15
|
+
"useInfiniteQuery",
|
|
16
|
+
"useQueries",
|
|
17
|
+
"useQuery",
|
|
18
|
+
"useSuspenseInfiniteQuery",
|
|
19
|
+
"useSuspenseQueries",
|
|
20
|
+
"useSuspenseQuery"
|
|
21
|
+
]);
|
|
22
|
+
const ROUTE_LOADER_HOOKS = /* @__PURE__ */ new Set(["beforeLoad", "loader"]);
|
|
23
|
+
const ROUTE_PENDING_COMPONENT_HOOK = "pendingComponent";
|
|
24
|
+
const isQueryClientReceiver = (node) => {
|
|
25
|
+
if (!node) return false;
|
|
26
|
+
if (node.type === "Identifier") return RAW_QUERY_CLIENT_RECEIVERS.has(node.name);
|
|
27
|
+
if (node.type !== "MemberExpression" || node.computed) return false;
|
|
28
|
+
return getPropertyName(node.property) === "queryClient";
|
|
29
|
+
};
|
|
30
|
+
const findRouteLoaderHook = (node) => {
|
|
31
|
+
let current = node.parent;
|
|
32
|
+
while (current) {
|
|
33
|
+
if (current.type === "Property") {
|
|
34
|
+
const name = getPropertyName(current.key);
|
|
35
|
+
if (name !== null && ROUTE_LOADER_HOOKS.has(name)) return name;
|
|
36
|
+
}
|
|
37
|
+
current = current.parent;
|
|
38
|
+
}
|
|
39
|
+
return null;
|
|
40
|
+
};
|
|
41
|
+
const findPendingComponentCandidate = (node) => {
|
|
42
|
+
let current = node.parent;
|
|
43
|
+
while (current) {
|
|
44
|
+
if (current.type === "Property") {
|
|
45
|
+
if (getPropertyName(current.key) === ROUTE_PENDING_COMPONENT_HOOK) return ROUTE_PENDING_COMPONENT_HOOK;
|
|
46
|
+
}
|
|
47
|
+
if (current.type === "FunctionDeclaration" && isIdentifier(current.id)) return current.id.name;
|
|
48
|
+
if (current.type === "VariableDeclarator" && isIdentifier(current.id)) return current.id.name;
|
|
49
|
+
current = current.parent;
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
};
|
|
53
|
+
const getQuerySubscriptionHookName = (callee, queryHookAliases, tanstackQueryNamespaces) => {
|
|
54
|
+
if (isIdentifier(callee) && queryHookAliases.has(callee.name)) return callee.name;
|
|
55
|
+
if (callee.type !== "MemberExpression" || callee.computed || !isIdentifier(callee.object) || !tanstackQueryNamespaces.has(callee.object.name)) return null;
|
|
56
|
+
const hookName = getPropertyName(callee.property);
|
|
57
|
+
return hookName !== null && QUERY_SUBSCRIPTION_HOOKS.has(hookName) ? hookName : null;
|
|
58
|
+
};
|
|
59
|
+
var no_raw_route_query_client_default = eslintCompatPlugin({
|
|
60
|
+
meta: { name: "no-raw-route-query-client" },
|
|
61
|
+
rules: { "no-raw-route-query-client": {
|
|
62
|
+
meta: {
|
|
63
|
+
type: "problem",
|
|
64
|
+
messages: {
|
|
65
|
+
noRawRouteQueryClient: "Raw queryClient.{{method}} inside route {{hook}} is forbidden. Use {{replacement}}(...), so route-seeded queries carry a freshness window.",
|
|
66
|
+
noGenericRouteQueryHelper: "Generic {{helper}} inside route {{hook}} is forbidden. Use {{replacement}}(...), so route-seeded queries carry a freshness window.",
|
|
67
|
+
noQueryHookInPendingComponent: "TanStack Query subscription hook {{hook}} is forbidden inside route pendingComponent {{component}}. Read cached data synchronously with useQueryClient().getQueryData(...) so abandoned pending renders cannot receive async state updates."
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
createOnce(context) {
|
|
71
|
+
const genericHelperAliases = /* @__PURE__ */ new Map();
|
|
72
|
+
const pendingComponentNames = /* @__PURE__ */ new Set();
|
|
73
|
+
const pendingQueryHookCalls = [];
|
|
74
|
+
const queryHookAliases = /* @__PURE__ */ new Set();
|
|
75
|
+
const routeQueryHelperNamespaces = /* @__PURE__ */ new Set();
|
|
76
|
+
const tanstackQueryNamespaces = /* @__PURE__ */ new Set();
|
|
77
|
+
return {
|
|
78
|
+
before() {
|
|
79
|
+
genericHelperAliases.clear();
|
|
80
|
+
pendingComponentNames.clear();
|
|
81
|
+
pendingQueryHookCalls.length = 0;
|
|
82
|
+
queryHookAliases.clear();
|
|
83
|
+
routeQueryHelperNamespaces.clear();
|
|
84
|
+
tanstackQueryNamespaces.clear();
|
|
85
|
+
},
|
|
86
|
+
ImportDeclaration(node) {
|
|
87
|
+
if (node.source?.value === TANSTACK_QUERY_MODULE) {
|
|
88
|
+
for (const specifier of node.specifiers) {
|
|
89
|
+
if (specifier.type === "ImportNamespaceSpecifier") {
|
|
90
|
+
tanstackQueryNamespaces.add(specifier.local.name);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (specifier.type !== "ImportSpecifier") continue;
|
|
94
|
+
const importedName = getImportedName(specifier);
|
|
95
|
+
if (importedName !== null && QUERY_SUBSCRIPTION_HOOKS.has(importedName)) queryHookAliases.add(specifier.local.name);
|
|
96
|
+
}
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (node.source?.value !== ROUTE_QUERY_HELPERS_MODULE) return;
|
|
100
|
+
for (const specifier of node.specifiers) {
|
|
101
|
+
if (specifier.type === "ImportNamespaceSpecifier") {
|
|
102
|
+
routeQueryHelperNamespaces.add(specifier.local.name);
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
if (specifier.type !== "ImportSpecifier") continue;
|
|
106
|
+
const importedName = getImportedName(specifier);
|
|
107
|
+
const replacement = importedName === null ? void 0 : GENERIC_ROUTE_QUERY_HELPERS.get(importedName);
|
|
108
|
+
if (replacement === void 0) continue;
|
|
109
|
+
genericHelperAliases.set(specifier.local.name, {
|
|
110
|
+
helper: importedName,
|
|
111
|
+
replacement
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
Property(node) {
|
|
116
|
+
if (getPropertyName(node.key) !== ROUTE_PENDING_COMPONENT_HOOK) return;
|
|
117
|
+
if (isIdentifier(node.value)) pendingComponentNames.add(node.value.name);
|
|
118
|
+
},
|
|
119
|
+
CallExpression(node) {
|
|
120
|
+
const hook = findRouteLoaderHook(node);
|
|
121
|
+
const callee = node.callee;
|
|
122
|
+
if (hook !== null) {
|
|
123
|
+
if (isIdentifier(callee)) {
|
|
124
|
+
const helper = genericHelperAliases.get(callee.name);
|
|
125
|
+
if (helper !== void 0) {
|
|
126
|
+
context.report({
|
|
127
|
+
node,
|
|
128
|
+
messageId: "noGenericRouteQueryHelper",
|
|
129
|
+
data: {
|
|
130
|
+
hook,
|
|
131
|
+
...helper
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (callee.type === "MemberExpression" && callee.computed === false && isIdentifier(callee.object) && routeQueryHelperNamespaces.has(callee.object.name)) {
|
|
138
|
+
const helperName = getPropertyName(callee.property);
|
|
139
|
+
const replacement = helperName === null ? void 0 : GENERIC_ROUTE_QUERY_HELPERS.get(helperName);
|
|
140
|
+
if (replacement !== void 0) {
|
|
141
|
+
context.report({
|
|
142
|
+
node,
|
|
143
|
+
messageId: "noGenericRouteQueryHelper",
|
|
144
|
+
data: {
|
|
145
|
+
helper: helperName,
|
|
146
|
+
hook,
|
|
147
|
+
replacement
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (callee.type === "MemberExpression" && !callee.computed && isQueryClientReceiver(callee.object)) {
|
|
154
|
+
const method = getPropertyName(callee.property);
|
|
155
|
+
const replacement = method === null ? void 0 : RAW_QUERY_CLIENT_METHODS.get(method);
|
|
156
|
+
if (replacement === void 0) return;
|
|
157
|
+
context.report({
|
|
158
|
+
node,
|
|
159
|
+
messageId: "noRawRouteQueryClient",
|
|
160
|
+
data: {
|
|
161
|
+
method,
|
|
162
|
+
hook,
|
|
163
|
+
replacement
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const pendingComponent = findPendingComponentCandidate(node);
|
|
170
|
+
if (pendingComponent === null) return;
|
|
171
|
+
const queryHookName = getQuerySubscriptionHookName(callee, queryHookAliases, tanstackQueryNamespaces);
|
|
172
|
+
if (queryHookName === null) return;
|
|
173
|
+
pendingQueryHookCalls.push({
|
|
174
|
+
component: pendingComponent,
|
|
175
|
+
hook: queryHookName,
|
|
176
|
+
node
|
|
177
|
+
});
|
|
178
|
+
},
|
|
179
|
+
"Program:exit"() {
|
|
180
|
+
for (const { component, hook, node } of pendingQueryHookCalls) {
|
|
181
|
+
if (component !== ROUTE_PENDING_COMPONENT_HOOK && !pendingComponentNames.has(component)) continue;
|
|
182
|
+
context.report({
|
|
183
|
+
node,
|
|
184
|
+
messageId: "noQueryHookInPendingComponent",
|
|
185
|
+
data: {
|
|
186
|
+
component,
|
|
187
|
+
hook
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
} }
|
|
195
|
+
});
|
|
196
|
+
//#endregion
|
|
197
|
+
export { no_raw_route_query_client_default as default };
|
|
198
|
+
|
|
199
|
+
//# sourceMappingURL=no-raw-route-query-client.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-raw-route-query-client.mjs","names":[],"sources":["../src/no-raw-route-query-client.ts"],"sourcesContent":["import { eslintCompatPlugin } from \"@oxlint/plugins\";\nimport type { Ranged } from \"@oxlint/plugins\";\n\nimport { getImportedName, getPropertyName, isIdentifier } from \"./utils.ts\";\n\nconst RAW_QUERY_CLIENT_METHODS = new Map([\n [\"ensureQueryData\", \"ensureRouteQueryData\"],\n [\"ensureInfiniteQueryData\", \"ensureRouteInfiniteQueryData\"],\n [\"fetchQuery\", \"fetchRouteQuery\"],\n [\"prefetchQuery\", \"prefetchRouteQuery\"],\n]);\nconst RAW_QUERY_CLIENT_RECEIVERS = new Set([\"qc\", \"queryClient\"]);\nconst TANSTACK_QUERY_MODULE = \"@tanstack/react-query\";\nconst ROUTE_QUERY_HELPERS_MODULE = \"@/lib/react-query\";\nconst GENERIC_ROUTE_QUERY_HELPERS = new Map([\n [\"ensureCriticalQueryData\", \"ensureRouteQueryData\"],\n [\"prefetchNonCriticalQuery\", \"prefetchRouteQuery\"],\n]);\nconst QUERY_SUBSCRIPTION_HOOKS = new Set([\n \"useInfiniteQuery\",\n \"useQueries\",\n \"useQuery\",\n \"useSuspenseInfiniteQuery\",\n \"useSuspenseQueries\",\n \"useSuspenseQuery\",\n]);\n\nconst ROUTE_LOADER_HOOKS = new Set([\"beforeLoad\", \"loader\"]);\nconst ROUTE_PENDING_COMPONENT_HOOK = \"pendingComponent\";\n\nconst isQueryClientReceiver = (node) => {\n if (!node) {\n return false;\n }\n\n if (node.type === \"Identifier\") {\n return RAW_QUERY_CLIENT_RECEIVERS.has(node.name);\n }\n\n if (node.type !== \"MemberExpression\" || node.computed) {\n return false;\n }\n\n const receiverName = getPropertyName(node.property);\n return receiverName === \"queryClient\";\n};\n\nconst findRouteLoaderHook = (node) => {\n let current = node.parent;\n\n while (current) {\n if (current.type === \"Property\") {\n const name = getPropertyName(current.key);\n\n if (name !== null && ROUTE_LOADER_HOOKS.has(name)) {\n return name;\n }\n }\n\n current = current.parent;\n }\n\n return null;\n};\n\nconst findPendingComponentCandidate = (node) => {\n let current = node.parent;\n\n while (current) {\n if (current.type === \"Property\") {\n const name = getPropertyName(current.key);\n\n if (name === ROUTE_PENDING_COMPONENT_HOOK) {\n return ROUTE_PENDING_COMPONENT_HOOK;\n }\n }\n\n if (current.type === \"FunctionDeclaration\" && isIdentifier(current.id)) {\n return current.id.name;\n }\n\n if (current.type === \"VariableDeclarator\" && isIdentifier(current.id)) {\n return current.id.name;\n }\n\n current = current.parent;\n }\n\n return null;\n};\n\nconst getQuerySubscriptionHookName = (\n callee,\n queryHookAliases,\n tanstackQueryNamespaces,\n) => {\n if (isIdentifier(callee) && queryHookAliases.has(callee.name)) {\n return callee.name;\n }\n\n if (\n callee.type !== \"MemberExpression\" ||\n callee.computed ||\n !isIdentifier(callee.object) ||\n !tanstackQueryNamespaces.has(callee.object.name)\n ) {\n return null;\n }\n\n const hookName = getPropertyName(callee.property);\n return hookName !== null && QUERY_SUBSCRIPTION_HOOKS.has(hookName)\n ? hookName\n : null;\n};\n\nexport default eslintCompatPlugin({\n meta: { name: \"no-raw-route-query-client\" },\n rules: {\n \"no-raw-route-query-client\": {\n meta: {\n type: \"problem\",\n messages: {\n noRawRouteQueryClient:\n \"Raw queryClient.{{method}} inside route {{hook}} \" +\n \"is forbidden. Use {{replacement}}(...), so route-seeded \" +\n \"queries carry a freshness window.\",\n noGenericRouteQueryHelper:\n \"Generic {{helper}} inside route {{hook}} is forbidden. \" +\n \"Use {{replacement}}(...), so route-seeded queries carry \" +\n \"a freshness window.\",\n noQueryHookInPendingComponent:\n \"TanStack Query subscription hook {{hook}} is forbidden \" +\n \"inside route pendingComponent {{component}}. Read cached \" +\n \"data synchronously with useQueryClient().getQueryData(...) \" +\n \"so abandoned pending renders cannot receive async state updates.\",\n },\n },\n createOnce(context) {\n const genericHelperAliases = new Map();\n const pendingComponentNames = new Set();\n const pendingQueryHookCalls: {\n component: string;\n hook: string;\n node: Ranged;\n }[] = [];\n const queryHookAliases = new Set();\n const routeQueryHelperNamespaces = new Set();\n const tanstackQueryNamespaces = new Set();\n\n return {\n before() {\n genericHelperAliases.clear();\n pendingComponentNames.clear();\n pendingQueryHookCalls.length = 0;\n queryHookAliases.clear();\n routeQueryHelperNamespaces.clear();\n tanstackQueryNamespaces.clear();\n },\n ImportDeclaration(node) {\n if (node.source?.value === TANSTACK_QUERY_MODULE) {\n for (const specifier of node.specifiers) {\n if (specifier.type === \"ImportNamespaceSpecifier\") {\n tanstackQueryNamespaces.add(specifier.local.name);\n continue;\n }\n if (specifier.type !== \"ImportSpecifier\") {\n continue;\n }\n\n const importedName = getImportedName(specifier);\n if (\n importedName !== null &&\n QUERY_SUBSCRIPTION_HOOKS.has(importedName)\n ) {\n queryHookAliases.add(specifier.local.name);\n }\n }\n return;\n }\n\n if (node.source?.value !== ROUTE_QUERY_HELPERS_MODULE) {\n return;\n }\n\n for (const specifier of node.specifiers) {\n if (specifier.type === \"ImportNamespaceSpecifier\") {\n routeQueryHelperNamespaces.add(specifier.local.name);\n continue;\n }\n if (specifier.type !== \"ImportSpecifier\") {\n continue;\n }\n\n const importedName = getImportedName(specifier);\n const replacement =\n importedName === null\n ? undefined\n : GENERIC_ROUTE_QUERY_HELPERS.get(importedName);\n if (replacement === undefined) {\n continue;\n }\n\n genericHelperAliases.set(specifier.local.name, {\n helper: importedName,\n replacement,\n });\n }\n },\n\n Property(node) {\n const name = getPropertyName(node.key);\n if (name !== ROUTE_PENDING_COMPONENT_HOOK) {\n return;\n }\n if (isIdentifier(node.value)) {\n pendingComponentNames.add(node.value.name);\n }\n },\n\n CallExpression(node) {\n const hook = findRouteLoaderHook(node);\n const callee = node.callee;\n\n if (hook !== null) {\n if (isIdentifier(callee)) {\n const helper = genericHelperAliases.get(callee.name);\n if (helper !== undefined) {\n context.report({\n node,\n messageId: \"noGenericRouteQueryHelper\",\n data: { hook, ...helper },\n });\n return;\n }\n }\n\n if (\n callee.type === \"MemberExpression\" &&\n callee.computed === false &&\n isIdentifier(callee.object) &&\n routeQueryHelperNamespaces.has(callee.object.name)\n ) {\n const helperName = getPropertyName(callee.property);\n const replacement =\n helperName === null\n ? undefined\n : GENERIC_ROUTE_QUERY_HELPERS.get(helperName);\n\n if (replacement !== undefined) {\n context.report({\n node,\n messageId: \"noGenericRouteQueryHelper\",\n data: { helper: helperName, hook, replacement },\n });\n return;\n }\n }\n\n if (\n callee.type === \"MemberExpression\" &&\n !callee.computed &&\n isQueryClientReceiver(callee.object)\n ) {\n const method = getPropertyName(callee.property);\n const replacement =\n method === null\n ? undefined\n : RAW_QUERY_CLIENT_METHODS.get(method);\n\n if (replacement === undefined) {\n return;\n }\n\n context.report({\n node,\n messageId: \"noRawRouteQueryClient\",\n data: { method, hook, replacement },\n });\n return;\n }\n }\n\n const pendingComponent = findPendingComponentCandidate(node);\n if (pendingComponent === null) {\n return;\n }\n\n const queryHookName = getQuerySubscriptionHookName(\n callee,\n queryHookAliases,\n tanstackQueryNamespaces,\n );\n if (queryHookName === null) {\n return;\n }\n\n pendingQueryHookCalls.push({\n component: pendingComponent,\n hook: queryHookName,\n node,\n });\n },\n\n \"Program:exit\"() {\n for (const { component, hook, node } of pendingQueryHookCalls) {\n if (\n component !== ROUTE_PENDING_COMPONENT_HOOK &&\n !pendingComponentNames.has(component)\n ) {\n continue;\n }\n\n context.report({\n node,\n messageId: \"noQueryHookInPendingComponent\",\n data: { component, hook },\n });\n }\n },\n };\n },\n },\n },\n});\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as
|
|
1
|
+
import { i as isIdentifier, o as unwrapExpression, r as getPropertyName, t as getCalleeName } from "./utils.mjs";
|
|
2
2
|
import { eslintCompatPlugin } from "@oxlint/plugins";
|
|
3
3
|
//#region src/no-unsafe-inner-html.ts
|
|
4
4
|
const HTML_SANITIZER_LEAF_RE = /^(?:escape(?:html|xml)|sanitize(?:html|dom)|purify(?:html|dom)|dompurify)$/iu;
|