@aiready/pattern-detect 0.17.14 → 0.17.15
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/dist/analyzer-entry/index.js +85 -0
- package/dist/analyzer-entry/index.mjs +3 -3
- package/dist/chunk-4SKGAZEW.mjs +514 -0
- package/dist/chunk-ATXO4JL7.mjs +404 -0
- package/dist/chunk-F42Q2M4O.mjs +143 -0
- package/dist/chunk-JWP5TCDM.mjs +143 -0
- package/dist/chunk-KDXWIT6W.mjs +408 -0
- package/dist/chunk-KZQXBBR3.mjs +143 -0
- package/dist/chunk-NVV4UFIV.mjs +514 -0
- package/dist/chunk-PFA2DO73.mjs +392 -0
- package/dist/chunk-WQX7IHAN.mjs +514 -0
- package/dist/cli.js +89 -4
- package/dist/cli.mjs +8 -8
- package/dist/context-rules-entry/index.js +85 -0
- package/dist/context-rules-entry/index.mjs +1 -1
- package/dist/detector-entry/index.js +85 -0
- package/dist/detector-entry/index.mjs +2 -2
- package/dist/index.js +85 -0
- package/dist/index.mjs +5 -5
- package/package.json +5 -5
|
@@ -159,12 +159,67 @@ var INFRA_RULES = [
|
|
|
159
159
|
severity: import_core3.Severity.Info,
|
|
160
160
|
reason: "CLI command definitions follow standard Commander.js patterns and are intentionally similar",
|
|
161
161
|
suggestion: "Command boilerplate duplication is acceptable for CLI interfaces"
|
|
162
|
+
},
|
|
163
|
+
// DynamoDB Single-Table Design - Standard single-table patterns with prefixed keys
|
|
164
|
+
{
|
|
165
|
+
name: "dynamodb-single-table",
|
|
166
|
+
detect: (file, code) => {
|
|
167
|
+
const hasDynamoDBPattern = code.includes("docClient") || code.includes("dynamodb") || code.includes("DynamoDB") || code.includes("queryItems") || code.includes("putItem") || code.includes("getItem") || code.includes("updateItem") || code.includes("deleteItem");
|
|
168
|
+
const hasKeyPrefix = code.includes("userId:") && code.includes("#") || code.includes("pk:") && code.includes("#") || code.includes("Key:") && code.includes("#") || /[A-Z]+#/.test(code);
|
|
169
|
+
const hasSingleTablePattern = code.includes("KeyConditionExpression") || code.includes("pk =") || code.includes("sk =") || code.includes("userId") && code.includes("timestamp");
|
|
170
|
+
return hasDynamoDBPattern && (hasKeyPrefix || hasSingleTablePattern);
|
|
171
|
+
},
|
|
172
|
+
severity: import_core3.Severity.Info,
|
|
173
|
+
reason: "DynamoDB single-table design with prefixed keys is a standard pattern for efficient data access",
|
|
174
|
+
suggestion: "Single-table query patterns are intentionally similar and should not be refactored"
|
|
175
|
+
},
|
|
176
|
+
// CLI Main Function Boilerplate - Standard argument parsing patterns
|
|
177
|
+
{
|
|
178
|
+
name: "cli-main-boilerplate",
|
|
179
|
+
detect: (file, code) => {
|
|
180
|
+
const basename = file.split("/").pop() || "";
|
|
181
|
+
const isCliFile = file.includes("/cli/") || file.includes("/commands/") || basename.startsWith("cli") || basename.endsWith(".cli.ts") || basename.endsWith(".cli.js");
|
|
182
|
+
const hasMainFunction = code.includes("function main()") || code.includes("async function main()") || code.includes("const main =") || code.includes("main()");
|
|
183
|
+
const hasArgParsing = code.includes("process.argv") || code.includes("yargs") || code.includes("commander") || code.includes("minimist") || code.includes(".parse(") || code.includes("args") && code.includes("._");
|
|
184
|
+
return isCliFile && hasMainFunction && hasArgParsing;
|
|
185
|
+
},
|
|
186
|
+
severity: import_core3.Severity.Info,
|
|
187
|
+
reason: "CLI main functions with argument parsing follow standard boilerplate patterns",
|
|
188
|
+
suggestion: "CLI argument parsing boilerplate is acceptable and should not be flagged as duplication"
|
|
162
189
|
}
|
|
163
190
|
];
|
|
164
191
|
|
|
165
192
|
// src/rules/categories/logic-rules.ts
|
|
166
193
|
var import_core4 = require("@aiready/core");
|
|
167
194
|
var LOGIC_RULES = [
|
|
195
|
+
// Enum Semantic Difference - Different enum names indicate different semantic meanings
|
|
196
|
+
{
|
|
197
|
+
name: "enum-semantic-difference",
|
|
198
|
+
detect: (file, code) => {
|
|
199
|
+
const enumRegex = /(?:export\s+)?(?:const\s+)?enum\s+([A-Z][a-zA-Z0-9]*)/g;
|
|
200
|
+
const enums = [];
|
|
201
|
+
let match;
|
|
202
|
+
while ((match = enumRegex.exec(code)) !== null) {
|
|
203
|
+
enums.push(match[1]);
|
|
204
|
+
}
|
|
205
|
+
return enums.length > 0;
|
|
206
|
+
},
|
|
207
|
+
severity: import_core4.Severity.Info,
|
|
208
|
+
reason: "Enums with different names represent different semantic domain concepts, even if they share similar values",
|
|
209
|
+
suggestion: "Different enums (e.g., EscalationPriority vs HealthSeverity) serve different purposes and should not be merged"
|
|
210
|
+
},
|
|
211
|
+
// Enum Value Similarity - Common enum values like LOW, MEDIUM, HIGH are standard
|
|
212
|
+
{
|
|
213
|
+
name: "enum-value-similarity",
|
|
214
|
+
detect: (file, code) => {
|
|
215
|
+
const hasCommonEnumValues = (code.includes("LOW = 'low'") || code.includes("LOW = 0") || code.includes("LOW = 'LOW'")) && (code.includes("HIGH = 'high'") || code.includes("HIGH = 2") || code.includes("HIGH = 'HIGH'")) && (code.includes("MEDIUM = 'medium'") || code.includes("MEDIUM = 1") || code.includes("MEDIUM = 'MEDIUM'"));
|
|
216
|
+
const isEnumDefinition = /(?:export\s+)?(?:const\s+)?enum\s+/.test(code) || code.includes("enum ") && code.includes("{") && code.includes("}");
|
|
217
|
+
return hasCommonEnumValues && isEnumDefinition;
|
|
218
|
+
},
|
|
219
|
+
severity: import_core4.Severity.Info,
|
|
220
|
+
reason: "Common enum values (LOW, MEDIUM, HIGH, CRITICAL) are standard patterns used across different domain enums",
|
|
221
|
+
suggestion: "Enum value similarity is expected for severity/priority enums and should not be flagged as duplication"
|
|
222
|
+
},
|
|
168
223
|
// Re-export / Barrel files - Intentional API surface consolidation
|
|
169
224
|
{
|
|
170
225
|
name: "re-export-files",
|
|
@@ -194,6 +249,20 @@ var LOGIC_RULES = [
|
|
|
194
249
|
reason: "Type/interface definitions are intentionally duplicated for module independence",
|
|
195
250
|
suggestion: "Extract to shared types package only if causing maintenance burden"
|
|
196
251
|
},
|
|
252
|
+
// Cross-Package Type Definitions - Different packages may have similar types
|
|
253
|
+
{
|
|
254
|
+
name: "cross-package-types",
|
|
255
|
+
detect: (file, code) => {
|
|
256
|
+
const hasTypeDefinition = code.includes("interface ") || code.includes("type ") || code.includes("enum ");
|
|
257
|
+
const isPackageOrApp = file.includes("/packages/") || file.includes("/apps/") || file.includes("/core/");
|
|
258
|
+
const packageMatch = file.match(/\/(packages|apps|core)\/([^/]+)\//);
|
|
259
|
+
const hasPackageStructure = packageMatch !== null;
|
|
260
|
+
return hasTypeDefinition && isPackageOrApp && hasPackageStructure;
|
|
261
|
+
},
|
|
262
|
+
severity: import_core4.Severity.Info,
|
|
263
|
+
reason: "Types in different packages/modules are often intentionally similar for module independence",
|
|
264
|
+
suggestion: "Cross-package type duplication is acceptable for decoupled module architecture"
|
|
265
|
+
},
|
|
197
266
|
// Utility Functions - Small helpers in dedicated utility files
|
|
198
267
|
{
|
|
199
268
|
name: "utility-functions",
|
|
@@ -276,6 +345,22 @@ var LOGIC_RULES = [
|
|
|
276
345
|
severity: import_core4.Severity.Info,
|
|
277
346
|
reason: "Validation functions are inherently similar and often intentionally duplicated for domain clarity",
|
|
278
347
|
suggestion: "Consider extracting to shared validators only if validation logic becomes complex"
|
|
348
|
+
},
|
|
349
|
+
// Singleton Getter Pattern - Standard singleton initialization pattern
|
|
350
|
+
{
|
|
351
|
+
name: "singleton-getter",
|
|
352
|
+
detect: (file, code) => {
|
|
353
|
+
const hasSingletonGetter = /(?:export\s+)?(?:async\s+)?function\s+get[A-Z][a-zA-Z0-9]*\s*\(/.test(
|
|
354
|
+
code
|
|
355
|
+
) || /(?:export\s+)?const\s+get[A-Z][a-zA-Z0-9]*\s*=\s*(?:async\s+)?\(\)\s*=>/.test(
|
|
356
|
+
code
|
|
357
|
+
);
|
|
358
|
+
const hasSingletonPattern = code.includes("if (!") && code.includes("instance") && code.includes(" = ") || code.includes("if (!_") && code.includes(" = new ") || code.includes("if (") && code.includes(" === null") && code.includes(" = new ");
|
|
359
|
+
return hasSingletonGetter && hasSingletonPattern;
|
|
360
|
+
},
|
|
361
|
+
severity: import_core4.Severity.Info,
|
|
362
|
+
reason: "Singleton getter functions follow standard initialization pattern and are intentionally similar",
|
|
363
|
+
suggestion: "Singleton getters are boilerplate and acceptable duplication for lazy initialization"
|
|
279
364
|
}
|
|
280
365
|
];
|
|
281
366
|
|
|
@@ -159,12 +159,67 @@ var INFRA_RULES = [
|
|
|
159
159
|
severity: import_core3.Severity.Info,
|
|
160
160
|
reason: "CLI command definitions follow standard Commander.js patterns and are intentionally similar",
|
|
161
161
|
suggestion: "Command boilerplate duplication is acceptable for CLI interfaces"
|
|
162
|
+
},
|
|
163
|
+
// DynamoDB Single-Table Design - Standard single-table patterns with prefixed keys
|
|
164
|
+
{
|
|
165
|
+
name: "dynamodb-single-table",
|
|
166
|
+
detect: (file, code) => {
|
|
167
|
+
const hasDynamoDBPattern = code.includes("docClient") || code.includes("dynamodb") || code.includes("DynamoDB") || code.includes("queryItems") || code.includes("putItem") || code.includes("getItem") || code.includes("updateItem") || code.includes("deleteItem");
|
|
168
|
+
const hasKeyPrefix = code.includes("userId:") && code.includes("#") || code.includes("pk:") && code.includes("#") || code.includes("Key:") && code.includes("#") || /[A-Z]+#/.test(code);
|
|
169
|
+
const hasSingleTablePattern = code.includes("KeyConditionExpression") || code.includes("pk =") || code.includes("sk =") || code.includes("userId") && code.includes("timestamp");
|
|
170
|
+
return hasDynamoDBPattern && (hasKeyPrefix || hasSingleTablePattern);
|
|
171
|
+
},
|
|
172
|
+
severity: import_core3.Severity.Info,
|
|
173
|
+
reason: "DynamoDB single-table design with prefixed keys is a standard pattern for efficient data access",
|
|
174
|
+
suggestion: "Single-table query patterns are intentionally similar and should not be refactored"
|
|
175
|
+
},
|
|
176
|
+
// CLI Main Function Boilerplate - Standard argument parsing patterns
|
|
177
|
+
{
|
|
178
|
+
name: "cli-main-boilerplate",
|
|
179
|
+
detect: (file, code) => {
|
|
180
|
+
const basename = file.split("/").pop() || "";
|
|
181
|
+
const isCliFile = file.includes("/cli/") || file.includes("/commands/") || basename.startsWith("cli") || basename.endsWith(".cli.ts") || basename.endsWith(".cli.js");
|
|
182
|
+
const hasMainFunction = code.includes("function main()") || code.includes("async function main()") || code.includes("const main =") || code.includes("main()");
|
|
183
|
+
const hasArgParsing = code.includes("process.argv") || code.includes("yargs") || code.includes("commander") || code.includes("minimist") || code.includes(".parse(") || code.includes("args") && code.includes("._");
|
|
184
|
+
return isCliFile && hasMainFunction && hasArgParsing;
|
|
185
|
+
},
|
|
186
|
+
severity: import_core3.Severity.Info,
|
|
187
|
+
reason: "CLI main functions with argument parsing follow standard boilerplate patterns",
|
|
188
|
+
suggestion: "CLI argument parsing boilerplate is acceptable and should not be flagged as duplication"
|
|
162
189
|
}
|
|
163
190
|
];
|
|
164
191
|
|
|
165
192
|
// src/rules/categories/logic-rules.ts
|
|
166
193
|
var import_core4 = require("@aiready/core");
|
|
167
194
|
var LOGIC_RULES = [
|
|
195
|
+
// Enum Semantic Difference - Different enum names indicate different semantic meanings
|
|
196
|
+
{
|
|
197
|
+
name: "enum-semantic-difference",
|
|
198
|
+
detect: (file, code) => {
|
|
199
|
+
const enumRegex = /(?:export\s+)?(?:const\s+)?enum\s+([A-Z][a-zA-Z0-9]*)/g;
|
|
200
|
+
const enums = [];
|
|
201
|
+
let match;
|
|
202
|
+
while ((match = enumRegex.exec(code)) !== null) {
|
|
203
|
+
enums.push(match[1]);
|
|
204
|
+
}
|
|
205
|
+
return enums.length > 0;
|
|
206
|
+
},
|
|
207
|
+
severity: import_core4.Severity.Info,
|
|
208
|
+
reason: "Enums with different names represent different semantic domain concepts, even if they share similar values",
|
|
209
|
+
suggestion: "Different enums (e.g., EscalationPriority vs HealthSeverity) serve different purposes and should not be merged"
|
|
210
|
+
},
|
|
211
|
+
// Enum Value Similarity - Common enum values like LOW, MEDIUM, HIGH are standard
|
|
212
|
+
{
|
|
213
|
+
name: "enum-value-similarity",
|
|
214
|
+
detect: (file, code) => {
|
|
215
|
+
const hasCommonEnumValues = (code.includes("LOW = 'low'") || code.includes("LOW = 0") || code.includes("LOW = 'LOW'")) && (code.includes("HIGH = 'high'") || code.includes("HIGH = 2") || code.includes("HIGH = 'HIGH'")) && (code.includes("MEDIUM = 'medium'") || code.includes("MEDIUM = 1") || code.includes("MEDIUM = 'MEDIUM'"));
|
|
216
|
+
const isEnumDefinition = /(?:export\s+)?(?:const\s+)?enum\s+/.test(code) || code.includes("enum ") && code.includes("{") && code.includes("}");
|
|
217
|
+
return hasCommonEnumValues && isEnumDefinition;
|
|
218
|
+
},
|
|
219
|
+
severity: import_core4.Severity.Info,
|
|
220
|
+
reason: "Common enum values (LOW, MEDIUM, HIGH, CRITICAL) are standard patterns used across different domain enums",
|
|
221
|
+
suggestion: "Enum value similarity is expected for severity/priority enums and should not be flagged as duplication"
|
|
222
|
+
},
|
|
168
223
|
// Re-export / Barrel files - Intentional API surface consolidation
|
|
169
224
|
{
|
|
170
225
|
name: "re-export-files",
|
|
@@ -194,6 +249,20 @@ var LOGIC_RULES = [
|
|
|
194
249
|
reason: "Type/interface definitions are intentionally duplicated for module independence",
|
|
195
250
|
suggestion: "Extract to shared types package only if causing maintenance burden"
|
|
196
251
|
},
|
|
252
|
+
// Cross-Package Type Definitions - Different packages may have similar types
|
|
253
|
+
{
|
|
254
|
+
name: "cross-package-types",
|
|
255
|
+
detect: (file, code) => {
|
|
256
|
+
const hasTypeDefinition = code.includes("interface ") || code.includes("type ") || code.includes("enum ");
|
|
257
|
+
const isPackageOrApp = file.includes("/packages/") || file.includes("/apps/") || file.includes("/core/");
|
|
258
|
+
const packageMatch = file.match(/\/(packages|apps|core)\/([^/]+)\//);
|
|
259
|
+
const hasPackageStructure = packageMatch !== null;
|
|
260
|
+
return hasTypeDefinition && isPackageOrApp && hasPackageStructure;
|
|
261
|
+
},
|
|
262
|
+
severity: import_core4.Severity.Info,
|
|
263
|
+
reason: "Types in different packages/modules are often intentionally similar for module independence",
|
|
264
|
+
suggestion: "Cross-package type duplication is acceptable for decoupled module architecture"
|
|
265
|
+
},
|
|
197
266
|
// Utility Functions - Small helpers in dedicated utility files
|
|
198
267
|
{
|
|
199
268
|
name: "utility-functions",
|
|
@@ -276,6 +345,22 @@ var LOGIC_RULES = [
|
|
|
276
345
|
severity: import_core4.Severity.Info,
|
|
277
346
|
reason: "Validation functions are inherently similar and often intentionally duplicated for domain clarity",
|
|
278
347
|
suggestion: "Consider extracting to shared validators only if validation logic becomes complex"
|
|
348
|
+
},
|
|
349
|
+
// Singleton Getter Pattern - Standard singleton initialization pattern
|
|
350
|
+
{
|
|
351
|
+
name: "singleton-getter",
|
|
352
|
+
detect: (file, code) => {
|
|
353
|
+
const hasSingletonGetter = /(?:export\s+)?(?:async\s+)?function\s+get[A-Z][a-zA-Z0-9]*\s*\(/.test(
|
|
354
|
+
code
|
|
355
|
+
) || /(?:export\s+)?const\s+get[A-Z][a-zA-Z0-9]*\s*=\s*(?:async\s+)?\(\)\s*=>/.test(
|
|
356
|
+
code
|
|
357
|
+
);
|
|
358
|
+
const hasSingletonPattern = code.includes("if (!") && code.includes("instance") && code.includes(" = ") || code.includes("if (!_") && code.includes(" = new ") || code.includes("if (") && code.includes(" === null") && code.includes(" = new ");
|
|
359
|
+
return hasSingletonGetter && hasSingletonPattern;
|
|
360
|
+
},
|
|
361
|
+
severity: import_core4.Severity.Info,
|
|
362
|
+
reason: "Singleton getter functions follow standard initialization pattern and are intentionally similar",
|
|
363
|
+
suggestion: "Singleton getters are boilerplate and acceptable duplication for lazy initialization"
|
|
279
364
|
}
|
|
280
365
|
];
|
|
281
366
|
|
package/dist/index.js
CHANGED
|
@@ -191,12 +191,67 @@ var INFRA_RULES = [
|
|
|
191
191
|
severity: import_core3.Severity.Info,
|
|
192
192
|
reason: "CLI command definitions follow standard Commander.js patterns and are intentionally similar",
|
|
193
193
|
suggestion: "Command boilerplate duplication is acceptable for CLI interfaces"
|
|
194
|
+
},
|
|
195
|
+
// DynamoDB Single-Table Design - Standard single-table patterns with prefixed keys
|
|
196
|
+
{
|
|
197
|
+
name: "dynamodb-single-table",
|
|
198
|
+
detect: (file, code) => {
|
|
199
|
+
const hasDynamoDBPattern = code.includes("docClient") || code.includes("dynamodb") || code.includes("DynamoDB") || code.includes("queryItems") || code.includes("putItem") || code.includes("getItem") || code.includes("updateItem") || code.includes("deleteItem");
|
|
200
|
+
const hasKeyPrefix = code.includes("userId:") && code.includes("#") || code.includes("pk:") && code.includes("#") || code.includes("Key:") && code.includes("#") || /[A-Z]+#/.test(code);
|
|
201
|
+
const hasSingleTablePattern = code.includes("KeyConditionExpression") || code.includes("pk =") || code.includes("sk =") || code.includes("userId") && code.includes("timestamp");
|
|
202
|
+
return hasDynamoDBPattern && (hasKeyPrefix || hasSingleTablePattern);
|
|
203
|
+
},
|
|
204
|
+
severity: import_core3.Severity.Info,
|
|
205
|
+
reason: "DynamoDB single-table design with prefixed keys is a standard pattern for efficient data access",
|
|
206
|
+
suggestion: "Single-table query patterns are intentionally similar and should not be refactored"
|
|
207
|
+
},
|
|
208
|
+
// CLI Main Function Boilerplate - Standard argument parsing patterns
|
|
209
|
+
{
|
|
210
|
+
name: "cli-main-boilerplate",
|
|
211
|
+
detect: (file, code) => {
|
|
212
|
+
const basename = file.split("/").pop() || "";
|
|
213
|
+
const isCliFile = file.includes("/cli/") || file.includes("/commands/") || basename.startsWith("cli") || basename.endsWith(".cli.ts") || basename.endsWith(".cli.js");
|
|
214
|
+
const hasMainFunction = code.includes("function main()") || code.includes("async function main()") || code.includes("const main =") || code.includes("main()");
|
|
215
|
+
const hasArgParsing = code.includes("process.argv") || code.includes("yargs") || code.includes("commander") || code.includes("minimist") || code.includes(".parse(") || code.includes("args") && code.includes("._");
|
|
216
|
+
return isCliFile && hasMainFunction && hasArgParsing;
|
|
217
|
+
},
|
|
218
|
+
severity: import_core3.Severity.Info,
|
|
219
|
+
reason: "CLI main functions with argument parsing follow standard boilerplate patterns",
|
|
220
|
+
suggestion: "CLI argument parsing boilerplate is acceptable and should not be flagged as duplication"
|
|
194
221
|
}
|
|
195
222
|
];
|
|
196
223
|
|
|
197
224
|
// src/rules/categories/logic-rules.ts
|
|
198
225
|
var import_core4 = require("@aiready/core");
|
|
199
226
|
var LOGIC_RULES = [
|
|
227
|
+
// Enum Semantic Difference - Different enum names indicate different semantic meanings
|
|
228
|
+
{
|
|
229
|
+
name: "enum-semantic-difference",
|
|
230
|
+
detect: (file, code) => {
|
|
231
|
+
const enumRegex = /(?:export\s+)?(?:const\s+)?enum\s+([A-Z][a-zA-Z0-9]*)/g;
|
|
232
|
+
const enums = [];
|
|
233
|
+
let match;
|
|
234
|
+
while ((match = enumRegex.exec(code)) !== null) {
|
|
235
|
+
enums.push(match[1]);
|
|
236
|
+
}
|
|
237
|
+
return enums.length > 0;
|
|
238
|
+
},
|
|
239
|
+
severity: import_core4.Severity.Info,
|
|
240
|
+
reason: "Enums with different names represent different semantic domain concepts, even if they share similar values",
|
|
241
|
+
suggestion: "Different enums (e.g., EscalationPriority vs HealthSeverity) serve different purposes and should not be merged"
|
|
242
|
+
},
|
|
243
|
+
// Enum Value Similarity - Common enum values like LOW, MEDIUM, HIGH are standard
|
|
244
|
+
{
|
|
245
|
+
name: "enum-value-similarity",
|
|
246
|
+
detect: (file, code) => {
|
|
247
|
+
const hasCommonEnumValues = (code.includes("LOW = 'low'") || code.includes("LOW = 0") || code.includes("LOW = 'LOW'")) && (code.includes("HIGH = 'high'") || code.includes("HIGH = 2") || code.includes("HIGH = 'HIGH'")) && (code.includes("MEDIUM = 'medium'") || code.includes("MEDIUM = 1") || code.includes("MEDIUM = 'MEDIUM'"));
|
|
248
|
+
const isEnumDefinition = /(?:export\s+)?(?:const\s+)?enum\s+/.test(code) || code.includes("enum ") && code.includes("{") && code.includes("}");
|
|
249
|
+
return hasCommonEnumValues && isEnumDefinition;
|
|
250
|
+
},
|
|
251
|
+
severity: import_core4.Severity.Info,
|
|
252
|
+
reason: "Common enum values (LOW, MEDIUM, HIGH, CRITICAL) are standard patterns used across different domain enums",
|
|
253
|
+
suggestion: "Enum value similarity is expected for severity/priority enums and should not be flagged as duplication"
|
|
254
|
+
},
|
|
200
255
|
// Re-export / Barrel files - Intentional API surface consolidation
|
|
201
256
|
{
|
|
202
257
|
name: "re-export-files",
|
|
@@ -226,6 +281,20 @@ var LOGIC_RULES = [
|
|
|
226
281
|
reason: "Type/interface definitions are intentionally duplicated for module independence",
|
|
227
282
|
suggestion: "Extract to shared types package only if causing maintenance burden"
|
|
228
283
|
},
|
|
284
|
+
// Cross-Package Type Definitions - Different packages may have similar types
|
|
285
|
+
{
|
|
286
|
+
name: "cross-package-types",
|
|
287
|
+
detect: (file, code) => {
|
|
288
|
+
const hasTypeDefinition = code.includes("interface ") || code.includes("type ") || code.includes("enum ");
|
|
289
|
+
const isPackageOrApp = file.includes("/packages/") || file.includes("/apps/") || file.includes("/core/");
|
|
290
|
+
const packageMatch = file.match(/\/(packages|apps|core)\/([^/]+)\//);
|
|
291
|
+
const hasPackageStructure = packageMatch !== null;
|
|
292
|
+
return hasTypeDefinition && isPackageOrApp && hasPackageStructure;
|
|
293
|
+
},
|
|
294
|
+
severity: import_core4.Severity.Info,
|
|
295
|
+
reason: "Types in different packages/modules are often intentionally similar for module independence",
|
|
296
|
+
suggestion: "Cross-package type duplication is acceptable for decoupled module architecture"
|
|
297
|
+
},
|
|
229
298
|
// Utility Functions - Small helpers in dedicated utility files
|
|
230
299
|
{
|
|
231
300
|
name: "utility-functions",
|
|
@@ -308,6 +377,22 @@ var LOGIC_RULES = [
|
|
|
308
377
|
severity: import_core4.Severity.Info,
|
|
309
378
|
reason: "Validation functions are inherently similar and often intentionally duplicated for domain clarity",
|
|
310
379
|
suggestion: "Consider extracting to shared validators only if validation logic becomes complex"
|
|
380
|
+
},
|
|
381
|
+
// Singleton Getter Pattern - Standard singleton initialization pattern
|
|
382
|
+
{
|
|
383
|
+
name: "singleton-getter",
|
|
384
|
+
detect: (file, code) => {
|
|
385
|
+
const hasSingletonGetter = /(?:export\s+)?(?:async\s+)?function\s+get[A-Z][a-zA-Z0-9]*\s*\(/.test(
|
|
386
|
+
code
|
|
387
|
+
) || /(?:export\s+)?const\s+get[A-Z][a-zA-Z0-9]*\s*=\s*(?:async\s+)?\(\)\s*=>/.test(
|
|
388
|
+
code
|
|
389
|
+
);
|
|
390
|
+
const hasSingletonPattern = code.includes("if (!") && code.includes("instance") && code.includes(" = ") || code.includes("if (!_") && code.includes(" = new ") || code.includes("if (") && code.includes(" === null") && code.includes(" = new ");
|
|
391
|
+
return hasSingletonGetter && hasSingletonPattern;
|
|
392
|
+
},
|
|
393
|
+
severity: import_core4.Severity.Info,
|
|
394
|
+
reason: "Singleton getter functions follow standard initialization pattern and are intentionally similar",
|
|
395
|
+
suggestion: "Singleton getters are boilerplate and acceptable duplication for lazy initialization"
|
|
311
396
|
}
|
|
312
397
|
];
|
|
313
398
|
|
package/dist/index.mjs
CHANGED
|
@@ -12,16 +12,16 @@ import {
|
|
|
12
12
|
getSmartDefaults,
|
|
13
13
|
groupDuplicatesByFilePair,
|
|
14
14
|
logConfiguration
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-WQX7IHAN.mjs";
|
|
16
16
|
import {
|
|
17
17
|
detectDuplicatePatterns
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-JWP5TCDM.mjs";
|
|
19
|
+
import {
|
|
20
|
+
filterBySeverity
|
|
21
|
+
} from "./chunk-KDXWIT6W.mjs";
|
|
19
22
|
import {
|
|
20
23
|
calculatePatternScore
|
|
21
24
|
} from "./chunk-G3GZFYRI.mjs";
|
|
22
|
-
import {
|
|
23
|
-
filterBySeverity
|
|
24
|
-
} from "./chunk-UKQFCUQA.mjs";
|
|
25
25
|
|
|
26
26
|
// src/index.ts
|
|
27
27
|
import { ToolRegistry } from "@aiready/core";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiready/pattern-detect",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.15",
|
|
4
4
|
"description": "Semantic duplicate pattern detection for AI-generated code - finds similar implementations that waste AI context tokens",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -56,16 +56,16 @@
|
|
|
56
56
|
"license": "MIT",
|
|
57
57
|
"repository": {
|
|
58
58
|
"type": "git",
|
|
59
|
-
"url": "https://github.com/
|
|
59
|
+
"url": "https://github.com/getaiready/aiready-pattern-detect.git"
|
|
60
60
|
},
|
|
61
|
-
"homepage": "https://github.com/
|
|
61
|
+
"homepage": "https://github.com/getaiready/aiready-pattern-detect",
|
|
62
62
|
"bugs": {
|
|
63
|
-
"url": "https://github.com/
|
|
63
|
+
"url": "https://github.com/getaiready/aiready-pattern-detect/issues"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"commander": "^14.0.0",
|
|
67
67
|
"chalk": "^5.3.0",
|
|
68
|
-
"@aiready/core": "0.24.
|
|
68
|
+
"@aiready/core": "0.24.16"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"tsup": "^8.3.5",
|