@arcteninc/core 0.0.23 → 0.0.25

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcteninc/core",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",
@@ -20,11 +20,12 @@
20
20
  },
21
21
  "sideEffects": false,
22
22
  "bin": {
23
- "arcten-extract-types": "./scripts/cli-extract-types-auto.ts"
23
+ "arcten-extract-types": "./scripts/cli-extract-types-auto.js"
24
24
  },
25
25
  "files": [
26
26
  "dist",
27
- "scripts/cli-extract-types-auto.ts"
27
+ "scripts/cli-extract-types-auto.ts",
28
+ "scripts/cli-extract-types-auto.js"
28
29
  ],
29
30
  "scripts": {
30
31
  "dev": "vite build --watch",
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Wrapper script to run the TypeScript CLI with bun
4
+ * Works with both npm and bun
5
+ */
6
+
7
+ import { spawn } from 'child_process';
8
+ import { fileURLToPath } from 'url';
9
+ import { dirname, join, resolve } from 'path';
10
+ import { existsSync } from 'fs';
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = dirname(__filename);
14
+
15
+ // Path to the TypeScript script - resolve relative to this wrapper
16
+ const tsScript = resolve(__dirname, 'cli-extract-types-auto.ts');
17
+
18
+ // Check if bun is available
19
+ function checkBun() {
20
+ return new Promise((resolve) => {
21
+ const bunCheck = spawn('bun', ['--version'], { stdio: 'ignore' });
22
+ bunCheck.on('close', (code) => {
23
+ resolve(code === 0);
24
+ });
25
+ bunCheck.on('error', () => {
26
+ resolve(false);
27
+ });
28
+ });
29
+ }
30
+
31
+ async function main() {
32
+ const hasBun = await checkBun();
33
+
34
+ if (!hasBun) {
35
+ console.error('❌ Error: bun is required to run arcten-extract-types');
36
+ console.error('');
37
+ console.error('Please install bun:');
38
+ console.error(' curl -fsSL https://bun.sh/install | bash');
39
+ console.error('');
40
+ console.error('Or use bunx instead of npx:');
41
+ console.error(' bunx arcten-extract-types .');
42
+ process.exit(1);
43
+ }
44
+
45
+ if (!existsSync(tsScript)) {
46
+ console.error(`❌ Error: Script not found at ${tsScript}`);
47
+ process.exit(1);
48
+ }
49
+
50
+ // Run the TypeScript script with bun
51
+ const args = process.argv.slice(2);
52
+ const bunProcess = spawn('bun', [tsScript, ...args], {
53
+ stdio: 'inherit',
54
+ shell: true
55
+ });
56
+
57
+ bunProcess.on('close', (code) => {
58
+ process.exit(code || 0);
59
+ });
60
+
61
+ bunProcess.on('error', (err) => {
62
+ console.error('❌ Error running script:', err.message);
63
+ process.exit(1);
64
+ });
65
+ }
66
+
67
+ main();
68
+
@@ -78,11 +78,25 @@ function extractToolNamesFromExpression(
78
78
  if (ts.isSpreadElement(element)) {
79
79
  // Handle spread: [...someArray]
80
80
  extractFromExpr(element.expression);
81
+ } else if (ts.isArrowFunction(element) || ts.isFunctionExpression(element)) {
82
+ // Skip anonymous functions - they don't have names to extract
83
+ // Example: tools: [function getStatus() { ... }] - this should have a name
84
+ if (ts.isFunctionExpression(element) && element.name) {
85
+ toolNames.add(element.name.getText(sourceFile));
86
+ }
87
+ // For arrow functions without names, skip them
81
88
  } else {
82
89
  const name = element.getText(sourceFile).trim();
83
90
  // Remove any object property access (e.g., tools.getOrders -> getOrders)
84
91
  const simpleName = name.split('.').pop() || name;
85
- if (simpleName && simpleName !== 'undefined' && simpleName !== 'null') {
92
+ // Skip if it looks like code (contains operators, semicolons, etc.)
93
+ if (simpleName &&
94
+ simpleName !== 'undefined' &&
95
+ simpleName !== 'null' &&
96
+ !simpleName.includes('?') &&
97
+ !simpleName.includes(';') &&
98
+ !simpleName.includes('=>') &&
99
+ simpleName.length < 100) {
86
100
  toolNames.add(simpleName);
87
101
  }
88
102
  }
@@ -90,12 +104,18 @@ function extractToolNamesFromExpression(
90
104
  return;
91
105
  }
92
106
 
93
- // Variable reference: toolsList
107
+ // Variable reference: toolsList or function name: generateReport
94
108
  if (ts.isIdentifier(node)) {
95
109
  const varName = node.getText(sourceFile);
96
110
  const varExpr = variableMap.get(varName);
97
111
  if (varExpr) {
98
112
  extractFromExpr(varExpr);
113
+ } else {
114
+ // If not in variableMap, it might be a function declaration name
115
+ // Add it directly as a tool name (findFunctionDefinition will find it later)
116
+ if (varName && varName !== 'undefined' && varName !== 'null') {
117
+ toolNames.add(varName);
118
+ }
99
119
  }
100
120
  return;
101
121
  }
@@ -275,16 +295,38 @@ function findFunctionDefinition(
275
295
  functionName: string,
276
296
  sourceFile: ts.SourceFile,
277
297
  program: ts.Program
278
- ): { sourceFile: ts.SourceFile; node: ts.FunctionDeclaration } | null {
298
+ ): { sourceFile: ts.SourceFile; node: ts.FunctionDeclaration | ts.VariableDeclaration } | null {
279
299
  // First, check if it's defined in the current file
280
- let foundNode: ts.FunctionDeclaration | null = null;
300
+ let foundNode: ts.FunctionDeclaration | ts.VariableDeclaration | null = null;
281
301
 
282
302
  function visitForDefinition(node: ts.Node) {
303
+ // Function declaration: function generateReport() {}
283
304
  if (ts.isFunctionDeclaration(node) && node.name) {
284
305
  if (node.name.getText(sourceFile) === functionName) {
285
306
  foundNode = node;
286
307
  }
287
308
  }
309
+
310
+ // Variable declaration with arrow function: const addFilter = async () => {}
311
+ // or function expression: const addFilter = async function() {}
312
+ if (ts.isVariableStatement(node)) {
313
+ for (const declaration of node.declarationList.declarations) {
314
+ if (ts.isIdentifier(declaration.name)) {
315
+ const varName = declaration.name.getText(sourceFile);
316
+ if (varName === functionName && declaration.initializer) {
317
+ // Check if it's an arrow function or function expression
318
+ if (
319
+ ts.isArrowFunction(declaration.initializer) ||
320
+ ts.isFunctionExpression(declaration.initializer)
321
+ ) {
322
+ foundNode = declaration;
323
+ break;
324
+ }
325
+ }
326
+ }
327
+ }
328
+ }
329
+
288
330
  if (!foundNode) {
289
331
  ts.forEachChild(node, visitForDefinition);
290
332
  }
@@ -301,9 +343,9 @@ function findFunctionDefinition(
301
343
 
302
344
  function visitForImports(node: ts.Node) {
303
345
  if (ts.isImportDeclaration(node)) {
304
- const moduleSpecifier = node.moduleClause;
305
- if (moduleSpecifier && ts.isImportClause(moduleSpecifier)) {
306
- const namedBindings = moduleSpecifier.namedBindings;
346
+ const importClause = node.importClause;
347
+ if (importClause) {
348
+ const namedBindings = importClause.namedBindings;
307
349
  if (namedBindings && ts.isNamedImports(namedBindings)) {
308
350
  for (const element of namedBindings.elements) {
309
351
  const importedName = element.name.getText(sourceFile);
@@ -502,16 +544,46 @@ function serializeType(
502
544
  * Extract metadata from a function
503
545
  */
504
546
  function extractFunctionMetadata(
505
- node: ts.FunctionDeclaration,
547
+ node: ts.FunctionDeclaration | ts.VariableDeclaration,
506
548
  checker: ts.TypeChecker,
507
549
  sourceFile: ts.SourceFile
508
550
  ): FunctionMetadata | null {
509
- if (!node.name) {
551
+ let functionNode: ts.FunctionDeclaration | ts.ArrowFunction | ts.FunctionExpression | null = null;
552
+ let functionName: string;
553
+
554
+ // Handle FunctionDeclaration: function generateReport() {}
555
+ if (ts.isFunctionDeclaration(node)) {
556
+ if (!node.name) {
557
+ return null;
558
+ }
559
+ functionNode = node;
560
+ functionName = node.name.getText(sourceFile);
561
+ }
562
+ // Handle VariableDeclaration: const addFilter = async () => {}
563
+ else if (ts.isVariableDeclaration(node)) {
564
+ if (!ts.isIdentifier(node.name)) {
565
+ return null;
566
+ }
567
+ functionName = node.name.getText(sourceFile);
568
+
569
+ if (node.initializer) {
570
+ if (ts.isArrowFunction(node.initializer) || ts.isFunctionExpression(node.initializer)) {
571
+ functionNode = node.initializer;
572
+ } else {
573
+ return null;
574
+ }
575
+ } else {
576
+ return null;
577
+ }
578
+ } else {
510
579
  return null;
511
580
  }
512
581
 
513
- const functionName = node.name.getText(sourceFile);
582
+ if (!functionNode) {
583
+ return null;
584
+ }
514
585
 
586
+ // Extract JSDoc comments
515
587
  const jsDocTags = ts.getJSDocTags(node);
516
588
  const jsDocComments = ts.getJSDocCommentsAndTags(node);
517
589
 
@@ -538,9 +610,24 @@ function extractFunctionMetadata(
538
610
 
539
611
  const properties: Record<string, JsonSchemaProperty> = {};
540
612
  const required: string[] = [];
541
- const isAsync = node.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) || false;
542
-
543
- for (const param of node.parameters) {
613
+
614
+ // Check if async - works for both function declarations and arrow functions
615
+ const isAsync =
616
+ (ts.isFunctionDeclaration(node) && node.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword)) ||
617
+ (ts.isVariableDeclaration(node) && node.initializer && ts.isArrowFunction(node.initializer) &&
618
+ (node.initializer.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) || false)) ||
619
+ (ts.isVariableDeclaration(node) && node.initializer && ts.isFunctionExpression(node.initializer) &&
620
+ (node.initializer.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) || false)) ||
621
+ false;
622
+
623
+ // Extract parameters from the function node
624
+ const parameters = ts.isFunctionDeclaration(node)
625
+ ? node.parameters
626
+ : (ts.isArrowFunction(functionNode) || ts.isFunctionExpression(functionNode))
627
+ ? functionNode.parameters
628
+ : [];
629
+
630
+ for (const param of parameters) {
544
631
  const paramName = param.name.getText(sourceFile);
545
632
  const hasDefault = param.initializer !== undefined;
546
633
 
@@ -581,8 +668,16 @@ function extractFunctionMetadata(
581
668
  }
582
669
 
583
670
  let returnType = 'any';
584
- if (node.type) {
671
+ if (ts.isFunctionDeclaration(node) && node.type) {
585
672
  returnType = node.type.getText(sourceFile);
673
+ } else if (
674
+ ts.isVariableDeclaration(node) &&
675
+ node.initializer &&
676
+ (ts.isArrowFunction(node.initializer) || ts.isFunctionExpression(node.initializer))
677
+ ) {
678
+ if (node.initializer.type) {
679
+ returnType = node.initializer.type.getText(sourceFile);
680
+ }
586
681
  }
587
682
 
588
683
  return {