@openapi-qraft/eslint-plugin-query 2.12.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/CHANGELOG.md +9 -0
- package/README.md +131 -0
- package/dist/cjs/index.cjs +44 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/rules/no-rest-destructuring/no-rest-destructuring.rule.cjs +116 -0
- package/dist/cjs/rules/no-rest-destructuring/no-rest-destructuring.rule.cjs.map +1 -0
- package/dist/cjs/rules/no-rest-destructuring/no-rest-destructuring.utils.cjs +15 -0
- package/dist/cjs/rules/no-rest-destructuring/no-rest-destructuring.utils.cjs.map +1 -0
- package/dist/cjs/rules/no-unstable-deps/no-unstable-deps.rule.cjs +126 -0
- package/dist/cjs/rules/no-unstable-deps/no-unstable-deps.rule.cjs.map +1 -0
- package/dist/cjs/rules.cjs +12 -0
- package/dist/cjs/rules.cjs.map +1 -0
- package/dist/cjs/utils/create-client-name-regex.cjs +27 -0
- package/dist/cjs/utils/create-client-name-regex.cjs.map +1 -0
- package/dist/cjs/utils/get-docs-url.cjs +6 -0
- package/dist/cjs/utils/get-docs-url.cjs.map +1 -0
- package/dist/cjs/utils/get-root-identifier.cjs +22 -0
- package/dist/cjs/utils/get-root-identifier.cjs.map +1 -0
- package/dist/esm/index.js +37 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/rules/no-rest-destructuring/no-rest-destructuring.rule.js +113 -0
- package/dist/esm/rules/no-rest-destructuring/no-rest-destructuring.rule.js.map +1 -0
- package/dist/esm/rules/no-rest-destructuring/no-rest-destructuring.utils.js +13 -0
- package/dist/esm/rules/no-rest-destructuring/no-rest-destructuring.utils.js.map +1 -0
- package/dist/esm/rules/no-unstable-deps/no-unstable-deps.rule.js +121 -0
- package/dist/esm/rules/no-unstable-deps/no-unstable-deps.rule.js.map +1 -0
- package/dist/esm/rules.js +10 -0
- package/dist/esm/rules.js.map +1 -0
- package/dist/esm/utils/create-client-name-regex.js +25 -0
- package/dist/esm/utils/create-client-name-regex.js.map +1 -0
- package/dist/esm/utils/get-docs-url.js +4 -0
- package/dist/esm/utils/get-docs-url.js.map +1 -0
- package/dist/esm/utils/get-root-identifier.js +20 -0
- package/dist/esm/utils/get-root-identifier.js.map +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/rules/no-rest-destructuring/no-rest-destructuring.rule.d.ts +5 -0
- package/dist/types/rules/no-rest-destructuring/no-rest-destructuring.rule.d.ts.map +1 -0
- package/dist/types/rules/no-rest-destructuring/no-rest-destructuring.utils.d.ts +5 -0
- package/dist/types/rules/no-rest-destructuring/no-rest-destructuring.utils.d.ts.map +1 -0
- package/dist/types/rules/no-unstable-deps/no-unstable-deps.rule.d.ts +7 -0
- package/dist/types/rules/no-unstable-deps/no-unstable-deps.rule.d.ts.map +1 -0
- package/dist/types/rules.d.ts +4 -0
- package/dist/types/rules.d.ts.map +1 -0
- package/dist/types/types.d.ts +4 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/utils/create-client-name-regex.d.ts +2 -0
- package/dist/types/utils/create-client-name-regex.d.ts.map +1 -0
- package/dist/types/utils/get-docs-url.d.ts +2 -0
- package/dist/types/utils/get-docs-url.d.ts.map +1 -0
- package/dist/types/utils/get-root-identifier.d.ts +3 -0
- package/dist/types/utils/get-root-identifier.d.ts.map +1 -0
- package/package.json +67 -0
- package/src/index.ts +54 -0
- package/src/rules/no-rest-destructuring/no-rest-destructuring.rule.ts +135 -0
- package/src/rules/no-rest-destructuring/no-rest-destructuring.utils.ts +11 -0
- package/src/rules/no-unstable-deps/no-unstable-deps.rule.ts +137 -0
- package/src/rules.ts +17 -0
- package/src/types.ts +3 -0
- package/src/utils/create-client-name-regex.ts +32 -0
- package/src/utils/get-docs-url.ts +2 -0
- package/src/utils/get-root-identifier.ts +25 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
2
|
+
import { createClientNameRegex } from '../../utils/create-client-name-regex.js';
|
|
3
|
+
import { getDocsUrl } from '../../utils/get-docs-url.js';
|
|
4
|
+
import { getRootIdentifier } from '../../utils/get-root-identifier.js';
|
|
5
|
+
import { NoRestDestructuringUtils } from './no-rest-destructuring.utils.js';
|
|
6
|
+
|
|
7
|
+
const name = 'no-rest-destructuring';
|
|
8
|
+
const createRule = ESLintUtils.RuleCreator(getDocsUrl);
|
|
9
|
+
const queryHooks = [
|
|
10
|
+
'useQuery',
|
|
11
|
+
'useQueries',
|
|
12
|
+
'useInfiniteQuery',
|
|
13
|
+
'useSuspenseQuery',
|
|
14
|
+
'useSuspenseQueries',
|
|
15
|
+
'useSuspenseInfiniteQuery'
|
|
16
|
+
];
|
|
17
|
+
const rule = createRule({
|
|
18
|
+
name,
|
|
19
|
+
meta: {
|
|
20
|
+
type: 'problem',
|
|
21
|
+
docs: {
|
|
22
|
+
description: 'Disallows rest destructuring in queries',
|
|
23
|
+
recommended: 'warn'
|
|
24
|
+
},
|
|
25
|
+
messages: {
|
|
26
|
+
objectRestDestructure: `Object rest destructuring on a query will observe all changes to the query, leading to excessive re-renders.`
|
|
27
|
+
},
|
|
28
|
+
schema: [
|
|
29
|
+
{
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: {
|
|
32
|
+
clientNamePattern: {
|
|
33
|
+
type: 'string'
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
additionalProperties: false
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
defaultOptions: [
|
|
41
|
+
{}
|
|
42
|
+
],
|
|
43
|
+
create: (context)=>{
|
|
44
|
+
const option = context.options[0] ?? {};
|
|
45
|
+
const clientRegex = createClientNameRegex(option.clientNamePattern);
|
|
46
|
+
const queryResultVariables = new Set();
|
|
47
|
+
return {
|
|
48
|
+
CallExpression: (node)=>{
|
|
49
|
+
if (node.parent.type !== AST_NODE_TYPES.VariableDeclarator) return;
|
|
50
|
+
const callee = node.callee;
|
|
51
|
+
if (callee.type !== AST_NODE_TYPES.MemberExpression) return;
|
|
52
|
+
const hookName = getHookNameIfTargetFromClient(clientRegex, callee);
|
|
53
|
+
if (!hookName) return;
|
|
54
|
+
const returnValue = node.parent.id;
|
|
55
|
+
if (hookName !== 'useQueries' && hookName !== 'useSuspenseQueries') {
|
|
56
|
+
if (NoRestDestructuringUtils.isObjectRestDestructuring(returnValue)) {
|
|
57
|
+
return context.report({
|
|
58
|
+
node: node.parent,
|
|
59
|
+
messageId: 'objectRestDestructure'
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (returnValue.type === AST_NODE_TYPES.Identifier) {
|
|
63
|
+
queryResultVariables.add(returnValue.name);
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (returnValue.type !== AST_NODE_TYPES.ArrayPattern) {
|
|
68
|
+
if (returnValue.type === AST_NODE_TYPES.Identifier) {
|
|
69
|
+
queryResultVariables.add(returnValue.name);
|
|
70
|
+
}
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
returnValue.elements.forEach((queryResult)=>{
|
|
74
|
+
if (queryResult === null) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (NoRestDestructuringUtils.isObjectRestDestructuring(queryResult)) {
|
|
78
|
+
context.report({
|
|
79
|
+
node: queryResult,
|
|
80
|
+
messageId: 'objectRestDestructure'
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
VariableDeclarator: (node)=>{
|
|
86
|
+
if (node.init?.type === AST_NODE_TYPES.Identifier && queryResultVariables.has(node.init.name) && NoRestDestructuringUtils.isObjectRestDestructuring(node.id)) {
|
|
87
|
+
context.report({
|
|
88
|
+
node,
|
|
89
|
+
messageId: 'objectRestDestructure'
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
SpreadElement: (node)=>{
|
|
94
|
+
if (node.argument.type === AST_NODE_TYPES.Identifier && queryResultVariables.has(node.argument.name)) {
|
|
95
|
+
context.report({
|
|
96
|
+
node,
|
|
97
|
+
messageId: 'objectRestDestructure'
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
function getHookNameIfTargetFromClient(clientRegex, callee) {
|
|
105
|
+
if (callee.property.type !== AST_NODE_TYPES.Identifier) return;
|
|
106
|
+
const name = callee.property.name;
|
|
107
|
+
if (!queryHooks.includes(name)) return;
|
|
108
|
+
const root = getRootIdentifier(callee.object);
|
|
109
|
+
return root && clientRegex.test(root.name) ? name : undefined;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export { name, rule };
|
|
113
|
+
//# sourceMappingURL=no-rest-destructuring.rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-rest-destructuring.rule.js","sources":["../../../../src/rules/no-rest-destructuring/no-rest-destructuring.rule.ts"],"sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport type { ExtraRuleDocs } from '../../types';\nimport { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';\nimport { createClientNameRegex } from '../../utils/create-client-name-regex';\nimport { getDocsUrl } from '../../utils/get-docs-url';\nimport { getRootIdentifier } from '../../utils/get-root-identifier';\nimport { NoRestDestructuringUtils } from './no-rest-destructuring.utils';\n\nexport const name = 'no-rest-destructuring';\n\nconst createRule = ESLintUtils.RuleCreator<ExtraRuleDocs>(getDocsUrl);\n\nconst queryHooks = [\n 'useQuery',\n 'useQueries',\n 'useInfiniteQuery',\n 'useSuspenseQuery',\n 'useSuspenseQueries',\n 'useSuspenseInfiniteQuery',\n];\n\nexport const rule = createRule({\n name,\n meta: {\n type: 'problem',\n docs: {\n description: 'Disallows rest destructuring in queries',\n recommended: 'warn',\n },\n messages: {\n objectRestDestructure: `Object rest destructuring on a query will observe all changes to the query, leading to excessive re-renders.`,\n },\n schema: [\n {\n type: 'object',\n properties: {\n clientNamePattern: { type: 'string' },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{}],\n\n create: (context) => {\n const option =\n (context.options[0] as { clientNamePattern?: string } | undefined) ?? {};\n\n const clientRegex = createClientNameRegex(option.clientNamePattern);\n\n const queryResultVariables = new Set<string>();\n\n return {\n CallExpression: (node) => {\n if (node.parent.type !== AST_NODE_TYPES.VariableDeclarator) return;\n\n const callee = node.callee;\n if (callee.type !== AST_NODE_TYPES.MemberExpression) return;\n const hookName = getHookNameIfTargetFromClient(clientRegex, callee);\n if (!hookName) return;\n const returnValue = node.parent.id;\n\n if (hookName !== 'useQueries' && hookName !== 'useSuspenseQueries') {\n if (NoRestDestructuringUtils.isObjectRestDestructuring(returnValue)) {\n return context.report({\n node: node.parent,\n messageId: 'objectRestDestructure',\n });\n }\n\n if (returnValue.type === AST_NODE_TYPES.Identifier) {\n queryResultVariables.add(returnValue.name);\n }\n\n return;\n }\n\n if (returnValue.type !== AST_NODE_TYPES.ArrayPattern) {\n if (returnValue.type === AST_NODE_TYPES.Identifier) {\n queryResultVariables.add(returnValue.name);\n }\n return;\n }\n\n returnValue.elements.forEach((queryResult) => {\n if (queryResult === null) {\n return;\n }\n if (NoRestDestructuringUtils.isObjectRestDestructuring(queryResult)) {\n context.report({\n node: queryResult,\n messageId: 'objectRestDestructure',\n });\n }\n });\n },\n\n VariableDeclarator: (node) => {\n if (\n node.init?.type === AST_NODE_TYPES.Identifier &&\n queryResultVariables.has(node.init.name) &&\n NoRestDestructuringUtils.isObjectRestDestructuring(node.id)\n ) {\n context.report({\n node,\n messageId: 'objectRestDestructure',\n });\n }\n },\n\n SpreadElement: (node) => {\n if (\n node.argument.type === AST_NODE_TYPES.Identifier &&\n queryResultVariables.has(node.argument.name)\n ) {\n context.report({\n node,\n messageId: 'objectRestDestructure',\n });\n }\n },\n };\n },\n});\n\nfunction getHookNameIfTargetFromClient(\n clientRegex: RegExp,\n callee: TSESTree.MemberExpression\n): string | undefined {\n if (callee.property.type !== AST_NODE_TYPES.Identifier) return;\n const name = callee.property.name;\n if (!queryHooks.includes(name)) return;\n const root = getRootIdentifier(callee.object);\n return root && clientRegex.test(root.name) ? name : undefined;\n}\n"],"names":["name","createRule","ESLintUtils","RuleCreator","getDocsUrl","queryHooks","rule","meta","type","docs","description","recommended","messages","objectRestDestructure","schema","properties","clientNamePattern","additionalProperties","defaultOptions","create","context","option","options","clientRegex","createClientNameRegex","queryResultVariables","Set","CallExpression","node","parent","AST_NODE_TYPES","VariableDeclarator","callee","MemberExpression","hookName","getHookNameIfTargetFromClient","returnValue","id","NoRestDestructuringUtils","isObjectRestDestructuring","report","messageId","Identifier","add","ArrayPattern","elements","forEach","queryResult","init","has","SpreadElement","argument","property","includes","root","getRootIdentifier","object","test","undefined"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
2
|
+
|
|
3
|
+
const NoRestDestructuringUtils = {
|
|
4
|
+
isObjectRestDestructuring (node) {
|
|
5
|
+
if (node.type !== AST_NODE_TYPES.ObjectPattern) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
return node.properties.some((p)=>p.type === AST_NODE_TYPES.RestElement);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export { NoRestDestructuringUtils };
|
|
13
|
+
//# sourceMappingURL=no-rest-destructuring.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-rest-destructuring.utils.js","sources":["../../../../src/rules/no-rest-destructuring/no-rest-destructuring.utils.ts"],"sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport { AST_NODE_TYPES } from '@typescript-eslint/utils';\n\nexport const NoRestDestructuringUtils = {\n isObjectRestDestructuring(node: TSESTree.Node): boolean {\n if (node.type !== AST_NODE_TYPES.ObjectPattern) {\n return false;\n }\n return node.properties.some((p) => p.type === AST_NODE_TYPES.RestElement);\n },\n};\n"],"names":["NoRestDestructuringUtils","isObjectRestDestructuring","node","type","AST_NODE_TYPES","ObjectPattern","properties","some","p","RestElement"],"mappings":";;MAGaA,wBAA2B,GAAA;AACtCC,IAAAA,yBAAAA,CAAAA,CAA0BC,IAAmB,EAAA;AAC3C,QAAA,IAAIA,IAAKC,CAAAA,IAAI,KAAKC,cAAAA,CAAeC,aAAa,EAAE;YAC9C,OAAO,KAAA,CAAA;AACT,SAAA;QACA,OAAOH,IAAAA,CAAKI,UAAU,CAACC,IAAI,CAAC,CAACC,CAAAA,GAAMA,CAAEL,CAAAA,IAAI,KAAKC,cAAAA,CAAeK,WAAW,CAAA,CAAA;AAC1E,KAAA;AACF;;;;"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { ESLintUtils, AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
2
|
+
import { createClientNameRegex } from '../../utils/create-client-name-regex.js';
|
|
3
|
+
import { getDocsUrl } from '../../utils/get-docs-url.js';
|
|
4
|
+
import { getRootIdentifier } from '../../utils/get-root-identifier.js';
|
|
5
|
+
|
|
6
|
+
const name = 'no-unstable-deps';
|
|
7
|
+
const reactHookNames = [
|
|
8
|
+
'useEffect',
|
|
9
|
+
'useCallback',
|
|
10
|
+
'useMemo'
|
|
11
|
+
];
|
|
12
|
+
const useQueryHookNames = [
|
|
13
|
+
'useQuery',
|
|
14
|
+
'useSuspenseQuery',
|
|
15
|
+
'useQueries',
|
|
16
|
+
'useSuspenseQueries',
|
|
17
|
+
'useInfiniteQuery',
|
|
18
|
+
'useSuspenseInfiniteQuery'
|
|
19
|
+
];
|
|
20
|
+
const allHookNames = [
|
|
21
|
+
'useMutation',
|
|
22
|
+
...useQueryHookNames
|
|
23
|
+
];
|
|
24
|
+
const createRule = ESLintUtils.RuleCreator(getDocsUrl);
|
|
25
|
+
const rule = createRule({
|
|
26
|
+
name,
|
|
27
|
+
meta: {
|
|
28
|
+
type: 'problem',
|
|
29
|
+
docs: {
|
|
30
|
+
description: 'Disallow putting the result of query hooks directly in a React hook dependency array',
|
|
31
|
+
recommended: 'error'
|
|
32
|
+
},
|
|
33
|
+
messages: {
|
|
34
|
+
noUnstableDeps: `The result of {{queryHook}} is not referentially stable, so don't pass it directly into the dependencies array of {{reactHook}}. Instead, destructure the return value of {{queryHook}} and pass the destructured values into the dependency array of {{reactHook}}.`
|
|
35
|
+
},
|
|
36
|
+
schema: [
|
|
37
|
+
{
|
|
38
|
+
type: 'object',
|
|
39
|
+
properties: {
|
|
40
|
+
clientNamePattern: {
|
|
41
|
+
type: 'string'
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
additionalProperties: false
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
},
|
|
48
|
+
defaultOptions: [
|
|
49
|
+
{}
|
|
50
|
+
],
|
|
51
|
+
create: (context)=>{
|
|
52
|
+
const option = context.options[0] ?? {};
|
|
53
|
+
const clientRegex = createClientNameRegex(option.clientNamePattern);
|
|
54
|
+
const trackedVariables = {};
|
|
55
|
+
const hookAliasMap = {};
|
|
56
|
+
function getReactHook(node) {
|
|
57
|
+
if (node.callee.type === 'Identifier') {
|
|
58
|
+
const calleeName = node.callee.name;
|
|
59
|
+
if (reactHookNames.includes(calleeName) || calleeName in hookAliasMap) {
|
|
60
|
+
// Return the actually used identifier (could be alias)
|
|
61
|
+
return calleeName;
|
|
62
|
+
}
|
|
63
|
+
} else if (node.callee.type === 'MemberExpression' && node.callee.object.type === 'Identifier' && node.callee.object.name === 'React' && node.callee.property.type === 'Identifier' && reactHookNames.includes(node.callee.property.name)) {
|
|
64
|
+
return node.callee.property.name;
|
|
65
|
+
}
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
ImportDeclaration (node) {
|
|
70
|
+
if (node.specifiers.length > 0 && node.importKind === 'value' && node.source.value === 'React') {
|
|
71
|
+
node.specifiers.forEach((specifier)=>{
|
|
72
|
+
if (specifier.type === AST_NODE_TYPES.ImportSpecifier && specifier.imported.type === AST_NODE_TYPES.Identifier && reactHookNames.includes(specifier.imported.name)) {
|
|
73
|
+
hookAliasMap[specifier.local.name] = specifier.imported.name;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
VariableDeclarator (node) {
|
|
79
|
+
if (node.init?.type !== AST_NODE_TYPES.CallExpression) return;
|
|
80
|
+
const hook = isQueryHookFromClient(clientRegex, node.init);
|
|
81
|
+
if (!hook) return;
|
|
82
|
+
if (node.id.type === AST_NODE_TYPES.Identifier) {
|
|
83
|
+
trackedVariables[node.id.name] = hook;
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
CallExpression: (node)=>{
|
|
87
|
+
const reactHook = getReactHook(node);
|
|
88
|
+
if (!reactHook) return;
|
|
89
|
+
if (node.arguments.length <= 1) return;
|
|
90
|
+
if (node.arguments[1]?.type !== AST_NODE_TYPES.ArrayExpression) return;
|
|
91
|
+
const depsArray = node.arguments[1].elements;
|
|
92
|
+
depsArray.forEach((dep)=>{
|
|
93
|
+
if (dep?.type !== AST_NODE_TYPES.Identifier) return;
|
|
94
|
+
const queryHook = trackedVariables[dep.name];
|
|
95
|
+
if (!queryHook) return;
|
|
96
|
+
context.report({
|
|
97
|
+
node: dep,
|
|
98
|
+
messageId: 'noUnstableDeps',
|
|
99
|
+
data: {
|
|
100
|
+
queryHook,
|
|
101
|
+
reactHook
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
function isQueryHookFromClient(clientRegex, call) {
|
|
110
|
+
if (call.callee.type !== AST_NODE_TYPES.MemberExpression) return null;
|
|
111
|
+
const member = call.callee;
|
|
112
|
+
if (member.property.type !== AST_NODE_TYPES.Identifier) return null;
|
|
113
|
+
const hook = member.property.name;
|
|
114
|
+
if (!allHookNames.includes(hook)) return null;
|
|
115
|
+
const root = getRootIdentifier(member.object);
|
|
116
|
+
if (!root) return null;
|
|
117
|
+
return clientRegex.test(root.name) ? hook : null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export { name, reactHookNames, rule, useQueryHookNames };
|
|
121
|
+
//# sourceMappingURL=no-unstable-deps.rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-unstable-deps.rule.js","sources":["../../../../src/rules/no-unstable-deps/no-unstable-deps.rule.ts"],"sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport type { ExtraRuleDocs } from '../../types';\nimport { AST_NODE_TYPES, ESLintUtils } from '@typescript-eslint/utils';\nimport { createClientNameRegex } from '../../utils/create-client-name-regex';\nimport { getDocsUrl } from '../../utils/get-docs-url';\nimport { getRootIdentifier } from '../../utils/get-root-identifier';\n\nexport const name = 'no-unstable-deps';\n\nexport const reactHookNames = ['useEffect', 'useCallback', 'useMemo'];\nexport const useQueryHookNames = [\n 'useQuery',\n 'useSuspenseQuery',\n 'useQueries',\n 'useSuspenseQueries',\n 'useInfiniteQuery',\n 'useSuspenseInfiniteQuery',\n];\nconst allHookNames = ['useMutation', ...useQueryHookNames];\nconst createRule = ESLintUtils.RuleCreator<ExtraRuleDocs>(getDocsUrl);\n\nexport const rule = createRule({\n name,\n meta: {\n type: 'problem',\n docs: {\n description:\n 'Disallow putting the result of query hooks directly in a React hook dependency array',\n recommended: 'error',\n },\n messages: {\n noUnstableDeps: `The result of {{queryHook}} is not referentially stable, so don't pass it directly into the dependencies array of {{reactHook}}. Instead, destructure the return value of {{queryHook}} and pass the destructured values into the dependency array of {{reactHook}}.`,\n },\n schema: [\n {\n type: 'object',\n properties: {\n clientNamePattern: { type: 'string' },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{}],\n\n create: (context) => {\n const option =\n (context.options[0] as { clientNamePattern?: string } | undefined) ?? {};\n const clientRegex = createClientNameRegex(option.clientNamePattern);\n\n const trackedVariables: Record<string, string> = {};\n const hookAliasMap: Record<string, string> = {};\n\n function getReactHook(node: TSESTree.CallExpression): string | undefined {\n if (node.callee.type === 'Identifier') {\n const calleeName = node.callee.name;\n if (reactHookNames.includes(calleeName) || calleeName in hookAliasMap) {\n // Return the actually used identifier (could be alias)\n return calleeName;\n }\n } else if (\n node.callee.type === 'MemberExpression' &&\n node.callee.object.type === 'Identifier' &&\n node.callee.object.name === 'React' &&\n node.callee.property.type === 'Identifier' &&\n reactHookNames.includes(node.callee.property.name)\n ) {\n return node.callee.property.name;\n }\n return undefined;\n }\n\n return {\n ImportDeclaration(node: TSESTree.ImportDeclaration) {\n if (\n node.specifiers.length > 0 &&\n node.importKind === 'value' &&\n node.source.value === 'React'\n ) {\n node.specifiers.forEach((specifier) => {\n if (\n specifier.type === AST_NODE_TYPES.ImportSpecifier &&\n specifier.imported.type === AST_NODE_TYPES.Identifier &&\n reactHookNames.includes(specifier.imported.name)\n ) {\n hookAliasMap[specifier.local.name] = specifier.imported.name;\n }\n });\n }\n },\n\n VariableDeclarator(node) {\n if (node.init?.type !== AST_NODE_TYPES.CallExpression) return;\n const hook = isQueryHookFromClient(clientRegex, node.init);\n if (!hook) return;\n if (node.id.type === AST_NODE_TYPES.Identifier) {\n trackedVariables[node.id.name] = hook;\n }\n },\n CallExpression: (node) => {\n const reactHook = getReactHook(node);\n if (!reactHook) return;\n if (node.arguments.length <= 1) return;\n if (node.arguments[1]?.type !== AST_NODE_TYPES.ArrayExpression) return;\n\n const depsArray = node.arguments[1].elements;\n depsArray.forEach((dep) => {\n if (dep?.type !== AST_NODE_TYPES.Identifier) return;\n const queryHook = trackedVariables[dep.name];\n if (!queryHook) return;\n context.report({\n node: dep,\n messageId: 'noUnstableDeps',\n data: {\n queryHook,\n reactHook,\n },\n });\n });\n },\n };\n },\n});\n\nfunction isQueryHookFromClient(\n clientRegex: RegExp,\n call: TSESTree.CallExpression\n): string | null {\n if (call.callee.type !== AST_NODE_TYPES.MemberExpression) return null;\n const member = call.callee;\n if (member.property.type !== AST_NODE_TYPES.Identifier) return null;\n const hook = member.property.name;\n if (!allHookNames.includes(hook)) return null;\n const root = getRootIdentifier(member.object);\n if (!root) return null;\n return clientRegex.test(root.name) ? hook : null;\n}\n"],"names":["name","reactHookNames","useQueryHookNames","allHookNames","createRule","ESLintUtils","RuleCreator","getDocsUrl","rule","meta","type","docs","description","recommended","messages","noUnstableDeps","schema","properties","clientNamePattern","additionalProperties","defaultOptions","create","context","option","options","clientRegex","createClientNameRegex","trackedVariables","hookAliasMap","getReactHook","node","callee","calleeName","includes","object","property","undefined","ImportDeclaration","specifiers","length","importKind","source","value","forEach","specifier","AST_NODE_TYPES","ImportSpecifier","imported","Identifier","local","VariableDeclarator","init","CallExpression","hook","isQueryHookFromClient","id","reactHook","arguments","ArrayExpression","depsArray","elements","dep","queryHook","report","messageId","data","call","MemberExpression","member","root","getRootIdentifier","test"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { name, rule } from './rules/no-rest-destructuring/no-rest-destructuring.rule.js';
|
|
2
|
+
import { name as name$1, rule as rule$1 } from './rules/no-unstable-deps/no-unstable-deps.rule.js';
|
|
3
|
+
|
|
4
|
+
const rules = {
|
|
5
|
+
[name]: rule,
|
|
6
|
+
[name$1]: rule$1
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export { rules };
|
|
10
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sources":["../../src/rules.ts"],"sourcesContent":["import type { ESLintUtils } from '@typescript-eslint/utils';\nimport type { ExtraRuleDocs } from './types';\nimport * as noRestDestructuring from './rules/no-rest-destructuring/no-rest-destructuring.rule';\nimport * as noUnstableDeps from './rules/no-unstable-deps/no-unstable-deps.rule';\n\nexport const rules: Record<\n string,\n ESLintUtils.RuleModule<\n string,\n ReadonlyArray<unknown>,\n ExtraRuleDocs,\n ESLintUtils.RuleListener\n >\n> = {\n [noRestDestructuring.name]: noRestDestructuring.rule,\n [noUnstableDeps.name]: noUnstableDeps.rule,\n};\n"],"names":["rules","noRestDestructuring","noUnstableDeps"],"mappings":";;;MAKaA,KAQT,GAAA;AACF,IAAA,CAACC,IAAwB,GAAGA,IAAwB;AACpD,IAAA,CAACC,MAAmB,GAAGA,MAAmB;AAC5C;;;;"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
function createClientNameRegex(clientNamePattern) {
|
|
2
|
+
clientNamePattern = clientNamePattern?.trim();
|
|
3
|
+
if (clientNamePattern) {
|
|
4
|
+
// Check if pattern is in regex format: /pattern/flags
|
|
5
|
+
const regexMatch = clientNamePattern.match(/^\/(.*)\/([gimuy]*)$/);
|
|
6
|
+
if (regexMatch) {
|
|
7
|
+
const regexPattern = regexMatch[1].trim();
|
|
8
|
+
const flags = regexMatch[2];
|
|
9
|
+
// Validate that regex pattern is not empty or whitespace-only
|
|
10
|
+
if (regexPattern === '') {
|
|
11
|
+
throw new Error('clientNamePattern cannot be empty or contain only whitespace');
|
|
12
|
+
}
|
|
13
|
+
return new RegExp(regexPattern, flags);
|
|
14
|
+
}
|
|
15
|
+
// Fallback to treating as plain string pattern
|
|
16
|
+
return new RegExp(clientNamePattern);
|
|
17
|
+
} else if (clientNamePattern === '') {
|
|
18
|
+
throw new Error('clientNamePattern cannot be empty or contain only whitespace');
|
|
19
|
+
}
|
|
20
|
+
// Default if no pattern provided
|
|
21
|
+
return /qraft|api/i;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { createClientNameRegex };
|
|
25
|
+
//# sourceMappingURL=create-client-name-regex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-client-name-regex.js","sources":["../../../src/utils/create-client-name-regex.ts"],"sourcesContent":["export function createClientNameRegex(clientNamePattern: string | undefined) {\n clientNamePattern = clientNamePattern?.trim();\n\n if (clientNamePattern) {\n // Check if pattern is in regex format: /pattern/flags\n const regexMatch = clientNamePattern.match(/^\\/(.*)\\/([gimuy]*)$/);\n\n if (regexMatch) {\n const regexPattern = regexMatch[1].trim();\n const flags = regexMatch[2];\n\n // Validate that regex pattern is not empty or whitespace-only\n if (regexPattern === '') {\n throw new Error(\n 'clientNamePattern cannot be empty or contain only whitespace'\n );\n }\n\n return new RegExp(regexPattern, flags);\n }\n\n // Fallback to treating as plain string pattern\n return new RegExp(clientNamePattern);\n } else if (clientNamePattern === '') {\n throw new Error(\n 'clientNamePattern cannot be empty or contain only whitespace'\n );\n }\n\n // Default if no pattern provided\n return /qraft|api/i;\n}\n"],"names":["createClientNameRegex","clientNamePattern","trim","regexMatch","match","regexPattern","flags","Error","RegExp"],"mappings":"AAAO,SAASA,sBAAsBC,iBAAqC,EAAA;AACzEA,IAAAA,iBAAAA,GAAoBA,iBAAmBC,EAAAA,IAAAA,EAAAA,CAAAA;AAEvC,IAAA,IAAID,iBAAmB,EAAA;;QAErB,MAAME,UAAAA,GAAaF,iBAAkBG,CAAAA,KAAK,CAAC,sBAAA,CAAA,CAAA;AAE3C,QAAA,IAAID,UAAY,EAAA;AACd,YAAA,MAAME,YAAeF,GAAAA,UAAU,CAAC,CAAA,CAAE,CAACD,IAAI,EAAA,CAAA;YACvC,MAAMI,KAAAA,GAAQH,UAAU,CAAC,CAAE,CAAA,CAAA;;AAG3B,YAAA,IAAIE,iBAAiB,EAAI,EAAA;AACvB,gBAAA,MAAM,IAAIE,KACR,CAAA,8DAAA,CAAA,CAAA;AAEJ,aAAA;YAEA,OAAO,IAAIC,OAAOH,YAAcC,EAAAA,KAAAA,CAAAA,CAAAA;AAClC,SAAA;;AAGA,QAAA,OAAO,IAAIE,MAAOP,CAAAA,iBAAAA,CAAAA,CAAAA;KACb,MAAA,IAAIA,sBAAsB,EAAI,EAAA;AACnC,QAAA,MAAM,IAAIM,KACR,CAAA,8DAAA,CAAA,CAAA;AAEJ,KAAA;;IAGA,OAAO,YAAA,CAAA;AACT;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-docs-url.js","sources":["../../../src/utils/get-docs-url.ts"],"sourcesContent":["export const getDocsUrl = (ruleName: string): string =>\n `https://openapi-qraft.github.io/openapi-qraft/docs/eslint/${ruleName}`;\n"],"names":["getDocsUrl","ruleName"],"mappings":"AAAO,MAAMA,aAAa,CAACC,QAAAA,GACzB,CAAC,0DAA0D,EAAEA,QAAS,CAAA;;;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
2
|
+
|
|
3
|
+
function getRootIdentifier(node) {
|
|
4
|
+
let current = node;
|
|
5
|
+
while(current.type === AST_NODE_TYPES.MemberExpression || current.type === AST_NODE_TYPES.TSNonNullExpression || current.type === AST_NODE_TYPES.ChainExpression){
|
|
6
|
+
if (current.type === AST_NODE_TYPES.MemberExpression) {
|
|
7
|
+
current = current.object;
|
|
8
|
+
continue;
|
|
9
|
+
}
|
|
10
|
+
if (current.type === AST_NODE_TYPES.TSNonNullExpression) {
|
|
11
|
+
current = current.expression;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
current = current.expression;
|
|
15
|
+
}
|
|
16
|
+
return current.type === AST_NODE_TYPES.Identifier ? current : undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export { getRootIdentifier };
|
|
20
|
+
//# sourceMappingURL=get-root-identifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-root-identifier.js","sources":["../../../src/utils/get-root-identifier.ts"],"sourcesContent":["import type { TSESTree } from '@typescript-eslint/utils';\nimport { AST_NODE_TYPES } from '@typescript-eslint/utils';\n\nexport function getRootIdentifier(\n node: TSESTree.Node\n): TSESTree.Identifier | undefined {\n let current: TSESTree.Node | undefined = node;\n while (\n current.type === AST_NODE_TYPES.MemberExpression ||\n current.type === AST_NODE_TYPES.TSNonNullExpression ||\n current.type === AST_NODE_TYPES.ChainExpression\n ) {\n if (current.type === AST_NODE_TYPES.MemberExpression) {\n current = current.object;\n continue;\n }\n if (current.type === AST_NODE_TYPES.TSNonNullExpression) {\n current = current.expression;\n continue;\n }\n\n current = current.expression;\n }\n return current.type === AST_NODE_TYPES.Identifier ? current : undefined;\n}\n"],"names":["getRootIdentifier","node","current","type","AST_NODE_TYPES","MemberExpression","TSNonNullExpression","ChainExpression","object","expression","Identifier","undefined"],"mappings":";;AAGO,SAASA,kBACdC,IAAmB,EAAA;AAEnB,IAAA,IAAIC,OAAqCD,GAAAA,IAAAA,CAAAA;AACzC,IAAA,MACEC,QAAQC,IAAI,KAAKC,cAAeC,CAAAA,gBAAgB,IAChDH,OAAQC,CAAAA,IAAI,KAAKC,cAAAA,CAAeE,mBAAmB,IACnDJ,OAAAA,CAAQC,IAAI,KAAKC,cAAAA,CAAeG,eAAe,CAC/C;AACA,QAAA,IAAIL,OAAQC,CAAAA,IAAI,KAAKC,cAAAA,CAAeC,gBAAgB,EAAE;AACpDH,YAAAA,OAAAA,GAAUA,QAAQM,MAAM,CAAA;AACxB,YAAA,SAAA;AACF,SAAA;AACA,QAAA,IAAIN,OAAQC,CAAAA,IAAI,KAAKC,cAAAA,CAAeE,mBAAmB,EAAE;AACvDJ,YAAAA,OAAAA,GAAUA,QAAQO,UAAU,CAAA;AAC5B,YAAA,SAAA;AACF,SAAA;AAEAP,QAAAA,OAAAA,GAAUA,QAAQO,UAAU,CAAA;AAC9B,KAAA;AACA,IAAA,OAAOP,QAAQC,IAAI,KAAKC,cAAeM,CAAAA,UAAU,GAAGR,OAAUS,GAAAA,SAAAA,CAAAA;AAChE;;;;"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { RuleModule } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
import type { ESLint, Linter } from 'eslint';
|
|
3
|
+
import { rules } from './rules';
|
|
4
|
+
type RuleKey = keyof typeof rules;
|
|
5
|
+
export interface Plugin extends Omit<ESLint.Plugin, 'rules'> {
|
|
6
|
+
rules: Record<RuleKey, RuleModule<any, any, any>>;
|
|
7
|
+
configs: {
|
|
8
|
+
recommended: ESLint.ConfigData;
|
|
9
|
+
'flat/recommended': Array<Linter.Config>;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export declare const plugin: Plugin;
|
|
13
|
+
export { rules };
|
|
14
|
+
export declare const configs: {
|
|
15
|
+
recommended: ESLint.ConfigData;
|
|
16
|
+
'flat/recommended': Array<Linter.Config>;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* @alias
|
|
20
|
+
* @type {Plugin}
|
|
21
|
+
**/
|
|
22
|
+
export default plugin;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,KAAK,OAAO,GAAG,MAAM,OAAO,KAAK,CAAC;AAElC,MAAM,WAAW,MAAO,SAAQ,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC1D,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAClD,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC,UAAU,CAAC;QAC/B,kBAAkB,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;KAC1C,CAAC;CACH;AAED,eAAO,MAAM,MAAM,EAAE,MAMpB,CAAC;AA0BF,OAAO,EAAE,KAAK,EAAE,CAAC;AACjB,eAAO,MAAM,OAAO;iBAtCH,MAAM,CAAC,UAAU;wBACV,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;CAqCP,CAAC;AAEtC;;;IAGI;AACJ,eAAe,MAAM,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ExtraRuleDocs } from '../../types';
|
|
2
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
3
|
+
export declare const name = "no-rest-destructuring";
|
|
4
|
+
export declare const rule: ESLintUtils.RuleModule<"objectRestDestructure", [{}], ExtraRuleDocs, ESLintUtils.RuleListener>;
|
|
5
|
+
//# sourceMappingURL=no-rest-destructuring.rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-rest-destructuring.rule.d.ts","sourceRoot":"","sources":["../../../../src/rules/no-rest-destructuring/no-rest-destructuring.rule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAkB,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAMvE,eAAO,MAAM,IAAI,0BAA0B,CAAC;AAa5C,eAAO,MAAM,IAAI,gGAsGf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-rest-destructuring.utils.d.ts","sourceRoot":"","sources":["../../../../src/rules/no-rest-destructuring/no-rest-destructuring.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAGzD,eAAO,MAAM,wBAAwB;oCACH,QAAQ,CAAC,IAAI,GAAG,OAAO;CAMxD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ExtraRuleDocs } from '../../types';
|
|
2
|
+
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
3
|
+
export declare const name = "no-unstable-deps";
|
|
4
|
+
export declare const reactHookNames: string[];
|
|
5
|
+
export declare const useQueryHookNames: string[];
|
|
6
|
+
export declare const rule: ESLintUtils.RuleModule<"noUnstableDeps", [{}], ExtraRuleDocs, ESLintUtils.RuleListener>;
|
|
7
|
+
//# sourceMappingURL=no-unstable-deps.rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-unstable-deps.rule.d.ts","sourceRoot":"","sources":["../../../../src/rules/no-unstable-deps/no-unstable-deps.rule.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAkB,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAKvE,eAAO,MAAM,IAAI,qBAAqB,CAAC;AAEvC,eAAO,MAAM,cAAc,UAA0C,CAAC;AACtE,eAAO,MAAM,iBAAiB,UAO7B,CAAC;AAIF,eAAO,MAAM,IAAI,yFAqGf,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
+
import type { ExtraRuleDocs } from './types';
|
|
3
|
+
export declare const rules: Record<string, ESLintUtils.RuleModule<string, ReadonlyArray<unknown>, ExtraRuleDocs, ESLintUtils.RuleListener>>;
|
|
4
|
+
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAI7C,eAAO,MAAM,KAAK,EAAE,MAAM,CACxB,MAAM,EACN,WAAW,CAAC,UAAU,CACpB,MAAM,EACN,aAAa,CAAC,OAAO,CAAC,EACtB,aAAa,EACb,WAAW,CAAC,YAAY,CACzB,CAIF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG;IAC1B,WAAW,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;CAC1C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-client-name-regex.d.ts","sourceRoot":"","sources":["../../../src/utils/create-client-name-regex.ts"],"names":[],"mappings":"AAAA,wBAAgB,qBAAqB,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,UA+B1E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-docs-url.d.ts","sourceRoot":"","sources":["../../../src/utils/get-docs-url.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,aAAc,MAAM,KAAG,MAC2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-root-identifier.d.ts","sourceRoot":"","sources":["../../../src/utils/get-root-identifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAGzD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,QAAQ,CAAC,IAAI,GAClB,QAAQ,CAAC,UAAU,GAAG,SAAS,CAmBjC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openapi-qraft/eslint-plugin-query",
|
|
3
|
+
"version": "2.12.0",
|
|
4
|
+
"description": "ESLint plugin for OpenAPI Qraft",
|
|
5
|
+
"homepage": "https://openapi-qraft.github.io/openapi-qraft/docs/eslint/eslint-plugin-query",
|
|
6
|
+
"packageManager": "yarn@4.0.2",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"publishConfig": {
|
|
9
|
+
"access": "public"
|
|
10
|
+
},
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "git+https://github.com/OpenAPI-Qraft/openapi-qraft.git",
|
|
14
|
+
"directory": "packages/eslint-plugin-query"
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "yarn clean && NODE_ENV=production rollup --config rollup.config.mjs && tsc --project tsconfig.build.json --emitDeclarationOnly",
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
19
|
+
"lint": "eslint",
|
|
20
|
+
"test": "vitest run --coverage",
|
|
21
|
+
"clean": "rimraf dist/"
|
|
22
|
+
},
|
|
23
|
+
"type": "module",
|
|
24
|
+
"types": "dist/types/index.d.ts",
|
|
25
|
+
"module": "dist/esm/index.js",
|
|
26
|
+
"main": "dist/cjs/index.cjs",
|
|
27
|
+
"exports": {
|
|
28
|
+
".": {
|
|
29
|
+
"types": "./dist/types/index.d.ts",
|
|
30
|
+
"import": "./dist/esm/index.js",
|
|
31
|
+
"require": "./dist/cjs/index.cjs"
|
|
32
|
+
},
|
|
33
|
+
"./package.json": "./package.json"
|
|
34
|
+
},
|
|
35
|
+
"typesVersions": {
|
|
36
|
+
"*": {
|
|
37
|
+
"*": [
|
|
38
|
+
"dist/types/*"
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"sideEffects": false,
|
|
43
|
+
"files": [
|
|
44
|
+
"dist",
|
|
45
|
+
"src",
|
|
46
|
+
"!src/__tests__"
|
|
47
|
+
],
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@typescript-eslint/utils": "^8.37.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@openapi-qraft/eslint-config": "1.0.1",
|
|
53
|
+
"@openapi-qraft/rollup-config": "1.1.1",
|
|
54
|
+
"@types/node": "^20.16.5",
|
|
55
|
+
"@typescript-eslint/rule-tester": "^8.37.0",
|
|
56
|
+
"@typescript-eslint/typescript-estree": "^8.39.1",
|
|
57
|
+
"@vitest/coverage-v8": "^3.0.5",
|
|
58
|
+
"eslint": "^9.24.0",
|
|
59
|
+
"rimraf": "^5.0.10",
|
|
60
|
+
"rollup": "~4.22.4",
|
|
61
|
+
"typescript": "^5.6.2",
|
|
62
|
+
"vitest": "^3.0.5"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"eslint": "^8.57.0 || ^9.0.0"
|
|
66
|
+
}
|
|
67
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { RuleModule } from '@typescript-eslint/utils/ts-eslint';
|
|
2
|
+
import type { ESLint, Linter } from 'eslint';
|
|
3
|
+
import { rules } from './rules';
|
|
4
|
+
|
|
5
|
+
type RuleKey = keyof typeof rules;
|
|
6
|
+
|
|
7
|
+
export interface Plugin extends Omit<ESLint.Plugin, 'rules'> {
|
|
8
|
+
rules: Record<RuleKey, RuleModule<any, any, any>>;
|
|
9
|
+
configs: {
|
|
10
|
+
recommended: ESLint.ConfigData;
|
|
11
|
+
'flat/recommended': Array<Linter.Config>;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const plugin: Plugin = {
|
|
16
|
+
meta: {
|
|
17
|
+
name: '@openapi-qraft/eslint-plugin-query',
|
|
18
|
+
},
|
|
19
|
+
configs: {} as Plugin['configs'],
|
|
20
|
+
rules,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// Assign configs here so we can reference `plugin`
|
|
24
|
+
Object.assign(plugin.configs, {
|
|
25
|
+
recommended: {
|
|
26
|
+
plugins: ['@openapi-qraft/query'],
|
|
27
|
+
rules: {
|
|
28
|
+
'@openapi-qraft/query/no-rest-destructuring': 'warn',
|
|
29
|
+
'@openapi-qraft/query/no-unstable-deps': 'error',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
'flat/recommended': [
|
|
33
|
+
{
|
|
34
|
+
name: 'openapi-qraft/query/flat/recommended',
|
|
35
|
+
plugins: {
|
|
36
|
+
'@openapi-qraft/query': plugin,
|
|
37
|
+
},
|
|
38
|
+
rules: {
|
|
39
|
+
'@openapi-qraft/query/no-rest-destructuring': 'warn',
|
|
40
|
+
'@openapi-qraft/query/no-unstable-deps': 'error',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Reexport rules & configs for the Legacy config
|
|
47
|
+
export { rules };
|
|
48
|
+
export const configs = plugin.configs;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @alias
|
|
52
|
+
* @type {Plugin}
|
|
53
|
+
**/
|
|
54
|
+
export default plugin;
|