@darraghor/eslint-plugin-nestjs-typed 6.9.19 → 6.10.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 +1 -0
- package/dist/configs/recommended.js +2 -1
- package/dist/rules/index.d.ts +1 -0
- package/dist/rules/index.js +3 -1
- package/dist/rules/useInjectableProvidedToken/useInjectableProvidedToken.d.ts +2 -0
- package/dist/rules/useInjectableProvidedToken/useInjectableProvidedToken.js +90 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,6 +62,7 @@ Awesome! [Click here](https://github.com/darraghoriordan/eslint-plugin-nestjs-ty
|
|
|
62
62
|
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- |
|
|
63
63
|
| Nest Modules and Dependency Injection | [`provided-injected-should-match-factory-parameters`](./src/docs/rules/provided-injected-should-match-factory-parameters.md) | ✅ |
|
|
64
64
|
| | [`injectable-should-be-provided`](./src/docs/rules/injectable-should-be-provided.md) | ✅ |
|
|
65
|
+
| | [`use-injectable-provided-token`](./src/docs/rules/use-injectable-provided-token.md) | ✅ |
|
|
65
66
|
| | | |
|
|
66
67
|
| Nest Swagger | [`api-property-matches-property-optionality`](./src/docs/rules/api-property-matches-property-optionality.md) | ✅ |
|
|
67
68
|
| | [`controllers-should-supply-api-tags`](./src/docs/rules/controllers-should-supply-api-tags.md) | ✅ |
|
|
@@ -22,9 +22,10 @@ export const rules = {
|
|
|
22
22
|
"@darraghor/nestjs-typed/api-method-should-specify-api-operation": "off",
|
|
23
23
|
"@darraghor/nestjs-typed/sort-module-metadata-arrays": "off",
|
|
24
24
|
"@darraghor/nestjs-typed/no-duplicate-decorators": "error",
|
|
25
|
+
"@darraghor/nestjs-typed/use-injectable-provided-token": "error",
|
|
25
26
|
};
|
|
26
27
|
export default {
|
|
27
28
|
extends: ["./configs/base"],
|
|
28
29
|
rules,
|
|
29
30
|
};
|
|
30
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb21tZW5kZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlncy9yZWNvbW1lbmRlZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxNQUFNLENBQUMsTUFBTSxLQUFLLEdBQWdDO0lBQzlDLDJFQUEyRSxFQUN2RSxPQUFPO0lBQ1gsdURBQXVELEVBQUU7UUFDckQsT0FBTztRQUNQO1lBQ0ksR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDO1lBQ3BCLGVBQWUsRUFBRSxDQUFDLGNBQWMsRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDO1NBQ3hEO0tBQ0o7SUFDRCxtRUFBbUUsRUFDL0QsT0FBTztJQUNYLGdFQUFnRSxFQUFFLE9BQU87SUFDekUsNERBQTRELEVBQUUsT0FBTztJQUNyRSwwREFBMEQsRUFBRSxPQUFPO0lBQ25FLHVFQUF1RSxFQUNuRSxPQUFPO0lBQ1gsOERBQThELEVBQUUsT0FBTztJQUN2RSxrRUFBa0UsRUFBRSxPQUFPO0lBQzNFLCtFQUErRSxFQUMzRSxPQUFPO0lBQ1gsa0VBQWtFLEVBQUUsT0FBTztJQUMzRSx3REFBd0QsRUFBRSxPQUFPO0lBQ2pFLDhEQUE4RCxFQUFFLE9BQU87SUFDdkUsdURBQXVELEVBQUUsS0FBSztJQUM5RCxpRUFBaUUsRUFBRSxLQUFLO0lBQ3hFLHFEQUFxRCxFQUFFLEtBQUs7SUFDNUQsaURBQWlELEVBQUUsT0FBTztJQUMxRCx1REFBdUQsRUFBRSxPQUFPO0NBQ25FLENBQUM7QUFDRixlQUFlO0lBQ1gsT0FBTyxFQUFFLENBQUMsZ0JBQWdCLENBQUM7SUFDM0IsS0FBSztDQUNSLENBQUMifQ==
|
package/dist/rules/index.d.ts
CHANGED
|
@@ -21,5 +21,6 @@ declare const allRules: {
|
|
|
21
21
|
"all-properties-are-whitelisted": import("@typescript-eslint/utils/ts-eslint").RuleModule<"missing-property-decorator", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
22
22
|
"api-methods-should-be-guarded": import("@typescript-eslint/utils/ts-eslint").RuleModule<"apiMethodsShouldBeGuarded", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
23
23
|
"sort-module-metadata-arrays": import("@typescript-eslint/utils/ts-eslint").RuleModule<"moduleMetadataArraysAreSorted", import("./sortModuleMetadataArrays/sortModuleMetadataArrays.js").RuleOptions, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
24
|
+
"use-injectable-provided-token": import("@typescript-eslint/utils/ts-eslint").RuleModule<"useInjectableProvidedToken", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
24
25
|
};
|
|
25
26
|
export default allRules;
|
package/dist/rules/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import apiMethodsShouldBeGuarded from "./apiMethodsShouldBeGuarded/apiMethodsSho
|
|
|
15
15
|
import apiMethodsShouldSpecifyApiOperation from "./apiMethodsShouldSpecifyApiOperation/apiMethodsShouldSpecifyApiOperation.js";
|
|
16
16
|
import sortModuleMetadataArrays from "./sortModuleMetadataArrays/sortModuleMetadataArrays.js";
|
|
17
17
|
import noDuplicateDecorators from "./noDuplicateDecorators/noDuplicateDecorators.js";
|
|
18
|
+
import useInjectableProvidedToken from "./useInjectableProvidedToken/useInjectableProvidedToken.js";
|
|
18
19
|
const allRules = {
|
|
19
20
|
"all-properties-have-explicit-defined": allPropertiesHaveExplicitDefined,
|
|
20
21
|
"api-property-matches-property-optionality": apiPropertyMatchesPropertyOptionality,
|
|
@@ -33,6 +34,7 @@ const allRules = {
|
|
|
33
34
|
"all-properties-are-whitelisted": allPropertiesAreWhitelisted,
|
|
34
35
|
"api-methods-should-be-guarded": apiMethodsShouldBeGuarded,
|
|
35
36
|
"sort-module-metadata-arrays": sortModuleMetadataArrays,
|
|
37
|
+
"use-injectable-provided-token": useInjectableProvidedToken,
|
|
36
38
|
};
|
|
37
39
|
export default allRules;
|
|
38
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
40
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVsZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTywwQkFBMEIsTUFBTSw2REFBNkQsQ0FBQztBQUNyRyxPQUFPLDRDQUE0QyxNQUFNLDRFQUE0RSxDQUFDO0FBQ3RJLE9BQU8scUNBQXFDLE1BQU0sa0ZBQWtGLENBQUM7QUFDckksT0FBTyw2QkFBNkIsTUFBTSxrRUFBa0UsQ0FBQztBQUM3RyxPQUFPLGtDQUFrQyxNQUFNLDRFQUE0RSxDQUFDO0FBQzVILE9BQU8sNEJBQTRCLE1BQU0sZ0VBQWdFLENBQUM7QUFDMUcsT0FBTyx1Q0FBdUMsTUFBTSxzRkFBc0YsQ0FBQztBQUMzSSxPQUFPLGdDQUFnQyxNQUFNLDRFQUE0RSxDQUFDO0FBQzFILE9BQU8sdUNBQXVDLE1BQU0sOEVBQThFLENBQUM7QUFDbkksT0FBTyxtQ0FBbUMsTUFBTSxpRkFBaUYsQ0FBQztBQUNsSSxPQUFPLGtDQUFrQyxNQUFNLDRFQUE0RSxDQUFDO0FBQzVILE9BQU8sMkJBQTJCLE1BQU0sOERBQThELENBQUM7QUFDdkcsT0FBTyxnQ0FBZ0MsTUFBTSx3RUFBd0UsQ0FBQztBQUN0SCxPQUFPLHlCQUF5QixNQUFNLDBEQUEwRCxDQUFDO0FBQ2pHLE9BQU8sbUNBQW1DLE1BQU0sOEVBQThFLENBQUM7QUFDL0gsT0FBTyx3QkFBd0IsTUFBTSx3REFBd0QsQ0FBQztBQUM5RixPQUFPLHFCQUFxQixNQUFNLGtEQUFrRCxDQUFDO0FBQ3JGLE9BQU8sMEJBQTBCLE1BQU0sNERBQTRELENBQUM7QUFDcEcsTUFBTSxRQUFRLEdBQUc7SUFDYixzQ0FBc0MsRUFBRSxnQ0FBZ0M7SUFDeEUsMkNBQTJDLEVBQ3ZDLHFDQUFxQztJQUN6QywrQkFBK0IsRUFBRSwwQkFBMEI7SUFDM0QseUJBQXlCLEVBQUUscUJBQXFCO0lBQ2hELG1EQUFtRCxFQUMvQyw0Q0FBNEM7SUFDaEQsb0NBQW9DLEVBQUUsNkJBQTZCO0lBQ25FLHdDQUF3QyxFQUNwQyxrQ0FBa0M7SUFDdEMseUNBQXlDLEVBQ3JDLG1DQUFtQztJQUN2QyxrQ0FBa0MsRUFBRSw0QkFBNEI7SUFDaEUsK0NBQStDLEVBQzNDLHVDQUF1QztJQUMzQyxzQ0FBc0MsRUFBRSxnQ0FBZ0M7SUFDeEUsMENBQTBDLEVBQ3RDLHVDQUF1QztJQUMzQyx1REFBdUQsRUFDbkQsbUNBQW1DO0lBQ3ZDLDBDQUEwQyxFQUN0QyxrQ0FBa0M7SUFDdEMsZ0NBQWdDLEVBQUUsMkJBQTJCO0lBQzdELCtCQUErQixFQUFFLHlCQUF5QjtJQUMxRCw2QkFBNkIsRUFBRSx3QkFBd0I7SUFDdkQsK0JBQStCLEVBQUUsMEJBQTBCO0NBQzlELENBQUM7QUFFRixlQUFlLFFBQVEsQ0FBQyJ9
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { TSESTree } from "@typescript-eslint/utils";
|
|
2
|
+
import { createRule } from "../../utils/createRule.js";
|
|
3
|
+
// These are special NestJS tokens that cannot be used with app.get() or @Inject()
|
|
4
|
+
// because they are applied globally and don't work like regular providers
|
|
5
|
+
const FORBIDDEN_APP_TOKENS = new Set([
|
|
6
|
+
"APP_GUARD",
|
|
7
|
+
"APP_PIPE",
|
|
8
|
+
"APP_FILTER",
|
|
9
|
+
"APP_INTERCEPTOR",
|
|
10
|
+
]);
|
|
11
|
+
/**
|
|
12
|
+
* Checks if a node is an identifier with one of the forbidden APP_* token names
|
|
13
|
+
*/
|
|
14
|
+
const isForbiddenAppToken = (node) => {
|
|
15
|
+
if (!node) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (node.type === TSESTree.AST_NODE_TYPES.Identifier) {
|
|
19
|
+
return FORBIDDEN_APP_TOKENS.has(node.name);
|
|
20
|
+
}
|
|
21
|
+
return false;
|
|
22
|
+
};
|
|
23
|
+
const rule = createRule({
|
|
24
|
+
name: "use-injectable-provided-token",
|
|
25
|
+
meta: {
|
|
26
|
+
docs: {
|
|
27
|
+
description: "Prevents using APP_GUARD, APP_PIPE, APP_FILTER, or APP_INTERCEPTOR tokens with app.get() or @Inject() as these are global providers that cannot be retrieved this way.",
|
|
28
|
+
},
|
|
29
|
+
messages: {
|
|
30
|
+
useInjectableProvidedToken: "Cannot use {{tokenName}} with {{method}}. These tokens are for global providers and cannot be retrieved or injected directly. Use them only in module provider arrays.",
|
|
31
|
+
},
|
|
32
|
+
schema: [],
|
|
33
|
+
hasSuggestions: false,
|
|
34
|
+
type: "problem",
|
|
35
|
+
},
|
|
36
|
+
defaultOptions: [],
|
|
37
|
+
create(context) {
|
|
38
|
+
return {
|
|
39
|
+
// Check for app.get(APP_*) calls
|
|
40
|
+
CallExpression(node) {
|
|
41
|
+
// Check if this is a member expression like app.get()
|
|
42
|
+
if (node.callee.type ===
|
|
43
|
+
TSESTree.AST_NODE_TYPES.MemberExpression) {
|
|
44
|
+
const memberExpression = node.callee;
|
|
45
|
+
// Check if the method is 'get'
|
|
46
|
+
if (memberExpression.property.type ===
|
|
47
|
+
TSESTree.AST_NODE_TYPES.Identifier &&
|
|
48
|
+
memberExpression.property.name === "get") {
|
|
49
|
+
// Check if the first argument is one of the forbidden tokens
|
|
50
|
+
const firstArgument = node.arguments[0];
|
|
51
|
+
if (isForbiddenAppToken(firstArgument)) {
|
|
52
|
+
context.report({
|
|
53
|
+
node: firstArgument,
|
|
54
|
+
messageId: "useInjectableProvidedToken",
|
|
55
|
+
data: {
|
|
56
|
+
tokenName: firstArgument.name,
|
|
57
|
+
method: "app.get()",
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
// Check for @Inject(APP_*) decorators
|
|
65
|
+
Decorator(node) {
|
|
66
|
+
// Check if this is an @Inject decorator
|
|
67
|
+
if (node.expression.type ===
|
|
68
|
+
TSESTree.AST_NODE_TYPES.CallExpression &&
|
|
69
|
+
node.expression.callee.type ===
|
|
70
|
+
TSESTree.AST_NODE_TYPES.Identifier &&
|
|
71
|
+
node.expression.callee.name === "Inject") {
|
|
72
|
+
// Check if the first argument is one of the forbidden tokens
|
|
73
|
+
const firstArgument = node.expression.arguments[0];
|
|
74
|
+
if (isForbiddenAppToken(firstArgument)) {
|
|
75
|
+
context.report({
|
|
76
|
+
node: firstArgument,
|
|
77
|
+
messageId: "useInjectableProvidedToken",
|
|
78
|
+
data: {
|
|
79
|
+
tokenName: firstArgument.name,
|
|
80
|
+
method: "@Inject()",
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
export default rule;
|
|
90
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlSW5qZWN0YWJsZVByb3ZpZGVkVG9rZW4uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcnVsZXMvdXNlSW5qZWN0YWJsZVByb3ZpZGVkVG9rZW4vdXNlSW5qZWN0YWJsZVByb3ZpZGVkVG9rZW4udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQ2xELE9BQU8sRUFBQyxVQUFVLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUVyRCxrRkFBa0Y7QUFDbEYsMEVBQTBFO0FBQzFFLE1BQU0sb0JBQW9CLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDakMsV0FBVztJQUNYLFVBQVU7SUFDVixZQUFZO0lBQ1osaUJBQWlCO0NBQ3BCLENBQUMsQ0FBQztBQUVIOztHQUVHO0FBQ0gsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLElBQStCLEVBQVcsRUFBRTtJQUNyRSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDUixPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBRUQsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDbkQsT0FBTyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFRCxPQUFPLEtBQUssQ0FBQztBQUNqQixDQUFDLENBQUM7QUFFRixNQUFNLElBQUksR0FBRyxVQUFVLENBQW1DO0lBQ3RELElBQUksRUFBRSwrQkFBK0I7SUFDckMsSUFBSSxFQUFFO1FBQ0YsSUFBSSxFQUFFO1lBQ0YsV0FBVyxFQUNQLHdLQUF3SztTQUMvSztRQUNELFFBQVEsRUFBRTtZQUNOLDBCQUEwQixFQUN0Qix3S0FBd0s7U0FDL0s7UUFDRCxNQUFNLEVBQUUsRUFBRTtRQUNWLGNBQWMsRUFBRSxLQUFLO1FBQ3JCLElBQUksRUFBRSxTQUFTO0tBQ2xCO0lBQ0QsY0FBYyxFQUFFLEVBQUU7SUFDbEIsTUFBTSxDQUFDLE9BQU87UUFDVixPQUFPO1lBQ0gsaUNBQWlDO1lBQ2pDLGNBQWMsQ0FBQyxJQUE2QjtnQkFDeEMsc0RBQXNEO2dCQUN0RCxJQUNJLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSTtvQkFDaEIsUUFBUSxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsRUFDMUMsQ0FBQztvQkFDQyxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7b0JBRXJDLCtCQUErQjtvQkFDL0IsSUFDSSxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsSUFBSTt3QkFDMUIsUUFBUSxDQUFDLGNBQWMsQ0FBQyxVQUFVO3dCQUN0QyxnQkFBZ0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxLQUFLLEtBQUssRUFDMUMsQ0FBQzt3QkFDQyw2REFBNkQ7d0JBQzdELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ3hDLElBQUksbUJBQW1CLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQzs0QkFDckMsT0FBTyxDQUFDLE1BQU0sQ0FBQztnQ0FDWCxJQUFJLEVBQUUsYUFBYTtnQ0FDbkIsU0FBUyxFQUFFLDRCQUE0QjtnQ0FDdkMsSUFBSSxFQUFFO29DQUNGLFNBQVMsRUFDTCxhQUNILENBQUMsSUFBSTtvQ0FDTixNQUFNLEVBQUUsV0FBVztpQ0FDdEI7NkJBQ0osQ0FBQyxDQUFDO3dCQUNQLENBQUM7b0JBQ0wsQ0FBQztnQkFDTCxDQUFDO1lBQ0wsQ0FBQztZQUVELHNDQUFzQztZQUN0QyxTQUFTLENBQUMsSUFBd0I7Z0JBQzlCLHdDQUF3QztnQkFDeEMsSUFDSSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUk7b0JBQ2hCLFFBQVEsQ0FBQyxjQUFjLENBQUMsY0FBYztvQkFDMUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsSUFBSTt3QkFDdkIsUUFBUSxDQUFDLGNBQWMsQ0FBQyxVQUFVO29CQUN0QyxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUMxQyxDQUFDO29CQUNDLDZEQUE2RDtvQkFDN0QsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ25ELElBQUksbUJBQW1CLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQzt3QkFDckMsT0FBTyxDQUFDLE1BQU0sQ0FBQzs0QkFDWCxJQUFJLEVBQUUsYUFBYTs0QkFDbkIsU0FBUyxFQUFFLDRCQUE0Qjs0QkFDdkMsSUFBSSxFQUFFO2dDQUNGLFNBQVMsRUFDTCxhQUNILENBQUMsSUFBSTtnQ0FDTixNQUFNLEVBQUUsV0FBVzs2QkFDdEI7eUJBQ0osQ0FBQyxDQUFDO29CQUNQLENBQUM7Z0JBQ0wsQ0FBQztZQUNMLENBQUM7U0FDSixDQUFDO0lBQ04sQ0FBQztDQUNKLENBQUMsQ0FBQztBQUVILGVBQWUsSUFBSSxDQUFDIn0=
|