UNPKG

@nestia/sdk

Version:

Nestia SDK and Swagger generator

198 lines (191 loc) 6.75 kB
import ts from "typescript"; import { IdentifierFactory } from "typia/lib/factories/IdentifierFactory"; import { LiteralFactory } from "typia/lib/factories/LiteralFactory"; import { INestiaProject } from "../../structures/INestiaProject"; import { ITypedHttpRoute } from "../../structures/ITypedHttpRoute"; import { FilePrinter } from "./FilePrinter"; import { ImportDictionary } from "./ImportDictionary"; import { SdkAliasCollection } from "./SdkAliasCollection"; import { SdkHttpParameterProgrammer } from "./SdkHttpParameterProgrammer"; import { SdkImportWizard } from "./SdkImportWizard"; export namespace E2eFileProgrammer { export const generate = (project: INestiaProject) => (props: { api: string; current: string }) => async (route: ITypedHttpRoute): Promise<void> => { const importer: ImportDictionary = new ImportDictionary( `${props.current}/${getFunctionName(route)}.ts`, ); if (project.config.clone !== true) importer.declarations(route.imports); importer.internal({ file: props.api, declaration: false, type: "default", name: "api", }); const functor: ts.Statement = generateFunctor(project)(importer)(route); await FilePrinter.write({ location: importer.file, statements: [ ...importer.toStatements(props.current), FilePrinter.enter(), functor, ], }); }; const generateFunctor = (project: INestiaProject) => (importer: ImportDictionary) => (route: ITypedHttpRoute): ts.Statement => ts.factory.createVariableStatement( [ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)], ts.factory.createVariableDeclarationList( [ ts.factory.createVariableDeclaration( ts.factory.createIdentifier(getFunctionName(route)), undefined, undefined, generateArrow(project)(importer)(route), ), ], ts.NodeFlags.Const, ), ); const generateArrow = (project: INestiaProject) => (importer: ImportDictionary) => (route: ITypedHttpRoute) => { const random = IdentifierFactory.access( ts.factory.createIdentifier(SdkImportWizard.typia(importer)), "random", ); const connection = route.headerObject ? ts.factory.createObjectLiteralExpression( [ ts.factory.createSpreadAssignment( ts.factory.createIdentifier("connection"), ), ts.factory.createPropertyAssignment( "headers", ts.factory.createObjectLiteralExpression( [ ts.factory.createSpreadAssignment( IdentifierFactory.access( ts.factory.createIdentifier("connection"), "headers", ), ), ts.factory.createSpreadAssignment( ts.factory.createCallExpression( random, [ project.config.clone === true ? SdkAliasCollection.from(project)(importer)( route.headerObject.metadata, ) : SdkAliasCollection.name(route.headerObject), ], undefined, ), ), ], true, ), ), ], true, ) : ts.factory.createIdentifier("connection"); const entries = SdkHttpParameterProgrammer.getEntries({ project, importer, route, body: true, e2e: true, prefix: ["api", "functional", ...route.accessor].join(".") + ".", }); const fetch = ts.factory.createCallExpression( ts.factory.createIdentifier( ["api", "functional", ...route.accessor].join("."), ), undefined, [ connection, ...(project.config.keyword === true && entries.length !== 0 ? [ LiteralFactory.write( Object.fromEntries( entries.map((e) => [ e.key, ts.factory.createCallExpression( IdentifierFactory.access( ts.factory.createIdentifier( SdkImportWizard.typia(importer), ), "random", ), [e.type], undefined, ), ]), ), ), ] : entries.map((e) => ts.factory.createCallExpression( IdentifierFactory.access( ts.factory.createIdentifier( SdkImportWizard.typia(importer), ), "random", ), [e.type], undefined, ), )), ], ); const assert = ts.factory.createCallExpression( IdentifierFactory.access( ts.factory.createIdentifier(SdkImportWizard.typia(importer)), "assert", ), undefined, [ts.factory.createIdentifier("output")], ); return ts.factory.createArrowFunction( [ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword)], undefined, [ IdentifierFactory.parameter( "connection", ts.factory.createTypeReferenceNode("api.IConnection"), ), ], undefined, undefined, ts.factory.createBlock([ ts.factory.createVariableStatement( [], ts.factory.createVariableDeclarationList( [ ts.factory.createVariableDeclaration( "output", undefined, project.config.propagate !== true && route.success.type.name === "void" ? undefined : SdkAliasCollection.response(project)(importer)(route), ts.factory.createAwaitExpression(fetch), ), ], ts.NodeFlags.Const, ), ), ts.factory.createExpressionStatement(assert), ]), ); }; } const getFunctionName = (route: ITypedHttpRoute): string => ["test", "api", ...route.accessor].join("_");