@n8n/eslint-plugin-community-nodes 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/README.md +15 -13
- package/dist/plugin.d.ts +12 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +4 -0
- package/dist/plugin.js.map +1 -1
- package/dist/rules/ai-node-package-json.d.ts +2 -0
- package/dist/rules/ai-node-package-json.d.ts.map +1 -0
- package/dist/rules/ai-node-package-json.js +80 -0
- package/dist/rules/ai-node-package-json.js.map +1 -0
- package/dist/rules/index.d.ts +2 -0
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +4 -0
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/no-deprecated-workflow-functions.d.ts.map +1 -1
- package/dist/rules/no-deprecated-workflow-functions.js +1 -13
- package/dist/rules/no-deprecated-workflow-functions.js.map +1 -1
- package/dist/rules/no-http-request-with-manual-auth.d.ts +19 -0
- package/dist/rules/no-http-request-with-manual-auth.d.ts.map +1 -0
- package/dist/rules/no-http-request-with-manual-auth.js +65 -0
- package/dist/rules/no-http-request-with-manual-auth.js.map +1 -0
- package/dist/rules/no-restricted-imports.d.ts.map +1 -1
- package/dist/rules/no-restricted-imports.js +2 -0
- package/dist/rules/no-restricted-imports.js.map +1 -1
- package/dist/rules/node-usable-as-tool.d.ts.map +1 -1
- package/dist/rules/node-usable-as-tool.js +18 -0
- package/dist/rules/node-usable-as-tool.js.map +1 -1
- package/dist/rules/package-name-convention.d.ts.map +1 -1
- package/dist/rules/package-name-convention.js +3 -5
- package/dist/rules/package-name-convention.js.map +1 -1
- package/dist/utils/ast-utils.d.ts +7 -0
- package/dist/utils/ast-utils.d.ts.map +1 -1
- package/dist/utils/ast-utils.js +27 -0
- package/dist/utils/ast-utils.js.map +1 -1
- package/docs/rules/ai-node-package-json.md +62 -0
- package/docs/rules/credential-documentation-url.md +5 -3
- package/docs/rules/no-http-request-with-manual-auth.md +57 -0
- package/package.json +2 -2
- package/src/plugin.ts +4 -0
- package/src/rules/ai-node-package-json.test.ts +111 -0
- package/src/rules/ai-node-package-json.ts +100 -0
- package/src/rules/index.ts +4 -0
- package/src/rules/no-deprecated-workflow-functions.ts +1 -17
- package/src/rules/no-http-request-with-manual-auth.test.ts +104 -0
- package/src/rules/no-http-request-with-manual-auth.ts +78 -0
- package/src/rules/no-restricted-imports.test.ts +2 -1
- package/src/rules/no-restricted-imports.ts +2 -0
- package/src/rules/node-usable-as-tool.test.ts +66 -0
- package/src/rules/node-usable-as-tool.ts +22 -0
- package/src/rules/package-name-convention.ts +3 -8
- package/src/utils/ast-utils.ts +43 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
2
|
-
import { createRule } from '../utils/index.js';
|
|
2
|
+
import { createRule, findJsonProperty } from '../utils/index.js';
|
|
3
3
|
export const PackageNameConventionRule = createRule({
|
|
4
4
|
name: 'package-name-convention',
|
|
5
5
|
meta: {
|
|
@@ -24,10 +24,8 @@ export const PackageNameConventionRule = createRule({
|
|
|
24
24
|
if (node.parent?.type === AST_NODE_TYPES.Property) {
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
|
-
const nameProperty = node
|
|
28
|
-
|
|
29
|
-
property.key.value === 'name');
|
|
30
|
-
if (!nameProperty || nameProperty.type !== AST_NODE_TYPES.Property) {
|
|
27
|
+
const nameProperty = findJsonProperty(node, 'name');
|
|
28
|
+
if (!nameProperty) {
|
|
31
29
|
return;
|
|
32
30
|
}
|
|
33
31
|
if (nameProperty.value.type !== AST_NODE_TYPES.Literal) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package-name-convention.js","sourceRoot":"","sources":["../../src/rules/package-name-convention.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG1D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"package-name-convention.js","sourceRoot":"","sources":["../../src/rules/package-name-convention.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ export declare function getLiteralValue(node: TSESTree.Node | null): string | bo
|
|
|
7
7
|
export declare function getStringLiteralValue(node: TSESTree.Node | null): string | null;
|
|
8
8
|
export declare function getModulePath(node: TSESTree.Node | null): string | null;
|
|
9
9
|
export declare function getBooleanLiteralValue(node: TSESTree.Node | null): boolean | null;
|
|
10
|
+
export declare function findJsonProperty(obj: TSESTree.ObjectExpression, propertyName: string): TSESTree.Property | null;
|
|
10
11
|
export declare function findArrayLiteralProperty(obj: TSESTree.ObjectExpression, propertyName: string): TSESTree.ArrayExpression | null;
|
|
11
12
|
export declare function hasArrayLiteralValue(node: TSESTree.PropertyDefinition, searchValue: string): boolean;
|
|
12
13
|
export declare function getTopLevelObjectInJson(node: TSESTree.ObjectExpression): TSESTree.ObjectExpression | null;
|
|
@@ -22,5 +23,11 @@ export declare function extractCredentialNameFromArray(element: TSESTree.ArrayEx
|
|
|
22
23
|
name: string;
|
|
23
24
|
node: TSESTree.Node;
|
|
24
25
|
} | null;
|
|
26
|
+
/** Matches the `this.helpers` MemberExpression (the object part of `this.helpers.foo`). */
|
|
27
|
+
export declare function isThisHelpersAccess(node: TSESTree.MemberExpression): boolean;
|
|
28
|
+
/** Matches a call expression of the form `this.methodName(...)`. */
|
|
29
|
+
export declare function isThisMethodCall(node: TSESTree.CallExpression, method: string): boolean;
|
|
30
|
+
/** Matches a call expression of the form `this.helpers.methodName(...)`. */
|
|
31
|
+
export declare function isThisHelpersMethodCall(node: TSESTree.CallExpression, method: string): boolean;
|
|
25
32
|
export declare function findSimilarStrings(target: string, candidates: Set<string>, maxDistance?: number, maxResults?: number): string[];
|
|
26
33
|
//# sourceMappingURL=ast-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast-utils.d.ts","sourceRoot":"","sources":["../../src/utils/ast-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAezD,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,GAAG,OAAO,CAUxE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,GAAG,OAAO,CAE9E;AAED,wBAAgB,iBAAiB,CAChC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,EAC/B,YAAY,EAAE,MAAM,GAClB,QAAQ,CAAC,kBAAkB,GAAG,IAAI,CAQpC;AAED,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,QAAQ,CAAC,gBAAgB,EAC9B,YAAY,EAAE,MAAM,GAClB,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAQ1B;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,CAK5F;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAG/E;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAevE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CAGjF;AAED,wBAAgB,wBAAwB,CACvC,GAAG,EAAE,QAAQ,CAAC,gBAAgB,EAC9B,YAAY,EAAE,MAAM,GAClB,QAAQ,CAAC,eAAe,GAAG,IAAI,CAMjC;AAED,wBAAgB,oBAAoB,CACnC,IAAI,EAAE,QAAQ,CAAC,kBAAkB,EACjC,WAAW,EAAE,MAAM,GACjB,OAAO,CAST;AAED,wBAAgB,uBAAuB,CACtC,IAAI,EAAE,QAAQ,CAAC,gBAAgB,GAC7B,QAAQ,CAAC,gBAAgB,GAAG,IAAI,CAKlC;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,GAAG,OAAO,CAM1E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,GAAG,OAAO,CAO1E;AAED,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GACnD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAA;CAAE,GAAG,IAAI,CA6BjE;AAED,wBAAgB,8BAA8B,CAC7C,OAAO,EAAE,QAAQ,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,GACnD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAA;CAAE,GAAG,IAAI,CAG9C;AAED,wBAAgB,kBAAkB,CACjC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EACvB,WAAW,GAAE,MAAU,EACvB,UAAU,GAAE,MAAU,GACpB,MAAM,EAAE,CAeV"}
|
|
1
|
+
{"version":3,"file":"ast-utils.d.ts","sourceRoot":"","sources":["../../src/utils/ast-utils.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/ast-utils.js
CHANGED
|
@@ -55,6 +55,12 @@ export function getBooleanLiteralValue(node) {
|
|
|
55
55
|
const value = getLiteralValue(node);
|
|
56
56
|
return typeof value === 'boolean' ? value : null;
|
|
57
57
|
}
|
|
58
|
+
export function findJsonProperty(obj, propertyName) {
|
|
59
|
+
const property = obj.properties.find((prop) => prop.type === AST_NODE_TYPES.Property &&
|
|
60
|
+
prop.key.type === AST_NODE_TYPES.Literal &&
|
|
61
|
+
prop.key.value === propertyName);
|
|
62
|
+
return property?.type === AST_NODE_TYPES.Property ? property : null;
|
|
63
|
+
}
|
|
58
64
|
export function findArrayLiteralProperty(obj, propertyName) {
|
|
59
65
|
const property = findObjectProperty(obj, propertyName);
|
|
60
66
|
if (property?.value.type === AST_NODE_TYPES.ArrayExpression) {
|
|
@@ -119,6 +125,27 @@ export function extractCredentialNameFromArray(element) {
|
|
|
119
125
|
const info = extractCredentialInfoFromArray(element);
|
|
120
126
|
return info ? { name: info.name, node: info.node } : null;
|
|
121
127
|
}
|
|
128
|
+
/** Matches the `this.helpers` MemberExpression (the object part of `this.helpers.foo`). */
|
|
129
|
+
export function isThisHelpersAccess(node) {
|
|
130
|
+
return (node.object?.type === AST_NODE_TYPES.MemberExpression &&
|
|
131
|
+
node.object.object?.type === AST_NODE_TYPES.ThisExpression &&
|
|
132
|
+
node.object.property?.type === AST_NODE_TYPES.Identifier &&
|
|
133
|
+
node.object.property.name === 'helpers');
|
|
134
|
+
}
|
|
135
|
+
/** Matches a call expression of the form `this.methodName(...)`. */
|
|
136
|
+
export function isThisMethodCall(node, method) {
|
|
137
|
+
return (node.callee.type === AST_NODE_TYPES.MemberExpression &&
|
|
138
|
+
node.callee.object.type === AST_NODE_TYPES.ThisExpression &&
|
|
139
|
+
node.callee.property.type === AST_NODE_TYPES.Identifier &&
|
|
140
|
+
node.callee.property.name === method);
|
|
141
|
+
}
|
|
142
|
+
/** Matches a call expression of the form `this.helpers.methodName(...)`. */
|
|
143
|
+
export function isThisHelpersMethodCall(node, method) {
|
|
144
|
+
return (node.callee.type === AST_NODE_TYPES.MemberExpression &&
|
|
145
|
+
node.callee.property.type === AST_NODE_TYPES.Identifier &&
|
|
146
|
+
node.callee.property.name === method &&
|
|
147
|
+
isThisHelpersAccess(node.callee));
|
|
148
|
+
}
|
|
122
149
|
export function findSimilarStrings(target, candidates, maxDistance = 3, maxResults = 3) {
|
|
123
150
|
const matches = [];
|
|
124
151
|
for (const candidate of candidates) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ast-utils.js","sourceRoot":"","sources":["../../src/utils/ast-utils.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ast-utils.js","sourceRoot":"","sources":["../../src/utils/ast-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Enforce consistency between n8n.aiNodeSdkVersion and ai-node-sdk peer dependency in community node packages (`@n8n/community-nodes/ai-node-package-json`)
|
|
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 consistency between `n8n.aiNodeSdkVersion` in `package.json` and the `ai-node-sdk` peer dependency. When a community node uses the AI Node SDK, both fields must be present and correct.
|
|
10
|
+
|
|
11
|
+
The rule checks four conditions:
|
|
12
|
+
|
|
13
|
+
- `aiNodeSdkVersion` is declared inside the `n8n` section (not at the root level)
|
|
14
|
+
- `aiNodeSdkVersion` is a positive integer
|
|
15
|
+
- If `n8n.aiNodeSdkVersion` is set, `ai-node-sdk` must appear in `peerDependencies`
|
|
16
|
+
- If `ai-node-sdk` is in `peerDependencies`, `n8n.aiNodeSdkVersion` must be set
|
|
17
|
+
|
|
18
|
+
## Examples
|
|
19
|
+
|
|
20
|
+
### ❌ Incorrect
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"name": "n8n-nodes-my-ai-node",
|
|
25
|
+
"n8n": {
|
|
26
|
+
"aiNodeSdkVersion": "1"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"name": "n8n-nodes-my-ai-node",
|
|
34
|
+
"aiNodeSdkVersion": 1,
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"ai-node-sdk": "*"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"name": "n8n-nodes-my-ai-node",
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"ai-node-sdk": "*"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### ✅ Correct
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"name": "n8n-nodes-my-ai-node",
|
|
55
|
+
"n8n": {
|
|
56
|
+
"aiNodeSdkVersion": 1
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"ai-node-sdk": "*"
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
|
|
4
4
|
|
|
5
|
+
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
|
6
|
+
|
|
5
7
|
<!-- end auto-generated rule header -->
|
|
6
8
|
|
|
7
9
|
## Options
|
|
8
10
|
|
|
9
11
|
<!-- begin auto-generated rule options list -->
|
|
10
12
|
|
|
11
|
-
| Name | Description
|
|
12
|
-
| :----------- |
|
|
13
|
+
| Name | Description | Type |
|
|
14
|
+
| :----------- | :--------------------------------------------------------- | :------ |
|
|
13
15
|
| `allowSlugs` | Whether to allow lowercase alphanumeric slugs with slashes | Boolean |
|
|
14
|
-
| `allowUrls` | Whether to allow valid URLs
|
|
16
|
+
| `allowUrls` | Whether to allow valid URLs | Boolean |
|
|
15
17
|
|
|
16
18
|
<!-- end auto-generated rule options list -->
|
|
17
19
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Disallow this.helpers.httpRequest() in functions that call this.getCredentials(). Use this.helpers.httpRequestWithAuthentication() instead (`@n8n/community-nodes/no-http-request-with-manual-auth`)
|
|
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 function calls `this.getCredentials()` to retrieve credentials, it should use `this.helpers.httpRequestWithAuthentication()` for HTTP requests instead of `this.helpers.httpRequest()`.
|
|
10
|
+
|
|
11
|
+
Manually extracting credentials and setting auth headers (e.g. `Authorization`) bypasses n8n's authentication layer, which provides:
|
|
12
|
+
|
|
13
|
+
- Consistent credential handling across all nodes
|
|
14
|
+
- Future improvements like token refresh and audit logging
|
|
15
|
+
- Better security review surface
|
|
16
|
+
|
|
17
|
+
## Examples
|
|
18
|
+
|
|
19
|
+
### ❌ Incorrect
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
async function apiRequest(this: IExecuteFunctions, endpoint: string) {
|
|
23
|
+
const credentials = await this.getCredentials('myServiceApi');
|
|
24
|
+
|
|
25
|
+
const options: IHttpRequestOptions = {
|
|
26
|
+
method: 'GET',
|
|
27
|
+
url: `https://api.example.com/${endpoint}`,
|
|
28
|
+
headers: {
|
|
29
|
+
Authorization: `Bearer ${credentials.apiKey}`,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return this.helpers.httpRequest(options);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### ✅ Correct
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
async function apiRequest(this: IExecuteFunctions, endpoint: string) {
|
|
41
|
+
const options: IHttpRequestOptions = {
|
|
42
|
+
method: 'GET',
|
|
43
|
+
url: `https://api.example.com/${endpoint}`,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
return this.helpers.httpRequestWithAuthentication.call(this, 'myServiceApi', options);
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## When to Disable
|
|
51
|
+
|
|
52
|
+
If a function genuinely retrieves credentials for a non-HTTP purpose (e.g. reading a config value) *and* also makes an unauthenticated HTTP request, you can suppress this rule with an inline comment:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
// eslint-disable-next-line @n8n/community-nodes/no-http-request-with-manual-auth
|
|
56
|
+
return this.helpers.httpRequest(options);
|
|
57
|
+
```
|
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.
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"main": "./dist/plugin.js",
|
|
6
6
|
"types": "./dist/plugin.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"typescript": "5.9.2",
|
|
23
23
|
"vitest": "^3.1.3",
|
|
24
24
|
"@n8n/typescript-config": "1.3.0",
|
|
25
|
-
"@n8n/vitest-config": "1.
|
|
25
|
+
"@n8n/vitest-config": "1.7.0"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"eslint": ">= 9"
|
package/src/plugin.ts
CHANGED
|
@@ -20,6 +20,7 @@ const configs = {
|
|
|
20
20
|
'@n8n/community-nodes': plugin,
|
|
21
21
|
},
|
|
22
22
|
rules: {
|
|
23
|
+
'@n8n/community-nodes/ai-node-package-json': 'error',
|
|
23
24
|
'@n8n/community-nodes/no-restricted-globals': 'error',
|
|
24
25
|
'@n8n/community-nodes/no-restricted-imports': 'error',
|
|
25
26
|
'@n8n/community-nodes/credential-password-field': 'error',
|
|
@@ -28,6 +29,7 @@ const configs = {
|
|
|
28
29
|
'@n8n/community-nodes/package-name-convention': 'error',
|
|
29
30
|
'@n8n/community-nodes/credential-test-required': 'error',
|
|
30
31
|
'@n8n/community-nodes/no-credential-reuse': 'error',
|
|
32
|
+
'@n8n/community-nodes/no-http-request-with-manual-auth': 'error',
|
|
31
33
|
'@n8n/community-nodes/icon-validation': 'error',
|
|
32
34
|
'@n8n/community-nodes/resource-operation-pattern': 'warn',
|
|
33
35
|
'@n8n/community-nodes/credential-documentation-url': 'error',
|
|
@@ -39,12 +41,14 @@ const configs = {
|
|
|
39
41
|
'@n8n/community-nodes': plugin,
|
|
40
42
|
},
|
|
41
43
|
rules: {
|
|
44
|
+
'@n8n/community-nodes/ai-node-package-json': 'error',
|
|
42
45
|
'@n8n/community-nodes/credential-password-field': 'error',
|
|
43
46
|
'@n8n/community-nodes/no-deprecated-workflow-functions': 'error',
|
|
44
47
|
'@n8n/community-nodes/node-usable-as-tool': 'error',
|
|
45
48
|
'@n8n/community-nodes/package-name-convention': 'error',
|
|
46
49
|
'@n8n/community-nodes/credential-test-required': 'error',
|
|
47
50
|
'@n8n/community-nodes/no-credential-reuse': 'error',
|
|
51
|
+
'@n8n/community-nodes/no-http-request-with-manual-auth': 'error',
|
|
48
52
|
'@n8n/community-nodes/icon-validation': 'error',
|
|
49
53
|
'@n8n/community-nodes/credential-documentation-url': 'error',
|
|
50
54
|
'@n8n/community-nodes/resource-operation-pattern': 'warn',
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { RuleTester } from '@typescript-eslint/rule-tester';
|
|
2
|
+
|
|
3
|
+
import { AiNodePackageJsonRule } from './ai-node-package-json.js';
|
|
4
|
+
|
|
5
|
+
const ruleTester = new RuleTester();
|
|
6
|
+
|
|
7
|
+
ruleTester.run('ai-node-package-json', AiNodePackageJsonRule, {
|
|
8
|
+
valid: [
|
|
9
|
+
{
|
|
10
|
+
name: 'both n8n.aiNodeSdkVersion and ai-node-sdk peer dependency present',
|
|
11
|
+
filename: 'package.json',
|
|
12
|
+
code: '{ "name": "n8n-nodes-example", "n8n": { "aiNodeSdkVersion": 1 }, "peerDependencies": { "n8n-workflow": "*", "ai-node-sdk": "*" } }',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: 'neither n8n.aiNodeSdkVersion nor ai-node-sdk present (non-AI package)',
|
|
16
|
+
filename: 'package.json',
|
|
17
|
+
code: '{ "name": "n8n-nodes-example", "version": "1.0.0" }',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'n8n section without aiNodeSdkVersion and no ai-node-sdk peer dep',
|
|
21
|
+
filename: 'package.json',
|
|
22
|
+
code: '{ "name": "n8n-nodes-example", "n8n": { "nodes": [] } }',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'non-package.json file is ignored',
|
|
26
|
+
filename: 'some-config.json',
|
|
27
|
+
code: '{ "n8n": { "aiNodeSdkVersion": 1 } }',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'peerDependencies without ai-node-sdk and no aiNodeSdkVersion',
|
|
31
|
+
filename: 'package.json',
|
|
32
|
+
code: '{ "name": "n8n-nodes-example", "n8n": { "nodes": [] }, "peerDependencies": { "n8n-workflow": "*" } }',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'aiNodeSdkVersion as a larger positive integer with multiple peer deps',
|
|
36
|
+
filename: 'package.json',
|
|
37
|
+
code: '{ "name": "n8n-nodes-example", "n8n": { "aiNodeSdkVersion": 42 }, "peerDependencies": { "n8n-workflow": "^1.0.0", "ai-node-sdk": "^1.0.0" } }',
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
invalid: [
|
|
41
|
+
{
|
|
42
|
+
name: 'n8n.aiNodeSdkVersion present but ai-node-sdk missing from peerDependencies',
|
|
43
|
+
filename: 'package.json',
|
|
44
|
+
code: '{ "name": "n8n-nodes-example", "n8n": { "aiNodeSdkVersion": 1 } }',
|
|
45
|
+
errors: [{ messageId: 'missingPeerDep' }],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'n8n.aiNodeSdkVersion present but peerDependencies has other deps only',
|
|
49
|
+
filename: 'package.json',
|
|
50
|
+
code: '{ "name": "n8n-nodes-example", "n8n": { "aiNodeSdkVersion": 1 }, "peerDependencies": { "n8n-workflow": "*" } }',
|
|
51
|
+
errors: [{ messageId: 'missingPeerDep' }],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'ai-node-sdk in peerDependencies but n8n.aiNodeSdkVersion missing',
|
|
55
|
+
filename: 'package.json',
|
|
56
|
+
code: '{ "name": "n8n-nodes-example", "n8n": { "nodes": [] }, "peerDependencies": { "n8n-workflow": "*", "ai-node-sdk": "*" } }',
|
|
57
|
+
errors: [{ messageId: 'missingSdkVersion' }],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'ai-node-sdk in peerDependencies but no n8n section at all',
|
|
61
|
+
filename: 'package.json',
|
|
62
|
+
code: '{ "name": "n8n-nodes-example", "peerDependencies": { "n8n-workflow": "*", "ai-node-sdk": "*" } }',
|
|
63
|
+
errors: [{ messageId: 'missingSdkVersion' }],
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'n8n.aiNodeSdkVersion is a string instead of integer',
|
|
67
|
+
filename: 'package.json',
|
|
68
|
+
code: '{ "name": "n8n-nodes-example", "n8n": { "aiNodeSdkVersion": "1" }, "peerDependencies": { "ai-node-sdk": "*" } }',
|
|
69
|
+
errors: [{ messageId: 'invalidSdkVersion', data: { value: '1' } }],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'n8n.aiNodeSdkVersion is zero',
|
|
73
|
+
filename: 'package.json',
|
|
74
|
+
code: '{ "name": "n8n-nodes-example", "n8n": { "aiNodeSdkVersion": 0 }, "peerDependencies": { "ai-node-sdk": "*" } }',
|
|
75
|
+
errors: [{ messageId: 'invalidSdkVersion', data: { value: '0' } }],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'n8n.aiNodeSdkVersion is negative (parsed as UnaryExpression, not Literal)',
|
|
79
|
+
filename: 'package.json',
|
|
80
|
+
code: '{ "name": "n8n-nodes-example", "n8n": { "aiNodeSdkVersion": -1 }, "peerDependencies": { "ai-node-sdk": "*" } }',
|
|
81
|
+
errors: [{ messageId: 'invalidSdkVersion', data: { value: 'non-literal' } }],
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'n8n.aiNodeSdkVersion is a float',
|
|
85
|
+
filename: 'package.json',
|
|
86
|
+
code: '{ "name": "n8n-nodes-example", "n8n": { "aiNodeSdkVersion": 1.5 }, "peerDependencies": { "ai-node-sdk": "*" } }',
|
|
87
|
+
errors: [{ messageId: 'invalidSdkVersion', data: { value: '1.5' } }],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
name: 'n8n.aiNodeSdkVersion is invalid and ai-node-sdk peer dep is missing (two errors)',
|
|
91
|
+
filename: 'package.json',
|
|
92
|
+
code: '{ "name": "n8n-nodes-example", "n8n": { "aiNodeSdkVersion": "bad" } }',
|
|
93
|
+
errors: [
|
|
94
|
+
{ messageId: 'invalidSdkVersion', data: { value: 'bad' } },
|
|
95
|
+
{ messageId: 'missingPeerDep' },
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'aiNodeSdkVersion at root level instead of inside n8n section',
|
|
100
|
+
filename: 'package.json',
|
|
101
|
+
code: '{ "name": "n8n-nodes-example", "aiNodeSdkVersion": 1, "peerDependencies": { "ai-node-sdk": "*" } }',
|
|
102
|
+
errors: [{ messageId: 'wrongLocation' }, { messageId: 'missingSdkVersion' }],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: 'aiNodeSdkVersion at root level without peer dep',
|
|
106
|
+
filename: 'package.json',
|
|
107
|
+
code: '{ "name": "n8n-nodes-example", "aiNodeSdkVersion": 1 }',
|
|
108
|
+
errors: [{ messageId: 'wrongLocation' }],
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { TSESTree } from '@typescript-eslint/utils';
|
|
2
|
+
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
3
|
+
|
|
4
|
+
import { createRule, findJsonProperty } from '../utils/index.js';
|
|
5
|
+
|
|
6
|
+
export const AiNodePackageJsonRule = createRule({
|
|
7
|
+
name: 'ai-node-package-json',
|
|
8
|
+
meta: {
|
|
9
|
+
type: 'problem',
|
|
10
|
+
docs: {
|
|
11
|
+
description:
|
|
12
|
+
'Enforce consistency between n8n.aiNodeSdkVersion and ai-node-sdk peer dependency in community node packages',
|
|
13
|
+
},
|
|
14
|
+
messages: {
|
|
15
|
+
missingPeerDep:
|
|
16
|
+
'Package declares "n8n.aiNodeSdkVersion" but is missing "ai-node-sdk" in peerDependencies. Add "ai-node-sdk": "*" to peerDependencies.',
|
|
17
|
+
missingSdkVersion:
|
|
18
|
+
'Package has "ai-node-sdk" in peerDependencies but is missing "aiNodeSdkVersion" in the "n8n" section of package.json.',
|
|
19
|
+
invalidSdkVersion: '"n8n.aiNodeSdkVersion" must be a positive integer, got {{ value }}.',
|
|
20
|
+
wrongLocation:
|
|
21
|
+
'"aiNodeSdkVersion" must be inside the "n8n" section, not at the root level of package.json.',
|
|
22
|
+
},
|
|
23
|
+
schema: [],
|
|
24
|
+
},
|
|
25
|
+
defaultOptions: [],
|
|
26
|
+
create(context) {
|
|
27
|
+
if (!context.filename.endsWith('package.json')) {
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
ObjectExpression(node: TSESTree.ObjectExpression) {
|
|
33
|
+
// Only process the root object, not nested ones
|
|
34
|
+
if (node.parent?.type === AST_NODE_TYPES.Property) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const n8nProp = findJsonProperty(node, 'n8n');
|
|
39
|
+
const n8nObject =
|
|
40
|
+
n8nProp?.value.type === AST_NODE_TYPES.ObjectExpression ? n8nProp.value : null;
|
|
41
|
+
|
|
42
|
+
const aiNodeSdkVersionProp = n8nObject
|
|
43
|
+
? findJsonProperty(n8nObject, 'aiNodeSdkVersion')
|
|
44
|
+
: null;
|
|
45
|
+
|
|
46
|
+
const rootAiNodeSdkVersionProp = findJsonProperty(node, 'aiNodeSdkVersion');
|
|
47
|
+
const peerDependenciesProp = findJsonProperty(node, 'peerDependencies');
|
|
48
|
+
|
|
49
|
+
const hasAiNodeSdkVersion = aiNodeSdkVersionProp !== null;
|
|
50
|
+
const hasAiNodeSdkPeerDep =
|
|
51
|
+
peerDependenciesProp?.value.type === AST_NODE_TYPES.ObjectExpression &&
|
|
52
|
+
findJsonProperty(peerDependenciesProp.value, 'ai-node-sdk') !== null;
|
|
53
|
+
|
|
54
|
+
// Catch aiNodeSdkVersion placed at root level instead of inside n8n
|
|
55
|
+
if (rootAiNodeSdkVersionProp) {
|
|
56
|
+
context.report({
|
|
57
|
+
node: rootAiNodeSdkVersionProp,
|
|
58
|
+
messageId: 'wrongLocation',
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Validate aiNodeSdkVersion is a positive integer when present
|
|
63
|
+
if (hasAiNodeSdkVersion) {
|
|
64
|
+
const valueNode = aiNodeSdkVersionProp.value;
|
|
65
|
+
if (valueNode.type !== AST_NODE_TYPES.Literal || !isPositiveInteger(valueNode.value)) {
|
|
66
|
+
context.report({
|
|
67
|
+
node: aiNodeSdkVersionProp,
|
|
68
|
+
messageId: 'invalidSdkVersion',
|
|
69
|
+
data: {
|
|
70
|
+
value: String(
|
|
71
|
+
valueNode.type === AST_NODE_TYPES.Literal ? valueNode.value : 'non-literal',
|
|
72
|
+
),
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// If aiNodeSdkVersion is declared, ai-node-sdk must be in peerDependencies
|
|
79
|
+
if (hasAiNodeSdkVersion && !hasAiNodeSdkPeerDep) {
|
|
80
|
+
context.report({
|
|
81
|
+
node: aiNodeSdkVersionProp,
|
|
82
|
+
messageId: 'missingPeerDep',
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// If ai-node-sdk is in peerDependencies, aiNodeSdkVersion must be declared
|
|
87
|
+
if (hasAiNodeSdkPeerDep && !hasAiNodeSdkVersion) {
|
|
88
|
+
context.report({
|
|
89
|
+
node: peerDependenciesProp,
|
|
90
|
+
messageId: 'missingSdkVersion',
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
function isPositiveInteger(value: unknown): boolean {
|
|
99
|
+
return typeof value === 'number' && Number.isInteger(value) && value > 0;
|
|
100
|
+
}
|
package/src/rules/index.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { AnyRuleModule } from '@typescript-eslint/utils/ts-eslint';
|
|
2
2
|
|
|
3
|
+
import { AiNodePackageJsonRule } from './ai-node-package-json.js';
|
|
3
4
|
import { CredentialDocumentationUrlRule } from './credential-documentation-url.js';
|
|
4
5
|
import { CredentialPasswordFieldRule } from './credential-password-field.js';
|
|
5
6
|
import { CredentialTestRequiredRule } from './credential-test-required.js';
|
|
6
7
|
import { IconValidationRule } from './icon-validation.js';
|
|
7
8
|
import { NoCredentialReuseRule } from './no-credential-reuse.js';
|
|
8
9
|
import { NoDeprecatedWorkflowFunctionsRule } from './no-deprecated-workflow-functions.js';
|
|
10
|
+
import { NoHttpRequestWithManualAuthRule } from './no-http-request-with-manual-auth.js';
|
|
9
11
|
import { NoRestrictedGlobalsRule } from './no-restricted-globals.js';
|
|
10
12
|
import { NoRestrictedImportsRule } from './no-restricted-imports.js';
|
|
11
13
|
import { NodeUsableAsToolRule } from './node-usable-as-tool.js';
|
|
@@ -13,6 +15,7 @@ import { PackageNameConventionRule } from './package-name-convention.js';
|
|
|
13
15
|
import { ResourceOperationPatternRule } from './resource-operation-pattern.js';
|
|
14
16
|
|
|
15
17
|
export const rules = {
|
|
18
|
+
'ai-node-package-json': AiNodePackageJsonRule,
|
|
16
19
|
'no-restricted-globals': NoRestrictedGlobalsRule,
|
|
17
20
|
'no-restricted-imports': NoRestrictedImportsRule,
|
|
18
21
|
'credential-password-field': CredentialPasswordFieldRule,
|
|
@@ -21,6 +24,7 @@ export const rules = {
|
|
|
21
24
|
'package-name-convention': PackageNameConventionRule,
|
|
22
25
|
'credential-test-required': CredentialTestRequiredRule,
|
|
23
26
|
'no-credential-reuse': NoCredentialReuseRule,
|
|
27
|
+
'no-http-request-with-manual-auth': NoHttpRequestWithManualAuthRule,
|
|
24
28
|
'icon-validation': IconValidationRule,
|
|
25
29
|
'resource-operation-pattern': ResourceOperationPatternRule,
|
|
26
30
|
'credential-documentation-url': CredentialDocumentationUrlRule,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type { TSESTree } from '@typescript-eslint/utils';
|
|
2
1
|
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
3
2
|
|
|
4
|
-
import { createRule } from '../utils/index.js';
|
|
3
|
+
import { createRule, isThisHelpersAccess } from '../utils/index.js';
|
|
5
4
|
|
|
6
5
|
const DEPRECATED_FUNCTIONS = {
|
|
7
6
|
request: 'httpRequest',
|
|
@@ -167,21 +166,6 @@ export const NoDeprecatedWorkflowFunctionsRule = createRule({
|
|
|
167
166
|
},
|
|
168
167
|
});
|
|
169
168
|
|
|
170
|
-
/**
|
|
171
|
-
* Check if the MemberExpression follows the this.helpers.* pattern
|
|
172
|
-
*/
|
|
173
|
-
function isThisHelpersAccess(node: TSESTree.MemberExpression): boolean {
|
|
174
|
-
if (node.object?.type === AST_NODE_TYPES.MemberExpression) {
|
|
175
|
-
const outerObject = node.object;
|
|
176
|
-
return (
|
|
177
|
-
outerObject.object?.type === AST_NODE_TYPES.ThisExpression &&
|
|
178
|
-
outerObject.property?.type === AST_NODE_TYPES.Identifier &&
|
|
179
|
-
outerObject.property.name === 'helpers'
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
return false;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
169
|
function getDeprecationMessage(functionName: string): string {
|
|
186
170
|
switch (functionName) {
|
|
187
171
|
case 'request':
|