@aiready/core 0.24.13 → 0.24.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.
@@ -0,0 +1,304 @@
1
+ import {
2
+ ParseError
3
+ } from "./chunk-U3IY2CFC.mjs";
4
+
5
+ // src/parsers/typescript-parser.ts
6
+ import { parse } from "@typescript-eslint/typescript-estree";
7
+ var TypeScriptParser = class {
8
+ constructor() {
9
+ this.language = "typescript" /* TypeScript */;
10
+ this.extensions = [".ts", ".tsx", ".js", ".jsx"];
11
+ }
12
+ async initialize() {
13
+ }
14
+ canHandle(filePath) {
15
+ return this.extensions.some((ext) => filePath.endsWith(ext));
16
+ }
17
+ async getAST(code, filePath) {
18
+ try {
19
+ return parse(code, {
20
+ filePath,
21
+ loc: true,
22
+ range: true,
23
+ tokens: true,
24
+ comment: true,
25
+ jsx: filePath.endsWith("x")
26
+ });
27
+ } catch (error) {
28
+ const err = error;
29
+ throw new ParseError(err.message || "Unknown error", filePath, {
30
+ line: err.lineNumber || 1,
31
+ column: err.column || 0
32
+ });
33
+ }
34
+ }
35
+ parse(code, filePath) {
36
+ try {
37
+ const ast = parse(code, {
38
+ filePath,
39
+ loc: true,
40
+ range: true,
41
+ tokens: true,
42
+ comment: true,
43
+ jsx: filePath.endsWith("x")
44
+ });
45
+ const imports = this.extractImports(ast);
46
+ const exports = this.extractExports(ast, code, filePath);
47
+ return {
48
+ exports,
49
+ imports,
50
+ language: this.language
51
+ };
52
+ } catch (error) {
53
+ throw new ParseError(error.message, filePath, {
54
+ line: error.lineNumber || 1,
55
+ column: error.column || 0
56
+ });
57
+ }
58
+ }
59
+ getNamingConventions() {
60
+ return {
61
+ variablePattern: /^[a-z][a-zA-Z0-9]*$/,
62
+ functionPattern: /^[a-z][a-zA-Z0-9]*$/,
63
+ classPattern: /^[A-Z][a-zA-Z0-9]*$/,
64
+ constantPattern: /^[A-Z][A-Z0-9_]*$/,
65
+ typePattern: /^[A-Z][a-zA-Z0-9]*$/,
66
+ interfacePattern: /^I?[A-Z][a-zA-Z0-9]*$/
67
+ };
68
+ }
69
+ analyzeMetadata(node, code) {
70
+ if (!code) return {};
71
+ return {
72
+ isPure: this.isLikelyPure(node),
73
+ hasSideEffects: !this.isLikelyPure(node)
74
+ };
75
+ }
76
+ extractImports(ast) {
77
+ const imports = [];
78
+ for (const node of ast.body) {
79
+ if (node.type === "ImportDeclaration") {
80
+ const specifiers = [];
81
+ let isTypeOnly = false;
82
+ if (node.importKind === "type") {
83
+ isTypeOnly = true;
84
+ }
85
+ for (const spec of node.specifiers) {
86
+ if (spec.type === "ImportSpecifier") {
87
+ const imported = spec.imported;
88
+ const name = imported.type === "Identifier" ? imported.name : imported.value;
89
+ specifiers.push(name);
90
+ } else if (spec.type === "ImportDefaultSpecifier") {
91
+ specifiers.push("default");
92
+ } else if (spec.type === "ImportNamespaceSpecifier") {
93
+ specifiers.push("*");
94
+ }
95
+ }
96
+ imports.push({
97
+ source: node.source.value,
98
+ specifiers,
99
+ isTypeOnly,
100
+ loc: node.loc ? {
101
+ start: {
102
+ line: node.loc.start.line,
103
+ column: node.loc.start.column
104
+ },
105
+ end: { line: node.loc.end.line, column: node.loc.end.column }
106
+ } : void 0
107
+ });
108
+ }
109
+ }
110
+ return imports;
111
+ }
112
+ extractExports(ast, code, filePath) {
113
+ const exports = [];
114
+ for (const node of ast.body) {
115
+ if (node.type === "ExportNamedDeclaration") {
116
+ if (node.declaration) {
117
+ const declaration = node.declaration;
118
+ if ((declaration.type === "FunctionDeclaration" || declaration.type === "TSDeclareFunction") && declaration.id) {
119
+ exports.push(
120
+ this.createExport(
121
+ declaration.id.name,
122
+ "function",
123
+ node,
124
+ // Pass the outer ExportNamedDeclaration
125
+ code,
126
+ filePath
127
+ )
128
+ );
129
+ } else if (declaration.type === "ClassDeclaration" && declaration.id) {
130
+ exports.push(
131
+ this.createExport(
132
+ declaration.id.name,
133
+ "class",
134
+ node,
135
+ // Pass the outer ExportNamedDeclaration
136
+ code,
137
+ filePath
138
+ )
139
+ );
140
+ } else if (declaration.type === "TSTypeAliasDeclaration") {
141
+ exports.push(
142
+ this.createExport(
143
+ declaration.id.name,
144
+ "type",
145
+ node,
146
+ // Pass the outer ExportNamedDeclaration
147
+ code,
148
+ filePath
149
+ )
150
+ );
151
+ } else if (declaration.type === "TSInterfaceDeclaration") {
152
+ exports.push(
153
+ this.createExport(
154
+ declaration.id.name,
155
+ "interface",
156
+ node,
157
+ // Pass the outer ExportNamedDeclaration
158
+ code,
159
+ filePath
160
+ )
161
+ );
162
+ } else if (declaration.type === "VariableDeclaration") {
163
+ for (const decl of declaration.declarations) {
164
+ if (decl.id.type === "Identifier") {
165
+ exports.push(
166
+ this.createExport(
167
+ decl.id.name,
168
+ "const",
169
+ node,
170
+ code,
171
+ filePath,
172
+ decl.init
173
+ )
174
+ );
175
+ }
176
+ }
177
+ }
178
+ }
179
+ } else if (node.type === "ExportDefaultDeclaration") {
180
+ exports.push(
181
+ this.createExport("default", "default", node, code, filePath)
182
+ );
183
+ }
184
+ }
185
+ return exports;
186
+ }
187
+ createExport(name, type, node, code, filePath, initializer) {
188
+ const documentation = this.extractDocumentation(node, code);
189
+ let methodCount;
190
+ let propertyCount;
191
+ let parameters;
192
+ let isPrimitive = false;
193
+ let isTyped = false;
194
+ if (initializer) {
195
+ if (initializer.type === "Literal" || initializer.type === "TemplateLiteral" && initializer.expressions.length === 0) {
196
+ isPrimitive = true;
197
+ }
198
+ }
199
+ let structNode = node.type === "ExportNamedDeclaration" && node.declaration ? node.declaration : node.type === "ExportDefaultDeclaration" ? node.declaration : node;
200
+ if (!structNode) structNode = node;
201
+ if (filePath.endsWith(".ts") || filePath.endsWith(".tsx")) {
202
+ if (structNode.type === "TSTypeAliasDeclaration" || structNode.type === "TSInterfaceDeclaration" || structNode.type === "TSEnumDeclaration") {
203
+ isTyped = true;
204
+ } else if (structNode.type === "FunctionDeclaration" || structNode.type === "TSDeclareFunction") {
205
+ const func = structNode;
206
+ const hasReturnType = !!func.returnType;
207
+ const allParamsTyped = func.params.length === 0 || func.params.every((p) => !!p.typeAnnotation);
208
+ isTyped = hasReturnType && allParamsTyped;
209
+ } else if (structNode.type === "VariableDeclaration") {
210
+ const variable = structNode;
211
+ isTyped = variable.declarations.every(
212
+ (d) => !!d.id.typeAnnotation || !!d.init
213
+ );
214
+ } else if (structNode.type === "ClassDeclaration") {
215
+ isTyped = true;
216
+ }
217
+ } else if (filePath.endsWith(".js") || filePath.endsWith(".jsx")) {
218
+ isTyped = false;
219
+ }
220
+ if (structNode.type === "ClassDeclaration" || structNode.type === "TSInterfaceDeclaration") {
221
+ const body = structNode.type === "ClassDeclaration" ? structNode.body.body : structNode.body.body;
222
+ methodCount = body.filter(
223
+ (m) => m.type === "MethodDefinition" || m.type === "TSMethodSignature"
224
+ ).length;
225
+ propertyCount = body.filter(
226
+ (m) => m.type === "PropertyDefinition" || m.type === "TSPropertySignature"
227
+ ).length;
228
+ if (structNode.type === "ClassDeclaration") {
229
+ const constructor = body.find(
230
+ (m) => m.type === "MethodDefinition" && m.kind === "constructor"
231
+ );
232
+ if (constructor && constructor.value && constructor.value.params) {
233
+ parameters = constructor.value.params.map((p) => {
234
+ if (p.type === "Identifier") return p.name;
235
+ if (p.type === "TSParameterProperty" && p.parameter.type === "Identifier") {
236
+ return p.parameter.name;
237
+ }
238
+ return void 0;
239
+ }).filter((p) => !!p);
240
+ }
241
+ }
242
+ }
243
+ if (!parameters && (structNode.type === "FunctionDeclaration" || structNode.type === "TSDeclareFunction" || structNode.type === "MethodDefinition")) {
244
+ const funcNode = structNode.type === "MethodDefinition" ? structNode.value : structNode;
245
+ if (funcNode && funcNode.params) {
246
+ parameters = funcNode.params.map((p) => {
247
+ if (p.type === "Identifier") return p.name;
248
+ return void 0;
249
+ }).filter((p) => !!p);
250
+ }
251
+ }
252
+ return {
253
+ name,
254
+ type,
255
+ isPrimitive,
256
+ loc: node.loc ? {
257
+ start: { line: node.loc.start.line, column: node.loc.start.column },
258
+ end: { line: node.loc.end.line, column: node.loc.end.column }
259
+ } : void 0,
260
+ documentation,
261
+ methodCount,
262
+ propertyCount,
263
+ parameters,
264
+ isPure: this.isLikelyPure(node),
265
+ hasSideEffects: !this.isLikelyPure(node),
266
+ isTyped
267
+ };
268
+ }
269
+ extractDocumentation(node, code) {
270
+ if (node.range) {
271
+ const start = node.range[0];
272
+ const precedingCode = code.substring(0, start);
273
+ const jsdocMatch = precedingCode.match(/\/\*\*([\s\S]*?)\*\/\s*$/);
274
+ if (jsdocMatch) {
275
+ return {
276
+ content: jsdocMatch[1].trim(),
277
+ type: "jsdoc"
278
+ };
279
+ }
280
+ }
281
+ return void 0;
282
+ }
283
+ isLikelyPure(node) {
284
+ const sn = node.type === "ExportNamedDeclaration" && node.declaration ? node.declaration : node.type === "ExportDefaultDeclaration" ? node.declaration : node;
285
+ if (!sn) return false;
286
+ if (sn.type === "VariableDeclaration" && sn.kind === "const") return true;
287
+ if (sn.type === "FunctionDeclaration" || sn.type === "MethodDefinition") {
288
+ const body = sn.type === "MethodDefinition" ? sn.value.body : sn.body;
289
+ if (body && body.type === "BlockStatement") {
290
+ const bodyContent = JSON.stringify(body);
291
+ if (bodyContent.includes('"name":"console"') || bodyContent.includes('"name":"process"') || bodyContent.includes('"name":"fs"') || bodyContent.includes('"name":"fetch"') || bodyContent.includes('"name":"axios"')) {
292
+ return false;
293
+ }
294
+ return true;
295
+ }
296
+ return true;
297
+ }
298
+ return false;
299
+ }
300
+ };
301
+
302
+ export {
303
+ TypeScriptParser
304
+ };
package/dist/index.js CHANGED
@@ -362,7 +362,7 @@ var init_typescript_parser = __esm({
362
362
  const body = sn.type === "MethodDefinition" ? sn.value.body : sn.body;
363
363
  if (body && body.type === "BlockStatement") {
364
364
  const bodyContent = JSON.stringify(body);
365
- if (bodyContent.includes('"name":"console"') || bodyContent.includes('"name":"process"') || bodyContent.includes('"type":"AssignmentExpression"')) {
365
+ if (bodyContent.includes('"name":"console"') || bodyContent.includes('"name":"process"') || bodyContent.includes('"name":"fs"') || bodyContent.includes('"name":"fetch"') || bodyContent.includes('"name":"axios"')) {
366
366
  return false;
367
367
  }
368
368
  return true;
@@ -4834,7 +4834,7 @@ function inferPatternType(keyword, name) {
4834
4834
  if (n.includes("validate") || n.includes("schema")) return "validator";
4835
4835
  if (n.includes("util") || n.includes("helper")) return "utility";
4836
4836
  if (keyword === "class") return "class-method";
4837
- if (n.match(/^[A-Z]/)) return "component";
4837
+ if (name.match(/^[A-Z]/)) return "component";
4838
4838
  if (keyword === "function" || keyword === "def") return "function";
4839
4839
  return "unknown";
4840
4840
  }
@@ -4900,7 +4900,14 @@ function extractCodeBlocks(file, content) {
4900
4900
  patternType: inferPatternType(type, name)
4901
4901
  });
4902
4902
  }
4903
- return blocks;
4903
+ return blocks.filter((block) => {
4904
+ const code = block.code.trim();
4905
+ if (/^export\s+\{[^}]+\}\s*(from\s+['"][^'"]+['"])?\s*;?\s*$/.test(code))
4906
+ return false;
4907
+ if (/^export\s+\*\s+from\s+/.test(code)) return false;
4908
+ if (/^export\s+\*\s+as\s+\w+\s+from\s+/.test(code)) return false;
4909
+ return true;
4910
+ });
4904
4911
  }
4905
4912
  function extractBlocksPython(file, content) {
4906
4913
  const blocks = [];
@@ -6332,7 +6339,15 @@ function calculateChangeAmplification(params) {
6332
6339
  recommendations: []
6333
6340
  };
6334
6341
  }
6335
- const hotspots = files.map((f) => ({ ...f, amplificationFactor: f.fanOut + f.fanIn * 0.5 })).sort((a, b) => b.amplificationFactor - a.amplificationFactor);
6342
+ const hotspots = files.map((f) => {
6343
+ const lowerFile = f.file.toLowerCase();
6344
+ const isSharedInfra = lowerFile.endsWith("logger.ts") || lowerFile.endsWith("logger.js") || lowerFile.endsWith("constants.ts") || lowerFile.endsWith("constants.js") || lowerFile.endsWith("types.ts") || lowerFile.endsWith("types.js") || lowerFile.endsWith("index.ts") || lowerFile.endsWith("index.js");
6345
+ const fanInWeight = isSharedInfra ? 0.1 : 0.5;
6346
+ return {
6347
+ ...f,
6348
+ amplificationFactor: f.fanOut + f.fanIn * fanInWeight
6349
+ };
6350
+ }).sort((a, b) => b.amplificationFactor - a.amplificationFactor);
6336
6351
  const maxAmplification = hotspots[0].amplificationFactor;
6337
6352
  const avgAmplification = hotspots.reduce((sum, h) => sum + h.amplificationFactor, 0) / hotspots.length;
6338
6353
  const avgPenalty = Math.log2(avgAmplification + 1) * 15;
package/dist/index.mjs CHANGED
@@ -55,7 +55,7 @@ import {
55
55
  } from "./chunk-LRM26BOB.mjs";
56
56
  import {
57
57
  TypeScriptParser
58
- } from "./chunk-5IVDH26E.mjs";
58
+ } from "./chunk-OT6FOHL4.mjs";
59
59
  import {
60
60
  PythonParser
61
61
  } from "./chunk-QY5YG2AZ.mjs";
@@ -922,11 +922,11 @@ var ParserFactory = class _ParserFactory {
922
922
  Object.entries(LANGUAGE_EXTENSIONS).map(([ext, lang]) => [ext, lang])
923
923
  );
924
924
  this.registerLazyParser("typescript" /* TypeScript */, async () => {
925
- const { TypeScriptParser: TypeScriptParser2 } = await import("./typescript-parser-4BA4VYAF.mjs");
925
+ const { TypeScriptParser: TypeScriptParser2 } = await import("./typescript-parser-RMNCTHRD.mjs");
926
926
  return new TypeScriptParser2();
927
927
  });
928
928
  this.registerLazyParser("javascript" /* JavaScript */, async () => {
929
- const { TypeScriptParser: TypeScriptParser2 } = await import("./typescript-parser-4BA4VYAF.mjs");
929
+ const { TypeScriptParser: TypeScriptParser2 } = await import("./typescript-parser-RMNCTHRD.mjs");
930
930
  return new TypeScriptParser2();
931
931
  });
932
932
  this.registerLazyParser("python" /* Python */, async () => {
@@ -1865,7 +1865,7 @@ function inferPatternType(keyword, name) {
1865
1865
  if (n.includes("validate") || n.includes("schema")) return "validator";
1866
1866
  if (n.includes("util") || n.includes("helper")) return "utility";
1867
1867
  if (keyword === "class") return "class-method";
1868
- if (n.match(/^[A-Z]/)) return "component";
1868
+ if (name.match(/^[A-Z]/)) return "component";
1869
1869
  if (keyword === "function" || keyword === "def") return "function";
1870
1870
  return "unknown";
1871
1871
  }
@@ -1931,7 +1931,14 @@ function extractCodeBlocks(file, content) {
1931
1931
  patternType: inferPatternType(type, name)
1932
1932
  });
1933
1933
  }
1934
- return blocks;
1934
+ return blocks.filter((block) => {
1935
+ const code = block.code.trim();
1936
+ if (/^export\s+\{[^}]+\}\s*(from\s+['"][^'"]+['"])?\s*;?\s*$/.test(code))
1937
+ return false;
1938
+ if (/^export\s+\*\s+from\s+/.test(code)) return false;
1939
+ if (/^export\s+\*\s+as\s+\w+\s+from\s+/.test(code)) return false;
1940
+ return true;
1941
+ });
1935
1942
  }
1936
1943
  function extractBlocksPython(file, content) {
1937
1944
  const blocks = [];
@@ -3355,7 +3362,15 @@ function calculateChangeAmplification(params) {
3355
3362
  recommendations: []
3356
3363
  };
3357
3364
  }
3358
- const hotspots = files.map((f) => ({ ...f, amplificationFactor: f.fanOut + f.fanIn * 0.5 })).sort((a, b) => b.amplificationFactor - a.amplificationFactor);
3365
+ const hotspots = files.map((f) => {
3366
+ const lowerFile = f.file.toLowerCase();
3367
+ const isSharedInfra = lowerFile.endsWith("logger.ts") || lowerFile.endsWith("logger.js") || lowerFile.endsWith("constants.ts") || lowerFile.endsWith("constants.js") || lowerFile.endsWith("types.ts") || lowerFile.endsWith("types.js") || lowerFile.endsWith("index.ts") || lowerFile.endsWith("index.js");
3368
+ const fanInWeight = isSharedInfra ? 0.1 : 0.5;
3369
+ return {
3370
+ ...f,
3371
+ amplificationFactor: f.fanOut + f.fanIn * fanInWeight
3372
+ };
3373
+ }).sort((a, b) => b.amplificationFactor - a.amplificationFactor);
3359
3374
  const maxAmplification = hotspots[0].amplificationFactor;
3360
3375
  const avgAmplification = hotspots.reduce((sum, h) => sum + h.amplificationFactor, 0) / hotspots.length;
3361
3376
  const avgPenalty = Math.log2(avgAmplification + 1) * 15;
@@ -0,0 +1,7 @@
1
+ import {
2
+ TypeScriptParser
3
+ } from "./chunk-OT6FOHL4.mjs";
4
+ import "./chunk-U3IY2CFC.mjs";
5
+ export {
6
+ TypeScriptParser
7
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiready/core",
3
- "version": "0.24.13",
3
+ "version": "0.24.15",
4
4
  "description": "Shared utilities for AIReady analysis tools",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",