@atom8n/eslint-plugin-community-nodes 0.7.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/.turbo/turbo-build.log +4 -0
- package/README.md +60 -0
- package/dist/plugin.d.ts +177 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +54 -0
- package/dist/plugin.js.map +1 -0
- package/dist/rules/credential-documentation-url.d.ts +7 -0
- package/dist/rules/credential-documentation-url.d.ts.map +1 -0
- package/dist/rules/credential-documentation-url.js +100 -0
- package/dist/rules/credential-documentation-url.js.map +1 -0
- package/dist/rules/credential-password-field.d.ts +2 -0
- package/dist/rules/credential-password-field.d.ts.map +1 -0
- package/dist/rules/credential-password-field.js +108 -0
- package/dist/rules/credential-password-field.js.map +1 -0
- package/dist/rules/credential-test-required.d.ts +2 -0
- package/dist/rules/credential-test-required.d.ts.map +1 -0
- package/dist/rules/credential-test-required.js +117 -0
- package/dist/rules/credential-test-required.js.map +1 -0
- package/dist/rules/icon-validation.d.ts +2 -0
- package/dist/rules/icon-validation.d.ts.map +1 -0
- package/dist/rules/icon-validation.js +197 -0
- package/dist/rules/icon-validation.js.map +1 -0
- package/dist/rules/index.d.ts +17 -0
- package/dist/rules/index.d.ts.map +1 -0
- package/dist/rules/index.js +25 -0
- package/dist/rules/index.js.map +1 -0
- package/dist/rules/no-credential-reuse.d.ts +2 -0
- package/dist/rules/no-credential-reuse.d.ts.map +1 -0
- package/dist/rules/no-credential-reuse.js +91 -0
- package/dist/rules/no-credential-reuse.js.map +1 -0
- package/dist/rules/no-deprecated-workflow-functions.d.ts +2 -0
- package/dist/rules/no-deprecated-workflow-functions.d.ts.map +1 -0
- package/dist/rules/no-deprecated-workflow-functions.js +172 -0
- package/dist/rules/no-deprecated-workflow-functions.js.map +1 -0
- package/dist/rules/no-restricted-globals.d.ts +3 -0
- package/dist/rules/no-restricted-globals.d.ts.map +1 -0
- package/dist/rules/no-restricted-globals.js +60 -0
- package/dist/rules/no-restricted-globals.js.map +1 -0
- package/dist/rules/no-restricted-imports.d.ts +2 -0
- package/dist/rules/no-restricted-imports.d.ts.map +1 -0
- package/dist/rules/no-restricted-imports.js +80 -0
- package/dist/rules/no-restricted-imports.js.map +1 -0
- package/dist/rules/node-usable-as-tool.d.ts +2 -0
- package/dist/rules/node-usable-as-tool.d.ts.map +1 -0
- package/dist/rules/node-usable-as-tool.js +58 -0
- package/dist/rules/node-usable-as-tool.js.map +1 -0
- package/dist/rules/package-name-convention.d.ts +2 -0
- package/dist/rules/package-name-convention.d.ts.map +1 -0
- package/dist/rules/package-name-convention.js +88 -0
- package/dist/rules/package-name-convention.js.map +1 -0
- package/dist/rules/resource-operation-pattern.d.ts +2 -0
- package/dist/rules/resource-operation-pattern.d.ts.map +1 -0
- package/dist/rules/resource-operation-pattern.js +79 -0
- package/dist/rules/resource-operation-pattern.js.map +1 -0
- package/dist/utils/ast-utils.d.ts +26 -0
- package/dist/utils/ast-utils.d.ts.map +1 -0
- package/dist/utils/ast-utils.js +135 -0
- package/dist/utils/ast-utils.js.map +1 -0
- package/dist/utils/file-utils.d.ts +26 -0
- package/dist/utils/file-utils.d.ts.map +1 -0
- package/dist/utils/file-utils.js +221 -0
- package/dist/utils/file-utils.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/rule-creator.d.ts +3 -0
- package/dist/utils/rule-creator.d.ts.map +1 -0
- package/dist/utils/rule-creator.js +5 -0
- package/dist/utils/rule-creator.js.map +1 -0
- package/docs/rules/credential-documentation-url.md +94 -0
- package/docs/rules/credential-password-field.md +45 -0
- package/docs/rules/credential-test-required.md +58 -0
- package/docs/rules/icon-validation.md +67 -0
- package/docs/rules/no-credential-reuse.md +82 -0
- package/docs/rules/no-deprecated-workflow-functions.md +61 -0
- package/docs/rules/no-restricted-globals.md +44 -0
- package/docs/rules/no-restricted-imports.md +47 -0
- package/docs/rules/node-usable-as-tool.md +43 -0
- package/docs/rules/package-name-convention.md +52 -0
- package/docs/rules/resource-operation-pattern.md +84 -0
- package/eslint.config.mjs +27 -0
- package/package.json +58 -0
- package/src/plugin.ts +59 -0
- package/src/rules/credential-documentation-url.test.ts +306 -0
- package/src/rules/credential-documentation-url.ts +129 -0
- package/src/rules/credential-password-field.test.ts +232 -0
- package/src/rules/credential-password-field.ts +141 -0
- package/src/rules/credential-test-required.test.ts +174 -0
- package/src/rules/credential-test-required.ts +145 -0
- package/src/rules/icon-validation.test.ts +279 -0
- package/src/rules/icon-validation.ts +239 -0
- package/src/rules/index.ts +27 -0
- package/src/rules/no-credential-reuse.test.ts +474 -0
- package/src/rules/no-credential-reuse.ts +121 -0
- package/src/rules/no-deprecated-workflow-functions.test.ts +187 -0
- package/src/rules/no-deprecated-workflow-functions.ts +200 -0
- package/src/rules/no-restricted-globals.test.ts +136 -0
- package/src/rules/no-restricted-globals.ts +74 -0
- package/src/rules/no-restricted-imports.test.ts +182 -0
- package/src/rules/no-restricted-imports.ts +91 -0
- package/src/rules/node-usable-as-tool.test.ts +81 -0
- package/src/rules/node-usable-as-tool.ts +72 -0
- package/src/rules/package-name-convention.test.ts +189 -0
- package/src/rules/package-name-convention.ts +107 -0
- package/src/rules/resource-operation-pattern.test.ts +217 -0
- package/src/rules/resource-operation-pattern.ts +104 -0
- package/src/utils/ast-utils.ts +207 -0
- package/src/utils/file-utils.ts +294 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/rule-creator.ts +6 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.eslint.json +5 -0
- package/tsconfig.json +10 -0
- package/vite.config.ts +4 -0
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# @n8n/eslint-plugin-community-nodes
|
|
2
|
+
|
|
3
|
+
ESLint plugin for linting n8n community node packages to ensure consistency and best practices.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm install --save-dev eslint @n8n/eslint-plugin-community-nodes
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**Requires ESLint `>=9` and [flat config](https://eslint.org/docs/latest/use/configure/configuration-files)
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
See the [ESLint docs](https://eslint.org/docs/latest/use/configure/configuration-files) for more information about extending config files.
|
|
16
|
+
|
|
17
|
+
### Recommended config
|
|
18
|
+
|
|
19
|
+
This plugin exports a `recommended` config that enforces good practices.
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
import { n8nCommunityNodesPlugin } from '@n8n/eslint-plugin-community-nodes';
|
|
23
|
+
|
|
24
|
+
export default [
|
|
25
|
+
// …
|
|
26
|
+
n8nCommunityNodesPlugin.configs.recommended,
|
|
27
|
+
{
|
|
28
|
+
rules: {
|
|
29
|
+
'@n8n/community-nodes/node-usable-as-tool': 'warn',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Rules
|
|
36
|
+
|
|
37
|
+
<!-- begin auto-generated rules list -->
|
|
38
|
+
|
|
39
|
+
💼 Configurations enabled in.\
|
|
40
|
+
⚠️ Configurations set to warn in.\
|
|
41
|
+
✅ Set in the `recommended` configuration.\
|
|
42
|
+
☑️ Set in the `recommendedWithoutN8nCloudSupport` configuration.\
|
|
43
|
+
🔧 Automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/user-guide/command-line-interface#--fix).\
|
|
44
|
+
💡 Manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
|
|
45
|
+
|
|
46
|
+
| Name | Description | 💼 | ⚠️ | 🔧 | 💡 |
|
|
47
|
+
| :--------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------- | :--- | :--- | :- | :- |
|
|
48
|
+
| [credential-documentation-url](docs/rules/credential-documentation-url.md) | Enforce valid credential documentationUrl format (URL or camelCase slug) | ✅ ☑️ | | | |
|
|
49
|
+
| [credential-password-field](docs/rules/credential-password-field.md) | Ensure credential fields with sensitive names have typeOptions.password = true | ✅ ☑️ | | 🔧 | |
|
|
50
|
+
| [credential-test-required](docs/rules/credential-test-required.md) | Ensure credentials have a credential test | ✅ ☑️ | | | 💡 |
|
|
51
|
+
| [icon-validation](docs/rules/icon-validation.md) | Validate node and credential icon files exist, are SVG format, and light/dark icons are different | ✅ ☑️ | | | 💡 |
|
|
52
|
+
| [no-credential-reuse](docs/rules/no-credential-reuse.md) | Prevent credential re-use security issues by ensuring nodes only reference credentials from the same package | ✅ ☑️ | | | 💡 |
|
|
53
|
+
| [no-deprecated-workflow-functions](docs/rules/no-deprecated-workflow-functions.md) | Disallow usage of deprecated functions and types from n8n-workflow package | ✅ ☑️ | | | 💡 |
|
|
54
|
+
| [no-restricted-globals](docs/rules/no-restricted-globals.md) | Disallow usage of restricted global variables in community nodes. | ✅ | | | |
|
|
55
|
+
| [no-restricted-imports](docs/rules/no-restricted-imports.md) | Disallow usage of restricted imports in community nodes. | ✅ | | | |
|
|
56
|
+
| [node-usable-as-tool](docs/rules/node-usable-as-tool.md) | Ensure node classes have usableAsTool property | ✅ ☑️ | | 🔧 | |
|
|
57
|
+
| [package-name-convention](docs/rules/package-name-convention.md) | Enforce correct package naming convention for n8n community nodes | ✅ ☑️ | | | 💡 |
|
|
58
|
+
| [resource-operation-pattern](docs/rules/resource-operation-pattern.md) | Enforce proper resource/operation pattern for better UX in n8n nodes | | ✅ ☑️ | | |
|
|
59
|
+
|
|
60
|
+
<!-- end auto-generated rules list -->
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import type { ESLint } from 'eslint';
|
|
2
|
+
import { rules } from './rules/index.js';
|
|
3
|
+
declare const configs: {
|
|
4
|
+
recommended: {
|
|
5
|
+
ignores: string[];
|
|
6
|
+
plugins: {
|
|
7
|
+
'@n8n/community-nodes': {
|
|
8
|
+
meta: {
|
|
9
|
+
name: string;
|
|
10
|
+
version: string;
|
|
11
|
+
namespace: string;
|
|
12
|
+
};
|
|
13
|
+
rules: ESLint.Plugin["rules"];
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
rules: {
|
|
17
|
+
'@n8n/community-nodes/no-restricted-globals': "error";
|
|
18
|
+
'@n8n/community-nodes/no-restricted-imports': "error";
|
|
19
|
+
'@n8n/community-nodes/credential-password-field': "error";
|
|
20
|
+
'@n8n/community-nodes/no-deprecated-workflow-functions': "error";
|
|
21
|
+
'@n8n/community-nodes/node-usable-as-tool': "error";
|
|
22
|
+
'@n8n/community-nodes/package-name-convention': "error";
|
|
23
|
+
'@n8n/community-nodes/credential-test-required': "error";
|
|
24
|
+
'@n8n/community-nodes/no-credential-reuse': "error";
|
|
25
|
+
'@n8n/community-nodes/icon-validation': "error";
|
|
26
|
+
'@n8n/community-nodes/resource-operation-pattern': "warn";
|
|
27
|
+
'@n8n/community-nodes/credential-documentation-url': "error";
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
recommendedWithoutN8nCloudSupport: {
|
|
31
|
+
ignores: string[];
|
|
32
|
+
plugins: {
|
|
33
|
+
'@n8n/community-nodes': {
|
|
34
|
+
meta: {
|
|
35
|
+
name: string;
|
|
36
|
+
version: string;
|
|
37
|
+
namespace: string;
|
|
38
|
+
};
|
|
39
|
+
rules: ESLint.Plugin["rules"];
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
rules: {
|
|
43
|
+
'@n8n/community-nodes/credential-password-field': "error";
|
|
44
|
+
'@n8n/community-nodes/no-deprecated-workflow-functions': "error";
|
|
45
|
+
'@n8n/community-nodes/node-usable-as-tool': "error";
|
|
46
|
+
'@n8n/community-nodes/package-name-convention': "error";
|
|
47
|
+
'@n8n/community-nodes/credential-test-required': "error";
|
|
48
|
+
'@n8n/community-nodes/no-credential-reuse': "error";
|
|
49
|
+
'@n8n/community-nodes/icon-validation': "error";
|
|
50
|
+
'@n8n/community-nodes/credential-documentation-url': "error";
|
|
51
|
+
'@n8n/community-nodes/resource-operation-pattern': "warn";
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
declare const pluginWithConfigs: {
|
|
56
|
+
configs: {
|
|
57
|
+
recommended: {
|
|
58
|
+
ignores: string[];
|
|
59
|
+
plugins: {
|
|
60
|
+
'@n8n/community-nodes': {
|
|
61
|
+
meta: {
|
|
62
|
+
name: string;
|
|
63
|
+
version: string;
|
|
64
|
+
namespace: string;
|
|
65
|
+
};
|
|
66
|
+
rules: ESLint.Plugin["rules"];
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
rules: {
|
|
70
|
+
'@n8n/community-nodes/no-restricted-globals': "error";
|
|
71
|
+
'@n8n/community-nodes/no-restricted-imports': "error";
|
|
72
|
+
'@n8n/community-nodes/credential-password-field': "error";
|
|
73
|
+
'@n8n/community-nodes/no-deprecated-workflow-functions': "error";
|
|
74
|
+
'@n8n/community-nodes/node-usable-as-tool': "error";
|
|
75
|
+
'@n8n/community-nodes/package-name-convention': "error";
|
|
76
|
+
'@n8n/community-nodes/credential-test-required': "error";
|
|
77
|
+
'@n8n/community-nodes/no-credential-reuse': "error";
|
|
78
|
+
'@n8n/community-nodes/icon-validation': "error";
|
|
79
|
+
'@n8n/community-nodes/resource-operation-pattern': "warn";
|
|
80
|
+
'@n8n/community-nodes/credential-documentation-url': "error";
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
recommendedWithoutN8nCloudSupport: {
|
|
84
|
+
ignores: string[];
|
|
85
|
+
plugins: {
|
|
86
|
+
'@n8n/community-nodes': {
|
|
87
|
+
meta: {
|
|
88
|
+
name: string;
|
|
89
|
+
version: string;
|
|
90
|
+
namespace: string;
|
|
91
|
+
};
|
|
92
|
+
rules: ESLint.Plugin["rules"];
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
rules: {
|
|
96
|
+
'@n8n/community-nodes/credential-password-field': "error";
|
|
97
|
+
'@n8n/community-nodes/no-deprecated-workflow-functions': "error";
|
|
98
|
+
'@n8n/community-nodes/node-usable-as-tool': "error";
|
|
99
|
+
'@n8n/community-nodes/package-name-convention': "error";
|
|
100
|
+
'@n8n/community-nodes/credential-test-required': "error";
|
|
101
|
+
'@n8n/community-nodes/no-credential-reuse': "error";
|
|
102
|
+
'@n8n/community-nodes/icon-validation': "error";
|
|
103
|
+
'@n8n/community-nodes/credential-documentation-url': "error";
|
|
104
|
+
'@n8n/community-nodes/resource-operation-pattern': "warn";
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
meta: {
|
|
109
|
+
name: string;
|
|
110
|
+
version: string;
|
|
111
|
+
namespace: string;
|
|
112
|
+
};
|
|
113
|
+
rules: ESLint.Plugin["rules"];
|
|
114
|
+
};
|
|
115
|
+
declare const n8nCommunityNodesPlugin: {
|
|
116
|
+
configs: {
|
|
117
|
+
recommended: {
|
|
118
|
+
ignores: string[];
|
|
119
|
+
plugins: {
|
|
120
|
+
'@n8n/community-nodes': {
|
|
121
|
+
meta: {
|
|
122
|
+
name: string;
|
|
123
|
+
version: string;
|
|
124
|
+
namespace: string;
|
|
125
|
+
};
|
|
126
|
+
rules: ESLint.Plugin["rules"];
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
rules: {
|
|
130
|
+
'@n8n/community-nodes/no-restricted-globals': "error";
|
|
131
|
+
'@n8n/community-nodes/no-restricted-imports': "error";
|
|
132
|
+
'@n8n/community-nodes/credential-password-field': "error";
|
|
133
|
+
'@n8n/community-nodes/no-deprecated-workflow-functions': "error";
|
|
134
|
+
'@n8n/community-nodes/node-usable-as-tool': "error";
|
|
135
|
+
'@n8n/community-nodes/package-name-convention': "error";
|
|
136
|
+
'@n8n/community-nodes/credential-test-required': "error";
|
|
137
|
+
'@n8n/community-nodes/no-credential-reuse': "error";
|
|
138
|
+
'@n8n/community-nodes/icon-validation': "error";
|
|
139
|
+
'@n8n/community-nodes/resource-operation-pattern': "warn";
|
|
140
|
+
'@n8n/community-nodes/credential-documentation-url': "error";
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
recommendedWithoutN8nCloudSupport: {
|
|
144
|
+
ignores: string[];
|
|
145
|
+
plugins: {
|
|
146
|
+
'@n8n/community-nodes': {
|
|
147
|
+
meta: {
|
|
148
|
+
name: string;
|
|
149
|
+
version: string;
|
|
150
|
+
namespace: string;
|
|
151
|
+
};
|
|
152
|
+
rules: ESLint.Plugin["rules"];
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
rules: {
|
|
156
|
+
'@n8n/community-nodes/credential-password-field': "error";
|
|
157
|
+
'@n8n/community-nodes/no-deprecated-workflow-functions': "error";
|
|
158
|
+
'@n8n/community-nodes/node-usable-as-tool': "error";
|
|
159
|
+
'@n8n/community-nodes/package-name-convention': "error";
|
|
160
|
+
'@n8n/community-nodes/credential-test-required': "error";
|
|
161
|
+
'@n8n/community-nodes/no-credential-reuse': "error";
|
|
162
|
+
'@n8n/community-nodes/icon-validation': "error";
|
|
163
|
+
'@n8n/community-nodes/credential-documentation-url': "error";
|
|
164
|
+
'@n8n/community-nodes/resource-operation-pattern': "warn";
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
meta: {
|
|
169
|
+
name: string;
|
|
170
|
+
version: string;
|
|
171
|
+
namespace: string;
|
|
172
|
+
};
|
|
173
|
+
rules: ESLint.Plugin["rules"];
|
|
174
|
+
};
|
|
175
|
+
export default pluginWithConfigs;
|
|
176
|
+
export { rules, configs, n8nCommunityNodesPlugin };
|
|
177
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AAG7C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAYzC,QAAA,MAAM,OAAO;;;;;;;;;;uBAHI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;uBAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;CAwCE,CAAC;AAE1C,QAAA,MAAM,iBAAiB;;;;;;;;;;;2BA1CN,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;2BAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;WAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;CA0CiC,CAAC;AAEzE,QAAA,MAAM,uBAAuB;;;;;;;;;;;2BA5CZ,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;2BAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;WAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;CA4CU,CAAC;AAClD,eAAe,iBAAiB,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
2
|
+
import { rules } from './rules/index.js';
|
|
3
|
+
const plugin = {
|
|
4
|
+
meta: {
|
|
5
|
+
name: pkg.name,
|
|
6
|
+
version: pkg.version,
|
|
7
|
+
namespace: '@n8n/community-nodes',
|
|
8
|
+
},
|
|
9
|
+
// @ts-expect-error Rules type does not match for typescript-eslint and eslint
|
|
10
|
+
rules: rules,
|
|
11
|
+
};
|
|
12
|
+
const configs = {
|
|
13
|
+
recommended: {
|
|
14
|
+
ignores: ['eslint.config.{js,mjs,ts,mts}'],
|
|
15
|
+
plugins: {
|
|
16
|
+
'@n8n/community-nodes': plugin,
|
|
17
|
+
},
|
|
18
|
+
rules: {
|
|
19
|
+
'@n8n/community-nodes/no-restricted-globals': 'error',
|
|
20
|
+
'@n8n/community-nodes/no-restricted-imports': 'error',
|
|
21
|
+
'@n8n/community-nodes/credential-password-field': 'error',
|
|
22
|
+
'@n8n/community-nodes/no-deprecated-workflow-functions': 'error',
|
|
23
|
+
'@n8n/community-nodes/node-usable-as-tool': 'error',
|
|
24
|
+
'@n8n/community-nodes/package-name-convention': 'error',
|
|
25
|
+
'@n8n/community-nodes/credential-test-required': 'error',
|
|
26
|
+
'@n8n/community-nodes/no-credential-reuse': 'error',
|
|
27
|
+
'@n8n/community-nodes/icon-validation': 'error',
|
|
28
|
+
'@n8n/community-nodes/resource-operation-pattern': 'warn',
|
|
29
|
+
'@n8n/community-nodes/credential-documentation-url': 'error',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
recommendedWithoutN8nCloudSupport: {
|
|
33
|
+
ignores: ['eslint.config.{js,mjs,ts,mts}'],
|
|
34
|
+
plugins: {
|
|
35
|
+
'@n8n/community-nodes': plugin,
|
|
36
|
+
},
|
|
37
|
+
rules: {
|
|
38
|
+
'@n8n/community-nodes/credential-password-field': 'error',
|
|
39
|
+
'@n8n/community-nodes/no-deprecated-workflow-functions': 'error',
|
|
40
|
+
'@n8n/community-nodes/node-usable-as-tool': 'error',
|
|
41
|
+
'@n8n/community-nodes/package-name-convention': 'error',
|
|
42
|
+
'@n8n/community-nodes/credential-test-required': 'error',
|
|
43
|
+
'@n8n/community-nodes/no-credential-reuse': 'error',
|
|
44
|
+
'@n8n/community-nodes/icon-validation': 'error',
|
|
45
|
+
'@n8n/community-nodes/credential-documentation-url': 'error',
|
|
46
|
+
'@n8n/community-nodes/resource-operation-pattern': 'warn',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
const pluginWithConfigs = { ...plugin, configs };
|
|
51
|
+
const n8nCommunityNodesPlugin = pluginWithConfigs;
|
|
52
|
+
export default pluginWithConfigs;
|
|
53
|
+
export { rules, configs, n8nCommunityNodesPlugin };
|
|
54
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAEA,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAEzC,MAAM,MAAM,GAAG;IACd,IAAI,EAAE;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,SAAS,EAAE,sBAAsB;KACjC;IACD,8EAA8E;IAC9E,KAAK,EAAE,KAA+B;CACd,CAAC;AAE1B,MAAM,OAAO,GAAG;IACf,WAAW,EAAE;QACZ,OAAO,EAAE,CAAC,+BAA+B,CAAC;QAC1C,OAAO,EAAE;YACR,sBAAsB,EAAE,MAAM;SAC9B;QACD,KAAK,EAAE;YACN,4CAA4C,EAAE,OAAO;YACrD,4CAA4C,EAAE,OAAO;YACrD,gDAAgD,EAAE,OAAO;YACzD,uDAAuD,EAAE,OAAO;YAChE,0CAA0C,EAAE,OAAO;YACnD,8CAA8C,EAAE,OAAO;YACvD,+CAA+C,EAAE,OAAO;YACxD,0CAA0C,EAAE,OAAO;YACnD,sCAAsC,EAAE,OAAO;YAC/C,iDAAiD,EAAE,MAAM;YACzD,mDAAmD,EAAE,OAAO;SAC5D;KACD;IACD,iCAAiC,EAAE;QAClC,OAAO,EAAE,CAAC,+BAA+B,CAAC;QAC1C,OAAO,EAAE;YACR,sBAAsB,EAAE,MAAM;SAC9B;QACD,KAAK,EAAE;YACN,gDAAgD,EAAE,OAAO;YACzD,uDAAuD,EAAE,OAAO;YAChE,0CAA0C,EAAE,OAAO;YACnD,8CAA8C,EAAE,OAAO;YACvD,+CAA+C,EAAE,OAAO;YACxD,0CAA0C,EAAE,OAAO;YACnD,sCAAsC,EAAE,OAAO;YAC/C,mDAAmD,EAAE,OAAO;YAC5D,iDAAiD,EAAE,MAAM;SACzD;KACD;CACuC,CAAC;AAE1C,MAAM,iBAAiB,GAAG,EAAE,GAAG,MAAM,EAAE,OAAO,EAA0B,CAAC;AAEzE,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;AAClD,eAAe,iBAAiB,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
type RuleOptions = {
|
|
2
|
+
allowUrls?: boolean;
|
|
3
|
+
allowSlugs?: boolean;
|
|
4
|
+
};
|
|
5
|
+
export declare const CredentialDocumentationUrlRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidDocumentationUrl", [RuleOptions], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=credential-documentation-url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-documentation-url.d.ts","sourceRoot":"","sources":["../../src/rules/credential-documentation-url.ts"],"names":[],"mappings":"AAOA,KAAK,WAAW,GAAG;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AA+CF,eAAO,MAAM,8BAA8B,uKAuEzC,CAAC"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { isCredentialTypeClass, findClassProperty, getStringLiteralValue, createRule, } from '../utils/index.js';
|
|
2
|
+
const DEFAULT_OPTIONS = {
|
|
3
|
+
allowUrls: true,
|
|
4
|
+
allowSlugs: false,
|
|
5
|
+
};
|
|
6
|
+
function isValidUrl(value) {
|
|
7
|
+
try {
|
|
8
|
+
new URL(value);
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function isValidSlug(value) {
|
|
16
|
+
// TODO: Remove this special case once these slugs are updated
|
|
17
|
+
if (['google/service-account', 'google/oauth-single-service', 'google/oauth-generic'].includes(value))
|
|
18
|
+
return true;
|
|
19
|
+
return value.split('/').every((segment) => /^[a-z][a-z0-9]*$/.test(segment));
|
|
20
|
+
}
|
|
21
|
+
function hasOnlyCaseIssues(value) {
|
|
22
|
+
return value.split('/').every((segment) => /^[a-zA-Z][a-zA-Z0-9]*$/.test(segment));
|
|
23
|
+
}
|
|
24
|
+
function validateDocumentationUrl(value, options) {
|
|
25
|
+
return (!!options.allowUrls && isValidUrl(value)) || (!!options.allowSlugs && isValidSlug(value));
|
|
26
|
+
}
|
|
27
|
+
function getExpectedFormatsMessage(options) {
|
|
28
|
+
const formats = [
|
|
29
|
+
...(options.allowUrls ? ['a valid URL'] : []),
|
|
30
|
+
...(options.allowSlugs ? ['a lowercase alphanumeric slug (can contain slashes)'] : []),
|
|
31
|
+
];
|
|
32
|
+
if (formats.length === 0)
|
|
33
|
+
return 'a valid format (none configured)';
|
|
34
|
+
if (formats.length === 1)
|
|
35
|
+
return formats[0];
|
|
36
|
+
return formats.slice(0, -1).join(', ') + ' or ' + formats[formats.length - 1];
|
|
37
|
+
}
|
|
38
|
+
export const CredentialDocumentationUrlRule = createRule({
|
|
39
|
+
name: 'credential-documentation-url',
|
|
40
|
+
meta: {
|
|
41
|
+
type: 'problem',
|
|
42
|
+
docs: {
|
|
43
|
+
description: 'Enforce valid credential documentationUrl format (URL or lowercase alphanumeric slug)',
|
|
44
|
+
},
|
|
45
|
+
messages: {
|
|
46
|
+
invalidDocumentationUrl: "documentationUrl '{{ value }}' must be {{ expectedFormats }}",
|
|
47
|
+
},
|
|
48
|
+
fixable: 'code',
|
|
49
|
+
schema: [
|
|
50
|
+
{
|
|
51
|
+
type: 'object',
|
|
52
|
+
properties: {
|
|
53
|
+
allowUrls: {
|
|
54
|
+
type: 'boolean',
|
|
55
|
+
description: 'Whether to allow valid URLs',
|
|
56
|
+
},
|
|
57
|
+
allowSlugs: {
|
|
58
|
+
type: 'boolean',
|
|
59
|
+
description: 'Whether to allow lowercase alphanumeric slugs with slashes',
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
additionalProperties: false,
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
defaultOptions: [DEFAULT_OPTIONS],
|
|
67
|
+
create(context, [options = {}]) {
|
|
68
|
+
const mergedOptions = { ...DEFAULT_OPTIONS, ...options };
|
|
69
|
+
return {
|
|
70
|
+
ClassDeclaration(node) {
|
|
71
|
+
if (!isCredentialTypeClass(node)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const documentationUrlProperty = findClassProperty(node, 'documentationUrl');
|
|
75
|
+
if (!documentationUrlProperty?.value) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const documentationUrl = getStringLiteralValue(documentationUrlProperty.value);
|
|
79
|
+
if (documentationUrl === null) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (!validateDocumentationUrl(documentationUrl, mergedOptions)) {
|
|
83
|
+
const canAutofix = !!mergedOptions.allowSlugs && hasOnlyCaseIssues(documentationUrl);
|
|
84
|
+
context.report({
|
|
85
|
+
node: documentationUrlProperty.value,
|
|
86
|
+
messageId: 'invalidDocumentationUrl',
|
|
87
|
+
data: {
|
|
88
|
+
value: documentationUrl,
|
|
89
|
+
expectedFormats: getExpectedFormatsMessage(mergedOptions),
|
|
90
|
+
},
|
|
91
|
+
fix: canAutofix
|
|
92
|
+
? (fixer) => fixer.replaceText(documentationUrlProperty.value, `'${documentationUrl.toLowerCase()}'`)
|
|
93
|
+
: undefined,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
//# sourceMappingURL=credential-documentation-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-documentation-url.js","sourceRoot":"","sources":["../../src/rules/credential-documentation-url.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-password-field.d.ts","sourceRoot":"","sources":["../../src/rules/credential-password-field.ts"],"names":[],"mappings":"AAoFA,eAAO,MAAM,2BAA2B,0JAwDtC,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { TSESTree } from '@typescript-eslint/types';
|
|
2
|
+
import { isCredentialTypeClass, findClassProperty, findObjectProperty, getStringLiteralValue, getBooleanLiteralValue, createRule, } from '../utils/index.js';
|
|
3
|
+
const SENSITIVE_PATTERNS = [
|
|
4
|
+
'password',
|
|
5
|
+
'secret',
|
|
6
|
+
'token',
|
|
7
|
+
'cert',
|
|
8
|
+
'passphrase',
|
|
9
|
+
'apikey',
|
|
10
|
+
'secretkey',
|
|
11
|
+
'privatekey',
|
|
12
|
+
'authkey',
|
|
13
|
+
];
|
|
14
|
+
const NON_SENSITIVE_PATTERNS = ['url', 'pub', 'id'];
|
|
15
|
+
function isSensitiveFieldName(name) {
|
|
16
|
+
const lowerName = name.toLowerCase();
|
|
17
|
+
if (NON_SENSITIVE_PATTERNS.some((pattern) => lowerName.includes(pattern))) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return SENSITIVE_PATTERNS.some((pattern) => lowerName.includes(pattern));
|
|
21
|
+
}
|
|
22
|
+
function hasPasswordTypeOption(element) {
|
|
23
|
+
const typeOptionsProperty = findObjectProperty(element, 'typeOptions');
|
|
24
|
+
if (typeOptionsProperty?.value.type !== TSESTree.AST_NODE_TYPES.ObjectExpression) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
const passwordProperty = findObjectProperty(typeOptionsProperty.value, 'password');
|
|
28
|
+
const passwordValue = passwordProperty ? getBooleanLiteralValue(passwordProperty.value) : null;
|
|
29
|
+
return passwordValue === true;
|
|
30
|
+
}
|
|
31
|
+
function createPasswordFix(element, typeOptionsProperty) {
|
|
32
|
+
return (fixer) => {
|
|
33
|
+
if (typeOptionsProperty?.value.type === TSESTree.AST_NODE_TYPES.ObjectExpression) {
|
|
34
|
+
const passwordProperty = findObjectProperty(typeOptionsProperty.value, 'password');
|
|
35
|
+
if (passwordProperty) {
|
|
36
|
+
return fixer.replaceText(passwordProperty.value, 'true');
|
|
37
|
+
}
|
|
38
|
+
const objectValue = typeOptionsProperty.value;
|
|
39
|
+
if (objectValue.properties.length > 0) {
|
|
40
|
+
const lastProperty = objectValue.properties[objectValue.properties.length - 1];
|
|
41
|
+
if (lastProperty) {
|
|
42
|
+
return fixer.insertTextAfter(lastProperty, ', password: true');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const range = objectValue.range;
|
|
47
|
+
if (range) {
|
|
48
|
+
const openBrace = range[0] + 1;
|
|
49
|
+
return fixer.insertTextAfterRange([openBrace, openBrace], ' password: true ');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const lastProperty = element.properties[element.properties.length - 1];
|
|
54
|
+
if (lastProperty) {
|
|
55
|
+
return fixer.insertTextAfter(lastProperty, ',\n\t\t\ttypeOptions: { password: true }');
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export const CredentialPasswordFieldRule = createRule({
|
|
61
|
+
name: 'credential-password-field',
|
|
62
|
+
meta: {
|
|
63
|
+
type: 'problem',
|
|
64
|
+
docs: {
|
|
65
|
+
description: 'Ensure credential fields with sensitive names have typeOptions.password = true',
|
|
66
|
+
},
|
|
67
|
+
messages: {
|
|
68
|
+
missingPasswordOption: "Field '{{ fieldName }}' appears to be a sensitive field but is missing 'typeOptions: { password: true }'",
|
|
69
|
+
},
|
|
70
|
+
fixable: 'code',
|
|
71
|
+
schema: [],
|
|
72
|
+
},
|
|
73
|
+
defaultOptions: [],
|
|
74
|
+
create(context) {
|
|
75
|
+
return {
|
|
76
|
+
ClassDeclaration(node) {
|
|
77
|
+
if (!isCredentialTypeClass(node)) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const propertiesProperty = findClassProperty(node, 'properties');
|
|
81
|
+
if (!propertiesProperty?.value ||
|
|
82
|
+
propertiesProperty.value.type !== TSESTree.AST_NODE_TYPES.ArrayExpression) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
for (const element of propertiesProperty.value.elements) {
|
|
86
|
+
if (element?.type !== TSESTree.AST_NODE_TYPES.ObjectExpression) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const nameProperty = findObjectProperty(element, 'name');
|
|
90
|
+
const fieldName = nameProperty ? getStringLiteralValue(nameProperty.value) : null;
|
|
91
|
+
if (!fieldName || !isSensitiveFieldName(fieldName)) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
if (!hasPasswordTypeOption(element)) {
|
|
95
|
+
const typeOptionsProperty = findObjectProperty(element, 'typeOptions');
|
|
96
|
+
context.report({
|
|
97
|
+
node: element,
|
|
98
|
+
messageId: 'missingPasswordOption',
|
|
99
|
+
data: { fieldName },
|
|
100
|
+
fix: createPasswordFix(element, typeOptionsProperty),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=credential-password-field.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-password-field.js","sourceRoot":"","sources":["../../src/rules/credential-password-field.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-test-required.d.ts","sourceRoot":"","sources":["../../src/rules/credential-test-required.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,0BAA0B,0KAyHrC,CAAC"}
|