(sourceFile)
| 79 | } |
| 80 | |
| 81 | function extractFunction(sourceFile) { |
| 82 | const functionParts = []; |
| 83 | |
| 84 | ts.forEachChild(sourceFile, node => { |
| 85 | if ( |
| 86 | ts.isExportAssignment(node) && |
| 87 | node.expression && |
| 88 | ts.isObjectLiteralExpression(node.expression) |
| 89 | ) { |
| 90 | const objectLiteral = node.expression; |
| 91 | objectLiteral.properties.forEach(prop => { |
| 92 | if (prop.name) { |
| 93 | const part = []; |
| 94 | const functionName = prop.name.text; |
| 95 | const chibiParamIndices = []; |
| 96 | |
| 97 | const functionCode = prop.getText(); |
| 98 | if (functionCode.includes('ctx.run(') && !functionCode.includes('ctx.runAsync(')) { |
| 99 | throw new Error(`Function ${functionName} contains ctx.run() but not ctx.runAsync()`); |
| 100 | } |
| 101 | |
| 102 | const args = prop.parameters || prop.initializer?.parameters || []; |
| 103 | const argsString = args.map((param, index) => { |
| 104 | const paramName = param.name.text || (param.dotDotDotToken ? '...args' : 'param'); |
| 105 | const optional = param.questionToken || param.initializer ? '?' : ''; |
| 106 | const type = param.type?.getText() || 'any'; |
| 107 | const dotDotDot = param.dotDotDotToken ? '...' : ''; |
| 108 | if (type.startsWith('ChibiParam<')) { |
| 109 | chibiParamIndices.push(index); |
| 110 | } |
| 111 | return `${dotDotDot}${paramName}${optional}: ${type}`; |
| 112 | }); |
| 113 | |
| 114 | if (chibiParamIndices.length) { |
| 115 | parameterMatrix[functionName] = chibiParamIndices; |
| 116 | } |
| 117 | |
| 118 | const jsDocs = prop.jsDoc ? prop.jsDoc.map(doc => ` ${doc.getText()}`) : []; |
| 119 | |
| 120 | const returnTypeNames = |
| 121 | prop.type?.getText() || |
| 122 | prop.initializer?.type?.getText() || |
| 123 | `ReturnType<typeof functionsRegistry.${functionName}>`; |
| 124 | |
| 125 | const typeParameters = prop.typeParameters || prop.initializer?.typeParameters; |
| 126 | const typeParametersString = typeParameters |
| 127 | ? typeParameters |
| 128 | .filter(param => !param.name || param.name.text !== 'Input') |
| 129 | .map(param => param.getText()) |
| 130 | .join(', ') |
| 131 | : ''; |
| 132 | |
| 133 | console.log(`Function Name: ${functionName}`); |
| 134 | |
| 135 | part.push( |
| 136 | `${jsDocs.join('\n').replace('*/', `* @see {@link functionsRegistry.${functionName}} for implementation details\n */`)}`, |
| 137 | ); |
| 138 |
no outgoing calls
no test coverage detected