eslint-plugin-crisp 1.7.7 → 1.7.9

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,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-crisp",
3
- "version": "1.7.7",
3
+ "version": "1.7.9",
4
4
  "description": "Custom ESLint Rules for Crisp",
5
5
  "author": "Crisp IM SAS",
6
6
  "main": "index.js",
@@ -94,6 +94,63 @@ function isReference(node) {
94
94
  );
95
95
  }
96
96
 
97
+ // Checks a fallback expression like `value || "none"` or `value ?? other`
98
+ function isFallback(node) {
99
+ node = unwrapTransparentExpression(node);
100
+
101
+ if (
102
+ !node ||
103
+ node.type !== "LogicalExpression" ||
104
+ (node.operator !== "||" && node.operator !== "??")
105
+ ) {
106
+ return false;
107
+ }
108
+
109
+ const isOperandValid = (operand) => {
110
+ operand = unwrapTransparentExpression(operand);
111
+
112
+ return (
113
+ operand.type === "Literal" ||
114
+ isReference(operand) ||
115
+ isFallback(operand)
116
+ );
117
+ };
118
+
119
+ return isReference(node.left) || isFallback(node.left)
120
+ ? isOperandValid(node.right)
121
+ : false;
122
+ }
123
+
124
+ // Checks a logger argument value is a reference, a fallback or an object of those
125
+ function isAllowedValue(node) {
126
+ return isReference(node) || isFallback(node) || isReferenceObject(node);
127
+ }
128
+
129
+ // Checks an inline object only contains references (no computed values)
130
+ function isReferenceObject(node) {
131
+ node = unwrapTransparentExpression(node);
132
+
133
+ if (!node || node.type !== "ObjectExpression") {
134
+ return false;
135
+ }
136
+
137
+ return node.properties.every((property) => {
138
+ if (property.type === "SpreadElement") {
139
+ return isReference(property.argument);
140
+ }
141
+
142
+ if (property.type !== "Property" || property.kind !== "init") {
143
+ return false;
144
+ }
145
+
146
+ if (property.computed && !isReference(property.key)) {
147
+ return false;
148
+ }
149
+
150
+ return isAllowedValue(property.value);
151
+ });
152
+ }
153
+
97
154
  export default {
98
155
  meta: {
99
156
  type: "suggestion",
@@ -107,7 +164,7 @@ export default {
107
164
  message:
108
165
  "Logger messages must be single-line, double-quoted string literals.",
109
166
  reference:
110
- "Logger interpolation arguments must be references, not computed expressions."
167
+ "Logger interpolation arguments must be references, fallbacks (`||`, `??`) or inline objects of those, not computed expressions."
111
168
  }
112
169
  },
113
170
 
@@ -136,7 +193,7 @@ export default {
136
193
  }
137
194
 
138
195
  for (const value of values) {
139
- if (!isReference(value)) {
196
+ if (!isAllowedValue(value)) {
140
197
  context.report({
141
198
  node: value,
142
199
  messageId: "reference"
@@ -15,6 +15,13 @@ ruleTester.run("logger-arguments", rule, {
15
15
  value
16
16
  );`,
17
17
  "App.logger.info(\"This intentionally long logger message may exceed the usual source line length when necessary.\");",
18
+ "App.logger.debug(\"Loaded value: %s\", value || \"default\");",
19
+ "App.logger.debug(\"Loaded value: %s\", this.value ?? \"none\");",
20
+ "App.logger.debug(\"Loaded value: %s\", first || second || \"none\");",
21
+ "App.logger.debug(\"Loaded value: %s\", { user: userId || \"none\" });",
22
+ "App.logger.warn(\"Shutting down\", { bufferedCount });",
23
+ "App.logger.warn(\"Shutting down\", { count: this.count, ...meta });",
24
+ "App.logger.warn(\"Shutting down\", { nested: { bufferedCount } }, logMeta);",
18
25
  "App.logger.child({ namespace: \"worker\" });",
19
26
  "console.info(`Unrelated logger calls are ignored: ${value}`);"
20
27
  ],
@@ -77,7 +84,15 @@ ruleTester.run("logger-arguments", rule, {
77
84
  ]
78
85
  },
79
86
  {
80
- code: "App.logger.debug(\"Loaded value: %s\", value || \"default\");",
87
+ code: "App.logger.debug(\"Loaded value: %s\", value || compute());",
88
+ errors: [
89
+ {
90
+ messageId: "reference"
91
+ }
92
+ ]
93
+ },
94
+ {
95
+ code: "App.logger.debug(\"Loaded value: %s\", value && \"default\");",
81
96
  errors: [
82
97
  {
83
98
  messageId: "reference"
@@ -93,7 +108,15 @@ ruleTester.run("logger-arguments", rule, {
93
108
  ]
94
109
  },
95
110
  {
96
- code: "App.logger.debug(\"Loaded value: %s\", { value });",
111
+ code: "App.logger.debug(\"Loaded value: %s\", { value: value.trim() });",
112
+ errors: [
113
+ {
114
+ messageId: "reference"
115
+ }
116
+ ]
117
+ },
118
+ {
119
+ code: "App.logger.debug(\"Loaded value: %s\", { value: 3 });",
97
120
  errors: [
98
121
  {
99
122
  messageId: "reference"
@@ -109,7 +132,7 @@ ruleTester.run("logger-arguments", rule, {
109
132
  ]
110
133
  },
111
134
  {
112
- code: "App.logger.debug(\"Values: %s / %s\", values.join(\", \"), fallback || \"none\");",
135
+ code: "App.logger.debug(\"Values: %s / %s\", values.join(\", \"), fallback || compute());",
113
136
  errors: [
114
137
  {
115
138
  messageId: "reference"