@n8n/eslint-plugin-community-nodes 0.14.0 → 0.16.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 (83) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/README.md +7 -0
  3. package/dist/plugin.d.ts +48 -0
  4. package/dist/plugin.d.ts.map +1 -1
  5. package/dist/plugin.js +16 -0
  6. package/dist/plugin.js.map +1 -1
  7. package/dist/rules/cred-class-name-suffix.d.ts +2 -0
  8. package/dist/rules/cred-class-name-suffix.d.ts.map +1 -0
  9. package/dist/rules/cred-class-name-suffix.js +53 -0
  10. package/dist/rules/cred-class-name-suffix.js.map +1 -0
  11. package/dist/rules/cred-class-oauth2-naming.d.ts +2 -0
  12. package/dist/rules/cred-class-oauth2-naming.d.ts.map +1 -0
  13. package/dist/rules/cred-class-oauth2-naming.js +96 -0
  14. package/dist/rules/cred-class-oauth2-naming.js.map +1 -0
  15. package/dist/rules/index.d.ts +11 -1
  16. package/dist/rules/index.d.ts.map +1 -1
  17. package/dist/rules/index.js +16 -0
  18. package/dist/rules/index.js.map +1 -1
  19. package/dist/rules/n8n-object-validation.d.ts +5 -0
  20. package/dist/rules/n8n-object-validation.d.ts.map +1 -0
  21. package/dist/rules/n8n-object-validation.js +148 -0
  22. package/dist/rules/n8n-object-validation.js.map +1 -0
  23. package/dist/rules/no-builder-hint-leakage.d.ts +7 -0
  24. package/dist/rules/no-builder-hint-leakage.d.ts.map +1 -0
  25. package/dist/rules/no-builder-hint-leakage.js +99 -0
  26. package/dist/rules/no-builder-hint-leakage.js.map +1 -0
  27. package/dist/rules/no-overrides-field.js +1 -1
  28. package/dist/rules/no-overrides-field.js.map +1 -1
  29. package/dist/rules/no-runtime-dependencies.d.ts +2 -0
  30. package/dist/rules/no-runtime-dependencies.d.ts.map +1 -0
  31. package/dist/rules/no-runtime-dependencies.js +41 -0
  32. package/dist/rules/no-runtime-dependencies.js.map +1 -0
  33. package/dist/rules/no-template-placeholders.d.ts +2 -0
  34. package/dist/rules/no-template-placeholders.d.ts.map +1 -0
  35. package/dist/rules/no-template-placeholders.js +57 -0
  36. package/dist/rules/no-template-placeholders.js.map +1 -0
  37. package/dist/rules/node-operation-error-itemindex.d.ts +12 -0
  38. package/dist/rules/node-operation-error-itemindex.d.ts.map +1 -0
  39. package/dist/rules/node-operation-error-itemindex.js +184 -0
  40. package/dist/rules/node-operation-error-itemindex.js.map +1 -0
  41. package/dist/rules/valid-credential-references.d.ts +2 -0
  42. package/dist/rules/valid-credential-references.d.ts.map +1 -0
  43. package/dist/rules/valid-credential-references.js +77 -0
  44. package/dist/rules/valid-credential-references.js.map +1 -0
  45. package/dist/rules/webhook-lifecycle-complete.d.ts +1 -1
  46. package/dist/rules/webhook-lifecycle-complete.d.ts.map +1 -1
  47. package/dist/rules/webhook-lifecycle-complete.js +8 -0
  48. package/dist/rules/webhook-lifecycle-complete.js.map +1 -1
  49. package/dist/utils/ast-utils.d.ts.map +1 -1
  50. package/dist/utils/ast-utils.js +5 -1
  51. package/dist/utils/ast-utils.js.map +1 -1
  52. package/docs/rules/cred-class-name-suffix.md +46 -0
  53. package/docs/rules/cred-class-oauth2-naming.md +68 -0
  54. package/docs/rules/n8n-object-validation.md +93 -0
  55. package/docs/rules/no-overrides-field.md +5 -5
  56. package/docs/rules/no-runtime-dependencies.md +58 -0
  57. package/docs/rules/no-template-placeholders.md +51 -0
  58. package/docs/rules/node-operation-error-itemindex.md +81 -0
  59. package/docs/rules/valid-credential-references.md +78 -0
  60. package/package.json +3 -3
  61. package/src/plugin.ts +16 -0
  62. package/src/rules/cred-class-name-suffix.test.ts +74 -0
  63. package/src/rules/cred-class-name-suffix.ts +57 -0
  64. package/src/rules/cred-class-oauth2-naming.test.ts +197 -0
  65. package/src/rules/cred-class-oauth2-naming.ts +118 -0
  66. package/src/rules/index.ts +16 -0
  67. package/src/rules/n8n-object-validation.test.ts +202 -0
  68. package/src/rules/n8n-object-validation.ts +200 -0
  69. package/src/rules/no-builder-hint-leakage.test.ts +84 -0
  70. package/src/rules/no-builder-hint-leakage.ts +112 -0
  71. package/src/rules/no-overrides-field.ts +1 -1
  72. package/src/rules/no-runtime-dependencies.test.ts +50 -0
  73. package/src/rules/no-runtime-dependencies.ts +50 -0
  74. package/src/rules/no-template-placeholders.test.ts +135 -0
  75. package/src/rules/no-template-placeholders.ts +68 -0
  76. package/src/rules/node-operation-error-itemindex.test.ts +280 -0
  77. package/src/rules/node-operation-error-itemindex.ts +223 -0
  78. package/src/rules/valid-credential-references.test.ts +230 -0
  79. package/src/rules/valid-credential-references.ts +105 -0
  80. package/src/rules/webhook-lifecycle-complete.test.ts +5 -0
  81. package/src/rules/webhook-lifecycle-complete.ts +10 -0
  82. package/src/utils/ast-utils.ts +5 -1
  83. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,10 +1,14 @@
1
1
  import { AiNodePackageJsonRule } from './ai-node-package-json.js';
2
2
  import { CredClassFieldIconMissingRule } from './cred-class-field-icon-missing.js';
3
+ import { CredClassNameSuffixRule } from './cred-class-name-suffix.js';
4
+ import { CredClassOAuth2NamingRule } from './cred-class-oauth2-naming.js';
3
5
  import { CredentialDocumentationUrlRule } from './credential-documentation-url.js';
4
6
  import { CredentialPasswordFieldRule } from './credential-password-field.js';
5
7
  import { CredentialTestRequiredRule } from './credential-test-required.js';
6
8
  import { IconValidationRule } from './icon-validation.js';
7
9
  import { MissingPairedItemRule } from './missing-paired-item.js';
10
+ import { N8nObjectValidationRule } from './n8n-object-validation.js';
11
+ import { NoBuilderHintLeakageRule } from './no-builder-hint-leakage.js';
8
12
  import { NoCredentialReuseRule } from './no-credential-reuse.js';
9
13
  import { NoDeprecatedWorkflowFunctionsRule } from './no-deprecated-workflow-functions.js';
10
14
  import { NoForbiddenLifecycleScriptsRule } from './no-forbidden-lifecycle-scripts.js';
@@ -12,8 +16,11 @@ import { NoHttpRequestWithManualAuthRule } from './no-http-request-with-manual-a
12
16
  import { NoOverridesFieldRule } from './no-overrides-field.js';
13
17
  import { NoRestrictedGlobalsRule } from './no-restricted-globals.js';
14
18
  import { NoRestrictedImportsRule } from './no-restricted-imports.js';
19
+ import { NoRuntimeDependenciesRule } from './no-runtime-dependencies.js';
20
+ import { NoTemplatePlaceholdersRule } from './no-template-placeholders.js';
15
21
  import { NodeClassDescriptionIconMissingRule } from './node-class-description-icon-missing.js';
16
22
  import { NodeConnectionTypeLiteralRule } from './node-connection-type-literal.js';
23
+ import { NodeOperationErrorItemIndexRule } from './node-operation-error-itemindex.js';
17
24
  import { NodeUsableAsToolRule } from './node-usable-as-tool.js';
18
25
  import { OptionsSortedAlphabeticallyRule } from './options-sorted-alphabetically.js';
19
26
  import { PackageNameConventionRule } from './package-name-convention.js';
@@ -22,6 +29,7 @@ import { RequireContinueOnFailRule } from './require-continue-on-fail.js';
22
29
  import { RequireNodeApiErrorRule } from './require-node-api-error.js';
23
30
  import { RequireNodeDescriptionFieldsRule } from './require-node-description-fields.js';
24
31
  import { ResourceOperationPatternRule } from './resource-operation-pattern.js';
32
+ import { ValidCredentialReferencesRule } from './valid-credential-references.js';
25
33
  import { ValidPeerDependenciesRule } from './valid-peer-dependencies.js';
26
34
  import { WebhookLifecycleCompleteRule } from './webhook-lifecycle-complete.js';
27
35
  export const rules = {
@@ -38,17 +46,25 @@ export const rules = {
38
46
  'no-forbidden-lifecycle-scripts': NoForbiddenLifecycleScriptsRule,
39
47
  'no-http-request-with-manual-auth': NoHttpRequestWithManualAuthRule,
40
48
  'no-overrides-field': NoOverridesFieldRule,
49
+ 'no-runtime-dependencies': NoRuntimeDependenciesRule,
50
+ 'no-template-placeholders': NoTemplatePlaceholdersRule,
41
51
  'icon-validation': IconValidationRule,
42
52
  'resource-operation-pattern': ResourceOperationPatternRule,
43
53
  'credential-documentation-url': CredentialDocumentationUrlRule,
44
54
  'node-class-description-icon-missing': NodeClassDescriptionIconMissingRule,
45
55
  'cred-class-field-icon-missing': CredClassFieldIconMissingRule,
56
+ 'cred-class-name-suffix': CredClassNameSuffixRule,
57
+ 'cred-class-oauth2-naming': CredClassOAuth2NamingRule,
46
58
  'node-connection-type-literal': NodeConnectionTypeLiteralRule,
59
+ 'node-operation-error-itemindex': NodeOperationErrorItemIndexRule,
47
60
  'missing-paired-item': MissingPairedItemRule,
61
+ 'no-builder-hint-leakage': NoBuilderHintLeakageRule,
62
+ 'n8n-object-validation': N8nObjectValidationRule,
48
63
  'require-community-node-keyword': RequireCommunityNodeKeywordRule,
49
64
  'require-continue-on-fail': RequireContinueOnFailRule,
50
65
  'require-node-api-error': RequireNodeApiErrorRule,
51
66
  'require-node-description-fields': RequireNodeDescriptionFieldsRule,
67
+ 'valid-credential-references': ValidCredentialReferencesRule,
52
68
  'valid-peer-dependencies': ValidPeerDependenciesRule,
53
69
  'webhook-lifecycle-complete': WebhookLifecycleCompleteRule,
54
70
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AACnF,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,iCAAiC,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAE,+BAA+B,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,EAAE,+BAA+B,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,mCAAmC,EAAE,MAAM,0CAA0C,CAAC;AAC/F,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,+BAA+B,EAAE,MAAM,oCAAoC,CAAC;AACrF,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,+BAA+B,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,gCAAgC,EAAE,MAAM,sCAAsC,CAAC;AACxF,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAE/E,MAAM,CAAC,MAAM,KAAK,GAAG;IACpB,sBAAsB,EAAE,qBAAqB;IAC7C,uBAAuB,EAAE,uBAAuB;IAChD,uBAAuB,EAAE,uBAAuB;IAChD,2BAA2B,EAAE,2BAA2B;IACxD,kCAAkC,EAAE,iCAAiC;IACrE,qBAAqB,EAAE,oBAAoB;IAC3C,+BAA+B,EAAE,+BAA+B;IAChE,yBAAyB,EAAE,yBAAyB;IACpD,0BAA0B,EAAE,0BAA0B;IACtD,qBAAqB,EAAE,qBAAqB;IAC5C,gCAAgC,EAAE,+BAA+B;IACjE,kCAAkC,EAAE,+BAA+B;IACnE,oBAAoB,EAAE,oBAAoB;IAC1C,iBAAiB,EAAE,kBAAkB;IACrC,4BAA4B,EAAE,4BAA4B;IAC1D,8BAA8B,EAAE,8BAA8B;IAC9D,qCAAqC,EAAE,mCAAmC;IAC1E,+BAA+B,EAAE,6BAA6B;IAC9D,8BAA8B,EAAE,6BAA6B;IAC7D,qBAAqB,EAAE,qBAAqB;IAC5C,gCAAgC,EAAE,+BAA+B;IACjE,0BAA0B,EAAE,yBAAyB;IACrD,wBAAwB,EAAE,uBAAuB;IACjD,iCAAiC,EAAE,gCAAgC;IACnE,yBAAyB,EAAE,yBAAyB;IACpD,4BAA4B,EAAE,4BAA4B;CAClB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,8BAA8B,EAAE,MAAM,mCAAmC,CAAC;AACnF,OAAO,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAC7E,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,iCAAiC,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAE,+BAA+B,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,EAAE,+BAA+B,EAAE,MAAM,uCAAuC,CAAC;AACxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,mCAAmC,EAAE,MAAM,0CAA0C,CAAC;AAC/F,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAE,+BAA+B,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,+BAA+B,EAAE,MAAM,oCAAoC,CAAC;AACrF,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,+BAA+B,EAAE,MAAM,qCAAqC,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,gCAAgC,EAAE,MAAM,sCAAsC,CAAC;AACxF,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAC/E,OAAO,EAAE,6BAA6B,EAAE,MAAM,kCAAkC,CAAC;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAE/E,MAAM,CAAC,MAAM,KAAK,GAAG;IACpB,sBAAsB,EAAE,qBAAqB;IAC7C,uBAAuB,EAAE,uBAAuB;IAChD,uBAAuB,EAAE,uBAAuB;IAChD,2BAA2B,EAAE,2BAA2B;IACxD,kCAAkC,EAAE,iCAAiC;IACrE,qBAAqB,EAAE,oBAAoB;IAC3C,+BAA+B,EAAE,+BAA+B;IAChE,yBAAyB,EAAE,yBAAyB;IACpD,0BAA0B,EAAE,0BAA0B;IACtD,qBAAqB,EAAE,qBAAqB;IAC5C,gCAAgC,EAAE,+BAA+B;IACjE,kCAAkC,EAAE,+BAA+B;IACnE,oBAAoB,EAAE,oBAAoB;IAC1C,yBAAyB,EAAE,yBAAyB;IACpD,0BAA0B,EAAE,0BAA0B;IACtD,iBAAiB,EAAE,kBAAkB;IACrC,4BAA4B,EAAE,4BAA4B;IAC1D,8BAA8B,EAAE,8BAA8B;IAC9D,qCAAqC,EAAE,mCAAmC;IAC1E,+BAA+B,EAAE,6BAA6B;IAC9D,wBAAwB,EAAE,uBAAuB;IACjD,0BAA0B,EAAE,yBAAyB;IACrD,8BAA8B,EAAE,6BAA6B;IAC7D,gCAAgC,EAAE,+BAA+B;IACjE,qBAAqB,EAAE,qBAAqB;IAC5C,yBAAyB,EAAE,wBAAwB;IACnD,uBAAuB,EAAE,uBAAuB;IAChD,gCAAgC,EAAE,+BAA+B;IACjE,0BAA0B,EAAE,yBAAyB;IACrD,wBAAwB,EAAE,uBAAuB;IACjD,iCAAiC,EAAE,gCAAgC;IACnE,6BAA6B,EAAE,6BAA6B;IAC5D,yBAAyB,EAAE,yBAAyB;IACpD,4BAA4B,EAAE,4BAA4B;CAClB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ type MessageIds = 'missingN8nObject' | 'wrongLocationApiVersion' | 'missingNodesApiVersion' | 'invalidNodesApiVersion' | 'missingN8nNodes' | 'n8nNodesNotArray' | 'emptyN8nNodes' | 'n8nCredentialsNotArray' | 'nodePathNotString' | 'nodePathNotInDist' | 'credentialPathNotString' | 'credentialPathNotInDist' | 'invalidStrict';
3
+ export declare const N8nObjectValidationRule: TSESLint.RuleModule<MessageIds, [], unknown, TSESLint.RuleListener>;
4
+ export {};
5
+ //# sourceMappingURL=n8n-object-validation.d.ts.map
@@ -0,0 +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,qEA8ElC,CAAC"}
@@ -0,0 +1,148 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
+ import { createRule, findJsonProperty, getTopLevelObjectInJson } from '../utils/index.js';
3
+ export const N8nObjectValidationRule = createRule({
4
+ name: 'n8n-object-validation',
5
+ meta: {
6
+ type: 'problem',
7
+ docs: {
8
+ description: 'Validate the structure of the "n8n" object in community node package.json (required keys, types, and dist/ paths)',
9
+ },
10
+ messages: {
11
+ missingN8nObject: 'Community node package.json must contain an "n8n" object describing the package.',
12
+ 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 }}.',
15
+ missingN8nNodes: 'The "n8n" object must declare "nodes" as an array of "dist/" paths.',
16
+ n8nNodesNotArray: '"n8n.nodes" must be an array of "dist/" paths.',
17
+ emptyN8nNodes: '"n8n.nodes" must contain at least one path.',
18
+ n8nCredentialsNotArray: '"n8n.credentials" must be an array of "dist/" paths.',
19
+ nodePathNotString: 'Each entry in "n8n.nodes" must be a string starting with "dist/".',
20
+ nodePathNotInDist: 'Path "{{ path }}" in "n8n.nodes" must start with "dist/" (compiled output).',
21
+ credentialPathNotString: 'Each entry in "n8n.credentials" must be a string starting with "dist/".',
22
+ credentialPathNotInDist: 'Path "{{ path }}" in "n8n.credentials" must start with "dist/" (compiled output).',
23
+ invalidStrict: '"n8n.strict" must be a boolean, got {{ value }}.',
24
+ },
25
+ schema: [],
26
+ },
27
+ defaultOptions: [],
28
+ create(context) {
29
+ if (!context.filename.endsWith('package.json')) {
30
+ return {};
31
+ }
32
+ return {
33
+ ObjectExpression(node) {
34
+ const root = getTopLevelObjectInJson(node);
35
+ if (!root)
36
+ return;
37
+ // Catch n8nNodesApiVersion accidentally placed at root level.
38
+ const rootApiVersionProp = findJsonProperty(root, 'n8nNodesApiVersion');
39
+ if (rootApiVersionProp) {
40
+ context.report({
41
+ node: rootApiVersionProp,
42
+ messageId: 'wrongLocationApiVersion',
43
+ });
44
+ }
45
+ const n8nProp = findJsonProperty(root, 'n8n');
46
+ if (!n8nProp) {
47
+ context.report({
48
+ node: root,
49
+ messageId: 'missingN8nObject',
50
+ });
51
+ return;
52
+ }
53
+ if (n8nProp.value.type !== AST_NODE_TYPES.ObjectExpression) {
54
+ context.report({
55
+ node: n8nProp,
56
+ messageId: 'missingN8nObject',
57
+ });
58
+ return;
59
+ }
60
+ const n8nObject = n8nProp.value;
61
+ validateApiVersion(context, n8nObject);
62
+ validateNodes(context, n8nObject);
63
+ validateCredentials(context, n8nObject);
64
+ validateStrict(context, n8nObject);
65
+ },
66
+ };
67
+ },
68
+ });
69
+ function validateApiVersion(context, n8nObject) {
70
+ const apiVersionProp = findJsonProperty(n8nObject, 'n8nNodesApiVersion');
71
+ if (!apiVersionProp) {
72
+ context.report({ node: n8nObject, messageId: 'missingNodesApiVersion' });
73
+ return;
74
+ }
75
+ const valueNode = apiVersionProp.value;
76
+ if (valueNode.type !== AST_NODE_TYPES.Literal || !isPositiveInteger(valueNode.value)) {
77
+ context.report({
78
+ node: apiVersionProp,
79
+ messageId: 'invalidNodesApiVersion',
80
+ data: {
81
+ value: String(valueNode.type === AST_NODE_TYPES.Literal ? valueNode.value : 'non-literal'),
82
+ },
83
+ });
84
+ }
85
+ }
86
+ function validateStrict(context, n8nObject) {
87
+ const strictProp = findJsonProperty(n8nObject, 'strict');
88
+ if (!strictProp)
89
+ return; // optional
90
+ const valueNode = strictProp.value;
91
+ if (valueNode.type !== AST_NODE_TYPES.Literal || typeof valueNode.value !== 'boolean') {
92
+ context.report({
93
+ node: strictProp,
94
+ messageId: 'invalidStrict',
95
+ data: {
96
+ value: String(valueNode.type === AST_NODE_TYPES.Literal ? valueNode.value : 'non-literal'),
97
+ },
98
+ });
99
+ }
100
+ }
101
+ function validateNodes(context, n8nObject) {
102
+ const nodesProp = findJsonProperty(n8nObject, 'nodes');
103
+ if (!nodesProp) {
104
+ context.report({ node: n8nObject, messageId: 'missingN8nNodes' });
105
+ return;
106
+ }
107
+ if (nodesProp.value.type !== AST_NODE_TYPES.ArrayExpression) {
108
+ context.report({ node: nodesProp, messageId: 'n8nNodesNotArray' });
109
+ return;
110
+ }
111
+ const elements = nodesProp.value.elements;
112
+ if (elements.length === 0) {
113
+ context.report({ node: nodesProp, messageId: 'emptyN8nNodes' });
114
+ return;
115
+ }
116
+ validatePathArray(context, elements, 'nodePathNotString', 'nodePathNotInDist');
117
+ }
118
+ function validateCredentials(context, n8nObject) {
119
+ const credentialsProp = findJsonProperty(n8nObject, 'credentials');
120
+ if (!credentialsProp)
121
+ return; // optional
122
+ if (credentialsProp.value.type !== AST_NODE_TYPES.ArrayExpression) {
123
+ context.report({ node: credentialsProp, messageId: 'n8nCredentialsNotArray' });
124
+ return;
125
+ }
126
+ validatePathArray(context, credentialsProp.value.elements, 'credentialPathNotString', 'credentialPathNotInDist');
127
+ }
128
+ function validatePathArray(context, elements, notStringMessageId, notInDistMessageId) {
129
+ for (const element of elements) {
130
+ if (!element)
131
+ continue;
132
+ if (element.type !== AST_NODE_TYPES.Literal || typeof element.value !== 'string') {
133
+ context.report({ node: element, messageId: notStringMessageId });
134
+ continue;
135
+ }
136
+ if (!element.value.startsWith('dist/')) {
137
+ context.report({
138
+ node: element,
139
+ messageId: notInDistMessageId,
140
+ data: { path: element.value },
141
+ });
142
+ }
143
+ }
144
+ }
145
+ function isPositiveInteger(value) {
146
+ return typeof value === 'number' && Number.isInteger(value) && value > 0;
147
+ }
148
+ //# sourceMappingURL=n8n-object-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"n8n-object-validation.js","sourceRoot":"","sources":["../../src/rules/n8n-object-validation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ type Options = [{
2
+ scope?: 'builderHint' | 'all';
3
+ }];
4
+ type MessageIds = 'wireExpression' | 'connectionTypeLiteral';
5
+ export declare const NoBuilderHintLeakageRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<MessageIds, Options, unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
6
+ export {};
7
+ //# sourceMappingURL=no-builder-hint-leakage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-builder-hint-leakage.d.ts","sourceRoot":"","sources":["../../src/rules/no-builder-hint-leakage.ts"],"names":[],"mappings":"AAaA,KAAK,OAAO,GAAG,CAAC;IAAE,KAAK,CAAC,EAAE,aAAa,GAAG,KAAK,CAAA;CAAE,CAAC,CAAC;AACnD,KAAK,UAAU,GAAG,gBAAgB,GAAG,uBAAuB,CAAC;AAyB7D,eAAO,MAAM,wBAAwB,kJAwEnC,CAAC"}
@@ -0,0 +1,99 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
+ import { createRule } from '../utils/index.js';
3
+ const WIRE_EXPRESSION_RE = /={{/;
4
+ const CONNECTION_NAME_GROUP = 'agent|chain|document|embedding|languageModel|memory|outputParser|retriever|reranker|textSplitter|tool|vectorStore';
5
+ const CONNECTION_NAME_RE = new RegExp(`\\bai_(${CONNECTION_NAME_GROUP})\\b`, 'g');
6
+ // Strings that are *exactly* a connection name are structured data values,
7
+ // not prose, so they're allowed (e.g. `connectionType: 'ai_languageModel'`).
8
+ const EXACT_CONNECTION_NAME_RE = new RegExp(`^ai_(${CONNECTION_NAME_GROUP})$`);
9
+ function isPropertyKey(node) {
10
+ const parent = node.parent;
11
+ return parent?.type === AST_NODE_TYPES.Property && parent.key === node;
12
+ }
13
+ function isInsideBuilderHintValue(node) {
14
+ let current = node;
15
+ let parent = current.parent;
16
+ while (parent) {
17
+ if (parent.type === AST_NODE_TYPES.Property &&
18
+ parent.value === current &&
19
+ ((parent.key.type === AST_NODE_TYPES.Identifier && parent.key.name === 'builderHint') ||
20
+ (parent.key.type === AST_NODE_TYPES.Literal && parent.key.value === 'builderHint'))) {
21
+ return true;
22
+ }
23
+ current = parent;
24
+ parent = current.parent;
25
+ }
26
+ return false;
27
+ }
28
+ export const NoBuilderHintLeakageRule = createRule({
29
+ name: 'no-builder-hint-leakage',
30
+ meta: {
31
+ type: 'problem',
32
+ docs: {
33
+ description: 'Disallow wire-format expression syntax (={{...}}) and NodeConnectionType string literals in builderHint texts and AI-builder prompts. Use expr() and SDK-canonical references instead.',
34
+ },
35
+ messages: {
36
+ wireExpression: 'Wire-format expression syntax leaks into {{ ctx }}. Use the expr() SDK helper instead.',
37
+ connectionTypeLiteral: 'NodeConnectionType literal "{{ value }}" leaks wire format into {{ ctx }}. Refer to the SDK helper instead (e.g. languageModel(), tool(), memory()).',
38
+ },
39
+ schema: [
40
+ {
41
+ type: 'object',
42
+ description: 'Configures where the rule scans for forbidden patterns. Default `builderHint` only checks string values inside builderHint property values; `all` checks every string in the file (used for AI-builder prompts).',
43
+ properties: {
44
+ scope: {
45
+ type: 'string',
46
+ enum: ['builderHint', 'all'],
47
+ description: '`builderHint` (default): only flag strings inside builderHint property values. `all`: flag every string literal/template in the file.',
48
+ },
49
+ },
50
+ additionalProperties: false,
51
+ },
52
+ ],
53
+ },
54
+ defaultOptions: [{}],
55
+ create(context, [options]) {
56
+ const scope = options.scope ?? 'builderHint';
57
+ const ctx = scope === 'all' ? 'AI-builder prompt' : 'builderHint';
58
+ function reportFor(node, str) {
59
+ if (WIRE_EXPRESSION_RE.test(str)) {
60
+ context.report({ node, messageId: 'wireExpression', data: { ctx } });
61
+ }
62
+ if (EXACT_CONNECTION_NAME_RE.test(str))
63
+ return;
64
+ CONNECTION_NAME_RE.lastIndex = 0;
65
+ let match;
66
+ while ((match = CONNECTION_NAME_RE.exec(str)) !== null) {
67
+ context.report({
68
+ node,
69
+ messageId: 'connectionTypeLiteral',
70
+ data: { value: match[0], ctx },
71
+ });
72
+ }
73
+ }
74
+ function shouldCheck(node) {
75
+ if (isPropertyKey(node))
76
+ return false;
77
+ if (scope === 'all')
78
+ return true;
79
+ return isInsideBuilderHintValue(node);
80
+ }
81
+ return {
82
+ Literal(node) {
83
+ if (typeof node.value !== 'string')
84
+ return;
85
+ if (!shouldCheck(node))
86
+ return;
87
+ reportFor(node, node.value);
88
+ },
89
+ TemplateLiteral(node) {
90
+ if (!shouldCheck(node))
91
+ return;
92
+ for (const quasi of node.quasis) {
93
+ reportFor(quasi, quasi.value.cooked ?? quasi.value.raw);
94
+ }
95
+ },
96
+ };
97
+ },
98
+ });
99
+ //# sourceMappingURL=no-builder-hint-leakage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-builder-hint-leakage.js","sourceRoot":"","sources":["../../src/rules/no-builder-hint-leakage.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ export const NoOverridesFieldRule = createRule({
8
8
  description: 'Ban the "overrides" field in community node package.json',
9
9
  },
10
10
  messages: {
11
- overridesForbidden: 'The "overrides" field is not allowed in community node packages. Dependency overrides can introduce incompatible versions of shared libraries into the n8n runtime and cause conflicts with other nodes.',
11
+ overridesForbidden: 'The "overrides" field is not allowed in community node packages. Each community package installs into an isolated dependency tree, so overrides do not affect other nodes or n8n core in practice they are copy-pasted boilerplate with no useful effect. Use the helpers on the execute context (this.helpers.httpRequest, etc.) instead; most community nodes do not need third-party runtime libraries.',
12
12
  },
13
13
  schema: [],
14
14
  },
@@ -1 +1 @@
1
- {"version":3,"file":"no-overrides-field.js","sourceRoot":"","sources":["../../src/rules/no-overrides-field.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC;IAC9C,IAAI,EAAE,oBAAoB;IAC1B,IAAI,EAAE;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACL,WAAW,EAAE,0DAA0D;SACvE;QACD,QAAQ,EAAE;YACT,kBAAkB,EACjB,0MAA0M;SAC3M;QACD,MAAM,EAAE,EAAE;KACV;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACb,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,CAAC;QACX,CAAC;QAED,OAAO;YACN,gBAAgB,CAAC,IAA+B;gBAC/C,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,cAAc,CAAC,mBAAmB,EAAE,CAAC;oBAC9D,OAAO;gBACR,CAAC;gBAED,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;gBAC1D,IAAI,CAAC,aAAa,EAAE,CAAC;oBACpB,OAAO;gBACR,CAAC;gBAED,OAAO,CAAC,MAAM,CAAC;oBACd,IAAI,EAAE,aAAa;oBACnB,SAAS,EAAE,oBAAoB;iBAC/B,CAAC,CAAC;YACJ,CAAC;SACD,CAAC;IACH,CAAC;CACD,CAAC,CAAC"}
1
+ {"version":3,"file":"no-overrides-field.js","sourceRoot":"","sources":["../../src/rules/no-overrides-field.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAAC;IAC9C,IAAI,EAAE,oBAAoB;IAC1B,IAAI,EAAE;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACL,WAAW,EAAE,0DAA0D;SACvE;QACD,QAAQ,EAAE;YACT,kBAAkB,EACjB,8YAA8Y;SAC/Y;QACD,MAAM,EAAE,EAAE;KACV;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACb,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,CAAC;QACX,CAAC;QAED,OAAO;YACN,gBAAgB,CAAC,IAA+B;gBAC/C,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,cAAc,CAAC,mBAAmB,EAAE,CAAC;oBAC9D,OAAO;gBACR,CAAC;gBAED,MAAM,aAAa,GAAG,gBAAgB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;gBAC1D,IAAI,CAAC,aAAa,EAAE,CAAC;oBACpB,OAAO;gBACR,CAAC;gBAED,OAAO,CAAC,MAAM,CAAC;oBACd,IAAI,EAAE,aAAa;oBACnB,SAAS,EAAE,oBAAoB;iBAC/B,CAAC,CAAC;YACJ,CAAC;SACD,CAAC;IACH,CAAC;CACD,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const NoRuntimeDependenciesRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"runtimeDependenciesForbidden", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
2
+ //# sourceMappingURL=no-runtime-dependencies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-runtime-dependencies.d.ts","sourceRoot":"","sources":["../../src/rules/no-runtime-dependencies.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,yBAAyB,iKA4CpC,CAAC"}
@@ -0,0 +1,41 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
+ import { createRule, findJsonProperty } from '../utils/index.js';
3
+ export const NoRuntimeDependenciesRule = createRule({
4
+ name: 'no-runtime-dependencies',
5
+ meta: {
6
+ type: 'problem',
7
+ docs: {
8
+ description: 'Disallow non-empty "dependencies" in community node package.json',
9
+ },
10
+ messages: {
11
+ runtimeDependenciesForbidden: 'The "dependencies" field must be empty or absent in community node packages. Runtime dependencies get bundled into the n8n instance and can conflict with other nodes or the n8n runtime itself. Move shared libraries to "peerDependencies" or bundle them into your build artifact.',
12
+ },
13
+ schema: [],
14
+ },
15
+ defaultOptions: [],
16
+ create(context) {
17
+ if (!context.filename.endsWith('package.json')) {
18
+ return {};
19
+ }
20
+ return {
21
+ ObjectExpression(node) {
22
+ if (node.parent?.type !== AST_NODE_TYPES.ExpressionStatement) {
23
+ return;
24
+ }
25
+ const depsProp = findJsonProperty(node, 'dependencies');
26
+ if (!depsProp) {
27
+ return;
28
+ }
29
+ if (depsProp.value.type !== AST_NODE_TYPES.ObjectExpression ||
30
+ depsProp.value.properties.length === 0) {
31
+ return;
32
+ }
33
+ context.report({
34
+ node: depsProp,
35
+ messageId: 'runtimeDependenciesForbidden',
36
+ });
37
+ },
38
+ };
39
+ },
40
+ });
41
+ //# sourceMappingURL=no-runtime-dependencies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-runtime-dependencies.js","sourceRoot":"","sources":["../../src/rules/no-runtime-dependencies.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,CAAC,MAAM,yBAAyB,GAAG,UAAU,CAAC;IACnD,IAAI,EAAE,yBAAyB;IAC/B,IAAI,EAAE;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACL,WAAW,EAAE,kEAAkE;SAC/E;QACD,QAAQ,EAAE;YACT,4BAA4B,EAC3B,uRAAuR;SACxR;QACD,MAAM,EAAE,EAAE;KACV;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACb,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,CAAC;QACX,CAAC;QAED,OAAO;YACN,gBAAgB,CAAC,IAA+B;gBAC/C,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,cAAc,CAAC,mBAAmB,EAAE,CAAC;oBAC9D,OAAO;gBACR,CAAC;gBAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;gBACxD,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACf,OAAO;gBACR,CAAC;gBAED,IACC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,gBAAgB;oBACvD,QAAQ,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EACrC,CAAC;oBACF,OAAO;gBACR,CAAC;gBAED,OAAO,CAAC,MAAM,CAAC;oBACd,IAAI,EAAE,QAAQ;oBACd,SAAS,EAAE,8BAA8B;iBACzC,CAAC,CAAC;YACJ,CAAC;SACD,CAAC;IACH,CAAC;CACD,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const NoTemplatePlaceholdersRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"unresolvedPlaceholder", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
2
+ //# sourceMappingURL=no-template-placeholders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-template-placeholders.d.ts","sourceRoot":"","sources":["../../src/rules/no-template-placeholders.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,0BAA0B,0JA+CrC,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
+ import { createRule } from '../utils/index.js';
3
+ const ANGLE_PLACEHOLDER = /<[^<>\n]+?>/;
4
+ const MUSTACHE_PLACEHOLDER = /\{\{[^{}\n]+?\}\}/;
5
+ function findPlaceholder(value) {
6
+ const angleMatch = ANGLE_PLACEHOLDER.exec(value);
7
+ if (angleMatch) {
8
+ return { pattern: angleMatch[0], type: 'angle' };
9
+ }
10
+ const mustacheMatch = MUSTACHE_PLACEHOLDER.exec(value);
11
+ if (mustacheMatch) {
12
+ return { pattern: mustacheMatch[0], type: 'mustache' };
13
+ }
14
+ return null;
15
+ }
16
+ export const NoTemplatePlaceholdersRule = createRule({
17
+ name: 'no-template-placeholders',
18
+ meta: {
19
+ type: 'problem',
20
+ docs: {
21
+ description: 'Disallow unresolved template placeholders in package.json',
22
+ },
23
+ messages: {
24
+ unresolvedPlaceholder: 'String value contains an unresolved template placeholder "{{ pattern }}". Replace it with a real value before publishing.',
25
+ },
26
+ schema: [],
27
+ },
28
+ defaultOptions: [],
29
+ create(context) {
30
+ if (!context.filename.endsWith('package.json')) {
31
+ return {};
32
+ }
33
+ return {
34
+ Literal(node) {
35
+ if (typeof node.value !== 'string') {
36
+ return;
37
+ }
38
+ // Skip property keys — only flag values.
39
+ if (node.parent?.type === AST_NODE_TYPES.Property &&
40
+ node.parent.key === node &&
41
+ !node.parent.computed) {
42
+ return;
43
+ }
44
+ const placeholder = findPlaceholder(node.value);
45
+ if (!placeholder) {
46
+ return;
47
+ }
48
+ context.report({
49
+ node,
50
+ messageId: 'unresolvedPlaceholder',
51
+ data: { pattern: placeholder.pattern },
52
+ });
53
+ },
54
+ };
55
+ },
56
+ });
57
+ //# sourceMappingURL=no-template-placeholders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-template-placeholders.js","sourceRoot":"","sources":["../../src/rules/no-template-placeholders.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAE/C,MAAM,iBAAiB,GAAG,aAAa,CAAC;AACxC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AAEjD,SAAS,eAAe,CAAC,KAAa;IACrC,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjD,IAAI,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAClD,CAAC;IACD,MAAM,aAAa,GAAG,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACvD,IAAI,aAAa,EAAE,CAAC;QACnB,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;IACxD,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,CAAC,MAAM,0BAA0B,GAAG,UAAU,CAAC;IACpD,IAAI,EAAE,0BAA0B;IAChC,IAAI,EAAE;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACL,WAAW,EAAE,2DAA2D;SACxE;QACD,QAAQ,EAAE;YACT,qBAAqB,EACpB,2HAA2H;SAC5H;QACD,MAAM,EAAE,EAAE;KACV;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACb,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YAChD,OAAO,EAAE,CAAC;QACX,CAAC;QAED,OAAO;YACN,OAAO,CAAC,IAAsB;gBAC7B,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACpC,OAAO;gBACR,CAAC;gBAED,yCAAyC;gBACzC,IACC,IAAI,CAAC,MAAM,EAAE,IAAI,KAAK,cAAc,CAAC,QAAQ;oBAC7C,IAAI,CAAC,MAAM,CAAC,GAAG,KAAK,IAAI;oBACxB,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EACpB,CAAC;oBACF,OAAO;gBACR,CAAC;gBAED,MAAM,WAAW,GAAG,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBAChD,IAAI,CAAC,WAAW,EAAE,CAAC;oBAClB,OAAO;gBACR,CAAC;gBAED,OAAO,CAAC,MAAM,CAAC;oBACd,IAAI;oBACJ,SAAS,EAAE,uBAAuB;oBAClC,IAAI,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC,OAAO,EAAE;iBACtC,CAAC,CAAC;YACJ,CAAC;SACD,CAAC;IACH,CAAC;CACD,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Flags `new NodeOperationError(...)` or `new NodeApiError(...)` inside item
3
+ * loops in `execute()` methods that omit `{ itemIndex }` from the options
4
+ * argument. Without it, n8n cannot associate the error with the specific item
5
+ * that caused it, breaking per-item error reporting and `continueOnFail`.
6
+ *
7
+ * "Item loop" means a `for` or `for...of` that iterates over the result of
8
+ * `this.getInputData()` (or a variable initialised from it). Errors outside
9
+ * such loops — e.g. in webhook handlers or trigger setup — are not flagged.
10
+ */
11
+ export declare const NodeOperationErrorItemIndexRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingItemIndex", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
12
+ //# sourceMappingURL=node-operation-error-itemindex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-operation-error-itemindex.d.ts","sourceRoot":"","sources":["../../src/rules/node-operation-error-itemindex.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiFH,eAAO,MAAM,+BAA+B,qJAoI1C,CAAC"}