first commit
This commit is contained in:
94
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/credential-documentation-url.md
generated
vendored
Normal file
94
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/credential-documentation-url.md
generated
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
# Enforce valid credential documentationUrl format (URL or lowercase alphanumeric slug) (`@n8n/community-nodes/credential-documentation-url`)
|
||||
|
||||
💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
## Options
|
||||
|
||||
<!-- begin auto-generated rule options list -->
|
||||
|
||||
| Name | Description | Type |
|
||||
| :----------- | :----------------------------------------------------- | :------ |
|
||||
| `allowSlugs` | Whether to allow lowercase alphanumeric slugs with slashes | Boolean |
|
||||
| `allowUrls` | Whether to allow valid URLs | Boolean |
|
||||
|
||||
<!-- end auto-generated rule options list -->
|
||||
|
||||
## Rule Details
|
||||
|
||||
Ensures that credential `documentationUrl` values are in a valid format. For community packages, this should always be a complete URL to your documentation.
|
||||
|
||||
The lowercase alphanumeric slug option (`allowSlugs`) is only intended for internal n8n use when referring to slugs on docs.n8n.io, and should not be used in community packages. When enabled, uppercase letters in slugs will be automatically converted to lowercase.
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ Incorrect
|
||||
|
||||
```typescript
|
||||
export class MyApiCredential implements ICredentialType {
|
||||
name = 'myApi';
|
||||
displayName = 'My API';
|
||||
documentationUrl = 'invalid-url-format'; // Not a valid URL
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
```typescript
|
||||
export class MyApiCredential implements ICredentialType {
|
||||
name = 'myApi';
|
||||
displayName = 'My API';
|
||||
documentationUrl = 'MyApi'; // Invalid: uppercase letters (will be autofixed to 'myapi')
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
```typescript
|
||||
export class MyApiCredential implements ICredentialType {
|
||||
name = 'myApi';
|
||||
displayName = 'My API';
|
||||
documentationUrl = 'my-api'; // Invalid: special characters not allowed
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Correct
|
||||
|
||||
```typescript
|
||||
export class MyApiCredential implements ICredentialType {
|
||||
name = 'myApi';
|
||||
displayName = 'My API';
|
||||
documentationUrl = 'https://docs.myservice.com/api-setup'; // Complete URL to documentation
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
```typescript
|
||||
export class MyApiCredential implements ICredentialType {
|
||||
name = 'myApi';
|
||||
displayName = 'My API';
|
||||
documentationUrl = 'https://github.com/myuser/n8n-nodes-myapi#credentials'; // GitHub README section
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
By default, only URLs are allowed, which is the recommended setting for community packages.
|
||||
|
||||
The `allowSlugs` option is available for internal n8n development:
|
||||
|
||||
```json
|
||||
{
|
||||
"rules": {
|
||||
"@n8n/community-nodes/credential-documentation-url": [
|
||||
"error",
|
||||
{
|
||||
"allowSlugs": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** Community package developers should keep the default settings and always use complete URLs for their documentation.
|
||||
45
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/credential-password-field.md
generated
vendored
Normal file
45
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/credential-password-field.md
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# Ensure credential fields with sensitive names have typeOptions.password = true (`@n8n/community-nodes/credential-password-field`)
|
||||
|
||||
💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
|
||||
|
||||
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
## Rule Details
|
||||
|
||||
Ensures that credential fields with names like "password", "secret", "token", or "key" are properly masked in the UI by having `typeOptions.password = true`.
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ Incorrect
|
||||
|
||||
```typescript
|
||||
export class MyApiCredential implements ICredentialType {
|
||||
properties: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'API Key',
|
||||
name: 'apiKey',
|
||||
type: 'string',
|
||||
default: '',
|
||||
// Missing typeOptions.password
|
||||
},
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Correct
|
||||
|
||||
```typescript
|
||||
export class MyApiCredential implements ICredentialType {
|
||||
properties: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'API Key',
|
||||
name: 'apiKey',
|
||||
type: 'string',
|
||||
typeOptions: { password: true },
|
||||
default: '',
|
||||
},
|
||||
];
|
||||
}
|
||||
```
|
||||
58
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/credential-test-required.md
generated
vendored
Normal file
58
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/credential-test-required.md
generated
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
# Ensure credentials have a credential test (`@n8n/community-nodes/credential-test-required`)
|
||||
|
||||
💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
|
||||
|
||||
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
## Rule Details
|
||||
|
||||
Ensures that your credentials include a `test` method to validate user credentials. This helps users verify their credentials are working correctly.
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ Incorrect
|
||||
|
||||
```typescript
|
||||
export class MyApiCredential implements ICredentialType {
|
||||
name = 'myApi';
|
||||
displayName = 'My API';
|
||||
properties: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'API Key',
|
||||
name: 'apiKey',
|
||||
type: 'string',
|
||||
typeOptions: { password: true },
|
||||
default: '',
|
||||
},
|
||||
];
|
||||
// Missing test method
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Correct
|
||||
|
||||
```typescript
|
||||
export class MyApiCredential implements ICredentialType {
|
||||
name = 'myApi';
|
||||
displayName = 'My API';
|
||||
properties: INodeProperties[] = [
|
||||
{
|
||||
displayName: 'API Key',
|
||||
name: 'apiKey',
|
||||
type: 'string',
|
||||
typeOptions: { password: true },
|
||||
default: '',
|
||||
},
|
||||
];
|
||||
|
||||
test: ICredentialTestRequest = {
|
||||
request: {
|
||||
baseURL: 'https://api.myservice.com',
|
||||
url: '/user',
|
||||
method: 'GET',
|
||||
},
|
||||
};
|
||||
}
|
||||
```
|
||||
67
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/icon-validation.md
generated
vendored
Normal file
67
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/icon-validation.md
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
# Validate node and credential icon files exist, are SVG format, and light/dark icons are different (`@n8n/community-nodes/icon-validation`)
|
||||
|
||||
💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
|
||||
|
||||
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
## Rule Details
|
||||
|
||||
Validates that your node and credential icon files exist, are in SVG format, and use the correct `file:` protocol. Icons must be different files when providing light/dark theme variants.
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ Incorrect
|
||||
|
||||
```typescript
|
||||
export class MyNode implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'My Node',
|
||||
name: 'myNode',
|
||||
icon: 'icons/my-icon.png', // Missing 'file:' prefix, wrong format
|
||||
// ...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
```typescript
|
||||
export class MyNode implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'My Node',
|
||||
name: 'myNode',
|
||||
icon: {
|
||||
light: 'file:icons/my-icon.svg',
|
||||
dark: 'file:icons/my-icon.svg', // Same file for both themes
|
||||
},
|
||||
// ...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Correct
|
||||
|
||||
```typescript
|
||||
export class MyNode implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'My Node',
|
||||
name: 'myNode',
|
||||
icon: 'file:icons/my-service.svg', // Correct format
|
||||
// ...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
```typescript
|
||||
export class MyNode implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'My Node',
|
||||
name: 'myNode',
|
||||
icon: {
|
||||
light: 'file:icons/my-service-light.svg',
|
||||
dark: 'file:icons/my-service-dark.svg', // Different files
|
||||
},
|
||||
// ...
|
||||
};
|
||||
}
|
||||
```
|
||||
82
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/no-credential-reuse.md
generated
vendored
Normal file
82
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/no-credential-reuse.md
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
# Prevent credential re-use security issues by ensuring nodes only reference credentials from the same package (`@n8n/community-nodes/no-credential-reuse`)
|
||||
|
||||
💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
|
||||
|
||||
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
## Rule Details
|
||||
|
||||
Ensures your nodes only reference credentials by their `name` property that match credential classes declared in your package's `package.json` file. This prevents security issues where nodes could access credentials from other packages.
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ Incorrect
|
||||
|
||||
```typescript
|
||||
// MyApiCredential.credentials.ts
|
||||
export class MyApiCredential implements ICredentialType {
|
||||
name = 'myApiCredential';
|
||||
displayName = 'My API';
|
||||
// ...
|
||||
}
|
||||
|
||||
// package.json: "n8n": { "credentials": ["dist/credentials/MyApiCredential.credentials.js"] }
|
||||
|
||||
export class MyNode implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'My Node',
|
||||
name: 'myNode',
|
||||
credentials: [
|
||||
{
|
||||
name: 'someOtherCredential', // No credential class with this name in package
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
// ...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Correct
|
||||
|
||||
```typescript
|
||||
// MyApiCredential.credentials.ts
|
||||
export class MyApiCredential implements ICredentialType {
|
||||
name = 'myApiCredential'; // This name must match what's used in nodes
|
||||
displayName = 'My API';
|
||||
// ...
|
||||
}
|
||||
|
||||
// package.json: "n8n": { "credentials": ["dist/credentials/MyApiCredential.credentials.js"] }
|
||||
|
||||
export class MyNode implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'My Node',
|
||||
name: 'myNode',
|
||||
credentials: [
|
||||
{
|
||||
name: 'myApiCredential', // Matches credential class name property
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
// ...
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
Declare your credential files in `package.json` and ensure the credential name in nodes matches the `name` property in your credential classes:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "n8n-nodes-my-service",
|
||||
"n8n": {
|
||||
"credentials": [
|
||||
"dist/credentials/MyApiCredential.credentials.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
61
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/no-deprecated-workflow-functions.md
generated
vendored
Normal file
61
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/no-deprecated-workflow-functions.md
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
# Disallow usage of deprecated functions and types from n8n-workflow package (`@n8n/community-nodes/no-deprecated-workflow-functions`)
|
||||
|
||||
💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
|
||||
|
||||
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
## Rule Details
|
||||
|
||||
Prevents usage of deprecated functions from n8n-workflow package and suggests modern alternatives.
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ Incorrect
|
||||
|
||||
```typescript
|
||||
import { IRequestOptions } from 'n8n-workflow';
|
||||
|
||||
export class MyNode implements INodeType {
|
||||
async execute(this: IExecuteFunctions) {
|
||||
// Using deprecated request helper function
|
||||
const response = await this.helpers.request({
|
||||
method: 'GET',
|
||||
url: 'https://api.example.com/data',
|
||||
});
|
||||
|
||||
// Using deprecated type
|
||||
const options: IRequestOptions = {
|
||||
method: 'POST',
|
||||
url: 'https://api.example.com/data',
|
||||
};
|
||||
|
||||
return [this.helpers.returnJsonArray([response])];
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Correct
|
||||
|
||||
```typescript
|
||||
import { IHttpRequestOptions } from 'n8n-workflow';
|
||||
|
||||
export class MyNode implements INodeType {
|
||||
async execute(this: IExecuteFunctions) {
|
||||
// Using modern httpRequest helper function
|
||||
const response = await this.helpers.httpRequest({
|
||||
method: 'GET',
|
||||
url: 'https://api.example.com/data',
|
||||
});
|
||||
|
||||
// Using modern type
|
||||
const options: IHttpRequestOptions = {
|
||||
method: 'POST',
|
||||
url: 'https://api.example.com/data',
|
||||
};
|
||||
|
||||
return [this.helpers.returnJsonArray([response])];
|
||||
}
|
||||
}
|
||||
```
|
||||
44
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/no-restricted-globals.md
generated
vendored
Normal file
44
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/no-restricted-globals.md
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
# Disallow usage of restricted global variables in community nodes (`@n8n/community-nodes/no-restricted-globals`)
|
||||
|
||||
💼 This rule is enabled in the ✅ `recommended` config.
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
## Rule Details
|
||||
|
||||
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.
|
||||
|
||||
Restricted globals include: `clearInterval`, `clearTimeout`, `global`, `globalThis`, `process`, `setInterval`, `setTimeout`, `setImmediate`, `clearImmediate`, `__dirname`, `__filename`.
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ Incorrect
|
||||
|
||||
```typescript
|
||||
export class MyNode implements INodeType {
|
||||
async execute(this: IExecuteFunctions) {
|
||||
// These globals are not allowed on n8n Cloud
|
||||
const pid = process.pid;
|
||||
const dir = __dirname;
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('This will not work on n8n Cloud');
|
||||
}, 1000);
|
||||
|
||||
return this.prepareOutputData([]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Correct
|
||||
|
||||
```typescript
|
||||
export class MyNode implements INodeType {
|
||||
async execute(this: IExecuteFunctions) {
|
||||
// Use n8n context methods instead
|
||||
const timezone = this.getTimezone();
|
||||
|
||||
return this.prepareOutputData([]);
|
||||
}
|
||||
}
|
||||
```
|
||||
47
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/no-restricted-imports.md
generated
vendored
Normal file
47
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/no-restricted-imports.md
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# Disallow usage of restricted imports in community nodes (`@n8n/community-nodes/no-restricted-imports`)
|
||||
|
||||
💼 This rule is enabled in the ✅ `recommended` config.
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
## Rule Details
|
||||
|
||||
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.
|
||||
|
||||
**Allowed modules:** `n8n-workflow`, `lodash`, `moment`, `p-limit`, `luxon`, `zod`, `crypto`, `node:crypto`
|
||||
|
||||
Relative imports (starting with `./` or `../`) are always allowed.
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ Incorrect
|
||||
|
||||
```typescript
|
||||
import axios from 'axios'; // External dependency not allowed
|
||||
import { readFile } from 'fs'; // Node.js modules not in allowlist
|
||||
const request = require('request'); // Same applies to require()
|
||||
|
||||
// Dynamic imports are also restricted
|
||||
const module = await import('some-package');
|
||||
```
|
||||
|
||||
### ✅ Correct
|
||||
|
||||
```typescript
|
||||
import { IExecuteFunctions, INodeType } from 'n8n-workflow'; // Allowed
|
||||
import { get } from 'lodash'; // Allowed
|
||||
import moment from 'moment'; // Allowed
|
||||
import { DateTime } from 'luxon'; // Allowed
|
||||
import { createHash } from 'crypto'; // Allowed
|
||||
|
||||
import { MyHelper } from './helpers/MyHelper'; // Relative imports allowed
|
||||
import config from '../config'; // Relative imports allowed
|
||||
|
||||
export class MyNode implements INodeType {
|
||||
// ... implementation
|
||||
}
|
||||
```
|
||||
|
||||
## When This Rule Doesn't Apply
|
||||
|
||||
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.
|
||||
43
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/node-usable-as-tool.md
generated
vendored
Normal file
43
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/node-usable-as-tool.md
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# Ensure node classes have usableAsTool property (`@n8n/community-nodes/node-usable-as-tool`)
|
||||
|
||||
💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
|
||||
|
||||
🔧 This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix).
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
## Rule Details
|
||||
|
||||
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.
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ Incorrect
|
||||
|
||||
```typescript
|
||||
export class MyNode implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'My Node',
|
||||
name: 'myNode',
|
||||
group: ['input'],
|
||||
version: 1,
|
||||
// Missing usableAsTool property
|
||||
properties: [],
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Correct
|
||||
|
||||
```typescript
|
||||
export class MyNode implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'My Node',
|
||||
name: 'myNode',
|
||||
group: ['input'],
|
||||
version: 1,
|
||||
usableAsTool: true,
|
||||
properties: [],
|
||||
};
|
||||
}
|
||||
```
|
||||
52
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/package-name-convention.md
generated
vendored
Normal file
52
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/package-name-convention.md
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
# Enforce correct package naming convention for n8n community nodes (`@n8n/community-nodes/package-name-convention`)
|
||||
|
||||
💼 This rule is enabled in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
|
||||
|
||||
💡 This rule is manually fixable by [editor suggestions](https://eslint.org/docs/latest/use/core-concepts#rule-suggestions).
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
## Rule Details
|
||||
|
||||
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.
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ Incorrect
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-service-integration"
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "nodes-my-service"
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "@company/my-service"
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Correct
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "n8n-nodes-my-service"
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "@company/n8n-nodes-my-service"
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Use descriptive service names: `n8n-nodes-github` rather than `n8n-nodes-api`
|
||||
- For company packages, use your organization scope: `@mycompany/n8n-nodes-internal-tool`
|
||||
84
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/resource-operation-pattern.md
generated
vendored
Normal file
84
node_modules/@n8n/eslint-plugin-community-nodes/docs/rules/resource-operation-pattern.md
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
# Enforce proper resource/operation pattern for better UX in n8n nodes (`@n8n/community-nodes/resource-operation-pattern`)
|
||||
|
||||
⚠️ This rule _warns_ in the following configs: ✅ `recommended`, ☑️ `recommendedWithoutN8nCloudSupport`.
|
||||
|
||||
<!-- end auto-generated rule header -->
|
||||
|
||||
## Rule Details
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
## Examples
|
||||
|
||||
### ❌ Incorrect
|
||||
|
||||
```typescript
|
||||
export class MyNode implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'My Service',
|
||||
name: 'myService',
|
||||
properties: [
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
options: [
|
||||
{ name: 'Get User', value: 'getUser' },
|
||||
{ name: 'Create User', value: 'createUser' },
|
||||
{ name: 'Update User', value: 'updateUser' },
|
||||
{ name: 'Delete User', value: 'deleteUser' },
|
||||
{ name: 'Get Project', value: 'getProject' },
|
||||
{ name: 'Create Project', value: 'createProject' },
|
||||
{ name: 'List Files', value: 'listFiles' },
|
||||
// 7+ operations without resources - hard to navigate!
|
||||
],
|
||||
},
|
||||
// ... other properties
|
||||
],
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ Correct
|
||||
|
||||
```typescript
|
||||
export class MyNode implements INodeType {
|
||||
description: INodeTypeDescription = {
|
||||
displayName: 'My Service',
|
||||
name: 'myService',
|
||||
properties: [
|
||||
{
|
||||
displayName: 'Resource',
|
||||
name: 'resource',
|
||||
type: 'options',
|
||||
options: [
|
||||
{ name: 'User', value: 'user' },
|
||||
{ name: 'Project', value: 'project' },
|
||||
{ name: 'File', value: 'file' },
|
||||
],
|
||||
default: 'user',
|
||||
},
|
||||
{
|
||||
displayName: 'Operation',
|
||||
name: 'operation',
|
||||
type: 'options',
|
||||
displayOptions: {
|
||||
show: {
|
||||
resource: ['user'],
|
||||
},
|
||||
},
|
||||
options: [
|
||||
{ name: 'Get', value: 'get' },
|
||||
{ name: 'Create', value: 'create' },
|
||||
{ name: 'Update', value: 'update' },
|
||||
{ name: 'Delete', value: 'delete' },
|
||||
],
|
||||
default: 'get',
|
||||
},
|
||||
// ... similar operation blocks for 'project' and 'file' resources
|
||||
],
|
||||
};
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user