@autobe/agent
Version:
AI backend server code generator
254 lines (252 loc) • 11.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeRealizeOperationTemplate = writeRealizeOperationTemplate;
const utils_1 = require("@autobe/utils");
const AutoBeRealizeCollectorProgrammer_1 = require("../AutoBeRealizeCollectorProgrammer");
const AutoBeRealizeTransformerProgrammer_1 = require("../AutoBeRealizeTransformerProgrammer");
const resolvePropertyTransformer_1 = require("./resolvePropertyTransformer");
function writeRealizeOperationTemplate(props) {
var _a, _b, _c, _d, _e;
const functionParameters = [];
if (props.authorization && props.authorization.actor.name) {
functionParameters.push(`${props.authorization.actor.name}: ${props.authorization.payload.name}`);
}
functionParameters.push(...props.operation.parameters.map((param) => `${param.name}: ${writeParameterType(param.schema)}`));
if (((_a = props.operation.requestBody) === null || _a === void 0 ? void 0 : _a.typeName.endsWith(".ILogin")) ||
((_b = props.operation.requestBody) === null || _b === void 0 ? void 0 : _b.typeName.endsWith(".IJoin")))
functionParameters.push("ip: string");
if ((_c = props.operation.requestBody) === null || _c === void 0 ? void 0 : _c.typeName) {
functionParameters.push(`body: ${props.operation.requestBody.typeName}`);
}
const hasParameters = functionParameters.length > 0;
const formattedSignature = hasParameters
? `props: {\n${functionParameters.map((p) => ` ${p}`).join(";\n")};\n}`
: "";
const returnType = (_e = (_d = props.operation.responseBody) === null || _d === void 0 ? void 0 : _d.typeName) !== null && _e !== void 0 ? _e : "void";
const body = writeBody({
method: props.operation.method,
operation: props.operation,
schemas: props.schemas,
collectors: props.collectors,
transformers: props.transformers,
});
const indentedBody = body
.split("\n")
.map((line) => (line.length > 0 ? ` ${line}` : line))
.join("\n");
return utils_1.StringUtil.trim `
Complete the code below, disregard the import part and return only the function part.
\`\`\`typescript
${props.imports.join("\n")}
// DON'T CHANGE FUNCTION NAME AND PARAMETERS,
// ONLY YOU HAVE TO WRITE THIS FUNCTION BODY, AND USE IMPORTED.
export async function ${props.scenario.functionName}(${formattedSignature}): Promise<${returnType}> {
${indentedBody}
}
\`\`\`
`;
}
function writeBody(props) {
var _a, _b, _c, _d;
const collector = ((_a = props.operation
.requestBody) === null || _a === void 0 ? void 0 : _a.typeName)
? props.collectors.find((c) => c.plan.dtoTypeName === props.operation.requestBody.typeName)
: undefined;
const responseTypeName = (_b = props.operation.responseBody) === null || _b === void 0 ? void 0 : _b.typeName;
const isPageType = !!(responseTypeName === null || responseTypeName === void 0 ? void 0 : responseTypeName.startsWith("IPage"));
const innerTypeName = isPageType
? responseTypeName.replace(/^IPage/, "")
: responseTypeName;
const transformer = innerTypeName
? props.transformers.find((t) => t.plan.dtoTypeName === innerTypeName)
: undefined;
// pagination (collector 와 동시에 올 수 없음)
if (isPageType && transformer) {
const tName = AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.getName(transformer.plan.dtoTypeName);
const table = transformer.plan.databaseSchemaName;
const isRecursive = AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.getRecursiveProperty({
schemas: props.schemas,
typeName: transformer.plan.dtoTypeName,
}) !== null;
const dataLine = isRecursive
? `data: await ${tName}.transformAll(records),`
: `data: await ArrayUtil.asyncMap(records, ${tName}.transform),`;
return utils_1.StringUtil.trim `
const records = await MyGlobal.prisma.${table}.findMany({
...${tName}.select(),
...,
});
return {
pagination: {
current: ...,
limit: ...,
records: ...,
pages: ...,
},
${dataLine}
};
`;
}
// collector + transformer (create and return)
if (collector && transformer) {
const cName = AutoBeRealizeCollectorProgrammer_1.AutoBeRealizeCollectorProgrammer.getName(collector.plan.dtoTypeName);
const tName = AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.getName(transformer.plan.dtoTypeName);
const table = collector.plan.databaseSchemaName;
return utils_1.StringUtil.trim `
const record = await MyGlobal.prisma.${table}.create({
data: await ${cName}.collect({
body: props.body,
...
}),
...${tName}.select(),
});
return await ${tName}.transform(record);
`;
}
// collector only (create, void return)
if (collector) {
const cName = AutoBeRealizeCollectorProgrammer_1.AutoBeRealizeCollectorProgrammer.getName(collector.plan.dtoTypeName);
const table = collector.plan.databaseSchemaName;
return utils_1.StringUtil.trim `
await MyGlobal.prisma.${table}.create({
data: await ${cName}.collect({
body: props.body,
...
}),
});
`;
}
// update + transformer (PUT: manual update, re-fetch, transform)
if (props.method === "put" && transformer) {
const tName = AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.getName(transformer.plan.dtoTypeName);
const table = transformer.plan.databaseSchemaName;
return utils_1.StringUtil.trim `
await MyGlobal.prisma.${table}.update({
where: { ... },
data: { ... },
});
const updated = await MyGlobal.prisma.${table}.findUniqueOrThrow({
where: { ... },
...${tName}.select(),
});
return await ${tName}.transform(updated);
`;
}
// update void (PUT: manual update, void return)
if (props.method === "put") {
const table = (_c = transformer === null || transformer === void 0 ? void 0 : transformer.plan.databaseSchemaName) !== null && _c !== void 0 ? _c : "...";
return utils_1.StringUtil.trim `
await MyGlobal.prisma.${table}.update({
where: { ... },
data: { ... },
});
`;
}
// delete (DELETE: simple delete, void return)
if (props.method === "delete") {
const table = (_d = transformer === null || transformer === void 0 ? void 0 : transformer.plan.databaseSchemaName) !== null && _d !== void 0 ? _d : "...";
return utils_1.StringUtil.trim `
await MyGlobal.prisma.${table}.delete({
where: { ... },
});
`;
}
// transformer only (read single or other non-PUT/DELETE)
if (transformer) {
const tName = AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.getName(transformer.plan.dtoTypeName);
const table = transformer.plan.databaseSchemaName;
return utils_1.StringUtil.trim `
const record = await MyGlobal.prisma.${table}.findFirstOrThrow({
...${tName}.select(),
where: { ... },
});
return await ${tName}.transform(record);
`;
}
// object response with transformer-backed properties
if (responseTypeName) {
const objectBody = writeObjectBody({
responseTypeName,
schemas: props.schemas,
transformers: props.transformers,
});
if (objectBody !== null)
return objectBody;
}
return [
"// No matching Collector/Transformer found for this operation.",
"// You MUST call getDatabaseSchemas first to get exact relation property names.",
"// NEVER guess relation names from table names — always verify against the schema.",
"...",
].join("\n ");
}
function writeObjectBody(props) {
const schema = props.schemas[props.responseTypeName];
if (!schema || !utils_1.AutoBeOpenApiTypeChecker.isObject(schema))
return null;
const lines = [];
let hasMatch = false;
for (const [key, prop] of Object.entries(schema.properties)) {
const match = (0, resolvePropertyTransformer_1.resolvePropertyTransformer)({
schema: prop,
transformers: props.transformers,
});
if (match) {
hasMatch = true;
const tName = AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.getName(match.transformer.plan.dtoTypeName);
if (match.isArray) {
const isRecursive = AutoBeRealizeTransformerProgrammer_1.AutoBeRealizeTransformerProgrammer.getRecursiveProperty({
schemas: props.schemas,
typeName: match.transformer.plan.dtoTypeName,
}) !== null;
lines.push(isRecursive
? ` ${key}: await ${tName}.transformAll(...),`
: ` ${key}: await ArrayUtil.asyncMap(..., (r) => ${tName}.transform(r)),`);
}
else {
lines.push(` ${key}: await ${tName}.transform(...),`);
}
}
else {
lines.push(` ${key}: ...,`);
}
}
if (!hasMatch)
return null;
return utils_1.StringUtil.trim `
return {
${lines.join("\n")}
};
`;
}
function writeParameterType(schema) {
const elements = schema.type === "integer"
? ["number", `tags.Type<"int32">`]
: [schema.type];
if (schema.type === "number") {
if (schema.minimum !== undefined)
elements.push(`tags.Minimum<${schema.minimum}>`);
if (schema.maximum !== undefined)
elements.push(`tags.Maximum<${schema.maximum}>`);
if (schema.exclusiveMinimum !== undefined)
elements.push(`tags.ExclusiveMinimum<${schema.exclusiveMinimum}>`);
if (schema.exclusiveMaximum !== undefined)
elements.push(`tags.ExclusiveMaximum<${schema.exclusiveMaximum}>`);
if (schema.multipleOf !== undefined)
elements.push(`tags.MultipleOf<${schema.multipleOf}>`);
}
else if (schema.type === "string") {
if (schema.format !== undefined)
elements.push(`tags.Format<${JSON.stringify(schema.format)}>`);
if (schema.contentMediaType !== undefined)
elements.push(`tags.ContentMediaType<${JSON.stringify(schema.contentMediaType)}>`);
if (schema.pattern !== undefined)
elements.push(`tags.Pattern<${JSON.stringify(schema.pattern)}>`);
if (schema.minLength !== undefined)
elements.push(`tags.MinLength<${schema.minLength}>`);
if (schema.maxLength !== undefined)
elements.push(`tags.MaxLength<${schema.maxLength}>`);
}
return elements.join(" & ");
}
//# sourceMappingURL=writeRealizeOperationTemplate.js.map