@blumintinc/eslint-plugin-blumint 1.1.9 → 1.2.1

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.
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.preferSettingsObject = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const createRule_1 = require("../utils/createRule");
6
+ const defaultOptions = {
7
+ minimumParameters: 3,
8
+ checkSameTypeParameters: true,
9
+ ignoreBoundMethods: true,
10
+ ignoreVariadicFunctions: true,
11
+ };
12
+ exports.preferSettingsObject = (0, createRule_1.createRule)({
13
+ name: 'prefer-settings-object',
14
+ meta: {
15
+ type: 'suggestion',
16
+ docs: {
17
+ description: 'Enforce using a settings object for functions with multiple parameters',
18
+ recommended: 'error',
19
+ },
20
+ fixable: 'code',
21
+ schema: [
22
+ {
23
+ type: 'object',
24
+ properties: {
25
+ minimumParameters: {
26
+ type: 'number',
27
+ minimum: 2,
28
+ },
29
+ checkSameTypeParameters: {
30
+ type: 'boolean',
31
+ },
32
+ ignoreBoundMethods: {
33
+ type: 'boolean',
34
+ },
35
+ ignoreVariadicFunctions: {
36
+ type: 'boolean',
37
+ },
38
+ },
39
+ additionalProperties: false,
40
+ },
41
+ ],
42
+ messages: {
43
+ tooManyParams: 'Function has too many parameters ({{count}}). Use a settings object instead.',
44
+ sameTypeParams: 'Function has multiple parameters of the same type. Use a settings object instead.',
45
+ },
46
+ },
47
+ defaultOptions: [defaultOptions],
48
+ create(context, [options]) {
49
+ const finalOptions = { ...defaultOptions, ...options };
50
+ function getParameterType(param) {
51
+ if (param.type === utils_1.AST_NODE_TYPES.Identifier && param.typeAnnotation) {
52
+ const typeNode = param.typeAnnotation.typeAnnotation;
53
+ if (typeNode.type === utils_1.AST_NODE_TYPES.TSTypeReference) {
54
+ return typeNode.typeName.type === utils_1.AST_NODE_TYPES.Identifier
55
+ ? typeNode.typeName.name
56
+ : 'unknown';
57
+ }
58
+ return typeNode.type;
59
+ }
60
+ return 'unknown';
61
+ }
62
+ function hasSameTypeParameters(params) {
63
+ const typeMap = new Map();
64
+ for (const param of params) {
65
+ const type = getParameterType(param);
66
+ typeMap.set(type, (typeMap.get(type) || 0) + 1);
67
+ if (typeMap.get(type) > 1) {
68
+ return true;
69
+ }
70
+ }
71
+ return false;
72
+ }
73
+ function shouldIgnoreNode(node) {
74
+ // Ignore variadic functions if configured
75
+ if (finalOptions.ignoreVariadicFunctions) {
76
+ const hasRestParam = node.type === utils_1.AST_NODE_TYPES.FunctionDeclaration &&
77
+ node.params.some(param => param.type === utils_1.AST_NODE_TYPES.RestElement);
78
+ if (hasRestParam)
79
+ return true;
80
+ }
81
+ // Ignore bound methods if configured
82
+ if (finalOptions.ignoreBoundMethods) {
83
+ let parent = node.parent;
84
+ while (parent) {
85
+ if (parent.type === utils_1.AST_NODE_TYPES.CallExpression ||
86
+ parent.type === utils_1.AST_NODE_TYPES.TSCallSignatureDeclaration) {
87
+ return true;
88
+ }
89
+ parent = parent.parent;
90
+ }
91
+ }
92
+ return false;
93
+ }
94
+ function checkFunction(node) {
95
+ if (shouldIgnoreNode(node))
96
+ return;
97
+ const params = node.params;
98
+ // Check for too many parameters
99
+ const minParams = finalOptions.minimumParameters !== undefined
100
+ ? finalOptions.minimumParameters
101
+ : defaultOptions.minimumParameters;
102
+ if (params.length >= minParams) {
103
+ context.report({
104
+ node,
105
+ messageId: 'tooManyParams',
106
+ data: { count: params.length },
107
+ });
108
+ return;
109
+ }
110
+ // Check for same type parameters if enabled
111
+ if (finalOptions.checkSameTypeParameters && params.length >= 2) {
112
+ if (hasSameTypeParameters(params)) {
113
+ context.report({
114
+ node,
115
+ messageId: 'sameTypeParams',
116
+ });
117
+ }
118
+ }
119
+ }
120
+ return {
121
+ FunctionDeclaration: checkFunction,
122
+ FunctionExpression: checkFunction,
123
+ ArrowFunctionExpression: checkFunction,
124
+ TSMethodSignature: checkFunction,
125
+ TSFunctionType: checkFunction,
126
+ };
127
+ },
128
+ });
129
+ //# sourceMappingURL=prefer-settings-object.js.map
@@ -8,7 +8,7 @@ exports.preferTypeOverInterface = (0, createRule_1.createRule)({
8
8
  type: 'suggestion',
9
9
  docs: {
10
10
  description: 'Prefer using type alias over interface',
11
- recommended: 'warn',
11
+ recommended: 'error',
12
12
  },
13
13
  schema: [],
14
14
  messages: {
@@ -42,30 +42,39 @@ module.exports = (0, createRule_1.createRule)({
42
42
  }
43
43
  },
44
44
  ThrowStatement(node) {
45
+ if (!node.argument) {
46
+ return;
47
+ }
45
48
  const argument = node.argument;
46
- if (argument &&
47
- argument.type === utils_1.AST_NODE_TYPES.NewExpression &&
48
- argument.callee) {
49
- if (argument.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
50
- argument.callee.name === 'Error') {
51
- context.report({
52
- node,
53
- messageId: 'useHttpsError',
54
- });
55
- }
56
- else if (hasFirebaseAdminImport &&
57
- ((argument.callee.type === utils_1.AST_NODE_TYPES.Identifier &&
58
- argument.callee.name === 'HttpsError') ||
59
- (argument.callee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
60
- argument.callee.object.type === utils_1.AST_NODE_TYPES.Identifier &&
61
- argument.callee.object.name === httpsIdentifier &&
62
- argument.callee.property.type === utils_1.AST_NODE_TYPES.Identifier &&
63
- argument.callee.property.name === 'HttpsError'))) {
64
- context.report({
65
- node,
66
- messageId: 'useProprietaryHttpsError',
67
- });
68
- }
49
+ if (argument.type !== utils_1.AST_NODE_TYPES.NewExpression) {
50
+ return;
51
+ }
52
+ const callee = argument.callee;
53
+ // Check for direct Error usage
54
+ if (callee.type === utils_1.AST_NODE_TYPES.Identifier &&
55
+ callee.name === 'Error') {
56
+ context.report({
57
+ node,
58
+ messageId: 'useHttpsError',
59
+ });
60
+ return;
61
+ }
62
+ // Check for firebase-admin HttpsError usage
63
+ if (!hasFirebaseAdminImport) {
64
+ return;
65
+ }
66
+ const isHttpsError = callee.type === utils_1.AST_NODE_TYPES.Identifier &&
67
+ callee.name === 'HttpsError';
68
+ const isFirebaseHttpsError = callee.type === utils_1.AST_NODE_TYPES.MemberExpression &&
69
+ callee.object.type === utils_1.AST_NODE_TYPES.Identifier &&
70
+ callee.object.name === httpsIdentifier &&
71
+ callee.property.type === utils_1.AST_NODE_TYPES.Identifier &&
72
+ callee.property.name === 'HttpsError';
73
+ if (isHttpsError || isFirebaseHttpsError) {
74
+ context.report({
75
+ node,
76
+ messageId: 'useProprietaryHttpsError',
77
+ });
69
78
  }
70
79
  },
71
80
  };
@@ -7,6 +7,7 @@ module.exports = (0, createRule_1.createRule)({
7
7
  docs: {
8
8
  description: 'Enforce using ImageOverlayed component instead of next/image or img tags',
9
9
  recommended: 'error',
10
+ requiresTypeChecking: false,
10
11
  },
11
12
  fixable: 'code',
12
13
  schema: [
@@ -15,6 +16,7 @@ module.exports = (0, createRule_1.createRule)({
15
16
  properties: {
16
17
  componentPath: {
17
18
  type: 'string',
19
+ description: 'The import path for the ImageOverlayed component',
18
20
  default: 'src/components/ImageOverlayed',
19
21
  },
20
22
  },
@@ -0,0 +1 @@
1
+ export declare const useCustomMemo: import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleModule<"useCustomMemo", [], import("@typescript-eslint/utils/dist/ts-eslint/Rule").RuleListener>;
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useCustomMemo = void 0;
4
+ const utils_1 = require("@typescript-eslint/utils");
5
+ const createRule_1 = require("../utils/createRule");
6
+ exports.useCustomMemo = (0, createRule_1.createRule)({
7
+ name: 'use-custom-memo',
8
+ meta: {
9
+ type: 'suggestion',
10
+ docs: {
11
+ description: 'Enforce using src/util/memo instead of React memo',
12
+ recommended: 'error',
13
+ },
14
+ fixable: 'code',
15
+ schema: [],
16
+ messages: {
17
+ useCustomMemo: 'Import memo from src/util/memo instead of react',
18
+ },
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ return {
23
+ ImportDeclaration(node) {
24
+ if (node.source.value === 'react') {
25
+ const specifiers = node.specifiers.filter((specifier) => specifier.type === utils_1.AST_NODE_TYPES.ImportSpecifier &&
26
+ specifier.imported.type === utils_1.AST_NODE_TYPES.Identifier &&
27
+ specifier.imported.name === 'memo');
28
+ if (specifiers.length > 0) {
29
+ context.report({
30
+ node,
31
+ messageId: 'useCustomMemo',
32
+ fix(fixer) {
33
+ // If there are other imports from react, keep them
34
+ const otherSpecifiers = node.specifiers.filter((specifier) => specifier.type !== utils_1.AST_NODE_TYPES.ImportSpecifier ||
35
+ (specifier.imported.type === utils_1.AST_NODE_TYPES.Identifier &&
36
+ specifier.imported.name !== 'memo'));
37
+ if (otherSpecifiers.length === 0) {
38
+ // If memo is the only import, replace the entire import
39
+ return fixer.replaceText(node, `import { ${specifiers
40
+ .map((s) => s.local.name !== s.imported.name
41
+ ? `memo as ${s.local.name}`
42
+ : 'memo')
43
+ .join(', ')} } from 'src/util/memo';`);
44
+ }
45
+ else {
46
+ // Create a new import for memo and keep other imports
47
+ const memoImport = `import { ${specifiers
48
+ .map((s) => s.local.name !== s.imported.name
49
+ ? `memo as ${s.local.name}`
50
+ : 'memo')
51
+ .join(', ')} } from 'src/util/memo';\n`;
52
+ const otherImports = `import { ${otherSpecifiers
53
+ .map((s) => s.local.name)
54
+ .join(', ')} } from 'react';`;
55
+ return fixer.replaceText(node, memoImport + otherImports);
56
+ }
57
+ },
58
+ });
59
+ }
60
+ }
61
+ },
62
+ };
63
+ },
64
+ });
65
+ //# sourceMappingURL=use-custom-memo.js.map
@@ -91,6 +91,20 @@ class ASTHelpers {
91
91
  return node.expressions.some((expr) => this.declarationIncludesIdentifier(expr));
92
92
  case 'TSAsExpression':
93
93
  return this.declarationIncludesIdentifier(node.expression);
94
+ case 'TSTypeReference':
95
+ // Handle type references (e.g., T in generic types)
96
+ return false;
97
+ case 'TSTypeParameterDeclaration':
98
+ // Handle type parameter declarations (e.g., <T extends ...>)
99
+ return false;
100
+ case 'TSTypeParameterInstantiation':
101
+ // Handle type parameter instantiations (e.g., <string>)
102
+ return false;
103
+ case 'TSIntersectionType':
104
+ case 'TSUnionType':
105
+ case 'TSTypeLiteral':
106
+ // Handle type constraints and literals
107
+ return false;
94
108
  default:
95
109
  return false;
96
110
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blumintinc/eslint-plugin-blumint",
3
- "version": "1.1.9",
3
+ "version": "1.2.1",
4
4
  "description": "Custom eslint rules for use within BluMint",
5
5
  "author": {
6
6
  "name": "Brodie McGuire",