@n8n/eslint-plugin-community-nodes 0.21.0 → 0.23.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 (67) hide show
  1. package/.turbo/turbo-build$colon$unchecked.log +1 -1
  2. package/README.md +52 -46
  3. package/dist/plugin.d.ts +36 -0
  4. package/dist/plugin.d.ts.map +1 -1
  5. package/dist/plugin.js +12 -0
  6. package/dist/plugin.js.map +1 -1
  7. package/dist/rules/ai-node-package-json.d.ts.map +1 -1
  8. package/dist/rules/ai-node-package-json.js +4 -3
  9. package/dist/rules/ai-node-package-json.js.map +1 -1
  10. package/dist/rules/index.d.ts +6 -0
  11. package/dist/rules/index.d.ts.map +1 -1
  12. package/dist/rules/index.js +12 -0
  13. package/dist/rules/index.js.map +1 -1
  14. package/dist/rules/no-asterisk-in-option-names.d.ts +2 -0
  15. package/dist/rules/no-asterisk-in-option-names.d.ts.map +1 -0
  16. package/dist/rules/no-asterisk-in-option-names.js +90 -0
  17. package/dist/rules/no-asterisk-in-option-names.js.map +1 -0
  18. package/dist/rules/no-duplicate-param-options.d.ts +2 -0
  19. package/dist/rules/no-duplicate-param-options.d.ts.map +1 -0
  20. package/dist/rules/no-duplicate-param-options.js +97 -0
  21. package/dist/rules/no-duplicate-param-options.js.map +1 -0
  22. package/dist/rules/node-class-description-name-camelcase.d.ts +2 -0
  23. package/dist/rules/node-class-description-name-camelcase.d.ts.map +1 -0
  24. package/dist/rules/node-class-description-name-camelcase.js +92 -0
  25. package/dist/rules/node-class-description-name-camelcase.js.map +1 -0
  26. package/dist/rules/require-mit-license.d.ts +2 -0
  27. package/dist/rules/require-mit-license.d.ts.map +1 -0
  28. package/dist/rules/require-mit-license.js +57 -0
  29. package/dist/rules/require-mit-license.js.map +1 -0
  30. package/dist/rules/require-param-default.d.ts +15 -0
  31. package/dist/rules/require-param-default.d.ts.map +1 -0
  32. package/dist/rules/require-param-default.js +75 -0
  33. package/dist/rules/require-param-default.js.map +1 -0
  34. package/dist/rules/trigger-node-conventions.d.ts +2 -0
  35. package/dist/rules/trigger-node-conventions.d.ts.map +1 -0
  36. package/dist/rules/trigger-node-conventions.js +70 -0
  37. package/dist/rules/trigger-node-conventions.js.map +1 -0
  38. package/dist/rules/valid-peer-dependencies.d.ts.map +1 -1
  39. package/dist/rules/valid-peer-dependencies.js +5 -3
  40. package/dist/rules/valid-peer-dependencies.js.map +1 -1
  41. package/dist/typecheck.tsbuildinfo +1 -1
  42. package/docs/rules/no-asterisk-in-option-names.md +61 -0
  43. package/docs/rules/no-duplicate-param-options.md +46 -0
  44. package/docs/rules/node-class-description-name-camelcase.md +41 -0
  45. package/docs/rules/require-mit-license.md +38 -0
  46. package/docs/rules/require-param-default.md +60 -0
  47. package/docs/rules/trigger-node-conventions.md +49 -0
  48. package/docs/rules/valid-peer-dependencies.md +1 -1
  49. package/package.json +6 -5
  50. package/src/plugin.ts +12 -0
  51. package/src/rules/ai-node-package-json.test.ts +5 -0
  52. package/src/rules/ai-node-package-json.ts +4 -3
  53. package/src/rules/index.ts +12 -0
  54. package/src/rules/no-asterisk-in-option-names.test.ts +185 -0
  55. package/src/rules/no-asterisk-in-option-names.ts +111 -0
  56. package/src/rules/no-duplicate-param-options.test.ts +125 -0
  57. package/src/rules/no-duplicate-param-options.ts +125 -0
  58. package/src/rules/node-class-description-name-camelcase.test.ts +121 -0
  59. package/src/rules/node-class-description-name-camelcase.ts +114 -0
  60. package/src/rules/require-mit-license.test.ts +67 -0
  61. package/src/rules/require-mit-license.ts +65 -0
  62. package/src/rules/require-param-default.test.ts +227 -0
  63. package/src/rules/require-param-default.ts +89 -0
  64. package/src/rules/trigger-node-conventions.test.ts +110 -0
  65. package/src/rules/trigger-node-conventions.ts +92 -0
  66. package/src/rules/valid-peer-dependencies.test.ts +5 -0
  67. package/src/rules/valid-peer-dependencies.ts +5 -3
@@ -0,0 +1,61 @@
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
+ ```
@@ -0,0 +1,46 @@
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
+ ```
@@ -0,0 +1,41 @@
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
+ ```
@@ -0,0 +1,38 @@
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
+ ```
@@ -0,0 +1,60 @@
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
+ ```
@@ -0,0 +1,49 @@
1
+ # Trigger nodes (class name ends with `Trigger`) must label themselves consistently as triggers (`@n8n/community-nodes/trigger-node-conventions`)
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 a node class name ends with `Trigger`, the node must consistently present
10
+ itself as a trigger so users and the editor recognize it as one. This rule
11
+ requires all of:
12
+
13
+ - `description.name` ends with `Trigger`
14
+ - `description.displayName` contains `Trigger`
15
+ - `description.inputs` is an empty array (`[]`) — trigger nodes start an
16
+ execution and take no main inputs
17
+
18
+ This consolidates three checks that form a single conceptual requirement: if
19
+ it's a trigger node, label it consistently.
20
+
21
+ ## Examples
22
+
23
+ ### Incorrect
24
+
25
+ ```typescript
26
+ export class MyTrigger implements INodeType {
27
+ description: INodeTypeDescription = {
28
+ displayName: 'My Node',
29
+ name: 'my',
30
+ inputs: ['main'],
31
+ outputs: ['main'],
32
+ // ...
33
+ };
34
+ }
35
+ ```
36
+
37
+ ### Correct
38
+
39
+ ```typescript
40
+ export class MyTrigger implements INodeType {
41
+ description: INodeTypeDescription = {
42
+ displayName: 'My Trigger',
43
+ name: 'myTrigger',
44
+ inputs: [],
45
+ outputs: ['main'],
46
+ // ...
47
+ };
48
+ }
49
+ ```
@@ -1,4 +1,4 @@
1
- # Require community node package.json peerDependencies to contain only "n8n-workflow": "*" (and optionally "ai-node-sdk") (`@n8n/community-nodes/valid-peer-dependencies`)
1
+ # Require community node package.json peerDependencies to contain only "n8n-workflow": "*" (and optionally "@n8n/ai-node-sdk") (`@n8n/community-nodes/valid-peer-dependencies`)
2
2
 
3
3
  💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
4
4
 
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.21.0",
4
+ "version": "0.23.0",
5
5
  "main": "./dist/plugin.js",
6
6
  "types": "./dist/plugin.d.ts",
7
7
  "exports": {
@@ -22,10 +22,11 @@
22
22
  "eslint-plugin-eslint-plugin": "^7.0.0",
23
23
  "rimraf": "6.0.1",
24
24
  "typescript": "6.0.2",
25
- "vitest": "^4.1.1",
26
- "@n8n/typescript-config": "1.6.0",
27
- "@n8n/vitest-config": "1.15.0",
28
- "n8n-workflow": "2.27.0"
25
+ "vite": "^8.0.2",
26
+ "vitest": "^4.1.9",
27
+ "@n8n/typescript-config": "1.7.0",
28
+ "@n8n/vitest-config": "1.16.0",
29
+ "n8n-workflow": "2.29.0"
29
30
  },
30
31
  "peerDependencies": {
31
32
  "eslint": "9.29.0",
package/src/plugin.ts CHANGED
@@ -27,6 +27,8 @@ const configs = {
27
27
  '@n8n/community-nodes/n8n-object-validation': 'error',
28
28
  '@n8n/community-nodes/no-deprecated-workflow-functions': 'error',
29
29
  '@n8n/community-nodes/no-emoji-in-options': 'error',
30
+ '@n8n/community-nodes/no-asterisk-in-option-names': 'warn',
31
+ '@n8n/community-nodes/no-duplicate-param-options': 'warn',
30
32
  '@n8n/community-nodes/node-usable-as-tool': 'error',
31
33
  '@n8n/community-nodes/package-name-convention': 'error',
32
34
  '@n8n/community-nodes/credential-test-required': 'error',
@@ -41,6 +43,7 @@ const configs = {
41
43
  '@n8n/community-nodes/icon-prefer-themed-variants': 'warn',
42
44
  '@n8n/community-nodes/options-sorted-alphabetically': 'warn',
43
45
  '@n8n/community-nodes/resource-operation-pattern': 'warn',
46
+ '@n8n/community-nodes/trigger-node-conventions': 'error',
44
47
  '@n8n/community-nodes/credential-documentation-url': 'error',
45
48
  '@n8n/community-nodes/cred-class-field-icon-missing': 'error',
46
49
  '@n8n/community-nodes/cred-class-name-field-conventions': 'error',
@@ -48,6 +51,7 @@ const configs = {
48
51
  '@n8n/community-nodes/cred-class-oauth2-naming': 'error',
49
52
  '@n8n/community-nodes/cred-filename-against-convention': 'error',
50
53
  '@n8n/community-nodes/node-connection-type-literal': 'error',
54
+ '@n8n/community-nodes/node-class-description-name-camelcase': 'error',
51
55
  '@n8n/community-nodes/node-filename-against-convention': 'error',
52
56
  '@n8n/community-nodes/missing-paired-item': 'error',
53
57
  '@n8n/community-nodes/no-builder-hint-leakage': 'error',
@@ -55,8 +59,10 @@ const configs = {
55
59
  '@n8n/community-nodes/node-registration-complete': 'warn',
56
60
  '@n8n/community-nodes/require-community-node-keyword': 'warn',
57
61
  '@n8n/community-nodes/require-continue-on-fail': 'error',
62
+ '@n8n/community-nodes/require-mit-license': 'error',
58
63
  '@n8n/community-nodes/require-node-api-error': 'error',
59
64
  '@n8n/community-nodes/require-node-description-fields': 'error',
65
+ '@n8n/community-nodes/require-param-default': 'error',
60
66
  '@n8n/community-nodes/require-version': 'error',
61
67
  '@n8n/community-nodes/valid-author': 'error',
62
68
  '@n8n/community-nodes/valid-credential-references': 'error',
@@ -76,6 +82,8 @@ const configs = {
76
82
  '@n8n/community-nodes/n8n-object-validation': 'error',
77
83
  '@n8n/community-nodes/no-deprecated-workflow-functions': 'error',
78
84
  '@n8n/community-nodes/no-emoji-in-options': 'error',
85
+ '@n8n/community-nodes/no-asterisk-in-option-names': 'warn',
86
+ '@n8n/community-nodes/no-duplicate-param-options': 'warn',
79
87
  '@n8n/community-nodes/node-usable-as-tool': 'error',
80
88
  '@n8n/community-nodes/package-name-convention': 'error',
81
89
  '@n8n/community-nodes/credential-test-required': 'error',
@@ -91,12 +99,14 @@ const configs = {
91
99
  '@n8n/community-nodes/options-sorted-alphabetically': 'warn',
92
100
  '@n8n/community-nodes/credential-documentation-url': 'error',
93
101
  '@n8n/community-nodes/resource-operation-pattern': 'warn',
102
+ '@n8n/community-nodes/trigger-node-conventions': 'error',
94
103
  '@n8n/community-nodes/cred-class-field-icon-missing': 'error',
95
104
  '@n8n/community-nodes/cred-class-name-field-conventions': 'error',
96
105
  '@n8n/community-nodes/cred-class-name-suffix': 'error',
97
106
  '@n8n/community-nodes/cred-class-oauth2-naming': 'error',
98
107
  '@n8n/community-nodes/cred-filename-against-convention': 'error',
99
108
  '@n8n/community-nodes/node-connection-type-literal': 'error',
109
+ '@n8n/community-nodes/node-class-description-name-camelcase': 'error',
100
110
  '@n8n/community-nodes/node-filename-against-convention': 'error',
101
111
  '@n8n/community-nodes/missing-paired-item': 'error',
102
112
  '@n8n/community-nodes/no-builder-hint-leakage': 'error',
@@ -104,8 +114,10 @@ const configs = {
104
114
  '@n8n/community-nodes/node-registration-complete': 'warn',
105
115
  '@n8n/community-nodes/require-community-node-keyword': 'warn',
106
116
  '@n8n/community-nodes/require-continue-on-fail': 'error',
117
+ '@n8n/community-nodes/require-mit-license': 'error',
107
118
  '@n8n/community-nodes/require-node-api-error': 'error',
108
119
  '@n8n/community-nodes/require-node-description-fields': 'error',
120
+ '@n8n/community-nodes/require-param-default': 'error',
109
121
  '@n8n/community-nodes/require-version': 'error',
110
122
  '@n8n/community-nodes/valid-author': 'error',
111
123
  '@n8n/community-nodes/valid-credential-references': 'error',
@@ -11,6 +11,11 @@ ruleTester.run('ai-node-package-json', AiNodePackageJsonRule, {
11
11
  filename: 'package.json',
12
12
  code: '{ "name": "n8n-nodes-example", "n8n": { "aiNodeSdkVersion": 1 }, "peerDependencies": { "n8n-workflow": "*", "ai-node-sdk": "*" } }',
13
13
  },
14
+ {
15
+ name: 'both n8n.aiNodeSdkVersion and scoped @n8n/ai-node-sdk peer dependency present',
16
+ filename: 'package.json',
17
+ code: '{ "name": "n8n-nodes-example", "n8n": { "aiNodeSdkVersion": 1 }, "peerDependencies": { "n8n-workflow": "*", "@n8n/ai-node-sdk": "*" } }',
18
+ },
14
19
  {
15
20
  name: 'neither n8n.aiNodeSdkVersion nor ai-node-sdk present (non-AI package)',
16
21
  filename: 'package.json',
@@ -13,9 +13,9 @@ export const AiNodePackageJsonRule = createRule({
13
13
  },
14
14
  messages: {
15
15
  missingPeerDep:
16
- 'Package declares "n8n.aiNodeSdkVersion" but is missing "ai-node-sdk" in peerDependencies. Add "ai-node-sdk": "*" to peerDependencies.',
16
+ 'Package declares "n8n.aiNodeSdkVersion" but is missing "@n8n/ai-node-sdk" in peerDependencies. Add "@n8n/ai-node-sdk": "*" to peerDependencies.',
17
17
  missingSdkVersion:
18
- 'Package has "ai-node-sdk" in peerDependencies but is missing "aiNodeSdkVersion" in the "n8n" section of package.json.',
18
+ 'Package has "@n8n/ai-node-sdk" in peerDependencies but is missing "aiNodeSdkVersion" in the "n8n" section of package.json.',
19
19
  invalidSdkVersion: '"n8n.aiNodeSdkVersion" must be a positive integer, got {{ value }}.',
20
20
  wrongLocation:
21
21
  '"aiNodeSdkVersion" must be inside the "n8n" section, not at the root level of package.json.',
@@ -49,7 +49,8 @@ export const AiNodePackageJsonRule = createRule({
49
49
  const hasAiNodeSdkVersion = aiNodeSdkVersionProp !== null;
50
50
  const hasAiNodeSdkPeerDep =
51
51
  peerDependenciesProp?.value.type === AST_NODE_TYPES.ObjectExpression &&
52
- findJsonProperty(peerDependenciesProp.value, 'ai-node-sdk') !== null;
52
+ (findJsonProperty(peerDependenciesProp.value, '@n8n/ai-node-sdk') !== null ||
53
+ findJsonProperty(peerDependenciesProp.value, 'ai-node-sdk') !== null);
53
54
 
54
55
  // Catch aiNodeSdkVersion placed at root level instead of inside n8n
55
56
  if (rootAiNodeSdkVersionProp) {
@@ -13,10 +13,12 @@ import { IconPreferThemedVariantsRule } from './icon-prefer-themed-variants.js';
13
13
  import { IconValidationRule } from './icon-validation.js';
14
14
  import { MissingPairedItemRule } from './missing-paired-item.js';
15
15
  import { N8nObjectValidationRule } from './n8n-object-validation.js';
16
+ import { NoAsteriskInOptionNamesRule } from './no-asterisk-in-option-names.js';
16
17
  import { NoBuilderHintLeakageRule } from './no-builder-hint-leakage.js';
17
18
  import { NoCredentialReuseRule } from './no-credential-reuse.js';
18
19
  import { NoDangerousFunctionsRule } from './no-dangerous-functions.js';
19
20
  import { NoDeprecatedWorkflowFunctionsRule } from './no-deprecated-workflow-functions.js';
21
+ import { NoDuplicateParamOptionsRule } from './no-duplicate-param-options.js';
20
22
  import { NoEmojiInOptionsRule } from './no-emoji-in-options.js';
21
23
  import { NoForbiddenLifecycleScriptsRule } from './no-forbidden-lifecycle-scripts.js';
22
24
  import { NoHttpRequestWithManualAuthRule } from './no-http-request-with-manual-auth.js';
@@ -26,6 +28,7 @@ import { NoRestrictedImportsRule } from './no-restricted-imports.js';
26
28
  import { NoRuntimeDependenciesRule } from './no-runtime-dependencies.js';
27
29
  import { NoTemplatePlaceholdersRule } from './no-template-placeholders.js';
28
30
  import { NodeClassDescriptionIconMissingRule } from './node-class-description-icon-missing.js';
31
+ import { NodeClassDescriptionNameCamelCaseRule } from './node-class-description-name-camelcase.js';
29
32
  import { NodeConnectionTypeLiteralRule } from './node-connection-type-literal.js';
30
33
  import { NodeFilenameAgainstConventionRule } from './node-filename-against-convention.js';
31
34
  import { NodeOperationErrorItemIndexRule } from './node-operation-error-itemindex.js';
@@ -35,10 +38,13 @@ import { OptionsSortedAlphabeticallyRule } from './options-sorted-alphabetically
35
38
  import { PackageNameConventionRule } from './package-name-convention.js';
36
39
  import { RequireCommunityNodeKeywordRule } from './require-community-node-keyword.js';
37
40
  import { RequireContinueOnFailRule } from './require-continue-on-fail.js';
41
+ import { RequireMitLicenseRule } from './require-mit-license.js';
38
42
  import { RequireNodeApiErrorRule } from './require-node-api-error.js';
39
43
  import { RequireNodeDescriptionFieldsRule } from './require-node-description-fields.js';
44
+ import { RequireParamDefaultRule } from './require-param-default.js';
40
45
  import { RequireVersionRule } from './require-version.js';
41
46
  import { ResourceOperationPatternRule } from './resource-operation-pattern.js';
47
+ import { TriggerNodeConventionsRule } from './trigger-node-conventions.js';
42
48
  import { ValidAuthorRule } from './valid-author.js';
43
49
  import { ValidCredentialReferencesRule } from './valid-credential-references.js';
44
50
  import { ValidDescriptionRule } from './valid-description.js';
@@ -52,6 +58,8 @@ export const rules = {
52
58
  'credential-password-field': CredentialPasswordFieldRule,
53
59
  'no-deprecated-workflow-functions': NoDeprecatedWorkflowFunctionsRule,
54
60
  'no-emoji-in-options': NoEmojiInOptionsRule,
61
+ 'no-asterisk-in-option-names': NoAsteriskInOptionNamesRule,
62
+ 'no-duplicate-param-options': NoDuplicateParamOptionsRule,
55
63
  'node-usable-as-tool': NodeUsableAsToolRule,
56
64
  'options-sorted-alphabetically': OptionsSortedAlphabeticallyRule,
57
65
  'package-name-convention': PackageNameConventionRule,
@@ -66,8 +74,10 @@ export const rules = {
66
74
  'icon-validation': IconValidationRule,
67
75
  'icon-prefer-themed-variants': IconPreferThemedVariantsRule,
68
76
  'resource-operation-pattern': ResourceOperationPatternRule,
77
+ 'trigger-node-conventions': TriggerNodeConventionsRule,
69
78
  'credential-documentation-url': CredentialDocumentationUrlRule,
70
79
  'node-class-description-icon-missing': NodeClassDescriptionIconMissingRule,
80
+ 'node-class-description-name-camelcase': NodeClassDescriptionNameCamelCaseRule,
71
81
  'cred-class-field-icon-missing': CredClassFieldIconMissingRule,
72
82
  'cred-class-name-field-conventions': CredClassNameFieldConventionsRule,
73
83
  'cred-class-name-suffix': CredClassNameSuffixRule,
@@ -82,8 +92,10 @@ export const rules = {
82
92
  'n8n-object-validation': N8nObjectValidationRule,
83
93
  'require-community-node-keyword': RequireCommunityNodeKeywordRule,
84
94
  'require-continue-on-fail': RequireContinueOnFailRule,
95
+ 'require-mit-license': RequireMitLicenseRule,
85
96
  'require-node-api-error': RequireNodeApiErrorRule,
86
97
  'require-node-description-fields': RequireNodeDescriptionFieldsRule,
98
+ 'require-param-default': RequireParamDefaultRule,
87
99
  'require-version': RequireVersionRule,
88
100
  'valid-author': ValidAuthorRule,
89
101
  'valid-credential-references': ValidCredentialReferencesRule,