@n8n/eslint-plugin-community-nodes 0.35.0 → 0.35.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"n8n-object-validation.d.ts","sourceRoot":"","sources":["../../src/rules/n8n-object-validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAC;AAKnE,KAAK,UAAU,GACZ,kBAAkB,GAClB,yBAAyB,GACzB,wBAAwB,GACxB,wBAAwB,GACxB,iBAAiB,GACjB,kBAAkB,GAClB,eAAe,GACf,wBAAwB,GACxB,mBAAmB,GACnB,mBAAmB,GACnB,yBAAyB,GACzB,yBAAyB,GACzB,eAAe,CAAC;AAInB,eAAO,MAAM,uBAAuB;;CA8ElC,CAAC"}
1
+ {"version":3,"file":"n8n-object-validation.d.ts","sourceRoot":"","sources":["../../src/rules/n8n-object-validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,0BAA0B,CAAC;AAKnE,KAAK,UAAU,GACZ,kBAAkB,GAClB,yBAAyB,GACzB,wBAAwB,GACxB,wBAAwB,GACxB,iBAAiB,GACjB,kBAAkB,GAClB,eAAe,GACf,wBAAwB,GACxB,mBAAmB,GACnB,mBAAmB,GACnB,yBAAyB,GACzB,yBAAyB,GACzB,eAAe,CAAC;AAInB,eAAO,MAAM,uBAAuB;;CA8ElC,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { parseNodesApiLevel } from '@n8n/utils/nodes-api-level';
1
2
  import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
3
  import { createRule, findJsonProperty, getTopLevelObjectInJson } from '../utils/index.js';
3
4
  export const N8nObjectValidationRule = createRule({
@@ -10,8 +11,8 @@ export const N8nObjectValidationRule = createRule({
10
11
  messages: {
11
12
  missingN8nObject: 'Community node package.json must contain an "n8n" object describing the package.',
12
13
  wrongLocationApiVersion: '"n8nNodesApiVersion" must be inside the "n8n" section, not at the root level of package.json.',
13
- missingNodesApiVersion: 'The "n8n" object must declare "n8nNodesApiVersion" (a positive integer).',
14
- invalidNodesApiVersion: '"n8n.n8nNodesApiVersion" must be a positive integer, got {{ value }}.',
14
+ missingNodesApiVersion: 'The "n8n" object must declare "n8nNodesApiVersion" (a positive integer, or a "<major>" or "<major>.<minor>" string).',
15
+ invalidNodesApiVersion: '"n8n.n8nNodesApiVersion" must be a positive integer, or a "<major>" or "<major>.<minor>" string, got {{ value }}.',
15
16
  missingN8nNodes: 'The "n8n" object must declare "nodes" as an array of "dist/" paths.',
16
17
  n8nNodesNotArray: '"n8n.nodes" must be an array of "dist/" paths.',
17
18
  emptyN8nNodes: '"n8n.nodes" must contain at least one path.',
@@ -73,7 +74,7 @@ function validateApiVersion(context, n8nObject) {
73
74
  return;
74
75
  }
75
76
  const valueNode = apiVersionProp.value;
76
- if (valueNode.type !== AST_NODE_TYPES.Literal || !isPositiveInteger(valueNode.value)) {
77
+ if (valueNode.type !== AST_NODE_TYPES.Literal || parseNodesApiLevel(valueNode.value) === null) {
77
78
  context.report({
78
79
  node: apiVersionProp,
79
80
  messageId: 'invalidNodesApiVersion',
@@ -142,7 +143,4 @@ function validatePathArray(context, elements, notStringMessageId, notInDistMessa
142
143
  }
143
144
  }
144
145
  }
145
- function isPositiveInteger(value) {
146
- return typeof value === 'number' && Number.isInteger(value) && value > 0;
147
- }
148
146
  //# sourceMappingURL=n8n-object-validation.js.map
@@ -17,8 +17,9 @@ register at install time and the failure is opaque to the user.
17
17
  This rule enforces the structural contract:
18
18
 
19
19
  - `package.json` must contain an `n8n` object.
20
- - `n8n.n8nNodesApiVersion` must be present and a positive integer. It must live
21
- inside `n8n`, not at the root.
20
+ - `n8n.n8nNodesApiVersion` must be present and a positive integer, or a
21
+ `"<major>"` or `"<major>.<minor>"` string such as `"3"` or `"3.1"`. It must
22
+ live inside `n8n`, not at the root.
22
23
  - `n8n.nodes` must be a non-empty array of strings, each starting with `dist/`.
23
24
  - `n8n.credentials`, if present, must be an array of strings, each starting
24
25
  with `dist/`.
@@ -53,7 +54,7 @@ the templates published by `@n8n/node-cli` and `@n8n/create-node`.
53
54
  {
54
55
  "name": "n8n-nodes-example",
55
56
  "n8n": {
56
- "n8nNodesApiVersion": "1",
57
+ "n8nNodesApiVersion": "v1",
57
58
  "nodes": ["nodes/Foo/Foo.node.js"]
58
59
  }
59
60
  }
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.35.0",
4
+ "version": "0.35.1",
5
5
  "main": "./dist/plugin.js",
6
6
  "types": "./dist/plugin.d.ts",
7
7
  "exports": {
@@ -11,15 +11,16 @@
11
11
  }
12
12
  },
13
13
  "dependencies": {
14
+ "@n8n/utils": "1.50.1",
14
15
  "@typescript-eslint/typescript-estree": "8.70.0",
15
16
  "@typescript-eslint/utils": "8.70.0",
16
17
  "fastest-levenshtein": "1.0.16"
17
18
  },
18
19
  "devDependencies": {
19
20
  "@n8n/typescript-config": "1.12.0",
20
- "@n8n/vitest-config": "1.23.0",
21
+ "@n8n/vitest-config": "1.24.0",
21
22
  "@types/node": "24.10.1",
22
- "n8n-workflow": "2.42.0",
23
+ "n8n-workflow": "2.43.2",
23
24
  "@typescript-eslint/rule-tester": "8.70.0",
24
25
  "eslint-doc-generator": "^2.2.2",
25
26
  "eslint-plugin-eslint-plugin": "^7.0.0",
@@ -26,6 +26,21 @@ ruleTester.run('n8n-object-validation', N8nObjectValidationRule, {
26
26
  filename: 'package.json',
27
27
  code: '{ "name": "n8n-nodes-example", "n8n": { "n8nNodesApiVersion": 2, "nodes": ["dist/x.js"] } }',
28
28
  },
29
+ {
30
+ name: 'major-only string api version is allowed',
31
+ filename: 'package.json',
32
+ code: '{ "name": "n8n-nodes-example", "n8n": { "n8nNodesApiVersion": "3", "nodes": ["dist/x.js"] } }',
33
+ },
34
+ {
35
+ name: 'major.minor string api version is allowed',
36
+ filename: 'package.json',
37
+ code: '{ "name": "n8n-nodes-example", "n8n": { "n8nNodesApiVersion": "3.1", "nodes": ["dist/x.js"] } }',
38
+ },
39
+ {
40
+ name: 'two-digit minor string api version is allowed',
41
+ filename: 'package.json',
42
+ code: '{ "name": "n8n-nodes-example", "n8n": { "n8nNodesApiVersion": "3.10", "nodes": ["dist/x.js"] } }',
43
+ },
29
44
  {
30
45
  name: 'non-package.json file is ignored',
31
46
  filename: 'some-config.json',
@@ -77,10 +92,22 @@ ruleTester.run('n8n-object-validation', N8nObjectValidationRule, {
77
92
  errors: [{ messageId: 'missingNodesApiVersion' }],
78
93
  },
79
94
  {
80
- name: 'n8nNodesApiVersion is a string',
95
+ name: 'n8nNodesApiVersion is a non-numeric string',
96
+ filename: 'package.json',
97
+ code: '{ "name": "n8n-nodes-example", "n8n": { "n8nNodesApiVersion": "v3", "nodes": ["dist/x.js"] } }',
98
+ errors: [{ messageId: 'invalidNodesApiVersion', data: { value: 'v3' } }],
99
+ },
100
+ {
101
+ name: 'n8nNodesApiVersion is a string with a patch part',
102
+ filename: 'package.json',
103
+ code: '{ "name": "n8n-nodes-example", "n8n": { "n8nNodesApiVersion": "3.1.0", "nodes": ["dist/x.js"] } }',
104
+ errors: [{ messageId: 'invalidNodesApiVersion', data: { value: '3.1.0' } }],
105
+ },
106
+ {
107
+ name: 'n8nNodesApiVersion is a zero-major string',
81
108
  filename: 'package.json',
82
- code: '{ "name": "n8n-nodes-example", "n8n": { "n8nNodesApiVersion": "1", "nodes": ["dist/x.js"] } }',
83
- errors: [{ messageId: 'invalidNodesApiVersion', data: { value: '1' } }],
109
+ code: '{ "name": "n8n-nodes-example", "n8n": { "n8nNodesApiVersion": "0.1", "nodes": ["dist/x.js"] } }',
110
+ errors: [{ messageId: 'invalidNodesApiVersion', data: { value: '0.1' } }],
84
111
  },
85
112
  {
86
113
  name: 'n8nNodesApiVersion is zero',
@@ -1,3 +1,4 @@
1
+ import { parseNodesApiLevel } from '@n8n/utils/nodes-api-level';
1
2
  import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
2
3
  import { AST_NODE_TYPES } from '@typescript-eslint/utils';
3
4
 
@@ -34,9 +35,9 @@ export const N8nObjectValidationRule = createRule<[], MessageIds>({
34
35
  wrongLocationApiVersion:
35
36
  '"n8nNodesApiVersion" must be inside the "n8n" section, not at the root level of package.json.',
36
37
  missingNodesApiVersion:
37
- 'The "n8n" object must declare "n8nNodesApiVersion" (a positive integer).',
38
+ 'The "n8n" object must declare "n8nNodesApiVersion" (a positive integer, or a "<major>" or "<major>.<minor>" string).',
38
39
  invalidNodesApiVersion:
39
- '"n8n.n8nNodesApiVersion" must be a positive integer, got {{ value }}.',
40
+ '"n8n.n8nNodesApiVersion" must be a positive integer, or a "<major>" or "<major>.<minor>" string, got {{ value }}.',
40
41
  missingN8nNodes: 'The "n8n" object must declare "nodes" as an array of "dist/" paths.',
41
42
  n8nNodesNotArray: '"n8n.nodes" must be an array of "dist/" paths.',
42
43
  emptyN8nNodes: '"n8n.nodes" must contain at least one path.',
@@ -108,7 +109,7 @@ function validateApiVersion(context: Context, n8nObject: TSESTree.ObjectExpressi
108
109
  }
109
110
 
110
111
  const valueNode = apiVersionProp.value;
111
- if (valueNode.type !== AST_NODE_TYPES.Literal || !isPositiveInteger(valueNode.value)) {
112
+ if (valueNode.type !== AST_NODE_TYPES.Literal || parseNodesApiLevel(valueNode.value) === null) {
112
113
  context.report({
113
114
  node: apiVersionProp,
114
115
  messageId: 'invalidNodesApiVersion',
@@ -194,7 +195,3 @@ function validatePathArray(
194
195
  }
195
196
  }
196
197
  }
197
-
198
- function isPositiveInteger(value: unknown): boolean {
199
- return typeof value === 'number' && Number.isInteger(value) && value > 0;
200
- }