UNPKG

@autobe/agent

Version:

AI backend server code generator

150 lines (140 loc) 5.04 kB
import { AutoBeOpenApi, AutoBeProgressEventBase, AutoBeTestAuthorizeFunction, AutoBeTestValidateEvent, IAutoBeCompiler, } from "@autobe/interface"; import { StringUtil } from "@autobe/utils"; import { NamingConvention } from "@typia/utils"; import { IValidation } from "typia"; import { validateEmptyCode } from "../../../utils/validateEmptyCode"; import { IAutoBeTestArtifacts } from "../structures/IAutoBeTestArtifacts"; import { IAutoBeTestAuthorizeProcedure } from "../structures/IAutoBeTestAuthorizeWriteResult"; import { AutoBeTestFunctionProgrammer } from "./AutoBeTestFunctionProgrammer"; export namespace AutoBeTestAuthorizeProgrammer { /* ---------------------------------------------------------------- GETTERS ---------------------------------------------------------------- */ export function size(document: AutoBeOpenApi.IDocument): number { return document.operations.filter((op) => op.authorizationType !== null) .length; } export function getFunctionName(operation: AutoBeOpenApi.IOperation): string { if ( operation.authorizationActor === null || operation.authorizationType === null ) throw new Error("Operation is not an authorization operation."); const elements: string[] = [ "authorize", operation.authorizationActor, operation.authorizationType, ]; return elements.map(NamingConvention.snake).join("_"); } /* ---------------------------------------------------------------- WRITERS ---------------------------------------------------------------- */ export function writeTemplate(props: { operation: AutoBeOpenApi.IOperation; schema: AutoBeOpenApi.IJsonSchema.IObject; }): string { if (props.operation.requestBody === null) throw new Error("Authorization operation needs request body."); else if (props.operation.responseBody === null) throw new Error("Authorization operation needs response body."); const functionName: string = getFunctionName(props.operation); const accessor: string[] = props.operation.accessor!; if (props.operation.authorizationActor !== "join") return StringUtil.trim` export async function ${functionName}( connection: api.IConnection, props: { body: ${props.operation.requestBody.typeName} }, ): Promise<${props.operation.responseBody.typeName}> { return await api.functional.${accessor.join(".")}( connection, { body: props.body, }, ); } `; return StringUtil.trim` export async function ${functionName}( connection: api.IConnection, props: { body?: ${props.operation.requestBody.typeName} }, ): Promise<${props.operation.responseBody.typeName}> { const joinInput = { ${Object.keys(props.schema.properties).map( (k) => ` ${NamingConvention.variable(k) ? k : `[${JSON.stringify(k)}]`}: ...,`, )} } satisfies ${props.operation.requestBody.typeName}; return await api.functional.${accessor.join(".")}( connection, { body: joinInput, }, ); } `; } /* ---------------------------------------------------------------- COMPILERS ---------------------------------------------------------------- */ export function compile(props: { compiler: IAutoBeCompiler; procedure: IAutoBeTestAuthorizeProcedure; progress: AutoBeProgressEventBase; step: number; }): Promise<AutoBeTestValidateEvent<AutoBeTestAuthorizeFunction>> { return AutoBeTestFunctionProgrammer.compile({ compiler: props.compiler, document: props.procedure.artifacts.document, function: props.procedure.function, files: { [props.procedure.function.location]: props.procedure.function.content, }, progress: props.progress, step: props.step, }); } export async function replaceImportStatements(props: { compiler: IAutoBeCompiler; artifacts: IAutoBeTestArtifacts; content: string; }): Promise<string> { let code: string = await props.compiler.typescript.removeImportStatements( props.content, ); const imports: string[] = AutoBeTestFunctionProgrammer.writeImportStatements( props.artifacts.document.components.schemas, ); code = [...imports, code].join("\n"); return await props.compiler.typescript.beautify(code); } /* ---------------------------------------------------------------- VALIDATE ---------------------------------------------------------------- */ export function validate(props: { procedure: IAutoBeTestAuthorizeProcedure; draft: string; revise: { final: string | null; }; }): IValidation.IError[] { return validateEmptyCode({ path: "$input", asynchronous: true, name: props.procedure.function.name, draft: props.draft, revise: props.revise, }); } }