moonflower 1.4.7 → 1.4.8

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.
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const q=require("path"),h=require("ts-morph"),u=require("../../utils/logger.cjs"),S=require("../discoveryModule/discoverImports/discoverImports.cjs"),k=require("../discoveryModule/discoverRouterFiles/discoverRouterFiles.cjs"),K=require("../discoveryModule/discoverRouters/discoverRouters.cjs"),H=require("../manager/OpenApiManager.cjs"),I=require("./getSourceFileTimestamp.cjs"),M=require("./nodeParsers.cjs"),U=require("./parseEndpoint.cjs"),E=require("./parseExposedModels.cjs"),N=require("./sourceFileCache.cjs");function W(e){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const a in e)if(a!=="default"){const c=Object.getOwnPropertyDescriptor(e,a);Object.defineProperty(r,a,c.get?c:{enumerable:!0,get:()=>e[a]})}}return r.default=e,Object.freeze(r)}const x=W(q),_=({logLevel:e,tsconfigPath:r,sourceFilePaths:a,sourceFileDiscovery:c,incremental:s})=>{const t=H.OpenApiManager.getInstance();if(t.isReady())return;e&&u.Logger.setLevel(e),u.Logger.info("Preparing OpenAPI spec");const o=new h.Project({tsConfigFilePath:x.resolve(r),skipFileDependencyResolution:!0}),{explicitRouters:n,discoveredRouterFiles:p,allSourceFiles:f}=(()=>{const l=(a??[]).map(d=>x.resolve(d)).map(d=>o.getSourceFileOrThrow(d)),z=l.flatMap(d=>({fileName:d.getFilePath(),sourceFile:d,routers:K.discoverRouters(d)})),{discoveredRouterFiles:L,discoveredSourceFiles:j}=(()=>{if(c===!1)return{discoveredRouterFiles:[],discoveredSourceFiles:[]};const d=performance.now(),g=k.discoverRouterFiles({targetPath:typeof c=="object"?c.rootPath:".",tsConfigPath:r});return u.Logger.info(`File discovery took ${Math.round(performance.now()-d)}ms`),g})(),$=l.reduce((d,g)=>d.some(w=>w.getFilePath()===g.getFilePath())?d:d.concat(g),j);return{explicitRouters:z,discoveredRouterFiles:L,allSourceFiles:$}})(),T=n.reduce((i,m)=>i.some(l=>l.fileName===m.fileName)?i:i.concat(m),p),F=f.flatMap(i=>O(i)).filter(i=>!!i);F.length>0&&F[0]&&t.setHeader(F[0]);const v=f.flatMap(i=>R(i));t.setExposedModels(v);const b=typeof s=="object"&&s.cachePath?s.cachePath:x.resolve(process.cwd(),"node_modules",".cache","moonflower"),y=P(T,{cachePath:b,timestampCache:{}});t.setStats({discoveredRouterFiles:p.map(i=>({path:i.fileName,routers:i.routers.named.map(m=>({name:m,endpoints:y.filter(l=>l.sourceFilePath===i.fileName).map(l=>`${l.method.toUpperCase()} ${l.path}`)}))})),explicitRouterFiles:n.map(i=>({path:i.fileName,routers:i.routers.named.map(m=>({name:m,endpoints:y.filter(l=>l.sourceFilePath===i.fileName).map(l=>`${l.method.toUpperCase()} ${l.path}`)}))}))}),t.setEndpoints(y),t.markAsReady()},P=(e,r,a)=>{const c=performance.now(),s=e.map(t=>C(t,r));return u.Logger.info(`Router analysis took ${Math.round(performance.now()-c)}ms`),s.map((t,o)=>({fileName:e[o].fileName,timeTaken:t.timing})).sort((t,o)=>o.timeTaken-t.timeTaken).filter(t=>t.timeTaken>500).forEach(t=>{u.Logger.info(`- [${t.fileName}] Took ${Math.round(t.timeTaken)}ms to analyze`)}),s.flatMap(t=>t.endpoints)},C=(e,r,a)=>{const c=I.getSourceFileTimestamp(e.sourceFile,r.timestampCache),s=N.SourceFileCache.getCachedResults(e.sourceFile,c,r.cachePath);if(s)return u.Logger.debug(`[${e.fileName}] Found cached results`),{endpoints:s.endpoints,timing:0};u.Logger.debug(`[${e.fileName}] Analyzing...`);const t=performance.now(),o=A(e),n=performance.now();return u.Logger.debug(`[${e.fileName}] Analyzed in ${n-t}ms`),N.SourceFileCache.cacheResults(e.sourceFile,c,r.cachePath,o),{endpoints:o,timing:n-t}},A=(e,r)=>{const a=[],s=["get","post","put","delete","del","patch"].join("|");return e.routers.named.forEach(t=>{e.sourceFile.forEachChild(o=>{const n=o.getText();new RegExp(`${t}\\.(?:${s})`).test(n)&&(M.resolveEndpointPath(o),a.push(U.parseEndpoint(o,e.fileName)))})}),a},O=e=>{const r=S.discoverImportedName({sourceFile:e,originalName:"useApiHeader"});if(!r)return null;const a=e.forEachChildAsArray().filter(o=>o.isKind(h.SyntaxKind.ExpressionStatement)).find(o=>r&&o.getText().startsWith(r));if(!a)return null;const c=a.getFirstDescendantByKindOrThrow(h.SyntaxKind.ObjectLiteralExpression),s=M.getValuesOfObjectLiteral(c),t=o=>typeof o=="string"||Array.isArray(o)&&o.every(n=>typeof n=="string")?o:o.reduce((n,p)=>typeof p=="string"?n:{...n,[p.identifier]:t(p.value)},{});return t(s)},R=e=>{const r=[],a=S.discoverImportedName({sourceFile:e,originalName:"useExposeApiModel"}),c=S.discoverImportedName({sourceFile:e,originalName:"useExposeNamedApiModels"});return e.forEachChildAsArray().filter(s=>s.isKind(h.SyntaxKind.ExpressionStatement)).map(s=>{if(a&&s.getText().startsWith(a)){const n=(s.getFirstChild()?.getChildrenOfKind(h.SyntaxKind.SyntaxList)||[])[0].getFirstChild();if(!n)return;r.push(E.parseExposedModel(n));return}if(c&&s.getText().startsWith(c)){const n=(s.getFirstChild()?.getChildrenOfKind(h.SyntaxKind.SyntaxList)||[])[0].getFirstChild();if(!n)return;E.parseNamedExposedModels(n).forEach(f=>r.push(f))}}),r};exports.analyzeMultipleSourceFiles=P;exports.analyzeSourceFileApiHeader=O;exports.analyzeSourceFileEndpoints=A;exports.analyzeSourceFileExposedModels=R;exports.analyzeSourceFileWithCache=C;exports.prepareOpenApiSpec=_;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const q=require("path"),h=require("ts-morph"),u=require("../../utils/logger.cjs"),S=require("../discoveryModule/discoverImports/discoverImports.cjs"),k=require("../discoveryModule/discoverRouterFiles/discoverRouterFiles.cjs"),K=require("../discoveryModule/discoverRouters/discoverRouters.cjs"),H=require("../manager/OpenApiManager.cjs"),I=require("./getSourceFileTimestamp.cjs"),M=require("./nodeParsers.cjs"),U=require("./parseEndpoint.cjs"),E=require("./parseExposedModels.cjs"),N=require("./sourceFileCache.cjs");function W(e){const r=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const a in e)if(a!=="default"){const c=Object.getOwnPropertyDescriptor(e,a);Object.defineProperty(r,a,c.get?c:{enumerable:!0,get:()=>e[a]})}}return r.default=e,Object.freeze(r)}const x=W(q),_=({logLevel:e,tsconfigPath:r,sourceFilePaths:a,sourceFileDiscovery:c,incremental:s})=>{const t=H.OpenApiManager.getInstance();if(t.isReady())return;e&&u.Logger.setLevel(e),u.Logger.info("Preparing OpenAPI spec");const o=new h.Project({tsConfigFilePath:x.resolve(r),skipFileDependencyResolution:!0}),{explicitRouters:n,discoveredRouterFiles:p,allSourceFiles:f}=(()=>{const l=(a??[]).map(d=>x.resolve(d)).map(d=>o.getSourceFileOrThrow(d)),z=l.flatMap(d=>({fileName:d.getFilePath(),sourceFile:d,routers:K.discoverRouters(d)})),{discoveredRouterFiles:L,discoveredSourceFiles:j}=(()=>{if(c===!1)return{discoveredRouterFiles:[],discoveredSourceFiles:[]};const d=performance.now(),g=k.discoverRouterFiles({targetPath:typeof c=="object"?c.rootPath:".",tsConfigPath:r});return u.Logger.info(`File discovery took ${Math.round(performance.now()-d)}ms`),g})(),$=l.reduce((d,g)=>d.some(w=>w.getFilePath()===g.getFilePath())?d:d.concat(g),j);return{explicitRouters:z,discoveredRouterFiles:L,allSourceFiles:$}})(),T=n.reduce((i,m)=>i.some(l=>l.fileName===m.fileName)?i:i.concat(m),p),F=f.flatMap(i=>O(i)).filter(i=>!!i);F.length>0&&F[0]&&t.setHeader(F[0]);const v=f.flatMap(i=>R(i));t.setExposedModels(v);const b=typeof s=="object"&&s.cachePath?s.cachePath:x.resolve(process.cwd(),"node_modules",".cache","moonflower"),y=C(T,{cachePath:b,timestampCache:{}});t.setStats({discoveredRouterFiles:p.map(i=>({path:i.fileName,routers:i.routers.named.map(m=>({name:m,endpoints:y.filter(l=>l.sourceFilePath===i.fileName).map(l=>`${l.method.toUpperCase()} ${l.path}`)}))})),explicitRouterFiles:n.map(i=>({path:i.fileName,routers:i.routers.named.map(m=>({name:m,endpoints:y.filter(l=>l.sourceFilePath===i.fileName).map(l=>`${l.method.toUpperCase()} ${l.path}`)}))}))}),t.setEndpoints(y),t.markAsReady()},C=(e,r,a)=>{const c=performance.now(),s=e.map(t=>P(t,r));return u.Logger.info(`Router analysis took ${Math.round(performance.now()-c)}ms`),s.map((t,o)=>({fileName:e[o].fileName,timeTaken:t.timing})).sort((t,o)=>o.timeTaken-t.timeTaken).filter(t=>t.timeTaken>500).forEach(t=>{u.Logger.info(`- [${t.fileName}] Took ${Math.round(t.timeTaken)}ms to analyze`)}),s.flatMap(t=>t.endpoints)},P=(e,r,a)=>{const c=I.getSourceFileTimestamp(e.sourceFile,r.timestampCache),s=N.SourceFileCache.getCachedResults(e.sourceFile,c,r.cachePath);if(s)return u.Logger.debug(`[${e.fileName}] Found cached results`),{endpoints:s.endpoints,timing:0};u.Logger.debug(`[${e.fileName}] Analyzing...`);const t=performance.now(),o=A(e),n=performance.now();return u.Logger.debug(`[${e.fileName}] Analyzed in ${n-t}ms`),N.SourceFileCache.cacheResults(e.sourceFile,c,r.cachePath,o),{endpoints:o,timing:n-t}},A=(e,r)=>{const a=[],s=["get","post","put","delete","del","patch"].join("|");return e.routers.named.forEach(t=>{const o=new RegExp(`${t}\\.(?:${s})`);e.sourceFile.forEachChild(n=>{const p=n.getText();o.test(p)&&(M.resolveEndpointPath(n),a.push(U.parseEndpoint(n,e.fileName)))})}),a},O=e=>{const r=S.discoverImportedName({sourceFile:e,originalName:"useApiHeader"});if(!r)return null;const a=e.forEachChildAsArray().filter(o=>o.isKind(h.SyntaxKind.ExpressionStatement)).find(o=>r&&o.getText().startsWith(r));if(!a)return null;const c=a.getFirstDescendantByKindOrThrow(h.SyntaxKind.ObjectLiteralExpression),s=M.getValuesOfObjectLiteral(c),t=o=>typeof o=="string"||Array.isArray(o)&&o.every(n=>typeof n=="string")?o:o.reduce((n,p)=>typeof p=="string"?n:{...n,[p.identifier]:t(p.value)},{});return t(s)},R=e=>{const r=[],a=S.discoverImportedName({sourceFile:e,originalName:"useExposeApiModel"}),c=S.discoverImportedName({sourceFile:e,originalName:"useExposeNamedApiModels"});return e.forEachChildAsArray().filter(s=>s.isKind(h.SyntaxKind.ExpressionStatement)).map(s=>{if(a&&s.getText().startsWith(a)){const n=(s.getFirstChild()?.getChildrenOfKind(h.SyntaxKind.SyntaxList)||[])[0].getFirstChild();if(!n)return;r.push(E.parseExposedModel(n));return}if(c&&s.getText().startsWith(c)){const n=(s.getFirstChild()?.getChildrenOfKind(h.SyntaxKind.SyntaxList)||[])[0].getFirstChild();if(!n)return;E.parseNamedExposedModels(n).forEach(f=>r.push(f))}}),r};exports.analyzeMultipleSourceFiles=C;exports.analyzeSourceFileApiHeader=O;exports.analyzeSourceFileEndpoints=A;exports.analyzeSourceFileExposedModels=R;exports.analyzeSourceFileWithCache=P;exports.prepareOpenApiSpec=_;
2
2
  //# sourceMappingURL=analyzerModule.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"analyzerModule.cjs","sources":["../../../src/openapi/analyzerModule/analyzerModule.ts"],"sourcesContent":["import * as path from 'path'\nimport { SourceFile, SyntaxKind } from 'ts-morph'\nimport { Project } from 'ts-morph'\n\nimport { Logger } from '../../utils/logger'\nimport { discoverImportedName } from '../discoveryModule/discoverImports/discoverImports'\nimport {\n\tDiscoveredSourceFile,\n\tdiscoverRouterFiles,\n} from '../discoveryModule/discoverRouterFiles/discoverRouterFiles'\nimport { discoverRouters } from '../discoveryModule/discoverRouters/discoverRouters'\nimport { ApiDocsHeader, OpenApiManager } from '../manager/OpenApiManager'\nimport { EndpointData, ExposedModelData } from '../types'\nimport { getSourceFileTimestamp, TimestampCache } from './getSourceFileTimestamp'\nimport { getValuesOfObjectLiteral, resolveEndpointPath } from './nodeParsers'\nimport { parseEndpoint } from './parseEndpoint'\nimport { parseExposedModel, parseNamedExposedModels } from './parseExposedModels'\nimport { SourceFileCache } from './sourceFileCache'\n\ntype Props = {\n\tlogLevel?: Parameters<(typeof Logger)['setLevel']>[0]\n\ttsconfigPath: string\n\tsourceFilePaths?: string[]\n\tsourceFileDiscovery?: boolean | FileDiscoveryConfig\n\tincremental?:\n\t\t| boolean\n\t\t| {\n\t\t\t\tcachePath: string\n\t\t }\n}\n\ntype FileDiscoveryConfig = {\n\trootPath: string\n}\n\n/**\n * @param tsconfigPath Path to tsconfig file relative to project root\n * @param sourceFilePaths Array of router source files relative to project root\n */\nexport const prepareOpenApiSpec = ({\n\tlogLevel,\n\ttsconfigPath,\n\tsourceFilePaths,\n\tsourceFileDiscovery,\n\tincremental,\n}: Props) => {\n\tconst openApiManager = OpenApiManager.getInstance()\n\n\tif (openApiManager.isReady()) {\n\t\treturn\n\t}\n\n\tif (logLevel) {\n\t\tLogger.setLevel(logLevel)\n\t}\n\n\tLogger.info('Preparing OpenAPI spec')\n\n\tconst project = new Project({\n\t\ttsConfigFilePath: path.resolve(tsconfigPath),\n\t\tskipFileDependencyResolution: true,\n\t})\n\n\tconst { explicitRouters, discoveredRouterFiles, allSourceFiles } = (() => {\n\t\tconst sourceFilesToAdd = sourceFilePaths ?? []\n\t\tconst resolvedSourceFilePaths = sourceFilesToAdd.map((filepath) => path.resolve(filepath))\n\t\tconst sourceFiles = resolvedSourceFilePaths.map((filePath) => project.getSourceFileOrThrow(filePath))\n\t\tconst explicitRouters = sourceFiles.flatMap((file) => ({\n\t\t\tfileName: file.getFilePath(),\n\t\t\tsourceFile: file,\n\t\t\trouters: discoverRouters(file),\n\t\t}))\n\n\t\tconst { discoveredRouterFiles, discoveredSourceFiles } = (() => {\n\t\t\tif (sourceFileDiscovery === false) {\n\t\t\t\treturn { discoveredRouterFiles: [], discoveredSourceFiles: [] }\n\t\t\t}\n\n\t\t\tconst startTime = performance.now()\n\t\t\tconst files = discoverRouterFiles({\n\t\t\t\ttargetPath: typeof sourceFileDiscovery === 'object' ? sourceFileDiscovery.rootPath : '.',\n\t\t\t\ttsConfigPath: tsconfigPath,\n\t\t\t})\n\t\t\tLogger.info(`File discovery took ${Math.round(performance.now() - startTime)}ms`)\n\t\t\treturn files\n\t\t})()\n\n\t\tconst allSourceFiles = sourceFiles.reduce(\n\t\t\t(acc, current) =>\n\t\t\t\tacc.some((r) => r.getFilePath() === current.getFilePath()) ? acc : acc.concat(current),\n\t\t\tdiscoveredSourceFiles,\n\t\t)\n\n\t\treturn { explicitRouters, discoveredRouterFiles, allSourceFiles }\n\t})()\n\n\tconst filesToAnalyze = explicitRouters.reduce(\n\t\t(acc, current) => (acc.some((r) => r.fileName === current.fileName) ? acc : acc.concat(current)),\n\t\tdiscoveredRouterFiles,\n\t)\n\n\tconst apiHeaders = allSourceFiles\n\t\t.flatMap((file) => analyzeSourceFileApiHeader(file))\n\t\t.filter((headers) => !!headers)\n\tif (apiHeaders.length > 0 && apiHeaders[0]) {\n\t\topenApiManager.setHeader(apiHeaders[0])\n\t}\n\n\tconst exposedModels = allSourceFiles.flatMap((file) => analyzeSourceFileExposedModels(file))\n\n\topenApiManager.setExposedModels(exposedModels)\n\n\tconst cachePath = (() => {\n\t\tif (typeof incremental === 'object' && incremental.cachePath) {\n\t\t\treturn incremental.cachePath\n\t\t}\n\t\treturn path.resolve(process.cwd(), 'node_modules', '.cache', 'moonflower')\n\t})()\n\tconst endpoints = analyzeMultipleSourceFiles(filesToAnalyze, {\n\t\tincremental: incremental !== false,\n\t\tcachePath,\n\t\ttimestampCache: {},\n\t})\n\n\topenApiManager.setStats({\n\t\tdiscoveredRouterFiles: discoveredRouterFiles.map((file) => ({\n\t\t\tpath: file.fileName,\n\t\t\trouters: file.routers.named.map((r) => ({\n\t\t\t\tname: r,\n\t\t\t\tendpoints: endpoints\n\t\t\t\t\t.filter((e) => e.sourceFilePath === file.fileName)\n\t\t\t\t\t.map((e) => `${e.method.toUpperCase()} ${e.path}`),\n\t\t\t})),\n\t\t})),\n\t\texplicitRouterFiles: explicitRouters.map((file) => ({\n\t\t\tpath: file.fileName,\n\t\t\trouters: file.routers.named.map((r) => ({\n\t\t\t\tname: r,\n\t\t\t\tendpoints: endpoints\n\t\t\t\t\t.filter((e) => e.sourceFilePath === file.fileName)\n\t\t\t\t\t.map((e) => `${e.method.toUpperCase()} ${e.path}`),\n\t\t\t})),\n\t\t})),\n\t})\n\n\topenApiManager.setEndpoints(endpoints)\n\topenApiManager.markAsReady()\n}\n\nexport const analyzeMultipleSourceFiles = (\n\tfiles: DiscoveredSourceFile[],\n\tconfig: {\n\t\tincremental: boolean\n\t\tcachePath: string\n\t\ttimestampCache: TimestampCache\n\t},\n\tfilterEndpointPaths?: string[],\n): EndpointData[] => {\n\tconst startTime = performance.now()\n\tconst analyzedFiles = files.map((file) => analyzeSourceFileWithCache(file, config, filterEndpointPaths))\n\tLogger.info(`Router analysis took ${Math.round(performance.now() - startTime)}ms`)\n\n\tanalyzedFiles\n\t\t.map((f, index) => ({\n\t\t\tfileName: files[index].fileName,\n\t\t\ttimeTaken: f.timing,\n\t\t}))\n\t\t.sort((a, b) => b.timeTaken - a.timeTaken)\n\t\t.filter((t) => t.timeTaken > 500)\n\t\t.forEach((t) => {\n\t\t\tLogger.info(`- [${t.fileName}] Took ${Math.round(t.timeTaken)}ms to analyze`)\n\t\t})\n\n\treturn analyzedFiles.flatMap((f) => f.endpoints)\n}\n\nexport const analyzeSourceFileWithCache = (\n\tfile: DiscoveredSourceFile,\n\tconfig: {\n\t\tincremental: boolean\n\t\tcachePath: string\n\t\ttimestampCache: TimestampCache\n\t},\n\tfilterEndpointPaths?: string[],\n): { endpoints: EndpointData[]; timing: number } => {\n\tconst timestamp = getSourceFileTimestamp(file.sourceFile, config.timestampCache)\n\tconst cachedResults = SourceFileCache.getCachedResults(file.sourceFile, timestamp, config.cachePath)\n\n\tif (cachedResults) {\n\t\tLogger.debug(`[${file.fileName}] Found cached results`)\n\t\treturn { endpoints: cachedResults.endpoints, timing: 0 }\n\t}\n\tLogger.debug(`[${file.fileName}] Analyzing...`)\n\n\tconst t1 = performance.now()\n\tconst endpoints = analyzeSourceFileEndpoints(file, filterEndpointPaths)\n\tconst t2 = performance.now()\n\tLogger.debug(`[${file.fileName}] Analyzed in ${t2 - t1}ms`)\n\tSourceFileCache.cacheResults(file.sourceFile, timestamp, config.cachePath, endpoints)\n\treturn { endpoints, timing: t2 - t1 }\n}\n\nexport const analyzeSourceFileEndpoints = (\n\tfile: DiscoveredSourceFile,\n\tfilterEndpointPaths?: string[],\n): EndpointData[] => {\n\tconst endpoints: EndpointData[] = []\n\tconst operations = ['get', 'post', 'put', 'delete', 'del', 'patch']\n\tconst joinedOperations = operations.join('|')\n\n\tfile.routers.named.forEach((routerName) => {\n\t\tfile.sourceFile.forEachChild((node) => {\n\t\t\tconst nodeText = node.getText()\n\t\t\tconst routerPattern = new RegExp(`${routerName}\\\\.(?:${joinedOperations})`)\n\n\t\t\tif (routerPattern.test(nodeText)) {\n\t\t\t\tconst endpointPath = resolveEndpointPath(node) ?? ''\n\n\t\t\t\tif (filterEndpointPaths && !filterEndpointPaths.some((path) => endpointPath.includes(path))) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tendpoints.push(parseEndpoint(node, file.fileName))\n\t\t\t}\n\t\t})\n\t})\n\n\treturn endpoints\n}\n\nexport const analyzeSourceFileApiHeader = (sourceFile: SourceFile): ApiDocsHeader | null => {\n\tconst nameOfUseApiHeader = discoverImportedName({\n\t\tsourceFile,\n\t\toriginalName: 'useApiHeader',\n\t})\n\n\tif (!nameOfUseApiHeader) {\n\t\treturn null\n\t}\n\n\tconst node = sourceFile\n\t\t.forEachChildAsArray()\n\t\t.filter((node) => node.isKind(SyntaxKind.ExpressionStatement))\n\t\t.find((node) => nameOfUseApiHeader && node.getText().startsWith(nameOfUseApiHeader))\n\n\tif (!node) {\n\t\treturn null\n\t}\n\n\tconst targetNode = node.getFirstDescendantByKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n\tconst values = getValuesOfObjectLiteral(targetNode)\n\n\tconst collapseObject = (v: string | string[] | typeof values): any => {\n\t\tif (typeof v === 'string') {\n\t\t\treturn v\n\t\t}\n\t\tif (Array.isArray(v) && v.every((value) => typeof value === 'string')) {\n\t\t\treturn v\n\t\t}\n\n\t\treturn v.reduce((acc, current) => {\n\t\t\tif (typeof current === 'string') {\n\t\t\t\treturn acc\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...acc,\n\t\t\t\t[current.identifier]: collapseObject(current.value as string[]),\n\t\t\t}\n\t\t}, {})\n\t}\n\treturn collapseObject(values)\n}\n\nexport const analyzeSourceFileExposedModels = (sourceFile: SourceFile): ExposedModelData[] => {\n\tconst models: ExposedModelData[] = []\n\n\tconst nameOfUseExposeApiModel = discoverImportedName({\n\t\tsourceFile,\n\t\toriginalName: 'useExposeApiModel',\n\t})\n\n\tconst nameOfUseExposeNamedApiModels = discoverImportedName({\n\t\tsourceFile,\n\t\toriginalName: 'useExposeNamedApiModels',\n\t})\n\n\tsourceFile\n\t\t.forEachChildAsArray()\n\t\t.filter((node) => node.isKind(SyntaxKind.ExpressionStatement))\n\t\t.map((node) => {\n\t\t\tif (nameOfUseExposeApiModel && node.getText().startsWith(nameOfUseExposeApiModel)) {\n\t\t\t\tconst callExpressionNode = node.getFirstChild()\n\t\t\t\tconst syntaxListChildren = callExpressionNode?.getChildrenOfKind(SyntaxKind.SyntaxList) || []\n\n\t\t\t\tconst firstChild = syntaxListChildren[0].getFirstChild()\n\t\t\t\tif (!firstChild) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tmodels.push(parseExposedModel(firstChild))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (nameOfUseExposeNamedApiModels && node.getText().startsWith(nameOfUseExposeNamedApiModels)) {\n\t\t\t\tconst callExpressionNode = node.getFirstChild()\n\t\t\t\tconst syntaxListChildren = callExpressionNode?.getChildrenOfKind(SyntaxKind.SyntaxList) || []\n\n\t\t\t\tconst firstChild = syntaxListChildren[0].getFirstChild()\n\t\t\t\tif (!firstChild) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst parsedModels = parseNamedExposedModels(firstChild)\n\t\t\t\tparsedModels.forEach((model) => models.push(model))\n\t\t\t}\n\t\t})\n\treturn models\n}\n"],"names":["prepareOpenApiSpec","logLevel","tsconfigPath","sourceFilePaths","sourceFileDiscovery","incremental","openApiManager","OpenApiManager","Logger","project","Project","path","explicitRouters","discoveredRouterFiles","allSourceFiles","sourceFiles","filepath","filePath","file","discoverRouters","discoveredSourceFiles","startTime","files","discoverRouterFiles","acc","current","r","filesToAnalyze","apiHeaders","analyzeSourceFileApiHeader","headers","exposedModels","analyzeSourceFileExposedModels","cachePath","endpoints","analyzeMultipleSourceFiles","e","config","filterEndpointPaths","analyzedFiles","analyzeSourceFileWithCache","f","index","a","b","timestamp","getSourceFileTimestamp","cachedResults","SourceFileCache","t1","analyzeSourceFileEndpoints","t2","joinedOperations","routerName","node","nodeText","resolveEndpointPath","parseEndpoint","sourceFile","nameOfUseApiHeader","discoverImportedName","SyntaxKind","targetNode","values","getValuesOfObjectLiteral","collapseObject","v","value","models","nameOfUseExposeApiModel","nameOfUseExposeNamedApiModels","firstChild","parseExposedModel","parseNamedExposedModels","model"],"mappings":"82BAuCaA,EAAqB,CAAC,CAClC,SAAAC,EACA,aAAAC,EACA,gBAAAC,EACA,oBAAAC,EACA,YAAAC,CACD,IAAa,CACN,MAAAC,EAAiBC,iBAAe,YAAY,EAE9C,GAAAD,EAAe,UAClB,OAGGL,GACHO,EAAA,OAAO,SAASP,CAAQ,EAGzBO,EAAA,OAAO,KAAK,wBAAwB,EAE9B,MAAAC,EAAU,IAAIC,UAAQ,CAC3B,iBAAkBC,EAAK,QAAQT,CAAY,EAC3C,6BAA8B,EAAA,CAC9B,EAEK,CAAE,gBAAAU,EAAiB,sBAAAC,EAAuB,eAAAC,CAAA,GAAoB,IAAM,CAGnE,MAAAC,GAFmBZ,GAAmB,CAAC,GACI,IAAKa,GAAaL,EAAK,QAAQK,CAAQ,CAAC,EAC7C,IAAKC,GAAaR,EAAQ,qBAAqBQ,CAAQ,CAAC,EAC9FL,EAAkBG,EAAY,QAASG,IAAU,CACtD,SAAUA,EAAK,YAAY,EAC3B,WAAYA,EACZ,QAASC,kBAAgBD,CAAI,CAAA,EAC5B,EAEI,CAAE,sBAAAL,EAAuB,sBAAAO,CAAA,GAA2B,IAAM,CAC/D,GAAIhB,IAAwB,GAC3B,MAAO,CAAE,sBAAuB,GAAI,sBAAuB,CAAA,CAAG,EAGzD,MAAAiB,EAAY,YAAY,IAAI,EAC5BC,EAAQC,EAAAA,oBAAoB,CACjC,WAAY,OAAOnB,GAAwB,SAAWA,EAAoB,SAAW,IACrF,aAAcF,CAAA,CACd,EACMM,OAAAA,EAAAA,OAAA,KAAK,uBAAuB,KAAK,MAAM,YAAY,IAAI,EAAIa,CAAS,CAAC,IAAI,EACzEC,CAAA,GACL,EAEGR,EAAiBC,EAAY,OAClC,CAACS,EAAKC,IACLD,EAAI,KAAME,GAAMA,EAAE,YAAY,IAAMD,EAAQ,YAAY,CAAC,EAAID,EAAMA,EAAI,OAAOC,CAAO,EACtFL,CACD,EAEA,MAAO,CAAE,gBAAAR,EAAiB,sBAAAC,EAAuB,eAAAC,CAAe,CAAA,GAC9D,EAEGa,EAAiBf,EAAgB,OACtC,CAACY,EAAKC,IAAaD,EAAI,KAAME,GAAMA,EAAE,WAAaD,EAAQ,QAAQ,EAAID,EAAMA,EAAI,OAAOC,CAAO,EAC9FZ,CACD,EAEMe,EAAad,EACjB,QAASI,GAASW,EAA2BX,CAAI,CAAC,EAClD,OAAQY,GAAY,CAAC,CAACA,CAAO,EAC3BF,EAAW,OAAS,GAAKA,EAAW,CAAC,GACzBtB,EAAA,UAAUsB,EAAW,CAAC,CAAC,EAGvC,MAAMG,EAAgBjB,EAAe,QAASI,GAASc,EAA+Bd,CAAI,CAAC,EAE3FZ,EAAe,iBAAiByB,CAAa,EAE7C,MAAME,EACD,OAAO5B,GAAgB,UAAYA,EAAY,UAC3CA,EAAY,UAEbM,EAAK,QAAQ,QAAQ,MAAO,eAAgB,SAAU,YAAY,EAEpEuB,EAAYC,EAA2BR,EAAgB,CAE5D,UAAAM,EACA,eAAgB,CAAA,CAAC,CACjB,EAED3B,EAAe,SAAS,CACvB,sBAAuBO,EAAsB,IAAKK,IAAU,CAC3D,KAAMA,EAAK,SACX,QAASA,EAAK,QAAQ,MAAM,IAAKQ,IAAO,CACvC,KAAMA,EACN,UAAWQ,EACT,OAAQE,GAAMA,EAAE,iBAAmBlB,EAAK,QAAQ,EAChD,IAAKkB,GAAM,GAAGA,EAAE,OAAO,aAAa,IAAIA,EAAE,IAAI,EAAE,CAAA,EACjD,CAAA,EACD,EACF,oBAAqBxB,EAAgB,IAAKM,IAAU,CACnD,KAAMA,EAAK,SACX,QAASA,EAAK,QAAQ,MAAM,IAAKQ,IAAO,CACvC,KAAMA,EACN,UAAWQ,EACT,OAAQE,GAAMA,EAAE,iBAAmBlB,EAAK,QAAQ,EAChD,IAAKkB,GAAM,GAAGA,EAAE,OAAO,aAAa,IAAIA,EAAE,IAAI,EAAE,CAAA,EACjD,CAAA,EACD,CAAA,CACF,EAED9B,EAAe,aAAa4B,CAAS,EACrC5B,EAAe,YAAY,CAC5B,EAEa6B,EAA6B,CACzCb,EACAe,EAKAC,IACoB,CACd,MAAAjB,EAAY,YAAY,IAAI,EAC5BkB,EAAgBjB,EAAM,IAAKJ,GAASsB,EAA2BtB,EAAMmB,CAA2B,CAAC,EAChG7B,OAAAA,EAAAA,OAAA,KAAK,wBAAwB,KAAK,MAAM,YAAY,IAAI,EAAIa,CAAS,CAAC,IAAI,EAG/EkB,EAAA,IAAI,CAACE,EAAGC,KAAW,CACnB,SAAUpB,EAAMoB,CAAK,EAAE,SACvB,UAAWD,EAAE,MAAA,EACZ,EACD,KAAK,CAACE,EAAGC,IAAMA,EAAE,UAAYD,EAAE,SAAS,EACxC,OAAQ,GAAM,EAAE,UAAY,GAAG,EAC/B,QAAS,GAAM,CACRnC,EAAAA,OAAA,KAAK,MAAM,EAAE,QAAQ,UAAU,KAAK,MAAM,EAAE,SAAS,CAAC,eAAe,CAAA,CAC5E,EAEK+B,EAAc,QAASE,GAAMA,EAAE,SAAS,CAChD,EAEaD,EAA6B,CACzCtB,EACAmB,EAKAC,IACmD,CACnD,MAAMO,EAAYC,EAAAA,uBAAuB5B,EAAK,WAAYmB,EAAO,cAAc,EACzEU,EAAgBC,EAAgB,gBAAA,iBAAiB9B,EAAK,WAAY2B,EAAWR,EAAO,SAAS,EAEnG,GAAIU,EACHvC,OAAAA,EAAA,OAAO,MAAM,IAAIU,EAAK,QAAQ,wBAAwB,EAC/C,CAAE,UAAW6B,EAAc,UAAW,OAAQ,CAAE,EAExDvC,EAAA,OAAO,MAAM,IAAIU,EAAK,QAAQ,gBAAgB,EAExC,MAAA+B,EAAK,YAAY,IAAI,EACrBf,EAAYgB,EAA2BhC,CAAyB,EAChEiC,EAAK,YAAY,IAAI,EAC3B3C,OAAAA,SAAO,MAAM,IAAIU,EAAK,QAAQ,iBAAiBiC,EAAKF,CAAE,IAAI,EAC1DD,EAAA,gBAAgB,aAAa9B,EAAK,WAAY2B,EAAWR,EAAO,UAAWH,CAAS,EAC7E,CAAE,UAAAA,EAAW,OAAQiB,EAAKF,CAAG,CACrC,EAEaC,EAA6B,CACzChC,EACAoB,IACoB,CACpB,MAAMJ,EAA4B,CAAC,EAE7BkB,EADa,CAAC,MAAO,OAAQ,MAAO,SAAU,MAAO,OAAO,EAC9B,KAAK,GAAG,EAE5C,OAAAlC,EAAK,QAAQ,MAAM,QAASmC,GAAe,CACrCnC,EAAA,WAAW,aAAcoC,GAAS,CAChC,MAAAC,EAAWD,EAAK,QAAQ,EACR,IAAI,OAAO,GAAGD,CAAU,SAASD,CAAgB,GAAG,EAExD,KAAKG,CAAQ,IACTC,EAAoB,oBAAAF,CAAI,EAM7CpB,EAAU,KAAKuB,EAAA,cAAcH,EAAMpC,EAAK,QAAQ,CAAC,EAClD,CACA,CAAA,CACD,EAEMgB,CACR,EAEaL,EAA8B6B,GAAiD,CAC3F,MAAMC,EAAqBC,EAAAA,qBAAqB,CAC/C,WAAAF,EACA,aAAc,cAAA,CACd,EAED,GAAI,CAACC,EACG,OAAA,KAGF,MAAAL,EAAOI,EACX,oBAAoB,EACpB,OAAQJ,GAASA,EAAK,OAAOO,EAAW,WAAA,mBAAmB,CAAC,EAC5D,KAAMP,GAASK,GAAsBL,EAAK,QAAQ,EAAE,WAAWK,CAAkB,CAAC,EAEpF,GAAI,CAACL,EACG,OAAA,KAGR,MAAMQ,EAAaR,EAAK,gCAAgCO,EAAAA,WAAW,uBAAuB,EACpFE,EAASC,2BAAyBF,CAAU,EAE5CG,EAAkBC,GACnB,OAAOA,GAAM,UAGb,MAAM,QAAQA,CAAC,GAAKA,EAAE,MAAOC,GAAU,OAAOA,GAAU,QAAQ,EAC5DD,EAGDA,EAAE,OAAO,CAAC1C,EAAKC,IACjB,OAAOA,GAAY,SACfD,EAED,CACN,GAAGA,EACH,CAACC,EAAQ,UAAU,EAAGwC,EAAexC,EAAQ,KAAiB,CAC/D,EACE,EAAE,EAEN,OAAOwC,EAAeF,CAAM,CAC7B,EAEa/B,EAAkC0B,GAA+C,CAC7F,MAAMU,EAA6B,CAAC,EAE9BC,EAA0BT,EAAAA,qBAAqB,CACpD,WAAAF,EACA,aAAc,mBAAA,CACd,EAEKY,EAAgCV,EAAAA,qBAAqB,CAC1D,WAAAF,EACA,aAAc,yBAAA,CACd,EAED,OAAAA,EACE,oBAAoB,EACpB,OAAQJ,GAASA,EAAK,OAAOO,EAAAA,WAAW,mBAAmB,CAAC,EAC5D,IAAKP,GAAS,CACd,GAAIe,GAA2Bf,EAAK,QAAU,EAAA,WAAWe,CAAuB,EAAG,CAIlF,MAAME,GAHqBjB,EAAK,cAAc,GACC,kBAAkBO,EAAAA,WAAW,UAAU,GAAK,CAAC,GAEtD,CAAC,EAAE,cAAc,EACvD,GAAI,CAACU,EACJ,OAGMH,EAAA,KAAKI,oBAAkBD,CAAU,CAAC,EACzC,MAAA,CAGD,GAAID,GAAiChB,EAAK,QAAU,EAAA,WAAWgB,CAA6B,EAAG,CAI9F,MAAMC,GAHqBjB,EAAK,cAAc,GACC,kBAAkBO,EAAAA,WAAW,UAAU,GAAK,CAAC,GAEtD,CAAC,EAAE,cAAc,EACvD,GAAI,CAACU,EACJ,OAGoBE,0BAAwBF,CAAU,EAC1C,QAASG,GAAUN,EAAO,KAAKM,CAAK,CAAC,CAAA,CACnD,CACA,EACKN,CACR"}
1
+ {"version":3,"file":"analyzerModule.cjs","sources":["../../../src/openapi/analyzerModule/analyzerModule.ts"],"sourcesContent":["import * as path from 'path'\nimport { SourceFile, SyntaxKind } from 'ts-morph'\nimport { Project } from 'ts-morph'\n\nimport { Logger } from '../../utils/logger'\nimport { discoverImportedName } from '../discoveryModule/discoverImports/discoverImports'\nimport {\n\tDiscoveredSourceFile,\n\tdiscoverRouterFiles,\n} from '../discoveryModule/discoverRouterFiles/discoverRouterFiles'\nimport { discoverRouters } from '../discoveryModule/discoverRouters/discoverRouters'\nimport { ApiDocsHeader, OpenApiManager } from '../manager/OpenApiManager'\nimport { EndpointData, ExposedModelData } from '../types'\nimport { getSourceFileTimestamp, TimestampCache } from './getSourceFileTimestamp'\nimport { getValuesOfObjectLiteral, resolveEndpointPath } from './nodeParsers'\nimport { parseEndpoint } from './parseEndpoint'\nimport { parseExposedModel, parseNamedExposedModels } from './parseExposedModels'\nimport { SourceFileCache } from './sourceFileCache'\n\ntype Props = {\n\tlogLevel?: Parameters<(typeof Logger)['setLevel']>[0]\n\ttsconfigPath: string\n\tsourceFilePaths?: string[]\n\tsourceFileDiscovery?: boolean | FileDiscoveryConfig\n\tincremental?:\n\t\t| boolean\n\t\t| {\n\t\t\t\tcachePath: string\n\t\t }\n}\n\ntype FileDiscoveryConfig = {\n\trootPath: string\n}\n\n/**\n * @param tsconfigPath Path to tsconfig file relative to project root\n * @param sourceFilePaths Array of router source files relative to project root\n */\nexport const prepareOpenApiSpec = ({\n\tlogLevel,\n\ttsconfigPath,\n\tsourceFilePaths,\n\tsourceFileDiscovery,\n\tincremental,\n}: Props) => {\n\tconst openApiManager = OpenApiManager.getInstance()\n\n\tif (openApiManager.isReady()) {\n\t\treturn\n\t}\n\n\tif (logLevel) {\n\t\tLogger.setLevel(logLevel)\n\t}\n\n\tLogger.info('Preparing OpenAPI spec')\n\n\tconst project = new Project({\n\t\ttsConfigFilePath: path.resolve(tsconfigPath),\n\t\tskipFileDependencyResolution: true,\n\t})\n\n\tconst { explicitRouters, discoveredRouterFiles, allSourceFiles } = (() => {\n\t\tconst sourceFilesToAdd = sourceFilePaths ?? []\n\t\tconst resolvedSourceFilePaths = sourceFilesToAdd.map((filepath) => path.resolve(filepath))\n\t\tconst sourceFiles = resolvedSourceFilePaths.map((filePath) => project.getSourceFileOrThrow(filePath))\n\t\tconst explicitRouters = sourceFiles.flatMap((file) => ({\n\t\t\tfileName: file.getFilePath(),\n\t\t\tsourceFile: file,\n\t\t\trouters: discoverRouters(file),\n\t\t}))\n\n\t\tconst { discoveredRouterFiles, discoveredSourceFiles } = (() => {\n\t\t\tif (sourceFileDiscovery === false) {\n\t\t\t\treturn { discoveredRouterFiles: [], discoveredSourceFiles: [] }\n\t\t\t}\n\n\t\t\tconst startTime = performance.now()\n\t\t\tconst files = discoverRouterFiles({\n\t\t\t\ttargetPath: typeof sourceFileDiscovery === 'object' ? sourceFileDiscovery.rootPath : '.',\n\t\t\t\ttsConfigPath: tsconfigPath,\n\t\t\t})\n\t\t\tLogger.info(`File discovery took ${Math.round(performance.now() - startTime)}ms`)\n\t\t\treturn files\n\t\t})()\n\n\t\tconst allSourceFiles = sourceFiles.reduce(\n\t\t\t(acc, current) =>\n\t\t\t\tacc.some((r) => r.getFilePath() === current.getFilePath()) ? acc : acc.concat(current),\n\t\t\tdiscoveredSourceFiles,\n\t\t)\n\n\t\treturn { explicitRouters, discoveredRouterFiles, allSourceFiles }\n\t})()\n\n\tconst filesToAnalyze = explicitRouters.reduce(\n\t\t(acc, current) => (acc.some((r) => r.fileName === current.fileName) ? acc : acc.concat(current)),\n\t\tdiscoveredRouterFiles,\n\t)\n\n\tconst apiHeaders = allSourceFiles\n\t\t.flatMap((file) => analyzeSourceFileApiHeader(file))\n\t\t.filter((headers) => !!headers)\n\tif (apiHeaders.length > 0 && apiHeaders[0]) {\n\t\topenApiManager.setHeader(apiHeaders[0])\n\t}\n\n\tconst exposedModels = allSourceFiles.flatMap((file) => analyzeSourceFileExposedModels(file))\n\n\topenApiManager.setExposedModels(exposedModels)\n\n\tconst cachePath = (() => {\n\t\tif (typeof incremental === 'object' && incremental.cachePath) {\n\t\t\treturn incremental.cachePath\n\t\t}\n\t\treturn path.resolve(process.cwd(), 'node_modules', '.cache', 'moonflower')\n\t})()\n\tconst endpoints = analyzeMultipleSourceFiles(filesToAnalyze, {\n\t\tincremental: incremental !== false,\n\t\tcachePath,\n\t\ttimestampCache: {},\n\t})\n\n\topenApiManager.setStats({\n\t\tdiscoveredRouterFiles: discoveredRouterFiles.map((file) => ({\n\t\t\tpath: file.fileName,\n\t\t\trouters: file.routers.named.map((r) => ({\n\t\t\t\tname: r,\n\t\t\t\tendpoints: endpoints\n\t\t\t\t\t.filter((e) => e.sourceFilePath === file.fileName)\n\t\t\t\t\t.map((e) => `${e.method.toUpperCase()} ${e.path}`),\n\t\t\t})),\n\t\t})),\n\t\texplicitRouterFiles: explicitRouters.map((file) => ({\n\t\t\tpath: file.fileName,\n\t\t\trouters: file.routers.named.map((r) => ({\n\t\t\t\tname: r,\n\t\t\t\tendpoints: endpoints\n\t\t\t\t\t.filter((e) => e.sourceFilePath === file.fileName)\n\t\t\t\t\t.map((e) => `${e.method.toUpperCase()} ${e.path}`),\n\t\t\t})),\n\t\t})),\n\t})\n\n\topenApiManager.setEndpoints(endpoints)\n\topenApiManager.markAsReady()\n}\n\nexport const analyzeMultipleSourceFiles = (\n\tfiles: DiscoveredSourceFile[],\n\tconfig: {\n\t\tincremental: boolean\n\t\tcachePath: string\n\t\ttimestampCache: TimestampCache\n\t},\n\tfilterEndpointPaths?: string[],\n): EndpointData[] => {\n\tconst startTime = performance.now()\n\tconst analyzedFiles = files.map((file) => analyzeSourceFileWithCache(file, config, filterEndpointPaths))\n\tLogger.info(`Router analysis took ${Math.round(performance.now() - startTime)}ms`)\n\n\tanalyzedFiles\n\t\t.map((f, index) => ({\n\t\t\tfileName: files[index].fileName,\n\t\t\ttimeTaken: f.timing,\n\t\t}))\n\t\t.sort((a, b) => b.timeTaken - a.timeTaken)\n\t\t.filter((t) => t.timeTaken > 500)\n\t\t.forEach((t) => {\n\t\t\tLogger.info(`- [${t.fileName}] Took ${Math.round(t.timeTaken)}ms to analyze`)\n\t\t})\n\n\treturn analyzedFiles.flatMap((f) => f.endpoints)\n}\n\nexport const analyzeSourceFileWithCache = (\n\tfile: DiscoveredSourceFile,\n\tconfig: {\n\t\tincremental: boolean\n\t\tcachePath: string\n\t\ttimestampCache: TimestampCache\n\t},\n\tfilterEndpointPaths?: string[],\n): { endpoints: EndpointData[]; timing: number } => {\n\tconst timestamp = getSourceFileTimestamp(file.sourceFile, config.timestampCache)\n\tconst cachedResults = SourceFileCache.getCachedResults(file.sourceFile, timestamp, config.cachePath)\n\n\tif (cachedResults) {\n\t\tLogger.debug(`[${file.fileName}] Found cached results`)\n\t\treturn { endpoints: cachedResults.endpoints, timing: 0 }\n\t}\n\tLogger.debug(`[${file.fileName}] Analyzing...`)\n\n\tconst t1 = performance.now()\n\tconst endpoints = analyzeSourceFileEndpoints(file, filterEndpointPaths)\n\tconst t2 = performance.now()\n\tLogger.debug(`[${file.fileName}] Analyzed in ${t2 - t1}ms`)\n\tSourceFileCache.cacheResults(file.sourceFile, timestamp, config.cachePath, endpoints)\n\treturn { endpoints, timing: t2 - t1 }\n}\n\nexport const analyzeSourceFileEndpoints = (\n\tfile: DiscoveredSourceFile,\n\tfilterEndpointPaths?: string[],\n): EndpointData[] => {\n\tconst endpoints: EndpointData[] = []\n\tconst operations = ['get', 'post', 'put', 'delete', 'del', 'patch']\n\tconst joinedOperations = operations.join('|')\n\n\tfile.routers.named.forEach((routerName) => {\n\t\tconst routerPattern = new RegExp(`${routerName}\\\\.(?:${joinedOperations})`)\n\t\tfile.sourceFile.forEachChild((node) => {\n\t\t\tconst nodeText = node.getText()\n\n\t\t\tif (routerPattern.test(nodeText)) {\n\t\t\t\tconst endpointPath = resolveEndpointPath(node) ?? ''\n\n\t\t\t\tif (filterEndpointPaths && !filterEndpointPaths.some((path) => endpointPath.includes(path))) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tendpoints.push(parseEndpoint(node, file.fileName))\n\t\t\t}\n\t\t})\n\t})\n\n\treturn endpoints\n}\n\nexport const analyzeSourceFileApiHeader = (sourceFile: SourceFile): ApiDocsHeader | null => {\n\tconst nameOfUseApiHeader = discoverImportedName({\n\t\tsourceFile,\n\t\toriginalName: 'useApiHeader',\n\t})\n\n\tif (!nameOfUseApiHeader) {\n\t\treturn null\n\t}\n\n\tconst node = sourceFile\n\t\t.forEachChildAsArray()\n\t\t.filter((node) => node.isKind(SyntaxKind.ExpressionStatement))\n\t\t.find((node) => nameOfUseApiHeader && node.getText().startsWith(nameOfUseApiHeader))\n\n\tif (!node) {\n\t\treturn null\n\t}\n\n\tconst targetNode = node.getFirstDescendantByKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n\tconst values = getValuesOfObjectLiteral(targetNode)\n\n\tconst collapseObject = (v: string | string[] | typeof values): any => {\n\t\tif (typeof v === 'string') {\n\t\t\treturn v\n\t\t}\n\t\tif (Array.isArray(v) && v.every((value) => typeof value === 'string')) {\n\t\t\treturn v\n\t\t}\n\n\t\treturn v.reduce((acc, current) => {\n\t\t\tif (typeof current === 'string') {\n\t\t\t\treturn acc\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...acc,\n\t\t\t\t[current.identifier]: collapseObject(current.value as string[]),\n\t\t\t}\n\t\t}, {})\n\t}\n\treturn collapseObject(values)\n}\n\nexport const analyzeSourceFileExposedModels = (sourceFile: SourceFile): ExposedModelData[] => {\n\tconst models: ExposedModelData[] = []\n\n\tconst nameOfUseExposeApiModel = discoverImportedName({\n\t\tsourceFile,\n\t\toriginalName: 'useExposeApiModel',\n\t})\n\n\tconst nameOfUseExposeNamedApiModels = discoverImportedName({\n\t\tsourceFile,\n\t\toriginalName: 'useExposeNamedApiModels',\n\t})\n\n\tsourceFile\n\t\t.forEachChildAsArray()\n\t\t.filter((node) => node.isKind(SyntaxKind.ExpressionStatement))\n\t\t.map((node) => {\n\t\t\tif (nameOfUseExposeApiModel && node.getText().startsWith(nameOfUseExposeApiModel)) {\n\t\t\t\tconst callExpressionNode = node.getFirstChild()\n\t\t\t\tconst syntaxListChildren = callExpressionNode?.getChildrenOfKind(SyntaxKind.SyntaxList) || []\n\n\t\t\t\tconst firstChild = syntaxListChildren[0].getFirstChild()\n\t\t\t\tif (!firstChild) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tmodels.push(parseExposedModel(firstChild))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (nameOfUseExposeNamedApiModels && node.getText().startsWith(nameOfUseExposeNamedApiModels)) {\n\t\t\t\tconst callExpressionNode = node.getFirstChild()\n\t\t\t\tconst syntaxListChildren = callExpressionNode?.getChildrenOfKind(SyntaxKind.SyntaxList) || []\n\n\t\t\t\tconst firstChild = syntaxListChildren[0].getFirstChild()\n\t\t\t\tif (!firstChild) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst parsedModels = parseNamedExposedModels(firstChild)\n\t\t\t\tparsedModels.forEach((model) => models.push(model))\n\t\t\t}\n\t\t})\n\treturn models\n}\n"],"names":["prepareOpenApiSpec","logLevel","tsconfigPath","sourceFilePaths","sourceFileDiscovery","incremental","openApiManager","OpenApiManager","Logger","project","Project","path","explicitRouters","discoveredRouterFiles","allSourceFiles","sourceFiles","filepath","filePath","file","discoverRouters","discoveredSourceFiles","startTime","files","discoverRouterFiles","acc","current","r","filesToAnalyze","apiHeaders","analyzeSourceFileApiHeader","headers","exposedModels","analyzeSourceFileExposedModels","cachePath","endpoints","analyzeMultipleSourceFiles","e","config","filterEndpointPaths","analyzedFiles","analyzeSourceFileWithCache","f","index","a","b","timestamp","getSourceFileTimestamp","cachedResults","SourceFileCache","t1","analyzeSourceFileEndpoints","t2","joinedOperations","routerName","routerPattern","node","nodeText","resolveEndpointPath","parseEndpoint","sourceFile","nameOfUseApiHeader","discoverImportedName","SyntaxKind","targetNode","values","getValuesOfObjectLiteral","collapseObject","v","value","models","nameOfUseExposeApiModel","nameOfUseExposeNamedApiModels","firstChild","parseExposedModel","parseNamedExposedModels","model"],"mappings":"82BAuCaA,EAAqB,CAAC,CAClC,SAAAC,EACA,aAAAC,EACA,gBAAAC,EACA,oBAAAC,EACA,YAAAC,CACD,IAAa,CACN,MAAAC,EAAiBC,iBAAe,YAAY,EAE9C,GAAAD,EAAe,UAClB,OAGGL,GACHO,EAAA,OAAO,SAASP,CAAQ,EAGzBO,EAAA,OAAO,KAAK,wBAAwB,EAE9B,MAAAC,EAAU,IAAIC,UAAQ,CAC3B,iBAAkBC,EAAK,QAAQT,CAAY,EAC3C,6BAA8B,EAAA,CAC9B,EAEK,CAAE,gBAAAU,EAAiB,sBAAAC,EAAuB,eAAAC,CAAA,GAAoB,IAAM,CAGnE,MAAAC,GAFmBZ,GAAmB,CAAC,GACI,IAAKa,GAAaL,EAAK,QAAQK,CAAQ,CAAC,EAC7C,IAAKC,GAAaR,EAAQ,qBAAqBQ,CAAQ,CAAC,EAC9FL,EAAkBG,EAAY,QAASG,IAAU,CACtD,SAAUA,EAAK,YAAY,EAC3B,WAAYA,EACZ,QAASC,kBAAgBD,CAAI,CAAA,EAC5B,EAEI,CAAE,sBAAAL,EAAuB,sBAAAO,CAAA,GAA2B,IAAM,CAC/D,GAAIhB,IAAwB,GAC3B,MAAO,CAAE,sBAAuB,GAAI,sBAAuB,CAAA,CAAG,EAGzD,MAAAiB,EAAY,YAAY,IAAI,EAC5BC,EAAQC,EAAAA,oBAAoB,CACjC,WAAY,OAAOnB,GAAwB,SAAWA,EAAoB,SAAW,IACrF,aAAcF,CAAA,CACd,EACMM,OAAAA,EAAAA,OAAA,KAAK,uBAAuB,KAAK,MAAM,YAAY,IAAI,EAAIa,CAAS,CAAC,IAAI,EACzEC,CAAA,GACL,EAEGR,EAAiBC,EAAY,OAClC,CAACS,EAAKC,IACLD,EAAI,KAAME,GAAMA,EAAE,YAAY,IAAMD,EAAQ,YAAY,CAAC,EAAID,EAAMA,EAAI,OAAOC,CAAO,EACtFL,CACD,EAEA,MAAO,CAAE,gBAAAR,EAAiB,sBAAAC,EAAuB,eAAAC,CAAe,CAAA,GAC9D,EAEGa,EAAiBf,EAAgB,OACtC,CAACY,EAAKC,IAAaD,EAAI,KAAME,GAAMA,EAAE,WAAaD,EAAQ,QAAQ,EAAID,EAAMA,EAAI,OAAOC,CAAO,EAC9FZ,CACD,EAEMe,EAAad,EACjB,QAASI,GAASW,EAA2BX,CAAI,CAAC,EAClD,OAAQY,GAAY,CAAC,CAACA,CAAO,EAC3BF,EAAW,OAAS,GAAKA,EAAW,CAAC,GACzBtB,EAAA,UAAUsB,EAAW,CAAC,CAAC,EAGvC,MAAMG,EAAgBjB,EAAe,QAASI,GAASc,EAA+Bd,CAAI,CAAC,EAE3FZ,EAAe,iBAAiByB,CAAa,EAE7C,MAAME,EACD,OAAO5B,GAAgB,UAAYA,EAAY,UAC3CA,EAAY,UAEbM,EAAK,QAAQ,QAAQ,MAAO,eAAgB,SAAU,YAAY,EAEpEuB,EAAYC,EAA2BR,EAAgB,CAE5D,UAAAM,EACA,eAAgB,CAAA,CAAC,CACjB,EAED3B,EAAe,SAAS,CACvB,sBAAuBO,EAAsB,IAAKK,IAAU,CAC3D,KAAMA,EAAK,SACX,QAASA,EAAK,QAAQ,MAAM,IAAKQ,IAAO,CACvC,KAAMA,EACN,UAAWQ,EACT,OAAQE,GAAMA,EAAE,iBAAmBlB,EAAK,QAAQ,EAChD,IAAKkB,GAAM,GAAGA,EAAE,OAAO,aAAa,IAAIA,EAAE,IAAI,EAAE,CAAA,EACjD,CAAA,EACD,EACF,oBAAqBxB,EAAgB,IAAKM,IAAU,CACnD,KAAMA,EAAK,SACX,QAASA,EAAK,QAAQ,MAAM,IAAKQ,IAAO,CACvC,KAAMA,EACN,UAAWQ,EACT,OAAQE,GAAMA,EAAE,iBAAmBlB,EAAK,QAAQ,EAChD,IAAKkB,GAAM,GAAGA,EAAE,OAAO,aAAa,IAAIA,EAAE,IAAI,EAAE,CAAA,EACjD,CAAA,EACD,CAAA,CACF,EAED9B,EAAe,aAAa4B,CAAS,EACrC5B,EAAe,YAAY,CAC5B,EAEa6B,EAA6B,CACzCb,EACAe,EAKAC,IACoB,CACd,MAAAjB,EAAY,YAAY,IAAI,EAC5BkB,EAAgBjB,EAAM,IAAKJ,GAASsB,EAA2BtB,EAAMmB,CAA2B,CAAC,EAChG7B,OAAAA,EAAAA,OAAA,KAAK,wBAAwB,KAAK,MAAM,YAAY,IAAI,EAAIa,CAAS,CAAC,IAAI,EAG/EkB,EAAA,IAAI,CAACE,EAAGC,KAAW,CACnB,SAAUpB,EAAMoB,CAAK,EAAE,SACvB,UAAWD,EAAE,MAAA,EACZ,EACD,KAAK,CAACE,EAAGC,IAAMA,EAAE,UAAYD,EAAE,SAAS,EACxC,OAAQ,GAAM,EAAE,UAAY,GAAG,EAC/B,QAAS,GAAM,CACRnC,EAAAA,OAAA,KAAK,MAAM,EAAE,QAAQ,UAAU,KAAK,MAAM,EAAE,SAAS,CAAC,eAAe,CAAA,CAC5E,EAEK+B,EAAc,QAASE,GAAMA,EAAE,SAAS,CAChD,EAEaD,EAA6B,CACzCtB,EACAmB,EAKAC,IACmD,CACnD,MAAMO,EAAYC,EAAAA,uBAAuB5B,EAAK,WAAYmB,EAAO,cAAc,EACzEU,EAAgBC,EAAgB,gBAAA,iBAAiB9B,EAAK,WAAY2B,EAAWR,EAAO,SAAS,EAEnG,GAAIU,EACHvC,OAAAA,EAAA,OAAO,MAAM,IAAIU,EAAK,QAAQ,wBAAwB,EAC/C,CAAE,UAAW6B,EAAc,UAAW,OAAQ,CAAE,EAExDvC,EAAA,OAAO,MAAM,IAAIU,EAAK,QAAQ,gBAAgB,EAExC,MAAA+B,EAAK,YAAY,IAAI,EACrBf,EAAYgB,EAA2BhC,CAAyB,EAChEiC,EAAK,YAAY,IAAI,EAC3B3C,OAAAA,SAAO,MAAM,IAAIU,EAAK,QAAQ,iBAAiBiC,EAAKF,CAAE,IAAI,EAC1DD,EAAA,gBAAgB,aAAa9B,EAAK,WAAY2B,EAAWR,EAAO,UAAWH,CAAS,EAC7E,CAAE,UAAAA,EAAW,OAAQiB,EAAKF,CAAG,CACrC,EAEaC,EAA6B,CACzChC,EACAoB,IACoB,CACpB,MAAMJ,EAA4B,CAAC,EAE7BkB,EADa,CAAC,MAAO,OAAQ,MAAO,SAAU,MAAO,OAAO,EAC9B,KAAK,GAAG,EAE5C,OAAAlC,EAAK,QAAQ,MAAM,QAASmC,GAAe,CAC1C,MAAMC,EAAgB,IAAI,OAAO,GAAGD,CAAU,SAASD,CAAgB,GAAG,EACrElC,EAAA,WAAW,aAAcqC,GAAS,CAChC,MAAAC,EAAWD,EAAK,QAAQ,EAE1BD,EAAc,KAAKE,CAAQ,IACTC,EAAoB,oBAAAF,CAAI,EAM7CrB,EAAU,KAAKwB,EAAA,cAAcH,EAAMrC,EAAK,QAAQ,CAAC,EAClD,CACA,CAAA,CACD,EAEMgB,CACR,EAEaL,EAA8B8B,GAAiD,CAC3F,MAAMC,EAAqBC,EAAAA,qBAAqB,CAC/C,WAAAF,EACA,aAAc,cAAA,CACd,EAED,GAAI,CAACC,EACG,OAAA,KAGF,MAAAL,EAAOI,EACX,oBAAoB,EACpB,OAAQJ,GAASA,EAAK,OAAOO,EAAW,WAAA,mBAAmB,CAAC,EAC5D,KAAMP,GAASK,GAAsBL,EAAK,QAAQ,EAAE,WAAWK,CAAkB,CAAC,EAEpF,GAAI,CAACL,EACG,OAAA,KAGR,MAAMQ,EAAaR,EAAK,gCAAgCO,EAAAA,WAAW,uBAAuB,EACpFE,EAASC,2BAAyBF,CAAU,EAE5CG,EAAkBC,GACnB,OAAOA,GAAM,UAGb,MAAM,QAAQA,CAAC,GAAKA,EAAE,MAAOC,GAAU,OAAOA,GAAU,QAAQ,EAC5DD,EAGDA,EAAE,OAAO,CAAC3C,EAAKC,IACjB,OAAOA,GAAY,SACfD,EAED,CACN,GAAGA,EACH,CAACC,EAAQ,UAAU,EAAGyC,EAAezC,EAAQ,KAAiB,CAC/D,EACE,EAAE,EAEN,OAAOyC,EAAeF,CAAM,CAC7B,EAEahC,EAAkC2B,GAA+C,CAC7F,MAAMU,EAA6B,CAAC,EAE9BC,EAA0BT,EAAAA,qBAAqB,CACpD,WAAAF,EACA,aAAc,mBAAA,CACd,EAEKY,EAAgCV,EAAAA,qBAAqB,CAC1D,WAAAF,EACA,aAAc,yBAAA,CACd,EAED,OAAAA,EACE,oBAAoB,EACpB,OAAQJ,GAASA,EAAK,OAAOO,EAAAA,WAAW,mBAAmB,CAAC,EAC5D,IAAKP,GAAS,CACd,GAAIe,GAA2Bf,EAAK,QAAU,EAAA,WAAWe,CAAuB,EAAG,CAIlF,MAAME,GAHqBjB,EAAK,cAAc,GACC,kBAAkBO,EAAAA,WAAW,UAAU,GAAK,CAAC,GAEtD,CAAC,EAAE,cAAc,EACvD,GAAI,CAACU,EACJ,OAGMH,EAAA,KAAKI,oBAAkBD,CAAU,CAAC,EACzC,MAAA,CAGD,GAAID,GAAiChB,EAAK,QAAU,EAAA,WAAWgB,CAA6B,EAAG,CAI9F,MAAMC,GAHqBjB,EAAK,cAAc,GACC,kBAAkBO,EAAAA,WAAW,UAAU,GAAK,CAAC,GAEtD,CAAC,EAAE,cAAc,EACvD,GAAI,CAACU,EACJ,OAGoBE,0BAAwBF,CAAU,EAC1C,QAASG,GAAUN,EAAO,KAAKM,CAAK,CAAC,CAAA,CACnD,CACA,EACKN,CACR"}
@@ -11,7 +11,7 @@ import { parseEndpoint as b } from "./parseEndpoint.mjs";
11
11
  import { parseExposedModel as K, parseNamedExposedModels as H } from "./parseExposedModels.mjs";
12
12
  import { SourceFileCache as N } from "./sourceFileCache.mjs";
13
13
  const oe = ({
14
- logLevel: o,
14
+ logLevel: t,
15
15
  tsconfigPath: n,
16
16
  sourceFilePaths: c,
17
17
  sourceFileDiscovery: a,
@@ -20,12 +20,12 @@ const oe = ({
20
20
  const e = k.getInstance();
21
21
  if (e.isReady())
22
22
  return;
23
- o && m.setLevel(o), m.info("Preparing OpenAPI spec");
24
- const t = new v({
23
+ t && m.setLevel(t), m.info("Preparing OpenAPI spec");
24
+ const o = new v({
25
25
  tsConfigFilePath: y.resolve(n),
26
26
  skipFileDependencyResolution: !0
27
27
  }), { explicitRouters: r, discoveredRouterFiles: d, allSourceFiles: f } = (() => {
28
- const l = (c ?? []).map((p) => y.resolve(p)).map((p) => t.getSourceFileOrThrow(p)), S = l.flatMap((p) => ({
28
+ const l = (c ?? []).map((p) => y.resolve(p)).map((p) => o.getSourceFileOrThrow(p)), S = l.flatMap((p) => ({
29
29
  fileName: p.getFilePath(),
30
30
  sourceFile: p,
31
31
  routers: w(p)
@@ -47,10 +47,10 @@ const oe = ({
47
47
  d
48
48
  ), g = f.flatMap((i) => B(i)).filter((i) => !!i);
49
49
  g.length > 0 && g[0] && e.setHeader(g[0]);
50
- const P = f.flatMap((i) => V(i));
51
- e.setExposedModels(P);
52
- const A = typeof s == "object" && s.cachePath ? s.cachePath : y.resolve(process.cwd(), "node_modules", ".cache", "moonflower"), x = U(C, {
53
- cachePath: A,
50
+ const A = f.flatMap((i) => V(i));
51
+ e.setExposedModels(A);
52
+ const P = typeof s == "object" && s.cachePath ? s.cachePath : y.resolve(process.cwd(), "node_modules", ".cache", "moonflower"), x = U(C, {
53
+ cachePath: P,
54
54
  timestampCache: {}
55
55
  });
56
56
  e.setStats({
@@ -69,53 +69,54 @@ const oe = ({
69
69
  }))
70
70
  }))
71
71
  }), e.setEndpoints(x), e.markAsReady();
72
- }, U = (o, n, c) => {
73
- const a = performance.now(), s = o.map((e) => W(e, n));
74
- return m.info(`Router analysis took ${Math.round(performance.now() - a)}ms`), s.map((e, t) => ({
75
- fileName: o[t].fileName,
72
+ }, U = (t, n, c) => {
73
+ const a = performance.now(), s = t.map((e) => W(e, n));
74
+ return m.info(`Router analysis took ${Math.round(performance.now() - a)}ms`), s.map((e, o) => ({
75
+ fileName: t[o].fileName,
76
76
  timeTaken: e.timing
77
- })).sort((e, t) => t.timeTaken - e.timeTaken).filter((e) => e.timeTaken > 500).forEach((e) => {
77
+ })).sort((e, o) => o.timeTaken - e.timeTaken).filter((e) => e.timeTaken > 500).forEach((e) => {
78
78
  m.info(`- [${e.fileName}] Took ${Math.round(e.timeTaken)}ms to analyze`);
79
79
  }), s.flatMap((e) => e.endpoints);
80
- }, W = (o, n, c) => {
81
- const a = z(o.sourceFile, n.timestampCache), s = N.getCachedResults(o.sourceFile, a, n.cachePath);
80
+ }, W = (t, n, c) => {
81
+ const a = z(t.sourceFile, n.timestampCache), s = N.getCachedResults(t.sourceFile, a, n.cachePath);
82
82
  if (s)
83
- return m.debug(`[${o.fileName}] Found cached results`), { endpoints: s.endpoints, timing: 0 };
84
- m.debug(`[${o.fileName}] Analyzing...`);
85
- const e = performance.now(), t = I(o), r = performance.now();
86
- return m.debug(`[${o.fileName}] Analyzed in ${r - e}ms`), N.cacheResults(o.sourceFile, a, n.cachePath, t), { endpoints: t, timing: r - e };
87
- }, I = (o, n) => {
83
+ return m.debug(`[${t.fileName}] Found cached results`), { endpoints: s.endpoints, timing: 0 };
84
+ m.debug(`[${t.fileName}] Analyzing...`);
85
+ const e = performance.now(), o = I(t), r = performance.now();
86
+ return m.debug(`[${t.fileName}] Analyzed in ${r - e}ms`), N.cacheResults(t.sourceFile, a, n.cachePath, o), { endpoints: o, timing: r - e };
87
+ }, I = (t, n) => {
88
88
  const c = [], s = ["get", "post", "put", "delete", "del", "patch"].join("|");
89
- return o.routers.named.forEach((e) => {
90
- o.sourceFile.forEachChild((t) => {
91
- const r = t.getText();
92
- new RegExp(`${e}\\.(?:${s})`).test(r) && (L(t), c.push(b(t, o.fileName)));
89
+ return t.routers.named.forEach((e) => {
90
+ const o = new RegExp(`${e}\\.(?:${s})`);
91
+ t.sourceFile.forEachChild((r) => {
92
+ const d = r.getText();
93
+ o.test(d) && (L(r), c.push(b(r, t.fileName)));
93
94
  });
94
95
  }), c;
95
- }, B = (o) => {
96
+ }, B = (t) => {
96
97
  const n = E({
97
- sourceFile: o,
98
+ sourceFile: t,
98
99
  originalName: "useApiHeader"
99
100
  });
100
101
  if (!n)
101
102
  return null;
102
- const c = o.forEachChildAsArray().filter((t) => t.isKind(h.ExpressionStatement)).find((t) => n && t.getText().startsWith(n));
103
+ const c = t.forEachChildAsArray().filter((o) => o.isKind(h.ExpressionStatement)).find((o) => n && o.getText().startsWith(n));
103
104
  if (!c)
104
105
  return null;
105
- const a = c.getFirstDescendantByKindOrThrow(h.ObjectLiteralExpression), s = j(a), e = (t) => typeof t == "string" || Array.isArray(t) && t.every((r) => typeof r == "string") ? t : t.reduce((r, d) => typeof d == "string" ? r : {
106
+ const a = c.getFirstDescendantByKindOrThrow(h.ObjectLiteralExpression), s = j(a), e = (o) => typeof o == "string" || Array.isArray(o) && o.every((r) => typeof r == "string") ? o : o.reduce((r, d) => typeof d == "string" ? r : {
106
107
  ...r,
107
108
  [d.identifier]: e(d.value)
108
109
  }, {});
109
110
  return e(s);
110
- }, V = (o) => {
111
+ }, V = (t) => {
111
112
  const n = [], c = E({
112
- sourceFile: o,
113
+ sourceFile: t,
113
114
  originalName: "useExposeApiModel"
114
115
  }), a = E({
115
- sourceFile: o,
116
+ sourceFile: t,
116
117
  originalName: "useExposeNamedApiModels"
117
118
  });
118
- return o.forEachChildAsArray().filter((s) => s.isKind(h.ExpressionStatement)).map((s) => {
119
+ return t.forEachChildAsArray().filter((s) => s.isKind(h.ExpressionStatement)).map((s) => {
119
120
  if (c && s.getText().startsWith(c)) {
120
121
  const r = (s.getFirstChild()?.getChildrenOfKind(h.SyntaxList) || [])[0].getFirstChild();
121
122
  if (!r)
@@ -1 +1 @@
1
- {"version":3,"file":"analyzerModule.mjs","sources":["../../../src/openapi/analyzerModule/analyzerModule.ts"],"sourcesContent":["import * as path from 'path'\nimport { SourceFile, SyntaxKind } from 'ts-morph'\nimport { Project } from 'ts-morph'\n\nimport { Logger } from '../../utils/logger'\nimport { discoverImportedName } from '../discoveryModule/discoverImports/discoverImports'\nimport {\n\tDiscoveredSourceFile,\n\tdiscoverRouterFiles,\n} from '../discoveryModule/discoverRouterFiles/discoverRouterFiles'\nimport { discoverRouters } from '../discoveryModule/discoverRouters/discoverRouters'\nimport { ApiDocsHeader, OpenApiManager } from '../manager/OpenApiManager'\nimport { EndpointData, ExposedModelData } from '../types'\nimport { getSourceFileTimestamp, TimestampCache } from './getSourceFileTimestamp'\nimport { getValuesOfObjectLiteral, resolveEndpointPath } from './nodeParsers'\nimport { parseEndpoint } from './parseEndpoint'\nimport { parseExposedModel, parseNamedExposedModels } from './parseExposedModels'\nimport { SourceFileCache } from './sourceFileCache'\n\ntype Props = {\n\tlogLevel?: Parameters<(typeof Logger)['setLevel']>[0]\n\ttsconfigPath: string\n\tsourceFilePaths?: string[]\n\tsourceFileDiscovery?: boolean | FileDiscoveryConfig\n\tincremental?:\n\t\t| boolean\n\t\t| {\n\t\t\t\tcachePath: string\n\t\t }\n}\n\ntype FileDiscoveryConfig = {\n\trootPath: string\n}\n\n/**\n * @param tsconfigPath Path to tsconfig file relative to project root\n * @param sourceFilePaths Array of router source files relative to project root\n */\nexport const prepareOpenApiSpec = ({\n\tlogLevel,\n\ttsconfigPath,\n\tsourceFilePaths,\n\tsourceFileDiscovery,\n\tincremental,\n}: Props) => {\n\tconst openApiManager = OpenApiManager.getInstance()\n\n\tif (openApiManager.isReady()) {\n\t\treturn\n\t}\n\n\tif (logLevel) {\n\t\tLogger.setLevel(logLevel)\n\t}\n\n\tLogger.info('Preparing OpenAPI spec')\n\n\tconst project = new Project({\n\t\ttsConfigFilePath: path.resolve(tsconfigPath),\n\t\tskipFileDependencyResolution: true,\n\t})\n\n\tconst { explicitRouters, discoveredRouterFiles, allSourceFiles } = (() => {\n\t\tconst sourceFilesToAdd = sourceFilePaths ?? []\n\t\tconst resolvedSourceFilePaths = sourceFilesToAdd.map((filepath) => path.resolve(filepath))\n\t\tconst sourceFiles = resolvedSourceFilePaths.map((filePath) => project.getSourceFileOrThrow(filePath))\n\t\tconst explicitRouters = sourceFiles.flatMap((file) => ({\n\t\t\tfileName: file.getFilePath(),\n\t\t\tsourceFile: file,\n\t\t\trouters: discoverRouters(file),\n\t\t}))\n\n\t\tconst { discoveredRouterFiles, discoveredSourceFiles } = (() => {\n\t\t\tif (sourceFileDiscovery === false) {\n\t\t\t\treturn { discoveredRouterFiles: [], discoveredSourceFiles: [] }\n\t\t\t}\n\n\t\t\tconst startTime = performance.now()\n\t\t\tconst files = discoverRouterFiles({\n\t\t\t\ttargetPath: typeof sourceFileDiscovery === 'object' ? sourceFileDiscovery.rootPath : '.',\n\t\t\t\ttsConfigPath: tsconfigPath,\n\t\t\t})\n\t\t\tLogger.info(`File discovery took ${Math.round(performance.now() - startTime)}ms`)\n\t\t\treturn files\n\t\t})()\n\n\t\tconst allSourceFiles = sourceFiles.reduce(\n\t\t\t(acc, current) =>\n\t\t\t\tacc.some((r) => r.getFilePath() === current.getFilePath()) ? acc : acc.concat(current),\n\t\t\tdiscoveredSourceFiles,\n\t\t)\n\n\t\treturn { explicitRouters, discoveredRouterFiles, allSourceFiles }\n\t})()\n\n\tconst filesToAnalyze = explicitRouters.reduce(\n\t\t(acc, current) => (acc.some((r) => r.fileName === current.fileName) ? acc : acc.concat(current)),\n\t\tdiscoveredRouterFiles,\n\t)\n\n\tconst apiHeaders = allSourceFiles\n\t\t.flatMap((file) => analyzeSourceFileApiHeader(file))\n\t\t.filter((headers) => !!headers)\n\tif (apiHeaders.length > 0 && apiHeaders[0]) {\n\t\topenApiManager.setHeader(apiHeaders[0])\n\t}\n\n\tconst exposedModels = allSourceFiles.flatMap((file) => analyzeSourceFileExposedModels(file))\n\n\topenApiManager.setExposedModels(exposedModels)\n\n\tconst cachePath = (() => {\n\t\tif (typeof incremental === 'object' && incremental.cachePath) {\n\t\t\treturn incremental.cachePath\n\t\t}\n\t\treturn path.resolve(process.cwd(), 'node_modules', '.cache', 'moonflower')\n\t})()\n\tconst endpoints = analyzeMultipleSourceFiles(filesToAnalyze, {\n\t\tincremental: incremental !== false,\n\t\tcachePath,\n\t\ttimestampCache: {},\n\t})\n\n\topenApiManager.setStats({\n\t\tdiscoveredRouterFiles: discoveredRouterFiles.map((file) => ({\n\t\t\tpath: file.fileName,\n\t\t\trouters: file.routers.named.map((r) => ({\n\t\t\t\tname: r,\n\t\t\t\tendpoints: endpoints\n\t\t\t\t\t.filter((e) => e.sourceFilePath === file.fileName)\n\t\t\t\t\t.map((e) => `${e.method.toUpperCase()} ${e.path}`),\n\t\t\t})),\n\t\t})),\n\t\texplicitRouterFiles: explicitRouters.map((file) => ({\n\t\t\tpath: file.fileName,\n\t\t\trouters: file.routers.named.map((r) => ({\n\t\t\t\tname: r,\n\t\t\t\tendpoints: endpoints\n\t\t\t\t\t.filter((e) => e.sourceFilePath === file.fileName)\n\t\t\t\t\t.map((e) => `${e.method.toUpperCase()} ${e.path}`),\n\t\t\t})),\n\t\t})),\n\t})\n\n\topenApiManager.setEndpoints(endpoints)\n\topenApiManager.markAsReady()\n}\n\nexport const analyzeMultipleSourceFiles = (\n\tfiles: DiscoveredSourceFile[],\n\tconfig: {\n\t\tincremental: boolean\n\t\tcachePath: string\n\t\ttimestampCache: TimestampCache\n\t},\n\tfilterEndpointPaths?: string[],\n): EndpointData[] => {\n\tconst startTime = performance.now()\n\tconst analyzedFiles = files.map((file) => analyzeSourceFileWithCache(file, config, filterEndpointPaths))\n\tLogger.info(`Router analysis took ${Math.round(performance.now() - startTime)}ms`)\n\n\tanalyzedFiles\n\t\t.map((f, index) => ({\n\t\t\tfileName: files[index].fileName,\n\t\t\ttimeTaken: f.timing,\n\t\t}))\n\t\t.sort((a, b) => b.timeTaken - a.timeTaken)\n\t\t.filter((t) => t.timeTaken > 500)\n\t\t.forEach((t) => {\n\t\t\tLogger.info(`- [${t.fileName}] Took ${Math.round(t.timeTaken)}ms to analyze`)\n\t\t})\n\n\treturn analyzedFiles.flatMap((f) => f.endpoints)\n}\n\nexport const analyzeSourceFileWithCache = (\n\tfile: DiscoveredSourceFile,\n\tconfig: {\n\t\tincremental: boolean\n\t\tcachePath: string\n\t\ttimestampCache: TimestampCache\n\t},\n\tfilterEndpointPaths?: string[],\n): { endpoints: EndpointData[]; timing: number } => {\n\tconst timestamp = getSourceFileTimestamp(file.sourceFile, config.timestampCache)\n\tconst cachedResults = SourceFileCache.getCachedResults(file.sourceFile, timestamp, config.cachePath)\n\n\tif (cachedResults) {\n\t\tLogger.debug(`[${file.fileName}] Found cached results`)\n\t\treturn { endpoints: cachedResults.endpoints, timing: 0 }\n\t}\n\tLogger.debug(`[${file.fileName}] Analyzing...`)\n\n\tconst t1 = performance.now()\n\tconst endpoints = analyzeSourceFileEndpoints(file, filterEndpointPaths)\n\tconst t2 = performance.now()\n\tLogger.debug(`[${file.fileName}] Analyzed in ${t2 - t1}ms`)\n\tSourceFileCache.cacheResults(file.sourceFile, timestamp, config.cachePath, endpoints)\n\treturn { endpoints, timing: t2 - t1 }\n}\n\nexport const analyzeSourceFileEndpoints = (\n\tfile: DiscoveredSourceFile,\n\tfilterEndpointPaths?: string[],\n): EndpointData[] => {\n\tconst endpoints: EndpointData[] = []\n\tconst operations = ['get', 'post', 'put', 'delete', 'del', 'patch']\n\tconst joinedOperations = operations.join('|')\n\n\tfile.routers.named.forEach((routerName) => {\n\t\tfile.sourceFile.forEachChild((node) => {\n\t\t\tconst nodeText = node.getText()\n\t\t\tconst routerPattern = new RegExp(`${routerName}\\\\.(?:${joinedOperations})`)\n\n\t\t\tif (routerPattern.test(nodeText)) {\n\t\t\t\tconst endpointPath = resolveEndpointPath(node) ?? ''\n\n\t\t\t\tif (filterEndpointPaths && !filterEndpointPaths.some((path) => endpointPath.includes(path))) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tendpoints.push(parseEndpoint(node, file.fileName))\n\t\t\t}\n\t\t})\n\t})\n\n\treturn endpoints\n}\n\nexport const analyzeSourceFileApiHeader = (sourceFile: SourceFile): ApiDocsHeader | null => {\n\tconst nameOfUseApiHeader = discoverImportedName({\n\t\tsourceFile,\n\t\toriginalName: 'useApiHeader',\n\t})\n\n\tif (!nameOfUseApiHeader) {\n\t\treturn null\n\t}\n\n\tconst node = sourceFile\n\t\t.forEachChildAsArray()\n\t\t.filter((node) => node.isKind(SyntaxKind.ExpressionStatement))\n\t\t.find((node) => nameOfUseApiHeader && node.getText().startsWith(nameOfUseApiHeader))\n\n\tif (!node) {\n\t\treturn null\n\t}\n\n\tconst targetNode = node.getFirstDescendantByKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n\tconst values = getValuesOfObjectLiteral(targetNode)\n\n\tconst collapseObject = (v: string | string[] | typeof values): any => {\n\t\tif (typeof v === 'string') {\n\t\t\treturn v\n\t\t}\n\t\tif (Array.isArray(v) && v.every((value) => typeof value === 'string')) {\n\t\t\treturn v\n\t\t}\n\n\t\treturn v.reduce((acc, current) => {\n\t\t\tif (typeof current === 'string') {\n\t\t\t\treturn acc\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...acc,\n\t\t\t\t[current.identifier]: collapseObject(current.value as string[]),\n\t\t\t}\n\t\t}, {})\n\t}\n\treturn collapseObject(values)\n}\n\nexport const analyzeSourceFileExposedModels = (sourceFile: SourceFile): ExposedModelData[] => {\n\tconst models: ExposedModelData[] = []\n\n\tconst nameOfUseExposeApiModel = discoverImportedName({\n\t\tsourceFile,\n\t\toriginalName: 'useExposeApiModel',\n\t})\n\n\tconst nameOfUseExposeNamedApiModels = discoverImportedName({\n\t\tsourceFile,\n\t\toriginalName: 'useExposeNamedApiModels',\n\t})\n\n\tsourceFile\n\t\t.forEachChildAsArray()\n\t\t.filter((node) => node.isKind(SyntaxKind.ExpressionStatement))\n\t\t.map((node) => {\n\t\t\tif (nameOfUseExposeApiModel && node.getText().startsWith(nameOfUseExposeApiModel)) {\n\t\t\t\tconst callExpressionNode = node.getFirstChild()\n\t\t\t\tconst syntaxListChildren = callExpressionNode?.getChildrenOfKind(SyntaxKind.SyntaxList) || []\n\n\t\t\t\tconst firstChild = syntaxListChildren[0].getFirstChild()\n\t\t\t\tif (!firstChild) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tmodels.push(parseExposedModel(firstChild))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (nameOfUseExposeNamedApiModels && node.getText().startsWith(nameOfUseExposeNamedApiModels)) {\n\t\t\t\tconst callExpressionNode = node.getFirstChild()\n\t\t\t\tconst syntaxListChildren = callExpressionNode?.getChildrenOfKind(SyntaxKind.SyntaxList) || []\n\n\t\t\t\tconst firstChild = syntaxListChildren[0].getFirstChild()\n\t\t\t\tif (!firstChild) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst parsedModels = parseNamedExposedModels(firstChild)\n\t\t\t\tparsedModels.forEach((model) => models.push(model))\n\t\t\t}\n\t\t})\n\treturn models\n}\n"],"names":["prepareOpenApiSpec","logLevel","tsconfigPath","sourceFilePaths","sourceFileDiscovery","incremental","openApiManager","OpenApiManager","Logger","project","Project","path","explicitRouters","discoveredRouterFiles","allSourceFiles","sourceFiles","filepath","filePath","file","discoverRouters","discoveredSourceFiles","startTime","files","discoverRouterFiles","acc","current","r","filesToAnalyze","apiHeaders","analyzeSourceFileApiHeader","headers","exposedModels","analyzeSourceFileExposedModels","cachePath","endpoints","analyzeMultipleSourceFiles","e","config","filterEndpointPaths","analyzedFiles","analyzeSourceFileWithCache","f","index","a","b","t","timestamp","getSourceFileTimestamp","cachedResults","SourceFileCache","t1","analyzeSourceFileEndpoints","t2","joinedOperations","routerName","node","nodeText","resolveEndpointPath","parseEndpoint","sourceFile","nameOfUseApiHeader","discoverImportedName","SyntaxKind","targetNode","values","getValuesOfObjectLiteral","collapseObject","v","value","models","nameOfUseExposeApiModel","nameOfUseExposeNamedApiModels","firstChild","parseExposedModel","parseNamedExposedModels","model"],"mappings":"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"}
1
+ {"version":3,"file":"analyzerModule.mjs","sources":["../../../src/openapi/analyzerModule/analyzerModule.ts"],"sourcesContent":["import * as path from 'path'\nimport { SourceFile, SyntaxKind } from 'ts-morph'\nimport { Project } from 'ts-morph'\n\nimport { Logger } from '../../utils/logger'\nimport { discoverImportedName } from '../discoveryModule/discoverImports/discoverImports'\nimport {\n\tDiscoveredSourceFile,\n\tdiscoverRouterFiles,\n} from '../discoveryModule/discoverRouterFiles/discoverRouterFiles'\nimport { discoverRouters } from '../discoveryModule/discoverRouters/discoverRouters'\nimport { ApiDocsHeader, OpenApiManager } from '../manager/OpenApiManager'\nimport { EndpointData, ExposedModelData } from '../types'\nimport { getSourceFileTimestamp, TimestampCache } from './getSourceFileTimestamp'\nimport { getValuesOfObjectLiteral, resolveEndpointPath } from './nodeParsers'\nimport { parseEndpoint } from './parseEndpoint'\nimport { parseExposedModel, parseNamedExposedModels } from './parseExposedModels'\nimport { SourceFileCache } from './sourceFileCache'\n\ntype Props = {\n\tlogLevel?: Parameters<(typeof Logger)['setLevel']>[0]\n\ttsconfigPath: string\n\tsourceFilePaths?: string[]\n\tsourceFileDiscovery?: boolean | FileDiscoveryConfig\n\tincremental?:\n\t\t| boolean\n\t\t| {\n\t\t\t\tcachePath: string\n\t\t }\n}\n\ntype FileDiscoveryConfig = {\n\trootPath: string\n}\n\n/**\n * @param tsconfigPath Path to tsconfig file relative to project root\n * @param sourceFilePaths Array of router source files relative to project root\n */\nexport const prepareOpenApiSpec = ({\n\tlogLevel,\n\ttsconfigPath,\n\tsourceFilePaths,\n\tsourceFileDiscovery,\n\tincremental,\n}: Props) => {\n\tconst openApiManager = OpenApiManager.getInstance()\n\n\tif (openApiManager.isReady()) {\n\t\treturn\n\t}\n\n\tif (logLevel) {\n\t\tLogger.setLevel(logLevel)\n\t}\n\n\tLogger.info('Preparing OpenAPI spec')\n\n\tconst project = new Project({\n\t\ttsConfigFilePath: path.resolve(tsconfigPath),\n\t\tskipFileDependencyResolution: true,\n\t})\n\n\tconst { explicitRouters, discoveredRouterFiles, allSourceFiles } = (() => {\n\t\tconst sourceFilesToAdd = sourceFilePaths ?? []\n\t\tconst resolvedSourceFilePaths = sourceFilesToAdd.map((filepath) => path.resolve(filepath))\n\t\tconst sourceFiles = resolvedSourceFilePaths.map((filePath) => project.getSourceFileOrThrow(filePath))\n\t\tconst explicitRouters = sourceFiles.flatMap((file) => ({\n\t\t\tfileName: file.getFilePath(),\n\t\t\tsourceFile: file,\n\t\t\trouters: discoverRouters(file),\n\t\t}))\n\n\t\tconst { discoveredRouterFiles, discoveredSourceFiles } = (() => {\n\t\t\tif (sourceFileDiscovery === false) {\n\t\t\t\treturn { discoveredRouterFiles: [], discoveredSourceFiles: [] }\n\t\t\t}\n\n\t\t\tconst startTime = performance.now()\n\t\t\tconst files = discoverRouterFiles({\n\t\t\t\ttargetPath: typeof sourceFileDiscovery === 'object' ? sourceFileDiscovery.rootPath : '.',\n\t\t\t\ttsConfigPath: tsconfigPath,\n\t\t\t})\n\t\t\tLogger.info(`File discovery took ${Math.round(performance.now() - startTime)}ms`)\n\t\t\treturn files\n\t\t})()\n\n\t\tconst allSourceFiles = sourceFiles.reduce(\n\t\t\t(acc, current) =>\n\t\t\t\tacc.some((r) => r.getFilePath() === current.getFilePath()) ? acc : acc.concat(current),\n\t\t\tdiscoveredSourceFiles,\n\t\t)\n\n\t\treturn { explicitRouters, discoveredRouterFiles, allSourceFiles }\n\t})()\n\n\tconst filesToAnalyze = explicitRouters.reduce(\n\t\t(acc, current) => (acc.some((r) => r.fileName === current.fileName) ? acc : acc.concat(current)),\n\t\tdiscoveredRouterFiles,\n\t)\n\n\tconst apiHeaders = allSourceFiles\n\t\t.flatMap((file) => analyzeSourceFileApiHeader(file))\n\t\t.filter((headers) => !!headers)\n\tif (apiHeaders.length > 0 && apiHeaders[0]) {\n\t\topenApiManager.setHeader(apiHeaders[0])\n\t}\n\n\tconst exposedModels = allSourceFiles.flatMap((file) => analyzeSourceFileExposedModels(file))\n\n\topenApiManager.setExposedModels(exposedModels)\n\n\tconst cachePath = (() => {\n\t\tif (typeof incremental === 'object' && incremental.cachePath) {\n\t\t\treturn incremental.cachePath\n\t\t}\n\t\treturn path.resolve(process.cwd(), 'node_modules', '.cache', 'moonflower')\n\t})()\n\tconst endpoints = analyzeMultipleSourceFiles(filesToAnalyze, {\n\t\tincremental: incremental !== false,\n\t\tcachePath,\n\t\ttimestampCache: {},\n\t})\n\n\topenApiManager.setStats({\n\t\tdiscoveredRouterFiles: discoveredRouterFiles.map((file) => ({\n\t\t\tpath: file.fileName,\n\t\t\trouters: file.routers.named.map((r) => ({\n\t\t\t\tname: r,\n\t\t\t\tendpoints: endpoints\n\t\t\t\t\t.filter((e) => e.sourceFilePath === file.fileName)\n\t\t\t\t\t.map((e) => `${e.method.toUpperCase()} ${e.path}`),\n\t\t\t})),\n\t\t})),\n\t\texplicitRouterFiles: explicitRouters.map((file) => ({\n\t\t\tpath: file.fileName,\n\t\t\trouters: file.routers.named.map((r) => ({\n\t\t\t\tname: r,\n\t\t\t\tendpoints: endpoints\n\t\t\t\t\t.filter((e) => e.sourceFilePath === file.fileName)\n\t\t\t\t\t.map((e) => `${e.method.toUpperCase()} ${e.path}`),\n\t\t\t})),\n\t\t})),\n\t})\n\n\topenApiManager.setEndpoints(endpoints)\n\topenApiManager.markAsReady()\n}\n\nexport const analyzeMultipleSourceFiles = (\n\tfiles: DiscoveredSourceFile[],\n\tconfig: {\n\t\tincremental: boolean\n\t\tcachePath: string\n\t\ttimestampCache: TimestampCache\n\t},\n\tfilterEndpointPaths?: string[],\n): EndpointData[] => {\n\tconst startTime = performance.now()\n\tconst analyzedFiles = files.map((file) => analyzeSourceFileWithCache(file, config, filterEndpointPaths))\n\tLogger.info(`Router analysis took ${Math.round(performance.now() - startTime)}ms`)\n\n\tanalyzedFiles\n\t\t.map((f, index) => ({\n\t\t\tfileName: files[index].fileName,\n\t\t\ttimeTaken: f.timing,\n\t\t}))\n\t\t.sort((a, b) => b.timeTaken - a.timeTaken)\n\t\t.filter((t) => t.timeTaken > 500)\n\t\t.forEach((t) => {\n\t\t\tLogger.info(`- [${t.fileName}] Took ${Math.round(t.timeTaken)}ms to analyze`)\n\t\t})\n\n\treturn analyzedFiles.flatMap((f) => f.endpoints)\n}\n\nexport const analyzeSourceFileWithCache = (\n\tfile: DiscoveredSourceFile,\n\tconfig: {\n\t\tincremental: boolean\n\t\tcachePath: string\n\t\ttimestampCache: TimestampCache\n\t},\n\tfilterEndpointPaths?: string[],\n): { endpoints: EndpointData[]; timing: number } => {\n\tconst timestamp = getSourceFileTimestamp(file.sourceFile, config.timestampCache)\n\tconst cachedResults = SourceFileCache.getCachedResults(file.sourceFile, timestamp, config.cachePath)\n\n\tif (cachedResults) {\n\t\tLogger.debug(`[${file.fileName}] Found cached results`)\n\t\treturn { endpoints: cachedResults.endpoints, timing: 0 }\n\t}\n\tLogger.debug(`[${file.fileName}] Analyzing...`)\n\n\tconst t1 = performance.now()\n\tconst endpoints = analyzeSourceFileEndpoints(file, filterEndpointPaths)\n\tconst t2 = performance.now()\n\tLogger.debug(`[${file.fileName}] Analyzed in ${t2 - t1}ms`)\n\tSourceFileCache.cacheResults(file.sourceFile, timestamp, config.cachePath, endpoints)\n\treturn { endpoints, timing: t2 - t1 }\n}\n\nexport const analyzeSourceFileEndpoints = (\n\tfile: DiscoveredSourceFile,\n\tfilterEndpointPaths?: string[],\n): EndpointData[] => {\n\tconst endpoints: EndpointData[] = []\n\tconst operations = ['get', 'post', 'put', 'delete', 'del', 'patch']\n\tconst joinedOperations = operations.join('|')\n\n\tfile.routers.named.forEach((routerName) => {\n\t\tconst routerPattern = new RegExp(`${routerName}\\\\.(?:${joinedOperations})`)\n\t\tfile.sourceFile.forEachChild((node) => {\n\t\t\tconst nodeText = node.getText()\n\n\t\t\tif (routerPattern.test(nodeText)) {\n\t\t\t\tconst endpointPath = resolveEndpointPath(node) ?? ''\n\n\t\t\t\tif (filterEndpointPaths && !filterEndpointPaths.some((path) => endpointPath.includes(path))) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tendpoints.push(parseEndpoint(node, file.fileName))\n\t\t\t}\n\t\t})\n\t})\n\n\treturn endpoints\n}\n\nexport const analyzeSourceFileApiHeader = (sourceFile: SourceFile): ApiDocsHeader | null => {\n\tconst nameOfUseApiHeader = discoverImportedName({\n\t\tsourceFile,\n\t\toriginalName: 'useApiHeader',\n\t})\n\n\tif (!nameOfUseApiHeader) {\n\t\treturn null\n\t}\n\n\tconst node = sourceFile\n\t\t.forEachChildAsArray()\n\t\t.filter((node) => node.isKind(SyntaxKind.ExpressionStatement))\n\t\t.find((node) => nameOfUseApiHeader && node.getText().startsWith(nameOfUseApiHeader))\n\n\tif (!node) {\n\t\treturn null\n\t}\n\n\tconst targetNode = node.getFirstDescendantByKindOrThrow(SyntaxKind.ObjectLiteralExpression)\n\tconst values = getValuesOfObjectLiteral(targetNode)\n\n\tconst collapseObject = (v: string | string[] | typeof values): any => {\n\t\tif (typeof v === 'string') {\n\t\t\treturn v\n\t\t}\n\t\tif (Array.isArray(v) && v.every((value) => typeof value === 'string')) {\n\t\t\treturn v\n\t\t}\n\n\t\treturn v.reduce((acc, current) => {\n\t\t\tif (typeof current === 'string') {\n\t\t\t\treturn acc\n\t\t\t}\n\t\t\treturn {\n\t\t\t\t...acc,\n\t\t\t\t[current.identifier]: collapseObject(current.value as string[]),\n\t\t\t}\n\t\t}, {})\n\t}\n\treturn collapseObject(values)\n}\n\nexport const analyzeSourceFileExposedModels = (sourceFile: SourceFile): ExposedModelData[] => {\n\tconst models: ExposedModelData[] = []\n\n\tconst nameOfUseExposeApiModel = discoverImportedName({\n\t\tsourceFile,\n\t\toriginalName: 'useExposeApiModel',\n\t})\n\n\tconst nameOfUseExposeNamedApiModels = discoverImportedName({\n\t\tsourceFile,\n\t\toriginalName: 'useExposeNamedApiModels',\n\t})\n\n\tsourceFile\n\t\t.forEachChildAsArray()\n\t\t.filter((node) => node.isKind(SyntaxKind.ExpressionStatement))\n\t\t.map((node) => {\n\t\t\tif (nameOfUseExposeApiModel && node.getText().startsWith(nameOfUseExposeApiModel)) {\n\t\t\t\tconst callExpressionNode = node.getFirstChild()\n\t\t\t\tconst syntaxListChildren = callExpressionNode?.getChildrenOfKind(SyntaxKind.SyntaxList) || []\n\n\t\t\t\tconst firstChild = syntaxListChildren[0].getFirstChild()\n\t\t\t\tif (!firstChild) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tmodels.push(parseExposedModel(firstChild))\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tif (nameOfUseExposeNamedApiModels && node.getText().startsWith(nameOfUseExposeNamedApiModels)) {\n\t\t\t\tconst callExpressionNode = node.getFirstChild()\n\t\t\t\tconst syntaxListChildren = callExpressionNode?.getChildrenOfKind(SyntaxKind.SyntaxList) || []\n\n\t\t\t\tconst firstChild = syntaxListChildren[0].getFirstChild()\n\t\t\t\tif (!firstChild) {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tconst parsedModels = parseNamedExposedModels(firstChild)\n\t\t\t\tparsedModels.forEach((model) => models.push(model))\n\t\t\t}\n\t\t})\n\treturn models\n}\n"],"names":["prepareOpenApiSpec","logLevel","tsconfigPath","sourceFilePaths","sourceFileDiscovery","incremental","openApiManager","OpenApiManager","Logger","project","Project","path","explicitRouters","discoveredRouterFiles","allSourceFiles","sourceFiles","filepath","filePath","file","discoverRouters","discoveredSourceFiles","startTime","files","discoverRouterFiles","acc","current","r","filesToAnalyze","apiHeaders","analyzeSourceFileApiHeader","headers","exposedModels","analyzeSourceFileExposedModels","cachePath","endpoints","analyzeMultipleSourceFiles","e","config","filterEndpointPaths","analyzedFiles","analyzeSourceFileWithCache","f","index","a","b","t","timestamp","getSourceFileTimestamp","cachedResults","SourceFileCache","t1","analyzeSourceFileEndpoints","t2","joinedOperations","routerName","routerPattern","node","nodeText","resolveEndpointPath","parseEndpoint","sourceFile","nameOfUseApiHeader","discoverImportedName","SyntaxKind","targetNode","values","getValuesOfObjectLiteral","collapseObject","v","value","models","nameOfUseExposeApiModel","nameOfUseExposeNamedApiModels","firstChild","parseExposedModel","parseNamedExposedModels","model"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("ts-morph"),x=require("../../utils/logger.cjs"),j=require("../manager/OpenApiManager.cjs"),L=new WeakMap,_=new WeakMap,R=new WeakMap,c=e=>{const n=L.get(e);if(n)return n;if(e.getKind()===t.SyntaxKind.Identifier){const i=e.asKind(t.SyntaxKind.Identifier).getImplementations()[0]?.getNode();if(i){const o=i.getParent().getLastChild();if(o===e)throw new Error("Recursive implementation found");const g=c(o);return L.set(e,g),g}const r=e.asKind(t.SyntaxKind.Identifier).getDefinitions()[0]?.getNode();if(r){const o=r.getParent().getLastChild();if(o===e)throw new Error("Recursive implementation found");const g=c(o);return L.set(e,g),g}throw new Error("No implementation nor definition available")}return L.set(e,e),e},N=e=>{const n=e.getChildrenOfKind(t.SyntaxKind.Identifier);return n.length===2?c(n[1]):e.getChildren().reverse().find(r=>r.getKind()!==t.SyntaxKind.GreaterThanToken&&r.getKind()!==t.SyntaxKind.CommaToken&&r.getKind()!==t.SyntaxKind.SemicolonToken)},b=e=>{const n=e.getFirstChildByKind(t.SyntaxKind.SyntaxList);return n.isKind(t.SyntaxKind.SyntaxList)?f(n.getFirstChild()):f(n)},f=e=>{const n=_.get(e);if(n!==void 0)return n;const i=M(e);return _.set(e,i),i},M=e=>{const n=e.getSymbol()?.getName();if(n&&j.OpenApiManager.getInstance().hasExposedModel(n))return[{role:"ref",shape:n,optional:!1}];const i=c(e);if(i.asKind(t.SyntaxKind.UndefinedKeyword))return"undefined";const l=i.asKind(t.SyntaxKind.LiteralType);if(l){if(l.getFirstChildByKind(t.SyntaxKind.TrueKeyword))return"true";if(l.getFirstChildByKind(t.SyntaxKind.FalseKeyword))return"false"}if(i.asKind(t.SyntaxKind.BooleanKeyword)||i.asKind(t.SyntaxKind.TrueKeyword)||i.asKind(t.SyntaxKind.FalseKeyword))return"boolean";if(i.asKind(t.SyntaxKind.StringKeyword)||i.asKind(t.SyntaxKind.StringLiteral))return"string";if(i.asKind(t.SyntaxKind.NumberKeyword)||i.asKind(t.SyntaxKind.NumericLiteral))return"number";if(i.asKind(t.SyntaxKind.BigIntKeyword)||i.asKind(t.SyntaxKind.BigIntLiteral))return"bigint";const s=i.asKind(t.SyntaxKind.TypeLiteral);if(s)return s.getFirstChildByKind(t.SyntaxKind.SyntaxList).getChildrenOfKind(t.SyntaxKind.PropertySignature).map(O=>{const v=O.getFirstChildByKind(t.SyntaxKind.Identifier),V=N(O),D=v.getNextSiblingIfKind(t.SyntaxKind.QuestionToken);return{role:"property",identifier:v.getText(),shape:f(V),optional:V.getType().isNullable()||!!D}});const y=i.asKind(t.SyntaxKind.TypeReference);if(y)return f(y.getFirstChild());if(i.asKind(t.SyntaxKind.PropertyAccessExpression)){const w=c(i.getLastChild());return u(w.asKind(t.SyntaxKind.CallExpression).getReturnType(),w)}const K=i.asKind(t.SyntaxKind.UnionType);if(K)return u(K.getType(),i);const A=i.asKind(t.SyntaxKind.TypeQuery);if(A)return f(A.getLastChild());const F=i.asKind(t.SyntaxKind.QualifiedName);if(F)return f(F.getLastChild());const T=i.asKind(t.SyntaxKind.CallExpression);if(T)return u(T.getReturnType(),T);const I=i.asKind(t.SyntaxKind.AwaitExpression);if(I)return f(I.getChildAtIndex(1));const k=i.asKind(t.SyntaxKind.AsExpression);if(k)return f(k.getChildAtIndex(2));const U=i.getSourceFile().getFilePath().split("/").pop();return x.Logger.warn(`[${U}] Unknown node type: ${i.getKindName()}`),"unknown_1"},$=e=>e.getFirstDescendantByKind(t.SyntaxKind.SyntaxList).getChildrenOfKind(t.SyntaxKind.PropertyAssignment).map(l=>{const o=l.getFirstChild(),g=(()=>{if(o.isKind(t.SyntaxKind.Identifier))return o.getText();if(o.isKind(t.SyntaxKind.StringLiteral))return o.getLiteralText();const s=l.getSourceFile().getFilePath().split("/").pop();return x.Logger.warn(`[${s}] Unknown identifier name: ${o.getText()}`),"unknown_30"})(),a=l.getLastChild(),d=c(a);return{role:"property",identifier:g,shape:m(d),optional:B(d),description:h(d,"description"),errorMessage:h(d,"errorMessage")}})||[],S=e=>{const n=e.asKind(t.SyntaxKind.CallExpression);return n?(n.getReturnType().getSymbol()?.getName()??"").startsWith("Zod"):!1},C=e=>{const n=e.asKind(t.SyntaxKind.CallExpression),i=n.getReturnType(),r=i.getSymbol()?.getName()??"";if(r==="ZodNumber")return"number";if(r==="ZodString")return"string";if(r==="ZodBoolean")return"boolean";if(r==="ZodBigInt")return"bigint";if(r==="ZodObject"){const g=n.getFirstChildByKind(t.SyntaxKind.SyntaxList)?.getFirstChild()?.asKind(t.SyntaxKind.ObjectLiteralExpression);if(!g)return"unknown_zod_object";const a=g.getFirstChildByKind(t.SyntaxKind.SyntaxList);return a?a.getChildrenOfKind(t.SyntaxKind.PropertyAssignment).map(s=>{const y=s.getFirstChildByKind(t.SyntaxKind.Identifier).getText(),p=s.getLastChild();return{role:"property",identifier:y,shape:S(p)?C(p):m(p),optional:!1}}):[]}if(r==="ZodArray"){const o=n.getFirstChildByKind(t.SyntaxKind.SyntaxList)?.getFirstChild();if(o)return[{role:"array",shape:S(o)?C(o):m(o),optional:!1}];const a=n.getFirstChildByKind(t.SyntaxKind.PropertyAccessExpression)?.getFirstChildByKind(t.SyntaxKind.CallExpression);return a&&S(a)?[{role:"array",shape:C(a),optional:!1}]:"unknown_zod_array"}if(r==="ZodEnum"){const o=i.getTypeArguments();if(o.length>0){const d=o[0].getProperties().map(s=>({role:"union_entry",shape:u(s.getTypeAtLocation(n),n,[]),optional:!1}));if(d.length===1)return d[0].shape;if(d.length>1)return[{role:"union",shape:d,optional:!1}]}return"unknown_zod_enum"}if(r==="ZodOptional"){const o=n.getFirstChildByKind(t.SyntaxKind.PropertyAccessExpression)?.getFirstChildByKind(t.SyntaxKind.CallExpression);return o&&S(o)?C(o):"unknown_zod_optional"}const l=e.getSourceFile().getFilePath().split("/").pop();return x.Logger.warn(`[${l}] Unknown zod type: ${r}`),"unknown_zod"},m=e=>{if(S(e))return C(e);const n=e.getParent().getFirstChildByKind(t.SyntaxKind.AsExpression);if(n){const s=n.getLastChildByKind(t.SyntaxKind.TypeReference);return b(s)}const i=e.getParent().getFirstChildByKind(t.SyntaxKind.TypeReference);if(i)return b(i);if(e.getParent().getChildrenOfKind(t.SyntaxKind.SyntaxList).length>=2){const s=e.getParent().getFirstChildByKind(t.SyntaxKind.SyntaxList).getFirstChild();return f(s)}const r=e.getParent().getFirstChildByKind(t.SyntaxKind.CallExpression);if(r){const s=c(r.getFirstChildByKind(t.SyntaxKind.SyntaxList).getFirstChild()),y=s.getParent().getFirstChildByKind(t.SyntaxKind.TypeReference);if(y)return u(y.getType(),y,[]);const p=s.getParent().getFirstChildByKind(t.SyntaxKind.ObjectLiteralExpression);if(p)return m(p);if(s.getKind()===t.SyntaxKind.CallExpression||s.getKind()===t.SyntaxKind.IntersectionType)return m(s);const K=e.getSourceFile().getFilePath().split("/").pop();return x.Logger.warn(`[${K}] Unknown call expression argument: ${s.getKindName()}`),"unknown_3"}const o=e.getFirstChildByKind(t.SyntaxKind.SyntaxList).getChildrenOfKind(t.SyntaxKind.PropertyAssignment).find(s=>s.getFirstChildByKind(t.SyntaxKind.Identifier)?.getText()==="parse");if(o){const s=N(o).asKind(t.SyntaxKind.ArrowFunction).getReturnType();return u(s,o)}const g=e.getFirstChildByKind(t.SyntaxKind.SyntaxList)?.getFirstChildByKind(t.SyntaxKind.ImportType);if(g){const s=g.getLastChildByKind(t.SyntaxKind.GreaterThanToken).getChildIndex(),y=g.getChildAtIndex(s-1);return f(y.getFirstChild())}const a=e.isKind(t.SyntaxKind.IntersectionType)?e:e.getParent()?.isKind(t.SyntaxKind.VariableDeclaration)?e.getParent()?.getFirstChildByKind(t.SyntaxKind.IntersectionType):null;if(a){const s=a.getFirstChildByKind(t.SyntaxKind.TypeReference);if(s)return b(s)}const d=e.getSourceFile().getFilePath().split("/").pop();return x.Logger.warn(`[${d}] Unknown import type node`),"unknown_2"},B=e=>{if(S(e))return(e.asKind(t.SyntaxKind.CallExpression).getReturnType().getSymbol()?.getName()??"")==="ZodOptional";const n=e.asKind(t.SyntaxKind.CallExpression);if(n){const l=n.getFirstChildByKind(t.SyntaxKind.Identifier);if(l?.getText()==="OptionalParam")return!0;if(l?.getText()==="RequiredParam")return!1;const o=n.getFirstChildByKind(t.SyntaxKind.SyntaxList),g=c(o.getFirstChild());return B(g)}return e.getFirstDescendantByKind(t.SyntaxKind.SyntaxList).getChildrenOfKind(t.SyntaxKind.PropertyAssignment).some(l=>l.getFirstDescendantByKind(t.SyntaxKind.Identifier).getText()==="optional"?N(l).getKind()===t.SyntaxKind.TrueKeyword:!1)},h=(e,n)=>{if(S(e))return"";const i=c(e),r=i.asKind(t.SyntaxKind.CallExpression);if(r){const y=r.getLastChildByKind(t.SyntaxKind.SyntaxList);return h(y,n)}const l=i.asKind(t.SyntaxKind.SyntaxList);if(l)return l.getChildren().map(p=>h(p,n)).find(p=>!!p&&p!=="unknown_25")||"";const o=i.asKind(t.SyntaxKind.ObjectLiteralExpression);if(o){const p=E(o).find(K=>K.identifier===n);return p?Array.isArray(p.value)?"array":p.value||"":""}const g=i.asKind(t.SyntaxKind.IntersectionType);if(g)return g.getTypeNodes().flatMap(y=>h(y,n)).filter(y=>!!y&&y!=="unknown_25")[0]||"unknown_27";const a=i.asKind(t.SyntaxKind.TypeLiteral);if(a)return h(a.getFirstChildByKind(t.SyntaxKind.SyntaxList),n);const d=i.asKind(t.SyntaxKind.PropertySignature);if(d&&i.getFirstDescendantByKind(t.SyntaxKind.Identifier).getText()===n)return N(d).getFirstDescendantByKind(t.SyntaxKind.StringLiteral).getLiteralText();const s=i.getSourceFile().getFilePath().split("/").pop();return x.Logger.dev(`[${s}] Unknown property string value node ${i.getKindName()}`),"unknown_25"},Z=e=>{const n=e.getSymbol();if(!e.isObject()||!n)return!1;const i=e.getTypeArguments();return n.getName()==="Promise"&&i.length===1},u=(e,n,i=[])=>{const r=e.getAliasSymbol()?.getName();if(r&&j.OpenApiManager.getInstance().hasExposedModel(r))return[{role:"ref",shape:r,optional:!1}];const l=Z(e)?e.getTypeArguments()[0]:e;if(i.some(d=>d===l))return"circular";const o=l.compilerType,g=R.get(o);if(g!==void 0)return g;const a=q(l,n,i);return R.set(o,a),a},q=(e,n,i)=>{const r=i.concat(e);if(e.getText()==="void")return"void";if(e.isAny())return"any";if(e.isUnknown())return"unknown";if(e.isNull())return"null";if(e.isUndefined())return"undefined";if(e.isBoolean()||e.isBooleanLiteral())return"boolean";if(e.isStringLiteral())return[{role:"literal_string",shape:String(e.getLiteralValue()),optional:!1}];if(e.isNumberLiteral())return[{role:"literal_number",shape:String(e.getLiteralValue()),optional:!1}];if(e.isString()||e.isTemplateLiteral())return"string";if(e.isNumber())return"number";if(e.getText()==="bigint")return"bigint";if(e.isTuple())return[{role:"tuple",shape:e.getTupleElements().map(a=>({role:"tuple_entry",shape:u(a,n,r),optional:!1})),optional:!1}];if(e.isArray())return[{role:"array",shape:u(e.getArrayElementType(),n,r),optional:!1}];if(e.isObject()){const a=e.getNumberIndexType(),s=e.getBaseTypes()?.find(y=>y.isArray());if(s)return[{role:"array",shape:u(s.getArrayElementType()??a,n,r),optional:!1}]}const l=e.getSymbol()?.getName(),o=new Set(["Buffer","Uint8Array","Int8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array","ArrayBuffer","SharedArrayBuffer","ReadableStream"]);if(e.isObject()&&l&&o.has(l))return[{role:"buffer",shape:"buffer",optional:!1}];if(e.isObject()&&l==="RegExp")return"string";if(e.isObject()&&l==="Map"){const d=e.getTypeArguments()[1];return[{role:"record",shape:d?u(d,n,r):"unknown",optional:!1}]}if(e.isObject()&&l==="Set"){const d=e.getTypeArguments()[0];return[{role:"array",shape:d?u(d,n,r):"unknown",optional:!1}]}if(e.isObject()&&e.getProperties().length===0){const a=e.getAliasTypeArguments()[1]??e.getStringIndexType();if(a)return[{role:"record",shape:u(a,n,r),optional:!1}]}if(e.isObject())return l==="Date"||e.getText()==="Date"?"Date":e.getProperties().map(a=>{const d=a.getValueDeclaration()||a.getDeclarations()[0];if(!d)return{role:"property",identifier:a.getName(),shape:u(a.getTypeAtLocation(n),n,r),optional:!1};if(!(d.asKind(t.SyntaxKind.PropertySignature)||d.asKind(t.SyntaxKind.PropertyAssignment)||d.asKind(t.SyntaxKind.ShorthandPropertyAssignment)))return{role:"property",identifier:a.getName(),shape:u(a.getTypeAtLocation(n),n,r),optional:!1};const y=a.getTypeAtLocation(n).isNullable(),p=u(a.getTypeAtLocation(n),n,r);return{role:"property",identifier:a.getName(),shape:p,optional:y}}).filter(a=>a.shape!=="undefined");if(e.isUnion()){const d=e.getUnionTypes().map(p=>({role:"union_entry",shape:u(p,n,r),optional:!1})).filter((p,K,A)=>!A.find((F,T)=>F.shape===p.shape&&T>K)),s=d.some(p=>p.shape==="undefined"),y=d.filter(p=>p.shape!=="undefined");return y.length===1?y[0].shape:[{role:"union",shape:y,optional:s}]}if(e.isIntersection())return e.getIntersectionTypes().map(s=>u(s,n,r)).filter(s=>typeof s!="string").reduce((s,y)=>[...s,...y],[]);const g=n.getSourceFile().getFilePath().split("/").pop();return x.Logger.warn(`[${g}] Unknown type shape node ${e.getText()}`),"unknown_5"},P=e=>{if(e.isKind(t.SyntaxKind.Identifier))return P(c(e));if(e.isKind(t.SyntaxKind.StringLiteral))return e.getLiteralValue();if(e.isKind(t.SyntaxKind.ArrayLiteralExpression))return e.forEachChildAsArray().map(i=>P(i));if(e.isKind(t.SyntaxKind.PropertyAccessExpression))return P(N(e));if(e.isKind(t.SyntaxKind.ObjectLiteralExpression))return E(e);const n=e.getSourceFile().getFilePath().split("/").pop();return x.Logger.dev(`[${n}] Unknown literal value node ${e.getKindName()}`),"unknown_6"},z=e=>{const n=e.getFirstDescendantByKind(t.SyntaxKind.CallExpression);if(!n)return null;const i=n.getArguments()[0];if(!i)return null;const r=i.getType();return r.isStringLiteral()?r.getLiteralValue():null},E=e=>e.getFirstDescendantByKind(t.SyntaxKind.SyntaxList).getChildrenOfKind(t.SyntaxKind.PropertyAssignment).map(l=>{const g=l.getFirstDescendantByKind(t.SyntaxKind.Identifier).getText(),a=l.getLastChild(),d=c(a),s=P(d);return{identifier:g,value:s}})||[];exports.findNodeImplementation=c;exports.findPropertyAssignmentValueNode=N;exports.getProperTypeShape=u;exports.getRecursiveNodeShape=f;exports.getShapeOfValidatorLiteral=$;exports.getTypeReferenceShape=b;exports.getValidatorPropertyOptionality=B;exports.getValidatorPropertyShape=m;exports.getValidatorPropertyStringValue=h;exports.getValuesOfObjectLiteral=E;exports.resolveEndpointPath=z;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("ts-morph"),x=require("../../utils/logger.cjs"),j=require("../manager/OpenApiManager.cjs"),L=new WeakMap,_=new WeakMap,R=new WeakMap,c=e=>{const n=L.get(e);if(n)return n;if(e.getKind()===t.SyntaxKind.Identifier){const i=e.asKind(t.SyntaxKind.Identifier).getImplementations()[0]?.getNode();if(i){const o=i.getParent().getLastChild();if(o===e)throw new Error("Recursive implementation found");const g=c(o);return L.set(e,g),g}const s=e.asKind(t.SyntaxKind.Identifier).getDefinitions()[0]?.getNode();if(s){const o=s.getParent().getLastChild();if(o===e)throw new Error("Recursive implementation found");const g=c(o);return L.set(e,g),g}throw new Error("No implementation nor definition available")}return L.set(e,e),e},N=e=>{const n=e.getChildrenOfKind(t.SyntaxKind.Identifier);return n.length===2?c(n[1]):e.getChildren().reverse().find(s=>s.getKind()!==t.SyntaxKind.GreaterThanToken&&s.getKind()!==t.SyntaxKind.CommaToken&&s.getKind()!==t.SyntaxKind.SemicolonToken)},b=e=>{const n=e.getFirstChildByKind(t.SyntaxKind.SyntaxList);return n.isKind(t.SyntaxKind.SyntaxList)?f(n.getFirstChild()):f(n)},f=e=>{const n=_.get(e);if(n!==void 0)return n;const i=M(e);return _.set(e,i),i},M=e=>{const n=e.getSymbol()?.getName();if(n&&j.OpenApiManager.getInstance().hasExposedModel(n))return[{role:"ref",shape:n,optional:!1}];const i=c(e);if(i.asKind(t.SyntaxKind.UndefinedKeyword))return"undefined";const l=i.asKind(t.SyntaxKind.LiteralType);if(l){if(l.getFirstChildByKind(t.SyntaxKind.TrueKeyword))return"true";if(l.getFirstChildByKind(t.SyntaxKind.FalseKeyword))return"false"}if(i.asKind(t.SyntaxKind.BooleanKeyword)||i.asKind(t.SyntaxKind.TrueKeyword)||i.asKind(t.SyntaxKind.FalseKeyword))return"boolean";if(i.asKind(t.SyntaxKind.StringKeyword)||i.asKind(t.SyntaxKind.StringLiteral))return"string";if(i.asKind(t.SyntaxKind.NumberKeyword)||i.asKind(t.SyntaxKind.NumericLiteral))return"number";if(i.asKind(t.SyntaxKind.BigIntKeyword)||i.asKind(t.SyntaxKind.BigIntLiteral))return"bigint";const r=i.asKind(t.SyntaxKind.TypeLiteral);if(r)return r.getFirstChildByKind(t.SyntaxKind.SyntaxList).getChildrenOfKind(t.SyntaxKind.PropertySignature).map(O=>{const v=O.getFirstChildByKind(t.SyntaxKind.Identifier),V=N(O),D=v.getNextSiblingIfKind(t.SyntaxKind.QuestionToken);return{role:"property",identifier:v.getText(),shape:f(V),optional:V.getType().isNullable()||!!D}});const y=i.asKind(t.SyntaxKind.TypeReference);if(y)return f(y.getFirstChild());if(i.asKind(t.SyntaxKind.PropertyAccessExpression)){const w=c(i.getLastChild());return u(w.asKind(t.SyntaxKind.CallExpression).getReturnType(),w)}const K=i.asKind(t.SyntaxKind.UnionType);if(K)return u(K.getType(),i);const A=i.asKind(t.SyntaxKind.TypeQuery);if(A)return f(A.getLastChild());const F=i.asKind(t.SyntaxKind.QualifiedName);if(F)return f(F.getLastChild());const T=i.asKind(t.SyntaxKind.CallExpression);if(T)return u(T.getReturnType(),T);const I=i.asKind(t.SyntaxKind.AwaitExpression);if(I)return f(I.getChildAtIndex(1));const k=i.asKind(t.SyntaxKind.AsExpression);if(k)return f(k.getChildAtIndex(2));const U=i.getSourceFile().getFilePath().split("/").pop();return x.Logger.warn(`[${U}] Unknown node type: ${i.getKindName()}`),"unknown_1"},$=e=>e.getFirstDescendantByKind(t.SyntaxKind.SyntaxList).getChildrenOfKind(t.SyntaxKind.PropertyAssignment).map(l=>{const o=l.getFirstChild(),g=(()=>{if(o.isKind(t.SyntaxKind.Identifier))return o.getText();if(o.isKind(t.SyntaxKind.StringLiteral))return o.getLiteralText();const r=l.getSourceFile().getFilePath().split("/").pop();return x.Logger.warn(`[${r}] Unknown identifier name: ${o.getText()}`),"unknown_30"})(),a=l.getLastChild(),d=c(a);return{role:"property",identifier:g,shape:m(d),optional:B(d),description:h(d,"description"),errorMessage:h(d,"errorMessage")}})||[],S=e=>{const n=e.asKind(t.SyntaxKind.CallExpression);return n?(n.getReturnType().getSymbol()?.getName()??"").startsWith("Zod"):!1},C=e=>{const n=e.asKind(t.SyntaxKind.CallExpression),i=n.getReturnType(),s=i.getSymbol()?.getName()??"";if(s==="ZodNumber")return"number";if(s==="ZodString")return"string";if(s==="ZodBoolean")return"boolean";if(s==="ZodBigInt")return"bigint";if(s==="ZodObject"){const g=n.getFirstChildByKind(t.SyntaxKind.SyntaxList)?.getFirstChild()?.asKind(t.SyntaxKind.ObjectLiteralExpression);if(!g)return"unknown_zod_object";const a=g.getFirstChildByKind(t.SyntaxKind.SyntaxList);return a?a.getChildrenOfKind(t.SyntaxKind.PropertyAssignment).map(r=>{const y=r.getFirstChildByKind(t.SyntaxKind.Identifier).getText(),p=r.getLastChild();return{role:"property",identifier:y,shape:S(p)?C(p):m(p),optional:!1}}):[]}if(s==="ZodArray"){const o=n.getFirstChildByKind(t.SyntaxKind.SyntaxList)?.getFirstChild();if(o)return[{role:"array",shape:S(o)?C(o):m(o),optional:!1}];const a=n.getFirstChildByKind(t.SyntaxKind.PropertyAccessExpression)?.getFirstChildByKind(t.SyntaxKind.CallExpression);return a&&S(a)?[{role:"array",shape:C(a),optional:!1}]:"unknown_zod_array"}if(s==="ZodEnum"){const o=i.getTypeArguments();if(o.length>0){const d=o[0].getProperties().map(r=>({role:"union_entry",shape:u(r.getTypeAtLocation(n),n,[]),optional:!1}));if(d.length===1)return d[0].shape;if(d.length>1)return[{role:"union",shape:d,optional:!1}]}return"unknown_zod_enum"}if(s==="ZodOptional"){const o=n.getFirstChildByKind(t.SyntaxKind.PropertyAccessExpression)?.getFirstChildByKind(t.SyntaxKind.CallExpression);return o&&S(o)?C(o):"unknown_zod_optional"}const l=e.getSourceFile().getFilePath().split("/").pop();return x.Logger.warn(`[${l}] Unknown zod type: ${s}`),"unknown_zod"},m=e=>{if(S(e))return C(e);const n=e.getParent().getFirstChildByKind(t.SyntaxKind.AsExpression);if(n){const r=n.getLastChildByKind(t.SyntaxKind.TypeReference);return b(r)}const i=e.getParent().getFirstChildByKind(t.SyntaxKind.TypeReference);if(i)return b(i);if(e.getParent().getChildrenOfKind(t.SyntaxKind.SyntaxList).length>=2){const r=e.getParent().getFirstChildByKind(t.SyntaxKind.SyntaxList).getFirstChild();return f(r)}const s=e.getParent().getFirstChildByKind(t.SyntaxKind.CallExpression);if(s){const r=c(s.getFirstChildByKind(t.SyntaxKind.SyntaxList).getFirstChild()),y=r.getParent().getFirstChildByKind(t.SyntaxKind.TypeReference);if(y)return u(y.getType(),y,[]);const p=r.getParent().getFirstChildByKind(t.SyntaxKind.ObjectLiteralExpression);if(p)return m(p);if(r.getKind()===t.SyntaxKind.CallExpression||r.getKind()===t.SyntaxKind.IntersectionType)return m(r);const K=e.getSourceFile().getFilePath().split("/").pop();return x.Logger.warn(`[${K}] Unknown call expression argument: ${r.getKindName()}`),"unknown_3"}const o=e.getFirstChildByKind(t.SyntaxKind.SyntaxList).getChildrenOfKind(t.SyntaxKind.PropertyAssignment).find(r=>r.getFirstChildByKind(t.SyntaxKind.Identifier)?.getText()==="parse");if(o){const r=N(o).asKind(t.SyntaxKind.ArrowFunction).getReturnType();return u(r,o)}const g=e.getFirstChildByKind(t.SyntaxKind.SyntaxList)?.getFirstChildByKind(t.SyntaxKind.ImportType);if(g){const r=g.getLastChildByKind(t.SyntaxKind.GreaterThanToken).getChildIndex(),y=g.getChildAtIndex(r-1);return f(y.getFirstChild())}const a=e.isKind(t.SyntaxKind.IntersectionType)?e:e.getParent()?.isKind(t.SyntaxKind.VariableDeclaration)?e.getParent()?.getFirstChildByKind(t.SyntaxKind.IntersectionType):null;if(a){const r=a.getFirstChildByKind(t.SyntaxKind.TypeReference);if(r)return b(r)}const d=e.getSourceFile().getFilePath().split("/").pop();return x.Logger.warn(`[${d}] Unknown import type node`),"unknown_2"},B=e=>{if(S(e))return(e.asKind(t.SyntaxKind.CallExpression).getReturnType().getSymbol()?.getName()??"")==="ZodOptional";const n=e.asKind(t.SyntaxKind.CallExpression);if(n){const l=n.getFirstChildByKind(t.SyntaxKind.Identifier);if(l?.getText()==="OptionalParam")return!0;if(l?.getText()==="RequiredParam")return!1;const o=n.getFirstChildByKind(t.SyntaxKind.SyntaxList),g=c(o.getFirstChild());return B(g)}return e.getFirstDescendantByKind(t.SyntaxKind.SyntaxList).getChildrenOfKind(t.SyntaxKind.PropertyAssignment).some(l=>l.getFirstDescendantByKind(t.SyntaxKind.Identifier).getText()==="optional"?N(l).getKind()===t.SyntaxKind.TrueKeyword:!1)},h=(e,n)=>{if(S(e))return"";const i=c(e),s=i.asKind(t.SyntaxKind.CallExpression);if(s){const y=s.getLastChildByKind(t.SyntaxKind.SyntaxList);return h(y,n)}const l=i.asKind(t.SyntaxKind.SyntaxList);if(l)return l.getChildren().map(p=>h(p,n)).find(p=>!!p&&p!=="unknown_25")||"";const o=i.asKind(t.SyntaxKind.ObjectLiteralExpression);if(o){const p=E(o).find(K=>K.identifier===n);return p?Array.isArray(p.value)?"array":p.value||"":""}const g=i.asKind(t.SyntaxKind.IntersectionType);if(g)return g.getTypeNodes().flatMap(y=>h(y,n)).filter(y=>!!y&&y!=="unknown_25")[0]||"unknown_27";const a=i.asKind(t.SyntaxKind.TypeLiteral);if(a)return h(a.getFirstChildByKind(t.SyntaxKind.SyntaxList),n);const d=i.asKind(t.SyntaxKind.PropertySignature);if(d&&i.getFirstDescendantByKind(t.SyntaxKind.Identifier).getText()===n)return N(d).getFirstDescendantByKind(t.SyntaxKind.StringLiteral).getLiteralText();const r=i.getSourceFile().getFilePath().split("/").pop();return x.Logger.dev(`[${r}] Unknown property string value node ${i.getKindName()}`),"unknown_25"},Z=e=>{const n=e.getSymbol();if(!e.isObject()||!n)return!1;const i=e.getTypeArguments();return n.getName()==="Promise"&&i.length===1},u=(e,n,i=[])=>{const s=e.getAliasSymbol()?.getName();if(s&&j.OpenApiManager.getInstance().hasExposedModel(s))return[{role:"ref",shape:s,optional:!1}];const l=Z(e)?e.getTypeArguments()[0]:e;if(i.some(d=>d===l))return"circular";const o=l.compilerType,g=R.get(o);if(g!==void 0)return g;const a=q(l,n,i);return R.set(o,a),a},q=(e,n,i)=>{const s=i.concat(e);if(e.getText()==="void")return"void";if(e.isAny())return"any";if(e.isUnknown())return"unknown";if(e.isNull())return"null";if(e.isUndefined())return"undefined";if(e.isBoolean()||e.isBooleanLiteral())return"boolean";if(e.isStringLiteral())return[{role:"literal_string",shape:String(e.getLiteralValue()),optional:!1}];if(e.isNumberLiteral())return[{role:"literal_number",shape:String(e.getLiteralValue()),optional:!1}];if(e.isString()||e.isTemplateLiteral())return"string";if(e.isNumber())return"number";if(e.getText()==="bigint")return"bigint";if(e.isTuple())return[{role:"tuple",shape:e.getTupleElements().map(a=>({role:"tuple_entry",shape:u(a,n,s),optional:!1})),optional:!1}];if(e.isArray())return[{role:"array",shape:u(e.getArrayElementType(),n,s),optional:!1}];if(e.isObject()){const a=e.getNumberIndexType(),r=e.getBaseTypes()?.find(y=>y.isArray());if(r)return[{role:"array",shape:u(r.getArrayElementType()??a,n,s),optional:!1}]}const l=e.getSymbol()?.getName(),o=new Set(["Buffer","Uint8Array","Int8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array","ArrayBuffer","SharedArrayBuffer","ReadableStream"]);if(e.isObject()&&l&&o.has(l))return[{role:"buffer",shape:"buffer",optional:!1}];if(e.isObject()&&l==="RegExp")return"string";if(e.isObject()&&l==="Map"){const d=e.getTypeArguments()[1];return[{role:"record",shape:d?u(d,n,s):"unknown",optional:!1}]}if(e.isObject()&&l==="Set"){const d=e.getTypeArguments()[0];return[{role:"array",shape:d?u(d,n,s):"unknown",optional:!1}]}if(e.isObject()&&e.getProperties().length===0){const a=e.getAliasTypeArguments()[1]??e.getStringIndexType();if(a)return[{role:"record",shape:u(a,n,s),optional:!1}]}if(e.isObject())return l==="Date"||e.getText()==="Date"?"Date":e.getProperties().map(a=>{const d=a.getValueDeclaration()||a.getDeclarations()[0],r=u(a.getTypeAtLocation(n),n,s);if(!d)return{role:"property",identifier:a.getName(),shape:r,optional:!1};if(!(d.asKind(t.SyntaxKind.PropertySignature)||d.asKind(t.SyntaxKind.PropertyAssignment)||d.asKind(t.SyntaxKind.ShorthandPropertyAssignment)))return{role:"property",identifier:a.getName(),shape:r,optional:!1};const p=a.getTypeAtLocation(n).isNullable();return{role:"property",identifier:a.getName(),shape:r,optional:p}}).filter(a=>a.shape!=="undefined");if(e.isUnion()){const d=e.getUnionTypes().map(p=>({role:"union_entry",shape:u(p,n,s),optional:!1})).filter((p,K,A)=>!A.find((F,T)=>F.shape===p.shape&&T>K)),r=d.some(p=>p.shape==="undefined"),y=d.filter(p=>p.shape!=="undefined");return y.length===1?y[0].shape:[{role:"union",shape:y,optional:r}]}if(e.isIntersection())return e.getIntersectionTypes().map(r=>u(r,n,s)).filter(r=>typeof r!="string").reduce((r,y)=>[...r,...y],[]);const g=n.getSourceFile().getFilePath().split("/").pop();return x.Logger.warn(`[${g}] Unknown type shape node ${e.getText()}`),"unknown_5"},P=e=>{if(e.isKind(t.SyntaxKind.Identifier))return P(c(e));if(e.isKind(t.SyntaxKind.StringLiteral))return e.getLiteralValue();if(e.isKind(t.SyntaxKind.ArrayLiteralExpression))return e.forEachChildAsArray().map(i=>P(i));if(e.isKind(t.SyntaxKind.PropertyAccessExpression))return P(N(e));if(e.isKind(t.SyntaxKind.ObjectLiteralExpression))return E(e);const n=e.getSourceFile().getFilePath().split("/").pop();return x.Logger.dev(`[${n}] Unknown literal value node ${e.getKindName()}`),"unknown_6"},z=e=>{const n=e.getFirstDescendantByKind(t.SyntaxKind.CallExpression);if(!n)return null;const i=n.getArguments()[0];if(!i)return null;const s=i.getType();return s.isStringLiteral()?s.getLiteralValue():null},E=e=>e.getFirstDescendantByKind(t.SyntaxKind.SyntaxList).getChildrenOfKind(t.SyntaxKind.PropertyAssignment).map(l=>{const g=l.getFirstDescendantByKind(t.SyntaxKind.Identifier).getText(),a=l.getLastChild(),d=c(a),r=P(d);return{identifier:g,value:r}})||[];exports.findNodeImplementation=c;exports.findPropertyAssignmentValueNode=N;exports.getProperTypeShape=u;exports.getRecursiveNodeShape=f;exports.getShapeOfValidatorLiteral=$;exports.getTypeReferenceShape=b;exports.getValidatorPropertyOptionality=B;exports.getValidatorPropertyShape=m;exports.getValidatorPropertyStringValue=h;exports.getValuesOfObjectLiteral=E;exports.resolveEndpointPath=z;
2
2
  //# sourceMappingURL=nodeParsers.cjs.map