@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
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
import { ESLintUtils } from '@typescript-eslint/utils';
|
|
2
|
-
import { isCredentialTypeClass, findClassProperty, hasArrayLiteralValue, isFileType, getStringLiteralValue, findPackageJson, areAllCredentialUsagesTestedByNodes, } from '../utils/index.js';
|
|
3
1
|
import { dirname } from 'node:path';
|
|
4
|
-
|
|
2
|
+
import { isCredentialTypeClass, findClassProperty, hasArrayLiteralValue, isFileType, getStringLiteralValue, findPackageJson, areAllCredentialUsagesTestedByNodes, createRule, } from '../utils/index.js';
|
|
3
|
+
export const CredentialTestRequiredRule = createRule({
|
|
4
|
+
name: 'credential-test-required',
|
|
5
5
|
meta: {
|
|
6
6
|
type: 'problem',
|
|
7
7
|
docs: {
|
|
8
8
|
description: 'Ensure credentials have a credential test',
|
|
9
9
|
},
|
|
10
10
|
messages: {
|
|
11
|
+
addTemplate: 'Add basic credential test template',
|
|
11
12
|
missingCredentialTest: 'Credential class "{{ className }}" must have a test property or be tested by a node via testedBy',
|
|
12
13
|
},
|
|
13
14
|
schema: [],
|
|
15
|
+
hasSuggestions: true,
|
|
14
16
|
},
|
|
15
17
|
defaultOptions: [],
|
|
16
18
|
create(context) {
|
|
@@ -53,27 +55,63 @@ export const CredentialTestRequiredRule = ESLintUtils.RuleCreator.withoutDocs({
|
|
|
53
55
|
}
|
|
54
56
|
const pkgDir = getPackageDir();
|
|
55
57
|
if (!pkgDir) {
|
|
58
|
+
const suggestions = [];
|
|
59
|
+
const testProperty = createCredentialTestTemplate();
|
|
60
|
+
suggestions.push({
|
|
61
|
+
messageId: 'addTemplate',
|
|
62
|
+
fix(fixer) {
|
|
63
|
+
const classBody = node.body.body;
|
|
64
|
+
const lastProperty = classBody[classBody.length - 1];
|
|
65
|
+
if (lastProperty) {
|
|
66
|
+
return fixer.insertTextAfter(lastProperty, `\n\n${testProperty}`);
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
},
|
|
70
|
+
});
|
|
56
71
|
context.report({
|
|
57
72
|
node,
|
|
58
73
|
messageId: 'missingCredentialTest',
|
|
59
74
|
data: {
|
|
60
|
-
className: node.id?.name
|
|
75
|
+
className: node.id?.name ?? 'Unknown',
|
|
61
76
|
},
|
|
77
|
+
suggest: suggestions,
|
|
62
78
|
});
|
|
63
79
|
return;
|
|
64
80
|
}
|
|
65
81
|
const allUsagesTestedByNodes = areAllCredentialUsagesTestedByNodes(credentialName, pkgDir);
|
|
66
82
|
if (!allUsagesTestedByNodes) {
|
|
83
|
+
const suggestions = [];
|
|
84
|
+
const testProperty = createCredentialTestTemplate();
|
|
85
|
+
suggestions.push({
|
|
86
|
+
messageId: 'addTemplate',
|
|
87
|
+
fix(fixer) {
|
|
88
|
+
const classBody = node.body.body;
|
|
89
|
+
const lastProperty = classBody[classBody.length - 1];
|
|
90
|
+
if (lastProperty) {
|
|
91
|
+
return fixer.insertTextAfter(lastProperty, `\n\n${testProperty}`);
|
|
92
|
+
}
|
|
93
|
+
return null;
|
|
94
|
+
},
|
|
95
|
+
});
|
|
67
96
|
context.report({
|
|
68
97
|
node,
|
|
69
98
|
messageId: 'missingCredentialTest',
|
|
70
99
|
data: {
|
|
71
|
-
className: node.id?.name
|
|
100
|
+
className: node.id?.name ?? 'Unknown',
|
|
72
101
|
},
|
|
102
|
+
suggest: suggestions,
|
|
73
103
|
});
|
|
74
104
|
}
|
|
75
105
|
},
|
|
76
106
|
};
|
|
77
107
|
},
|
|
78
108
|
});
|
|
109
|
+
function createCredentialTestTemplate() {
|
|
110
|
+
return `\ttest: ICredentialTestRequest = {
|
|
111
|
+
\t\trequest: {
|
|
112
|
+
\t\t\tmethod: 'GET',
|
|
113
|
+
\t\t\turl: '={{$credentials.server}}/test', // Replace with actual endpoint
|
|
114
|
+
\t\t},
|
|
115
|
+
\t};`;
|
|
116
|
+
}
|
|
79
117
|
//# sourceMappingURL=credential-test-required.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-test-required.js","sourceRoot":"","sources":["../../src/rules/credential-test-required.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"credential-test-required.js","sourceRoot":"","sources":["../../src/rules/credential-test-required.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EACN,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,EACpB,UAAU,EACV,qBAAqB,EACrB,eAAe,EACf,mCAAmC,EACnC,UAAU,GACV,MAAM,mBAAmB,CAAC;AAE3B,MAAM,CAAC,MAAM,0BAA0B,GAAG,UAAU,CAAC;IACpD,IAAI,EAAE,0BAA0B;IAChC,IAAI,EAAE;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACL,WAAW,EAAE,2CAA2C;SACxD;QACD,QAAQ,EAAE;YACT,WAAW,EAAE,oCAAoC;YACjD,qBAAqB,EACpB,kGAAkG;SACnG;QACD,MAAM,EAAE,EAAE;QACV,cAAc,EAAE,IAAI;KACpB;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACb,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC,EAAE,CAAC;YACtD,OAAO,EAAE,CAAC;QACX,CAAC;QAED,IAAI,UAAU,GAAkB,IAAI,CAAC;QAErC,MAAM,aAAa,GAAG,GAAkB,EAAE;YACzC,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;gBACzB,OAAO,UAAU,CAAC;YACnB,CAAC;YAED,MAAM,eAAe,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC1D,IAAI,CAAC,eAAe,EAAE,CAAC;gBACtB,UAAU,GAAG,EAAE,CAAC;gBAChB,OAAO,UAAU,CAAC;YACnB,CAAC;YAED,UAAU,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;YACtC,OAAO,UAAU,CAAC;QACnB,CAAC,CAAC;QAEF,OAAO;YACN,gBAAgB,CAAC,IAAI;gBACpB,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClC,OAAO;gBACR,CAAC;gBAED,MAAM,eAAe,GAAG,iBAAiB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;gBAC3D,IAAI,eAAe,IAAI,oBAAoB,CAAC,eAAe,EAAE,WAAW,CAAC,EAAE,CAAC;oBAC3E,OAAO;gBACR,CAAC;gBAED,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACrD,IAAI,YAAY,EAAE,CAAC;oBAClB,OAAO;gBACR,CAAC;gBAED,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACrD,IAAI,CAAC,YAAY,EAAE,CAAC;oBACnB,OAAO;gBACR,CAAC;gBAED,MAAM,cAAc,GAAG,qBAAqB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;gBACjE,IAAI,CAAC,cAAc,EAAE,CAAC;oBACrB,OAAO;gBACR,CAAC;gBAED,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;oBACb,MAAM,WAAW,GAAmE,EAAE,CAAC;oBAEvF,MAAM,YAAY,GAAG,4BAA4B,EAAE,CAAC;oBACpD,WAAW,CAAC,IAAI,CAAC;wBAChB,SAAS,EAAE,aAAa;wBACxB,GAAG,CAAC,KAAK;4BACR,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;4BACjC,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;4BACrD,IAAI,YAAY,EAAE,CAAC;gCAClB,OAAO,KAAK,CAAC,eAAe,CAAC,YAAY,EAAE,OAAO,YAAY,EAAE,CAAC,CAAC;4BACnE,CAAC;4BACD,OAAO,IAAI,CAAC;wBACb,CAAC;qBACD,CAAC,CAAC;oBAEH,OAAO,CAAC,MAAM,CAAC;wBACd,IAAI;wBACJ,SAAS,EAAE,uBAAuB;wBAClC,IAAI,EAAE;4BACL,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,IAAI,SAAS;yBACrC;wBACD,OAAO,EAAE,WAAW;qBACpB,CAAC,CAAC;oBACH,OAAO;gBACR,CAAC;gBAED,MAAM,sBAAsB,GAAG,mCAAmC,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;gBAC3F,IAAI,CAAC,sBAAsB,EAAE,CAAC;oBAC7B,MAAM,WAAW,GAAmE,EAAE,CAAC;oBAEvF,MAAM,YAAY,GAAG,4BAA4B,EAAE,CAAC;oBACpD,WAAW,CAAC,IAAI,CAAC;wBAChB,SAAS,EAAE,aAAa;wBACxB,GAAG,CAAC,KAAK;4BACR,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;4BACjC,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;4BACrD,IAAI,YAAY,EAAE,CAAC;gCAClB,OAAO,KAAK,CAAC,eAAe,CAAC,YAAY,EAAE,OAAO,YAAY,EAAE,CAAC,CAAC;4BACnE,CAAC;4BACD,OAAO,IAAI,CAAC;wBACb,CAAC;qBACD,CAAC,CAAC;oBAEH,OAAO,CAAC,MAAM,CAAC;wBACd,IAAI;wBACJ,SAAS,EAAE,uBAAuB;wBAClC,IAAI,EAAE;4BACL,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,IAAI,SAAS;yBACrC;wBACD,OAAO,EAAE,WAAW;qBACpB,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;SACD,CAAC;IACH,CAAC;CACD,CAAC,CAAC;AAEH,SAAS,4BAA4B;IACpC,OAAO;;;;;KAKH,CAAC;AACN,CAAC"}
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
export declare const IconValidationRule: ESLintUtils.RuleModule<"iconFileNotFound" | "iconNotSvg" | "lightDarkSame" | "invalidIconPath" | "missingIcon", [], unknown, ESLintUtils.RuleListener>;
|
|
1
|
+
export declare const IconValidationRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"iconFileNotFound" | "iconNotSvg" | "lightDarkSame" | "invalidIconPath" | "missingIcon" | "addPlaceholder" | "addFileProtocol" | "changeExtension" | "similarIcon", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
3
2
|
//# sourceMappingURL=icon-validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon-validation.d.ts","sourceRoot":"","sources":["../../src/rules/icon-validation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"icon-validation.d.ts","sourceRoot":"","sources":["../../src/rules/icon-validation.ts"],"names":[],"mappings":"AA4BA,eAAO,MAAM,kBAAkB,qSAkN7B,CAAC"}
|
|
@@ -1,20 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TSESTree } from '@typescript-eslint/utils';
|
|
2
2
|
import { dirname } from 'node:path';
|
|
3
|
-
import { isNodeTypeClass, isCredentialTypeClass, findClassProperty, findObjectProperty, getStringLiteralValue, validateIconPath, isFileType, } from '../utils/index.js';
|
|
4
|
-
|
|
3
|
+
import { isNodeTypeClass, isCredentialTypeClass, findClassProperty, findObjectProperty, getStringLiteralValue, validateIconPath, findSimilarSvgFiles, isFileType, createRule, } from '../utils/index.js';
|
|
4
|
+
const messages = {
|
|
5
|
+
iconFileNotFound: 'Icon file "{{ iconPath }}" does not exist',
|
|
6
|
+
iconNotSvg: 'Icon file "{{ iconPath }}" must be an SVG file (end with .svg)',
|
|
7
|
+
lightDarkSame: 'Light and dark icons cannot be the same file. Both point to "{{ iconPath }}"',
|
|
8
|
+
invalidIconPath: 'Icon path "{{ iconPath }}" must use file: protocol and be a string',
|
|
9
|
+
missingIcon: 'Node/Credential class must have an icon property defined',
|
|
10
|
+
addPlaceholder: 'Add icon property with placeholder',
|
|
11
|
+
addFileProtocol: "Add 'file:' protocol to icon path",
|
|
12
|
+
changeExtension: "Change icon extension to '.svg'",
|
|
13
|
+
similarIcon: "Use existing icon '{{ suggestedName }}'",
|
|
14
|
+
};
|
|
15
|
+
export const IconValidationRule = createRule({
|
|
16
|
+
name: 'icon-validation',
|
|
5
17
|
meta: {
|
|
6
18
|
type: 'problem',
|
|
7
19
|
docs: {
|
|
8
20
|
description: 'Validate node and credential icon files exist, are SVG format, and light/dark icons are different',
|
|
9
21
|
},
|
|
10
|
-
messages
|
|
11
|
-
iconFileNotFound: 'Icon file "{{ iconPath }}" does not exist',
|
|
12
|
-
iconNotSvg: 'Icon file "{{ iconPath }}" must be an SVG file (end with .svg)',
|
|
13
|
-
lightDarkSame: 'Light and dark icons cannot be the same file. Both point to "{{ iconPath }}"',
|
|
14
|
-
invalidIconPath: 'Icon path "{{ iconPath }}" must use file: protocol and be a string',
|
|
15
|
-
missingIcon: 'Node/Credential class must have an icon property defined',
|
|
16
|
-
},
|
|
22
|
+
messages,
|
|
17
23
|
schema: [],
|
|
24
|
+
hasSuggestions: true,
|
|
18
25
|
},
|
|
19
26
|
defaultOptions: [],
|
|
20
27
|
create(context) {
|
|
@@ -27,46 +34,79 @@ export const IconValidationRule = ESLintUtils.RuleCreator.withoutDocs({
|
|
|
27
34
|
context.report({
|
|
28
35
|
node,
|
|
29
36
|
messageId: 'invalidIconPath',
|
|
30
|
-
data: { iconPath: iconPath
|
|
37
|
+
data: { iconPath: iconPath ?? '' },
|
|
31
38
|
});
|
|
32
39
|
return false;
|
|
33
40
|
}
|
|
34
41
|
const currentDir = dirname(context.filename);
|
|
35
42
|
const validation = validateIconPath(iconPath, currentDir);
|
|
36
43
|
if (!validation.isFile) {
|
|
44
|
+
const suggestions = [];
|
|
45
|
+
if (!iconPath.startsWith('file:')) {
|
|
46
|
+
suggestions.push({
|
|
47
|
+
messageId: 'addFileProtocol',
|
|
48
|
+
fix(fixer) {
|
|
49
|
+
return fixer.replaceText(node, `"file:${iconPath}"`);
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
}
|
|
37
53
|
context.report({
|
|
38
54
|
node,
|
|
39
55
|
messageId: 'invalidIconPath',
|
|
40
56
|
data: { iconPath },
|
|
57
|
+
suggest: suggestions,
|
|
41
58
|
});
|
|
42
59
|
return false;
|
|
43
60
|
}
|
|
44
61
|
if (!validation.isSvg) {
|
|
45
62
|
const relativePath = iconPath.replace(/^file:/, '');
|
|
63
|
+
const suggestions = [];
|
|
64
|
+
const pathWithoutExt = relativePath.replace(/\.[^/.]+$/, '');
|
|
65
|
+
const svgPath = `${pathWithoutExt}.svg`;
|
|
66
|
+
suggestions.push({
|
|
67
|
+
messageId: 'changeExtension',
|
|
68
|
+
fix(fixer) {
|
|
69
|
+
return fixer.replaceText(node, `"file:${svgPath}"`);
|
|
70
|
+
},
|
|
71
|
+
});
|
|
46
72
|
context.report({
|
|
47
73
|
node,
|
|
48
74
|
messageId: 'iconNotSvg',
|
|
49
75
|
data: { iconPath: relativePath },
|
|
76
|
+
suggest: suggestions,
|
|
50
77
|
});
|
|
51
78
|
return false;
|
|
52
79
|
}
|
|
53
80
|
if (!validation.exists) {
|
|
54
81
|
const relativePath = iconPath.replace(/^file:/, '');
|
|
82
|
+
const suggestions = [];
|
|
83
|
+
// Find similar SVG files in the same directory
|
|
84
|
+
const similarFiles = findSimilarSvgFiles(relativePath, currentDir);
|
|
85
|
+
for (const similarFile of similarFiles) {
|
|
86
|
+
suggestions.push({
|
|
87
|
+
messageId: 'similarIcon',
|
|
88
|
+
data: { suggestedName: similarFile },
|
|
89
|
+
fix(fixer) {
|
|
90
|
+
return fixer.replaceText(node, `"file:${similarFile}"`);
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
55
94
|
context.report({
|
|
56
95
|
node,
|
|
57
96
|
messageId: 'iconFileNotFound',
|
|
58
97
|
data: { iconPath: relativePath },
|
|
98
|
+
suggest: suggestions,
|
|
59
99
|
});
|
|
60
100
|
return false;
|
|
61
101
|
}
|
|
62
102
|
return true;
|
|
63
103
|
};
|
|
64
104
|
const validateIconValue = (iconValue) => {
|
|
65
|
-
if (iconValue.type ===
|
|
105
|
+
if (iconValue.type === TSESTree.AST_NODE_TYPES.Literal) {
|
|
66
106
|
const iconPath = getStringLiteralValue(iconValue);
|
|
67
107
|
validateIcon(iconPath, iconValue);
|
|
68
108
|
}
|
|
69
|
-
else if (iconValue.type ===
|
|
109
|
+
else if (iconValue.type === TSESTree.AST_NODE_TYPES.ObjectExpression) {
|
|
70
110
|
const lightProperty = findObjectProperty(iconValue, 'light');
|
|
71
111
|
const darkProperty = findObjectProperty(iconValue, 'dark');
|
|
72
112
|
const lightPath = lightProperty ? getStringLiteralValue(lightProperty.value) : null;
|
|
@@ -96,18 +136,31 @@ export const IconValidationRule = ESLintUtils.RuleCreator.withoutDocs({
|
|
|
96
136
|
if (isNodeClass) {
|
|
97
137
|
const descriptionProperty = findClassProperty(node, 'description');
|
|
98
138
|
if (!descriptionProperty?.value ||
|
|
99
|
-
descriptionProperty.value.type !==
|
|
139
|
+
descriptionProperty.value.type !== TSESTree.AST_NODE_TYPES.ObjectExpression) {
|
|
100
140
|
context.report({
|
|
101
141
|
node,
|
|
102
142
|
messageId: 'missingIcon',
|
|
103
143
|
});
|
|
104
144
|
return;
|
|
105
145
|
}
|
|
106
|
-
const
|
|
146
|
+
const descriptionValue = descriptionProperty.value;
|
|
147
|
+
const iconProperty = findObjectProperty(descriptionValue, 'icon');
|
|
107
148
|
if (!iconProperty) {
|
|
149
|
+
const suggestions = [];
|
|
150
|
+
suggestions.push({
|
|
151
|
+
messageId: 'addPlaceholder',
|
|
152
|
+
fix(fixer) {
|
|
153
|
+
const lastProperty = descriptionValue.properties[descriptionValue.properties.length - 1];
|
|
154
|
+
if (lastProperty) {
|
|
155
|
+
return fixer.insertTextAfter(lastProperty, ',\n\t\ticon: "file:./icon.svg"');
|
|
156
|
+
}
|
|
157
|
+
return null;
|
|
158
|
+
},
|
|
159
|
+
});
|
|
108
160
|
context.report({
|
|
109
161
|
node,
|
|
110
162
|
messageId: 'missingIcon',
|
|
163
|
+
suggest: suggestions,
|
|
111
164
|
});
|
|
112
165
|
return;
|
|
113
166
|
}
|
|
@@ -116,9 +169,22 @@ export const IconValidationRule = ESLintUtils.RuleCreator.withoutDocs({
|
|
|
116
169
|
else if (isCredentialClass) {
|
|
117
170
|
const iconProperty = findClassProperty(node, 'icon');
|
|
118
171
|
if (!iconProperty?.value) {
|
|
172
|
+
const suggestions = [];
|
|
173
|
+
suggestions.push({
|
|
174
|
+
messageId: 'addPlaceholder',
|
|
175
|
+
fix(fixer) {
|
|
176
|
+
const classBody = node.body.body;
|
|
177
|
+
const lastProperty = classBody[classBody.length - 1];
|
|
178
|
+
if (lastProperty) {
|
|
179
|
+
return fixer.insertTextAfter(lastProperty, '\n\n\ticon = "file:./icon.svg";');
|
|
180
|
+
}
|
|
181
|
+
return null;
|
|
182
|
+
},
|
|
183
|
+
});
|
|
119
184
|
context.report({
|
|
120
185
|
node,
|
|
121
186
|
messageId: 'missingIcon',
|
|
187
|
+
suggest: suggestions,
|
|
122
188
|
});
|
|
123
189
|
return;
|
|
124
190
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icon-validation.js","sourceRoot":"","sources":["../../src/rules/icon-validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"icon-validation.js","sourceRoot":"","sources":["../../src/rules/icon-validation.ts"],"names":[],"mappings":"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"}
|
package/dist/rules/index.d.ts
CHANGED
|
@@ -2,12 +2,16 @@ export declare const rules: {
|
|
|
2
2
|
'no-restricted-globals': import("@typescript-eslint/utils/ts-eslint").RuleModule<"restrictedGlobal", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
3
3
|
'no-restricted-imports': import("@typescript-eslint/utils/ts-eslint").RuleModule<"restrictedImport" | "restrictedRequire" | "restrictedDynamicImport", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
4
4
|
'credential-password-field': import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingPasswordOption", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
|
-
'no-deprecated-workflow-functions': import("@typescript-eslint/utils/ts-eslint").RuleModule<"deprecatedRequestFunction" | "deprecatedFunction" | "deprecatedType" | "deprecatedWithoutReplacement", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
5
|
+
'no-deprecated-workflow-functions': import("@typescript-eslint/utils/ts-eslint").RuleModule<"deprecatedRequestFunction" | "deprecatedFunction" | "deprecatedType" | "deprecatedWithoutReplacement" | "suggestReplaceFunction" | "suggestReplaceType", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
6
6
|
'node-usable-as-tool': import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingUsableAsTool", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
7
|
-
'package-name-convention': import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidPackageName", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
8
|
-
'credential-test-required': import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingCredentialTest", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
9
|
-
'no-credential-reuse': import("@typescript-eslint/utils/ts-eslint").RuleModule<"credentialNotInPackage", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
10
|
-
'icon-validation': import("@typescript-eslint/utils/ts-eslint").RuleModule<"iconFileNotFound" | "iconNotSvg" | "lightDarkSame" | "invalidIconPath" | "missingIcon", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
7
|
+
'package-name-convention': import("@typescript-eslint/utils/ts-eslint").RuleModule<"renameTo" | "invalidPackageName", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
8
|
+
'credential-test-required': import("@typescript-eslint/utils/ts-eslint").RuleModule<"addTemplate" | "missingCredentialTest", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
9
|
+
'no-credential-reuse': import("@typescript-eslint/utils/ts-eslint").RuleModule<"didYouMean" | "useAvailable" | "credentialNotInPackage", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
10
|
+
'icon-validation': import("@typescript-eslint/utils/ts-eslint").RuleModule<"iconFileNotFound" | "iconNotSvg" | "lightDarkSame" | "invalidIconPath" | "missingIcon" | "addPlaceholder" | "addFileProtocol" | "changeExtension" | "similarIcon", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
11
11
|
'resource-operation-pattern': import("@typescript-eslint/utils/ts-eslint").RuleModule<"tooManyOperationsWithoutResources", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
12
|
+
'credential-documentation-url': import("@typescript-eslint/utils/ts-eslint").RuleModule<"invalidDocumentationUrl", [{
|
|
13
|
+
allowUrls?: boolean;
|
|
14
|
+
allowSlugs?: boolean;
|
|
15
|
+
}], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
12
16
|
};
|
|
13
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;CAYuB,CAAC"}
|
package/dist/rules/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { NoRestrictedImportsRule } from './no-restricted-imports.js';
|
|
1
|
+
import { CredentialDocumentationUrlRule } from './credential-documentation-url.js';
|
|
3
2
|
import { CredentialPasswordFieldRule } from './credential-password-field.js';
|
|
3
|
+
import { CredentialTestRequiredRule } from './credential-test-required.js';
|
|
4
|
+
import { IconValidationRule } from './icon-validation.js';
|
|
5
|
+
import { NoCredentialReuseRule } from './no-credential-reuse.js';
|
|
4
6
|
import { NoDeprecatedWorkflowFunctionsRule } from './no-deprecated-workflow-functions.js';
|
|
7
|
+
import { NoRestrictedGlobalsRule } from './no-restricted-globals.js';
|
|
8
|
+
import { NoRestrictedImportsRule } from './no-restricted-imports.js';
|
|
5
9
|
import { NodeUsableAsToolRule } from './node-usable-as-tool.js';
|
|
6
10
|
import { PackageNameConventionRule } from './package-name-convention.js';
|
|
7
|
-
import { CredentialTestRequiredRule } from './credential-test-required.js';
|
|
8
|
-
import { NoCredentialReuseRule } from './no-credential-reuse.js';
|
|
9
|
-
import { IconValidationRule } from './icon-validation.js';
|
|
10
11
|
import { ResourceOperationPatternRule } from './resource-operation-pattern.js';
|
|
11
12
|
export const rules = {
|
|
12
13
|
'no-restricted-globals': NoRestrictedGlobalsRule,
|
|
@@ -19,5 +20,6 @@ export const rules = {
|
|
|
19
20
|
'no-credential-reuse': NoCredentialReuseRule,
|
|
20
21
|
'icon-validation': IconValidationRule,
|
|
21
22
|
'resource-operation-pattern': ResourceOperationPatternRule,
|
|
23
|
+
'credential-documentation-url': CredentialDocumentationUrlRule,
|
|
22
24
|
};
|
|
23
25
|
//# sourceMappingURL=index.js.map
|
package/dist/rules/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rules/index.ts"],"names":[],"mappings":"AAEA,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,iCAAiC,EAAE,MAAM,uCAAuC,CAAC;AAC1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,4BAA4B,EAAE,MAAM,iCAAiC,CAAC;AAE/E,MAAM,CAAC,MAAM,KAAK,GAAG;IACpB,uBAAuB,EAAE,uBAAuB;IAChD,uBAAuB,EAAE,uBAAuB;IAChD,2BAA2B,EAAE,2BAA2B;IACxD,kCAAkC,EAAE,iCAAiC;IACrE,qBAAqB,EAAE,oBAAoB;IAC3C,yBAAyB,EAAE,yBAAyB;IACpD,0BAA0B,EAAE,0BAA0B;IACtD,qBAAqB,EAAE,qBAAqB;IAC5C,iBAAiB,EAAE,kBAAkB;IACrC,4BAA4B,EAAE,4BAA4B;IAC1D,8BAA8B,EAAE,8BAA8B;CACtB,CAAC"}
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
export declare const NoCredentialReuseRule: ESLintUtils.RuleModule<"credentialNotInPackage", [], unknown, ESLintUtils.RuleListener>;
|
|
1
|
+
export declare const NoCredentialReuseRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"didYouMean" | "useAvailable" | "credentialNotInPackage", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
3
2
|
//# sourceMappingURL=no-credential-reuse.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-credential-reuse.d.ts","sourceRoot":"","sources":["../../src/rules/no-credential-reuse.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"no-credential-reuse.d.ts","sourceRoot":"","sources":["../../src/rules/no-credential-reuse.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,qBAAqB,2LAyGhC,CAAC"}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isNodeTypeClass, findClassProperty, findArrayLiteralProperty, extractCredentialNameFromArray, findPackageJson, readPackageJsonCredentials, isFileType, } from '../utils/index.js';
|
|
3
|
-
export const NoCredentialReuseRule =
|
|
1
|
+
import { TSESTree } from '@typescript-eslint/types';
|
|
2
|
+
import { isNodeTypeClass, findClassProperty, findArrayLiteralProperty, extractCredentialNameFromArray, findPackageJson, readPackageJsonCredentials, isFileType, findSimilarStrings, createRule, } from '../utils/index.js';
|
|
3
|
+
export const NoCredentialReuseRule = createRule({
|
|
4
|
+
name: 'no-credential-reuse',
|
|
4
5
|
meta: {
|
|
5
6
|
type: 'problem',
|
|
6
7
|
docs: {
|
|
7
8
|
description: 'Prevent credential re-use security issues by ensuring nodes only reference credentials from the same package',
|
|
8
9
|
},
|
|
9
10
|
messages: {
|
|
11
|
+
didYouMean: "Did you mean '{{ suggestedName }}'?",
|
|
12
|
+
useAvailable: "Use available credential '{{ suggestedName }}'",
|
|
10
13
|
credentialNotInPackage: 'SECURITY: Node references credential "{{ credentialName }}" which is not defined in this package. This creates a security risk as it attempts to reuse credentials from other packages. Nodes can only use credentials from the same package as listed in package.json n8n.credentials field.',
|
|
11
14
|
},
|
|
12
15
|
schema: [],
|
|
16
|
+
hasSuggestions: true,
|
|
13
17
|
},
|
|
14
18
|
defaultOptions: [],
|
|
15
19
|
create(context) {
|
|
@@ -35,7 +39,8 @@ export const NoCredentialReuseRule = ESLintUtils.RuleCreator.withoutDocs({
|
|
|
35
39
|
return;
|
|
36
40
|
}
|
|
37
41
|
const descriptionProperty = findClassProperty(node, 'description');
|
|
38
|
-
if (!descriptionProperty?.value ||
|
|
42
|
+
if (!descriptionProperty?.value ||
|
|
43
|
+
descriptionProperty.value.type !== TSESTree.AST_NODE_TYPES.ObjectExpression) {
|
|
39
44
|
return;
|
|
40
45
|
}
|
|
41
46
|
const credentialsArray = findArrayLiteralProperty(descriptionProperty.value, 'credentials');
|
|
@@ -46,12 +51,36 @@ export const NoCredentialReuseRule = ESLintUtils.RuleCreator.withoutDocs({
|
|
|
46
51
|
credentialsArray.elements.forEach((element) => {
|
|
47
52
|
const credentialInfo = extractCredentialNameFromArray(element);
|
|
48
53
|
if (credentialInfo && !allowedCredentials.has(credentialInfo.name)) {
|
|
54
|
+
const similarCredentials = findSimilarStrings(credentialInfo.name, allowedCredentials);
|
|
55
|
+
const suggestions = [];
|
|
56
|
+
for (const similarName of similarCredentials) {
|
|
57
|
+
suggestions.push({
|
|
58
|
+
messageId: 'didYouMean',
|
|
59
|
+
data: { suggestedName: similarName },
|
|
60
|
+
fix(fixer) {
|
|
61
|
+
return fixer.replaceText(credentialInfo.node, `"${similarName}"`);
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (suggestions.length === 0 && allowedCredentials.size > 0) {
|
|
66
|
+
const availableCredentials = Array.from(allowedCredentials).slice(0, 3);
|
|
67
|
+
for (const availableName of availableCredentials) {
|
|
68
|
+
suggestions.push({
|
|
69
|
+
messageId: 'useAvailable',
|
|
70
|
+
data: { suggestedName: availableName },
|
|
71
|
+
fix(fixer) {
|
|
72
|
+
return fixer.replaceText(credentialInfo.node, `"${availableName}"`);
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
49
77
|
context.report({
|
|
50
78
|
node: credentialInfo.node,
|
|
51
79
|
messageId: 'credentialNotInPackage',
|
|
52
80
|
data: {
|
|
53
81
|
credentialName: credentialInfo.name,
|
|
54
82
|
},
|
|
83
|
+
suggest: suggestions,
|
|
55
84
|
});
|
|
56
85
|
}
|
|
57
86
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-credential-reuse.js","sourceRoot":"","sources":["../../src/rules/no-credential-reuse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"no-credential-reuse.js","sourceRoot":"","sources":["../../src/rules/no-credential-reuse.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
export declare const NoDeprecatedWorkflowFunctionsRule: ESLintUtils.RuleModule<"deprecatedRequestFunction" | "deprecatedFunction" | "deprecatedType" | "deprecatedWithoutReplacement", [], unknown, ESLintUtils.RuleListener>;
|
|
1
|
+
export declare const NoDeprecatedWorkflowFunctionsRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"deprecatedRequestFunction" | "deprecatedFunction" | "deprecatedType" | "deprecatedWithoutReplacement" | "suggestReplaceFunction" | "suggestReplaceType", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
|
|
3
2
|
//# sourceMappingURL=no-deprecated-workflow-functions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-deprecated-workflow-functions.d.ts","sourceRoot":"","sources":["../../src/rules/no-deprecated-workflow-functions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"no-deprecated-workflow-functions.d.ts","sourceRoot":"","sources":["../../src/rules/no-deprecated-workflow-functions.ts"],"names":[],"mappings":"AA0BA,eAAO,MAAM,iCAAiC,2RA6I5C,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AST_NODE_TYPES } from '@typescript-eslint/utils';
|
|
2
|
+
import { createRule } from '../utils/index.js';
|
|
2
3
|
const DEPRECATED_FUNCTIONS = {
|
|
3
4
|
request: 'httpRequest',
|
|
4
5
|
requestWithAuthentication: 'httpRequestWithAuthentication',
|
|
@@ -16,7 +17,8 @@ function isDeprecatedFunctionName(name) {
|
|
|
16
17
|
function isDeprecatedTypeName(name) {
|
|
17
18
|
return name in DEPRECATED_TYPES;
|
|
18
19
|
}
|
|
19
|
-
export const NoDeprecatedWorkflowFunctionsRule =
|
|
20
|
+
export const NoDeprecatedWorkflowFunctionsRule = createRule({
|
|
21
|
+
name: 'no-deprecated-workflow-functions',
|
|
20
22
|
meta: {
|
|
21
23
|
type: 'problem',
|
|
22
24
|
docs: {
|
|
@@ -27,8 +29,11 @@ export const NoDeprecatedWorkflowFunctionsRule = ESLintUtils.RuleCreator.without
|
|
|
27
29
|
deprecatedFunction: "'{{ functionName }}' is deprecated and should be avoided. {{ message }}",
|
|
28
30
|
deprecatedType: "'{{ typeName }}' is deprecated. Use '{{ replacement }}' instead.",
|
|
29
31
|
deprecatedWithoutReplacement: "'{{ functionName }}' is deprecated and should be removed or replaced with alternative implementation.",
|
|
32
|
+
suggestReplaceFunction: "Replace '{{ functionName }}' with '{{ replacement }}'",
|
|
33
|
+
suggestReplaceType: "Replace '{{ typeName }}' with '{{ replacement }}'",
|
|
30
34
|
},
|
|
31
35
|
schema: [],
|
|
36
|
+
hasSuggestions: true,
|
|
32
37
|
},
|
|
33
38
|
defaultOptions: [],
|
|
34
39
|
create(context) {
|
|
@@ -37,14 +42,16 @@ export const NoDeprecatedWorkflowFunctionsRule = ESLintUtils.RuleCreator.without
|
|
|
37
42
|
ImportDeclaration(node) {
|
|
38
43
|
if (node.source.value === 'n8n-workflow') {
|
|
39
44
|
node.specifiers.forEach((specifier) => {
|
|
40
|
-
if (specifier.type ===
|
|
45
|
+
if (specifier.type === AST_NODE_TYPES.ImportSpecifier &&
|
|
46
|
+
specifier.imported.type === AST_NODE_TYPES.Identifier) {
|
|
41
47
|
n8nWorkflowTypes.add(specifier.local.name);
|
|
42
48
|
}
|
|
43
49
|
});
|
|
44
50
|
}
|
|
45
51
|
},
|
|
46
52
|
MemberExpression(node) {
|
|
47
|
-
if (node.property.type ===
|
|
53
|
+
if (node.property.type === AST_NODE_TYPES.Identifier &&
|
|
54
|
+
isDeprecatedFunctionName(node.property.name)) {
|
|
48
55
|
if (!isThisHelpersAccess(node)) {
|
|
49
56
|
return;
|
|
50
57
|
}
|
|
@@ -62,6 +69,13 @@ export const NoDeprecatedWorkflowFunctionsRule = ESLintUtils.RuleCreator.without
|
|
|
62
69
|
replacement,
|
|
63
70
|
message: getDeprecationMessage(functionName),
|
|
64
71
|
},
|
|
72
|
+
suggest: [
|
|
73
|
+
{
|
|
74
|
+
messageId: 'suggestReplaceFunction',
|
|
75
|
+
data: { functionName, replacement },
|
|
76
|
+
fix: (fixer) => fixer.replaceText(node.property, replacement),
|
|
77
|
+
},
|
|
78
|
+
],
|
|
65
79
|
});
|
|
66
80
|
}
|
|
67
81
|
else {
|
|
@@ -76,7 +90,7 @@ export const NoDeprecatedWorkflowFunctionsRule = ESLintUtils.RuleCreator.without
|
|
|
76
90
|
}
|
|
77
91
|
},
|
|
78
92
|
TSTypeReference(node) {
|
|
79
|
-
if (node.typeName.type ===
|
|
93
|
+
if (node.typeName.type === AST_NODE_TYPES.Identifier &&
|
|
80
94
|
isDeprecatedTypeName(node.typeName.name) &&
|
|
81
95
|
n8nWorkflowTypes.has(node.typeName.name)) {
|
|
82
96
|
const typeName = node.typeName.name;
|
|
@@ -88,15 +102,22 @@ export const NoDeprecatedWorkflowFunctionsRule = ESLintUtils.RuleCreator.without
|
|
|
88
102
|
typeName,
|
|
89
103
|
replacement,
|
|
90
104
|
},
|
|
105
|
+
suggest: [
|
|
106
|
+
{
|
|
107
|
+
messageId: 'suggestReplaceType',
|
|
108
|
+
data: { typeName, replacement },
|
|
109
|
+
fix: (fixer) => fixer.replaceText(node.typeName, replacement),
|
|
110
|
+
},
|
|
111
|
+
],
|
|
91
112
|
});
|
|
92
113
|
}
|
|
93
114
|
},
|
|
94
115
|
ImportSpecifier(node) {
|
|
95
116
|
// Check if this import is from n8n-workflow by looking at the parent ImportDeclaration
|
|
96
117
|
const importDeclaration = node.parent;
|
|
97
|
-
if (importDeclaration?.type ===
|
|
118
|
+
if (importDeclaration?.type === AST_NODE_TYPES.ImportDeclaration &&
|
|
98
119
|
importDeclaration.source.value === 'n8n-workflow' &&
|
|
99
|
-
node.imported.type ===
|
|
120
|
+
node.imported.type === AST_NODE_TYPES.Identifier &&
|
|
100
121
|
isDeprecatedTypeName(node.imported.name)) {
|
|
101
122
|
const typeName = node.imported.name;
|
|
102
123
|
const replacement = DEPRECATED_TYPES[typeName];
|
|
@@ -107,6 +128,13 @@ export const NoDeprecatedWorkflowFunctionsRule = ESLintUtils.RuleCreator.without
|
|
|
107
128
|
typeName,
|
|
108
129
|
replacement,
|
|
109
130
|
},
|
|
131
|
+
suggest: [
|
|
132
|
+
{
|
|
133
|
+
messageId: 'suggestReplaceType',
|
|
134
|
+
data: { typeName, replacement },
|
|
135
|
+
fix: (fixer) => fixer.replaceText(node.imported, replacement),
|
|
136
|
+
},
|
|
137
|
+
],
|
|
110
138
|
});
|
|
111
139
|
}
|
|
112
140
|
},
|
|
@@ -117,10 +145,10 @@ export const NoDeprecatedWorkflowFunctionsRule = ESLintUtils.RuleCreator.without
|
|
|
117
145
|
* Check if the MemberExpression follows the this.helpers.* pattern
|
|
118
146
|
*/
|
|
119
147
|
function isThisHelpersAccess(node) {
|
|
120
|
-
if (node.object?.type ===
|
|
148
|
+
if (node.object?.type === AST_NODE_TYPES.MemberExpression) {
|
|
121
149
|
const outerObject = node.object;
|
|
122
|
-
return (outerObject.object?.type ===
|
|
123
|
-
outerObject.property?.type ===
|
|
150
|
+
return (outerObject.object?.type === AST_NODE_TYPES.ThisExpression &&
|
|
151
|
+
outerObject.property?.type === AST_NODE_TYPES.Identifier &&
|
|
124
152
|
outerObject.property.name === 'helpers');
|
|
125
153
|
}
|
|
126
154
|
return false;
|