@n8n/eslint-plugin-community-nodes 0.12.0 → 0.13.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.
Files changed (34) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/README.md +2 -1
  3. package/dist/plugin.d.ts +12 -6
  4. package/dist/plugin.d.ts.map +1 -1
  5. package/dist/plugin.js +4 -2
  6. package/dist/plugin.js.map +1 -1
  7. package/dist/rules/index.d.ts +2 -0
  8. package/dist/rules/index.d.ts.map +1 -1
  9. package/dist/rules/index.js +4 -0
  10. package/dist/rules/index.js.map +1 -1
  11. package/dist/rules/node-class-description-icon-missing.d.ts +1 -0
  12. package/dist/rules/node-class-description-icon-missing.d.ts.map +1 -1
  13. package/dist/rules/node-class-description-icon-missing.js +6 -1
  14. package/dist/rules/node-class-description-icon-missing.js.map +1 -1
  15. package/dist/rules/require-community-node-keyword.d.ts +2 -0
  16. package/dist/rules/require-community-node-keyword.d.ts.map +1 -0
  17. package/dist/rules/require-community-node-keyword.js +65 -0
  18. package/dist/rules/require-community-node-keyword.js.map +1 -0
  19. package/dist/rules/require-node-description-fields.d.ts +2 -0
  20. package/dist/rules/require-node-description-fields.d.ts.map +1 -0
  21. package/dist/rules/require-node-description-fields.js +58 -0
  22. package/dist/rules/require-node-description-fields.js.map +1 -0
  23. package/docs/rules/node-class-description-icon-missing.md +1 -1
  24. package/docs/rules/require-community-node-keyword.md +45 -0
  25. package/docs/rules/require-node-description-fields.md +46 -0
  26. package/package.json +3 -3
  27. package/src/plugin.ts +4 -2
  28. package/src/rules/index.ts +4 -0
  29. package/src/rules/node-class-description-icon-missing.ts +7 -1
  30. package/src/rules/require-community-node-keyword.test.ts +82 -0
  31. package/src/rules/require-community-node-keyword.ts +78 -0
  32. package/src/rules/require-node-description-fields.test.ts +171 -0
  33. package/src/rules/require-node-description-fields.ts +77 -0
  34. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,4 +1,4 @@
1
1
 
2
- > @n8n/eslint-plugin-community-nodes@0.12.0 build /home/runner/work/n8n/n8n/packages/@n8n/eslint-plugin-community-nodes
2
+ > @n8n/eslint-plugin-community-nodes@0.13.0 build /home/runner/work/n8n/n8n/packages/@n8n/eslint-plugin-community-nodes
3
3
  > tsc --project tsconfig.build.json
4
4
 
package/README.md CHANGED
@@ -58,12 +58,13 @@ export default [
58
58
  | [no-http-request-with-manual-auth](docs/rules/no-http-request-with-manual-auth.md) | Disallow this.helpers.httpRequest() in functions that call this.getCredentials(). Use this.helpers.httpRequestWithAuthentication() instead. | ✅ ☑️ | | | |
59
59
  | [no-restricted-globals](docs/rules/no-restricted-globals.md) | Disallow usage of restricted global variables in community nodes. | ✅ | | | |
60
60
  | [no-restricted-imports](docs/rules/no-restricted-imports.md) | Disallow usage of restricted imports in community nodes. | ✅ | | | |
61
- | [node-class-description-icon-missing](docs/rules/node-class-description-icon-missing.md) | Node class description must have an `icon` property defined | ✅ ☑️ | | | 💡 |
61
+ | [node-class-description-icon-missing](docs/rules/node-class-description-icon-missing.md) | **Deprecated.** Node class description must have an `icon` property defined. Use `require-node-description-fields` instead. | ✅ ☑️ | | | 💡 |
62
62
  | [node-connection-type-literal](docs/rules/node-connection-type-literal.md) | Disallow string literals in node description `inputs`/`outputs` — use `NodeConnectionTypes` enum instead | ✅ ☑️ | | 🔧 | |
63
63
  | [node-usable-as-tool](docs/rules/node-usable-as-tool.md) | Ensure node classes have usableAsTool property | ✅ ☑️ | | 🔧 | |
64
64
  | [options-sorted-alphabetically](docs/rules/options-sorted-alphabetically.md) | Enforce alphabetical ordering of options arrays in n8n node properties | | ✅ ☑️ | | |
65
65
  | [package-name-convention](docs/rules/package-name-convention.md) | Enforce correct package naming convention for n8n community nodes | ✅ ☑️ | | | 💡 |
66
66
  | [require-continue-on-fail](docs/rules/require-continue-on-fail.md) | Require continueOnFail() handling in execute() methods of node classes | ✅ ☑️ | | | |
67
+ | [require-node-description-fields](docs/rules/require-node-description-fields.md) | Node class description must define all required fields | ✅ ☑️ | | | |
67
68
  | [resource-operation-pattern](docs/rules/resource-operation-pattern.md) | Enforce proper resource/operation pattern for better UX in n8n nodes | | ✅ ☑️ | | |
68
69
 
69
70
  <!-- end auto-generated rules list -->
package/dist/plugin.d.ts CHANGED
@@ -29,11 +29,12 @@ declare const configs: {
29
29
  '@n8n/community-nodes/options-sorted-alphabetically': "warn";
30
30
  '@n8n/community-nodes/resource-operation-pattern': "warn";
31
31
  '@n8n/community-nodes/credential-documentation-url': "error";
32
- '@n8n/community-nodes/node-class-description-icon-missing': "error";
33
32
  '@n8n/community-nodes/cred-class-field-icon-missing': "error";
34
33
  '@n8n/community-nodes/node-connection-type-literal': "error";
35
34
  '@n8n/community-nodes/missing-paired-item': "error";
35
+ '@n8n/community-nodes/require-community-node-keyword': "warn";
36
36
  '@n8n/community-nodes/require-continue-on-fail': "error";
37
+ '@n8n/community-nodes/require-node-description-fields': "error";
37
38
  };
38
39
  };
39
40
  recommendedWithoutN8nCloudSupport: {
@@ -62,11 +63,12 @@ declare const configs: {
62
63
  '@n8n/community-nodes/options-sorted-alphabetically': "warn";
63
64
  '@n8n/community-nodes/credential-documentation-url': "error";
64
65
  '@n8n/community-nodes/resource-operation-pattern': "warn";
65
- '@n8n/community-nodes/node-class-description-icon-missing': "error";
66
66
  '@n8n/community-nodes/cred-class-field-icon-missing': "error";
67
67
  '@n8n/community-nodes/node-connection-type-literal': "error";
68
68
  '@n8n/community-nodes/missing-paired-item': "error";
69
+ '@n8n/community-nodes/require-community-node-keyword': "warn";
69
70
  '@n8n/community-nodes/require-continue-on-fail': "error";
71
+ '@n8n/community-nodes/require-node-description-fields': "error";
70
72
  };
71
73
  };
72
74
  };
@@ -100,11 +102,12 @@ declare const pluginWithConfigs: {
100
102
  '@n8n/community-nodes/options-sorted-alphabetically': "warn";
101
103
  '@n8n/community-nodes/resource-operation-pattern': "warn";
102
104
  '@n8n/community-nodes/credential-documentation-url': "error";
103
- '@n8n/community-nodes/node-class-description-icon-missing': "error";
104
105
  '@n8n/community-nodes/cred-class-field-icon-missing': "error";
105
106
  '@n8n/community-nodes/node-connection-type-literal': "error";
106
107
  '@n8n/community-nodes/missing-paired-item': "error";
108
+ '@n8n/community-nodes/require-community-node-keyword': "warn";
107
109
  '@n8n/community-nodes/require-continue-on-fail': "error";
110
+ '@n8n/community-nodes/require-node-description-fields': "error";
108
111
  };
109
112
  };
110
113
  recommendedWithoutN8nCloudSupport: {
@@ -133,11 +136,12 @@ declare const pluginWithConfigs: {
133
136
  '@n8n/community-nodes/options-sorted-alphabetically': "warn";
134
137
  '@n8n/community-nodes/credential-documentation-url': "error";
135
138
  '@n8n/community-nodes/resource-operation-pattern': "warn";
136
- '@n8n/community-nodes/node-class-description-icon-missing': "error";
137
139
  '@n8n/community-nodes/cred-class-field-icon-missing': "error";
138
140
  '@n8n/community-nodes/node-connection-type-literal': "error";
139
141
  '@n8n/community-nodes/missing-paired-item': "error";
142
+ '@n8n/community-nodes/require-community-node-keyword': "warn";
140
143
  '@n8n/community-nodes/require-continue-on-fail': "error";
144
+ '@n8n/community-nodes/require-node-description-fields': "error";
141
145
  };
142
146
  };
143
147
  };
@@ -178,11 +182,12 @@ declare const n8nCommunityNodesPlugin: {
178
182
  '@n8n/community-nodes/options-sorted-alphabetically': "warn";
179
183
  '@n8n/community-nodes/resource-operation-pattern': "warn";
180
184
  '@n8n/community-nodes/credential-documentation-url': "error";
181
- '@n8n/community-nodes/node-class-description-icon-missing': "error";
182
185
  '@n8n/community-nodes/cred-class-field-icon-missing': "error";
183
186
  '@n8n/community-nodes/node-connection-type-literal': "error";
184
187
  '@n8n/community-nodes/missing-paired-item': "error";
188
+ '@n8n/community-nodes/require-community-node-keyword': "warn";
185
189
  '@n8n/community-nodes/require-continue-on-fail': "error";
190
+ '@n8n/community-nodes/require-node-description-fields': "error";
186
191
  };
187
192
  };
188
193
  recommendedWithoutN8nCloudSupport: {
@@ -211,11 +216,12 @@ declare const n8nCommunityNodesPlugin: {
211
216
  '@n8n/community-nodes/options-sorted-alphabetically': "warn";
212
217
  '@n8n/community-nodes/credential-documentation-url': "error";
213
218
  '@n8n/community-nodes/resource-operation-pattern': "warn";
214
- '@n8n/community-nodes/node-class-description-icon-missing': "error";
215
219
  '@n8n/community-nodes/cred-class-field-icon-missing': "error";
216
220
  '@n8n/community-nodes/node-connection-type-literal': "error";
217
221
  '@n8n/community-nodes/missing-paired-item': "error";
222
+ '@n8n/community-nodes/require-community-node-keyword': "warn";
218
223
  '@n8n/community-nodes/require-continue-on-fail': "error";
224
+ '@n8n/community-nodes/require-node-description-fields': "error";
219
225
  };
220
226
  };
221
227
  };
@@ -1 +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;;;;;;;;;;;;;;;;;;;;;;;;CA0DE,CAAC;AAE1C,QAAA,MAAM,iBAAiB;;;;;;;;;;;2BA5DN,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;CA4DiC,CAAC;AAEzE,QAAA,MAAM,uBAAuB;;;;;;;;;;;2BA9DZ,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;CA8DU,CAAC;AAClD,eAAe,iBAAiB,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
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;;;;;;;;;;;;;;;;;;;;;;;;;CA4DE,CAAC;AAE1C,QAAA,MAAM,iBAAiB;;;;;;;;;;;2BA9DN,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;CA8DiC,CAAC;AAEzE,QAAA,MAAM,uBAAuB;;;;;;;;;;;2BAhEZ,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAAtB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;CAgEU,CAAC;AAClD,eAAe,iBAAiB,CAAC;AACjC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC"}
package/dist/plugin.js CHANGED
@@ -31,11 +31,12 @@ const configs = {
31
31
  '@n8n/community-nodes/options-sorted-alphabetically': 'warn',
32
32
  '@n8n/community-nodes/resource-operation-pattern': 'warn',
33
33
  '@n8n/community-nodes/credential-documentation-url': 'error',
34
- '@n8n/community-nodes/node-class-description-icon-missing': 'error',
35
34
  '@n8n/community-nodes/cred-class-field-icon-missing': 'error',
36
35
  '@n8n/community-nodes/node-connection-type-literal': 'error',
37
36
  '@n8n/community-nodes/missing-paired-item': 'error',
37
+ '@n8n/community-nodes/require-community-node-keyword': 'warn',
38
38
  '@n8n/community-nodes/require-continue-on-fail': 'error',
39
+ '@n8n/community-nodes/require-node-description-fields': 'error',
39
40
  },
40
41
  },
41
42
  recommendedWithoutN8nCloudSupport: {
@@ -57,11 +58,12 @@ const configs = {
57
58
  '@n8n/community-nodes/options-sorted-alphabetically': 'warn',
58
59
  '@n8n/community-nodes/credential-documentation-url': 'error',
59
60
  '@n8n/community-nodes/resource-operation-pattern': 'warn',
60
- '@n8n/community-nodes/node-class-description-icon-missing': 'error',
61
61
  '@n8n/community-nodes/cred-class-field-icon-missing': 'error',
62
62
  '@n8n/community-nodes/node-connection-type-literal': 'error',
63
63
  '@n8n/community-nodes/missing-paired-item': 'error',
64
+ '@n8n/community-nodes/require-community-node-keyword': 'warn',
64
65
  '@n8n/community-nodes/require-continue-on-fail': 'error',
66
+ '@n8n/community-nodes/require-node-description-fields': 'error',
65
67
  },
66
68
  },
67
69
  };
@@ -1 +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,2CAA2C,EAAE,OAAO;YACpD,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,qDAAqD,EAAE,OAAO;YAC9D,uDAAuD,EAAE,OAAO;YAChE,sCAAsC,EAAE,OAAO;YAC/C,oDAAoD,EAAE,MAAM;YAC5D,iDAAiD,EAAE,MAAM;YACzD,mDAAmD,EAAE,OAAO;YAC5D,0DAA0D,EAAE,OAAO;YACnE,oDAAoD,EAAE,OAAO;YAC7D,mDAAmD,EAAE,OAAO;YAC5D,0CAA0C,EAAE,OAAO;YACnD,+CAA+C,EAAE,OAAO;SACxD;KACD;IACD,iCAAiC,EAAE;QAClC,OAAO,EAAE,CAAC,+BAA+B,CAAC;QAC1C,OAAO,EAAE;YACR,sBAAsB,EAAE,MAAM;SAC9B;QACD,KAAK,EAAE;YACN,2CAA2C,EAAE,OAAO;YACpD,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,qDAAqD,EAAE,OAAO;YAC9D,uDAAuD,EAAE,OAAO;YAChE,sCAAsC,EAAE,OAAO;YAC/C,oDAAoD,EAAE,MAAM;YAC5D,mDAAmD,EAAE,OAAO;YAC5D,iDAAiD,EAAE,MAAM;YACzD,0DAA0D,EAAE,OAAO;YACnE,oDAAoD,EAAE,OAAO;YAC7D,mDAAmD,EAAE,OAAO;YAC5D,0CAA0C,EAAE,OAAO;YACnD,+CAA+C,EAAE,OAAO;SACxD;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"}
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,2CAA2C,EAAE,OAAO;YACpD,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,qDAAqD,EAAE,OAAO;YAC9D,uDAAuD,EAAE,OAAO;YAChE,sCAAsC,EAAE,OAAO;YAC/C,oDAAoD,EAAE,MAAM;YAC5D,iDAAiD,EAAE,MAAM;YACzD,mDAAmD,EAAE,OAAO;YAC5D,oDAAoD,EAAE,OAAO;YAC7D,mDAAmD,EAAE,OAAO;YAC5D,0CAA0C,EAAE,OAAO;YACnD,qDAAqD,EAAE,MAAM;YAC7D,+CAA+C,EAAE,OAAO;YACxD,sDAAsD,EAAE,OAAO;SAC/D;KACD;IACD,iCAAiC,EAAE;QAClC,OAAO,EAAE,CAAC,+BAA+B,CAAC;QAC1C,OAAO,EAAE;YACR,sBAAsB,EAAE,MAAM;SAC9B;QACD,KAAK,EAAE;YACN,2CAA2C,EAAE,OAAO;YACpD,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,qDAAqD,EAAE,OAAO;YAC9D,uDAAuD,EAAE,OAAO;YAChE,sCAAsC,EAAE,OAAO;YAC/C,oDAAoD,EAAE,MAAM;YAC5D,mDAAmD,EAAE,OAAO;YAC5D,iDAAiD,EAAE,MAAM;YACzD,oDAAoD,EAAE,OAAO;YAC7D,mDAAmD,EAAE,OAAO;YAC5D,0CAA0C,EAAE,OAAO;YACnD,qDAAqD,EAAE,MAAM;YAC7D,+CAA+C,EAAE,OAAO;YACxD,sDAAsD,EAAE,OAAO;SAC/D;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"}
@@ -21,6 +21,8 @@ export declare const rules: {
21
21
  'cred-class-field-icon-missing': import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingIcon" | "addPlaceholder", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
22
22
  'node-connection-type-literal': import("@typescript-eslint/utils/ts-eslint").RuleModule<"stringLiteralInInputs" | "stringLiteralInOutputs" | "unknownStringLiteralInInputs" | "unknownStringLiteralInOutputs", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
23
23
  'missing-paired-item': import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingPairedItem", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
24
+ 'require-community-node-keyword': import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingKeyword" | "missingKeywordsArray", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
24
25
  'require-continue-on-fail': import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingContinueOnFail", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
26
+ 'require-node-description-fields': import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingField" | "missingFields", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
25
27
  };
26
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAuBA,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;CAqBuB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAyBA,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;CAuBuB,CAAC"}
@@ -16,7 +16,9 @@ import { NodeConnectionTypeLiteralRule } from './node-connection-type-literal.js
16
16
  import { NodeUsableAsToolRule } from './node-usable-as-tool.js';
17
17
  import { OptionsSortedAlphabeticallyRule } from './options-sorted-alphabetically.js';
18
18
  import { PackageNameConventionRule } from './package-name-convention.js';
19
+ import { RequireCommunityNodeKeywordRule } from './require-community-node-keyword.js';
19
20
  import { RequireContinueOnFailRule } from './require-continue-on-fail.js';
21
+ import { RequireNodeDescriptionFieldsRule } from './require-node-description-fields.js';
20
22
  import { ResourceOperationPatternRule } from './resource-operation-pattern.js';
21
23
  export const rules = {
22
24
  'ai-node-package-json': AiNodePackageJsonRule,
@@ -38,6 +40,8 @@ export const rules = {
38
40
  'cred-class-field-icon-missing': CredClassFieldIconMissingRule,
39
41
  'node-connection-type-literal': NodeConnectionTypeLiteralRule,
40
42
  'missing-paired-item': MissingPairedItemRule,
43
+ 'require-community-node-keyword': RequireCommunityNodeKeywordRule,
41
44
  'require-continue-on-fail': RequireContinueOnFailRule,
45
+ 'require-node-description-fields': RequireNodeDescriptionFieldsRule,
42
46
  };
43
47
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AACnF,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,iCAAiC,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAE,+BAA+B,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,EAAE,+BAA+B,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,mCAAmC,EAAE,MAAM,0CAA0C,CAAC;AAC/F,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,+BAA+B,EAAE,MAAM,oCAAoC,CAAC;AACrF,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAE/E,MAAM,CAAC,MAAM,KAAK,GAAG;IACpB,sBAAsB,EAAE,qBAAqB;IAC7C,uBAAuB,EAAE,uBAAuB;IAChD,uBAAuB,EAAE,uBAAuB;IAChD,2BAA2B,EAAE,2BAA2B;IACxD,kCAAkC,EAAE,iCAAiC;IACrE,qBAAqB,EAAE,oBAAoB;IAC3C,+BAA+B,EAAE,+BAA+B;IAChE,yBAAyB,EAAE,yBAAyB;IACpD,0BAA0B,EAAE,0BAA0B;IACtD,qBAAqB,EAAE,qBAAqB;IAC5C,gCAAgC,EAAE,+BAA+B;IACjE,kCAAkC,EAAE,+BAA+B;IACnE,iBAAiB,EAAE,kBAAkB;IACrC,4BAA4B,EAAE,4BAA4B;IAC1D,8BAA8B,EAAE,8BAA8B;IAC9D,qCAAqC,EAAE,mCAAmC;IAC1E,+BAA+B,EAAE,6BAA6B;IAC9D,8BAA8B,EAAE,6BAA6B;IAC7D,qBAAqB,EAAE,qBAAqB;IAC5C,0BAA0B,EAAE,yBAAyB;CACb,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AACnF,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,iCAAiC,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAE,+BAA+B,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,EAAE,+BAA+B,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,mCAAmC,EAAE,MAAM,0CAA0C,CAAC;AAC/F,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,+BAA+B,EAAE,MAAM,oCAAoC,CAAC;AACrF,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,+BAA+B,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,gCAAgC,EAAE,MAAM,sCAAsC,CAAC;AACxF,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAE/E,MAAM,CAAC,MAAM,KAAK,GAAG;IACpB,sBAAsB,EAAE,qBAAqB;IAC7C,uBAAuB,EAAE,uBAAuB;IAChD,uBAAuB,EAAE,uBAAuB;IAChD,2BAA2B,EAAE,2BAA2B;IACxD,kCAAkC,EAAE,iCAAiC;IACrE,qBAAqB,EAAE,oBAAoB;IAC3C,+BAA+B,EAAE,+BAA+B;IAChE,yBAAyB,EAAE,yBAAyB;IACpD,0BAA0B,EAAE,0BAA0B;IACtD,qBAAqB,EAAE,qBAAqB;IAC5C,gCAAgC,EAAE,+BAA+B;IACjE,kCAAkC,EAAE,+BAA+B;IACnE,iBAAiB,EAAE,kBAAkB;IACrC,4BAA4B,EAAE,4BAA4B;IAC1D,8BAA8B,EAAE,8BAA8B;IAC9D,qCAAqC,EAAE,mCAAmC;IAC1E,+BAA+B,EAAE,6BAA6B;IAC9D,8BAA8B,EAAE,6BAA6B;IAC7D,qBAAqB,EAAE,qBAAqB;IAC5C,gCAAgC,EAAE,+BAA+B;IACjE,0BAA0B,EAAE,yBAAyB;IACrD,iCAAiC,EAAE,gCAAgC;CAC3B,CAAC"}
@@ -1,2 +1,3 @@
1
+ /** @deprecated Use `require-node-description-fields` instead. */
1
2
  export declare const NodeClassDescriptionIconMissingRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingIcon" | "addPlaceholder", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
2
3
  //# sourceMappingURL=node-class-description-icon-missing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"node-class-description-icon-missing.d.ts","sourceRoot":"","sources":["../../src/rules/node-class-description-icon-missing.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,mCAAmC,mKA4D9C,CAAC"}
1
+ {"version":3,"file":"node-class-description-icon-missing.d.ts","sourceRoot":"","sources":["../../src/rules/node-class-description-icon-missing.ts"],"names":[],"mappings":"AAUA,iEAAiE;AACjE,eAAO,MAAM,mCAAmC,mKAiE9C,CAAC"}
@@ -1,11 +1,16 @@
1
1
  import { TSESTree } from '@typescript-eslint/utils';
2
2
  import { isNodeTypeClass, findClassProperty, findObjectProperty, isFileType, createRule, } from '../utils/index.js';
3
+ /** @deprecated Use `require-node-description-fields` instead. */
3
4
  export const NodeClassDescriptionIconMissingRule = createRule({
4
5
  name: 'node-class-description-icon-missing',
5
6
  meta: {
6
7
  type: 'problem',
8
+ deprecated: {
9
+ message: 'Use require-node-description-fields instead.',
10
+ replacedBy: [{ rule: { name: 'require-node-description-fields' } }],
11
+ },
7
12
  docs: {
8
- description: 'Node class description must have an `icon` property defined',
13
+ description: 'Node class description must have an `icon` property defined. Deprecated: use `require-node-description-fields` instead.',
9
14
  },
10
15
  messages: {
11
16
  missingIcon: 'Node class description is missing required `icon` property',
@@ -1 +1 @@
1
- {"version":3,"file":"node-class-description-icon-missing.js","sourceRoot":"","sources":["../../src/rules/node-class-description-icon-missing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,EACV,UAAU,GACV,MAAM,mBAAmB,CAAC;AAE3B,MAAM,CAAC,MAAM,mCAAmC,GAAG,UAAU,CAAC;IAC7D,IAAI,EAAE,qCAAqC;IAC3C,IAAI,EAAE;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACL,WAAW,EAAE,6DAA6D;SAC1E;QACD,QAAQ,EAAE;YACT,WAAW,EAAE,4DAA4D;YACzE,cAAc,EAAE,oCAAoC;SACpD;QACD,MAAM,EAAE,EAAE;QACV,cAAc,EAAE,IAAI;KACpB;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACb,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;YAC/C,OAAO,EAAE,CAAC;QACX,CAAC;QAED,OAAO;YACN,gBAAgB,CAAC,IAAI;gBACpB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5B,OAAO;gBACR,CAAC;gBAED,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;gBACnE,IACC,CAAC,mBAAmB,EAAE,KAAK;oBAC3B,mBAAmB,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,cAAc,CAAC,gBAAgB,EAC1E,CAAC;oBACF,OAAO;gBACR,CAAC;gBAED,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,KAAK,CAAC;gBACnD,MAAM,YAAY,GAAG,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;gBAClE,IAAI,YAAY,EAAE,CAAC;oBAClB,OAAO;gBACR,CAAC;gBAED,OAAO,CAAC,MAAM,CAAC;oBACd,IAAI;oBACJ,SAAS,EAAE,aAAa;oBACxB,OAAO,EAAE;wBACR;4BACC,SAAS,EAAE,gBAAgB;4BAC3B,GAAG,CAAC,KAAK;gCACR,MAAM,YAAY,GACjB,gBAAgB,CAAC,UAAU,CAAC,gBAAgB,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gCACrE,IAAI,YAAY,EAAE,CAAC;oCAClB,OAAO,KAAK,CAAC,eAAe,CAAC,YAAY,EAAE,gCAAgC,CAAC,CAAC;gCAC9E,CAAC;gCACD,OAAO,IAAI,CAAC;4BACb,CAAC;yBACD;qBACD;iBACD,CAAC,CAAC;YACJ,CAAC;SACD,CAAC;IACH,CAAC;CACD,CAAC,CAAC"}
1
+ {"version":3,"file":"node-class-description-icon-missing.js","sourceRoot":"","sources":["../../src/rules/node-class-description-icon-missing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,EACV,UAAU,GACV,MAAM,mBAAmB,CAAC;AAE3B,iEAAiE;AACjE,MAAM,CAAC,MAAM,mCAAmC,GAAG,UAAU,CAAC;IAC7D,IAAI,EAAE,qCAAqC;IAC3C,IAAI,EAAE;QACL,IAAI,EAAE,SAAS;QACf,UAAU,EAAE;YACX,OAAO,EAAE,8CAA8C;YACvD,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,iCAAiC,EAAE,EAAE,CAAC;SACnE;QACD,IAAI,EAAE;YACL,WAAW,EACV,yHAAyH;SAC1H;QACD,QAAQ,EAAE;YACT,WAAW,EAAE,4DAA4D;YACzE,cAAc,EAAE,oCAAoC;SACpD;QACD,MAAM,EAAE,EAAE;QACV,cAAc,EAAE,IAAI;KACpB;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACb,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;YAC/C,OAAO,EAAE,CAAC;QACX,CAAC;QAED,OAAO;YACN,gBAAgB,CAAC,IAAI;gBACpB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5B,OAAO;gBACR,CAAC;gBAED,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;gBACnE,IACC,CAAC,mBAAmB,EAAE,KAAK;oBAC3B,mBAAmB,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,cAAc,CAAC,gBAAgB,EAC1E,CAAC;oBACF,OAAO;gBACR,CAAC;gBAED,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,KAAK,CAAC;gBACnD,MAAM,YAAY,GAAG,kBAAkB,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;gBAClE,IAAI,YAAY,EAAE,CAAC;oBAClB,OAAO;gBACR,CAAC;gBAED,OAAO,CAAC,MAAM,CAAC;oBACd,IAAI;oBACJ,SAAS,EAAE,aAAa;oBACxB,OAAO,EAAE;wBACR;4BACC,SAAS,EAAE,gBAAgB;4BAC3B,GAAG,CAAC,KAAK;gCACR,MAAM,YAAY,GACjB,gBAAgB,CAAC,UAAU,CAAC,gBAAgB,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gCACrE,IAAI,YAAY,EAAE,CAAC;oCAClB,OAAO,KAAK,CAAC,eAAe,CAAC,YAAY,EAAE,gCAAgC,CAAC,CAAC;gCAC9E,CAAC;gCACD,OAAO,IAAI,CAAC;4BACb,CAAC;yBACD;qBACD;iBACD,CAAC,CAAC;YACJ,CAAC;SACD,CAAC;IACH,CAAC;CACD,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const RequireCommunityNodeKeywordRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingKeyword" | "missingKeywordsArray", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
2
+ //# sourceMappingURL=require-community-node-keyword.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-community-node-keyword.d.ts","sourceRoot":"","sources":["../../src/rules/require-community-node-keyword.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,+BAA+B,4KAsE1C,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
+ import { createRule, findJsonProperty } from '../utils/index.js';
3
+ const REQUIRED_KEYWORD = 'n8n-community-node-package';
4
+ export const RequireCommunityNodeKeywordRule = createRule({
5
+ name: 'require-community-node-keyword',
6
+ meta: {
7
+ type: 'problem',
8
+ docs: {
9
+ description: 'Require the "n8n-community-node-package" keyword in community node package.json',
10
+ },
11
+ fixable: 'code',
12
+ messages: {
13
+ missingKeyword: `The "keywords" array must include "${REQUIRED_KEYWORD}". This keyword is required for n8n to discover community node packages.`,
14
+ missingKeywordsArray: `The package.json must have a "keywords" array containing "${REQUIRED_KEYWORD}".`,
15
+ },
16
+ schema: [],
17
+ },
18
+ defaultOptions: [],
19
+ create(context) {
20
+ if (!context.filename.endsWith('package.json')) {
21
+ return {};
22
+ }
23
+ return {
24
+ ObjectExpression(node) {
25
+ if (node.parent?.type !== AST_NODE_TYPES.ExpressionStatement) {
26
+ return;
27
+ }
28
+ const keywordsProp = findJsonProperty(node, 'keywords');
29
+ if (!keywordsProp) {
30
+ context.report({
31
+ node,
32
+ messageId: 'missingKeywordsArray',
33
+ fix(fixer) {
34
+ const lastProp = node.properties[node.properties.length - 1];
35
+ if (!lastProp) {
36
+ return fixer.replaceText(node, `{ "keywords": ["${REQUIRED_KEYWORD}"] }`);
37
+ }
38
+ return fixer.insertTextAfter(lastProp, `, "keywords": ["${REQUIRED_KEYWORD}"]`);
39
+ },
40
+ });
41
+ return;
42
+ }
43
+ if (keywordsProp.value.type !== AST_NODE_TYPES.ArrayExpression) {
44
+ return;
45
+ }
46
+ const keywordsArray = keywordsProp.value;
47
+ const hasRequiredKeyword = keywordsArray.elements.some((element) => element?.type === AST_NODE_TYPES.Literal && element.value === REQUIRED_KEYWORD);
48
+ if (!hasRequiredKeyword) {
49
+ context.report({
50
+ node: keywordsProp,
51
+ messageId: 'missingKeyword',
52
+ fix(fixer) {
53
+ const lastElement = keywordsArray.elements[keywordsArray.elements.length - 1];
54
+ if (!lastElement) {
55
+ return fixer.replaceText(keywordsArray, `["${REQUIRED_KEYWORD}"]`);
56
+ }
57
+ return fixer.insertTextAfter(lastElement, `, "${REQUIRED_KEYWORD}"`);
58
+ },
59
+ });
60
+ }
61
+ },
62
+ };
63
+ },
64
+ });
65
+ //# sourceMappingURL=require-community-node-keyword.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-community-node-keyword.js","sourceRoot":"","sources":["../../src/rules/require-community-node-keyword.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,gBAAgB,GAAG,4BAA4B,CAAC;AAEtD,MAAM,CAAC,MAAM,+BAA+B,GAAG,UAAU,CAAC;IACzD,IAAI,EAAE,gCAAgC;IACtC,IAAI,EAAE;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACL,WAAW,EACV,iFAAiF;SAClF;QACD,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE;YACT,cAAc,EAAE,sCAAsC,gBAAgB,0EAA0E;YAChJ,oBAAoB,EAAE,6DAA6D,gBAAgB,IAAI;SACvG;QACD,MAAM,EAAE,EAAE;KACV;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACb,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,CAAC;QACX,CAAC;QAED,OAAO;YACN,gBAAgB,CAAC,IAA+B;gBAC/C,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,cAAc,CAAC,mBAAmB,EAAE,CAAC;oBAC9D,OAAO;gBACR,CAAC;gBAED,MAAM,YAAY,GAAG,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBAExD,IAAI,CAAC,YAAY,EAAE,CAAC;oBACnB,OAAO,CAAC,MAAM,CAAC;wBACd,IAAI;wBACJ,SAAS,EAAE,sBAAsB;wBACjC,GAAG,CAAC,KAAK;4BACR,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;4BAC7D,IAAI,CAAC,QAAQ,EAAE,CAAC;gCACf,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,mBAAmB,gBAAgB,MAAM,CAAC,CAAC;4BAC3E,CAAC;4BACD,OAAO,KAAK,CAAC,eAAe,CAAC,QAAQ,EAAE,mBAAmB,gBAAgB,IAAI,CAAC,CAAC;wBACjF,CAAC;qBACD,CAAC,CAAC;oBACH,OAAO;gBACR,CAAC;gBAED,IAAI,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,eAAe,EAAE,CAAC;oBAChE,OAAO;gBACR,CAAC;gBAED,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,CAAC;gBACzC,MAAM,kBAAkB,GAAG,aAAa,CAAC,QAAQ,CAAC,IAAI,CACrD,CAAC,OAAO,EAAE,EAAE,CACX,OAAO,EAAE,IAAI,KAAK,cAAc,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,KAAK,gBAAgB,CAC/E,CAAC;gBAEF,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBACzB,OAAO,CAAC,MAAM,CAAC;wBACd,IAAI,EAAE,YAAY;wBAClB,SAAS,EAAE,gBAAgB;wBAC3B,GAAG,CAAC,KAAK;4BACR,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;4BAC9E,IAAI,CAAC,WAAW,EAAE,CAAC;gCAClB,OAAO,KAAK,CAAC,WAAW,CAAC,aAAa,EAAE,KAAK,gBAAgB,IAAI,CAAC,CAAC;4BACpE,CAAC;4BACD,OAAO,KAAK,CAAC,eAAe,CAAC,WAAW,EAAE,MAAM,gBAAgB,GAAG,CAAC,CAAC;wBACtE,CAAC;qBACD,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;SACD,CAAC;IACH,CAAC;CACD,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const RequireNodeDescriptionFieldsRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingField" | "missingFields", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
2
+ //# sourceMappingURL=require-node-description-fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-node-description-fields.d.ts","sourceRoot":"","sources":["../../src/rules/require-node-description-fields.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,gCAAgC,mKA2D3C,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { TSESTree } from '@typescript-eslint/utils';
2
+ import { isNodeTypeClass, findClassProperty, findObjectProperty, isFileType, createRule, } from '../utils/index.js';
3
+ // Fields that are optional in the TypeScript interface but required by
4
+ // community node review standards. TypeScript-required fields (displayName,
5
+ // name, group, version, description, etc.) are already caught by tsc.
6
+ const REQUIRED_FIELDS = ['icon', 'subtitle'];
7
+ export const RequireNodeDescriptionFieldsRule = createRule({
8
+ name: 'require-node-description-fields',
9
+ meta: {
10
+ type: 'problem',
11
+ docs: {
12
+ description: `Node class description must define all required fields: ${REQUIRED_FIELDS.join(', ')}`,
13
+ },
14
+ messages: {
15
+ missingField: 'Node class description is missing required `{{field}}` property',
16
+ missingFields: 'Node class description is missing required properties: {{fields}}',
17
+ },
18
+ schema: [],
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ if (!isFileType(context.filename, '.node.ts')) {
23
+ return {};
24
+ }
25
+ return {
26
+ ClassDeclaration(node) {
27
+ if (!isNodeTypeClass(node)) {
28
+ return;
29
+ }
30
+ const descriptionProperty = findClassProperty(node, 'description');
31
+ if (!descriptionProperty?.value ||
32
+ descriptionProperty.value.type !== TSESTree.AST_NODE_TYPES.ObjectExpression) {
33
+ return;
34
+ }
35
+ const descriptionValue = descriptionProperty.value;
36
+ const missingFields = REQUIRED_FIELDS.filter((field) => !findObjectProperty(descriptionValue, field));
37
+ if (missingFields.length === 0) {
38
+ return;
39
+ }
40
+ if (missingFields.length === 1) {
41
+ context.report({
42
+ node: descriptionProperty,
43
+ messageId: 'missingField',
44
+ data: { field: missingFields[0] },
45
+ });
46
+ }
47
+ else {
48
+ context.report({
49
+ node: descriptionProperty,
50
+ messageId: 'missingFields',
51
+ data: { fields: missingFields.map((f) => `\`${f}\``).join(', ') },
52
+ });
53
+ }
54
+ },
55
+ };
56
+ },
57
+ });
58
+ //# sourceMappingURL=require-node-description-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-node-description-fields.js","sourceRoot":"","sources":["../../src/rules/require-node-description-fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,EACV,UAAU,GACV,MAAM,mBAAmB,CAAC;AAE3B,uEAAuE;AACvE,4EAA4E;AAC5E,sEAAsE;AACtE,MAAM,eAAe,GAAG,CAAC,MAAM,EAAE,UAAU,CAAU,CAAC;AAItD,MAAM,CAAC,MAAM,gCAAgC,GAAG,UAAU,CAAC;IAC1D,IAAI,EAAE,iCAAiC;IACvC,IAAI,EAAE;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACL,WAAW,EAAE,2DAA2D,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACpG;QACD,QAAQ,EAAE;YACT,YAAY,EAAE,iEAAiE;YAC/E,aAAa,EAAE,mEAAmE;SAClF;QACD,MAAM,EAAE,EAAE;KACV;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACb,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;YAC/C,OAAO,EAAE,CAAC;QACX,CAAC;QAED,OAAO;YACN,gBAAgB,CAAC,IAAI;gBACpB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5B,OAAO;gBACR,CAAC;gBAED,MAAM,mBAAmB,GAAG,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;gBACnE,IACC,CAAC,mBAAmB,EAAE,KAAK;oBAC3B,mBAAmB,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,cAAc,CAAC,gBAAgB,EAC1E,CAAC;oBACF,OAAO;gBACR,CAAC;gBAED,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,KAAK,CAAC;gBAEnD,MAAM,aAAa,GAAoB,eAAe,CAAC,MAAM,CAC5D,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,kBAAkB,CAAC,gBAAgB,EAAE,KAAK,CAAC,CACvD,CAAC;gBAEF,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAChC,OAAO;gBACR,CAAC;gBAED,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAChC,OAAO,CAAC,MAAM,CAAC;wBACd,IAAI,EAAE,mBAAmB;wBACzB,SAAS,EAAE,cAAc;wBACzB,IAAI,EAAE,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE;qBACjC,CAAC,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACP,OAAO,CAAC,MAAM,CAAC;wBACd,IAAI,EAAE,mBAAmB;wBACzB,SAAS,EAAE,eAAe;wBAC1B,IAAI,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;qBACjE,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;SACD,CAAC;IACH,CAAC;CACD,CAAC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  # Node class description must have an `icon` property defined (`@n8n/community-nodes/node-class-description-icon-missing`)
2
2
 
3
- 💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
3
+ This rule is **deprecated**. Use [`require-node-description-fields`](require-node-description-fields.md) instead.
4
4
 
5
5
  💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
6
6
 
@@ -0,0 +1,45 @@
1
+ # Require the "n8n-community-node-package" keyword in package.json (`@n8n/community-nodes/require-community-node-keyword`)
2
+
3
+ ⚠️ This rule is set to `warn` in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
4
+
5
+ 🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/use/command-line-interface#--fix).
6
+
7
+ <!-- end auto-generated rule header -->
8
+
9
+ ## Rule Details
10
+
11
+ Validates that the `package.json` of a community node package includes `"n8n-community-node-package"` in its `keywords` array. This keyword is required for n8n to discover and list community node packages.
12
+
13
+ ## Examples
14
+
15
+ ### ❌ Incorrect
16
+
17
+ ```json
18
+ {
19
+ "name": "n8n-nodes-my-service",
20
+ "version": "1.0.0"
21
+ }
22
+ ```
23
+
24
+ ```json
25
+ {
26
+ "name": "n8n-nodes-my-service",
27
+ "keywords": ["n8n", "automation"]
28
+ }
29
+ ```
30
+
31
+ ### ✅ Correct
32
+
33
+ ```json
34
+ {
35
+ "name": "n8n-nodes-my-service",
36
+ "keywords": ["n8n-community-node-package"]
37
+ }
38
+ ```
39
+
40
+ ```json
41
+ {
42
+ "name": "n8n-nodes-my-service",
43
+ "keywords": ["n8n", "automation", "n8n-community-node-package"]
44
+ }
45
+ ```
@@ -0,0 +1,46 @@
1
+ # Node class description must define all required fields (`@n8n/community-nodes/require-node-description-fields`)
2
+
3
+ 💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
4
+
5
+ <!-- end auto-generated rule header -->
6
+
7
+ ## Rule Details
8
+
9
+ Enforces that community node class descriptions include fields that are optional in the TypeScript interface but required by community node review standards.
10
+
11
+ This rule supersedes `node-class-description-icon-missing`, which only checked for the `icon` field.
12
+
13
+ ## Examples
14
+
15
+ ### ❌ Incorrect
16
+
17
+ ```typescript
18
+ export class MyNode implements INodeType {
19
+ description: INodeTypeDescription = {
20
+ displayName: 'My Node',
21
+ name: 'myNode',
22
+ icon: 'file:myNode.svg',
23
+ group: ['transform'],
24
+ version: 1,
25
+ description: 'My node description',
26
+ // Missing subtitle
27
+ };
28
+ }
29
+ ```
30
+
31
+ ### ✅ Correct
32
+
33
+ ```typescript
34
+ export class MyNode implements INodeType {
35
+ description: INodeTypeDescription = {
36
+ displayName: 'My Node',
37
+ name: 'myNode',
38
+ icon: 'file:myNode.svg',
39
+ group: ['transform'],
40
+ version: 1,
41
+ description: 'My node description',
42
+ subtitle: '={{$parameter["operation"]}}',
43
+ // ...
44
+ };
45
+ }
46
+ ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@n8n/eslint-plugin-community-nodes",
3
3
  "type": "module",
4
- "version": "0.12.0",
4
+ "version": "0.13.0",
5
5
  "main": "./dist/plugin.js",
6
6
  "types": "./dist/plugin.d.ts",
7
7
  "exports": {
@@ -23,8 +23,8 @@
23
23
  "typescript": "6.0.2",
24
24
  "vitest": "^4.1.1",
25
25
  "@n8n/typescript-config": "1.4.0",
26
- "@n8n/vitest-config": "1.9.0",
27
- "n8n-workflow": "2.17.0"
26
+ "n8n-workflow": "2.18.0",
27
+ "@n8n/vitest-config": "1.9.0"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "eslint": ">= 9",
package/src/plugin.ts CHANGED
@@ -35,11 +35,12 @@ const configs = {
35
35
  '@n8n/community-nodes/options-sorted-alphabetically': 'warn',
36
36
  '@n8n/community-nodes/resource-operation-pattern': 'warn',
37
37
  '@n8n/community-nodes/credential-documentation-url': 'error',
38
- '@n8n/community-nodes/node-class-description-icon-missing': 'error',
39
38
  '@n8n/community-nodes/cred-class-field-icon-missing': 'error',
40
39
  '@n8n/community-nodes/node-connection-type-literal': 'error',
41
40
  '@n8n/community-nodes/missing-paired-item': 'error',
41
+ '@n8n/community-nodes/require-community-node-keyword': 'warn',
42
42
  '@n8n/community-nodes/require-continue-on-fail': 'error',
43
+ '@n8n/community-nodes/require-node-description-fields': 'error',
43
44
  },
44
45
  },
45
46
  recommendedWithoutN8nCloudSupport: {
@@ -61,11 +62,12 @@ const configs = {
61
62
  '@n8n/community-nodes/options-sorted-alphabetically': 'warn',
62
63
  '@n8n/community-nodes/credential-documentation-url': 'error',
63
64
  '@n8n/community-nodes/resource-operation-pattern': 'warn',
64
- '@n8n/community-nodes/node-class-description-icon-missing': 'error',
65
65
  '@n8n/community-nodes/cred-class-field-icon-missing': 'error',
66
66
  '@n8n/community-nodes/node-connection-type-literal': 'error',
67
67
  '@n8n/community-nodes/missing-paired-item': 'error',
68
+ '@n8n/community-nodes/require-community-node-keyword': 'warn',
68
69
  '@n8n/community-nodes/require-continue-on-fail': 'error',
70
+ '@n8n/community-nodes/require-node-description-fields': 'error',
69
71
  },
70
72
  },
71
73
  } satisfies Record<string, Linter.Config>;
@@ -18,7 +18,9 @@ import { NodeConnectionTypeLiteralRule } from './node-connection-type-literal.js
18
18
  import { NodeUsableAsToolRule } from './node-usable-as-tool.js';
19
19
  import { OptionsSortedAlphabeticallyRule } from './options-sorted-alphabetically.js';
20
20
  import { PackageNameConventionRule } from './package-name-convention.js';
21
+ import { RequireCommunityNodeKeywordRule } from './require-community-node-keyword.js';
21
22
  import { RequireContinueOnFailRule } from './require-continue-on-fail.js';
23
+ import { RequireNodeDescriptionFieldsRule } from './require-node-description-fields.js';
22
24
  import { ResourceOperationPatternRule } from './resource-operation-pattern.js';
23
25
 
24
26
  export const rules = {
@@ -41,5 +43,7 @@ export const rules = {
41
43
  'cred-class-field-icon-missing': CredClassFieldIconMissingRule,
42
44
  'node-connection-type-literal': NodeConnectionTypeLiteralRule,
43
45
  'missing-paired-item': MissingPairedItemRule,
46
+ 'require-community-node-keyword': RequireCommunityNodeKeywordRule,
44
47
  'require-continue-on-fail': RequireContinueOnFailRule,
48
+ 'require-node-description-fields': RequireNodeDescriptionFieldsRule,
45
49
  } satisfies Record<string, AnyRuleModule>;
@@ -8,12 +8,18 @@ import {
8
8
  createRule,
9
9
  } from '../utils/index.js';
10
10
 
11
+ /** @deprecated Use `require-node-description-fields` instead. */
11
12
  export const NodeClassDescriptionIconMissingRule = createRule({
12
13
  name: 'node-class-description-icon-missing',
13
14
  meta: {
14
15
  type: 'problem',
16
+ deprecated: {
17
+ message: 'Use require-node-description-fields instead.',
18
+ replacedBy: [{ rule: { name: 'require-node-description-fields' } }],
19
+ },
15
20
  docs: {
16
- description: 'Node class description must have an `icon` property defined',
21
+ description:
22
+ 'Node class description must have an `icon` property defined. Deprecated: use `require-node-description-fields` instead.',
17
23
  },
18
24
  messages: {
19
25
  missingIcon: 'Node class description is missing required `icon` property',