@clipboard-health/eslint-plugin 0.4.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@clipboard-health/eslint-plugin",
3
3
  "description": "Clipboard's ESLint Plugin",
4
- "version": "0.4.0",
4
+ "version": "0.5.0",
5
5
  "dependencies": {
6
6
  "@typescript-eslint/utils": "8.33.0",
7
7
  "tslib": "2.8.1"
package/src/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export declare const rules: {
2
2
  "enforce-ts-rest-in-controllers": import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"missingDecorator" | "missingReturn" | "decoratorNotFromPackage" | "callNotFromPackage", [], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
3
3
  "require-http-module-factory": import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"requireFactory" | "wrongPackage" | "noImport", [], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
4
+ "forbid-object-assign": import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"objectAssignReturnValueUsed", unknown[], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
4
5
  };
package/src/index.js CHANGED
@@ -3,9 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.rules = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const enforce_ts_rest_in_controllers_1 = tslib_1.__importDefault(require("./lib/rules/enforce-ts-rest-in-controllers"));
6
+ const forbid_object_assign_1 = tslib_1.__importDefault(require("./lib/rules/forbid-object-assign"));
6
7
  const require_http_module_factory_1 = tslib_1.__importDefault(require("./lib/rules/require-http-module-factory"));
7
8
  exports.rules = {
8
9
  "enforce-ts-rest-in-controllers": enforce_ts_rest_in_controllers_1.default,
9
10
  "require-http-module-factory": require_http_module_factory_1.default,
11
+ "forbid-object-assign": forbid_object_assign_1.default,
10
12
  };
11
13
  //# sourceMappingURL=index.js.map
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/eslint-plugin/src/index.ts"],"names":[],"mappings":";;;;AAAA,wHAAoF;AACpF,kHAA+E;AAElE,QAAA,KAAK,GAAG;IACnB,gCAAgC,EAAE,wCAA0B;IAC5D,6BAA6B,EAAE,qCAAwB;CACxD,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/eslint-plugin/src/index.ts"],"names":[],"mappings":";;;;AAAA,wHAAoF;AACpF,oGAAkE;AAClE,kHAA+E;AAElE,QAAA,KAAK,GAAG;IACnB,gCAAgC,EAAE,wCAA0B;IAC5D,6BAA6B,EAAE,qCAAwB;IACvD,sBAAsB,EAAE,8BAAkB;CAC3C,CAAC"}
@@ -0,0 +1,2 @@
1
+ declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<"objectAssignReturnValueUsed", unknown[], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
2
+ export default rule;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const createRule_1 = tslib_1.__importDefault(require("../../createRule"));
6
+ const tsEsTreeTypeGuards_1 = require("../tsEsTreeTypeGuards");
7
+ function reportViolationIfObjectAssignReturnValueUsed(context, expression) {
8
+ const unwrappedExpression = unwrapExpression(expression);
9
+ if (isObjectAssignCall(unwrappedExpression)) {
10
+ context.report({
11
+ node: unwrappedExpression,
12
+ messageId: "objectAssignReturnValueUsed",
13
+ });
14
+ }
15
+ }
16
+ // Returns true iff the expression is the invocation of `Object.assign`
17
+ function isObjectAssignCall(expression) {
18
+ // Verify that the passed in expression is a function call
19
+ if (expression.type !== utils_1.AST_NODE_TYPES.CallExpression) {
20
+ return false;
21
+ }
22
+ // Verify that the expression is a member function on an object, e.g. x.call() or f().call()
23
+ const { callee } = expression;
24
+ if (!(0, tsEsTreeTypeGuards_1.isMemberExpression)(callee)) {
25
+ return false;
26
+ }
27
+ // Verify that the function call is on an object identity, e.g. X.call() (but not f().call())
28
+ const { object } = callee;
29
+ if (!(0, tsEsTreeTypeGuards_1.isIdentifierExpression)(object)) {
30
+ return false;
31
+ }
32
+ // Verify that the function call is on the identifier referring to Object, e.g. Object.call()
33
+ if (object.name !== "Object") {
34
+ return false;
35
+ }
36
+ // Verify that the function being called is "assign"
37
+ const { property } = callee;
38
+ return property.type === utils_1.AST_NODE_TYPES.Identifier && property.name === "assign";
39
+ }
40
+ /*
41
+ * Unwraps some wrapped expressions to get to the base expression. For example,
42
+ * Unwraps "return x as Type" to "return x" and unwraps "(x)!" to "x"
43
+ * This is necessary so that our rule can lint the underlying expression for violations
44
+ *
45
+ * If you want to reuse this in a wider use case, you may have to expand this to specifically deal
46
+ * with parentheses and other cases.
47
+ */
48
+ function unwrapExpression(expression) {
49
+ if ((0, tsEsTreeTypeGuards_1.isTypescriptTypedExpression)(expression) || (0, tsEsTreeTypeGuards_1.isNonNullAssertion)(expression)) {
50
+ return unwrapExpression(expression.expression);
51
+ }
52
+ return expression;
53
+ }
54
+ const rule = (0, createRule_1.default)({
55
+ name: "forbid-object-assign",
56
+ defaultOptions: [],
57
+ meta: {
58
+ type: "problem",
59
+ docs: {
60
+ description: "Favor object spread operator {...obj} over Object.assign",
61
+ },
62
+ schema: [],
63
+ messages: {
64
+ objectAssignReturnValueUsed: "Use the object spread operator. Object.assign mutates the first argument which is confusing. See https://www.notion.so/BP-TypeScript-Style-Guide-5d4c24aea08a4b9f9feb03550f2c5310?source=copy_link#2568643321f4805ba04ecce1082b2b38 for more information.",
65
+ },
66
+ },
67
+ create(context) {
68
+ return {
69
+ VariableDeclarator(node) {
70
+ if (node.init === null) {
71
+ return;
72
+ }
73
+ reportViolationIfObjectAssignReturnValueUsed(context, node.init);
74
+ },
75
+ AssignmentExpression(node) {
76
+ const rightHandSideOfAssignment = node.right;
77
+ reportViolationIfObjectAssignReturnValueUsed(context, rightHandSideOfAssignment);
78
+ },
79
+ ReturnStatement(node) {
80
+ if (node.argument === null) {
81
+ return;
82
+ }
83
+ reportViolationIfObjectAssignReturnValueUsed(context, node.argument);
84
+ },
85
+ MemberExpression(node) {
86
+ reportViolationIfObjectAssignReturnValueUsed(context, node.object);
87
+ },
88
+ TemplateLiteral(node) {
89
+ node.expressions.forEach((expression) => {
90
+ reportViolationIfObjectAssignReturnValueUsed(context, expression);
91
+ });
92
+ },
93
+ ArrayExpression(node) {
94
+ node.elements.forEach((expression) => {
95
+ if (expression === null) {
96
+ return;
97
+ }
98
+ if (expression.type === utils_1.AST_NODE_TYPES.SpreadElement) {
99
+ reportViolationIfObjectAssignReturnValueUsed(context, expression.argument);
100
+ }
101
+ else {
102
+ reportViolationIfObjectAssignReturnValueUsed(context, expression);
103
+ }
104
+ });
105
+ },
106
+ CallExpression(node) {
107
+ node.arguments.forEach((argument) => {
108
+ if (argument.type === utils_1.AST_NODE_TYPES.SpreadElement) {
109
+ reportViolationIfObjectAssignReturnValueUsed(context, argument.argument);
110
+ }
111
+ else {
112
+ reportViolationIfObjectAssignReturnValueUsed(context, argument);
113
+ }
114
+ });
115
+ },
116
+ };
117
+ },
118
+ });
119
+ exports.default = rule;
120
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/eslint-plugin/src/lib/rules/forbid-object-assign/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { TSESTree } from "@typescript-eslint/utils";
2
+ export declare function isMemberExpression(expression: TSESTree.Expression | TSESTree.Super): expression is TSESTree.MemberExpression;
3
+ export declare function isIdentifierExpression(expression: TSESTree.Expression): expression is TSESTree.Identifier;
4
+ export declare function isTypescriptTypedExpression(expression: TSESTree.Expression): expression is TSESTree.TSAsExpression | TSESTree.TSTypeAssertion;
5
+ export declare function isNonNullAssertion(expression: TSESTree.Expression): expression is TSESTree.TSNonNullExpression;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isMemberExpression = isMemberExpression;
4
+ exports.isIdentifierExpression = isIdentifierExpression;
5
+ exports.isTypescriptTypedExpression = isTypescriptTypedExpression;
6
+ exports.isNonNullAssertion = isNonNullAssertion;
7
+ const utils_1 = require("@typescript-eslint/utils");
8
+ function isMemberExpression(expression) {
9
+ return expression.type === utils_1.AST_NODE_TYPES.MemberExpression;
10
+ }
11
+ function isIdentifierExpression(expression) {
12
+ return expression.type === utils_1.AST_NODE_TYPES.Identifier;
13
+ }
14
+ function isTypescriptTypedExpression(expression) {
15
+ return (expression.type === utils_1.AST_NODE_TYPES.TSAsExpression ||
16
+ expression.type === utils_1.AST_NODE_TYPES.TSTypeAssertion);
17
+ }
18
+ function isNonNullAssertion(expression) {
19
+ return expression.type === utils_1.AST_NODE_TYPES.TSNonNullExpression;
20
+ }
21
+ //# sourceMappingURL=tsEsTreeTypeGuards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsEsTreeTypeGuards.js","sourceRoot":"","sources":["../../../../../../packages/eslint-plugin/src/lib/rules/tsEsTreeTypeGuards.ts"],"names":[],"mappings":";;AAGA,gDAIC;AAED,wDAIC;AAED,kEAOC;AAED,gDAIC;AA3BD,oDAA0D;AAE1D,SAAgB,kBAAkB,CAChC,UAAgD;IAEhD,OAAO,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,gBAAgB,CAAC;AAC7D,CAAC;AAED,SAAgB,sBAAsB,CACpC,UAA+B;IAE/B,OAAO,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,UAAU,CAAC;AACvD,CAAC;AAED,SAAgB,2BAA2B,CACzC,UAA+B;IAE/B,OAAO,CACL,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,cAAc;QACjD,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,eAAe,CACnD,CAAC;AACJ,CAAC;AAED,SAAgB,kBAAkB,CAChC,UAA+B;IAE/B,OAAO,UAAU,CAAC,IAAI,KAAK,sBAAc,CAAC,mBAAmB,CAAC;AAChE,CAAC"}