UNPKG

@nexica/nestjs-trpc

Version:
261 lines 12.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FileScanner = void 0; const fs = require("fs"); const path = require("path"); const glob = require("glob"); const ts_morph_1 = require("ts-morph"); const error_handler_1 = require("./error-handler"); class FileScanner { static findFiles(directory, pattern) { return glob.sync(pattern, { cwd: directory, absolute: true }); } static findTypeScriptFiles(directory) { return this.findFiles(directory, '**/*.{ts,tsx}'); } static findTsConfigFile(directory) { let currentDir = directory; while (currentDir !== path.parse(currentDir).root) { const tsConfigPath = path.join(currentDir, 'tsconfig.json'); if (fs.existsSync(tsConfigPath)) { return tsConfigPath; } currentDir = path.dirname(currentDir); } return null; } static getCallerFilePath() { var _a, _b; const originalStackPrepareStackTrace = (_a = Error.prepareStackTrace) === null || _a === void 0 ? void 0 : _a.bind(Error); Error.prepareStackTrace = (_, stack) => stack; const stack = new Error().stack; Error.prepareStackTrace = originalStackPrepareStackTrace; const callerFile = ((_b = stack[2]) === null || _b === void 0 ? void 0 : _b.getFileName()) || ''; return callerFile; } static findProjectRoot(startDir = process.cwd()) { let dir = startDir; const maxIterations = 10; let iterations = 0; while (dir !== path.parse(dir).root && iterations < maxIterations) { if (fs.existsSync(path.join(dir, 'package.json')) || fs.existsSync(path.join(dir, 'tsconfig.json'))) { return dir; } const parentDir = path.dirname(dir); if (parentDir === dir) { break; } dir = parentDir; iterations++; } error_handler_1.ErrorHandler.logWarning('FileScanner', `Could not find project root, using ${startDir} as fallback`); return startDir; } static getTsEquivalentPath(filePath) { return filePath.replace('\\dist\\', '\\src\\').replace('.js', '.ts'); } static getInputAndOutputNamesFromDecorator(filePath, methodName) { var _a, _b, _c; const tsPath = this.getTsEquivalentPath(filePath); if (!fs.existsSync(tsPath)) { return { input: undefined, output: undefined }; } const project = new ts_morph_1.Project({ compilerOptions: { target: ts_morph_1.ts.ScriptTarget.ES2019, module: ts_morph_1.ts.ModuleKind.CommonJS, emitDecoratorMetadata: true, experimentalDecorators: true, }, }); const sourceFile = project.addSourceFileAtPath(tsPath); const classes = sourceFile.getClasses(); for (const classDeclaration of classes) { const method = classDeclaration.getMethod(methodName); if (!method) continue; let queryDecorator = method.getDecorator('Query'); if (!queryDecorator) queryDecorator = method.getDecorator('Mutation'); if (!queryDecorator) continue; const args = queryDecorator.getArguments(); if (args.length === 0) continue; const objLiteral = args[0]; if (!objLiteral || !objLiteral.asKind(ts_morph_1.ts.SyntaxKind.ObjectLiteralExpression)) continue; const properties = (_a = objLiteral.asKind(ts_morph_1.ts.SyntaxKind.ObjectLiteralExpression)) === null || _a === void 0 ? void 0 : _a.getProperties(); if (!properties) continue; let inputName; let outputName; for (const prop of properties) { const propName = (_b = prop.getChildrenOfKind(ts_morph_1.ts.SyntaxKind.Identifier)[0]) === null || _b === void 0 ? void 0 : _b.getText(); if (propName === 'input') { inputName = (_c = prop.getChildrenOfKind(ts_morph_1.ts.SyntaxKind.Identifier)[1]) === null || _c === void 0 ? void 0 : _c.getText(); } else if (propName === 'output') { const initializer = prop.getLastChild(); outputName = initializer === null || initializer === void 0 ? void 0 : initializer.getText(); } } return { input: inputName, output: outputName }; } return { input: undefined, output: undefined }; } static resolvePathWithAliases(filePath, pathAliases, tsConfigDir, moduleCallerFilePath) { if (path.isAbsolute(filePath) || filePath.startsWith('./') || filePath.startsWith('../')) { const resolvedPath = path.resolve(tsConfigDir, filePath); return resolvedPath; } if (filePath.startsWith('@/')) { for (const [alias, targets] of Object.entries(pathAliases)) { if ((alias === '@/*' || alias === '@*') && targets.length > 0) { const target = targets[0].replace(/\*/g, ''); const modulePath = filePath.replace('@/', ''); const resolvedPath = path.resolve(tsConfigDir, target, modulePath); if (fs.existsSync(resolvedPath)) { return resolvedPath; } } } if (moduleCallerFilePath) { const commonSourceFolders = [ moduleCallerFilePath, path.join(moduleCallerFilePath, 'src'), path.join(moduleCallerFilePath, 'app'), path.join(moduleCallerFilePath, 'lib'), ]; for (const srcFolder of commonSourceFolders) { if (fs.existsSync(srcFolder)) { const modulePath = filePath.replace('@/', ''); const resolvedPath = path.resolve(srcFolder, modulePath); if (fs.existsSync(resolvedPath)) { return resolvedPath; } } } } } for (const [alias, targets] of Object.entries(pathAliases)) { const aliasPattern = alias.replace(/\*/g, '(.+)'); const aliasRegex = new RegExp(`^${aliasPattern}$`); if (aliasRegex.test(filePath)) { if (targets.length > 0) { const target = targets[0]; const processed = filePath.replace(aliasRegex, (_, capture) => { return target.replace(/\*/g, capture); }); const resolvedPath = path.resolve(tsConfigDir, processed); return resolvedPath; } } } if (!filePath.includes('/') && !filePath.includes('\\')) { try { const resolvedPath = require.resolve(filePath, { paths: [process.cwd(), tsConfigDir] }); return resolvedPath; } catch (e) { error_handler_1.ErrorHandler.logWarning('FileScanner', `Could not resolve module: ${filePath}`); } } if (filePath.endsWith('.ts') || filePath.endsWith('.js')) { const projectRootPath = path.resolve(process.cwd(), filePath); if (fs.existsSync(projectRootPath)) { return projectRootPath; } const tsConfigRelativePath = path.resolve(tsConfigDir, filePath); if (fs.existsSync(tsConfigRelativePath)) { return tsConfigRelativePath; } const srcPath = path.resolve(process.cwd(), 'src', filePath); if (fs.existsSync(srcPath)) { return srcPath; } } error_handler_1.ErrorHandler.logWarning('FileScanner', `Could not resolve path with aliases, returning as is: ${filePath}`); return filePath; } static injectFilesContent(filePaths, sourceFile, moduleCallerFilePath) { var _a; try { const tsConfigFilePath = FileScanner.findTsConfigFile(moduleCallerFilePath); if (tsConfigFilePath) { const tsConfigContent = fs.readFileSync(tsConfigFilePath, 'utf8'); try { const tsConfigObj = JSON.parse(tsConfigContent); const pathAliases = ((_a = tsConfigObj.compilerOptions) === null || _a === void 0 ? void 0 : _a.paths) || {}; const tsConfigDir = path.dirname(tsConfigFilePath); const expandedFilePaths = []; for (const filePath of filePaths) { let resolvedBasePath = moduleCallerFilePath; let effectivePattern = filePath; if (filePath.startsWith('@/')) { let aliasBaseResolved = false; for (const [alias, targets] of Object.entries(pathAliases)) { if ((alias === '@/*' || alias === '@*') && targets.length > 0) { const target = targets[0].replace(/\*/g, ''); resolvedBasePath = path.resolve(tsConfigDir, target); effectivePattern = filePath.replace('@/', ''); aliasBaseResolved = true; break; } } if (!aliasBaseResolved) { error_handler_1.ErrorHandler.logWarning('FileScanner', `Could not resolve base path for alias pattern: ${filePath}`); continue; } } const isGlob = filePath.includes('*') || filePath.includes('?') || filePath.includes('['); if (isGlob) { try { const globMatches = glob.sync(effectivePattern, { cwd: resolvedBasePath, absolute: true, }); const filteredMatches = globMatches.filter((match) => match.endsWith('.ts') || match.endsWith('.js')); expandedFilePaths.push(...filteredMatches); } catch (error) { error_handler_1.ErrorHandler.logWarning('FileScanner', `Error expanding glob pattern ${filePath}`, error); } } else { const resolvedPath = this.resolvePathWithAliases(filePath, pathAliases, tsConfigDir, moduleCallerFilePath); if (resolvedPath) { expandedFilePaths.push(resolvedPath); } } } for (const resolvedPath of expandedFilePaths) { if (fs.existsSync(resolvedPath)) { try { const content = fs.readFileSync(resolvedPath, 'utf8'); sourceFile.addStatements(content); } catch (error) { error_handler_1.ErrorHandler.logWarning('FileScanner', `Error injecting file ${resolvedPath}`, error); } } else { error_handler_1.ErrorHandler.logWarning('FileScanner', `Could not resolve path for ${resolvedPath} or file doesn't exist`); } } } catch (parseError) { error_handler_1.ErrorHandler.logWarning('FileScanner', `Error parsing tsconfig.json`, parseError); } } else { error_handler_1.ErrorHandler.logWarning('FileScanner', 'Could not find tsconfig.json file'); } } catch (error) { error_handler_1.ErrorHandler.logWarning('FileScanner', `Error injecting files`, error); } } } exports.FileScanner = FileScanner; //# sourceMappingURL=file-scanner.js.map