UNPKG

@autobe/agent

Version:

AI backend server code generator

752 lines 181 kB
"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.orchestrateTestScenario = void 0; const __typia_transform__validateReport = __importStar(require("typia/lib/internal/_validateReport.js")); const __typia_transform__llmApplicationFinalize = __importStar(require("typia/lib/internal/_llmApplicationFinalize.js")); const utils_1 = require("@autobe/utils"); const tstl_1 = require("tstl"); const typia_1 = __importDefault(require("typia")); const NamingConvention_1 = require("typia/lib/utils/NamingConvention"); const uuid_1 = require("uuid"); const assertSchemaModel_1 = require("../../context/assertSchemaModel"); const divideArray_1 = require("../../utils/divideArray"); const executeCachedBatch_1 = require("../../utils/executeCachedBatch"); const AutoBePreliminaryController_1 = require("../common/AutoBePreliminaryController"); const transformTestScenarioHistory_1 = require("./histories/transformTestScenarioHistory"); const orchestrateTestScenarioReview_1 = require("./orchestrateTestScenarioReview"); const getPrerequisites_1 = require("./utils/getPrerequisites"); const orchestrateTestScenario = (ctx, instruction) => __awaiter(void 0, void 0, void 0, function* () { var _a; const document = (_a = ctx.state().interface) === null || _a === void 0 ? void 0 : _a.document; if (document === undefined) { throw new Error("Cannot write test scenarios because these are no operations."); } const dict = new tstl_1.HashMap(document.operations.map((op) => new tstl_1.Pair({ path: op.path, method: op.method, }, op)), utils_1.AutoBeOpenApiEndpointComparator.hashCode, utils_1.AutoBeOpenApiEndpointComparator.equals); const endpointNotFound = [ `You have to select one of the endpoints below`, "", " method | path ", "--------|------", ...document.operations .map((op) => `\`${op.method}\` | \`${op.path}\``) .join("\n"), ].join("\n"); const progress = { total: document.operations.length, completed: 0, }; const reviewProgress = { total: document.operations.length, completed: 0, }; const exclude = []; let include = [...document.operations]; let trial = 0; do { const matrix = (0, divideArray_1.divideArray)({ array: include, capacity: 2 /* AutoBeConfigConstant.INTERFACE_CAPACITY */, }); yield (0, executeCachedBatch_1.executeCachedBatch)(ctx, matrix.map((include) => (promptCacheKey) => __awaiter(void 0, void 0, void 0, function* () { exclude.push(...(yield divideAndConquer(ctx, { dict, endpointNotFound, include, exclude: exclude.map((x) => x.endpoint), progress, reviewProgress, promptCacheKey, instruction, }))); }))); include = include.filter((op) => { if (exclude.some((pg) => pg.endpoint.method === op.method && pg.endpoint.path === op.path)) { return false; } return true; }); progress.total = include.length + exclude.length; reviewProgress.total = include.length + exclude.length; } while (include.length > 0 && ++trial < ctx.retry); return exclude.flatMap((pg) => { return pg.scenarios.map((plan) => { return { endpoint: pg.endpoint, draft: plan.draft, functionName: plan.functionName, dependencies: plan.dependencies, }; }); }); }); exports.orchestrateTestScenario = orchestrateTestScenario; const divideAndConquer = (ctx, props) => __awaiter(void 0, void 0, void 0, function* () { try { return yield process(ctx, props); } catch (_a) { return []; } }); const process = (ctx, props) => __awaiter(void 0, void 0, void 0, function* () { var _a, _b; const authorizations = (_b = (_a = ctx.state().interface) === null || _a === void 0 ? void 0 : _a.authorizations) !== null && _b !== void 0 ? _b : []; const document = ctx.state().interface.document; const preliminary = new AutoBePreliminaryController_1.AutoBePreliminaryController({ application: { version: "3.1", components: { schemas: { "IAutoBeTestScenarioApplication.IProps": { type: "object", properties: { thinking: { type: "string", description: "Think before you act.\n\nBefore requesting preliminary data or completing your task, reflect on your\ncurrent state and explain your reasoning:\n\nFor preliminary requests (getAnalysisFiles, getPrismaSchemas, etc.):\n- What critical information is missing that you don't already have?\n- Why do you need it specifically right now?\n- Be brief - state the gap, don't list everything you have.\n\nFor completion (complete):\n- What key assets did you acquire?\n- What did you accomplish?\n- Why is it sufficient to complete?\n- Summarize - don't enumerate every single item.\n\nThis reflection helps you avoid duplicate requests and premature completion." }, request: { oneOf: [ { $ref: "#/components/schemas/IAutoBePreliminaryGetAnalysisFiles" }, { $ref: "#/components/schemas/IAutoBePreliminaryGetInterfaceOperations" }, { $ref: "#/components/schemas/IAutoBePreliminaryGetInterfaceSchemas" }, { $ref: "#/components/schemas/IAutoBeTestScenarioApplication.IComplete" } ], discriminator: { propertyName: "type", mapping: { getAnalysisFiles: "#/components/schemas/IAutoBePreliminaryGetAnalysisFiles", getInterfaceOperations: "#/components/schemas/IAutoBePreliminaryGetInterfaceOperations", getInterfaceSchemas: "#/components/schemas/IAutoBePreliminaryGetInterfaceSchemas", complete: "#/components/schemas/IAutoBeTestScenarioApplication.IComplete" } }, description: "Type discriminator for the request.\n\nDetermines which action to perform: preliminary data retrieval\n(getAnalysisFiles, getInterfaceOperations, getInterfaceSchemas) or\nfinal test scenario generation (complete). When preliminary returns\nempty array, that type is removed from the union, physically\npreventing repeated calls." } }, required: [ "thinking", "request" ] }, IAutoBePreliminaryGetAnalysisFiles: { type: "object", properties: { type: { "const": "getAnalysisFiles", description: "Type discriminator for the request.\n\nDetermines which action to perform: preliminary data retrieval or actual\ntask execution. Value \"getAnalysisFiles\" indicates this is a preliminary\ndata request for analysis files." }, fileNames: { type: "array", items: { type: "string" }, minItems: 1, description: "List of analysis file names to retrieve.\n\nFile names from the analyze phase containing requirements, use cases, and\nbusiness logic documentation.\n\nCRITICAL: DO NOT request the same file names that you have already\nrequested in previous calls." } }, required: [ "type", "fileNames" ], description: "Request to retrieve requirements analysis files for context.\n\nThis type is used in the preliminary phase to request specific analysis files\nthat provide business requirements and domain context." }, IAutoBePreliminaryGetInterfaceOperations: { type: "object", properties: { type: { "const": "getInterfaceOperations", description: "Type discriminator for the request.\n\nDetermines which action to perform: preliminary data retrieval or actual\ntask execution. Value \"getInterfaceOperations\" indicates this is a\npreliminary data request for interface operations." }, endpoints: { type: "array", items: { $ref: "#/components/schemas/AutoBeOpenApi.IEndpoint" }, minItems: 1, description: "List of existing API operation endpoints to retrieve.\n\nOperations that have been generated in previous phases, containing paths,\nmethods, parameters, and request/response bodies.\n\nCRITICAL: DO NOT request the same endpoints that you have already requested\nin previous calls." } }, required: [ "type", "endpoints" ], description: "Request to retrieve existing interface operations for context.\n\nThis type is used in the preliminary phase to request already-generated API\noperations for review, validation, or complementary generation tasks." }, "AutoBeOpenApi.IEndpoint": { type: "object", properties: { path: { type: "string", pattern: "^\\/[a-zA-Z0-9\\/_{}.-]*$", 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)" }, method: { oneOf: [ { "const": "get" }, { "const": "post" }, { "const": "put" }, { "const": "delete" }, { "const": "patch" } ], description: "HTTP method of the API operation.\n\n**IMPORTANT**: Methods must be written in lowercase only (e.g., \"get\",\nnot \"GET\").\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" } }, required: [ "path", "method" ], description: "API endpoint information." }, IAutoBePreliminaryGetInterfaceSchemas: { type: "object", properties: { type: { "const": "getInterfaceSchemas", description: "Type discriminator for the request.\n\nDetermines which action to perform: preliminary data retrieval or actual\ntask execution. Value \"getInterfaceSchemas\" indicates this is a preliminary\ndata request for interface schemas." }, typeNames: { type: "array", items: { type: "string" }, minItems: 1, description: "List of schema type names to retrieve.\n\nSchema names from the OpenAPI components.schemas section (e.g., \"IUser\",\n\"IUser.ICreate\", \"IPost.IUpdate\").\n\nCRITICAL: DO NOT request the same type names that you have already\nrequested in previous calls." } }, required: [ "type", "typeNames" ], description: "Request to retrieve OpenAPI schema type definitions for context.\n\nThis type is used in the preliminary phase to request specific schema\ndefinitions from components.schemas for review or complementary generation." }, "IAutoBeTestScenarioApplication.IComplete": { type: "object", properties: { type: { "const": "complete", description: "Type discriminator for the request.\n\nDetermines which action to perform: preliminary data retrieval or actual\ntask execution. Value \"complete\" indicates this is the final task\nexecution request." }, scenarioGroups: { type: "array", items: { $ref: "#/components/schemas/IAutoBeTestScenarioApplication.IScenarioGroup" }, description: "Collection of test scenario groups organized by endpoint.\n\nEach group contains multiple test scenarios for a single endpoint,\ncovering various user scenarios, edge cases, and business rule\nvalidations. Dependencies on other endpoints are explicitly captured to\nensure implementable tests." } }, required: [ "type", "scenarioGroups" ], description: "Request to generate test scenarios for API endpoints.\n\nExecutes test scenario generation to create comprehensive, implementable\ntest scenarios covering all endpoint behaviors, edge cases, and business\nlogic validations." }, "IAutoBeTestScenarioApplication.IScenarioGroup": { type: "object", properties: { endpoint: { $ref: "#/components/schemas/AutoBeOpenApi.IEndpoint", description: "Target API endpoint to test.\n\nThis must be **unique** across all scenario groups. An endpoint is\nidentified by its `path` and `method` combination.\n\nMultiple test scenarios may exist for a single endpoint." }, scenarios: { type: "array", items: { $ref: "#/components/schemas/IAutoBeTestScenarioApplication.IScenario" }, minItems: 1, description: "An array of test scenarios associated with the given endpoint.\n\nEach scenario represents a specific test case for the same `path` and\n`method`.\n\nIMPORTANT: Each scenario must be actually implementable. A scenario's\nimplementability is determined by the existence of ALL APIs (endpoints)\nrequired to test it. This includes not only the primary endpoint being\ntested, but also ALL dependency endpoints needed for setup,\nauthentication, and data preparation. If even one required dependency API\nis missing from the available operations, the scenario cannot be\nimplemented and should not be generated.\n\nExample: A \"test banned user login\" scenario requires both a login API\nAND a ban user API. If the ban API doesn't exist, this scenario is not\nimplementable regardless of database schema fields." } }, required: [ "endpoint", "scenarios" ] }, "IAutoBeTestScenarioApplication.IScenario": { type: "object", properties: { draft: { type: "string", description: "A detailed natural language description of how this API endpoint should\nbe tested. This should include both successful and failure scenarios,\nbusiness rule validations, edge cases, and any sequence of steps\nnecessary to perform the test. A subsequent agent will use this draft to\ngenerate multiple concrete test cases." }, functionName: { type: "string", description: "Descriptive function name derived from the user scenario.\n\nThe function name serves as a concise, technical identifier that clearly\nrepresents the specific user scenario being described. It should be\nimmediately understandable and directly correspond to the user situation\nwithout requiring additional context.\n\n## Naming Convention\n\nDO: Use snake_case naming convention.\n\n- Must start with `test_api_` prefix (mandatory requirement)\n- ALWAYS start with business feature, NOT action verbs\n- Business feature comes first, followed by scenario context\n- Embed action verbs within the scenario description, not at the beginning\n\n## Content Structure\n\nFunction names should follow this pattern:\n`test_api_[core_feature]_[specific_scenario]`\n\nWhere:\n\n- `core_feature`: The main business feature or entity being tested\n (customer, seller, cart, push_message, etc.)\n- `specific_scenario`: The specific operation or scenario context\n (join_verification_not_found, login_success,\n moderator_assignment_update, discountable_ticket_duplicated,\n csv_export, etc.)\n\n## Business Feature-Based Examples\n\n- `test_api_customer_join_verification_not_found` - Customer join\n verification when verification code not found\n- `test_api_seller_login` - Seller login operation\n- `test_api_cart_discountable_ticket_duplicated` - Cart discountable ticket\n with duplication scenario\n- `test_api_push_message_csv` - Push message functionality with CSV format\n- `test_api_product_review_update` - Product review update operation\n\n## Clarity Guidelines\n\n- Prioritize clarity over brevity\n- Avoid technical jargon or implementation terms\n- Use terminology that reflects user perspective\n- Ensure the name alone conveys the user's intent\n- Make it understandable to non-technical stakeholders\n- Keep consistent with user scenario description\n\n## Single Endpoint Alignment\n\nFunction names must reflect scenarios that:\n\n- Accomplish user goals through this single endpoint only\n- Don't imply dependency on other API operations\n- Represent complete user interactions" }, dependencies: { type: "array", items: { $ref: "#/components/schemas/IAutoBeTestScenarioApplication.IDependencies" }, description: "A list of other API endpoints that this scenario logically depends on.\n\nThese dependencies represent context or prerequisite conditions, such as\nauthentication, resource creation, or data setup, that are relevant to\nthe test. This list is not a strict execution order \u2014 if ordering is\nimportant, it must be described explicitly in the `purpose`.\n\nWARNING: Every endpoint referenced here MUST exist in the provided API\noperations. Do NOT reference endpoints that are not explicitly available,\neven if they seem logically necessary based on database schema or\nbusiness logic." } }, required: [ "draft", "functionName", "dependencies" ], description: "Represents a test scenario for a single API operation.\n\nThis interface defines a structured, user-centric test draft that includes\na descriptive function name, a detailed scenario draft, and logical\ndependencies on other endpoints required for context or setup.\n\nCRITICAL: All referenced endpoints MUST exist in the provided API\noperations. Do NOT create scenarios for non-existent APIs, even if database\nschema fields suggest their existence. Test scenarios must be implementable\nwith available APIs only." }, "IAutoBeTestScenarioApplication.IDependencies": { type: "object", properties: { endpoint: { $ref: "#/components/schemas/AutoBeOpenApi.IEndpoint", description: "Target API endpoint that this scenario depends on.\n\nThis endpoint MUST exist in the available API operations list.\nNon-existent endpoints will cause test implementation failures." }, purpose: { type: "string", description: "A concise explanation of why this API call is relevant or required for\nthe main test scenario.\n\nThis should describe the contextual or setup role of the dependency, such\nas creating necessary data or establishing user authentication.\n\nExample: \"Creates a category so that a product can be linked to it during\ncreation.\"" } }, required: [ "endpoint", "purpose" ] } } }, functions: [ { name: "process", async: false, parameters: [ { name: "props", description: " Request containing either preliminary data request or complete\ntask", required: true, schema: { $ref: "#/components/schemas/IAutoBeTestScenarioApplication.IProps" } } ], description: "Process test scenario generation task or preliminary data requests.\n\nCreates comprehensive test scenarios for API endpoints by retrieving\nnecessary interface operations via RAG (Retrieval-Augmented Generation) and\ngenerating detailed test drafts with dependencies." } ] }, source: SOURCE, kinds: ["analysisFiles", "interfaceOperations", "interfaceSchemas"], state: ctx.state(), local: { interfaceOperations: (() => { const unique = new tstl_1.HashSet(utils_1.AutoBeOpenApiEndpointComparator.hashCode, utils_1.AutoBeOpenApiEndpointComparator.equals); for (const op of props.include) { unique.insert({ method: op.method, path: op.path }); for (const pr of (0, getPrerequisites_1.getPrerequisites)({ document, endpoint: op, })) unique.insert(pr.endpoint); } return unique .toJSON() .map((endpoint) => document.operations.find((op) => op.method === endpoint.method && op.path === endpoint.path)) .filter((op) => op !== undefined); })(), }, }); return yield preliminary.orchestrate(ctx, (out) => __awaiter(void 0, void 0, void 0, function* () { var _a, _b; const pointer = { value: [], }; const result = yield ctx.conversate(Object.assign({ source: SOURCE, controller: createController({ model: ctx.model, endpointNotFound: props.endpointNotFound, dict: props.dict, authorizations, preliminary, build: (next) => { var _a; next.scenarioGroups.forEach((sg) => sg.scenarios.forEach((s) => { s.functionName = NamingConvention_1.NamingConvention.snake(s.functionName); })); (_a = pointer.value) !== null && _a !== void 0 ? _a : (pointer.value = []); pointer.value.push(...next.scenarioGroups); }, }), enforceFunctionCall: true, promptCacheKey: props.promptCacheKey }, (0, transformTestScenarioHistory_1.transformTestScenarioHistory)({ state: ctx.state(), include: props.include, exclude: props.exclude, instruction: props.instruction, preliminary, }))); if (pointer.value !== null) { if (pointer.value.length === 0) return out(result)([]); props.progress.total = Math.max(props.progress.total, (props.progress.completed += pointer.value.length)); ctx.dispatch({ type: SOURCE, id: (0, uuid_1.v7)(), metric: result.metric, tokenUsage: result.tokenUsage, scenarios: pointer.value .map((v) => v.scenarios.map((s) => ({ endpoint: v.endpoint, draft: s.draft, functionName: s.functionName, dependencies: s.dependencies, }))) .flat(), completed: props.progress.completed, total: props.progress.total, step: (_b = (_a = ctx.state().interface) === null || _a === void 0 ? void 0 : _a.step) !== null && _b !== void 0 ? _b : 0, created_at: new Date().toISOString(), }); return out(result)(yield (0, orchestrateTestScenarioReview_1.orchestrateTestScenarioReview)(ctx, { preliminary, instruction: props.instruction, groups: pointer.value, progress: props.reviewProgress, })); } return out(result)(null); })); }); const createController = (props) => { (0, assertSchemaModel_1.assertSchemaModel)(props.model); const validate = (next) => { const result = (() => { const _io0 = input => "string" === typeof input.thinking && ("object" === typeof input.request && null !== input.request && _iu0(input.request)); const _io1 = input => "getAnalysisFiles" === input.type && (Array.isArray(input.fileNames) && (1 <= input.fileNames.length && input.fileNames.every(elem => "string" === typeof elem))); const _io2 = input => "getInterfaceOperations" === input.type && (Array.isArray(input.endpoints) && (1 <= input.endpoints.length && input.endpoints.every(elem => "object" === typeof elem && null !== elem && _io3(elem)))); const _io3 = input => "string" === typeof input.path && RegExp("^\\/[a-zA-Z0-9\\/_{}.-]*$").test(input.path) && ("get" === input.method || "post" === input.method || "put" === input.method || "delete" === input.method || "patch" === input.method); const _io4 = input => "getInterfaceSchemas" === input.type && (Array.isArray(input.typeNames) && (1 <= input.typeNames.length && input.typeNames.every(elem => "string" === typeof elem))); const _io5 = input => "complete" === input.type && (Array.isArray(input.scenarioGroups) && input.scenarioGroups.every(elem => "object" === typeof elem && null !== elem && _io6(elem))); const _io6 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io3(input.endpoint) && (Array.isArray(input.scenarios) && (1 <= input.scenarios.length && input.scenarios.every(elem => "object" === typeof elem && null !== elem && _io7(elem)))); const _io7 = input => "string" === typeof input.draft && "string" === typeof input.functionName && (Array.isArray(input.dependencies) && input.dependencies.every(elem => "object" === typeof elem && null !== elem && _io8(elem))); const _io8 = input => "object" === typeof input.endpoint && null !== input.endpoint && _io3(input.endpoint) && "string" === typeof input.purpose; const _iu0 = input => (() => { if ("getAnalysisFiles" === input.type) return _io1(input); else if ("getInterfaceOperations" === input.type) return _io2(input); else if ("getInterfaceSchemas" === input.type) return _io4(input); else if ("complete" === input.type) return _io5(input); else return false; })(); const _vo0 = (input, _path, _exceptionable = true) => ["string" === typeof input.thinking || _report(_exceptionable, { path: _path + ".thinking", expected: "string", value: input.thinking }), ("object" === typeof input.request && null !== input.request || _report(_exceptionable, { path: _path + ".request", expected: "(IAutoBePreliminaryGetAnalysisFiles | IAutoBePreliminaryGetInterfaceOperations | IAutoBePreliminaryGetInterfaceSchemas | IAutoBeTestScenarioApplication.IComplete)", value: input.request })) && _vu0(input.request, _path + ".request", true && _exceptionable) || _report(_exceptionable, { path: _path + ".request", expected: "(IAutoBePreliminaryGetAnalysisFiles | IAutoBePreliminaryGetInterfaceOperations | IAutoBePreliminaryGetInterfaceSchemas | IAutoBeTestScenarioApplication.IComplete)", value: input.request })].every(flag => flag); const _vo1 = (input, _path, _exceptionable = true) => ["getAnalysisFiles" === input.type || _report(_exceptionable, { path: _path + ".type", expected: "\"getAnalysisFiles\"", value: input.type }), (Array.isArray(input.fileNames) || _report(_exceptionable, { path: _path + ".fileNames", expected: "(Array<string> & MinItems<1>)", value: input.fileNames })) && ((1 <= input.fileNames.length || _report(_exceptionable, { path: _path + ".fileNames", expected: "Array<> & MinItems<1>", value: input.fileNames })) && input.fileNames.map((elem, _index7) => "string" === typeof elem || _report(_exceptionable, { path: _path + ".fileNames[" + _index7 + "]", expected: "string", value: elem })).every(flag => flag)) || _report(_exceptionable, { path: _path + ".fileNames", expected: "(Array<string> & MinItems<1>)", value: input.fileNames })].every(flag => flag); const _vo2 = (input, _path, _exceptionable = true) => ["getInterfaceOperations" === input.type || _report(_exceptionable, { path: _path + ".type", expected: "\"getInterfaceOperations\"", value: input.type }), (Array.isArray(input.endpoints) || _report(_exceptionable, { path: _path + ".endpoints", expected: "(Array<AutoBeOpenApi.IEndpoint> & MinItems<1>)", value: input.endpoints })) && ((1 <= input.endpoints.length || _report(_exceptionable, { path: _path + ".endpoints", expected: "Array<> & MinItems<1>", value: input.endpoints })) && input.endpoints.map((elem, _index8) => ("object" === typeof elem && null !== elem || _report(_exceptionable, { path: _path + ".endpoints[" + _index8 + "]", expected: "AutoBeOpenApi.IEndpoint", value: elem })) && _vo3(elem, _path + ".endpoints[" + _index8 + "]", true && _exceptionable) || _report(_exceptionable, { path: _path + ".endpoints[" + _index8 + "]", expected: "AutoBeOpenApi.IEndpoint", value: elem })).every(flag => flag)) || _report(_exceptionable, { path: _path + ".endpoints", expected: "(Array<AutoBeOpenApi.IEndpoint> & MinItems<1>)", value: input.endpoints })].every(flag => flag); const _vo3 = (input, _path, _exceptionable = true) => ["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 }), "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 _vo4 = (input, _path, _exceptionable = true) => ["getInterfaceSchemas" === input.type || _report(_exceptionable, { path: _path + ".type", expected: "\"getInterfaceSchemas\"", value: input.type }), (Array.isArray(input.typeNames) || _report(_exceptionable, { path: _path + ".typeNames", expected: "(Array<string> & MinItems<1>)", value: input.typeNames })) && ((1 <= input.typeNames.length || _report(_exceptionable, { path: _path + ".typeNames", expected: "Array<> & MinItems<1>", value: input.typeNames })) && input.typeNames.map((elem, _index9) => "string" === typeof elem || _report(_exceptionable, { path: _path + ".typeNames[" + _index9 + "]", expected: "string", value: elem })).every(flag => flag)) || _report(_exceptionable, { path: _path + ".typeNames", expected: "(Array<string> & MinItems<1>)", value: input.typeNames })].every(flag => flag); const _vo5 = (input, _path, _exceptionable = true) => ["complete" === input.type || _report(_exceptionable, { path: _path + ".type", expected: "\"complete\"", value: input.type }), (Array.isArray(input.scenarioGroups) || _report(_exceptionable, { path: _path + ".scenarioGroups", expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>", value: input.scenarioGroups })) && input.scenarioGroups.map((elem, _index10) => ("object" === typeof elem && null !== elem || _report(_exceptionable, { path: _path + ".scenarioGroups[" + _index10 + "]", expected: "IAutoBeTestScenarioApplication.IScenarioGroup", value: elem })) && _vo6(elem, _path + ".scenarioGroups[" + _index10 + "]", true && _exceptionable) || _report(_exceptionable, { path: _path + ".scenarioGroups[" + _index10 + "]", expected: "IAutoBeTestScenarioApplication.IScenarioGroup", value: elem })).every(flag => flag) || _report(_exceptionable, { path: _path + ".scenarioGroups", expected: "Array<IAutoBeTestScenarioApplication.IScenarioGroup>", value: input.scenarioGroups })].every(flag => flag); const _vo6 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, { path: _path + ".endpoint", expected: "AutoBeOpenApi.IEndpoint", value: input.endpoint })) && _vo3(input.endpoint, _path + ".endpoint", true && _exceptionable) || _report(_exceptionable, { path: _path + ".endpoint", expected: "AutoBeOpenApi.IEndpoint", value: input.endpoint }), (Array.isArray(input.scenarios) || _report(_exceptionable, { path: _path + ".scenarios", expected: "(Array<IAutoBeTestScenarioApplication.IScenario> & MinItems<1>)", value: input.scenarios })) && ((1 <= input.scenarios.length || _report(_exceptionable, { path: _path + ".scenarios", expected: "Array<> & MinItems<1>", value: input.scenarios })) && input.scenarios.map((elem, _index11) => ("object" === typeof elem && null !== elem || _report(_exceptionable, { path: _path + ".scenarios[" + _index11 + "]", expected: "IAutoBeTestScenarioApplication.IScenario", value: elem })) && _vo7(elem, _path + ".scenarios[" + _index11 + "]", true && _exceptionable) || _report(_exceptionable, { path: _path + ".scenarios[" + _index11 + "]", expected: "IAutoBeTestScenarioApplication.IScenario", value: elem })).every(flag => flag)) || _report(_exceptionable, { path: _path + ".scenarios", expected: "(Array<IAutoBeTestScenarioApplication.IScenario> & MinItems<1>)", value: input.scenarios })].every(flag => flag); const _vo7 = (input, _path, _exceptionable = true) => ["string" === typeof input.draft || _report(_exceptionable, { path: _path + ".draft", expected: "string", value: input.draft }), "string" === typeof input.functionName || _report(_exceptionable, { path: _path + ".functionName", expected: "string", value: input.functionName }), (Array.isArray(input.dependencies) || _report(_exceptionable, { path: _path + ".dependencies", expected: "Array<IAutoBeTestScenarioApplication.IDependencies>", value: input.dependencies })) && input.dependencies.map((elem, _index12) => ("object" === typeof elem && null !== elem || _report(_exceptionable, { path: _path + ".dependencies[" + _index12 + "]", expected: "IAutoBeTestScenarioApplication.IDependencies", value: elem })) && _vo8(elem, _path + ".dependencies[" + _index12 + "]", true && _exceptionable) || _report(_exceptionable, { path: _path + ".dependencies[" + _index12 + "]", expected: "IAutoBeTestScenarioApplication.IDependencies", value: elem })).every(flag => flag) || _report(_exceptionable, { path: _path + ".dependencies", expected: "Array<IAutoBeTestScenarioApplication.IDependencies>", value: input.dependencies })].every(flag => flag); const _vo8 = (input, _path, _exceptionable = true) => [("object" === typeof input.endpoint && null !== input.endpoint || _report(_exceptionable, { path: _path + ".endpoint", expected: "AutoBeOpenApi.IEndpoint", value: input.endpoint })) && _vo3(input.endpoint, _path + ".endpoint", true && _exceptionable) || _report(_exceptionable, { path: _path + ".endpoint", expected: "AutoBeOpenApi.IEndpoint", value: input.endpoint }), "string" === typeof input.purpose || _report(_exceptionable, { path: _path + ".purpose", expected: "string", value: input.purpose })].every(flag => flag); const _vu0 = (input, _path, _exceptionable = true) => (() => { if ("getAnalysisFiles" === input.type) return _vo1(input, _path, true && _exceptionable); else if ("getInterfaceOperations" === input.type) return _vo2(input, _path, true && _exceptionable); else if ("getInterfaceSchemas" === input.type) return _vo4(input, _path, true && _exceptionable); else if ("complete" === input.type) return _vo5(input, _path, true && _exceptionable); else return _report(_exceptionable, { path: _path, expected: "(IAutoBePreliminaryGetAnalysisFiles | IAutoBePreliminaryGetInterfaceOperations | IAutoBePreliminaryGetInterfaceSchemas | IAutoBeTestScenarioApplication.IComplete)", 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: "IAutoBeTestScenarioApplication.IProps", value: input })) && _vo0(input, _path + "", true) || _report(true, { path: _path + "", expected: "IAutoBeTestScenarioApplication.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; else if (result.data.request.type !== "complete") return props.preliminary.validate({ thinking: result.data.thinking, request: result.data.request, }); // merge to unique scenario groups const scenarioGroups = uniqueScenarioGroups(result.data.request.scenarioGroups); // validate endpoints const errors = []; scenarioGroups.forEach((group, i) => { if (props.dict.has(group.endpoint) === false) errors.push({ value: group.endpoint, path: `$input.request.scenarioGroups[${i}].endpoint`, expected: "AutoBeOpenApi.IEndpoint", description: props.endpointNotFound, }); group.scenarios.forEach((s, j) => { s.dependencies.forEach((dep, k) => { if (props.dict.has(dep.endpoint) === false) errors.push({ value: dep.endpoint, path: `$input.request.scenarioGroups[${i}].scenarios[${j}].dependencies[${k}].endpoint`, expected: "AutoBeOpenApi.IEndpoint", description: props.endpointNotFound, }); }); }); }); // Authentication Correction const entireRoles = new Map(); for (const authorization of props.authorizations) { for (const op of authorization.operations) { if (op.authorizationType === null) continue; const value = utils_1.MapUtil.take(entireRoles, authorization.name, () => ({ name: authorization.name, join: null, login: null, })); if (op.authorizationType === "join") value.join = op; else if (op.authorizationType === "login") value.login = op; } } scenarioGroups.forEach((group) => { if (props.dict.has(group.endpoint) === false) return; const operation = props.dict.get(