eslint-plugin-effector 0.16.0 → 0.18.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/README.md +24 -37
- package/dist/index.cjs +1488 -0
- package/dist/index.d.cts +164 -0
- package/dist/index.d.mts +165 -0
- package/dist/index.mjs +1465 -0
- package/package.json +73 -17
- package/.nvmrc +0 -1
- package/config/future.js +0 -7
- package/config/patronum.js +0 -5
- package/config/react.js +0 -7
- package/config/recommended.js +0 -15
- package/config/scope.js +0 -6
- package/index.js +0 -31
- package/rules/enforce-effect-naming-convention/enforce-effect-naming-convention.js +0 -143
- package/rules/enforce-gate-naming-convention/enforce-gate-naming-convention.js +0 -122
- package/rules/enforce-store-naming-convention/enforce-store-naming-convention.js +0 -205
- package/rules/keep-options-order/config.js +0 -3
- package/rules/keep-options-order/keep-options-order.js +0 -107
- package/rules/mandatory-scope-binding/mandatory-scope-binding.js +0 -81
- package/rules/no-ambiguity-target/no-ambiguity-target.js +0 -74
- package/rules/no-duplicate-clock-or-source-array-values/no-duplicate-clock-or-source-array-values.js +0 -124
- package/rules/no-duplicate-on/no-duplicate-on.js +0 -137
- package/rules/no-forward/no-forward.js +0 -73
- package/rules/no-getState/no-getState.js +0 -50
- package/rules/no-guard/no-guard.js +0 -78
- package/rules/no-patronum-debug/no-patronum-debug.js +0 -133
- package/rules/no-unnecessary-combination/no-unnecessary-combination.js +0 -88
- package/rules/no-unnecessary-duplication/no-unnecessary-duplication.js +0 -115
- package/rules/no-useless-methods/no-useless-methods.js +0 -93
- package/rules/no-watch/no-watch.js +0 -61
- package/rules/prefer-sample-over-forward-with-mapping/prefer-sample-over-forward-with-mapping.js +0 -111
- package/rules/prefer-useUnit/prefer-useUnit.js +0 -56
- package/rules/require-pickup-in-persist/require-pickup-in-persist.js +0 -47
- package/rules/strict-effect-handlers/strict-effect-handlers.js +0 -76
- package/utils/are-nodes-same-in-text.js +0 -22
- package/utils/builders.js +0 -19
- package/utils/create-link-to-rule.js +0 -5
- package/utils/extract-config.js +0 -26
- package/utils/extract-imported-from.js +0 -18
- package/utils/get-corrected-store-name.js +0 -45
- package/utils/get-nested-object-name.js +0 -18
- package/utils/get-store-name-convention.js +0 -6
- package/utils/is.js +0 -39
- package/utils/method.js +0 -23
- package/utils/naming.js +0 -47
- package/utils/node-is-type.js +0 -5
- package/utils/node-type-is.js +0 -106
- package/utils/react.js +0 -214
- package/utils/read-example.js +0 -63
- package/utils/replace-by-sample.js +0 -98
- package/utils/traverse-nested-object-node.js +0 -9
- package/utils/traverse-parent-by-type.js +0 -15
- package/utils/validate-store-name-convention.js +0 -13
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
const { createLinkToRule } = require("../../utils/create-link-to-rule");
|
|
2
|
-
const { extractImportedFrom } = require("../../utils/extract-imported-from");
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
meta: {
|
|
6
|
-
type: "problem",
|
|
7
|
-
docs: {
|
|
8
|
-
description:
|
|
9
|
-
"Suggests to replace old hooks `useStore`/`useEvent` by the new one `useUnit`",
|
|
10
|
-
category: "Quality",
|
|
11
|
-
recommended: true,
|
|
12
|
-
url: createLinkToRule("prefer-useUnit"),
|
|
13
|
-
},
|
|
14
|
-
messages: {
|
|
15
|
-
useUnitNeeded: "`{{ hookName }}` could be replaced by `useUnit`",
|
|
16
|
-
},
|
|
17
|
-
schema: [],
|
|
18
|
-
},
|
|
19
|
-
create(context) {
|
|
20
|
-
const importedFromEffectorReact = new Map();
|
|
21
|
-
|
|
22
|
-
return {
|
|
23
|
-
ImportDeclaration(node) {
|
|
24
|
-
extractImportedFrom({
|
|
25
|
-
importMap: importedFromEffectorReact,
|
|
26
|
-
packageName: "effector-react",
|
|
27
|
-
node,
|
|
28
|
-
});
|
|
29
|
-
},
|
|
30
|
-
CallExpression(node) {
|
|
31
|
-
const OLD_HOOKS = ["useStore", "useEvent"];
|
|
32
|
-
const NEW_HOOK = ["useUnit"];
|
|
33
|
-
|
|
34
|
-
for (const oldHookName of OLD_HOOKS) {
|
|
35
|
-
const localOldHookName = importedFromEffectorReact.get(oldHookName);
|
|
36
|
-
if (!localOldHookName) {
|
|
37
|
-
continue;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const isOldHook = node.callee.name === localOldHookName;
|
|
41
|
-
if (!isOldHook) {
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
context.report({
|
|
46
|
-
node,
|
|
47
|
-
messageId: "useUnitNeeded",
|
|
48
|
-
data: {
|
|
49
|
-
hookName: oldHookName,
|
|
50
|
-
},
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
},
|
|
56
|
-
};
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
const { createLinkToRule } = require("../../utils/create-link-to-rule");
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
meta: {
|
|
5
|
-
type: "problem",
|
|
6
|
-
docs: {
|
|
7
|
-
category: "Quality",
|
|
8
|
-
url: createLinkToRule("require-pickup-in-persist"),
|
|
9
|
-
},
|
|
10
|
-
messages: {
|
|
11
|
-
pickupMissing:
|
|
12
|
-
"This `persist` call does not specify a `pickup` event that is required for scoped usage of `effector-storage`.",
|
|
13
|
-
},
|
|
14
|
-
schema: [],
|
|
15
|
-
},
|
|
16
|
-
create(context) {
|
|
17
|
-
const pickupImports = new Set();
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Finds `effector-storage` packages, scoped and unscoped, including
|
|
21
|
-
* contents of these packages. See examples for a full list.
|
|
22
|
-
*/
|
|
23
|
-
const PACKAGE_NAME = /^@?effector-storage(\u002F[\w-]+)*$/;
|
|
24
|
-
|
|
25
|
-
const declarationSelector = `ImportDeclaration[source.value=${PACKAGE_NAME}]`;
|
|
26
|
-
const persistImportSelector = `ImportSpecifier[imported.name="persist"]`;
|
|
27
|
-
|
|
28
|
-
const configSelector = `[arguments.length=1][arguments.0.type="ObjectExpression"]`;
|
|
29
|
-
const callSelector = `[callee.type="Identifier"]`;
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
[`${declarationSelector} > ${persistImportSelector}`](node) {
|
|
33
|
-
pickupImports.add(node.local.name);
|
|
34
|
-
},
|
|
35
|
-
[`CallExpression${configSelector}${callSelector}`](node) {
|
|
36
|
-
if (!pickupImports.has(node.callee.name)) return;
|
|
37
|
-
|
|
38
|
-
const config = node.arguments[0];
|
|
39
|
-
|
|
40
|
-
if (config.properties.some((prop) => prop.key?.name === "pickup"))
|
|
41
|
-
return;
|
|
42
|
-
|
|
43
|
-
context.report({ node, messageId: "pickupMissing" });
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
},
|
|
47
|
-
};
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
const { createLinkToRule } = require("../../utils/create-link-to-rule");
|
|
2
|
-
const { is } = require("../../utils/is");
|
|
3
|
-
|
|
4
|
-
module.exports = {
|
|
5
|
-
meta: {
|
|
6
|
-
type: "problem",
|
|
7
|
-
docs: {
|
|
8
|
-
description:
|
|
9
|
-
"Forbids mix of async functions and effects calls in effect handlers.",
|
|
10
|
-
category: "Quality",
|
|
11
|
-
recommended: true,
|
|
12
|
-
url: createLinkToRule("strict-effect-handlers"),
|
|
13
|
-
},
|
|
14
|
-
messages: {
|
|
15
|
-
mixedCallsInHandler:
|
|
16
|
-
"Handler of effect `{{ effectName }}` can lead to scope loosing in Fork API.",
|
|
17
|
-
mixedCallsInFunction:
|
|
18
|
-
"Function `{{ functionName }}` can lead to scope loosing in Fork API.",
|
|
19
|
-
},
|
|
20
|
-
schema: [],
|
|
21
|
-
},
|
|
22
|
-
create(context) {
|
|
23
|
-
function onEffectHandler(node) {
|
|
24
|
-
const functionBody = node.body?.body;
|
|
25
|
-
|
|
26
|
-
if (!Array.isArray(functionBody)) {
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const calledNodes = functionBody
|
|
31
|
-
.filter((bodyNode) => bodyNode.expression?.type === "AwaitExpression")
|
|
32
|
-
.map((awaitNode) => ({
|
|
33
|
-
node: awaitNode.expression.argument.callee,
|
|
34
|
-
context,
|
|
35
|
-
}));
|
|
36
|
-
|
|
37
|
-
const hasEffects = calledNodes.some(is.effect);
|
|
38
|
-
const hasRegularAsyncFunctions = calledNodes.some(is.not.effect);
|
|
39
|
-
|
|
40
|
-
const hasError = hasEffects && hasRegularAsyncFunctions;
|
|
41
|
-
|
|
42
|
-
if (!hasError) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const isEffectHandler = is.effect({
|
|
47
|
-
node: node.parent?.parent,
|
|
48
|
-
context,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
if (isEffectHandler) {
|
|
52
|
-
const effectName = node.parent?.parent?.id?.name ?? "Unknown";
|
|
53
|
-
|
|
54
|
-
context.report({
|
|
55
|
-
node: node.parent,
|
|
56
|
-
messageId: "mixedCallsInHandler",
|
|
57
|
-
data: { effectName },
|
|
58
|
-
});
|
|
59
|
-
} else {
|
|
60
|
-
const functionName = node.id?.name ?? "Unknown";
|
|
61
|
-
|
|
62
|
-
context.report({
|
|
63
|
-
node,
|
|
64
|
-
messageId: "mixedCallsInFunction",
|
|
65
|
-
data: { functionName },
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return {
|
|
71
|
-
ArrowFunctionExpression: onEffectHandler,
|
|
72
|
-
FunctionExpression: onEffectHandler,
|
|
73
|
-
FunctionDeclaration: onEffectHandler,
|
|
74
|
-
};
|
|
75
|
-
},
|
|
76
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
const prettier = require("prettier");
|
|
2
|
-
|
|
3
|
-
function areNodesSameInText({ context, nodes }) {
|
|
4
|
-
const texts = nodes.map((node) => {
|
|
5
|
-
let sourceText = context.getSourceCode().getText(node);
|
|
6
|
-
|
|
7
|
-
const shouldBeWrapped =
|
|
8
|
-
sourceText.startsWith("{") && sourceText.endsWith("}");
|
|
9
|
-
|
|
10
|
-
if (shouldBeWrapped) {
|
|
11
|
-
sourceText = `(${sourceText})`;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
return prettier.format(sourceText, {
|
|
15
|
-
parser: "babel-ts",
|
|
16
|
-
});
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
return texts.every((text) => text === texts[0]);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
module.exports = { areNodesSameInText };
|
package/utils/builders.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
const buildObjectInText = {
|
|
2
|
-
fromArrayOfNodes({ properties, context }) {
|
|
3
|
-
const content = properties
|
|
4
|
-
.map((property) => context.getSourceCode().getText(property))
|
|
5
|
-
.join(", ");
|
|
6
|
-
|
|
7
|
-
return `{ ${content} }`;
|
|
8
|
-
},
|
|
9
|
-
fromMapOfNodes({ properties, context }) {
|
|
10
|
-
const content = Object.entries(properties)
|
|
11
|
-
.filter(([_, node]) => Boolean(node))
|
|
12
|
-
.map(([key, node]) => `${key}: ${context.getSourceCode().getText(node)}`)
|
|
13
|
-
.join(", ");
|
|
14
|
-
|
|
15
|
-
return `{ ${content} }`;
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
module.exports = { buildObjectInText };
|
package/utils/extract-config.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
function extractConfig(fields, { node }) {
|
|
2
|
-
const config = {};
|
|
3
|
-
|
|
4
|
-
if (isObject(node.arguments?.[0])) {
|
|
5
|
-
extractConfigFromObject(config, fields, node.arguments?.[0]);
|
|
6
|
-
} else if (isObject(node.arguments?.[1])) {
|
|
7
|
-
extractConfigFromObject(config, fields, node.arguments?.[1]);
|
|
8
|
-
if (fields.includes("clock")) {
|
|
9
|
-
config.clock = { value: node.arguments?.[0] };
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return config;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function isObject(node) {
|
|
17
|
-
return Boolean(node?.properties);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function extractConfigFromObject(config, fields, node) {
|
|
21
|
-
fields.forEach((field) => {
|
|
22
|
-
config[field] = node?.properties?.find((n) => n.key?.name === field);
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
module.exports = { extractConfig };
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
function extractImportedFrom({ importMap, nodeMap, node, packageName }) {
|
|
2
|
-
const normalizePackageName = Array.isArray(packageName)
|
|
3
|
-
? packageName
|
|
4
|
-
: [packageName];
|
|
5
|
-
|
|
6
|
-
if (normalizePackageName.includes(node.source.value)) {
|
|
7
|
-
for (const s of node.specifiers) {
|
|
8
|
-
if (s.type === "ImportDefaultSpecifier") {
|
|
9
|
-
continue;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
importMap.set(s.imported.name, s.local.name);
|
|
13
|
-
nodeMap?.set(s.imported.name, s);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
module.exports = { extractImportedFrom };
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
const { getStoreNameConvention } = require("./get-store-name-convention");
|
|
2
|
-
|
|
3
|
-
function getCorrectedStoreName(storeName, context) {
|
|
4
|
-
const storeNameConvention = getStoreNameConvention(context);
|
|
5
|
-
|
|
6
|
-
// handle edge case
|
|
7
|
-
if (storeName.startsWith("$") && storeName.endsWith("$")) {
|
|
8
|
-
const storeNameWithoutConvention = trimByPattern(storeName, "$");
|
|
9
|
-
return formatStoreName(storeNameWithoutConvention, storeNameConvention);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const correctedStoreName = formatStoreName(storeName, storeNameConvention);
|
|
13
|
-
|
|
14
|
-
return correctedStoreName;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function formatStoreName(storeName, convention) {
|
|
18
|
-
return convention === "prefix" ? `$${storeName}` : `${storeName}$`;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function trimByPattern(s, template) {
|
|
22
|
-
let l = 0,
|
|
23
|
-
r = s.length - 1;
|
|
24
|
-
|
|
25
|
-
while (l <= r) {
|
|
26
|
-
const head = s[l];
|
|
27
|
-
const tail = s[r];
|
|
28
|
-
|
|
29
|
-
if (head === template) {
|
|
30
|
-
l++;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (tail === template) {
|
|
34
|
-
r--;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (head !== template && tail !== template) {
|
|
38
|
-
return s.slice(l, r + 1);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return s;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
module.exports = { getCorrectedStoreName };
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
function getNestedObjectName(node) {
|
|
2
|
-
let root = node;
|
|
3
|
-
let name = "";
|
|
4
|
-
|
|
5
|
-
while (root.type === "MemberExpression") {
|
|
6
|
-
name = `${root.property.name}.${name}`;
|
|
7
|
-
root = root.object;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
if (root.type === "Identifier") {
|
|
11
|
-
name = `${root.name}.${name}`;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// Remove last dot
|
|
15
|
-
return name.slice(0, -1);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
module.exports = { getNestedObjectName };
|
package/utils/is.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
const { ESLintUtils } = require("@typescript-eslint/utils");
|
|
2
|
-
|
|
3
|
-
const { nodeTypeIs } = require("./node-type-is");
|
|
4
|
-
const { namingOf } = require("./naming");
|
|
5
|
-
|
|
6
|
-
function isSomething({ isValidNaming, isTypeCorrect }) {
|
|
7
|
-
return ({ node, context }) => {
|
|
8
|
-
let parserServices;
|
|
9
|
-
try {
|
|
10
|
-
parserServices = ESLintUtils.getParserServices(context);
|
|
11
|
-
} catch (e) {
|
|
12
|
-
// no types info
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
if (parserServices?.program) {
|
|
16
|
-
return isTypeCorrect({ node, context });
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return isValidNaming({ name: node?.name ?? node?.id?.name, context });
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const isStore = isSomething({
|
|
24
|
-
isTypeCorrect: nodeTypeIs.store,
|
|
25
|
-
isValidNaming: namingOf.store.isValid,
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const isEffect = isSomething({
|
|
29
|
-
isTypeCorrect: nodeTypeIs.effect,
|
|
30
|
-
isValidNaming: namingOf.effect.isValid,
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const is = {
|
|
34
|
-
store: (opts) => isStore(opts),
|
|
35
|
-
effect: (opts) => isEffect(opts),
|
|
36
|
-
not: { store: (opts) => !isStore(opts), effect: (opts) => !isEffect(opts) },
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
module.exports = { is };
|
package/utils/method.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
function isSomeMethod(methodName, { node, importMap }) {
|
|
2
|
-
const normalizedMethodNames = Array.isArray(methodName)
|
|
3
|
-
? methodName
|
|
4
|
-
: [methodName];
|
|
5
|
-
|
|
6
|
-
return normalizedMethodNames.some((method) => {
|
|
7
|
-
const localMethod = importMap.get(method);
|
|
8
|
-
if (!localMethod) {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const isEffectorMethod = node?.callee?.name === localMethod;
|
|
13
|
-
|
|
14
|
-
return isEffectorMethod;
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const method = {
|
|
19
|
-
is: (...args) => isSomeMethod(...args),
|
|
20
|
-
isNot: (...args) => !isSomeMethod(...args),
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
module.exports = { method };
|
package/utils/naming.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
const { getStoreNameConvention } = require("./get-store-name-convention");
|
|
2
|
-
|
|
3
|
-
function isEffectNameValid({ name }) {
|
|
4
|
-
return Boolean(name?.endsWith("Fx"));
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
function isGateNameValid({ name }) {
|
|
8
|
-
const [firstChar] = name.split("");
|
|
9
|
-
|
|
10
|
-
return Boolean(firstChar?.toUpperCase() === firstChar);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function isStoreNameValid({ name, context }) {
|
|
14
|
-
const storeNameConvention = getStoreNameConvention(context);
|
|
15
|
-
|
|
16
|
-
// validate edge case
|
|
17
|
-
if (name?.length > 1 && name?.startsWith("$") && name?.endsWith("$")) {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
if (storeNameConvention === "prefix" && name?.startsWith("$")) {
|
|
22
|
-
return true;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (storeNameConvention === "postfix" && name?.endsWith("$")) {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const namingOf = {
|
|
33
|
-
effect: {
|
|
34
|
-
isValid: (opts) => isEffectNameValid(opts),
|
|
35
|
-
isInvalid: (opts) => !isEffectNameValid(opts),
|
|
36
|
-
},
|
|
37
|
-
store: {
|
|
38
|
-
isValid: (opts) => isStoreNameValid(opts),
|
|
39
|
-
isInvalid: (opts) => !isStoreNameValid(opts),
|
|
40
|
-
},
|
|
41
|
-
gate: {
|
|
42
|
-
isValid: (opts) => isGateNameValid(opts),
|
|
43
|
-
isInvalid: (opts) => !isGateNameValid(opts),
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
module.exports = { namingOf };
|
package/utils/node-is-type.js
DELETED
package/utils/node-type-is.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
const { ESLintUtils } = require("@typescript-eslint/utils");
|
|
2
|
-
|
|
3
|
-
function hasType({ node, possibleTypes, context, from }) {
|
|
4
|
-
try {
|
|
5
|
-
const parserServices = ESLintUtils.getParserServices(context);
|
|
6
|
-
const checker = parserServices.program.getTypeChecker();
|
|
7
|
-
const originalNode = parserServices.esTreeNodeToTSNodeMap.get(node);
|
|
8
|
-
const type = checker.getTypeAtLocation(
|
|
9
|
-
originalNode?.initializer ?? originalNode
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
const symbol = type?.symbol ?? type?.aliasSymbol;
|
|
13
|
-
|
|
14
|
-
return (
|
|
15
|
-
possibleTypes.includes(symbol?.escapedName) &&
|
|
16
|
-
Boolean(symbol?.parent?.escapedName?.includes(from))
|
|
17
|
-
);
|
|
18
|
-
} catch (e) {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const nodeTypeIs = {
|
|
24
|
-
effect: (opts) =>
|
|
25
|
-
hasType({ ...opts, possibleTypes: ["Effect"], from: "effector" }),
|
|
26
|
-
store: (opts) =>
|
|
27
|
-
hasType({
|
|
28
|
-
...opts,
|
|
29
|
-
possibleTypes: ["Store", "StoreWritable"],
|
|
30
|
-
from: "effector",
|
|
31
|
-
}),
|
|
32
|
-
event: (opts) =>
|
|
33
|
-
hasType({
|
|
34
|
-
...opts,
|
|
35
|
-
possibleTypes: ["Event", "EventCallable"],
|
|
36
|
-
from: "effector",
|
|
37
|
-
}),
|
|
38
|
-
unit: (opts) =>
|
|
39
|
-
hasType({
|
|
40
|
-
...opts,
|
|
41
|
-
possibleTypes: [
|
|
42
|
-
"Effect",
|
|
43
|
-
"Store",
|
|
44
|
-
"Event",
|
|
45
|
-
"EventCallable",
|
|
46
|
-
"StoreWritable",
|
|
47
|
-
],
|
|
48
|
-
from: "effector",
|
|
49
|
-
}),
|
|
50
|
-
gate: (opts) =>
|
|
51
|
-
hasType({ ...opts, possibleTypes: ["Gate"], from: "effector-react" }),
|
|
52
|
-
effectorReactHook: (opts) =>
|
|
53
|
-
hasType({
|
|
54
|
-
...opts,
|
|
55
|
-
possibleTypes: opts.hook
|
|
56
|
-
? [].concat(opts.hook)
|
|
57
|
-
: [
|
|
58
|
-
"useStore",
|
|
59
|
-
"useStoreMap",
|
|
60
|
-
"useList",
|
|
61
|
-
"useEvent",
|
|
62
|
-
"useGate",
|
|
63
|
-
"useUnit",
|
|
64
|
-
],
|
|
65
|
-
from: "effector-react",
|
|
66
|
-
}),
|
|
67
|
-
not: {
|
|
68
|
-
effect: (opts) =>
|
|
69
|
-
!hasType({
|
|
70
|
-
...opts,
|
|
71
|
-
possibleTypes: ["Effect"],
|
|
72
|
-
from: "effector",
|
|
73
|
-
}),
|
|
74
|
-
store: (opts) =>
|
|
75
|
-
!hasType({
|
|
76
|
-
...opts,
|
|
77
|
-
possibleTypes: ["Store", "StoreWritable"],
|
|
78
|
-
from: "effector",
|
|
79
|
-
}),
|
|
80
|
-
event: (opts) =>
|
|
81
|
-
!hasType({
|
|
82
|
-
...opts,
|
|
83
|
-
possibleTypes: ["Event", "EventCallable"],
|
|
84
|
-
from: "effector",
|
|
85
|
-
}),
|
|
86
|
-
unit: (opts) =>
|
|
87
|
-
!hasType({
|
|
88
|
-
...opts,
|
|
89
|
-
possibleTypes: [
|
|
90
|
-
"Effect",
|
|
91
|
-
"Store",
|
|
92
|
-
"Event",
|
|
93
|
-
"EventCallable",
|
|
94
|
-
"StoreWritable",
|
|
95
|
-
],
|
|
96
|
-
from: "effector",
|
|
97
|
-
}),
|
|
98
|
-
gate: (opts) =>
|
|
99
|
-
!hasType({ ...opts, possibleTypes: ["Gate"], from: "effector-react" }),
|
|
100
|
-
effectorReactHook: (opts) => !nodeTypeIs.effectorReactHook(opts),
|
|
101
|
-
},
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
module.exports = {
|
|
105
|
-
nodeTypeIs,
|
|
106
|
-
};
|