@n8n/eslint-plugin-community-nodes 0.24.0 → 0.26.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 (137) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/README.md +39 -52
  3. package/dist/plugin.d.ts +15 -93
  4. package/dist/plugin.d.ts.map +1 -1
  5. package/dist/plugin.js +0 -26
  6. package/dist/plugin.js.map +1 -1
  7. package/dist/rules/ai-node-package-json.d.ts +1 -1
  8. package/dist/rules/cred-class-field-icon-missing.d.ts +1 -1
  9. package/dist/rules/cred-class-oauth2-naming.d.ts +1 -1
  10. package/dist/rules/icon-validation.d.ts +1 -1
  11. package/dist/rules/index.d.ts +20 -33
  12. package/dist/rules/index.d.ts.map +1 -1
  13. package/dist/rules/index.js +0 -26
  14. package/dist/rules/index.js.map +1 -1
  15. package/dist/rules/no-credential-reuse.d.ts +1 -1
  16. package/dist/rules/no-dangerous-functions.d.ts +1 -1
  17. package/dist/rules/no-deprecated-workflow-functions.d.ts +1 -1
  18. package/dist/rules/no-restricted-imports.d.ts +1 -1
  19. package/dist/rules/no-restricted-imports.d.ts.map +1 -1
  20. package/dist/rules/no-restricted-imports.js +14 -5
  21. package/dist/rules/no-restricted-imports.js.map +1 -1
  22. package/dist/rules/node-class-description-icon-missing.d.ts +1 -1
  23. package/dist/rules/node-connection-type-literal.js.map +1 -1
  24. package/dist/rules/package-name-convention.d.ts +1 -1
  25. package/dist/rules/require-version.d.ts +1 -1
  26. package/dist/rules/trigger-node-conventions.d.ts +1 -1
  27. package/dist/rules/valid-author.d.ts +1 -1
  28. package/dist/rules/valid-credential-references.d.ts +1 -1
  29. package/dist/rules/valid-description.d.ts +1 -1
  30. package/dist/rules/valid-peer-dependencies.d.ts +1 -1
  31. package/dist/rules/webhook-lifecycle-complete.d.ts +1 -1
  32. package/dist/typecheck.tsbuildinfo +1 -1
  33. package/dist/utils/ast-utils.js.map +1 -1
  34. package/dist/utils/file-utils.d.ts +7 -0
  35. package/dist/utils/file-utils.d.ts.map +1 -1
  36. package/dist/utils/file-utils.js +28 -6
  37. package/dist/utils/file-utils.js.map +1 -1
  38. package/docs/rules/no-forbidden-lifecycle-scripts.md +1 -1
  39. package/docs/rules/no-restricted-imports.md +9 -0
  40. package/package.json +6 -5
  41. package/src/plugin.ts +0 -26
  42. package/src/rules/index.ts +0 -26
  43. package/src/rules/no-restricted-imports.test.ts +63 -0
  44. package/src/rules/no-restricted-imports.ts +17 -4
  45. package/src/utils/file-utils.ts +27 -6
  46. package/tsconfig.json +1 -1
  47. package/dist/rules/cred-class-name-field-conventions.d.ts +0 -2
  48. package/dist/rules/cred-class-name-field-conventions.d.ts.map +0 -1
  49. package/dist/rules/cred-class-name-field-conventions.js +0 -89
  50. package/dist/rules/cred-class-name-field-conventions.js.map +0 -1
  51. package/dist/rules/cred-class-name-suffix.d.ts +0 -2
  52. package/dist/rules/cred-class-name-suffix.d.ts.map +0 -1
  53. package/dist/rules/cred-class-name-suffix.js +0 -53
  54. package/dist/rules/cred-class-name-suffix.js.map +0 -1
  55. package/dist/rules/cred-filename-against-convention.d.ts +0 -2
  56. package/dist/rules/cred-filename-against-convention.d.ts.map +0 -1
  57. package/dist/rules/cred-filename-against-convention.js +0 -42
  58. package/dist/rules/cred-filename-against-convention.js.map +0 -1
  59. package/dist/rules/no-asterisk-in-option-names.d.ts +0 -2
  60. package/dist/rules/no-asterisk-in-option-names.d.ts.map +0 -1
  61. package/dist/rules/no-asterisk-in-option-names.js +0 -90
  62. package/dist/rules/no-asterisk-in-option-names.js.map +0 -1
  63. package/dist/rules/no-duplicate-param-options.d.ts +0 -2
  64. package/dist/rules/no-duplicate-param-options.d.ts.map +0 -1
  65. package/dist/rules/no-duplicate-param-options.js +0 -97
  66. package/dist/rules/no-duplicate-param-options.js.map +0 -1
  67. package/dist/rules/node-class-description-name-camelcase.d.ts +0 -2
  68. package/dist/rules/node-class-description-name-camelcase.d.ts.map +0 -1
  69. package/dist/rules/node-class-description-name-camelcase.js +0 -92
  70. package/dist/rules/node-class-description-name-camelcase.js.map +0 -1
  71. package/dist/rules/node-filename-against-convention.d.ts +0 -2
  72. package/dist/rules/node-filename-against-convention.d.ts.map +0 -1
  73. package/dist/rules/node-filename-against-convention.js +0 -61
  74. package/dist/rules/node-filename-against-convention.js.map +0 -1
  75. package/dist/rules/node-operation-error-itemindex.d.ts +0 -12
  76. package/dist/rules/node-operation-error-itemindex.d.ts.map +0 -1
  77. package/dist/rules/node-operation-error-itemindex.js +0 -184
  78. package/dist/rules/node-operation-error-itemindex.js.map +0 -1
  79. package/dist/rules/options-sorted-alphabetically.d.ts +0 -2
  80. package/dist/rules/options-sorted-alphabetically.d.ts.map +0 -1
  81. package/dist/rules/options-sorted-alphabetically.js +0 -95
  82. package/dist/rules/options-sorted-alphabetically.js.map +0 -1
  83. package/dist/rules/require-community-node-keyword.d.ts +0 -2
  84. package/dist/rules/require-community-node-keyword.d.ts.map +0 -1
  85. package/dist/rules/require-community-node-keyword.js +0 -65
  86. package/dist/rules/require-community-node-keyword.js.map +0 -1
  87. package/dist/rules/require-continue-on-fail.d.ts +0 -2
  88. package/dist/rules/require-continue-on-fail.d.ts.map +0 -1
  89. package/dist/rules/require-continue-on-fail.js +0 -76
  90. package/dist/rules/require-continue-on-fail.js.map +0 -1
  91. package/dist/rules/require-mit-license.d.ts +0 -2
  92. package/dist/rules/require-mit-license.d.ts.map +0 -1
  93. package/dist/rules/require-mit-license.js +0 -57
  94. package/dist/rules/require-mit-license.js.map +0 -1
  95. package/dist/rules/require-param-default.d.ts +0 -15
  96. package/dist/rules/require-param-default.d.ts.map +0 -1
  97. package/dist/rules/require-param-default.js +0 -75
  98. package/dist/rules/require-param-default.js.map +0 -1
  99. package/docs/rules/cred-class-name-field-conventions.md +0 -38
  100. package/docs/rules/cred-class-name-suffix.md +0 -46
  101. package/docs/rules/cred-filename-against-convention.md +0 -42
  102. package/docs/rules/no-asterisk-in-option-names.md +0 -61
  103. package/docs/rules/no-duplicate-param-options.md +0 -46
  104. package/docs/rules/node-class-description-name-camelcase.md +0 -41
  105. package/docs/rules/node-filename-against-convention.md +0 -50
  106. package/docs/rules/node-operation-error-itemindex.md +0 -81
  107. package/docs/rules/options-sorted-alphabetically.md +0 -63
  108. package/docs/rules/require-community-node-keyword.md +0 -45
  109. package/docs/rules/require-continue-on-fail.md +0 -56
  110. package/docs/rules/require-mit-license.md +0 -38
  111. package/docs/rules/require-param-default.md +0 -60
  112. package/src/rules/cred-class-name-field-conventions.test.ts +0 -121
  113. package/src/rules/cred-class-name-field-conventions.ts +0 -102
  114. package/src/rules/cred-class-name-suffix.test.ts +0 -74
  115. package/src/rules/cred-class-name-suffix.ts +0 -57
  116. package/src/rules/cred-filename-against-convention.test.ts +0 -72
  117. package/src/rules/cred-filename-against-convention.ts +0 -48
  118. package/src/rules/no-asterisk-in-option-names.test.ts +0 -185
  119. package/src/rules/no-asterisk-in-option-names.ts +0 -111
  120. package/src/rules/no-duplicate-param-options.test.ts +0 -125
  121. package/src/rules/no-duplicate-param-options.ts +0 -125
  122. package/src/rules/node-class-description-name-camelcase.test.ts +0 -121
  123. package/src/rules/node-class-description-name-camelcase.ts +0 -114
  124. package/src/rules/node-filename-against-convention.test.ts +0 -115
  125. package/src/rules/node-filename-against-convention.ts +0 -76
  126. package/src/rules/node-operation-error-itemindex.test.ts +0 -280
  127. package/src/rules/node-operation-error-itemindex.ts +0 -223
  128. package/src/rules/options-sorted-alphabetically.test.ts +0 -468
  129. package/src/rules/options-sorted-alphabetically.ts +0 -129
  130. package/src/rules/require-community-node-keyword.test.ts +0 -82
  131. package/src/rules/require-community-node-keyword.ts +0 -78
  132. package/src/rules/require-continue-on-fail.test.ts +0 -129
  133. package/src/rules/require-continue-on-fail.ts +0 -88
  134. package/src/rules/require-mit-license.test.ts +0 -67
  135. package/src/rules/require-mit-license.ts +0 -65
  136. package/src/rules/require-param-default.test.ts +0 -227
  137. package/src/rules/require-param-default.ts +0 -89
@@ -1 +0,0 @@
1
- {"version":3,"file":"require-param-default.js","sourceRoot":"","sources":["../../src/rules/require-param-default.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EACN,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,UAAU,EACV,eAAe,GACf,MAAM,mBAAmB,CAAC;AAE3B,sFAAsF;AACtF,MAAM,mBAAmB,GAAG,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAErE,8EAA8E;AAC9E,SAAS,eAAe,CAAC,IAA+B;IACvD,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACxC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/C,OAAO,QAAQ,KAAK,IAAI,IAAI,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;IAC5E,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAAC;IACjD,IAAI,EAAE,uBAAuB;IAC7B,IAAI,EAAE;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACL,WAAW,EAAE,0DAA0D;SACvE;QACD,QAAQ,EAAE;YACT,cAAc,EACb,+HAA+H;SAChI;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,MAAM,sBAAsB,GAAG,CAAC,IAA+B,EAAQ,EAAE;YACxE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC5E,OAAO;YACR,CAAC;YACD,MAAM,YAAY,GAAG,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACtD,OAAO,CAAC,MAAM,CAAC;gBACd,IAAI;gBACJ,SAAS,EAAE,gBAAgB;gBAC3B,IAAI,EAAE,EAAE,IAAI,EAAE,qBAAqB,CAAC,YAAY,EAAE,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE;aACxE,CAAC,CAAC;QACJ,CAAC,CAAC;QAEF,OAAO;YACN,mEAAmE;YACnE,uEAAuE;YACvE,sEAAsE;YACtE,gBAAgB,CAAC,IAAI;gBACpB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;oBAAE,OAAO;gBACnC,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;gBAC3D,IAAI,WAAW,EAAE,KAAK,EAAE,IAAI,KAAK,cAAc,CAAC,gBAAgB;oBAAE,OAAO;gBAEzE,cAAc,CAAC,WAAW,CAAC,KAAK,EAAE;oBACjC,KAAK,CAAC,KAAK;wBACV,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,gBAAgB,EAAE,CAAC;4BACpD,sBAAsB,CAAC,KAAK,CAAC,CAAC;wBAC/B,CAAC;oBACF,CAAC;iBACD,CAAC,CAAC;YACJ,CAAC;SACD,CAAC;IACH,CAAC;CACD,CAAC,CAAC"}
@@ -1,38 +0,0 @@
1
- # Credential `name` field must end with `Api` and start with a lowercase letter (`@n8n/community-nodes/cred-class-name-field-conventions`)
2
-
3
- 💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
4
-
5
- 🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
6
-
7
- <!-- end auto-generated rule header -->
8
-
9
- ## Rule Details
10
-
11
- The `name` field of a credential class (those implementing `ICredentialType` in `*.credentials.ts` files) is the internal identifier referenced by nodes and stored in the credential registry. n8n convention requires this identifier to:
12
-
13
- - End with `Api` (e.g. `githubApi`), so credentials are easily recognisable across the codebase.
14
- - Start with a lowercase letter (camelCase), since it is an identifier value rather than a class name.
15
-
16
- Both checks are automatically fixable.
17
-
18
- ## Examples
19
-
20
- ### ❌ Incorrect
21
-
22
- ```typescript
23
- export class GithubApi implements ICredentialType {
24
- name = 'Github';
25
- displayName = 'GitHub API';
26
- properties: INodeProperties[] = [];
27
- }
28
- ```
29
-
30
- ### ✅ Correct
31
-
32
- ```typescript
33
- export class GithubApi implements ICredentialType {
34
- name = 'githubApi';
35
- displayName = 'GitHub API';
36
- properties: INodeProperties[] = [];
37
- }
38
- ```
@@ -1,46 +0,0 @@
1
- # Credential class names must be suffixed with `Api` (`@n8n/community-nodes/cred-class-name-suffix`)
2
-
3
- 💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
4
-
5
- 🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
6
-
7
- <!-- end auto-generated rule header -->
8
-
9
- ## Rule Details
10
-
11
- Credential classes (those implementing `ICredentialType` in `*.credentials.ts` files) must have a class name ending in `Api`. This is the n8n convention so credentials are easily recognisable in code, in import statements, and across the credential registry.
12
-
13
- For OAuth2 credentials extending the OAuth2 base, see the sibling rule `cred-class-oauth2-naming` which enforces the more specific `OAuth2Api` suffix.
14
-
15
- ## Opt-out
16
-
17
- For legitimate exceptions (for example credentials representing custom auth headers where the `Api` suffix would be misleading), disable the rule for the specific class with a standard ESLint comment:
18
-
19
- ```typescript
20
- // eslint-disable-next-line @n8n/community-nodes/cred-class-name-suffix
21
- export class CustomAuthHeader implements ICredentialType {
22
- // ...
23
- }
24
- ```
25
-
26
- ## Examples
27
-
28
- ### ❌ Incorrect
29
-
30
- ```typescript
31
- export class MyService implements ICredentialType {
32
- name = 'myServiceApi';
33
- displayName = 'My Service API';
34
- properties: INodeProperties[] = [];
35
- }
36
- ```
37
-
38
- ### ✅ Correct
39
-
40
- ```typescript
41
- export class MyServiceApi implements ICredentialType {
42
- name = 'myServiceApi';
43
- displayName = 'My Service API';
44
- properties: INodeProperties[] = [];
45
- }
46
- ```
@@ -1,42 +0,0 @@
1
- # Credential filename must match the credential class name (`@n8n/community-nodes/cred-filename-against-convention`)
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
- This rule enforces that the basename of a `*.credentials.ts` file (without the
10
- `.credentials.ts` extension) matches the name of the credential class it
11
- contains. The class name is the source of truth.
12
-
13
- Keeping filenames in sync with class names makes credentials predictable to
14
- locate and matches the convention used throughout n8n's built-in credentials.
15
-
16
- ## Examples
17
-
18
- ### Incorrect
19
-
20
- ```typescript
21
- // File: GithubApi.credentials.ts
22
- import type { ICredentialType, INodeProperties } from 'n8n-workflow';
23
-
24
- export class GitlabApi implements ICredentialType {
25
- name = 'gitlabApi';
26
- displayName = 'GitLab API';
27
- properties: INodeProperties[] = [];
28
- }
29
- ```
30
-
31
- ### Correct
32
-
33
- ```typescript
34
- // File: GithubApi.credentials.ts
35
- import type { ICredentialType, INodeProperties } from 'n8n-workflow';
36
-
37
- export class GithubApi implements ICredentialType {
38
- name = 'githubApi';
39
- displayName = 'GitHub API';
40
- properties: INodeProperties[] = [];
41
- }
42
- ```
@@ -1,61 +0,0 @@
1
- # Disallow asterisk characters in node option name values (`@n8n/community-nodes/no-asterisk-in-option-names`)
2
-
3
- ⚠️ This rule _warns_ in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
4
-
5
- 💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
6
-
7
- <!-- end auto-generated rule header -->
8
-
9
- ## Rule Details
10
-
11
- The `name` of each entry in an `options` array is rendered directly in the n8n
12
- editor. An asterisk (`*`) in these labels renders ambiguously — it reads like a
13
- markdown bullet or emphasis marker rather than literal text. This rule flags any
14
- option `name` containing `*` and suggests replacing it with bracketed notation
15
- such as `[All]`.
16
-
17
- The rule only inspects `name` values inside `options` arrays (including nested
18
- `collection` and `fixedCollection` options); asterisks elsewhere are not
19
- reported.
20
-
21
- ## Examples
22
-
23
- ### Incorrect
24
-
25
- ```typescript
26
- export class MyNode implements INodeType {
27
- description: INodeTypeDescription = {
28
- displayName: 'My Node',
29
- name: 'myNode',
30
- properties: [
31
- {
32
- displayName: 'Resource',
33
- name: 'resource',
34
- type: 'options',
35
- options: [{ name: '* All', value: 'all' }],
36
- default: 'all',
37
- },
38
- ],
39
- };
40
- }
41
- ```
42
-
43
- ### Correct
44
-
45
- ```typescript
46
- export class MyNode implements INodeType {
47
- description: INodeTypeDescription = {
48
- displayName: 'My Node',
49
- name: 'myNode',
50
- properties: [
51
- {
52
- displayName: 'Resource',
53
- name: 'resource',
54
- type: 'options',
55
- options: [{ name: '[All]', value: 'all' }],
56
- default: 'all',
57
- },
58
- ],
59
- };
60
- }
61
- ```
@@ -1,46 +0,0 @@
1
- # Disallow duplicate option names or values within a single node parameter (`@n8n/community-nodes/no-duplicate-param-options`)
2
-
3
- ⚠️ This rule _warns_ in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
4
-
5
- <!-- end auto-generated rule header -->
6
-
7
- ## Rule Details
8
-
9
- Within an `options`- or `multiOptions`-typed node parameter, each option must
10
- have a unique `name` and a unique `value`. Duplicate names confuse users in the
11
- dropdown, and duplicate values make selections ambiguous and break value-based
12
- logic downstream.
13
-
14
- ## Examples
15
-
16
- ### Incorrect
17
-
18
- ```typescript
19
- {
20
- displayName: 'Resource',
21
- name: 'resource',
22
- type: 'options',
23
- options: [
24
- { name: 'Contact', value: 'contact' },
25
- { name: 'Contact', value: 'person' }, // duplicate name
26
- { name: 'User', value: 'contact' }, // duplicate value
27
- ],
28
- default: 'contact',
29
- }
30
- ```
31
-
32
- ### Correct
33
-
34
- ```typescript
35
- {
36
- displayName: 'Resource',
37
- name: 'resource',
38
- type: 'options',
39
- options: [
40
- { name: 'Contact', value: 'contact' },
41
- { name: 'Person', value: 'person' },
42
- { name: 'User', value: 'user' },
43
- ],
44
- default: 'contact',
45
- }
46
- ```
@@ -1,41 +0,0 @@
1
- # Node class `description.name` must be camelCase (`@n8n/community-nodes/node-class-description-name-camelcase`)
2
-
3
- 💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
4
-
5
- 🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
6
-
7
- <!-- end auto-generated rule header -->
8
-
9
- ## Rule Details
10
-
11
- The `name` field inside a node class `description` (those implementing `INodeType` or extending `Node` in `*.node.ts` files) is the internal identifier used to register and reference the node. n8n convention requires this identifier to be camelCase: it must start with a lowercase letter and contain only letters and digits, with no spaces, hyphens, underscores, or other separators.
12
-
13
- The value must match `^[a-z][a-zA-Z0-9]*$`.
14
-
15
- The rule is automatically fixable: separators are removed, each subsequent word is upper-cased, and the first character is lower-cased (e.g. `My Node` → `myNode`). Names that cannot be repaired into a valid identifier (for example, those starting with a digit) are reported without an autofix.
16
-
17
- ## Examples
18
-
19
- ### ❌ Incorrect
20
-
21
- ```typescript
22
- export class MyNode implements INodeType {
23
- description: INodeTypeDescription = {
24
- displayName: 'My Node',
25
- name: 'My Node',
26
- // ...
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
- // ...
39
- };
40
- }
41
- ```
@@ -1,50 +0,0 @@
1
- # Node filename must match the node `description.name` (`@n8n/community-nodes/node-filename-against-convention`)
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
- Every `*.node.ts` file must be named after its node's `description.name`, with the
10
- first character upper-cased. The source of truth is `description.name` — **not**
11
- the class name. Keeping the filename in sync with the registered node name makes
12
- nodes predictable to locate and matches the convention n8n tooling expects.
13
-
14
- A trailing version suffix (`V2`, `V3`, …) is allowed, so versioned implementations
15
- such as `GithubV2.node.ts` are accepted for a node whose `description.name` is
16
- `github`.
17
-
18
- The comparison is case-sensitive: a node named `github` must live in
19
- `Github.node.ts`, not `github.node.ts` or `GitHub.node.ts`.
20
-
21
- This rule is not auto-fixable because ESLint cannot rename files. Rename the file
22
- to the reported name.
23
-
24
- ## Examples
25
-
26
- ### ❌ Incorrect
27
-
28
- ```typescript
29
- // File: Gitlab.node.ts
30
- export class Github implements INodeType {
31
- description: INodeTypeDescription = {
32
- displayName: 'GitHub',
33
- name: 'github', // expected file to be named "Github.node.ts"
34
- // ...
35
- };
36
- }
37
- ```
38
-
39
- ### ✅ Correct
40
-
41
- ```typescript
42
- // File: Github.node.ts (or GithubV2.node.ts)
43
- export class Github implements INodeType {
44
- description: INodeTypeDescription = {
45
- displayName: 'GitHub',
46
- name: 'github',
47
- // ...
48
- };
49
- }
50
- ```
@@ -1,81 +0,0 @@
1
- # Require { itemIndex } in NodeOperationError / NodeApiError options inside item loops (`@n8n/community-nodes/node-operation-error-itemindex`)
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
- When throwing `NodeOperationError` or `NodeApiError` inside the item-processing loop of an `execute()` method, the options object (third argument) must contain an `itemIndex` property. Without it, n8n cannot associate the error with the specific item that caused it, which breaks per-item error reporting and `continueOnFail` behaviour.
10
-
11
- The rule only fires inside **item loops** — `for` or `for...of` statements that iterate over the result of `this.getInputData()`. Errors thrown outside such loops (e.g. in webhook handlers, trigger setup, or credential testing helpers) are not flagged.
12
-
13
- ## Examples
14
-
15
- ### ❌ Incorrect
16
-
17
- ```typescript
18
- export class MyNode implements INodeType {
19
- description: INodeTypeDescription = { /* ... */ };
20
-
21
- async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
22
- const items = this.getInputData();
23
- const returnData: INodeExecutionData[] = [];
24
-
25
- for (let i = 0; i < items.length; i++) {
26
- try {
27
- // ...
28
- } catch (error) {
29
- // Missing { itemIndex } — n8n cannot map this error back to item i
30
- throw new NodeOperationError(this.getNode(), error);
31
- }
32
- }
33
-
34
- return [returnData];
35
- }
36
- }
37
- ```
38
-
39
- ### ✅ Correct
40
-
41
- ```typescript
42
- export class MyNode implements INodeType {
43
- description: INodeTypeDescription = { /* ... */ };
44
-
45
- async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
46
- const items = this.getInputData();
47
- const returnData: INodeExecutionData[] = [];
48
-
49
- for (let i = 0; i < items.length; i++) {
50
- try {
51
- // ...
52
- } catch (error) {
53
- throw new NodeOperationError(this.getNode(), error, { itemIndex: i });
54
- }
55
- }
56
-
57
- return [returnData];
58
- }
59
- }
60
- ```
61
-
62
- Using `for...of` with a named loop variable:
63
-
64
- ```typescript
65
- async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
66
- const items = this.getInputData();
67
- const returnData: INodeExecutionData[] = [];
68
- let itemIndex = 0;
69
-
70
- for (const item of items) {
71
- try {
72
- // ...
73
- } catch (error) {
74
- throw new NodeApiError(this.getNode(), error, { itemIndex });
75
- }
76
- itemIndex++;
77
- }
78
-
79
- return [returnData];
80
- }
81
- ```
@@ -1,63 +0,0 @@
1
- # Enforce alphabetical ordering of options arrays in n8n node properties (`@n8n/community-nodes/options-sorted-alphabetically`)
2
-
3
- ⚠️ This rule _warns_ in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
4
-
5
- <!-- end auto-generated rule header -->
6
-
7
- ## Rule Details
8
-
9
- Warns when an `options`-type parameter has its options array not sorted alphabetically by name. Applies to all `type: 'options'` parameters — including `resource`, `operation`, and any other dropdowns.
10
-
11
- Alphabetical ordering is an [official n8n UI design requirement](https://docs.n8n.io/integrations/creating-nodes/plan/node-ui-design/#lists) and the most frequently flagged issue in community node reviews.
12
-
13
- Comparison is case-insensitive and locale-aware (handles non-ASCII names such as Spanish or Portuguese labels).
14
-
15
- ## Examples
16
-
17
- ### ❌ Incorrect
18
-
19
- ```typescript
20
- export class MyNode implements INodeType {
21
- description: INodeTypeDescription = {
22
- displayName: 'My Service',
23
- name: 'myService',
24
- properties: [
25
- {
26
- displayName: 'Resource',
27
- name: 'resource',
28
- type: 'options',
29
- options: [
30
- { name: 'User', value: 'user' },
31
- { name: 'Contact', value: 'contact' }, // out of order
32
- { name: 'Project', value: 'project' },
33
- ],
34
- default: 'user',
35
- },
36
- ],
37
- };
38
- }
39
- ```
40
-
41
- ### ✅ Correct
42
-
43
- ```typescript
44
- export class MyNode implements INodeType {
45
- description: INodeTypeDescription = {
46
- displayName: 'My Service',
47
- name: 'myService',
48
- properties: [
49
- {
50
- displayName: 'Resource',
51
- name: 'resource',
52
- type: 'options',
53
- options: [
54
- { name: 'Contact', value: 'contact' },
55
- { name: 'Project', value: 'project' },
56
- { name: 'User', value: 'user' },
57
- ],
58
- default: 'contact',
59
- },
60
- ],
61
- };
62
- }
63
- ```
@@ -1,45 +0,0 @@
1
- # Require the "n8n-community-node-package" keyword in community node package.json (`@n8n/community-nodes/require-community-node-keyword`)
2
-
3
- ⚠️ This rule _warns_ in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
4
-
5
- 🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/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
- ```
@@ -1,56 +0,0 @@
1
- # Require continueOnFail() handling in execute() methods of node classes (`@n8n/community-nodes/require-continue-on-fail`)
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
- Ensures that `execute()` methods in node classes include a `this.continueOnFail()` check. Without this, a single item error will abort the entire workflow instead of allowing execution to continue past the failing item.
10
-
11
- ## Examples
12
-
13
- ### ❌ Incorrect
14
-
15
- ```typescript
16
- export class MyNode implements INodeType {
17
- description: INodeTypeDescription = { /* ... */ };
18
-
19
- async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
20
- const items = this.getInputData();
21
- const returnData: INodeExecutionData[] = [];
22
- for (let i = 0; i < items.length; i++) {
23
- // No error handling — one bad item kills the whole workflow
24
- const result = await someApiCall(items[i]);
25
- returnData.push({ json: result });
26
- }
27
- return [returnData];
28
- }
29
- }
30
- ```
31
-
32
- ### ✅ Correct
33
-
34
- ```typescript
35
- export class MyNode implements INodeType {
36
- description: INodeTypeDescription = { /* ... */ };
37
-
38
- async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
39
- const items = this.getInputData();
40
- const returnData: INodeExecutionData[] = [];
41
- for (let i = 0; i < items.length; i++) {
42
- try {
43
- const result = await someApiCall(items[i]);
44
- returnData.push({ json: result });
45
- } catch (error) {
46
- if (this.continueOnFail()) {
47
- returnData.push({ json: { error: error.message }, pairedItem: { item: i } });
48
- continue;
49
- }
50
- throw error;
51
- }
52
- }
53
- return [returnData];
54
- }
55
- }
56
- ```
@@ -1,38 +0,0 @@
1
- # Require the "license" field in community node package.json to be "MIT" (`@n8n/community-nodes/require-mit-license`)
2
-
3
- 💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
4
-
5
- 🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/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 declares its `license` as `"MIT"`. Community node packages must be MIT licensed to be distributed through n8n.
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
- "license": "Apache-2.0"
28
- }
29
- ```
30
-
31
- ### ✅ Correct
32
-
33
- ```json
34
- {
35
- "name": "n8n-nodes-my-service",
36
- "license": "MIT"
37
- }
38
- ```
@@ -1,60 +0,0 @@
1
- # Require every node parameter to declare a default value (`@n8n/community-nodes/require-param-default`)
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
- Every node parameter must declare a `default` property. A parameter is detected
10
- by its shape: an object inside the node's `description` with `displayName`,
11
- `name`, and `type` all set to string literals — the shape every
12
- `INodeProperties` entry has. Entries in an `options` array (which carry
13
- `name`/`value` but no `displayName`/`type`) are not treated as parameters.
14
-
15
- Without a `default`, n8n cannot reliably initialise the parameter's value. This
16
- leads to inconsistent behaviour in the editor (empty or `undefined` fields) and
17
- at execution time. Even non-input types such as `notice` are expected to declare
18
- `default: ''`.
19
-
20
- This rule also checks parameters nested inside `options` of `collection` and
21
- `fixedCollection` parameters.
22
-
23
- ## Examples
24
-
25
- ### Incorrect
26
-
27
- ```typescript
28
- export class MyNode implements INodeType {
29
- description: INodeTypeDescription = {
30
- displayName: 'My Node',
31
- name: 'myNode',
32
- properties: [
33
- {
34
- displayName: 'Field',
35
- name: 'field',
36
- type: 'string',
37
- },
38
- ],
39
- };
40
- }
41
- ```
42
-
43
- ### Correct
44
-
45
- ```typescript
46
- export class MyNode implements INodeType {
47
- description: INodeTypeDescription = {
48
- displayName: 'My Node',
49
- name: 'myNode',
50
- properties: [
51
- {
52
- displayName: 'Field',
53
- name: 'field',
54
- type: 'string',
55
- default: '',
56
- },
57
- ],
58
- };
59
- }
60
- ```