moonflower 1.4.6 → 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.
- package/dist/openapi/analyzerModule/analyzerModule.cjs +1 -1
- package/dist/openapi/analyzerModule/analyzerModule.cjs.map +1 -1
- package/dist/openapi/analyzerModule/analyzerModule.mjs +33 -32
- package/dist/openapi/analyzerModule/analyzerModule.mjs.map +1 -1
- package/dist/openapi/analyzerModule/nodeParsers.cjs +1 -1
- package/dist/openapi/analyzerModule/nodeParsers.cjs.map +1 -1
- package/dist/openapi/analyzerModule/nodeParsers.d.ts.map +1 -1
- package/dist/openapi/analyzerModule/nodeParsers.mjs +320 -308
- package/dist/openapi/analyzerModule/nodeParsers.mjs.map +1 -1
- package/dist/openapi/analyzerModule/parseEndpoint.cjs +1 -1
- package/dist/openapi/analyzerModule/parseEndpoint.cjs.map +1 -1
- package/dist/openapi/analyzerModule/parseEndpoint.d.ts.map +1 -1
- package/dist/openapi/analyzerModule/parseEndpoint.mjs +105 -95
- package/dist/openapi/analyzerModule/parseEndpoint.mjs.map +1 -1
- package/package.json +1 -1
- package/src/openapi/analyzerModule/analyzerModule.ts +1 -1
- package/src/openapi/analyzerModule/nodeParsers.ts +28 -5
- package/src/openapi/analyzerModule/parseEndpoint.ts +41 -29
|
@@ -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=
|
|
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":"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"}
|
|
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":"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"}
|
|
@@ -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:
|
|
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
|
-
|
|
24
|
-
const
|
|
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) =>
|
|
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
|
|
51
|
-
e.setExposedModels(
|
|
52
|
-
const
|
|
53
|
-
cachePath:
|
|
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 = (
|
|
73
|
-
const a = performance.now(), s =
|
|
74
|
-
return m.info(`Router analysis took ${Math.round(performance.now() - a)}ms`), s.map((e,
|
|
75
|
-
fileName: o
|
|
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,
|
|
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 = (
|
|
81
|
-
const a = z(
|
|
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(`[${
|
|
84
|
-
m.debug(`[${
|
|
85
|
-
const e = performance.now(),
|
|
86
|
-
return m.debug(`[${
|
|
87
|
-
}, I = (
|
|
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
|
|
90
|
-
o
|
|
91
|
-
|
|
92
|
-
|
|
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 = (
|
|
96
|
+
}, B = (t) => {
|
|
96
97
|
const n = E({
|
|
97
|
-
sourceFile:
|
|
98
|
+
sourceFile: t,
|
|
98
99
|
originalName: "useApiHeader"
|
|
99
100
|
});
|
|
100
101
|
if (!n)
|
|
101
102
|
return null;
|
|
102
|
-
const c =
|
|
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 = (
|
|
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 = (
|
|
111
|
+
}, V = (t) => {
|
|
111
112
|
const n = [], c = E({
|
|
112
|
-
sourceFile:
|
|
113
|
+
sourceFile: t,
|
|
113
114
|
originalName: "useExposeApiModel"
|
|
114
115
|
}), a = E({
|
|
115
|
-
sourceFile:
|
|
116
|
+
sourceFile: t,
|
|
116
117
|
originalName: "useExposeNamedApiModels"
|
|
117
118
|
});
|
|
118
|
-
return
|
|
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 e=require("ts-morph"),S=require("../../utils/logger.cjs"),_=require("../manager/OpenApiManager.cjs"),P=new WeakMap,K=t=>{const i=P.get(t);if(i)return i;if(t.getKind()===e.SyntaxKind.Identifier){const s=t.asKind(e.SyntaxKind.Identifier).getImplementations()[0]?.getNode();if(s){const a=s.getParent().getLastChild();if(a===t)throw new Error("Recursive implementation found");const l=K(a);return P.set(t,l),l}const d=t.asKind(e.SyntaxKind.Identifier).getDefinitions()[0]?.getNode();if(d){const a=d.getParent().getLastChild();if(a===t)throw new Error("Recursive implementation found");const l=K(a);return P.set(t,l),l}throw new Error("No implementation nor definition available")}return P.set(t,t),t},T=t=>{const i=t.getChildrenOfKind(e.SyntaxKind.Identifier);return i.length===2?K(i[1]):t.getChildren().reverse().find(d=>d.getKind()!==e.SyntaxKind.GreaterThanToken&&d.getKind()!==e.SyntaxKind.CommaToken&&d.getKind()!==e.SyntaxKind.SemicolonToken)},w=t=>{const i=t.getFirstChildByKind(e.SyntaxKind.SyntaxList);return i.isKind(e.SyntaxKind.SyntaxList)?x(i.getFirstChild()):x(i)},x=t=>{const i=t.getSymbol()?.getName();if(i&&_.OpenApiManager.getInstance().hasExposedModel(i))return[{role:"ref",shape:i,optional:!1}];const s=K(t);if(s.asKind(e.SyntaxKind.UndefinedKeyword))return"undefined";const n=s.asKind(e.SyntaxKind.LiteralType);if(n){if(n.getFirstChildByKind(e.SyntaxKind.TrueKeyword))return"true";if(n.getFirstChildByKind(e.SyntaxKind.FalseKeyword))return"false"}if(s.asKind(e.SyntaxKind.BooleanKeyword)||s.asKind(e.SyntaxKind.TrueKeyword)||s.asKind(e.SyntaxKind.FalseKeyword))return"boolean";if(s.asKind(e.SyntaxKind.StringKeyword)||s.asKind(e.SyntaxKind.StringLiteral))return"string";if(s.asKind(e.SyntaxKind.NumberKeyword)||s.asKind(e.SyntaxKind.NumericLiteral))return"number";if(s.asKind(e.SyntaxKind.BigIntKeyword)||s.asKind(e.SyntaxKind.BigIntLiteral))return"bigint";const r=s.asKind(e.SyntaxKind.TypeLiteral);if(r)return r.getFirstChildByKind(e.SyntaxKind.SyntaxList).getChildrenOfKind(e.SyntaxKind.PropertySignature).map(O=>{const v=O.getFirstChildByKind(e.SyntaxKind.Identifier),V=T(O),j=v.getNextSiblingIfKind(e.SyntaxKind.QuestionToken);return{role:"property",identifier:v.getText(),shape:x(V),optional:V.getType().isNullable()||!!j}});const o=s.asKind(e.SyntaxKind.TypeReference);if(o)return x(o.getFirstChild());if(s.asKind(e.SyntaxKind.PropertyAccessExpression)){const E=K(s.getLastChild());return u(E.asKind(e.SyntaxKind.CallExpression).getReturnType(),E)}const c=s.asKind(e.SyntaxKind.UnionType);if(c)return u(c.getType(),s);const f=s.asKind(e.SyntaxKind.TypeQuery);if(f)return x(f.getLastChild());const F=s.asKind(e.SyntaxKind.QualifiedName);if(F)return x(F.getLastChild());const C=s.asKind(e.SyntaxKind.CallExpression);if(C)return u(C.getReturnType(),C);const L=s.asKind(e.SyntaxKind.AwaitExpression);if(L)return x(L.getChildAtIndex(1));const b=s.asKind(e.SyntaxKind.AsExpression);if(b)return x(b.getChildAtIndex(2));const R=s.getSourceFile().getFilePath().split("/").pop();return S.Logger.warn(`[${R}] Unknown node type: ${s.getKindName()}`),"unknown_1"},U=t=>t.getFirstDescendantByKind(e.SyntaxKind.SyntaxList).getChildrenOfKind(e.SyntaxKind.PropertyAssignment).map(n=>{const a=n.getFirstChild(),l=(()=>{if(a.isKind(e.SyntaxKind.Identifier))return a.getText();if(a.isKind(e.SyntaxKind.StringLiteral))return a.getLiteralText();const r=n.getSourceFile().getFilePath().split("/").pop();return S.Logger.warn(`[${r}] Unknown identifier name: ${a.getText()}`),"unknown_30"})(),p=n.getLastChild(),g=K(p);return{role:"property",identifier:l,shape:N(g),optional:I(g),description:m(g,"description"),errorMessage:m(g,"errorMessage")}})||[],h=t=>{const i=t.asKind(e.SyntaxKind.CallExpression);return i?(i.getReturnType().getSymbol()?.getName()??"").startsWith("Zod"):!1},A=t=>{const i=t.asKind(e.SyntaxKind.CallExpression),s=i.getReturnType(),d=s.getSymbol()?.getName()??"";if(d==="ZodNumber")return"number";if(d==="ZodString")return"string";if(d==="ZodBoolean")return"boolean";if(d==="ZodBigInt")return"bigint";if(d==="ZodObject"){const l=i.getFirstChildByKind(e.SyntaxKind.SyntaxList)?.getFirstChild()?.asKind(e.SyntaxKind.ObjectLiteralExpression);if(!l)return"unknown_zod_object";const p=l.getFirstChildByKind(e.SyntaxKind.SyntaxList);return p?p.getChildrenOfKind(e.SyntaxKind.PropertyAssignment).map(r=>{const o=r.getFirstChildByKind(e.SyntaxKind.Identifier).getText(),y=r.getLastChild();return{role:"property",identifier:o,shape:h(y)?A(y):N(y),optional:!1}}):[]}if(d==="ZodArray"){const a=i.getFirstChildByKind(e.SyntaxKind.SyntaxList)?.getFirstChild();if(a)return[{role:"array",shape:h(a)?A(a):N(a),optional:!1}];const p=i.getFirstChildByKind(e.SyntaxKind.PropertyAccessExpression)?.getFirstChildByKind(e.SyntaxKind.CallExpression);return p&&h(p)?[{role:"array",shape:A(p),optional:!1}]:"unknown_zod_array"}if(d==="ZodEnum"){const a=s.getTypeArguments();if(a.length>0){const g=a[0].getProperties().map(r=>({role:"union_entry",shape:u(r.getTypeAtLocation(i),i,[]),optional:!1}));if(g.length===1)return g[0].shape;if(g.length>1)return[{role:"union",shape:g,optional:!1}]}return"unknown_zod_enum"}if(d==="ZodOptional"){const a=i.getFirstChildByKind(e.SyntaxKind.PropertyAccessExpression)?.getFirstChildByKind(e.SyntaxKind.CallExpression);return a&&h(a)?A(a):"unknown_zod_optional"}const n=t.getSourceFile().getFilePath().split("/").pop();return S.Logger.warn(`[${n}] Unknown zod type: ${d}`),"unknown_zod"},N=t=>{if(h(t))return A(t);const i=t.getParent().getFirstChildByKind(e.SyntaxKind.AsExpression);if(i){const r=i.getLastChildByKind(e.SyntaxKind.TypeReference);return w(r)}const s=t.getParent().getFirstChildByKind(e.SyntaxKind.TypeReference);if(s)return w(s);if(t.getParent().getChildrenOfKind(e.SyntaxKind.SyntaxList).length>=2){const r=t.getParent().getFirstChildByKind(e.SyntaxKind.SyntaxList).getFirstChild();return x(r)}const d=t.getParent().getFirstChildByKind(e.SyntaxKind.CallExpression);if(d){const r=K(d.getFirstChildByKind(e.SyntaxKind.SyntaxList).getFirstChild()),o=r.getParent().getFirstChildByKind(e.SyntaxKind.TypeReference);if(o)return u(o.getType(),o,[]);const y=r.getParent().getFirstChildByKind(e.SyntaxKind.ObjectLiteralExpression);if(y)return N(y);if(r.getKind()===e.SyntaxKind.CallExpression||r.getKind()===e.SyntaxKind.IntersectionType)return N(r);const c=t.getSourceFile().getFilePath().split("/").pop();return S.Logger.warn(`[${c}] Unknown call expression argument: ${r.getKindName()}`),"unknown_3"}const a=t.getFirstChildByKind(e.SyntaxKind.SyntaxList).getChildrenOfKind(e.SyntaxKind.PropertyAssignment).find(r=>r.getFirstChildByKind(e.SyntaxKind.Identifier)?.getText()==="parse");if(a){const r=T(a).asKind(e.SyntaxKind.ArrowFunction).getReturnType();return u(r,a)}const l=t.getFirstChildByKind(e.SyntaxKind.SyntaxList)?.getFirstChildByKind(e.SyntaxKind.ImportType);if(l){const r=l.getLastChildByKind(e.SyntaxKind.GreaterThanToken).getChildIndex(),o=l.getChildAtIndex(r-1);return x(o.getFirstChild())}const p=t.isKind(e.SyntaxKind.IntersectionType)?t:t.getParent()?.isKind(e.SyntaxKind.VariableDeclaration)?t.getParent()?.getFirstChildByKind(e.SyntaxKind.IntersectionType):null;if(p){const r=p.getFirstChildByKind(e.SyntaxKind.TypeReference);if(r)return w(r)}const g=t.getSourceFile().getFilePath().split("/").pop();return S.Logger.warn(`[${g}] Unknown import type node`),"unknown_2"},I=t=>{if(h(t))return(t.asKind(e.SyntaxKind.CallExpression).getReturnType().getSymbol()?.getName()??"")==="ZodOptional";const i=t.asKind(e.SyntaxKind.CallExpression);if(i){const n=i.getFirstChildByKind(e.SyntaxKind.Identifier);if(n?.getText()==="OptionalParam")return!0;if(n?.getText()==="RequiredParam")return!1;const a=i.getFirstChildByKind(e.SyntaxKind.SyntaxList),l=K(a.getFirstChild());return I(l)}return t.getFirstDescendantByKind(e.SyntaxKind.SyntaxList).getChildrenOfKind(e.SyntaxKind.PropertyAssignment).some(n=>n.getFirstDescendantByKind(e.SyntaxKind.Identifier).getText()==="optional"?T(n).getKind()===e.SyntaxKind.TrueKeyword:!1)},m=(t,i)=>{if(h(t))return"";const s=K(t),d=s.asKind(e.SyntaxKind.CallExpression);if(d){const o=d.getLastChildByKind(e.SyntaxKind.SyntaxList);return m(o,i)}const n=s.asKind(e.SyntaxKind.SyntaxList);if(n)return n.getChildren().map(y=>m(y,i)).find(y=>!!y&&y!=="unknown_25")||"";const a=s.asKind(e.SyntaxKind.ObjectLiteralExpression);if(a){const y=k(a).find(c=>c.identifier===i);return y?Array.isArray(y.value)?"array":y.value||"":""}const l=s.asKind(e.SyntaxKind.IntersectionType);if(l)return l.getTypeNodes().flatMap(o=>m(o,i)).filter(o=>!!o&&o!=="unknown_25")[0]||"unknown_27";const p=s.asKind(e.SyntaxKind.TypeLiteral);if(p)return m(p.getFirstChildByKind(e.SyntaxKind.SyntaxList),i);const g=s.asKind(e.SyntaxKind.PropertySignature);if(g&&s.getFirstDescendantByKind(e.SyntaxKind.Identifier).getText()===i)return T(g).getFirstDescendantByKind(e.SyntaxKind.StringLiteral).getLiteralText();const r=s.getSourceFile().getFilePath().split("/").pop();return S.Logger.dev(`[${r}] Unknown property string value node ${s.getKindName()}`),"unknown_25"},D=t=>{const i=t.getSymbol();if(!t.isObject()||!i)return!1;const s=t.getTypeArguments();return i.getName()==="Promise"&&s.length===1},u=(t,i,s=[])=>{const d=t.getAliasSymbol()?.getName();if(d&&_.OpenApiManager.getInstance().hasExposedModel(d))return[{role:"ref",shape:d,optional:!1}];const n=D(t)?t.getTypeArguments()[0]:t;if(s.some(r=>r===n))return"circular";const a=s.concat(n);if(n.getText()==="void")return"void";if(n.isAny())return"any";if(n.isUnknown())return"unknown";if(n.isNull())return"null";if(n.isUndefined())return"undefined";if(n.isBoolean()||n.isBooleanLiteral())return"boolean";if(n.isStringLiteral())return[{role:"literal_string",shape:String(n.getLiteralValue()),optional:!1}];if(n.isNumberLiteral())return[{role:"literal_number",shape:String(n.getLiteralValue()),optional:!1}];if(n.isString()||n.isTemplateLiteral())return"string";if(n.isNumber())return"number";if(n.getText()==="bigint")return"bigint";if(n.isTuple())return[{role:"tuple",shape:n.getTupleElements().map(r=>({role:"tuple_entry",shape:u(r,i,a),optional:!1})),optional:!1}];if(n.isArray())return[{role:"array",shape:u(n.getArrayElementType(),i,a),optional:!1}];if(n.isObject()){const r=n.getNumberIndexType(),y=n.getBaseTypes()?.find(c=>c.isArray());if(y)return[{role:"array",shape:u(y.getArrayElementType()??r,i,a),optional:!1}]}const l=n.getSymbol()?.getName(),p=new Set(["Buffer","Uint8Array","Int8Array","Uint8ClampedArray","Int16Array","Uint16Array","Int32Array","Uint32Array","Float32Array","Float64Array","BigInt64Array","BigUint64Array","ArrayBuffer","SharedArrayBuffer","ReadableStream"]);if(n.isObject()&&l&&p.has(l))return[{role:"buffer",shape:"buffer",optional:!1}];if(n.isObject()&&l==="RegExp")return"string";if(n.isObject()&&l==="Map"){const o=n.getTypeArguments()[1];return[{role:"record",shape:o?u(o,i,a):"unknown",optional:!1}]}if(n.isObject()&&l==="Set"){const o=n.getTypeArguments()[0];return[{role:"array",shape:o?u(o,i,a):"unknown",optional:!1}]}if(n.isObject()&&n.getProperties().length===0){const r=n.getAliasTypeArguments()[1]??n.getStringIndexType();if(r)return[{role:"record",shape:u(r,i,a),optional:!1}]}if(n.isObject())return l==="Date"||n.getText()==="Date"?"Date":n.getProperties().map(r=>{const o=r.getValueDeclaration()||r.getDeclarations()[0];if(!o)return{role:"property",identifier:r.getName(),shape:u(r.getTypeAtLocation(i),i,a),optional:!1};if(!(o.asKind(e.SyntaxKind.PropertySignature)||o.asKind(e.SyntaxKind.PropertyAssignment)||o.asKind(e.SyntaxKind.ShorthandPropertyAssignment)))return{role:"property",identifier:r.getName(),shape:u(r.getTypeAtLocation(i),i,a),optional:!1};const c=r.getTypeAtLocation(i).isNullable(),f=u(r.getTypeAtLocation(i),i,a);return{role:"property",identifier:r.getName(),shape:f,optional:c}}).filter(r=>r.shape!=="undefined");if(n.isUnion()){const o=n.getUnionTypes().map(f=>({role:"union_entry",shape:u(f,i,a),optional:!1})).filter((f,F,C)=>!C.find((L,b)=>L.shape===f.shape&&b>F)),y=o.some(f=>f.shape==="undefined"),c=o.filter(f=>f.shape!=="undefined");return c.length===1?c[0].shape:[{role:"union",shape:c,optional:y}]}if(n.isIntersection())return n.getIntersectionTypes().map(y=>u(y,i,a)).filter(y=>typeof y!="string").reduce((y,c)=>[...y,...c],[]);const g=i.getSourceFile().getFilePath().split("/").pop();return S.Logger.warn(`[${g}] Unknown type shape node ${t.getText()}`),"unknown_5"},B=t=>{if(t.isKind(e.SyntaxKind.Identifier))return B(K(t));if(t.isKind(e.SyntaxKind.StringLiteral))return t.getLiteralValue();if(t.isKind(e.SyntaxKind.ArrayLiteralExpression))return t.forEachChildAsArray().map(s=>B(s));if(t.isKind(e.SyntaxKind.PropertyAccessExpression))return B(T(t));if(t.isKind(e.SyntaxKind.ObjectLiteralExpression))return k(t);const i=t.getSourceFile().getFilePath().split("/").pop();return S.Logger.dev(`[${i}] Unknown literal value node ${t.getKindName()}`),"unknown_6"},M=t=>{const i=t.getFirstDescendantByKind(e.SyntaxKind.CallExpression);if(!i)return null;const s=i.getArguments()[0];if(!s)return null;const d=s.getType();return d.isStringLiteral()?d.getLiteralValue():null},k=t=>t.getFirstDescendantByKind(e.SyntaxKind.SyntaxList).getChildrenOfKind(e.SyntaxKind.PropertyAssignment).map(n=>{const l=n.getFirstDescendantByKind(e.SyntaxKind.Identifier).getText(),p=n.getLastChild(),g=K(p),r=B(g);return{identifier:l,value:r}})||[];exports.findNodeImplementation=K;exports.findPropertyAssignmentValueNode=T;exports.getProperTypeShape=u;exports.getRecursiveNodeShape=x;exports.getShapeOfValidatorLiteral=U;exports.getTypeReferenceShape=w;exports.getValidatorPropertyOptionality=I;exports.getValidatorPropertyShape=N;exports.getValidatorPropertyStringValue=m;exports.getValuesOfObjectLiteral=k;exports.resolveEndpointPath=M;
|
|
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
|