@mimik/eslint-plugin-logger 1.0.2 → 1.0.3

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 (3) hide show
  1. package/README.md +22 -147
  2. package/index.js +31 -44
  3. package/package.json +12 -10
package/README.md CHANGED
@@ -81,166 +81,41 @@ logger.info('User logged in', { userId: 123 }, correlationId, { type: 'audit' })
81
81
  - The rule only applies to **default imports** (e.g. `import logger from '...'`)
82
82
  - Named imports (`import { logger } from '...'`) are ignored
83
83
  - Supports dot notation (`logger.info`), bracket notation with a string literal (`logger['info']`), and bracket notation with a variable (`logger[level]`)
84
- - For bracket notation with a string literal, the value must be a recognised log level
84
+ - For bracket notation with a string literal, the value must be a recognized log level
85
85
  - For bracket notation with a variable, the call is always validated (the variable is assumed to hold a valid level)
86
86
  - Minimum 2 arguments, maximum 4
87
87
  - `message` must be a string (when passed as a literal)
88
88
  - `correlationId` must be a string (when passed as a literal)
89
89
  - `options` object must contain a `type` property with a string value
90
- - When 2 arguments are passed and the 2nd is an object literal, it is treated as `(message, meta)` with a missing `correlationId`
90
+ - When 2 arguments are passed and the 2nd is an object or array literal, it is treated as `(message, meta)` with a missing `correlationId`
91
91
  - When 3 arguments are passed, the 2nd argument type determines the signature:
92
92
  - Object literal → `(message, meta, correlationId)`
93
93
  - Otherwise → `(message, correlationId, options)`
94
94
 
95
95
  ## API Reference
96
96
 
97
- ## Constants
98
-
99
- <dl>
100
- <dt><a href="#plugin">plugin</a> : <code>Object</code></dt>
101
- <dd><p>ESLint plugin for validating logger call arguments.</p>
102
- </dd>
103
- </dl>
104
-
105
- ## Functions
106
-
107
- <dl>
108
- <dt><a href="#isNonStringLiteral">isNonStringLiteral(node)</a> ⇒ <code>boolean</code></dt>
109
- <dd><p>Check whether an AST node is a non-string literal (number, boolean, null).</p>
110
- </dd>
111
- <dt><a href="#isObjectNode">isObjectNode(node)</a> ⇒ <code>boolean</code></dt>
112
- <dd><p>Check whether an AST node is an object expression.</p>
113
- </dd>
114
- <dt><a href="#isTypeKey">isTypeKey(prop)</a> ⇒ <code>boolean</code></dt>
115
- <dd><p>Check whether a property node has the key <code>type</code> (identifier or string literal).</p>
116
- </dd>
117
- <dt><a href="#findTypeProperty">findTypeProperty(node)</a> ⇒ <code>Object</code> | <code>undefined</code></dt>
118
- <dd><p>Find the <code>type</code> property node inside an ObjectExpression.
119
- Handles both identifier keys (<code>{ type: ... }</code>) and string-literal keys (<code>{ &quot;type&quot;: ... }</code>).</p>
120
- </dd>
121
- <dt><a href="#validateOptions">validateOptions(context, optionsArg, level)</a></dt>
122
- <dd><p>Validate the options argument of a logger call.
123
- Reports an error when the options object is missing a <code>type</code> property or when the
124
- <code>type</code> value is a non-string literal. Variable references (e.g. <code>{ type: someVar }</code>)
125
- are allowed because their runtime type cannot be determined statically.</p>
126
- </dd>
127
- <dt><a href="#resolveLevel">resolveLevel(callee)</a> ⇒ <code>string</code> | <code>null</code></dt>
128
- <dd><p>Resolve the log level from a MemberExpression callee.
129
- Supports dot notation (<code>logger.info</code>), bracket notation with a string literal
130
- (<code>logger[&#39;info&#39;]</code>), and bracket notation with a variable (<code>logger[level]</code>).
131
- For string literals the value must be a recognised level; variables are assumed
132
- to hold a valid level and the variable name is returned for error messages.</p>
133
- </dd>
134
- <dt><a href="#validateStringArg">validateStringArg(context, argNode, level, messageId)</a></dt>
135
- <dd><p>Validate that a logger argument is a string when it is a literal.
136
- Non-literal nodes (identifiers, call expressions) are skipped because their
137
- runtime type cannot be determined statically.</p>
138
- </dd>
139
- </dl>
140
-
141
- <a name="plugin"></a>
142
-
143
- ## plugin : <code>Object</code>
144
- ESLint plugin for validating logger call arguments.
145
-
146
- **Kind**: global constant
147
- <a name="isNonStringLiteral"></a>
148
-
149
- ## isNonStringLiteral(node) ⇒ <code>boolean</code>
150
- Check whether an AST node is a non-string literal (number, boolean, null).
151
-
152
- **Kind**: global function
153
- **Returns**: <code>boolean</code> - True when the node is a literal whose value is not a string.
154
-
155
- | Param | Type | Description |
156
- | --- | --- | --- |
157
- | node | <code>Object</code> | The AST node to check. |
158
-
159
- <a name="isObjectNode"></a>
160
-
161
- ## isObjectNode(node) ⇒ <code>boolean</code>
162
- Check whether an AST node is an object expression.
163
-
164
- **Kind**: global function
165
- **Returns**: <code>boolean</code> - True when the node is an ObjectExpression.
166
-
167
- | Param | Type | Description |
168
- | --- | --- | --- |
169
- | node | <code>Object</code> | The AST node to check. |
170
-
171
- <a name="isTypeKey"></a>
172
-
173
- ## isTypeKey(prop) ⇒ <code>boolean</code>
174
- Check whether a property node has the key `type` (identifier or string literal).
175
-
176
- **Kind**: global function
177
- **Returns**: <code>boolean</code> - True when the key is `type`.
178
-
179
- | Param | Type | Description |
180
- | --- | --- | --- |
181
- | prop | <code>Object</code> | The property node. |
182
-
183
- <a name="findTypeProperty"></a>
184
-
185
- ## findTypeProperty(node) ⇒ <code>Object</code> \| <code>undefined</code>
186
- Find the `type` property node inside an ObjectExpression.
187
- Handles both identifier keys (`{ type: ... }`) and string-literal keys (`{ "type": ... }`).
188
-
189
- **Kind**: global function
190
- **Returns**: <code>Object</code> \| <code>undefined</code> - The property node, or undefined if not found.
191
-
192
- | Param | Type | Description |
193
- | --- | --- | --- |
194
- | node | <code>Object</code> | The object expression node. |
195
-
196
- <a name="validateOptions"></a>
197
-
198
- ## validateOptions(context, optionsArg, level)
199
- Validate the options argument of a logger call.
200
- Reports an error when the options object is missing a `type` property or when the
201
- `type` value is a non-string literal. Variable references (e.g. `{ type: someVar }`)
202
- are allowed because their runtime type cannot be determined statically.
203
-
204
- **Kind**: global function
205
-
206
- | Param | Type | Description |
207
- | --- | --- | --- |
208
- | context | <code>Object</code> | The ESLint rule context. |
209
- | optionsArg | <code>Object</code> | The options argument AST node. |
210
- | level | <code>string</code> | The logger level (e.g. 'info', 'error'). |
211
-
212
- <a name="resolveLevel"></a>
213
-
214
- ## resolveLevel(callee) ⇒ <code>string</code> \| <code>null</code>
215
- Resolve the log level from a MemberExpression callee.
216
- Supports dot notation (`logger.info`), bracket notation with a string literal
217
- (`logger['info']`), and bracket notation with a variable (`logger[level]`).
218
- For string literals the value must be a recognised level; variables are assumed
219
- to hold a valid level and the variable name is returned for error messages.
97
+ The plugin exports a single object with the following shape:
220
98
 
221
- **Kind**: global function
222
- **Returns**: <code>string</code> \| <code>null</code> - The resolved level name, or null when the call should be skipped.
223
-
224
- | Param | Type | Description |
225
- | --- | --- | --- |
226
- | callee | <code>Object</code> | The MemberExpression callee node. |
227
-
228
- <a name="validateStringArg"></a>
229
-
230
- ## validateStringArg(context, argNode, level, messageId)
231
- Validate that a logger argument is a string when it is a literal.
232
- Non-literal nodes (identifiers, call expressions) are skipped because their
233
- runtime type cannot be determined statically.
234
-
235
- **Kind**: global function
236
-
237
- | Param | Type | Description |
238
- | --- | --- | --- |
239
- | context | <code>Object</code> | The ESLint rule context. |
240
- | argNode | <code>Object</code> | The argument AST node. |
241
- | level | <code>string</code> | The logger level (e.g. 'info', 'error'). |
242
- | messageId | <code>string</code> | The ESLint message ID to report on failure. |
99
+ ```js
100
+ {
101
+ rules: {
102
+ 'validate-logger-args': { meta, create(context) }
103
+ }
104
+ }
105
+ ```
243
106
 
107
+ ### Error Messages
108
+
109
+ | Message ID | Description |
110
+ |---|---|
111
+ | `tooFewArguments` | Fewer than 2 arguments passed |
112
+ | `tooManyArguments` | More than 4 arguments passed |
113
+ | `messageNotString` | First argument is a non-string literal |
114
+ | `correlationIdNotString` | correlationId argument is a non-string literal |
115
+ | `missingCorrelationId` | 2nd argument is an object or array — correlationId is missing |
116
+ | `optionsNotObject` | Options argument is a literal instead of an object |
117
+ | `optionsMissingType` | Options object does not contain a `type` property |
118
+ | `optionsTypeNotString` | Options `type` property is a non-string literal |
244
119
 
245
120
  ## License
246
121
 
package/index.js CHANGED
@@ -3,49 +3,39 @@ const MIN_ARGS = 2;
3
3
  const THREE_ARGS = 3;
4
4
  const MAX_ARGS = 4;
5
5
 
6
- /**
7
- * Check whether an AST node is a non-string literal (number, boolean, null).
8
- * @param {Object} node - The AST node to check.
9
- * @returns {boolean} True when the node is a literal whose value is not a string.
10
- */
6
+ /** @private True when node is a literal whose value is not a string. */
11
7
  const isNonStringLiteral = node => node.type === 'Literal' && typeof node.value !== 'string';
12
8
 
13
- /**
14
- * Check whether an AST node is an object expression.
15
- * @param {Object} node - The AST node to check.
16
- * @returns {boolean} True when the node is an ObjectExpression.
17
- */
9
+ /** @private True when node is an ObjectExpression. */
18
10
  const isObjectNode = node => node.type === 'ObjectExpression';
19
11
 
20
- /**
21
- * Check whether a property node has the key `type` (identifier or string literal).
22
- * @param {Object} prop - The property node.
23
- * @returns {boolean} True when the key is `type`.
24
- */
12
+ /** @private True when the property key is `type` (identifier or string literal). */
25
13
  const isTypeKey = prop => prop.type === 'Property'
26
14
  && !prop.computed
27
15
  && ((prop.key.type === 'Identifier' && prop.key.name === 'type')
28
16
  || (prop.key.type === 'Literal' && prop.key.value === 'type'));
29
17
 
30
- /**
31
- * Find the `type` property node inside an ObjectExpression.
32
- * Handles both identifier keys (`{ type: ... }`) and string-literal keys (`{ "type": ... }`).
33
- * @param {Object} node - The object expression node.
34
- * @returns {Object|undefined} The property node, or undefined if not found.
35
- */
18
+ /** @private Find the `type` property inside an ObjectExpression. */
36
19
  const findTypeProperty = node => node.properties.find(isTypeKey);
37
20
 
38
21
  /**
39
22
  * Validate the options argument of a logger call.
40
- * Reports an error when the options object is missing a `type` property or when the
41
- * `type` value is a non-string literal. Variable references (e.g. `{ type: someVar }`)
42
- * are allowed because their runtime type cannot be determined statically.
43
- * @param {Object} context - The ESLint rule context.
44
- * @param {Object} optionsArg - The options argument AST node.
45
- * @param {string} level - The logger level (e.g. 'info', 'error').
23
+ * Reports when options is any literal (not an object), when the object is missing
24
+ * a `type` property, or when `type` is a non-string literal.
25
+ * Identifiers and other expressions are skipped (runtime type unknown).
26
+ * @private
46
27
  */
47
28
  const validateOptions = (context, optionsArg, level) => {
48
- if (!isObjectNode(optionsArg)) return;
29
+ if (!isObjectNode(optionsArg)) {
30
+ if (optionsArg.type === 'Literal') {
31
+ context.report({
32
+ node: optionsArg,
33
+ messageId: 'optionsNotObject',
34
+ data: { level, actualType: typeof optionsArg.value },
35
+ });
36
+ }
37
+ return;
38
+ }
49
39
  const typeProp = findTypeProperty(optionsArg);
50
40
  if (!typeProp) {
51
41
  context.report({
@@ -65,12 +55,8 @@ const validateOptions = (context, optionsArg, level) => {
65
55
 
66
56
  /**
67
57
  * Resolve the log level from a MemberExpression callee.
68
- * Supports dot notation (`logger.info`), bracket notation with a string literal
69
- * (`logger['info']`), and bracket notation with a variable (`logger[level]`).
70
- * For string literals the value must be a recognised level; variables are assumed
71
- * to hold a valid level and the variable name is returned for error messages.
72
- * @param {Object} callee - The MemberExpression callee node.
73
- * @returns {string|null} The resolved level name, or null when the call should be skipped.
58
+ * Returns the level name for dot/bracket notation, or null to skip.
59
+ * @private
74
60
  */
75
61
  const resolveLevel = (callee) => {
76
62
  if (!callee.computed) {
@@ -89,13 +75,9 @@ const resolveLevel = (callee) => {
89
75
  };
90
76
 
91
77
  /**
92
- * Validate that a logger argument is a string when it is a literal.
93
- * Non-literal nodes (identifiers, call expressions) are skipped because their
94
- * runtime type cannot be determined statically.
95
- * @param {Object} context - The ESLint rule context.
96
- * @param {Object} argNode - The argument AST node.
97
- * @param {string} level - The logger level (e.g. 'info', 'error').
98
- * @param {string} messageId - The ESLint message ID to report on failure.
78
+ * Report when a literal argument is not a string.
79
+ * Non-literal nodes are skipped (runtime type unknown).
80
+ * @private
99
81
  */
100
82
  const validateStringArg = (context, argNode, level, messageId) => {
101
83
  if (isNonStringLiteral(argNode)) {
@@ -108,10 +90,14 @@ const validateStringArg = (context, argNode, level, messageId) => {
108
90
  };
109
91
 
110
92
  /**
111
- * ESLint plugin for validating logger call arguments.
112
- * @type {Object}
93
+ * ESLint plugin that validates logger call argument signatures.
94
+ * Only tracks default imports (`import logger from '...'`).
113
95
  */
114
96
  const plugin = {
97
+ meta: {
98
+ name: '@mimik/eslint-plugin-logger',
99
+ version: '2.0.8',
100
+ },
115
101
  rules: {
116
102
  'validate-logger-args': {
117
103
  meta: {
@@ -126,7 +112,8 @@ const plugin = {
126
112
  tooManyArguments: 'logger.{{ level }}() accepts at most 4 arguments: (message, meta, correlationId, options). Found {{ count }}.',
127
113
  messageNotString: 'logger.{{ level }}() message (1st argument) must be a string. Found {{ actualType }}.',
128
114
  correlationIdNotString: 'logger.{{ level }}() correlationId must be a string. Found {{ actualType }}.',
129
- missingCorrelationId: 'logger.{{ level }}() called with (message, meta) but missing required correlationId. Expected (message, meta, correlationId).',
115
+ missingCorrelationId: 'logger.{{ level }}() 2nd argument is an object or array — missing required correlationId. Expected (message, meta, correlationId).',
116
+ optionsNotObject: 'logger.{{ level }}() options argument must be an object. Found {{ actualType }}.',
130
117
  optionsMissingType: 'logger.{{ level }}() options object must contain a "type" property.',
131
118
  optionsTypeNotString: 'logger.{{ level }}() options "type" property must be a string.',
132
119
  },
package/package.json CHANGED
@@ -1,13 +1,17 @@
1
1
  {
2
2
  "name": "@mimik/eslint-plugin-logger",
3
- "version": "1.0.2",
4
- "description": "validation of the logger parameters for mimik",
3
+ "version": "1.0.3",
4
+ "description": "Validation of logger call parameters for mimik services",
5
5
  "main": "./index.js",
6
6
  "type": "module",
7
+ "exports": "./index.js",
8
+ "engines": {
9
+ "node": ">=24.0.0"
10
+ },
7
11
  "scripts": {
8
- "lint": "eslint . --no-error-on-unmatched-pattern",
9
12
  "docs": "jsdoc2md --template docs/README.hbs index.js > README.md",
10
- "test": "mocha --reporter mochawesome test/ --recursive",
13
+ "lint": "eslint . --no-error-on-unmatched-pattern",
14
+ "test": "mocha --reporter mochawesome --bail --exit --check-leaks test/",
11
15
  "test-ci": "c8 --reporter=lcov --reporter=text npm test",
12
16
  "prepublishOnly": "npm run docs && npm run lint && npm run test-ci",
13
17
  "commit-ready": "npm run docs && npm run lint && npm run test-ci"
@@ -17,22 +21,20 @@
17
21
  "eslint",
18
22
  "eslint-plugin",
19
23
  "eslintplugin",
20
- "logger"
24
+ "logger",
25
+ "@mimik/sumologic-winston-logger"
21
26
  ],
22
27
  "author": "mimik technology inc <support@mimik.com> (https://developer.mimik.com/)",
23
28
  "license": "MIT",
24
- "engines": {
25
- "node": ">=24"
26
- },
27
29
  "repository": {
28
30
  "type": "git",
29
31
  "url": "git+https://bitbucket.org/mimiktech/eslint-plugin-logger.git"
30
32
  },
31
33
  "devDependencies": {
32
- "@eslint/js": "9.39.3",
34
+ "@eslint/js": "9.39.4",
33
35
  "@stylistic/eslint-plugin": "5.10.0",
34
36
  "c8": "11.0.0",
35
- "eslint": "9.39.3",
37
+ "eslint": "9.39.4",
36
38
  "eslint-plugin-import": "2.32.0",
37
39
  "globals": "17.4.0",
38
40
  "husky": "9.1.7",