@n8n/eslint-plugin-community-nodes 0.3.0 → 0.5.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 +2 -2
- package/README.md +60 -0
- package/dist/plugin.d.ts +144 -28
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +28 -25
- package/dist/plugin.js.map +1 -1
- package/dist/rules/credential-documentation-url.d.ts +7 -0
- package/dist/rules/credential-documentation-url.d.ts.map +1 -0
- package/dist/rules/credential-documentation-url.js +100 -0
- package/dist/rules/credential-documentation-url.js.map +1 -0
- package/dist/rules/credential-password-field.d.ts +1 -2
- package/dist/rules/credential-password-field.d.ts.map +1 -1
- package/dist/rules/credential-password-field.js +25 -14
- package/dist/rules/credential-password-field.js.map +1 -1
- package/dist/rules/credential-test-required.d.ts +1 -2
- package/dist/rules/credential-test-required.d.ts.map +1 -1
- package/dist/rules/credential-test-required.js +43 -5
- package/dist/rules/credential-test-required.js.map +1 -1
- package/dist/rules/icon-validation.d.ts +1 -2
- package/dist/rules/icon-validation.d.ts.map +1 -1
- package/dist/rules/icon-validation.js +81 -15
- package/dist/rules/icon-validation.js.map +1 -1
- package/dist/rules/index.d.ts +9 -5
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +7 -5
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/no-credential-reuse.d.ts +1 -2
- package/dist/rules/no-credential-reuse.d.ts.map +1 -1
- package/dist/rules/no-credential-reuse.js +33 -4
- package/dist/rules/no-credential-reuse.js.map +1 -1
- package/dist/rules/no-deprecated-workflow-functions.d.ts +1 -2
- package/dist/rules/no-deprecated-workflow-functions.d.ts.map +1 -1
- package/dist/rules/no-deprecated-workflow-functions.js +38 -10
- package/dist/rules/no-deprecated-workflow-functions.js.map +1 -1
- package/dist/rules/no-restricted-globals.d.ts +2 -2
- package/dist/rules/no-restricted-globals.d.ts.map +1 -1
- package/dist/rules/no-restricted-globals.js +5 -3
- package/dist/rules/no-restricted-globals.js.map +1 -1
- package/dist/rules/no-restricted-imports.d.ts +1 -2
- package/dist/rules/no-restricted-imports.d.ts.map +1 -1
- package/dist/rules/no-restricted-imports.js +3 -3
- package/dist/rules/no-restricted-imports.js.map +1 -1
- package/dist/rules/node-usable-as-tool.d.ts +1 -2
- package/dist/rules/node-usable-as-tool.d.ts.map +1 -1
- package/dist/rules/node-usable-as-tool.js +6 -5
- package/dist/rules/node-usable-as-tool.js.map +1 -1
- package/dist/rules/package-name-convention.d.ts +1 -2
- package/dist/rules/package-name-convention.d.ts.map +1 -1
- package/dist/rules/package-name-convention.js +38 -2
- package/dist/rules/package-name-convention.js.map +1 -1
- package/dist/rules/resource-operation-pattern.d.ts +1 -2
- package/dist/rules/resource-operation-pattern.d.ts.map +1 -1
- package/dist/rules/resource-operation-pattern.js +9 -7
- package/dist/rules/resource-operation-pattern.js.map +1 -1
- package/dist/utils/ast-utils.d.ts +2 -1
- package/dist/utils/ast-utils.d.ts.map +1 -1
- package/dist/utils/ast-utils.js +37 -19
- package/dist/utils/ast-utils.js.map +1 -1
- package/dist/utils/file-utils.d.ts +14 -0
- package/dist/utils/file-utils.d.ts.map +1 -1
- package/dist/utils/file-utils.js +85 -18
- package/dist/utils/file-utils.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/rule-creator.d.ts +3 -0
- package/dist/utils/rule-creator.d.ts.map +1 -0
- package/dist/utils/rule-creator.js +5 -0
- package/dist/utils/rule-creator.js.map +1 -0
- package/docs/rules/credential-documentation-url.md +94 -0
- package/docs/rules/credential-password-field.md +45 -0
- package/docs/rules/credential-test-required.md +58 -0
- package/docs/rules/icon-validation.md +67 -0
- package/docs/rules/no-credential-reuse.md +82 -0
- package/docs/rules/no-deprecated-workflow-functions.md +61 -0
- package/docs/rules/no-restricted-globals.md +44 -0
- package/docs/rules/no-restricted-imports.md +47 -0
- package/docs/rules/node-usable-as-tool.md +43 -0
- package/docs/rules/package-name-convention.md +52 -0
- package/docs/rules/resource-operation-pattern.md +84 -0
- package/eslint.config.mjs +27 -0
- package/package.json +25 -4
- package/src/plugin.ts +30 -26
- package/src/rules/credential-documentation-url.test.ts +306 -0
- package/src/rules/credential-documentation-url.ts +129 -0
- package/src/rules/credential-password-field.test.ts +1 -0
- package/src/rules/credential-password-field.ts +34 -16
- package/src/rules/credential-test-required.test.ts +84 -57
- package/src/rules/credential-test-required.ts +51 -5
- package/src/rules/icon-validation.test.ts +97 -14
- package/src/rules/icon-validation.ts +95 -14
- package/src/rules/index.ts +8 -5
- package/src/rules/no-credential-reuse.test.ts +306 -58
- package/src/rules/no-credential-reuse.ts +43 -3
- package/src/rules/no-deprecated-workflow-functions.test.ts +70 -0
- package/src/rules/no-deprecated-workflow-functions.ts +44 -10
- package/src/rules/no-restricted-globals.test.ts +1 -0
- package/src/rules/no-restricted-globals.ts +6 -3
- package/src/rules/no-restricted-imports.test.ts +1 -0
- package/src/rules/no-restricted-imports.ts +8 -3
- package/src/rules/node-usable-as-tool.test.ts +1 -0
- package/src/rules/node-usable-as-tool.ts +8 -6
- package/src/rules/package-name-convention.test.ts +82 -5
- package/src/rules/package-name-convention.ts +46 -2
- package/src/rules/resource-operation-pattern.test.ts +1 -0
- package/src/rules/resource-operation-pattern.ts +13 -6
- package/src/utils/ast-utils.ts +47 -19
- package/src/utils/file-utils.ts +108 -18
- package/src/utils/index.ts +1 -0
- package/src/utils/rule-creator.ts +6 -0
- package/tsconfig.build.json +4 -0
- package/tsconfig.eslint.json +5 -0
- package/tsconfig.json +1 -2
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Disallow usage of restricted global variables in community nodes (`@n8n/community-nodes/no-restricted-globals`)
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the ✅ `recommended` config.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
## Rule Details
|
|
8
|
+
|
|
9
|
+
Prevents the use of Node.js global variables that are not allowed in n8n Cloud. While these globals may be available in self-hosted environments, they are restricted on n8n Cloud for security and stability reasons.
|
|
10
|
+
|
|
11
|
+
Restricted globals include: `clearInterval`, `clearTimeout`, `global`, `globalThis`, `process`, `setInterval`, `setTimeout`, `setImmediate`, `clearImmediate`, `__dirname`, `__filename`.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### ❌ Incorrect
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
export class MyNode implements INodeType {
|
|
19
|
+
async execute(this: IExecuteFunctions) {
|
|
20
|
+
// These globals are not allowed on n8n Cloud
|
|
21
|
+
const pid = process.pid;
|
|
22
|
+
const dir = __dirname;
|
|
23
|
+
|
|
24
|
+
setTimeout(() => {
|
|
25
|
+
console.log('This will not work on n8n Cloud');
|
|
26
|
+
}, 1000);
|
|
27
|
+
|
|
28
|
+
return this.prepareOutputData([]);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### ✅ Correct
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
export class MyNode implements INodeType {
|
|
37
|
+
async execute(this: IExecuteFunctions) {
|
|
38
|
+
// Use n8n context methods instead
|
|
39
|
+
const timezone = this.getTimezone();
|
|
40
|
+
|
|
41
|
+
return this.prepareOutputData([]);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Disallow usage of restricted imports in community nodes (`@n8n/community-nodes/no-restricted-imports`)
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled in the ✅ `recommended` config.
|
|
4
|
+
|
|
5
|
+
<!-- end auto-generated rule header -->
|
|
6
|
+
|
|
7
|
+
## Rule Details
|
|
8
|
+
|
|
9
|
+
Prevents importing external dependencies that are not allowed on n8n Cloud. Community nodes running on n8n Cloud are restricted to a specific set of allowed modules for security and performance reasons.
|
|
10
|
+
|
|
11
|
+
**Allowed modules:** `n8n-workflow`, `lodash`, `moment`, `p-limit`, `luxon`, `zod`, `crypto`, `node:crypto`
|
|
12
|
+
|
|
13
|
+
Relative imports (starting with `./` or `../`) are always allowed.
|
|
14
|
+
|
|
15
|
+
## Examples
|
|
16
|
+
|
|
17
|
+
### ❌ Incorrect
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import axios from 'axios'; // External dependency not allowed
|
|
21
|
+
import { readFile } from 'fs'; // Node.js modules not in allowlist
|
|
22
|
+
const request = require('request'); // Same applies to require()
|
|
23
|
+
|
|
24
|
+
// Dynamic imports are also restricted
|
|
25
|
+
const module = await import('some-package');
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### ✅ Correct
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { IExecuteFunctions, INodeType } from 'n8n-workflow'; // Allowed
|
|
32
|
+
import { get } from 'lodash'; // Allowed
|
|
33
|
+
import moment from 'moment'; // Allowed
|
|
34
|
+
import { DateTime } from 'luxon'; // Allowed
|
|
35
|
+
import { createHash } from 'crypto'; // Allowed
|
|
36
|
+
|
|
37
|
+
import { MyHelper } from './helpers/MyHelper'; // Relative imports allowed
|
|
38
|
+
import config from '../config'; // Relative imports allowed
|
|
39
|
+
|
|
40
|
+
export class MyNode implements INodeType {
|
|
41
|
+
// ... implementation
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## When This Rule Doesn't Apply
|
|
46
|
+
|
|
47
|
+
This rule only applies to community nodes intended for n8n Cloud. If you're building nodes exclusively for self-hosted environments, you may disable this rule, but be aware that your package will not be compatible with n8n Cloud.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Ensure node classes have usableAsTool property (`@n8n/community-nodes/node-usable-as-tool`)
|
|
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
|
+
Ensures your nodes declare whether they can be used as tools in AI workflows. This property helps n8n determine if your node is suitable for AI-assisted automation.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### ❌ Incorrect
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
export class MyNode implements INodeType {
|
|
19
|
+
description: INodeTypeDescription = {
|
|
20
|
+
displayName: 'My Node',
|
|
21
|
+
name: 'myNode',
|
|
22
|
+
group: ['input'],
|
|
23
|
+
version: 1,
|
|
24
|
+
// Missing usableAsTool property
|
|
25
|
+
properties: [],
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### ✅ Correct
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
export class MyNode implements INodeType {
|
|
34
|
+
description: INodeTypeDescription = {
|
|
35
|
+
displayName: 'My Node',
|
|
36
|
+
name: 'myNode',
|
|
37
|
+
group: ['input'],
|
|
38
|
+
version: 1,
|
|
39
|
+
usableAsTool: true,
|
|
40
|
+
properties: [],
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
```
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Enforce correct package naming convention for n8n community nodes (`@n8n/community-nodes/package-name-convention`)
|
|
2
|
+
|
|
3
|
+
💼 This rule is enabled 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
|
+
Validates that your package name follows the correct n8n community node naming convention. Package names must start with `n8n-nodes-` and can optionally be scoped.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### ❌ Incorrect
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"name": "my-service-integration"
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{
|
|
25
|
+
"name": "nodes-my-service"
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"name": "@company/my-service"
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### ✅ Correct
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"name": "n8n-nodes-my-service"
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```json
|
|
44
|
+
{
|
|
45
|
+
"name": "@company/n8n-nodes-my-service"
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Best Practices
|
|
50
|
+
|
|
51
|
+
- Use descriptive service names: `n8n-nodes-github` rather than `n8n-nodes-api`
|
|
52
|
+
- For company packages, use your organization scope: `@mycompany/n8n-nodes-internal-tool`
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Enforce proper resource/operation pattern for better UX in n8n nodes (`@n8n/community-nodes/resource-operation-pattern`)
|
|
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 a node has more than 5 operations without organizing them into resources. The resource/operation pattern improves user experience by grouping related operations together, making complex nodes easier to navigate.
|
|
10
|
+
|
|
11
|
+
When you have many operations, users benefit from having them organized into logical resource groups (e.g., "User", "Project", "File") rather than seeing a long flat list of operations.
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
|
|
15
|
+
### ❌ Incorrect
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
export class MyNode implements INodeType {
|
|
19
|
+
description: INodeTypeDescription = {
|
|
20
|
+
displayName: 'My Service',
|
|
21
|
+
name: 'myService',
|
|
22
|
+
properties: [
|
|
23
|
+
{
|
|
24
|
+
displayName: 'Operation',
|
|
25
|
+
name: 'operation',
|
|
26
|
+
type: 'options',
|
|
27
|
+
options: [
|
|
28
|
+
{ name: 'Get User', value: 'getUser' },
|
|
29
|
+
{ name: 'Create User', value: 'createUser' },
|
|
30
|
+
{ name: 'Update User', value: 'updateUser' },
|
|
31
|
+
{ name: 'Delete User', value: 'deleteUser' },
|
|
32
|
+
{ name: 'Get Project', value: 'getProject' },
|
|
33
|
+
{ name: 'Create Project', value: 'createProject' },
|
|
34
|
+
{ name: 'List Files', value: 'listFiles' },
|
|
35
|
+
// 7+ operations without resources - hard to navigate!
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
// ... other properties
|
|
39
|
+
],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### ✅ Correct
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
export class MyNode implements INodeType {
|
|
48
|
+
description: INodeTypeDescription = {
|
|
49
|
+
displayName: 'My Service',
|
|
50
|
+
name: 'myService',
|
|
51
|
+
properties: [
|
|
52
|
+
{
|
|
53
|
+
displayName: 'Resource',
|
|
54
|
+
name: 'resource',
|
|
55
|
+
type: 'options',
|
|
56
|
+
options: [
|
|
57
|
+
{ name: 'User', value: 'user' },
|
|
58
|
+
{ name: 'Project', value: 'project' },
|
|
59
|
+
{ name: 'File', value: 'file' },
|
|
60
|
+
],
|
|
61
|
+
default: 'user',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
displayName: 'Operation',
|
|
65
|
+
name: 'operation',
|
|
66
|
+
type: 'options',
|
|
67
|
+
displayOptions: {
|
|
68
|
+
show: {
|
|
69
|
+
resource: ['user'],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
options: [
|
|
73
|
+
{ name: 'Get', value: 'get' },
|
|
74
|
+
{ name: 'Create', value: 'create' },
|
|
75
|
+
{ name: 'Update', value: 'update' },
|
|
76
|
+
{ name: 'Delete', value: 'delete' },
|
|
77
|
+
],
|
|
78
|
+
default: 'get',
|
|
79
|
+
},
|
|
80
|
+
// ... similar operation blocks for 'project' and 'file' resources
|
|
81
|
+
],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
```
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
import { nodeConfig } from '@n8n/eslint-config/node';
|
|
3
|
+
import eslintPlugin from 'eslint-plugin-eslint-plugin';
|
|
4
|
+
|
|
5
|
+
export default defineConfig([
|
|
6
|
+
nodeConfig,
|
|
7
|
+
eslintPlugin.configs.recommended,
|
|
8
|
+
{
|
|
9
|
+
files: ['src/**/*.ts'],
|
|
10
|
+
languageOptions: {
|
|
11
|
+
parserOptions: {
|
|
12
|
+
project: './tsconfig.json',
|
|
13
|
+
allowDefaultProject: true,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
rules: {
|
|
17
|
+
// We use RuleCreator which adds this automatically
|
|
18
|
+
'eslint-plugin/require-meta-docs-url': 'off',
|
|
19
|
+
// typescript-eslint uses different pattern
|
|
20
|
+
'eslint-plugin/require-meta-default-options': 'off',
|
|
21
|
+
// Disable naming convention for plugin configs (ESLint rule names use kebab-case)
|
|
22
|
+
'@typescript-eslint/naming-convention': 'off',
|
|
23
|
+
// Allow default exports for ESLint plugin
|
|
24
|
+
'import-x/no-default-export': 'off',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
]);
|
package/package.json
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@n8n/eslint-plugin-community-nodes",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
|
+
"main": "./dist/plugin.js",
|
|
6
|
+
"types": "./dist/plugin.d.ts",
|
|
5
7
|
"exports": {
|
|
6
8
|
".": {
|
|
7
9
|
"types": "./dist/plugin.d.ts",
|
|
@@ -9,10 +11,13 @@
|
|
|
9
11
|
}
|
|
10
12
|
},
|
|
11
13
|
"dependencies": {
|
|
12
|
-
"@typescript-eslint/utils": "^8.35.0"
|
|
14
|
+
"@typescript-eslint/utils": "^8.35.0",
|
|
15
|
+
"fastest-levenshtein": "1.0.16"
|
|
13
16
|
},
|
|
14
17
|
"devDependencies": {
|
|
15
18
|
"@typescript-eslint/rule-tester": "^8.35.0",
|
|
19
|
+
"eslint-doc-generator": "^2.2.2",
|
|
20
|
+
"eslint-plugin-eslint-plugin": "^7.0.0",
|
|
16
21
|
"rimraf": "6.0.1",
|
|
17
22
|
"typescript": "5.9.2",
|
|
18
23
|
"vitest": "^3.1.3",
|
|
@@ -22,6 +27,18 @@
|
|
|
22
27
|
"peerDependencies": {
|
|
23
28
|
"eslint": ">= 9"
|
|
24
29
|
},
|
|
30
|
+
"eslint-doc-generator": {
|
|
31
|
+
"configEmoji": [
|
|
32
|
+
[
|
|
33
|
+
"recommended",
|
|
34
|
+
"✅"
|
|
35
|
+
],
|
|
36
|
+
[
|
|
37
|
+
"recommendedWithoutN8nCloudSupport",
|
|
38
|
+
"☑️"
|
|
39
|
+
]
|
|
40
|
+
]
|
|
41
|
+
},
|
|
25
42
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
26
43
|
"homepage": "https://n8n.io",
|
|
27
44
|
"author": {
|
|
@@ -33,14 +50,18 @@
|
|
|
33
50
|
"url": "git+https://github.com/n8n-io/n8n.git"
|
|
34
51
|
},
|
|
35
52
|
"scripts": {
|
|
36
|
-
"build": "tsc",
|
|
53
|
+
"build": "tsc --project tsconfig.build.json",
|
|
54
|
+
"build:docs": "eslint-doc-generator",
|
|
37
55
|
"clean": "rimraf dist .turbo",
|
|
38
56
|
"dev": "pnpm watch",
|
|
39
57
|
"format": "biome format --write .",
|
|
40
58
|
"format:check": "biome ci .",
|
|
59
|
+
"lint": "eslint src",
|
|
60
|
+
"lint:fix": "eslint src --fix",
|
|
61
|
+
"lint:docs": "eslint-doc-generator --check",
|
|
41
62
|
"test": "vitest run",
|
|
42
63
|
"test:dev": "vitest",
|
|
43
64
|
"typecheck": "tsc --noEmit",
|
|
44
|
-
"watch": "tsc --watch"
|
|
65
|
+
"watch": "tsc --watch --project tsconfig.build.json"
|
|
45
66
|
}
|
|
46
67
|
}
|
package/src/plugin.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import type { ESLint, Linter } from 'eslint';
|
|
2
|
-
import { rules } from './rules/index.js';
|
|
3
|
-
import fs from 'node:fs';
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
4
|
+
import { rules } from './rules/index.js';
|
|
6
5
|
|
|
7
6
|
const plugin = {
|
|
8
7
|
meta: {
|
|
9
8
|
name: pkg.name,
|
|
10
9
|
version: pkg.version,
|
|
11
|
-
namespace: 'n8n
|
|
10
|
+
namespace: '@n8n/community-nodes',
|
|
12
11
|
},
|
|
13
12
|
// @ts-expect-error Rules type does not match for typescript-eslint and eslint
|
|
14
13
|
rules: rules as ESLint.Plugin['rules'],
|
|
@@ -18,38 +17,43 @@ const configs = {
|
|
|
18
17
|
recommended: {
|
|
19
18
|
ignores: ['eslint.config.{js,mjs,ts,mts}'],
|
|
20
19
|
plugins: {
|
|
21
|
-
'n8n
|
|
20
|
+
'@n8n/community-nodes': plugin,
|
|
22
21
|
},
|
|
23
22
|
rules: {
|
|
24
|
-
'n8n
|
|
25
|
-
'n8n
|
|
26
|
-
'n8n
|
|
27
|
-
'n8n
|
|
28
|
-
'n8n
|
|
29
|
-
'n8n
|
|
30
|
-
'n8n
|
|
31
|
-
'n8n
|
|
32
|
-
'n8n
|
|
33
|
-
'n8n
|
|
23
|
+
'@n8n/community-nodes/no-restricted-globals': 'error',
|
|
24
|
+
'@n8n/community-nodes/no-restricted-imports': 'error',
|
|
25
|
+
'@n8n/community-nodes/credential-password-field': 'error',
|
|
26
|
+
'@n8n/community-nodes/no-deprecated-workflow-functions': 'error',
|
|
27
|
+
'@n8n/community-nodes/node-usable-as-tool': 'error',
|
|
28
|
+
'@n8n/community-nodes/package-name-convention': 'error',
|
|
29
|
+
'@n8n/community-nodes/credential-test-required': 'error',
|
|
30
|
+
'@n8n/community-nodes/no-credential-reuse': 'error',
|
|
31
|
+
'@n8n/community-nodes/icon-validation': 'error',
|
|
32
|
+
'@n8n/community-nodes/resource-operation-pattern': 'warn',
|
|
33
|
+
'@n8n/community-nodes/credential-documentation-url': 'error',
|
|
34
34
|
},
|
|
35
35
|
},
|
|
36
36
|
recommendedWithoutN8nCloudSupport: {
|
|
37
37
|
ignores: ['eslint.config.{js,mjs,ts,mts}'],
|
|
38
38
|
plugins: {
|
|
39
|
-
'n8n
|
|
39
|
+
'@n8n/community-nodes': plugin,
|
|
40
40
|
},
|
|
41
41
|
rules: {
|
|
42
|
-
'n8n
|
|
43
|
-
'n8n
|
|
44
|
-
'n8n
|
|
45
|
-
'n8n
|
|
46
|
-
'n8n
|
|
47
|
-
'n8n
|
|
48
|
-
'n8n
|
|
49
|
-
'n8n
|
|
42
|
+
'@n8n/community-nodes/credential-password-field': 'error',
|
|
43
|
+
'@n8n/community-nodes/no-deprecated-workflow-functions': 'error',
|
|
44
|
+
'@n8n/community-nodes/node-usable-as-tool': 'error',
|
|
45
|
+
'@n8n/community-nodes/package-name-convention': 'error',
|
|
46
|
+
'@n8n/community-nodes/credential-test-required': 'error',
|
|
47
|
+
'@n8n/community-nodes/no-credential-reuse': 'error',
|
|
48
|
+
'@n8n/community-nodes/icon-validation': 'error',
|
|
49
|
+
'@n8n/community-nodes/credential-documentation-url': 'error',
|
|
50
|
+
'@n8n/community-nodes/resource-operation-pattern': 'warn',
|
|
50
51
|
},
|
|
51
52
|
},
|
|
52
53
|
} satisfies Record<string, Linter.Config>;
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
const pluginWithConfigs = { ...plugin, configs } satisfies ESLint.Plugin;
|
|
56
|
+
|
|
57
|
+
const n8nCommunityNodesPlugin = pluginWithConfigs;
|
|
58
|
+
export default pluginWithConfigs;
|
|
59
|
+
export { rules, configs, n8nCommunityNodesPlugin };
|