@n8n/eslint-plugin-community-nodes 0.22.0 → 0.23.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 (49) hide show
  1. package/.turbo/turbo-build$colon$unchecked.log +1 -1
  2. package/README.md +5 -0
  3. package/dist/plugin.d.ts +30 -0
  4. package/dist/plugin.d.ts.map +1 -1
  5. package/dist/plugin.js +10 -0
  6. package/dist/plugin.js.map +1 -1
  7. package/dist/rules/index.d.ts +5 -0
  8. package/dist/rules/index.d.ts.map +1 -1
  9. package/dist/rules/index.js +10 -0
  10. package/dist/rules/index.js.map +1 -1
  11. package/dist/rules/no-asterisk-in-option-names.d.ts +2 -0
  12. package/dist/rules/no-asterisk-in-option-names.d.ts.map +1 -0
  13. package/dist/rules/no-asterisk-in-option-names.js +90 -0
  14. package/dist/rules/no-asterisk-in-option-names.js.map +1 -0
  15. package/dist/rules/no-duplicate-param-options.d.ts +2 -0
  16. package/dist/rules/no-duplicate-param-options.d.ts.map +1 -0
  17. package/dist/rules/no-duplicate-param-options.js +97 -0
  18. package/dist/rules/no-duplicate-param-options.js.map +1 -0
  19. package/dist/rules/require-mit-license.d.ts +2 -0
  20. package/dist/rules/require-mit-license.d.ts.map +1 -0
  21. package/dist/rules/require-mit-license.js +57 -0
  22. package/dist/rules/require-mit-license.js.map +1 -0
  23. package/dist/rules/require-param-default.d.ts +15 -0
  24. package/dist/rules/require-param-default.d.ts.map +1 -0
  25. package/dist/rules/require-param-default.js +75 -0
  26. package/dist/rules/require-param-default.js.map +1 -0
  27. package/dist/rules/trigger-node-conventions.d.ts +2 -0
  28. package/dist/rules/trigger-node-conventions.d.ts.map +1 -0
  29. package/dist/rules/trigger-node-conventions.js +70 -0
  30. package/dist/rules/trigger-node-conventions.js.map +1 -0
  31. package/dist/typecheck.tsbuildinfo +1 -1
  32. package/docs/rules/no-asterisk-in-option-names.md +61 -0
  33. package/docs/rules/no-duplicate-param-options.md +46 -0
  34. package/docs/rules/require-mit-license.md +38 -0
  35. package/docs/rules/require-param-default.md +60 -0
  36. package/docs/rules/trigger-node-conventions.md +49 -0
  37. package/package.json +6 -5
  38. package/src/plugin.ts +10 -0
  39. package/src/rules/index.ts +10 -0
  40. package/src/rules/no-asterisk-in-option-names.test.ts +185 -0
  41. package/src/rules/no-asterisk-in-option-names.ts +111 -0
  42. package/src/rules/no-duplicate-param-options.test.ts +125 -0
  43. package/src/rules/no-duplicate-param-options.ts +125 -0
  44. package/src/rules/require-mit-license.test.ts +67 -0
  45. package/src/rules/require-mit-license.ts +65 -0
  46. package/src/rules/require-param-default.test.ts +227 -0
  47. package/src/rules/require-param-default.ts +89 -0
  48. package/src/rules/trigger-node-conventions.test.ts +110 -0
  49. package/src/rules/trigger-node-conventions.ts +92 -0
@@ -0,0 +1,97 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
+ import { isNodeTypeClass, findClassProperty, findObjectProperty, getStringLiteralValue, getLiteralValue, isFileType, createRule, } from '../utils/index.js';
3
+ export const NoDuplicateParamOptionsRule = createRule({
4
+ name: 'no-duplicate-param-options',
5
+ meta: {
6
+ type: 'problem',
7
+ docs: {
8
+ description: 'Disallow duplicate option names or values within a single node parameter',
9
+ },
10
+ messages: {
11
+ duplicateName: 'Duplicate option name "{{ value }}" in parameter "{{ displayName }}".',
12
+ duplicateValue: 'Duplicate option value "{{ value }}" in parameter "{{ displayName }}".',
13
+ },
14
+ schema: [],
15
+ },
16
+ defaultOptions: [],
17
+ create(context) {
18
+ if (!isFileType(context.filename, '.node.ts')) {
19
+ return {};
20
+ }
21
+ const checkProperty = (property) => {
22
+ const typeProperty = findObjectProperty(property, 'type');
23
+ const type = typeProperty ? getStringLiteralValue(typeProperty.value) : null;
24
+ if (type !== 'options' && type !== 'multiOptions') {
25
+ return;
26
+ }
27
+ const optionsProperty = findObjectProperty(property, 'options');
28
+ if (!optionsProperty?.value ||
29
+ optionsProperty.value.type !== AST_NODE_TYPES.ArrayExpression) {
30
+ return;
31
+ }
32
+ const displayNameProperty = findObjectProperty(property, 'displayName');
33
+ const displayName = (displayNameProperty ? getStringLiteralValue(displayNameProperty.value) : null) ??
34
+ 'unknown';
35
+ const seenNames = new Set();
36
+ const seenValues = new Set();
37
+ for (const option of optionsProperty.value.elements) {
38
+ if (!option || option.type !== AST_NODE_TYPES.ObjectExpression) {
39
+ continue;
40
+ }
41
+ const nameProperty = findObjectProperty(option, 'name');
42
+ const name = nameProperty ? getStringLiteralValue(nameProperty.value) : null;
43
+ if (name !== null) {
44
+ if (seenNames.has(name)) {
45
+ context.report({
46
+ node: nameProperty.value,
47
+ messageId: 'duplicateName',
48
+ data: { value: name, displayName },
49
+ });
50
+ }
51
+ seenNames.add(name);
52
+ }
53
+ const valueProperty = findObjectProperty(option, 'value');
54
+ const value = valueProperty ? getLiteralValue(valueProperty.value) : null;
55
+ if (value !== null) {
56
+ if (seenValues.has(value)) {
57
+ context.report({
58
+ node: valueProperty.value,
59
+ messageId: 'duplicateValue',
60
+ data: { value: String(value), displayName },
61
+ });
62
+ }
63
+ seenValues.add(value);
64
+ }
65
+ }
66
+ };
67
+ const analyzeNodeDescription = (descriptionValue) => {
68
+ if (!descriptionValue || descriptionValue.type !== AST_NODE_TYPES.ObjectExpression) {
69
+ return;
70
+ }
71
+ const propertiesProperty = findObjectProperty(descriptionValue, 'properties');
72
+ if (!propertiesProperty?.value ||
73
+ propertiesProperty.value.type !== AST_NODE_TYPES.ArrayExpression) {
74
+ return;
75
+ }
76
+ for (const property of propertiesProperty.value.elements) {
77
+ if (!property || property.type !== AST_NODE_TYPES.ObjectExpression) {
78
+ continue;
79
+ }
80
+ checkProperty(property);
81
+ }
82
+ };
83
+ return {
84
+ ClassDeclaration(node) {
85
+ if (!isNodeTypeClass(node)) {
86
+ return;
87
+ }
88
+ const descriptionProperty = findClassProperty(node, 'description');
89
+ if (!descriptionProperty) {
90
+ return;
91
+ }
92
+ analyzeNodeDescription(descriptionProperty.value);
93
+ },
94
+ };
95
+ },
96
+ });
97
+ //# sourceMappingURL=no-duplicate-param-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-duplicate-param-options.js","sourceRoot":"","sources":["../../src/rules/no-duplicate-param-options.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const RequireMitLicenseRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingLicense" | "wrongLicense", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
2
+ //# sourceMappingURL=require-mit-license.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-mit-license.d.ts","sourceRoot":"","sources":["../../src/rules/require-mit-license.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,qBAAqB,oKAyDhC,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
+ import { createRule, findJsonProperty, getStringLiteralValue } from '../utils/index.js';
3
+ const REQUIRED_LICENSE = 'MIT';
4
+ export const RequireMitLicenseRule = createRule({
5
+ name: 'require-mit-license',
6
+ meta: {
7
+ type: 'problem',
8
+ docs: {
9
+ description: 'Require the "license" field in community node package.json to be "MIT"',
10
+ },
11
+ fixable: 'code',
12
+ messages: {
13
+ missingLicense: `The package.json must have a "license" field set to "${REQUIRED_LICENSE}".`,
14
+ wrongLicense: `The "license" field must be "${REQUIRED_LICENSE}".`,
15
+ },
16
+ schema: [],
17
+ },
18
+ defaultOptions: [],
19
+ create(context) {
20
+ if (!context.filename.endsWith('package.json')) {
21
+ return {};
22
+ }
23
+ return {
24
+ ObjectExpression(node) {
25
+ if (node.parent?.type !== AST_NODE_TYPES.ExpressionStatement) {
26
+ return;
27
+ }
28
+ const licenseProp = findJsonProperty(node, 'license');
29
+ if (!licenseProp) {
30
+ context.report({
31
+ node,
32
+ messageId: 'missingLicense',
33
+ fix(fixer) {
34
+ const lastProp = node.properties[node.properties.length - 1];
35
+ if (!lastProp) {
36
+ return fixer.replaceText(node, `{ "license": "${REQUIRED_LICENSE}" }`);
37
+ }
38
+ return fixer.insertTextAfter(lastProp, `, "license": "${REQUIRED_LICENSE}"`);
39
+ },
40
+ });
41
+ return;
42
+ }
43
+ if (getStringLiteralValue(licenseProp.value) === REQUIRED_LICENSE) {
44
+ return;
45
+ }
46
+ context.report({
47
+ node: licenseProp.value,
48
+ messageId: 'wrongLicense',
49
+ fix(fixer) {
50
+ return fixer.replaceText(licenseProp.value, `"${REQUIRED_LICENSE}"`);
51
+ },
52
+ });
53
+ },
54
+ };
55
+ },
56
+ });
57
+ //# sourceMappingURL=require-mit-license.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-mit-license.js","sourceRoot":"","sources":["../../src/rules/require-mit-license.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAExF,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAE/B,MAAM,CAAC,MAAM,qBAAqB,GAAG,UAAU,CAAC;IAC/C,IAAI,EAAE,qBAAqB;IAC3B,IAAI,EAAE;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACL,WAAW,EAAE,wEAAwE;SACrF;QACD,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE;YACT,cAAc,EAAE,wDAAwD,gBAAgB,IAAI;YAC5F,YAAY,EAAE,gCAAgC,gBAAgB,IAAI;SAClE;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,WAAW,GAAG,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;gBAEtD,IAAI,CAAC,WAAW,EAAE,CAAC;oBAClB,OAAO,CAAC,MAAM,CAAC;wBACd,IAAI;wBACJ,SAAS,EAAE,gBAAgB;wBAC3B,GAAG,CAAC,KAAK;4BACR,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;4BAC7D,IAAI,CAAC,QAAQ,EAAE,CAAC;gCACf,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,EAAE,iBAAiB,gBAAgB,KAAK,CAAC,CAAC;4BACxE,CAAC;4BACD,OAAO,KAAK,CAAC,eAAe,CAAC,QAAQ,EAAE,iBAAiB,gBAAgB,GAAG,CAAC,CAAC;wBAC9E,CAAC;qBACD,CAAC,CAAC;oBACH,OAAO;gBACR,CAAC;gBAED,IAAI,qBAAqB,CAAC,WAAW,CAAC,KAAK,CAAC,KAAK,gBAAgB,EAAE,CAAC;oBACnE,OAAO;gBACR,CAAC;gBAED,OAAO,CAAC,MAAM,CAAC;oBACd,IAAI,EAAE,WAAW,CAAC,KAAK;oBACvB,SAAS,EAAE,cAAc;oBACzB,GAAG,CAAC,KAAK;wBACR,OAAO,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,gBAAgB,GAAG,CAAC,CAAC;oBACtE,CAAC;iBACD,CAAC,CAAC;YACJ,CAAC;SACD,CAAC;IACH,CAAC;CACD,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Requires every node parameter to declare a `default` property.
3
+ *
4
+ * A parameter is detected structurally: an object literal inside a node's
5
+ * `description` with `displayName`, `name`, and `type` all set to string
6
+ * literals — the shape every `INodeProperties` entry has. This avoids
7
+ * hardcoding the `NodePropertyTypes` union (which would silently go stale as
8
+ * new types are added) and naturally excludes `options`-array entries, which
9
+ * carry `name`/`value` but no `displayName`/`type`.
10
+ *
11
+ * Without a `default`, n8n cannot reliably initialise the parameter's value,
12
+ * which leads to inconsistent runtime behaviour in the editor and on execution.
13
+ */
14
+ export declare const RequireParamDefaultRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"missingDefault", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
15
+ //# sourceMappingURL=require-param-default.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-param-default.d.ts","sourceRoot":"","sources":["../../src/rules/require-param-default.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA0BH,eAAO,MAAM,uBAAuB,mJAkDlC,CAAC"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Requires every node parameter to declare a `default` property.
3
+ *
4
+ * A parameter is detected structurally: an object literal inside a node's
5
+ * `description` with `displayName`, `name`, and `type` all set to string
6
+ * literals — the shape every `INodeProperties` entry has. This avoids
7
+ * hardcoding the `NodePropertyTypes` union (which would silently go stale as
8
+ * new types are added) and naturally excludes `options`-array entries, which
9
+ * carry `name`/`value` but no `displayName`/`type`.
10
+ *
11
+ * Without a `default`, n8n cannot reliably initialise the parameter's value,
12
+ * which leads to inconsistent runtime behaviour in the editor and on execution.
13
+ */
14
+ import { simpleTraverse } from '@typescript-eslint/typescript-estree';
15
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
16
+ import { createRule, findClassProperty, findObjectProperty, getStringLiteralValue, isFileType, isNodeTypeClass, } from '../utils/index.js';
17
+ /** Property keys an `INodeProperties` parameter always carries as string literals. */
18
+ const REQUIRED_PARAM_KEYS = ['displayName', 'name', 'type'];
19
+ /** Returns true when the object literal has the shape of a node parameter. */
20
+ function isNodeParameter(node) {
21
+ return REQUIRED_PARAM_KEYS.every((key) => {
22
+ const property = findObjectProperty(node, key);
23
+ return property !== null && getStringLiteralValue(property.value) !== null;
24
+ });
25
+ }
26
+ export const RequireParamDefaultRule = createRule({
27
+ name: 'require-param-default',
28
+ meta: {
29
+ type: 'problem',
30
+ docs: {
31
+ description: 'Require every node parameter to declare a default value.',
32
+ },
33
+ messages: {
34
+ missingDefault: "Node parameter '{{ name }}' is missing a `default` value. Add a `default` property so the parameter initialises consistently.",
35
+ },
36
+ schema: [],
37
+ },
38
+ defaultOptions: [],
39
+ create(context) {
40
+ if (!isFileType(context.filename, '.node.ts')) {
41
+ return {};
42
+ }
43
+ const reportIfMissingDefault = (node) => {
44
+ if (!isNodeParameter(node) || findObjectProperty(node, 'default') !== null) {
45
+ return;
46
+ }
47
+ const nameProperty = findObjectProperty(node, 'name');
48
+ context.report({
49
+ node,
50
+ messageId: 'missingDefault',
51
+ data: { name: getStringLiteralValue(nameProperty?.value ?? null) ?? '' },
52
+ });
53
+ };
54
+ return {
55
+ // Scope to an INodeType class's `description`, then walk only that
56
+ // subtree, so helper classes and object literals elsewhere in the file
57
+ // (e.g. in method bodies) that share the parameter shape are ignored.
58
+ ClassDeclaration(node) {
59
+ if (!isNodeTypeClass(node))
60
+ return;
61
+ const description = findClassProperty(node, 'description');
62
+ if (description?.value?.type !== AST_NODE_TYPES.ObjectExpression)
63
+ return;
64
+ simpleTraverse(description.value, {
65
+ enter(child) {
66
+ if (child.type === AST_NODE_TYPES.ObjectExpression) {
67
+ reportIfMissingDefault(child);
68
+ }
69
+ },
70
+ });
71
+ },
72
+ };
73
+ },
74
+ });
75
+ //# sourceMappingURL=require-param-default.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-param-default.js","sourceRoot":"","sources":["../../src/rules/require-param-default.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,OAAO,EACN,UAAU,EACV,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,UAAU,EACV,eAAe,GACf,MAAM,mBAAmB,CAAC;AAE3B,sFAAsF;AACtF,MAAM,mBAAmB,GAAG,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAErE,8EAA8E;AAC9E,SAAS,eAAe,CAAC,IAA+B;IACvD,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACxC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/C,OAAO,QAAQ,KAAK,IAAI,IAAI,qBAAqB,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;IAC5E,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG,UAAU,CAAC;IACjD,IAAI,EAAE,uBAAuB;IAC7B,IAAI,EAAE;QACL,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACL,WAAW,EAAE,0DAA0D;SACvE;QACD,QAAQ,EAAE;YACT,cAAc,EACb,+HAA+H;SAChI;QACD,MAAM,EAAE,EAAE;KACV;IACD,cAAc,EAAE,EAAE;IAClB,MAAM,CAAC,OAAO;QACb,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,CAAC;YAC/C,OAAO,EAAE,CAAC;QACX,CAAC;QAED,MAAM,sBAAsB,GAAG,CAAC,IAA+B,EAAQ,EAAE;YACxE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,IAAI,EAAE,CAAC;gBAC5E,OAAO;YACR,CAAC;YACD,MAAM,YAAY,GAAG,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACtD,OAAO,CAAC,MAAM,CAAC;gBACd,IAAI;gBACJ,SAAS,EAAE,gBAAgB;gBAC3B,IAAI,EAAE,EAAE,IAAI,EAAE,qBAAqB,CAAC,YAAY,EAAE,KAAK,IAAI,IAAI,CAAC,IAAI,EAAE,EAAE;aACxE,CAAC,CAAC;QACJ,CAAC,CAAC;QAEF,OAAO;YACN,mEAAmE;YACnE,uEAAuE;YACvE,sEAAsE;YACtE,gBAAgB,CAAC,IAAI;gBACpB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;oBAAE,OAAO;gBACnC,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;gBAC3D,IAAI,WAAW,EAAE,KAAK,EAAE,IAAI,KAAK,cAAc,CAAC,gBAAgB;oBAAE,OAAO;gBAEzE,cAAc,CAAC,WAAW,CAAC,KAAK,EAAE;oBACjC,KAAK,CAAC,KAAK;wBACV,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,CAAC,gBAAgB,EAAE,CAAC;4BACpD,sBAAsB,CAAC,KAAK,CAAC,CAAC;wBAC/B,CAAC;oBACF,CAAC;iBACD,CAAC,CAAC;YACJ,CAAC;SACD,CAAC;IACH,CAAC;CACD,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const TriggerNodeConventionsRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"nameMissingSuffix" | "displayNameMissingTrigger" | "inputsNotEmpty", [], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
2
+ //# sourceMappingURL=trigger-node-conventions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger-node-conventions.d.ts","sourceRoot":"","sources":["../../src/rules/trigger-node-conventions.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,0BAA0B,uMAgFrC,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { TSESTree } from '@typescript-eslint/utils';
2
+ import { isNodeTypeClass, findClassProperty, findObjectProperty, getStringLiteralValue, isFileType, createRule, } from '../utils/index.js';
3
+ export const TriggerNodeConventionsRule = createRule({
4
+ name: 'trigger-node-conventions',
5
+ meta: {
6
+ type: 'problem',
7
+ docs: {
8
+ description: 'Trigger nodes (class name ends with `Trigger`) must label themselves consistently as triggers',
9
+ },
10
+ messages: {
11
+ nameMissingSuffix: "Trigger node `description.name` '{{value}}' must end with 'Trigger'",
12
+ displayNameMissingTrigger: "Trigger node `description.displayName` '{{value}}' must contain 'Trigger'",
13
+ inputsNotEmpty: 'Trigger node `description.inputs` must be an empty array `[]`',
14
+ },
15
+ schema: [],
16
+ },
17
+ defaultOptions: [],
18
+ create(context) {
19
+ if (!isFileType(context.filename, '.node.ts')) {
20
+ return {};
21
+ }
22
+ return {
23
+ ClassDeclaration(node) {
24
+ if (!isNodeTypeClass(node)) {
25
+ return;
26
+ }
27
+ if (!node.id?.name.endsWith('Trigger')) {
28
+ return;
29
+ }
30
+ const descriptionProperty = findClassProperty(node, 'description');
31
+ if (descriptionProperty?.value?.type !== TSESTree.AST_NODE_TYPES.ObjectExpression) {
32
+ return;
33
+ }
34
+ const description = descriptionProperty.value;
35
+ const displayNameProperty = findObjectProperty(description, 'displayName');
36
+ const displayNameValue = displayNameProperty
37
+ ? getStringLiteralValue(displayNameProperty.value)
38
+ : null;
39
+ if (displayNameProperty &&
40
+ displayNameValue !== null &&
41
+ !displayNameValue.includes('Trigger')) {
42
+ context.report({
43
+ node: displayNameProperty.value,
44
+ messageId: 'displayNameMissingTrigger',
45
+ data: { value: displayNameValue },
46
+ });
47
+ }
48
+ const nameProperty = findObjectProperty(description, 'name');
49
+ const nameValue = nameProperty ? getStringLiteralValue(nameProperty.value) : null;
50
+ if (nameProperty && nameValue !== null && !nameValue.endsWith('Trigger')) {
51
+ context.report({
52
+ node: nameProperty.value,
53
+ messageId: 'nameMissingSuffix',
54
+ data: { value: nameValue },
55
+ });
56
+ }
57
+ const inputsProperty = findObjectProperty(description, 'inputs');
58
+ if (inputsProperty &&
59
+ !(inputsProperty.value.type === TSESTree.AST_NODE_TYPES.ArrayExpression &&
60
+ inputsProperty.value.elements.length === 0)) {
61
+ context.report({
62
+ node: inputsProperty.value,
63
+ messageId: 'inputsNotEmpty',
64
+ });
65
+ }
66
+ },
67
+ };
68
+ },
69
+ });
70
+ //# sourceMappingURL=trigger-node-conventions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger-node-conventions.js","sourceRoot":"","sources":["../../src/rules/trigger-node-conventions.ts"],"names":[],"mappings":"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"}