@sun-asterisk/sunlint 1.3.0 → 1.3.2

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 (124) hide show
  1. package/CHANGELOG.md +115 -1
  2. package/CONTRIBUTING.md +249 -605
  3. package/README.md +3 -4
  4. package/config/ci-cd.json +54 -0
  5. package/config/development.json +56 -0
  6. package/config/large-project.json +143 -0
  7. package/config/presets/all.json +0 -1
  8. package/config/release.json +70 -0
  9. package/config/rule-analysis-strategies.js +38 -3
  10. package/config/rules/enhanced-rules-registry.json +474 -1179
  11. package/config/rules/rules-registry-generated.json +3 -3
  12. package/core/cli-action-handler.js +24 -30
  13. package/core/cli-program.js +11 -3
  14. package/core/config-merger.js +29 -2
  15. package/core/enhanced-rules-registry.js +3 -2
  16. package/core/semantic-engine.js +129 -19
  17. package/core/semantic-rule-base.js +4 -2
  18. package/core/unified-rule-registry.js +1 -1
  19. package/docs/COMMAND-EXAMPLES.md +134 -0
  20. package/docs/LARGE-PROJECT-GUIDE.md +324 -0
  21. package/engines/heuristic-engine.js +135 -16
  22. package/integrations/eslint/plugin/index.js +0 -2
  23. package/integrations/eslint/plugin/rules/common/c003-no-vague-abbreviations.js +59 -1
  24. package/integrations/eslint/plugin/rules/common/c006-function-name-verb-noun.js +26 -1
  25. package/integrations/eslint/plugin/rules/common/c030-use-custom-error-classes.js +54 -19
  26. package/origin-rules/common-en.md +19 -15
  27. package/package.json +1 -1
  28. package/rules/common/C002_no_duplicate_code/analyzer.js +334 -36
  29. package/rules/common/C003_no_vague_abbreviations/analyzer.js +220 -35
  30. package/rules/common/C006_function_naming/analyzer.js +29 -3
  31. package/rules/common/C010_limit_block_nesting/analyzer.js +181 -337
  32. package/rules/common/C010_limit_block_nesting/config.json +64 -0
  33. package/rules/common/C010_limit_block_nesting/regex-based-analyzer.js +379 -0
  34. package/rules/common/C010_limit_block_nesting/symbol-based-analyzer.js +231 -0
  35. package/rules/common/C013_no_dead_code/analyzer.js +75 -177
  36. package/rules/common/C013_no_dead_code/config.json +61 -0
  37. package/rules/common/C013_no_dead_code/regex-based-analyzer.js +345 -0
  38. package/rules/common/C013_no_dead_code/symbol-based-analyzer.js +640 -0
  39. package/rules/common/C014_dependency_injection/analyzer.js +48 -313
  40. package/rules/common/C014_dependency_injection/config.json +26 -0
  41. package/rules/common/C014_dependency_injection/symbol-based-analyzer.js +751 -0
  42. package/rules/common/C017_constructor_logic/analyzer.js +254 -17
  43. package/rules/common/C017_constructor_logic/semantic-analyzer.js +340 -0
  44. package/rules/common/C018_no_throw_generic_error/analyzer.js +232 -0
  45. package/rules/common/C018_no_throw_generic_error/config.json +50 -0
  46. package/rules/common/C018_no_throw_generic_error/regex-based-analyzer.js +387 -0
  47. package/rules/common/C018_no_throw_generic_error/symbol-based-analyzer.js +314 -0
  48. package/rules/common/C019_log_level_usage/analyzer.js +110 -317
  49. package/rules/common/C019_log_level_usage/pattern-analyzer.js +88 -0
  50. package/rules/common/C019_log_level_usage/system-log-analyzer.js +1267 -0
  51. package/rules/common/C023_no_duplicate_variable/analyzer.js +180 -0
  52. package/rules/common/C023_no_duplicate_variable/config.json +50 -0
  53. package/rules/common/C023_no_duplicate_variable/symbol-based-analyzer.js +158 -0
  54. package/rules/common/C024_no_scatter_hardcoded_constants/analyzer.js +180 -0
  55. package/rules/common/C024_no_scatter_hardcoded_constants/config.json +50 -0
  56. package/rules/common/C024_no_scatter_hardcoded_constants/symbol-based-analyzer.js +181 -0
  57. package/rules/common/C030_use_custom_error_classes/analyzer.js +200 -0
  58. package/rules/common/C033_separate_service_repository/README.md +78 -0
  59. package/rules/common/C033_separate_service_repository/analyzer.js +160 -0
  60. package/rules/common/C033_separate_service_repository/config.json +50 -0
  61. package/rules/common/C033_separate_service_repository/regex-based-analyzer.js +585 -0
  62. package/rules/common/C033_separate_service_repository/symbol-based-analyzer.js +368 -0
  63. package/rules/common/C035_error_logging_context/STRATEGY.md +99 -0
  64. package/rules/common/C035_error_logging_context/analyzer.js +232 -0
  65. package/rules/common/C035_error_logging_context/config.json +54 -0
  66. package/rules/common/C035_error_logging_context/regex-based-analyzer.js +299 -0
  67. package/rules/common/C035_error_logging_context/symbol-based-analyzer.js +454 -0
  68. package/rules/common/C040_centralized_validation/analyzer.js +165 -0
  69. package/rules/common/C040_centralized_validation/config.json +46 -0
  70. package/rules/common/C040_centralized_validation/regex-based-analyzer.js +243 -0
  71. package/rules/common/C040_centralized_validation/symbol-based-analyzer.js +416 -0
  72. package/rules/common/{C076_single_test_behavior → C072_single_test_behavior}/analyzer.js +6 -6
  73. package/rules/common/C076_explicit_function_types/README.md +30 -0
  74. package/rules/common/C076_explicit_function_types/analyzer.js +172 -0
  75. package/rules/common/C076_explicit_function_types/config.json +15 -0
  76. package/rules/common/C076_explicit_function_types/semantic-analyzer.js +341 -0
  77. package/rules/index.js +6 -1
  78. package/rules/parser/rule-parser.js +13 -2
  79. package/rules/security/S005_no_origin_auth/README.md +226 -0
  80. package/rules/security/S005_no_origin_auth/analyzer.js +184 -0
  81. package/rules/security/S005_no_origin_auth/ast-analyzer.js +406 -0
  82. package/rules/security/S005_no_origin_auth/config.json +85 -0
  83. package/rules/security/S006_no_plaintext_recovery_codes/README.md +139 -0
  84. package/rules/security/S006_no_plaintext_recovery_codes/analyzer.js +306 -0
  85. package/rules/security/S006_no_plaintext_recovery_codes/config.json +48 -0
  86. package/rules/security/S007_no_plaintext_otp/README.md +198 -0
  87. package/rules/security/S007_no_plaintext_otp/analyzer.js +406 -0
  88. package/rules/security/S007_no_plaintext_otp/config.json +79 -0
  89. package/rules/security/S007_no_plaintext_otp/semantic-analyzer.js +609 -0
  90. package/rules/security/S007_no_plaintext_otp/semantic-config.json +195 -0
  91. package/rules/security/S007_no_plaintext_otp/semantic-wrapper.js +280 -0
  92. package/rules/security/S009_no_insecure_encryption/README.md +158 -0
  93. package/rules/security/S009_no_insecure_encryption/analyzer.js +319 -0
  94. package/rules/security/S009_no_insecure_encryption/config.json +55 -0
  95. package/rules/security/S010_no_insecure_encryption/README.md +224 -0
  96. package/rules/security/S010_no_insecure_encryption/analyzer.js +493 -0
  97. package/rules/security/S010_no_insecure_encryption/config.json +48 -0
  98. package/rules/security/S016_no_sensitive_querystring/STRATEGY.md +149 -0
  99. package/rules/security/S016_no_sensitive_querystring/analyzer.js +276 -0
  100. package/rules/security/S016_no_sensitive_querystring/config.json +127 -0
  101. package/rules/security/S016_no_sensitive_querystring/regex-based-analyzer.js +258 -0
  102. package/rules/security/S016_no_sensitive_querystring/symbol-based-analyzer.js +495 -0
  103. package/rules/security/S027_no_hardcoded_secrets/analyzer.js +180 -366
  104. package/rules/security/S027_no_hardcoded_secrets/categories.json +153 -0
  105. package/rules/security/S027_no_hardcoded_secrets/categorized-analyzer.js +250 -0
  106. package/rules/security/S048_no_current_password_in_reset/README.md +222 -0
  107. package/rules/security/S048_no_current_password_in_reset/analyzer.js +366 -0
  108. package/rules/security/S048_no_current_password_in_reset/config.json +48 -0
  109. package/rules/security/S055_content_type_validation/README.md +176 -0
  110. package/rules/security/S055_content_type_validation/analyzer.js +312 -0
  111. package/rules/security/S055_content_type_validation/config.json +48 -0
  112. package/rules/utils/rule-helpers.js +140 -1
  113. package/scripts/consolidate-config.js +116 -0
  114. package/scripts/prepare-release.sh +1 -1
  115. package/config/rules/rules-registry.json +0 -765
  116. package/docs/ESLINT-INTEGRATION-STRATEGY.md +0 -392
  117. package/docs/FUTURE_PACKAGES.md +0 -83
  118. package/docs/HEURISTIC_VS_AI.md +0 -113
  119. package/docs/PRODUCTION_DEPLOYMENT_ANALYSIS.md +0 -112
  120. package/docs/PRODUCTION_SIZE_IMPACT.md +0 -183
  121. package/docs/RELEASE_GUIDE.md +0 -230
  122. package/docs/STANDARDIZED-CATEGORY-FILTERING.md +0 -156
  123. package/integrations/eslint/plugin/rules/common/c076-single-behavior-per-test.js +0 -254
  124. package/rules/common/C006_function_naming/smart-analyzer.js +0 -503
@@ -1,338 +1,73 @@
1
- const fs = require('fs');
2
- const path = require('path');
1
+ const C014SymbolBasedAnalyzer = require('./symbol-based-analyzer.js');
3
2
 
4
3
  class C014Analyzer {
5
- constructor() {
4
+ constructor(semanticEngine = null) {
6
5
  this.ruleId = 'C014';
7
6
  this.ruleName = 'Dependency Injection Pattern';
8
- this.description = 'Dùng Dependency Injection thay new trực tiếp trong logic';
9
- }
10
-
11
- async analyze(files, language, options = {}) {
12
- const violations = [];
13
-
14
- for (const filePath of files) {
15
- if (options.verbose) {
16
- console.log(`🔍 Running C014 analysis on ${path.basename(filePath)}`);
17
- }
18
-
19
- try {
20
- const content = fs.readFileSync(filePath, 'utf8');
21
- const fileViolations = await this.analyzeFile(filePath, content, language, options);
22
- violations.push(...fileViolations);
23
- } catch (error) {
24
- console.warn(`⚠️ Failed to analyze ${filePath}: ${error.message}`);
25
- }
26
- }
7
+ this.description = 'Use Dependency Injection instead of direct instantiation in business logic';
8
+ this.semanticEngine = semanticEngine;
9
+ this.verbose = false;
27
10
 
28
- return violations;
11
+ // Use symbol-based only for accuracy
12
+ this.symbolAnalyzer = new C014SymbolBasedAnalyzer(semanticEngine);
29
13
  }
30
14
 
31
- async analyzeFile(filePath, content, language, config) {
32
- switch (language) {
33
- case 'typescript':
34
- case 'javascript':
35
- return this.analyzeTypeScript(filePath, content, config);
36
- default:
37
- return [];
15
+ async initialize(semanticEngine = null) {
16
+ if (semanticEngine) {
17
+ this.semanticEngine = semanticEngine;
38
18
  }
19
+ this.verbose = semanticEngine?.verbose || false;
20
+ await this.symbolAnalyzer.initialize(semanticEngine);
39
21
  }
40
22
 
41
- async analyzeTypeScript(filePath, content, config) {
42
- const violations = [];
43
- const lines = content.split('\n');
44
-
45
- lines.forEach((line, index) => {
46
- const lineNumber = index + 1;
47
- const trimmedLine = line.trim();
48
-
49
- // Skip comments and imports
50
- if (this.isCommentOrImport(trimmedLine)) {
51
- return;
52
- }
53
-
54
- // Find new expressions
55
- const newExpressions = this.findNewExpressions(trimmedLine, line);
56
-
57
- newExpressions.forEach(expr => {
58
- if (this.shouldFlag(expr.className, line, filePath)) {
59
- violations.push({
60
- ruleId: this.ruleId,
61
- file: filePath,
62
- line: lineNumber,
63
- column: expr.column,
64
- message: `Avoid direct instantiation of '${expr.className}'. Use dependency injection or factory pattern instead`,
65
- severity: 'warning',
66
- code: trimmedLine,
67
- type: 'direct_instantiation',
68
- confidence: expr.confidence,
69
- suggestion: `Consider injecting ${expr.className} as a dependency or using a factory`
70
- });
23
+ async analyzeFileBasic(filePath, options = {}) {
24
+ try {
25
+ // Check if symbol engine is ready
26
+ if (!this.semanticEngine?.isSymbolEngineReady?.() || !this.semanticEngine.project) {
27
+ const errorMsg = 'Symbol engine required for C014 analysis - consider enabling semantic analysis';
28
+ if (this.verbose) {
29
+ console.log(`[DEBUG] C014: ${errorMsg} for ${filePath.split('/').pop()}`);
71
30
  }
72
- });
73
- });
74
-
75
- return violations;
76
- }
77
-
78
- isCommentOrImport(line) {
79
- const trimmed = line.trim();
80
- return trimmed.startsWith('//') ||
81
- trimmed.startsWith('/*') ||
82
- trimmed.startsWith('*') ||
83
- trimmed.startsWith('import ') ||
84
- trimmed.startsWith('export ');
85
- }
31
+ throw new Error(errorMsg);
32
+ }
86
33
 
87
- findNewExpressions(line, originalLine) {
88
- const expressions = [];
89
- const regex = /\bnew\s+([A-Z][a-zA-Z0-9_]*)\s*\(/g;
90
-
91
- let match;
92
- while ((match = regex.exec(line)) !== null) {
93
- expressions.push({
94
- className: match[1],
95
- column: match.index + 1,
96
- confidence: this.calculateConfidence(match[1], line)
97
- });
98
- }
99
-
100
- return expressions;
101
- }
34
+ if (this.verbose) {
35
+ console.log(`[DEBUG] 🎯 C014: Using symbol-based analysis for ${filePath.split('/').pop()}`);
36
+ }
102
37
 
103
- shouldFlag(className, line, filePath) {
104
- // Don't flag built-in JavaScript/TypeScript classes and common patterns
105
- const allowedClasses = [
106
- // Built-in JavaScript classes
107
- 'Date', 'Array', 'Object', 'String', 'Number', 'Boolean', 'RegExp',
108
- 'Map', 'Set', 'WeakMap', 'WeakSet', 'Promise', 'Error', 'TypeError',
109
- 'RangeError', 'SyntaxError', 'ReferenceError', 'EvalError', 'URIError',
110
- 'Function', 'Symbol', 'BigInt', 'ArrayBuffer', 'DataView',
111
- 'Int8Array', 'Uint8Array', 'Uint8ClampedArray', 'Int16Array', 'Uint16Array',
112
- 'Int32Array', 'Uint32Array', 'Float32Array', 'Float64Array',
113
-
114
- // DOM classes (Frontend)
115
- 'FormData', 'Headers', 'Request', 'Response', 'URLSearchParams',
116
- 'URL', 'Blob', 'File', 'FileReader', 'Image', 'Audio', 'Video',
117
- 'XMLHttpRequest', 'WebSocket', 'Worker', 'MessageChannel',
118
- 'MutationObserver', 'ResizeObserver', 'IntersectionObserver',
119
- 'AbortController', 'CustomEvent', 'Event', 'ErrorEvent',
120
-
121
- // Node.js classes
122
- 'Buffer', 'URL', 'URLSearchParams', 'ReadableStream', 'WritableStream',
38
+ const violations = await this.symbolAnalyzer.analyzeFileBasic(filePath, options);
123
39
 
124
- // React/Next.js common patterns
125
- 'NextResponse', 'Response', 'Headers', 'FormData',
126
-
127
- // Common library classes that are okay to instantiate directly
128
- 'Axios', 'HttpClient', 'Logger', 'Configuration', 'Config', 'AppConfig', 'UserSettings',
129
- 'AppConfiguration', 'SystemLogger', 'Cache', 'Monitor', 'Connection', 'DatabaseConfig'
130
- ];
131
-
132
- if (allowedClasses.includes(className)) {
133
- return false;
134
- }
135
-
136
- // Don't flag if it's clearly for testing
137
- if (this.isTestContext(line, filePath)) {
138
- return false;
139
- }
140
-
141
- // Don't flag if it's in React hooks or state management
142
- if (this.isReactHookContext(line)) {
143
- return false;
144
- }
145
-
146
- // Don't flag if it's in a factory pattern or builder pattern
147
- if (this.isFactoryOrBuilderPattern(line)) {
148
- return false;
149
- }
150
-
151
- // Don't flag if it's a utility class or static helper
152
- if (this.isUtilityClass(className, line)) {
153
- return false;
154
- }
155
-
156
- // Don't flag if it's in constructor or initialization context
157
- if (this.isConstructorOrInitContext(line)) {
158
- return false;
159
- }
160
-
161
- // Don't flag if it's immediate usage pattern (e.g., new Date().getTime())
162
- if (this.isImmediateUsagePattern(line)) {
163
- return false;
164
- }
165
-
166
- return true;
167
- }
168
-
169
- isTestContext(line, filePath) {
170
- // Check if file is a test file
171
- const testPatterns = ['.test.', '.spec.', '__tests__', '/tests/'];
172
- const isTestFile = testPatterns.some(pattern => filePath.includes(pattern));
173
-
174
- if (isTestFile) {
175
- return true;
176
- }
177
-
178
- // Check if line contains test-related keywords - use word boundaries to avoid false matches
179
- const testKeywords = ['test', 'describe', 'expect', 'mock', 'spy', 'stub'];
180
- const lowerLine = line.toLowerCase();
181
-
182
- // Use word boundaries to avoid false positives like "Repository" containing "it"
183
- const hasTestKeywords = testKeywords.some(keyword => {
184
- const wordBoundaryRegex = new RegExp(`\\b${keyword}\\b`);
185
- return wordBoundaryRegex.test(lowerLine);
186
- });
187
-
188
- // Special case for "it" - only match as standalone word or in specific contexts
189
- const hasItKeyword = /\bit\s*\(/.test(lowerLine); // it( function calls
190
-
191
- return hasTestKeywords || hasItKeyword;
192
- }
193
-
194
- isFactoryOrBuilderPattern(line) {
195
- const lowerLine = line.toLowerCase();
196
- const patterns = [
197
- 'factory',
198
- 'builder',
199
- 'create',
200
- 'build',
201
- 'make',
202
- 'construct',
203
- 'getinstance',
204
- 'newinstance',
205
- '=> new',
206
- 'return new'
207
- ];
208
-
209
- return patterns.some(pattern => lowerLine.includes(pattern));
210
- }
40
+ if (this.verbose) {
41
+ console.log(`[DEBUG] 🎯 C014: Symbol-based analysis found ${violations.length} violations`);
42
+ }
211
43
 
212
- isUtilityClass(className, line) {
213
- // Common utility class patterns based on name - but exclude business logic handlers
214
- const utilityPatterns = [
215
- /Helper$/,
216
- /Util$/,
217
- /Utils$/,
218
- /Manager$/,
219
- /Processor$/,
220
- /Validator$/,
221
- /Parser$/,
222
- /Formatter$/,
223
- /Converter$/
224
- ];
225
-
226
- // Business logic handlers should not be considered utilities
227
- const businessLogicExceptions = [
228
- 'EventHandler',
229
- 'CommandHandler',
230
- 'RequestHandler',
231
- 'ActionHandler',
232
- 'MessageHandler',
233
- 'HttpHandler',
234
- 'ApiHandler'
235
- ];
236
-
237
- if (businessLogicExceptions.includes(className)) {
238
- return false; // These should be flagged as DI violations
239
- }
240
-
241
- const isUtilityName = utilityPatterns.some(pattern => pattern.test(className));
242
-
243
- if (isUtilityName) {
244
- return true;
44
+ return violations;
45
+ } catch (error) {
46
+ if (this.verbose) {
47
+ console.error(`[DEBUG] ❌ C014: Analysis failed: ${error.message}`);
48
+ }
49
+ throw new Error(`C014 analysis failed: ${error.message}`);
245
50
  }
246
-
247
- // Check if it's used as return value (factory pattern)
248
- const factoryContext = [
249
- 'return new',
250
- 'export new',
251
- 'export default new'
252
- ];
253
-
254
- return factoryContext.some(context => line.includes(context));
255
- }
256
-
257
- isConstructorOrInitContext(line) {
258
- const lowerLine = line.toLowerCase();
259
- const patterns = [
260
- 'constructor',
261
- 'init',
262
- 'setup',
263
- 'configure',
264
- 'this.',
265
- 'super(',
266
- 'initialize'
267
- ];
268
-
269
- return patterns.some(pattern => lowerLine.includes(pattern));
270
51
  }
271
52
 
272
- isReactHookContext(line) {
273
- // Check for React hooks patterns
274
- const reactHookPatterns = [
275
- 'useState(',
276
- 'useEffect(',
277
- 'useMemo(',
278
- 'useCallback(',
279
- 'useRef(',
280
- 'useContext(',
281
- 'useReducer(',
282
- 'useImperativeHandle(',
283
- 'useLayoutEffect(',
284
- 'useDebugValue(',
285
- // Custom hooks
286
- 'use[A-Z]'
287
- ];
288
-
289
- return reactHookPatterns.some(pattern => {
290
- if (pattern.includes('[A-Z]')) {
291
- return new RegExp(pattern).test(line);
53
+ async analyzeFiles(files, options = {}) {
54
+ const allViolations = [];
55
+ for (const filePath of files) {
56
+ try {
57
+ const violations = await this.analyzeFileBasic(filePath, options);
58
+ allViolations.push(...violations);
59
+ } catch (error) {
60
+ console.warn(`C014: Skipping ${filePath}: ${error.message}`);
292
61
  }
293
- return line.includes(pattern);
294
- });
295
- }
296
-
297
- isImmediateUsagePattern(line) {
298
- // Check for immediate usage patterns like new Date().getTime()
299
- const immediatePatterns = [
300
- /new\s+\w+\(\)\./, // new Date().getTime(), new Error().stack
301
- /new\s+\w+\([^)]*\)\./, // new Date(value).getTime()
302
- /window\.dispatchEvent\(new\s+/, // window.dispatchEvent(new Event())
303
- /document\.dispatchEvent\(new\s+/, // document.dispatchEvent(new Event())
304
- ];
305
-
306
- // Special case: standalone built-in class instantiation (not assignment)
307
- const standaloneBuiltinPattern = /(?:^|\s|;)\s*new\s+(Date|Error|Array|Set|Map|Promise|RegExp|URL|FormData|Event|FileReader|XMLHttpRequest)\(\)\s*;?\s*$/;
308
- if (standaloneBuiltinPattern.test(line)) {
309
- return true;
310
62
  }
311
-
312
- return immediatePatterns.some(pattern => pattern.test(line));
63
+ return allViolations;
313
64
  }
314
65
 
315
- calculateConfidence(className, line) {
316
- let confidence = 0.7; // Base confidence
317
-
318
- // Increase confidence for business logic classes
319
- if (className.includes('Service') || className.includes('Repository') ||
320
- className.includes('Controller') || className.includes('Component')) {
321
- confidence += 0.2;
322
- }
323
-
324
- // Decrease confidence if in constructor or initialization context
325
- if (line.includes('constructor') || line.includes('init') || line.includes('setup')) {
326
- confidence -= 0.1;
327
- }
328
-
329
- // Decrease confidence if it looks like configuration
330
- if (line.includes('config') || line.includes('options') || line.includes('settings')) {
331
- confidence -= 0.1;
332
- }
333
-
334
- return Math.max(0.3, Math.min(1.0, confidence));
66
+ // Legacy method for backward compatibility
67
+ async analyze(files, language, options = {}) {
68
+ return this.analyzeFiles(files, options);
335
69
  }
70
+
336
71
  }
337
72
 
338
- module.exports = new C014Analyzer();
73
+ module.exports = C014Analyzer;
@@ -0,0 +1,26 @@
1
+ {
2
+ "maxNestingLevel": 3,
3
+ "allowedBuiltins": [
4
+ "Date", "Array", "Object", "String", "Number", "Boolean", "RegExp",
5
+ "Map", "Set", "WeakMap", "WeakSet", "Promise", "Error", "TypeError",
6
+ "FormData", "Headers", "Request", "Response", "URLSearchParams",
7
+ "URL", "Blob", "File", "Buffer"
8
+ ],
9
+ "allowedValueObjects": [
10
+ "Money", "Price", "Currency", "Quantity", "Amount",
11
+ "Email", "Phone", "Address", "Name", "Id", "UserId",
12
+ "UUID", "Timestamp", "Duration", "Range"
13
+ ],
14
+ "infraPatterns": [
15
+ "Client", "Repository", "Service", "Gateway", "Adapter",
16
+ "Provider", "Factory", "Builder", "Manager", "Handler",
17
+ "Controller", "Processor", "Validator", "Logger"
18
+ ],
19
+ "excludePatterns": [
20
+ "**/*.test.ts", "**/*.spec.ts", "**/*.test.js", "**/*.spec.js",
21
+ "**/tests/**", "**/test/**", "**/migration/**", "**/scripts/**"
22
+ ],
23
+ "includePatterns": [
24
+ "**/*.js", "**/*.ts", "**/*.jsx", "**/*.tsx"
25
+ ]
26
+ }