@autobe/agent
Version:
AI backend server code generator
628 lines • 137 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.orchestrateInterfaceOperations = orchestrateInterfaceOperations;
const __typia_transform__validateReport = __importStar(require("typia/lib/internal/_validateReport.js"));
const core_1 = require("@agentica/core");
const tstl_1 = require("tstl");
const typia_1 = __importDefault(require("typia"));
const NamingConvention_1 = require("typia/lib/utils/NamingConvention");
const assertSchemaModel_1 = require("../../context/assertSchemaModel");
const divideArray_1 = require("../../utils/divideArray");
const enforceToolCall_1 = require("../../utils/enforceToolCall");
const forceRetry_1 = require("../../utils/forceRetry");
const transformInterfaceOperationHistories_1 = require("./histories/transformInterfaceOperationHistories");
const OpenApiEndpointComparator_1 = require("./utils/OpenApiEndpointComparator");
function orchestrateInterfaceOperations(ctx_1, endpoints_1) {
return __awaiter(this, arguments, void 0, function* (ctx, endpoints, capacity = 12) {
const matrix = (0, divideArray_1.divideArray)({
array: endpoints,
capacity,
});
const progress = {
total: endpoints.length,
completed: 0,
};
const operations = yield Promise.all(matrix.map((it) => __awaiter(this, void 0, void 0, function* () {
var _a, _b;
const row = yield divideAndConquer(ctx, it, 3, progress);
ctx.dispatch(Object.assign(Object.assign({ type: "interfaceOperations", operations: row }, progress), { step: (_b = (_a = ctx.state().analyze) === null || _a === void 0 ? void 0 : _a.step) !== null && _b !== void 0 ? _b : 0, created_at: new Date().toISOString() }));
return row;
})));
return operations.flat();
});
}
function divideAndConquer(ctx, endpoints, retry, progress) {
return __awaiter(this, void 0, void 0, function* () {
const remained = new tstl_1.HashSet(endpoints, OpenApiEndpointComparator_1.OpenApiEndpointComparator.hashCode, OpenApiEndpointComparator_1.OpenApiEndpointComparator.equals);
const operations = new tstl_1.HashMap(OpenApiEndpointComparator_1.OpenApiEndpointComparator.hashCode, OpenApiEndpointComparator_1.OpenApiEndpointComparator.equals);
for (let i = 0; i < retry; ++i) {
if (remained.empty() === true || operations.size() >= endpoints.length)
break;
const newbie = yield (0, forceRetry_1.forceRetry)(() => process(ctx, Array.from(remained), progress));
for (const item of newbie) {
operations.set(item, item);
remained.erase(item);
}
}
return operations.toJSON().map((it) => it.second);
});
}
function process(ctx, endpoints, progress) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c;
const prefix = NamingConvention_1.NamingConvention.camel(ctx.state().analyze.prefix);
const pointer = {
value: null,
};
const agentica = new core_1.MicroAgentica({
model: ctx.model,
vendor: ctx.vendor,
config: Object.assign(Object.assign({}, ((_a = ctx.config) !== null && _a !== void 0 ? _a : {})), { executor: {
describe: null,
} }),
histories: (0, transformInterfaceOperationHistories_1.transformInterfaceOperationHistories)(ctx.state(), endpoints),
controllers: [
createApplication({
model: ctx.model,
roles: (_c = (_b = ctx.state().analyze) === null || _b === void 0 ? void 0 : _b.roles.map((it) => it.name)) !== null && _c !== void 0 ? _c : [],
build: (operations) => {
var _a;
(_a = pointer.value) !== null && _a !== void 0 ? _a : (pointer.value = []);
const matrix = operations.map((op) => {
if (op.authorizationRoles.length === 0)
return [
Object.assign(Object.assign({}, op), { path: "/" +
[prefix, ...op.path.split("/")]
.filter((it) => it !== "")
.join("/"), authorizationRole: null }),
];
return op.authorizationRoles.map((role) => (Object.assign(Object.assign({}, op), { path: "/" +
[prefix, role, ...op.path.split("/")]
.filter((it) => it !== "")
.join("/"), authorizationRole: role })));
});
progress.completed += matrix.flat().length;
progress.total += matrix
.filter((it) => it.length > 1)
.map((it) => it.length - 1)
.reduce((a, b) => a + b, 0);
pointer.value.push(...matrix.flat());
},
}),
],
});
(0, enforceToolCall_1.enforceToolCall)(agentica);
yield agentica.conversate("Make API operations").finally(() => {
const tokenUsage = agentica.getTokenUsage();
ctx.usage().record(tokenUsage, ["interface"]);
});
if (pointer.value === null)
throw new Error("Failed to create operations."); // never be happened
return pointer.value;
});
}
function createApplication(props) {
(0, assertSchemaModel_1.assertSchemaModel)(props.model);
const application = collection[props.model];
application.functions[0].validate = (next) => {
const result = (() => { const _io0 = input => Array.isArray(input.operations) && input.operations.every(elem => "object" === typeof elem && null !== elem && _io1(elem)); const _io1 = input => Array.isArray(input.authorizationRoles) && input.authorizationRoles.every(elem => "string" === typeof elem && 1 <= elem.length) && "string" === typeof input.description && "string" === typeof input.name && "string" === typeof input.specification && "string" === typeof input.summary && ("string" === typeof input.path && RegExp("^\\/[a-zA-Z0-9\\/_{}.-]*$").test(input.path)) && (Array.isArray(input.parameters) && input.parameters.every(elem => "object" === typeof elem && null !== elem && _io2(elem))) && (null === input.requestBody || "object" === typeof input.requestBody && null !== input.requestBody && _io6(input.requestBody)) && (null === input.responseBody || "object" === typeof input.responseBody && null !== input.responseBody && _io7(input.responseBody)) && ("get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method); const _io2 = input => "string" === typeof input.name && "string" === typeof input.description && ("object" === typeof input.schema && null !== input.schema && _iu0(input.schema)); const _io3 = input => (undefined === input.minimum || "number" === typeof input.minimum && (Math.floor(input.minimum) === input.minimum && -9223372036854776000 <= input.minimum && input.minimum <= 9223372036854776000)) && (undefined === input.maximum || "number" === typeof input.maximum && (Math.floor(input.maximum) === input.maximum && -9223372036854776000 <= input.maximum && input.maximum <= 9223372036854776000)) && (undefined === input.exclusiveMinimum || "number" === typeof input.exclusiveMinimum) && (undefined === input.exclusiveMaximum || "number" === typeof input.exclusiveMaximum) && (undefined === input.multipleOf || "number" === typeof input.multipleOf && (Math.floor(input.multipleOf) === input.multipleOf && 0 <= input.multipleOf && input.multipleOf <= 18446744073709552000 && 0 < input.multipleOf)) && "integer" === input.type; const _io4 = input => (undefined === input.minimum || "number" === typeof input.minimum) && (undefined === input.maximum || "number" === typeof input.maximum) && (undefined === input.exclusiveMinimum || "number" === typeof input.exclusiveMinimum) && (undefined === input.exclusiveMaximum || "number" === typeof input.exclusiveMaximum) && (undefined === input.multipleOf || "number" === typeof input.multipleOf && 0 < input.multipleOf) && "number" === input.type; const _io5 = input => (undefined === input.format || "string" === typeof input.format) && (undefined === input.pattern || "string" === typeof input.pattern) && (undefined === input.contentMediaType || "string" === typeof input.contentMediaType) && (undefined === input.minLength || "number" === typeof input.minLength && (Math.floor(input.minLength) === input.minLength && 0 <= input.minLength && input.minLength <= 18446744073709552000)) && (undefined === input.maxLength || "number" === typeof input.maxLength && (Math.floor(input.maxLength) === input.maxLength && 0 <= input.maxLength && input.maxLength <= 18446744073709552000)) && "string" === input.type; const _io6 = input => "string" === typeof input.description && "string" === typeof input.typeName; const _io7 = input => "string" === typeof input.description && "string" === typeof input.typeName; const _iu0 = input => (() => {
if ("number" === input.type)
return _io4(input);
else if ("integer" === input.type)
return _io3(input);
else if ("string" === input.type)
return _io5(input);
else
return false;
})(); const _vo0 = (input, _path, _exceptionable = true) => [(Array.isArray(input.operations) || _report(_exceptionable, {
path: _path + ".operations",
expected: "Array<IAutoBeInterfaceOperationApplication.IOperation>",
value: input.operations
})) && input.operations.map((elem, _index4) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
path: _path + ".operations[" + _index4 + "]",
expected: "IAutoBeInterfaceOperationApplication.IOperation",
value: elem
})) && _vo1(elem, _path + ".operations[" + _index4 + "]", true && _exceptionable) || _report(_exceptionable, {
path: _path + ".operations[" + _index4 + "]",
expected: "IAutoBeInterfaceOperationApplication.IOperation",
value: elem
})).every(flag => flag) || _report(_exceptionable, {
path: _path + ".operations",
expected: "Array<IAutoBeInterfaceOperationApplication.IOperation>",
value: input.operations
})].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => [(Array.isArray(input.authorizationRoles) || _report(_exceptionable, {
path: _path + ".authorizationRoles",
expected: "Array<string & MinLength<1>>",
value: input.authorizationRoles
})) && input.authorizationRoles.map((elem, _index5) => "string" === typeof elem && (1 <= elem.length || _report(_exceptionable, {
path: _path + ".authorizationRoles[" + _index5 + "]",
expected: "string & MinLength<1>",
value: elem
})) || _report(_exceptionable, {
path: _path + ".authorizationRoles[" + _index5 + "]",
expected: "(string & MinLength<1>)",
value: elem
})).every(flag => flag) || _report(_exceptionable, {
path: _path + ".authorizationRoles",
expected: "Array<string & MinLength<1>>",
value: input.authorizationRoles
}), "string" === typeof input.description || _report(_exceptionable, {
path: _path + ".description",
expected: "string",
value: input.description
}), "string" === typeof input.name || _report(_exceptionable, {
path: _path + ".name",
expected: "string",
value: input.name
}), "string" === typeof input.specification || _report(_exceptionable, {
path: _path + ".specification",
expected: "string",
value: input.specification
}), "string" === typeof input.summary || _report(_exceptionable, {
path: _path + ".summary",
expected: "string",
value: input.summary
}), "string" === typeof input.path && (RegExp("^\\/[a-zA-Z0-9\\/_{}.-]*$").test(input.path) || _report(_exceptionable, {
path: _path + ".path",
expected: "string & Pattern<\"^\\\\/[a-zA-Z0-9\\\\/_{}.-]*$\">",
value: input.path
})) || _report(_exceptionable, {
path: _path + ".path",
expected: "(string & Pattern<\"^\\\\/[a-zA-Z0-9\\\\/_{}.-]*$\">)",
value: input.path
}), (Array.isArray(input.parameters) || _report(_exceptionable, {
path: _path + ".parameters",
expected: "Array<AutoBeOpenApi.IParameter>",
value: input.parameters
})) && input.parameters.map((elem, _index6) => ("object" === typeof elem && null !== elem || _report(_exceptionable, {
path: _path + ".parameters[" + _index6 + "]",
expected: "AutoBeOpenApi.IParameter",
value: elem
})) && _vo2(elem, _path + ".parameters[" + _index6 + "]", true && _exceptionable) || _report(_exceptionable, {
path: _path + ".parameters[" + _index6 + "]",
expected: "AutoBeOpenApi.IParameter",
value: elem
})).every(flag => flag) || _report(_exceptionable, {
path: _path + ".parameters",
expected: "Array<AutoBeOpenApi.IParameter>",
value: input.parameters
}), null === input.requestBody || ("object" === typeof input.requestBody && null !== input.requestBody || _report(_exceptionable, {
path: _path + ".requestBody",
expected: "(AutoBeOpenApi.IRequestBody | null)",
value: input.requestBody
})) && _vo6(input.requestBody, _path + ".requestBody", true && _exceptionable) || _report(_exceptionable, {
path: _path + ".requestBody",
expected: "(AutoBeOpenApi.IRequestBody | null)",
value: input.requestBody
}), null === input.responseBody || ("object" === typeof input.responseBody && null !== input.responseBody || _report(_exceptionable, {
path: _path + ".responseBody",
expected: "(AutoBeOpenApi.IResponseBody | null)",
value: input.responseBody
})) && _vo7(input.responseBody, _path + ".responseBody", true && _exceptionable) || _report(_exceptionable, {
path: _path + ".responseBody",
expected: "(AutoBeOpenApi.IResponseBody | null)",
value: input.responseBody
}), "get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method || _report(_exceptionable, {
path: _path + ".method",
expected: "(\"delete\" | \"get\" | \"patch\" | \"post\" | \"put\")",
value: input.method
})].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["string" === typeof input.name || _report(_exceptionable, {
path: _path + ".name",
expected: "string",
value: input.name
}), "string" === typeof input.description || _report(_exceptionable, {
path: _path + ".description",
expected: "string",
value: input.description
}), ("object" === typeof input.schema && null !== input.schema || _report(_exceptionable, {
path: _path + ".schema",
expected: "(AutoBeOpenApi.IJsonSchema.IInteger | AutoBeOpenApi.IJsonSchema.INumber | AutoBeOpenApi.IJsonSchema.IString)",
value: input.schema
})) && _vu0(input.schema, _path + ".schema", true && _exceptionable) || _report(_exceptionable, {
path: _path + ".schema",
expected: "(AutoBeOpenApi.IJsonSchema.IInteger | AutoBeOpenApi.IJsonSchema.INumber | AutoBeOpenApi.IJsonSchema.IString)",
value: input.schema
})].every(flag => flag); const _vo3 = (input, _path, _exceptionable = true) => [undefined === input.minimum || "number" === typeof input.minimum && (Math.floor(input.minimum) === input.minimum && -9223372036854776000 <= input.minimum && input.minimum <= 9223372036854776000 || _report(_exceptionable, {
path: _path + ".minimum",
expected: "number & Type<\"int64\">",
value: input.minimum
})) || _report(_exceptionable, {
path: _path + ".minimum",
expected: "((number & Type<\"int64\">) | undefined)",
value: input.minimum
}), undefined === input.maximum || "number" === typeof input.maximum && (Math.floor(input.maximum) === input.maximum && -9223372036854776000 <= input.maximum && input.maximum <= 9223372036854776000 || _report(_exceptionable, {
path: _path + ".maximum",
expected: "number & Type<\"int64\">",
value: input.maximum
})) || _report(_exceptionable, {
path: _path + ".maximum",
expected: "((number & Type<\"int64\">) | undefined)",
value: input.maximum
}), undefined === input.exclusiveMinimum || "number" === typeof input.exclusiveMinimum || _report(_exceptionable, {
path: _path + ".exclusiveMinimum",
expected: "(number | undefined)",
value: input.exclusiveMinimum
}), undefined === input.exclusiveMaximum || "number" === typeof input.exclusiveMaximum || _report(_exceptionable, {
path: _path + ".exclusiveMaximum",
expected: "(number | undefined)",
value: input.exclusiveMaximum
}), undefined === input.multipleOf || "number" === typeof input.multipleOf && (Math.floor(input.multipleOf) === input.multipleOf && 0 <= input.multipleOf && input.multipleOf <= 18446744073709552000 || _report(_exceptionable, {
path: _path + ".multipleOf",
expected: "number & Type<\"uint64\">",
value: input.multipleOf
})) && (0 < input.multipleOf || _report(_exceptionable, {
path: _path + ".multipleOf",
expected: "number & ExclusiveMinimum<0>",
value: input.multipleOf
})) || _report(_exceptionable, {
path: _path + ".multipleOf",
expected: "((number & Type<\"uint64\"> & ExclusiveMinimum<0>) | undefined)",
value: input.multipleOf
}), "integer" === input.type || _report(_exceptionable, {
path: _path + ".type",
expected: "\"integer\"",
value: input.type
})].every(flag => flag); const _vo4 = (input, _path, _exceptionable = true) => [undefined === input.minimum || "number" === typeof input.minimum || _report(_exceptionable, {
path: _path + ".minimum",
expected: "(number | undefined)",
value: input.minimum
}), undefined === input.maximum || "number" === typeof input.maximum || _report(_exceptionable, {
path: _path + ".maximum",
expected: "(number | undefined)",
value: input.maximum
}), undefined === input.exclusiveMinimum || "number" === typeof input.exclusiveMinimum || _report(_exceptionable, {
path: _path + ".exclusiveMinimum",
expected: "(number | undefined)",
value: input.exclusiveMinimum
}), undefined === input.exclusiveMaximum || "number" === typeof input.exclusiveMaximum || _report(_exceptionable, {
path: _path + ".exclusiveMaximum",
expected: "(number | undefined)",
value: input.exclusiveMaximum
}), undefined === input.multipleOf || "number" === typeof input.multipleOf && (0 < input.multipleOf || _report(_exceptionable, {
path: _path + ".multipleOf",
expected: "number & ExclusiveMinimum<0>",
value: input.multipleOf
})) || _report(_exceptionable, {
path: _path + ".multipleOf",
expected: "((number & ExclusiveMinimum<0>) | undefined)",
value: input.multipleOf
}), "number" === input.type || _report(_exceptionable, {
path: _path + ".type",
expected: "\"number\"",
value: input.type
})].every(flag => flag); const _vo5 = (input, _path, _exceptionable = true) => [undefined === input.format || "string" === typeof input.format || _report(_exceptionable, {
path: _path + ".format",
expected: "(string | undefined)",
value: input.format
}), undefined === input.pattern || "string" === typeof input.pattern || _report(_exceptionable, {
path: _path + ".pattern",
expected: "(string | undefined)",
value: input.pattern
}), undefined === input.contentMediaType || "string" === typeof input.contentMediaType || _report(_exceptionable, {
path: _path + ".contentMediaType",
expected: "(string | undefined)",
value: input.contentMediaType
}), undefined === input.minLength || "number" === typeof input.minLength && (Math.floor(input.minLength) === input.minLength && 0 <= input.minLength && input.minLength <= 18446744073709552000 || _report(_exceptionable, {
path: _path + ".minLength",
expected: "number & Type<\"uint64\">",
value: input.minLength
})) || _report(_exceptionable, {
path: _path + ".minLength",
expected: "((number & Type<\"uint64\">) | undefined)",
value: input.minLength
}), undefined === input.maxLength || "number" === typeof input.maxLength && (Math.floor(input.maxLength) === input.maxLength && 0 <= input.maxLength && input.maxLength <= 18446744073709552000 || _report(_exceptionable, {
path: _path + ".maxLength",
expected: "number & Type<\"uint64\">",
value: input.maxLength
})) || _report(_exceptionable, {
path: _path + ".maxLength",
expected: "((number & Type<\"uint64\">) | undefined)",
value: input.maxLength
}), "string" === input.type || _report(_exceptionable, {
path: _path + ".type",
expected: "\"string\"",
value: input.type
})].every(flag => flag); const _vo6 = (input, _path, _exceptionable = true) => ["string" === typeof input.description || _report(_exceptionable, {
path: _path + ".description",
expected: "string",
value: input.description
}), "string" === typeof input.typeName || _report(_exceptionable, {
path: _path + ".typeName",
expected: "string",
value: input.typeName
})].every(flag => flag); const _vo7 = (input, _path, _exceptionable = true) => ["string" === typeof input.description || _report(_exceptionable, {
path: _path + ".description",
expected: "string",
value: input.description
}), "string" === typeof input.typeName || _report(_exceptionable, {
path: _path + ".typeName",
expected: "string",
value: input.typeName
})].every(flag => flag); const _vu0 = (input, _path, _exceptionable = true) => (() => {
if ("number" === input.type)
return _vo4(input, _path, true && _exceptionable);
else if ("integer" === input.type)
return _vo3(input, _path, true && _exceptionable);
else if ("string" === input.type)
return _vo5(input, _path, true && _exceptionable);
else
return _report(_exceptionable, {
path: _path,
expected: "(AutoBeOpenApi.IJsonSchema.INumber | AutoBeOpenApi.IJsonSchema.IInteger | AutoBeOpenApi.IJsonSchema.IString)",
value: input
});
})(); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => {
if (false === __is(input)) {
errors = [];
_report = __typia_transform__validateReport._validateReport(errors);
((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, {
path: _path + "",
expected: "IAutoBeInterfaceOperationApplication.IProps",
value: input
})) && _vo0(input, _path + "", true) || _report(true, {
path: _path + "",
expected: "IAutoBeInterfaceOperationApplication.IProps",
value: input
}))(input, "$input", true);
const success = 0 === errors.length;
return success ? {
success,
data: input
} : {
success,
errors,
data: input
};
}
return {
success: true,
data: input
};
}; })()(next);
if (result.success === false)
return result;
const operations = result.data.operations;
const errors = [];
operations.forEach((op, i) => {
if (op.method === "get" && op.requestBody !== null)
errors.push({
path: `$input.operations[${i}].requestBody`,
expected: "GET method should not have request body. Change method, or re-design the operation.",
value: op.requestBody,
});
if (props.roles.length === 0)
op.authorizationRoles = [];
else if (op.authorizationRoles.length !== 0 && props.roles.length !== 0)
op.authorizationRoles.forEach((role, j) => {
if (props.roles.includes(role) === true)
return;
errors.push({
path: `$input.operations[${i}].authorizationRoles[${j}]`,
expected: `null | ${props.roles.map((str) => JSON.stringify(str)).join(" | ")}`,
description: [
`Role "${role}" is not defined in the roles list.`,
"",
"Please select one of them below, or do not define (`null`): ",
"",
...props.roles.map((role) => `- ${role}`),
].join("\n"),
value: role,
});
});
});
if (errors.length !== 0)
return {
success: false,
errors,
data: next,
};
return result;
};
return {
protocol: "class",
name: "interface",
application,
execute: {
makeOperations: (next) => {
props.build(next.operations);
},
},
};
}
const claude = {
model: "claude",
options: {
reference: true,
separate: null
},
functions: [
{
name: "makeOperations",
parameters: {
description: " Properties containing the operations to generate.\n\n------------------------------\n\nCurrent Type: {@link IAutoBeInterfaceOperationApplication.IProps}",
type: "object",
properties: {
operations: {
description: "Array of API operations to generate.\n\nEach operation in this array must include:\n\n- Specification: Detailed API specification with clear purpose and\n functionality\n- Path: Resource-centric URL path (e.g., \"/resources/{resourceId}\")\n- Method: HTTP method (get, post, put, delete, patch)\n- Description: Extremely detailed multi-paragraph description referencing\n Prisma schema comments\n- Summary: Concise one-sentence summary of the endpoint\n- Parameters: Array of all necessary parameters with descriptions and\n schema definitions\n- RequestBody: For POST/PUT/PATCH methods, with typeName referencing\n components.schemas\n- ResponseBody: With typeName referencing appropriate response type\n\nAll operations must follow strict quality standards:\n\n1. Detailed descriptions referencing Prisma schema comments\n2. Accurate parameter definitions matching path parameters\n3. Appropriate request/response body type references\n4. Consistent patterns for CRUD operations\n\nFor list retrievals (typically PATCH), include pagination, search, and\nsorting. For detail retrieval (GET), return a single resource. For\ncreation (POST), use .ICreate request body. For modification (PUT), use\n.IUpdate request body.",
type: "array",
items: {
$ref: "#/$defs/IAutoBeInterfaceOperationApplication.IOperation"
}
}
},
required: [
"operations"
],
additionalProperties: false,
$defs: {
"IAutoBeInterfaceOperationApplication.IOperation": {
description: "Operation of the Restful API.\n\nThis interface defines a single API endpoint with its HTTP {@link method},\n{@link path}, {@link parameters path parameters},\n{@link requestBody request body}, and {@link responseBody} structure. It\ncorresponds to an individual operation in the paths section of an OpenAPI\ndocument.\n\nEach operation requires a detailed explanation of its purpose through the\nreason and description fields, making it clear why the API was designed and\nhow it should be used.\n\nAll request bodies and responses for this operation must be object types\nand must reference named types defined in the components section. The\ncontent-type is always `application/json`. For file upload/download\noperations, use `string & tags.Format<\"uri\">` in the appropriate schema\ninstead of binary data formats.\n\nIn OpenAPI, this might represent:\n\n```json\n{\n \"/shoppings/customers/orders\": {\n \"post\": {\n \"description\": \"Create a new order application from shopping cart...\",\n \"parameters\": [...],\n \"requestBody\": {...},\n \"responses\": {...}\n }\n }\n}\n```",
type: "object",
properties: {
authorizationRoles: {
description: "Authorization roles required to access this API operation.\n\nThis field specifies which user roles are allowed to access this\nendpoint. Multiple roles can be specified to allow different types of\nusers to access the same endpoint.\n\n## Important Guidelines\n\n- Set to empty array `[]` for public endpoints that require no\n authentication\n- Set to array with role strings for role-restricted endpoints\n- The role names MUST match exactly with the user type/role defined in the\n database\n- This will be used by the Realize Agent to generate appropriate decorator\n and authorization logic in the provider functions\n- The controller will apply the corresponding authentication decorator\n based on these roles\n\n## Examples\n\n- `[]` - Public endpoint, no authentication required\n- `[\"user\"]` - Any authenticated user can access\n- `[\"admin\"]` - Only admin users can access\n- `[\"admin\", \"moderator\"]` - Both admin and moderator users can access\n- `[\"seller\"]` - Only seller users can access\n\nNote: The actual authentication/authorization implementation will be\nhandled by decorators at the controller level, and the provider function\nwill receive the authenticated user object with the appropriate type.",
type: "array",
items: {
type: "string",
minLength: 1
}
},
description: {
description: "Detailed description about the API operation.\n\nIMPORTANT: This field MUST be extensively detailed and MUST reference the\ndescription comments from the related Prisma DB schema tables and\ncolumns. The description should be organized into MULTIPLE PARAGRAPHS\nseparated by line breaks to improve readability and comprehension.\n\nFor example, include separate paragraphs for:\n\n- The purpose and overview of the API operation\n- Security considerations and user permissions\n- Relationship to underlying database entities\n- Validation rules and business logic\n- Related API operations that might be used together with this one\n- Expected behavior and error handling\n\nWhen writing the description, be sure to incorporate the corresponding DB\nschema's description comments, matching the level of detail and style of\nthose comments. This ensures consistency between the API documentation\nand database structure.\n\nIf there's a dependency to other APIs, please describe the dependency API\noperation in this field with detailed reason. For example, if this API\noperation needs a pre-execution of other API operation, it must be\nexplicitly described.\n\n- `GET /shoppings/customers/sales` must be pre-executed to get entire list\n of summarized sales. Detailed sale information would be obtained by\n specifying the sale ID in the path parameter.\n\n> MUST be written in English. Never use other languages.",
type: "string"
},
name: {
description: "Functional name of the API endpoint.\n\nThis is a semantic identifier that represents the primary function or\npurpose of the API endpoint. It serves as a canonical name that can be\nused for code generation, SDK method names, and internal references.\n\n## Standard Endpoint Names\n\nUse these conventional names based on the endpoint's primary function:\n\n- **`index`**: List/search operations that return multiple entities\n\n - Typically used with PATCH method for complex queries\n - Example: `PATCH /users` \u2192 `name: \"index\"`\n- **`at`**: Retrieve a specific entity by identifier\n\n - Typically used with GET method on single resource\n - Example: `GET /users/{userId}` \u2192 `name: \"at\"`\n- **`create`**: Create a new entity\n\n - Typically used with POST method\n - Example: `POST /users` \u2192 `name: \"create\"`\n- **`update`**: Update an existing entity\n\n - Typically used with PUT method\n - Example: `PUT /users/{userId}` \u2192 `name: \"update\"`\n- **`erase`**: Delete/remove an entity\n\n - Typically used with DELETE method\n - Example: `DELETE /users/{userId}` \u2192 `name: \"erase\"`\n\n## Custom Endpoint Names\n\nFor specialized operations beyond basic CRUD, use descriptive verbs:\n\n- **`activate`**: Enable or turn on a feature/entity\n- **`deactivate`**: Disable or turn off a feature/entity\n- **`approve`**: Approve a request or entity\n- **`reject`**: Reject a request or entity\n- **`publish`**: Make content publicly available\n- **`archive`**: Move to archived state\n- **`restore`**: Restore from archived/deleted state\n- **`duplicate`**: Create a copy of an entity\n- **`transfer`**: Move ownership or change assignment\n- **`validate`**: Validate data or state\n- **`process`**: Execute a business process or workflow\n- **`export`**: Generate downloadable data\n- **`import`**: Process uploaded data\n\n## Naming Guidelines\n\n- Use lowercase, singular verb forms\n- Be concise but descriptive\n- Avoid abbreviations unless widely understood\n- Ensure the name clearly represents the endpoint's primary action\n- For nested resources, focus on the action rather than hierarchy\n\nExamples:\n\n- `GET /shopping/orders/{orderId}/items` \u2192 `name: \"index\"` (lists items)\n- `POST /shopping/orders/{orderId}/cancel` \u2192 `name: \"cancel\"`\n- `PUT /users/{userId}/password` \u2192 `name: \"updatePassword\"`",
type: "string"
},
specification: {
description: "Specification of the API operation.\n\nBefore defining the API operation interface, please describe what you're\nplanning to write in this `specification` field.\n\nThe specification must be fully detailed and clear, so that anyone can\nunderstand the purpose and functionality of the API operation and its\nrelated components (e.g., {@link path}, {@link parameters},\n{@link requestBody}).\n\nIMPORTANT: The specification MUST identify which Prisma DB table this\noperation is associated with, helping ensure complete coverage of all\ndatabase entities.",
type: "string"
},
summary: {
description: "Short summary of the API operation.\n\nThis should be a concise description of the API operation, typically one\nsentence long. It should provide a quick overview of what the API does\nwithout going into too much detail.\n\nThis summary will be used in the OpenAPI documentation to give users a\nquick understanding of the API operation's purpose.\n\nIMPORTANT: The summary should clearly indicate which Prisma DB table this\noperation relates to, helping to ensure all tables have API coverage.\n\n> MUST be written in English. Never use other languages",
type: "string"
},
path: {
description: "HTTP path of the API operation.\n\nThe URL path for accessing this API operation, using path parameters\nenclosed in curly braces (e.g., `/shoppings/customers/sales/{saleId}`).\n\nIt must be corresponded to the {@link parameters path parameters}.\n\nThe path structure should clearly indicate which database entity this\noperation is manipulating, helping to ensure all entities have\nappropriate API coverage.\n\nPath validation rules:\n\n- Must start with a forward slash (/)\n- Can contain only: letters (a-z, A-Z), numbers (0-9), forward slashes (/),\n curly braces for parameters ({paramName}), hyphens (-), and underscores\n (_)\n- Parameters must be enclosed in curly braces: {paramName}\n- Resource names should be in camelCase\n- No quotes, spaces, or invalid special characters allowed\n- No domain or role-based prefixes\n\nValid examples:\n\n- \"/users\"\n- \"/users/{userId}\"\n- \"/articles/{articleId}/comments\"\n- \"/attachmentFiles\"\n- \"/orders/{orderId}/items/{itemId}\"\n\nInvalid examples:\n\n- \"'/users'\" (contains quotes)\n- \"/user profile\" (contains space)\n- \"/users/[userId]\" (wrong bracket format)\n- \"/admin/users\" (role prefix)\n- \"/api/v1/users\" (API prefix)",
type: "string",
pattern: "^\\/[a-zA-Z0-9\\/_{}.-]*$"
},
parameters: {
description: "List of path parameters.\n\nNote that, the {@link AutoBeOpenApi.IParameter.name identifier name} of\npath parameter must be corresponded to the\n{@link path API operation path}.\n\nFor example, if there's an API operation which has {@link path} of\n`/shoppings/customers/sales/{saleId}/questions/${questionId}/comments/${commentId}`,\nits list of {@link AutoBeOpenApi.IParameter.name path parameters} must be\nlike:\n\n- `saleId`\n- `questionId`\n- `commentId`",
type: "array",
items: {
$ref: "#/$defs/AutoBeOpenApi.IParameter"
}
},
requestBody: {
description: "Request body of the API operation.\n\nDefines the payload structure for the request. Contains a description and\nschema reference to define the expected input data.\n\nShould be `null` for operations that don't require a request body, such\nas most \"get\" operations.",
oneOf: [
{
type: "null"
},
{
$ref: "#/$defs/AutoBeOpenApi.IRequestBody"
}
]
},
responseBody: {
description: "Response body of the API operation.\n\nDefines the structure of the successful response data. Contains a\ndescription and schema reference for the returned data.\n\nShould be null for operations that don't return any data.",
oneOf: [
{
type: "null"
},
{
$ref: "#/$defs/AutoBeOpenApi.IResponseBody"
}
]
},
method: {
description: "HTTP method of the API operation.\n\nNote that, if the API operation has {@link requestBody}, method must not\nbe `get`.\n\nAlso, even though the API operation has been designed to only get\ninformation, but it needs complicated request information, it must be\ndefined as `patch` method with {@link requestBody} data specification.\n\n- `get`: get information\n- `patch`: get information with complicated request data\n ({@link requestBody})\n- `post`: create new record\n- `put`: update existing record\n- `delete`: remove record",
oneOf: [
{
"const": "get"
},
{
"const": "post"
},
{
"const": "put"
},
{
"const": "delete"
},
{
"const": "patch"
}
]
}
},
required: [
"authorizationRoles",
"description",
"name",
"specification",
"summary",
"path",
"parameters",
"requestBody",
"responseBody",
"method"
]
},
"AutoBeOpenApi.IParameter": {
description: "Path parameter information for API routes.\n\nThis interface defines a path parameter that appears in the URL of an API\nendpoint. Path parameters are enclosed in curly braces in the\n{@link AutoBeOpenApi.IOperation.path operation path} and must be defined\nwith their types and descriptions.\n\nFor example, if API operation path is\n`/shoppings/customers/sales/{saleId}/questions/${questionId}/comments/${commentId}`,\nthe path parameters should be like below:\n\n```json\n{\n \"path\": \"/shoppings/customers/sales/{saleId}/questions/${questionId}/comments/${commentId}\",\n \"method\": \"get\",\n \"parameters\": [\n {\n \"name\": \"saleId\",\n \"in\": \"path\",\n \"schema\": { \"type\": \"string\", \"format\": \"uuid\" },\n \"description\": \"Target sale's ID\"\n },\n {\n \"name\": \"questionId\",\n \"in\": \"path\",\n \"schema\": { \"type\": \"string\", \"format\": \"uuid\" },\n \"description\": \"Target question's ID\"\n },\n {\n \"name\": \"commentId\",\n \"in\": \"path\",\n \"schema\": { \"type\": \"string\", \"format\": \"uuid\" },\n \"description\": \"Target comment's ID\"\n }\n ]\n}\n```",
type: "object",
properties: {
name: {
description: "Identifier name of the path parameter.\n\nThis name must match exactly with the parameter name in the route path.\nIt must be corresponded to the\n{@link AutoBeOpenApi.IOperation.path API operation path}.",
type: "string"
},
description: {
description: "Description about the path parameter.\n\nMake short, concise and clear description about the path parameter.\n\n> MUST be written in English. Never use other languages.",
type: "string"
},
schema: {
description: "Type schema of the path parameter.\n\nPath parameters are typically primitive types like\n{@link AutoBeOpenApi.IJsonSchema.IString strings},\n{@link AutoBeOpenApi.IJsonSchema.IInteger integers},\n{@link AutoBeOpenApi.IJsonSchema.INumber numbers}.\n\nIf you need other types, please use request body instead with object type\nencapsulation.",
oneOf: [
{
$ref: "#/$defs/AutoBeOpenApi.IJsonSchema.INumber"
},
{
$ref: "#/$defs/AutoBeOpenApi.IJsonSchema.IInteger"
},
{
$ref: "#/$defs/AutoBeOpenApi.IJsonSchema.IString"
}
],
discriminator: {
propertyName: "type",
mapping: {
number: "#/$defs/AutoBeOpenApi.IJsonSchema.INumber",
integer: "#/$defs/AutoBeOpenApi.IJsonSchema.IInte