@blumintinc/eslint-plugin-blumint 1.1.5 → 1.1.7

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/lib/index.js CHANGED
@@ -34,10 +34,12 @@ const require_image_overlayed_1 = __importDefault(require("./rules/require-image
34
34
  const require_usememo_object_literals_1 = require("./rules/require-usememo-object-literals");
35
35
  const enforce_safe_stringify_1 = require("./rules/enforce-safe-stringify");
36
36
  const avoid_utils_directory_1 = require("./rules/avoid-utils-directory");
37
+ const no_entire_object_hook_deps_1 = require("./rules/no-entire-object-hook-deps");
38
+ const enforce_firestore_path_utils_1 = require("./rules/enforce-firestore-path-utils");
37
39
  module.exports = {
38
40
  meta: {
39
41
  name: '@blumintinc/eslint-plugin-blumint',
40
- version: '1.1.5',
42
+ version: '1.1.7',
41
43
  },
42
44
  parseOptions: {
43
45
  ecmaVersion: 2020,
@@ -47,6 +49,7 @@ module.exports = {
47
49
  plugins: ['@blumintinc/blumint'],
48
50
  rules: {
49
51
  '@blumintinc/blumint/avoid-utils-directory': 'error',
52
+ '@blumintinc/blumint/enforce-firestore-path-utils': 'error',
50
53
  '@blumintinc/blumint/no-jsx-whitespace-literal': 'error',
51
54
  '@blumintinc/blumint/array-methods-this-context': 'warn',
52
55
  '@blumintinc/blumint/class-methods-read-top-to-bottom': 'warn',
@@ -77,6 +80,7 @@ module.exports = {
77
80
  '@blumintinc/blumint/require-image-overlayed': 'error',
78
81
  '@blumintinc/blumint/require-usememo-object-literals': 'error',
79
82
  '@blumintinc/blumint/enforce-safe-stringify': 'error',
83
+ '@blumintinc/blumint/no-entire-object-hook-deps': 'error',
80
84
  },
81
85
  },
82
86
  },
@@ -112,6 +116,8 @@ module.exports = {
112
116
  'require-usememo-object-literals': require_usememo_object_literals_1.requireUseMemoObjectLiterals,
113
117
  'enforce-safe-stringify': enforce_safe_stringify_1.enforceStableStringify,
114
118
  'avoid-utils-directory': avoid_utils_directory_1.avoidUtilsDirectory,
119
+ 'no-entire-object-hook-deps': no_entire_object_hook_deps_1.noEntireObjectHookDeps,
120
+ 'enforce-firestore-path-utils': enforce_firestore_path_utils_1.enforceFirestorePathUtils,
115
121
  },
116
122
  };
117
123
  //# sourceMappingURL=index.js.map
@@ -49,10 +49,12 @@ exports.classMethodsReadTopToBottom = (0, createRule_1.createRule)({
49
49
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
50
50
  const memberNode = node.body.find((member) => getMemberName(member) === n);
51
51
  const comments = sourceCode.getCommentsBefore(memberNode);
52
- memberNode.range = [
53
- Math.min(memberNode.range[0], Math.min(...comments.map((comment) => comment.range[0]))),
54
- Math.max(memberNode.range[1], Math.max(...comments.map((comment) => comment.range[1]))),
55
- ];
52
+ memberNode.range = comments.length
53
+ ? [
54
+ Math.min(memberNode.range[0], Math.min(...comments.map((comment) => comment.range[0]))),
55
+ Math.max(memberNode.range[1], Math.max(...comments.map((comment) => comment.range[1]))),
56
+ ]
57
+ : memberNode.range;
56
58
  return sourceCode.getText(memberNode);
57
59
  })
58
60
  .join('\n');
@@ -23,6 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
23
23
  return result;
24
24
  };
25
25
  const createRule_1 = require("../utils/createRule");
26
+ const utils_1 = require("@typescript-eslint/utils");
26
27
  const ts = __importStar(require("typescript"));
27
28
  module.exports = (0, createRule_1.createRule)({
28
29
  name: 'consistent-callback-naming',
@@ -101,6 +102,34 @@ module.exports = (0, createRule_1.createRule)({
101
102
  if (propName && isPascalCase(propName)) {
102
103
  return;
103
104
  }
105
+ // Skip common non-callback props
106
+ const commonNonCallbackProps = new Set([
107
+ 'theme',
108
+ 'style',
109
+ 'className',
110
+ 'ref',
111
+ 'key',
112
+ 'component',
113
+ 'as',
114
+ 'sx',
115
+ 'css', // Emotion css prop
116
+ ]);
117
+ if (propName && commonNonCallbackProps.has(propName)) {
118
+ return;
119
+ }
120
+ // Skip props on components that commonly use function props that aren't callbacks
121
+ const parentName = node.parent?.name;
122
+ const componentName = parentName?.type === 'JSXIdentifier' ? parentName.name : undefined;
123
+ const componentsWithFunctionProps = new Set([
124
+ 'ThemeProvider',
125
+ 'Transition',
126
+ 'CSSTransition',
127
+ 'TransitionGroup',
128
+ 'SwitchTransition', // React Transition Group
129
+ ]);
130
+ if (componentName && componentsWithFunctionProps.has(componentName)) {
131
+ return;
132
+ }
104
133
  // Check if the value is a function type and not a React component
105
134
  if (isFunctionType(node.value.expression) &&
106
135
  propName &&
@@ -122,14 +151,84 @@ module.exports = (0, createRule_1.createRule)({
122
151
  'FunctionDeclaration, VariableDeclarator'(node) {
123
152
  const functionName = node.id?.type === 'Identifier' ? node.id.name : undefined;
124
153
  if (functionName && functionName.startsWith('handle') && node.id) {
154
+ // Skip autofixing for "handler" and "handlers"
155
+ if (functionName === 'handler' || functionName === 'handlers') {
156
+ context.report({
157
+ node,
158
+ messageId: 'callbackFunctionPrefix',
159
+ });
160
+ return;
161
+ }
162
+ // Skip autofixing for class parameters and getters
163
+ const parent = node.parent;
164
+ if (parent?.type === utils_1.AST_NODE_TYPES.PropertyDefinition || parent?.type === utils_1.AST_NODE_TYPES.MethodDefinition) {
165
+ context.report({
166
+ node,
167
+ messageId: 'callbackFunctionPrefix',
168
+ });
169
+ return;
170
+ }
171
+ // Get all references to this variable
172
+ const scope = context.getScope();
173
+ const variable = scope.variables.find(v => v.name === functionName);
174
+ const references = new Set(variable?.references ?? []);
175
+ // Get references from all scopes
176
+ const allScopes = [scope];
177
+ let currentScope = scope;
178
+ while (currentScope.upper) {
179
+ currentScope = currentScope.upper;
180
+ allScopes.push(currentScope);
181
+ }
182
+ // Get references from all scopes and their children
183
+ for (const s of allScopes) {
184
+ // Get references from current scope
185
+ const currentVar = s.variables.find(v => v.name === functionName);
186
+ if (currentVar) {
187
+ currentVar.references.forEach(ref => references.add(ref));
188
+ }
189
+ // Get references from child scopes
190
+ const childScopes = s.childScopes;
191
+ for (const childScope of childScopes) {
192
+ const childVar = childScope.variables.find(v => v.name === functionName);
193
+ if (childVar) {
194
+ childVar.references.forEach(ref => references.add(ref));
195
+ }
196
+ }
197
+ }
198
+ // Get references from sibling scopes
199
+ const siblingScopes = scope.upper?.childScopes ?? [];
200
+ for (const siblingScope of siblingScopes) {
201
+ if (siblingScope !== scope) {
202
+ const siblingVar = siblingScope.variables.find(v => v.name === functionName);
203
+ if (siblingVar) {
204
+ siblingVar.references.forEach(ref => references.add(ref));
205
+ }
206
+ }
207
+ }
208
+ // Get references from global scope
209
+ const sourceCode = context.getSourceCode();
210
+ if (sourceCode.scopeManager?.globalScope) {
211
+ const globalVar = sourceCode.scopeManager.globalScope.variables.find(v => v.name === functionName);
212
+ if (globalVar) {
213
+ globalVar.references.forEach(ref => references.add(ref));
214
+ }
215
+ }
125
216
  context.report({
126
217
  node,
127
218
  messageId: 'callbackFunctionPrefix',
128
- fix(fixer) {
219
+ *fix(fixer) {
129
220
  // Remove 'handle' prefix and convert first character to lowercase
130
221
  const newName = functionName.slice(6).charAt(0).toLowerCase() +
131
222
  functionName.slice(7);
132
- return fixer.replaceText(node.id, newName);
223
+ // Fix the declaration and all references
224
+ const fixes = [];
225
+ fixes.push(fixer.replaceText(node.id, newName));
226
+ for (const ref of references) {
227
+ if (ref.identifier !== node.id) {
228
+ fixes.push(fixer.replaceText(ref.identifier, newName));
229
+ }
230
+ }
231
+ return fixes;
133
232
  },
134
233
  });
135
234
  }
@@ -140,6 +239,22 @@ module.exports = (0, createRule_1.createRule)({
140
239
  node.key.name &&
141
240
  node.key.name.startsWith('handle')) {
142
241
  const name = node.key.name;
242
+ // Skip autofixing for "handler" and "handlers"
243
+ if (name === 'handler' || name === 'handlers') {
244
+ context.report({
245
+ node: node.key,
246
+ messageId: 'callbackFunctionPrefix',
247
+ });
248
+ return;
249
+ }
250
+ // Skip autofixing for class parameters and getters
251
+ if (node.type === 'MethodDefinition' && node.kind === 'get') {
252
+ context.report({
253
+ node: node.key,
254
+ messageId: 'callbackFunctionPrefix',
255
+ });
256
+ return;
257
+ }
143
258
  context.report({
144
259
  node: node.key,
145
260
  messageId: 'callbackFunctionPrefix',
@@ -151,6 +266,16 @@ module.exports = (0, createRule_1.createRule)({
151
266
  });
152
267
  }
153
268
  },
269
+ // Check constructor parameters
270
+ 'TSParameterProperty'(node) {
271
+ if (node.parameter.type === 'Identifier' &&
272
+ node.parameter.name.startsWith('handle')) {
273
+ context.report({
274
+ node,
275
+ messageId: 'callbackFunctionPrefix',
276
+ });
277
+ }
278
+ },
154
279
  };
155
280
  },
156
281
  });
@@ -0,0 +1 @@
1
+ export declare const enforceFirestorePathUtils: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"requirePathUtil", [], import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enforceFirestorePathUtils = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const createRule_1 = require("../utils/createRule");
6
+ const FIRESTORE_METHODS = new Set(['doc', 'collection']);
7
+ exports.enforceFirestorePathUtils = (0, createRule_1.createRule)({
8
+ name: 'enforce-firestore-path-utils',
9
+ meta: {
10
+ type: 'suggestion',
11
+ docs: {
12
+ description: 'Enforce usage of utility functions for Firestore paths',
13
+ recommended: 'error',
14
+ },
15
+ schema: [],
16
+ messages: {
17
+ requirePathUtil: 'Use a utility function (e.g., toUserPath, toCollectionPath) for Firestore paths instead of string literals',
18
+ },
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ function isFirestoreCall(node) {
23
+ if (node.callee.type !== utils_1.AST_NODE_TYPES.MemberExpression) {
24
+ return false;
25
+ }
26
+ const property = node.callee.property;
27
+ if (property.type !== utils_1.AST_NODE_TYPES.Identifier) {
28
+ return false;
29
+ }
30
+ return FIRESTORE_METHODS.has(property.name);
31
+ }
32
+ function isStringLiteralOrTemplate(node) {
33
+ return (node.type === utils_1.AST_NODE_TYPES.Literal && typeof node.value === 'string' ||
34
+ node.type === utils_1.AST_NODE_TYPES.TemplateLiteral);
35
+ }
36
+ function isUtilityFunction(node) {
37
+ if (node.type !== utils_1.AST_NODE_TYPES.CallExpression) {
38
+ return false;
39
+ }
40
+ const callee = node.callee;
41
+ if (callee.type !== utils_1.AST_NODE_TYPES.Identifier) {
42
+ return false;
43
+ }
44
+ // Match functions starting with 'to' and ending with 'Path'
45
+ return /^to.*Path$/.test(callee.name);
46
+ }
47
+ return {
48
+ CallExpression(node) {
49
+ if (!isFirestoreCall(node)) {
50
+ return;
51
+ }
52
+ // Check first argument of doc() or collection() call
53
+ const pathArg = node.arguments[0];
54
+ if (!pathArg) {
55
+ return;
56
+ }
57
+ // Skip if it's already using a utility function
58
+ if (isUtilityFunction(pathArg)) {
59
+ return;
60
+ }
61
+ // Skip if it's a variable or other non-literal expression
62
+ if (!isStringLiteralOrTemplate(pathArg)) {
63
+ return;
64
+ }
65
+ // Skip test files
66
+ const filename = context.getFilename();
67
+ if (filename.includes('__tests__') || filename.includes('.test.') || filename.includes('.spec.')) {
68
+ return;
69
+ }
70
+ context.report({
71
+ node: pathArg,
72
+ messageId: 'requirePathUtil',
73
+ });
74
+ },
75
+ };
76
+ },
77
+ });
78
+ //# sourceMappingURL=enforce-firestore-path-utils.js.map
@@ -0,0 +1 @@
1
+ export declare const enforceRealtimedbPathUtils: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"requirePathUtil", [], import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.enforceRealtimedbPathUtils = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const createRule_1 = require("../utils/createRule");
6
+ const RTDB_METHODS = new Set(['ref', 'child']);
7
+ exports.enforceRealtimedbPathUtils = (0, createRule_1.createRule)({
8
+ name: 'enforce-realtimedb-path-utils',
9
+ meta: {
10
+ type: 'suggestion',
11
+ docs: {
12
+ description: 'Enforce usage of utility functions for Realtime Database paths',
13
+ recommended: 'error',
14
+ },
15
+ schema: [],
16
+ messages: {
17
+ requirePathUtil: 'Use a utility function (e.g., toUserPath, toItemPath) for Realtime Database paths instead of string literals',
18
+ },
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ function isRTDBCall(node) {
23
+ if (node.callee.type !== utils_1.AST_NODE_TYPES.MemberExpression) {
24
+ return false;
25
+ }
26
+ const property = node.callee.property;
27
+ if (property.type !== utils_1.AST_NODE_TYPES.Identifier) {
28
+ return false;
29
+ }
30
+ // Check for both frontend and backend SDK patterns
31
+ if (!RTDB_METHODS.has(property.name)) {
32
+ return false;
33
+ }
34
+ // Check if it's a Firebase RTDB call by looking at the chain
35
+ let current = node.callee.object;
36
+ while (current) {
37
+ if (current.type === utils_1.AST_NODE_TYPES.CallExpression) {
38
+ if (current.callee.type === utils_1.AST_NODE_TYPES.MemberExpression) {
39
+ const method = current.callee.property;
40
+ if (method.type === utils_1.AST_NODE_TYPES.Identifier &&
41
+ method.name === 'database') {
42
+ return true;
43
+ }
44
+ }
45
+ current = current.callee;
46
+ }
47
+ else if (current.type === utils_1.AST_NODE_TYPES.MemberExpression) {
48
+ // Handle chained calls like ref().child()
49
+ current = current.object;
50
+ }
51
+ else {
52
+ break;
53
+ }
54
+ }
55
+ return false;
56
+ }
57
+ function isStringLiteralOrTemplate(node) {
58
+ return ((node.type === utils_1.AST_NODE_TYPES.Literal && typeof node.value === 'string') ||
59
+ node.type === utils_1.AST_NODE_TYPES.TemplateLiteral);
60
+ }
61
+ function isUtilityFunction(node) {
62
+ if (node.type !== utils_1.AST_NODE_TYPES.CallExpression) {
63
+ return false;
64
+ }
65
+ const callee = node.callee;
66
+ if (callee.type !== utils_1.AST_NODE_TYPES.Identifier) {
67
+ return false;
68
+ }
69
+ // Match functions starting with 'to' and ending with 'Path'
70
+ return /^to.*Path$/.test(callee.name);
71
+ }
72
+ return {
73
+ CallExpression(node) {
74
+ if (!isRTDBCall(node)) {
75
+ return;
76
+ }
77
+ // Check first argument of ref() or child() call
78
+ const pathArg = node.arguments[0];
79
+ if (!pathArg) {
80
+ return;
81
+ }
82
+ // Skip if it's already using a utility function
83
+ if (isUtilityFunction(pathArg)) {
84
+ return;
85
+ }
86
+ // Skip if it's a variable or other non-literal expression
87
+ if (!isStringLiteralOrTemplate(pathArg)) {
88
+ return;
89
+ }
90
+ // Skip test files
91
+ const filename = context.getFilename();
92
+ if (filename.includes('__tests__') ||
93
+ filename.includes('.test.') ||
94
+ filename.includes('.spec.') ||
95
+ filename.includes('mocks')) {
96
+ return;
97
+ }
98
+ context.report({
99
+ node: pathArg,
100
+ messageId: 'requirePathUtil',
101
+ });
102
+ },
103
+ };
104
+ },
105
+ });
106
+ //# sourceMappingURL=enforce-realtimedb-path-utils.js.map
@@ -0,0 +1 @@
1
+ export declare const noEntireObjectHookDeps: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"avoidEntireObject", [], import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.noEntireObjectHookDeps = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const createRule_1 = require("../utils/createRule");
6
+ const HOOK_NAMES = new Set(['useEffect', 'useCallback', 'useMemo']);
7
+ function isHookCall(node) {
8
+ const callee = node.callee;
9
+ return (callee.type === utils_1.AST_NODE_TYPES.Identifier &&
10
+ HOOK_NAMES.has(callee.name));
11
+ }
12
+ function getObjectUsagesInHook(hookBody, objectName) {
13
+ const usages = new Set();
14
+ const visited = new Set();
15
+ function buildAccessPath(node) {
16
+ const parts = [];
17
+ let current = node;
18
+ while (current.type === utils_1.AST_NODE_TYPES.MemberExpression) {
19
+ if (current.computed) {
20
+ return null; // Skip computed properties
21
+ }
22
+ if (current.property.type !== utils_1.AST_NODE_TYPES.Identifier) {
23
+ return null;
24
+ }
25
+ parts.unshift(current.property.name);
26
+ current = current.object;
27
+ }
28
+ if (current.type === utils_1.AST_NODE_TYPES.Identifier && current.name === objectName) {
29
+ parts.unshift(objectName);
30
+ return parts.join('.');
31
+ }
32
+ return null;
33
+ }
34
+ function visit(node) {
35
+ if (visited.has(node)) {
36
+ return;
37
+ }
38
+ visited.add(node);
39
+ if (node.type === utils_1.AST_NODE_TYPES.MemberExpression && !node.computed) {
40
+ const accessPath = buildAccessPath(node);
41
+ if (accessPath) {
42
+ usages.add(accessPath);
43
+ }
44
+ }
45
+ // Visit children
46
+ switch (node.type) {
47
+ case utils_1.AST_NODE_TYPES.BlockStatement:
48
+ case utils_1.AST_NODE_TYPES.Program:
49
+ node.body.forEach(child => visit(child));
50
+ break;
51
+ case utils_1.AST_NODE_TYPES.ExpressionStatement:
52
+ visit(node.expression);
53
+ break;
54
+ case utils_1.AST_NODE_TYPES.CallExpression:
55
+ visit(node.callee);
56
+ node.arguments.forEach(arg => visit(arg));
57
+ break;
58
+ case utils_1.AST_NODE_TYPES.MemberExpression:
59
+ visit(node.object);
60
+ if (!node.computed) {
61
+ visit(node.property);
62
+ }
63
+ break;
64
+ case utils_1.AST_NODE_TYPES.ArrowFunctionExpression:
65
+ case utils_1.AST_NODE_TYPES.FunctionExpression:
66
+ if (node.body.type === utils_1.AST_NODE_TYPES.BlockStatement) {
67
+ visit(node.body);
68
+ }
69
+ else {
70
+ visit(node.body);
71
+ }
72
+ break;
73
+ case utils_1.AST_NODE_TYPES.ReturnStatement:
74
+ if (node.argument) {
75
+ visit(node.argument);
76
+ }
77
+ break;
78
+ case utils_1.AST_NODE_TYPES.ConditionalExpression:
79
+ visit(node.test);
80
+ visit(node.consequent);
81
+ visit(node.alternate);
82
+ break;
83
+ case utils_1.AST_NODE_TYPES.LogicalExpression:
84
+ case utils_1.AST_NODE_TYPES.BinaryExpression:
85
+ visit(node.left);
86
+ visit(node.right);
87
+ break;
88
+ case utils_1.AST_NODE_TYPES.TemplateLiteral:
89
+ node.expressions.forEach(expr => visit(expr));
90
+ break;
91
+ }
92
+ }
93
+ visit(hookBody);
94
+ // Filter out intermediate paths
95
+ const paths = Array.from(usages);
96
+ const filteredPaths = paths.filter(path => !paths.some(otherPath => otherPath !== path && otherPath.startsWith(path + '.')));
97
+ return new Set(filteredPaths);
98
+ }
99
+ exports.noEntireObjectHookDeps = (0, createRule_1.createRule)({
100
+ name: 'no-entire-object-hook-deps',
101
+ meta: {
102
+ type: 'suggestion',
103
+ docs: {
104
+ description: 'Avoid using entire objects in React hook dependency arrays when only specific fields are used',
105
+ recommended: 'error',
106
+ },
107
+ fixable: 'code',
108
+ schema: [],
109
+ messages: {
110
+ avoidEntireObject: 'Avoid using entire object "{{objectName}}" in dependency array. Use specific fields: {{fields}}',
111
+ },
112
+ },
113
+ defaultOptions: [],
114
+ create(context) {
115
+ return {
116
+ CallExpression(node) {
117
+ if (!isHookCall(node)) {
118
+ return;
119
+ }
120
+ // Get the dependency array argument
121
+ const depsArg = node.arguments[node.arguments.length - 1];
122
+ if (!depsArg ||
123
+ depsArg.type !== utils_1.AST_NODE_TYPES.ArrayExpression) {
124
+ return;
125
+ }
126
+ // Get the hook callback function
127
+ const callbackArg = node.arguments[0];
128
+ if (!callbackArg ||
129
+ (callbackArg.type !== utils_1.AST_NODE_TYPES.ArrowFunctionExpression &&
130
+ callbackArg.type !== utils_1.AST_NODE_TYPES.FunctionExpression)) {
131
+ return;
132
+ }
133
+ // Check each dependency in the array
134
+ depsArg.elements.forEach(element => {
135
+ if (element &&
136
+ element.type === utils_1.AST_NODE_TYPES.Identifier) {
137
+ const objectName = element.name;
138
+ const usages = getObjectUsagesInHook(callbackArg.body, objectName);
139
+ // If we found specific field usages and the entire object is in deps
140
+ if (usages.size > 0) {
141
+ const fields = Array.from(usages).join(', ');
142
+ context.report({
143
+ node: element,
144
+ messageId: 'avoidEntireObject',
145
+ data: {
146
+ objectName,
147
+ fields,
148
+ },
149
+ fix(fixer) {
150
+ // Only provide fix if we have specific fields to suggest
151
+ if (usages.size > 0) {
152
+ return fixer.replaceText(element, Array.from(usages).join(', '));
153
+ }
154
+ return null;
155
+ },
156
+ });
157
+ }
158
+ }
159
+ });
160
+ },
161
+ };
162
+ },
163
+ });
164
+ //# sourceMappingURL=no-entire-object-hook-deps.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blumintinc/eslint-plugin-blumint",
3
- "version": "1.1.5",
3
+ "version": "1.1.7",
4
4
  "description": "Custom eslint rules for use within BluMint",
5
5
  "author": {
6
6
  "name": "Brodie McGuire",
@@ -36,23 +36,28 @@
36
36
  "docs": "./scripts/make-docs.sh && npm run update:eslint-docs",
37
37
  "update:eslint-docs": "eslint-doc-generator",
38
38
  "build": "tsc",
39
- "prepare": "npm run build",
39
+ "prepare": "husky install && npm run build",
40
40
  "version": "git add -A src",
41
41
  "postversion": "git push && git push --tags",
42
42
  "remove-hooks": "del-cli ./.husky/",
43
43
  "release:dry-run": "semantic-release --dry-run --no-ci",
44
- "test:release": "node scripts/test-release.js"
44
+ "test:release": "node scripts/test-release.js",
45
+ "commitlint": "commitlint --edit"
45
46
  },
46
47
  "dependencies": {
47
48
  "requireindex": "1.2.0"
48
49
  },
49
50
  "devDependencies": {
51
+ "@commitlint/cli": "19.6.1",
52
+ "@commitlint/config-conventional": "19.6.0",
50
53
  "@semantic-release/changelog": "6.0.1",
51
54
  "@semantic-release/commit-analyzer": "9.0.2",
55
+ "@semantic-release/exec": "6.0.3",
52
56
  "@semantic-release/git": "10.0.1",
53
57
  "@semantic-release/npm": "9.0.1",
54
58
  "@semantic-release/release-notes-generator": "10.0.3",
55
59
  "@types/eslint": "8.37.0",
60
+ "@types/jest": "29.5.14",
56
61
  "@types/node": "18.7.13",
57
62
  "@typescript-eslint/eslint-plugin": "5.34.0",
58
63
  "@typescript-eslint/parser": "5.48.0",
@@ -69,11 +74,12 @@
69
74
  "eslint-import-resolver-typescript": "3.5.5",
70
75
  "eslint-plugin-eslint-plugin": "5.0.0",
71
76
  "eslint-plugin-import": "2.26.0",
72
- "eslint-plugin-node": "11.1.0",
73
77
  "eslint-plugin-jsdoc": "44.0.0",
78
+ "eslint-plugin-node": "11.1.0",
74
79
  "eslint-plugin-prettier": "4.2.1",
75
80
  "eslint-plugin-security": "1.5.0",
76
81
  "fs": "0.0.1-security",
82
+ "husky": "9.1.7",
77
83
  "jest": "29.3.1",
78
84
  "jest-junit": "14.0.0",
79
85
  "jsonc-eslint-parser": "2.3.0",
@@ -85,9 +91,7 @@
85
91
  "semantic-release": "19.0.3",
86
92
  "ts-jest": "29.0.5",
87
93
  "ts-node": "10.9.1",
88
- "typescript": "4.9.5",
89
- "@types/jest": "^29.3.1",
90
- "@semantic-release/exec": "^6.0.3"
94
+ "typescript": "4.9.5"
91
95
  },
92
96
  "peerDependencies": {
93
97
  "eslint": ">=7"