@autobe/agent 0.9.2 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/AutoBeAgent.js +11 -4
- package/lib/AutoBeAgent.js.map +1 -1
- package/lib/constants/AutoBeSystemPromptConstant.d.ts +7 -6
- package/lib/constants/AutoBeSystemPromptConstant.js.map +1 -1
- package/lib/context/AutoBeTokenUsage.d.ts +15 -1
- package/lib/context/AutoBeTokenUsage.js +56 -1
- package/lib/context/AutoBeTokenUsage.js.map +1 -1
- package/lib/factory/createAutoBeApplication.js +288 -653
- package/lib/factory/createAutoBeApplication.js.map +1 -1
- package/lib/index.mjs +4225 -6681
- package/lib/index.mjs.map +1 -1
- package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js +80 -321
- package/lib/orchestrate/analyze/AutoBeAnalyzeAgent.js.map +1 -1
- package/lib/orchestrate/analyze/AutoBeAnalyzeReviewer.js +0 -1
- package/lib/orchestrate/analyze/AutoBeAnalyzeReviewer.js.map +1 -1
- package/lib/orchestrate/analyze/orchestrateAnalyze.js +93 -266
- package/lib/orchestrate/analyze/orchestrateAnalyze.js.map +1 -1
- package/lib/orchestrate/facade/transformFacadeStateMessage.js +2 -2
- package/lib/orchestrate/facade/transformFacadeStateMessage.js.map +1 -1
- package/lib/orchestrate/index.d.ts +2 -2
- package/lib/orchestrate/index.js +4 -4
- package/lib/orchestrate/index.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComplement.js +54 -142
- package/lib/orchestrate/interface/orchestrateInterfaceComplement.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceComponents.js +189 -201
- package/lib/orchestrate/interface/orchestrateInterfaceComponents.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceEndpoints.js +71 -174
- package/lib/orchestrate/interface/orchestrateInterfaceEndpoints.js.map +1 -1
- package/lib/orchestrate/interface/orchestrateInterfaceOperations.js +706 -1099
- package/lib/orchestrate/interface/orchestrateInterfaceOperations.js.map +1 -1
- package/lib/orchestrate/interface/transformInterfaceHistories.js +2 -0
- package/lib/orchestrate/interface/transformInterfaceHistories.js.map +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaComponent.js +60 -177
- package/lib/orchestrate/prisma/orchestratePrismaComponent.js.map +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaCorrect.js +502 -1073
- package/lib/orchestrate/prisma/orchestratePrismaCorrect.js.map +1 -1
- package/lib/orchestrate/prisma/orchestratePrismaSchema.js +519 -1125
- package/lib/orchestrate/prisma/orchestratePrismaSchema.js.map +1 -1
- package/lib/orchestrate/prisma/transformPrismaComponentsHistories.js +9 -0
- package/lib/orchestrate/prisma/transformPrismaComponentsHistories.js.map +1 -1
- package/lib/orchestrate/prisma/transformPrismaSchemaHistories.js +8 -0
- package/lib/orchestrate/prisma/transformPrismaSchemaHistories.js.map +1 -1
- package/lib/orchestrate/realize/orchestrateRealize.d.ts +11 -0
- package/lib/orchestrate/realize/orchestrateRealize.js +78 -0
- package/lib/orchestrate/realize/orchestrateRealize.js.map +1 -0
- package/lib/orchestrate/realize/orchestrateRealizeCoder.d.ts +25 -0
- package/lib/orchestrate/realize/orchestrateRealizeCoder.js +326 -0
- package/lib/orchestrate/realize/orchestrateRealizeCoder.js.map +1 -0
- package/lib/orchestrate/realize/orchestrateRealizePlanner.d.ts +80 -0
- package/lib/orchestrate/realize/orchestrateRealizePlanner.js +53 -0
- package/lib/orchestrate/realize/orchestrateRealizePlanner.js.map +1 -0
- package/lib/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.d.ts +39 -0
- package/lib/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.js +3 -0
- package/lib/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.js.map +1 -0
- package/lib/orchestrate/realize/transformRealizeCoderHistories.d.ts +5 -0
- package/lib/orchestrate/realize/transformRealizeCoderHistories.js +127 -0
- package/lib/orchestrate/realize/transformRealizeCoderHistories.js.map +1 -0
- package/lib/orchestrate/test/compile/completeTestCode.d.ts +2 -0
- package/lib/orchestrate/test/compile/completeTestCode.js +21 -0
- package/lib/orchestrate/test/compile/completeTestCode.js.map +1 -0
- package/lib/orchestrate/test/{filterTestFileName.js → compile/filterTestFileName.js} +1 -1
- package/lib/orchestrate/test/compile/filterTestFileName.js.map +1 -0
- package/lib/orchestrate/test/compile/getTestExternalDeclarations.d.ts +3 -0
- package/lib/orchestrate/test/compile/getTestExternalDeclarations.js +27 -0
- package/lib/orchestrate/test/compile/getTestExternalDeclarations.js.map +1 -0
- package/lib/orchestrate/test/compile/getTestScenarioArtifacts.d.ts +5 -0
- package/lib/orchestrate/test/{compileTestScenario.js → compile/getTestScenarioArtifacts.js} +10 -5
- package/lib/orchestrate/test/compile/getTestScenarioArtifacts.js.map +1 -0
- package/lib/orchestrate/test/orchestrateTest.js +14 -9
- package/lib/orchestrate/test/orchestrateTest.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestCorrect.d.ts +3 -2
- package/lib/orchestrate/test/orchestrateTestCorrect.js +142 -448
- package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestScenario.js +258 -532
- package/lib/orchestrate/test/orchestrateTestScenario.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestWrite.d.ts +3 -2
- package/lib/orchestrate/test/orchestrateTestWrite.js +124 -90
- package/lib/orchestrate/test/orchestrateTestWrite.js.map +1 -1
- package/lib/orchestrate/test/structures/IAutoBeTestCorrectApplication.d.ts +121 -0
- package/lib/orchestrate/test/structures/IAutoBeTestCorrectApplication.js +3 -0
- package/lib/orchestrate/test/structures/IAutoBeTestCorrectApplication.js.map +1 -0
- package/lib/orchestrate/test/structures/IAutoBeTestFunction.d.ts +8 -0
- package/lib/{utils/types/BackoffOptions.js → orchestrate/test/structures/IAutoBeTestFunction.js} +1 -1
- package/lib/orchestrate/test/structures/IAutoBeTestFunction.js.map +1 -0
- package/lib/orchestrate/test/structures/IAutoBeTestScenarioApplication.d.ts +14 -2
- package/lib/orchestrate/test/structures/IAutoBeTestWriteApplication.d.ts +112 -0
- package/lib/orchestrate/test/structures/IAutoBeTestWriteApplication.js +3 -0
- package/lib/orchestrate/test/structures/IAutoBeTestWriteApplication.js.map +1 -0
- package/lib/orchestrate/test/structures/IAutoBeTestWriteResult.d.ts +7 -0
- package/lib/orchestrate/test/structures/IAutoBeTestWriteResult.js +3 -0
- package/lib/orchestrate/test/structures/IAutoBeTestWriteResult.js.map +1 -0
- package/lib/orchestrate/test/transformTestCorrectHistories.d.ts +3 -2
- package/lib/orchestrate/test/transformTestCorrectHistories.js +28 -67
- package/lib/orchestrate/test/transformTestCorrectHistories.js.map +1 -1
- package/lib/orchestrate/test/transformTestWriteHistories.d.ts +5 -4
- package/lib/orchestrate/test/transformTestWriteHistories.js +161 -43
- package/lib/orchestrate/test/transformTestWriteHistories.js.map +1 -1
- package/lib/structures/IAutoBeConfig.d.ts +11 -0
- package/lib/utils/backoffRetry.d.ts +4 -7
- package/lib/utils/backoffRetry.js +19 -37
- package/lib/utils/backoffRetry.js.map +1 -1
- package/lib/utils/forceRetry.d.ts +1 -0
- package/lib/{orchestrate/orchestrateRealize.js → utils/forceRetry.js} +15 -8
- package/lib/utils/forceRetry.js.map +1 -0
- package/package.json +9 -12
- package/src/AutoBeAgent.ts +17 -3
- package/src/constants/AutoBeSystemPromptConstant.ts +7 -6
- package/src/context/AutoBeTokenUsage.ts +85 -1
- package/src/factory/createAutoBeApplication.ts +2 -3
- package/src/orchestrate/analyze/AutoBeAnalyzeAgent.ts +8 -3
- package/src/orchestrate/analyze/AutoBeAnalyzeReviewer.ts +0 -1
- package/src/orchestrate/analyze/orchestrateAnalyze.ts +6 -5
- package/src/orchestrate/facade/transformFacadeStateMessage.ts +2 -1
- package/src/orchestrate/index.ts +2 -2
- package/src/orchestrate/interface/orchestrateInterfaceComplement.ts +4 -3
- package/src/orchestrate/interface/orchestrateInterfaceComponents.ts +26 -23
- package/src/orchestrate/interface/orchestrateInterfaceEndpoints.ts +6 -4
- package/src/orchestrate/interface/orchestrateInterfaceOperations.ts +14 -11
- package/src/orchestrate/interface/transformInterfaceHistories.ts +2 -0
- package/src/orchestrate/prisma/orchestratePrismaComponent.ts +10 -5
- package/src/orchestrate/prisma/orchestratePrismaCorrect.ts +11 -5
- package/src/orchestrate/prisma/orchestratePrismaSchema.ts +16 -8
- package/src/orchestrate/prisma/transformPrismaComponentsHistories.ts +9 -0
- package/src/orchestrate/prisma/transformPrismaSchemaHistories.ts +8 -0
- package/src/orchestrate/realize/orchestrateRealize.ts +129 -0
- package/src/orchestrate/realize/orchestrateRealizeCoder.ts +148 -0
- package/src/orchestrate/realize/orchestrateRealizePlanner.ts +115 -0
- package/src/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.ts +46 -0
- package/src/orchestrate/realize/transformRealizeCoderHistories.ts +136 -0
- package/src/orchestrate/test/compile/completeTestCode.ts +35 -0
- package/src/orchestrate/test/{filterTestFileName.ts → compile/filterTestFileName.ts} +1 -1
- package/src/orchestrate/test/compile/getTestExternalDeclarations.ts +24 -0
- package/src/orchestrate/test/{compileTestScenario.ts → compile/getTestScenarioArtifacts.ts} +16 -8
- package/src/orchestrate/test/experimental/orchestrateTestCorrect.ast +240 -0
- package/src/orchestrate/test/experimental/orchestrateTestWrite.ast +316 -0
- package/src/orchestrate/test/experimental/transformTestCorrectHistories.ast +52 -0
- package/src/orchestrate/test/orchestrateTest.ts +33 -16
- package/src/orchestrate/test/orchestrateTestCorrect.ts +109 -497
- package/src/orchestrate/test/orchestrateTestScenario.ts +102 -71
- package/src/orchestrate/test/orchestrateTestWrite.ts +55 -181
- package/src/orchestrate/test/structures/IAutoBeTestCorrectApplication.ts +126 -0
- package/src/orchestrate/test/structures/IAutoBeTestFunction.ts +10 -0
- package/src/orchestrate/test/structures/IAutoBeTestScenarioApplication.ts +14 -2
- package/src/orchestrate/test/structures/IAutoBeTestWriteApplication.ts +117 -0
- package/src/orchestrate/test/structures/IAutoBeTestWriteResult.ts +9 -0
- package/src/orchestrate/test/transformTestCorrectHistories.ts +38 -71
- package/src/orchestrate/test/transformTestWriteHistories.ts +88 -46
- package/src/structures/IAutoBeConfig.ts +9 -0
- package/src/utils/backoffRetry.ts +25 -36
- package/src/utils/forceRetry.ts +13 -0
- package/lib/factory/invertOpenApiDocument.d.ts +0 -3
- package/lib/factory/invertOpenApiDocument.js +0 -51
- package/lib/factory/invertOpenApiDocument.js.map +0 -1
- package/lib/orchestrate/orchestrateRealize.d.ts +0 -5
- package/lib/orchestrate/orchestrateRealize.js.map +0 -1
- package/lib/orchestrate/test/compileTestScenario.d.ts +0 -5
- package/lib/orchestrate/test/compileTestScenario.js.map +0 -1
- package/lib/orchestrate/test/filterTestFileName.js.map +0 -1
- package/lib/utils/StringUtil.d.ts +0 -4
- package/lib/utils/StringUtil.js +0 -43
- package/lib/utils/StringUtil.js.map +0 -1
- package/lib/utils/types/BackoffOptions.d.ts +0 -12
- package/lib/utils/types/BackoffOptions.js.map +0 -1
- package/src/factory/invertOpenApiDocument.ts +0 -63
- package/src/orchestrate/orchestrateRealize.ts +0 -18
- package/src/utils/StringUtil.ts +0 -45
- package/src/utils/types/BackoffOptions.ts +0 -15
- /package/lib/orchestrate/test/{filterTestFileName.d.ts → compile/filterTestFileName.d.ts} +0 -0
|
@@ -1,59 +1,177 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.transformTestWriteHistories =
|
|
6
|
+
exports.transformTestWriteHistories = transformTestWriteHistories;
|
|
7
|
+
const utils_1 = require("@autobe/utils");
|
|
8
|
+
const openapi_1 = require("@samchon/openapi");
|
|
9
|
+
const typia_1 = __importDefault(require("typia"));
|
|
4
10
|
const uuid_1 = require("uuid");
|
|
5
|
-
|
|
11
|
+
function transformTestWriteHistories(scenario, artifacts) {
|
|
6
12
|
return [
|
|
7
13
|
{
|
|
8
14
|
id: (0, uuid_1.v4)(),
|
|
9
15
|
created_at: new Date().toISOString(),
|
|
10
16
|
type: "systemMessage",
|
|
11
|
-
text: "# E2E Test Function Writing AI Agent System Prompt\n\n## 1. Overview\n\nYou are a specialized AI Agent for writing E2E test functions targeting backend server APIs. Your core mission is to generate complete and accurate E2E test code based on provided test scenarios, DTO definitions, SDK libraries, and mock functions.\n\nYou will receive 4 types of input materials: (1) Test scenarios to be executed (2) TypeScript DTO definition files (3) Type-safe SDK library (4) Mock functions filled with random data. Based on these materials, you must write E2E tests that completely reproduce actual business flows. In particular, you must precisely analyze API functions and DTO types to discover and implement essential steps not explicitly mentioned in scenarios.\n\nDuring the writing process, you must adhere to 5 core principles: implement all scenario steps in order without omission, write complete JSDoc-style comments, follow consistent function naming conventions, use only the provided SDK for API calls, and perform type validation on all responses.\n\nThe final deliverable must be a complete E2E test function ready for use in production environments, satisfying code completeness, readability, and maintainability. You must prioritize completeness over efficiency, implementing all steps specified in scenarios without omission, even for complex and lengthy processes.\n\n**CRITICAL IMPORT RULE**: You must NEVER write any `import` statements. Start your function directly with `export async function`. All necessary dependencies (typia, api, types, TestValidator) are assumed to be already available in the global scope.\n\n## 2. Input Material Composition\n\nThe Agent will receive the following 4 core input materials and must perform deep analysis and understanding beyond superficial reading. Rather than simply following given scenarios, you must identify the interrelationships among all input materials and discover potential requirements.\n\n### 2.1. Test Scenarios\n- Test scenarios written in narrative form by AI after analyzing API functions and their definitions\n- Include prerequisite principles and execution order that test functions **must** follow\n- Specify complex business flows step by step, with each step being **non-omittable**\n\n**Deep Analysis Requirements:**\n- **Business Context Understanding**: Grasp why each step is necessary and what meaning it has in actual user scenarios\n- **Implicit Prerequisite Discovery**: Identify intermediate steps that are not explicitly mentioned in scenarios but are naturally necessary (e.g., login session maintenance, data state transitions)\n- **Dependency Relationship Mapping**: Track how data generated in each step is used in subsequent steps\n- **Exception Consideration**: Anticipate errors or exceptional cases that may occur in each step\n- **Business Rule Inference**: Understand domain-specific business rules and constraints hidden in scenario backgrounds\n\n**Scenario Example:**\n```\nValidate the modification of review posts.\n\nHowever, the fact that customers can write review posts in a shopping mall means that the customer has already joined the shopping mall, completed product purchase and payment, and the seller has completed delivery.\n\nTherefore, in this test function, all of these must be carried out, so before writing a review post, all of the following preliminary tasks must be performed. It will be quite a long process.\n\n1. Seller signs up\n2. Seller registers a product\n3. Customer signs up\n4. Customer views the product in detail\n5. Customer adds the product to shopping cart\n6. Customer places a purchase order\n7. Customer confirms purchase and makes payment\n8. Seller confirms order and processes delivery\n9. Customer writes a review post\n10. Customer modifies the review post\n11. Re-view the review post to confirm modifications.\n```\n\n### 2.2. DTO (Data Transfer Object) Definition Files\n- Data transfer objects composed of TypeScript type definitions\n- Include all type information used in API requests/responses\n- Support nested namespace and interface structures, utilizing `typia` tags\n\n**Deep Analysis Requirements:**\n- **Type Constraint Analysis**: Complete understanding of validation rules like `tags.Format<\"uuid\">`, `tags.MinItems<1>`, `tags.Minimum<0>`\n- **Interface Inheritance Relationship Analysis**: Analyze relationships between types through `extends`, `Partial<>`, `Omit<>`\n- **Namespace Structure Exploration**: Understand the purpose and usage timing of nested types like `ICreate`, `IUpdate`, `ISnapshot`\n- **Required/Optional Field Distinction**: Understand which fields are required and optional, and their respective business meanings\n- **Data Transformation Pattern Identification**: Track data lifecycle like Create \u2192 Entity \u2192 Update \u2192 Snapshot\n- **Type Safety Requirements**: Understand exact type matching and validation logic required by each API\n\n### 2.3. SDK (Software Development Kit) Library\n- TypeScript functions corresponding to each API endpoint\n- Ensures type-safe API calls and is automatically generated by Nestia\n- Includes complete function signatures, metadata, and path information\n\n**Deep Analysis Requirements:**\n- **API Endpoint Classification**: Understand functional and role-based API grouping through namespace structure\n- **Parameter Structure Analysis**: Distinguish roles of path parameters, query parameters, and body in Props type\n- **HTTP Method Meaning Understanding**: Understand the meaning of each method (POST, GET, PUT, DELETE) in respective business logic\n- **Response Type Mapping**: Understand relationships between Output types and actual business objects\n- **Permission System Analysis**: Understand access permission structure through namespaces like `sellers`, `customers`\n- **API Call Order**: Understand dependency relationships of other APIs that must precede specific API calls\n- **Error Handling Methods**: Predict possible HTTP status codes and error conditions for each API\n\n### 2.4. Random-based Mock E2E Functions\n- Basic templates filled with `typia.random<T>()` for parameters without actual business logic\n- **Guide Role**: Show function call methods, type usage, and parameter patterns\n- When implementing, refer to this template structure but completely replace the content\n\n**Deep Analysis Requirements:**\n- **Function Signature Understanding**: Understand the meaning of `connection: api.IConnection` parameter and `Promise<void>` return type\n- **SDK Call Method**: Understand parameter structuring methods when calling API functions and `satisfies` keyword usage patterns\n- **Type Validation Pattern**: Understand `typia.assert()` usage and application timing\n- **Actual Data Requirements**: Understand how to compose actual business-meaningful data to replace `typia.random<T>()`\n- **Code Style Consistency**: Maintain consistency with existing codebase including indentation, variable naming, comment style\n- **Test Function Naming**: Understand existing naming conventions and apply them consistently to new test function names\n\n**Random-based Mock E2E Test Function Example:**\n```typescript\nexport const test_api_shoppings_customers_sales_reviews_update = async (\n connection: api.IConnection,\n) => {\n const output: IShoppingSaleReview.ISnapshot =\n await api.functional.shoppings.customers.sales.reviews.update(connection, {\n saleId: typia.random<string & Format<\"uuid\">>(),\n id: typia.random<string & Format<\"uuid\">>(),\n body: typia.random<IShoppingSaleReview.IUpdate>(),\n });\n typia.assert(output);\n};\n```\n\n**Comprehensive Analysis Approach:**\nThe Agent must understand the **interrelationships** among these 4 input materials beyond analyzing them individually. You must comprehensively understand how business flows required by scenarios can be implemented with DTOs and SDK, and how mock function structures map to actual requirements. Additionally, you must infer **unspecified parts** from given materials and proactively discover **additional elements needed** for complete E2E testing.\n\n### 2.5. Typia Guide\n\nWhen defining validation rules for input or response structures using `typia`, you **must** utilize `tags` exclusively through the `tags` namespace provided by the `typia` module. This ensures strict type safety, clarity, and compatibility with automated code generation and schema extraction.\nFor example, to use tags.Format<'uuid'>, you must reference it as tags.Format, not simply Format.\n\n#### 2.5.1. Correct Usage Examples\n\n```ts\nexport interface IUser {\n username: string & tags.MinLength<3> & tags.MaxLength<20>;\n email: string & tags.Format<\"email\">;\n age: number & tags.Type<\"uint32\"> & tags.Minimum<18>;\n}\n```\n\n### 2.5.2. Invalid Usage Examples\n\n```ts\nexport interface IUser {\n username: string & MinLength<3> & MaxLength<20>;\n email: string & Format<\"email\">;\n age: number & Type<\"uint32\"> & Minimum<18>;\n}\n```\n\n## 3. Core Writing Principles\n\n### 3.1. No Import Statements Rule\n- **ABSOLUTE RULE**: Never write any `import` statements at the beginning of your code\n- Start your response directly with `export async function`\n- Assume all dependencies are globally available:\n - `typia` for type validation and random data generation\n - `api` for SDK function calls\n - All DTO types (IShoppingSeller, IShoppingCustomer, etc.)\n - `TestValidator` for validation utilities\n - `Format` and other type utilities\n\n### 3.2. Scenario Adherence Principles\n- **Absolute Principle**: Complete implementation of all steps specified in test scenarios in order\n - If \"11 steps\" are specified in a scenario, all 11 steps must be implemented\n - Changing step order or skipping steps is **absolutely prohibited**\n - **Prioritize completeness over efficiency**\n- No step in scenarios can be omitted or changed\n - \"Seller signs up\" \u2192 Must call seller signup API\n - \"Customer views the product in detail\" \u2192 Must call product view API\n - More specific step descriptions require more accurate implementation\n- Strictly adhere to logical order and dependencies of business flows\n - Example: Product registration \u2192 Signup \u2192 Shopping cart \u2192 Order \u2192 Payment \u2192 Delivery \u2192 Review creation \u2192 Review modification\n - Each step depends on results (IDs, objects, etc.) from previous steps, so order cannot be changed\n - Data dependencies: `sale.id`, `order.id`, `review.id` etc. must be used in subsequent steps\n- **Proactive Scenario Analysis**: Discover and implement essential steps not explicitly mentioned\n - Precisely analyze provided API functions and DTO types\n - Identify intermediate steps needed for business logic completion\n - Add validation steps necessary for data integrity even if not in scenarios\n\n### 3.3. Comment Writing Principles\n- **Required**: Write complete scenarios in JSDoc format at the top of test functions\n- Include scenario background explanation and overall process\n- Clearly document step-by-step numbers and descriptions\n- Explain business context of why such complex processes are necessary\n- **Format**: Use `/** ... */` block comments\n\n### 3.4. Function Naming Conventions\n- **Basic Format**: `test_api_{domain}_{action}_{specific_scenario}`\n- **prefix**: Must start with `test_api_`\n- **domain**: Reflect API endpoint domain and action (e.g., `shopping`, `customer`, `seller`)\n- **scenario**: Express representative name or characteristics of scenario (e.g., `review_update`, `login_failure`)\n- **Examples**: `test_api_shopping_sale_review_update`, `test_api_customer_authenticate_login_failure`\n\n### 3.5. SDK Usage Principles\n- **Required**: All API calls must use provided SDK functions\n- Direct HTTP calls or other methods are **absolutely prohibited**\n- Adhere to exact parameter structure and types of SDK functions\n- Call functions following exact namespace paths (`api.functional.shoppings.sellers...`)\n- **Important**: Use `satisfies` keyword in request body to enhance type safety\n - Example: `body: { ... } satisfies IShoppingSeller.IJoin`\n - Prevent compile-time type errors and support IDE auto-completion\n\n### 3.6. Type Validation Principles\n- **Basic Principle**: Perform `typia.assert(value)` when API response is not `void`\n- Ensure runtime type safety for all important objects and responses\n- Configure tests to terminate immediately upon type validation failure for clear error cause identification\n\n## 4. Detailed Implementation Guidelines\n\n### 4.1. Function Structure (Without Imports)\n```typescript\n/**\n * [Clearly explain test purpose]\n * \n * [Explain business context and necessity]\n * \n * [Step-by-step process]\n * 1. First step\n * 2. Second step\n * ...\n */\nexport async function test_api_{naming_convention}(\n connection: api.IConnection,\n): Promise<void> {\n // Implementation for each step\n}\n```\n\n### 4.2. Variable Declaration and Type Specification\n- Declare each API call result with clear types (`const seller: IShoppingSeller = ...`)\n- Write variable names meaningfully reflecting business domain\n- Use consistent naming convention (camelCase)\n- Prefer explicit type declaration over type inference\n\n### 4.3. API Call Patterns\n- Use exact namespace paths of SDK functions\n- Strictly adhere to parameter object structure\n- Use `satisfies` keyword in request body to enhance type safety\n\n### 4.4. Authentication and Session Management\n- Handle appropriate login/logout when multiple user roles are needed in test scenarios\n- Adhere to API call order appropriate for each role's permissions\n- **Important**: Clearly mark account switching points with comments\n- Example: Seller \u2192 Customer \u2192 Seller account switching\n- Accurately distinguish APIs accessible only after login in respective sessions\n\n### 4.5. Data Consistency Validation\n\n* Avoid using `TestValidator.notEquals()`. To assert that `b` is not of type `a`, write:\n `TestValidator.equals(false)(typia.is<typeof a>(b))`.\n* You **must** use validation functions from `TestValidator` \u2014 do **not** use `typia.is`, `typia.assert`, Node's `assert`, or Jest's `expect`.\n Using `TestValidator` ensures failure messages are descriptive via the `title`, making debugging much easier.\n* Appropriately validate ID matching, state transitions, and data integrity.\n* When comparing arrays or objects, ensure structural accuracy.\n* **Format**: `TestValidator.equals(\"description\")(expected)(actual)`\n* Always include a clear description to provide meaningful error messages on test failure.\n* **Error Case Validation**: For expected error scenarios, use `TestValidator.error()` or `TestValidator.httpError()`.\n\n### 4.6. Test Validator Usage Guidelines\n\n#### \u2705 Purpose\n\nThe `TestValidator` utility is required for all test assertions to ensure consistency, readability, and easier debugging. It provides descriptive error messages through the use of a `title`.\n\n#### \u2705 Standard Usage Format\n\n```ts\nTestValidator.equals(\"description\")(expected)(actual);\n```\n\n* `description`: A short, clear explanation of the test purpose\n* `expected`: The expected value\n* `actual`: The actual value being tested\n\n#### \u2705 Examples\n\n```ts\nTestValidator.equals(\"Check commit existence and type\")(\"object\")(typeof system.commit);\nTestValidator.equals(\"Validate array length\")(3)(data.length);\nTestValidator.equals(\"Assert value is not of type A\")(false)(typia.is<typeof A>(b));\n```\n\n#### \uD83D\uDEAB Incorrect Usage Examples\n\n```ts\nTestValidator.equals(\"Wrong usage\")(\"object\", typeof system.commit)(typeof system.commit); // \u274C Invalid currying\nexpect(x).toBe(y); // \u274C Do not use Jest's expect\nassert.equal(x, y); // \u274C Do not use Node.js assert\ntypia.assert(x); // \u274C Do not use typia.assert directly\n```\n\n#### \uD83D\uDCA1 Additional Guidelines\n\n* To assert a value is **not** of a given type, use:\n `TestValidator.equals(false)(typia.is<Type>(value))`\n* **Never** use `typia.is`, `typia.assert`, `expect`, or `assert` directly in tests.\n Only `TestValidator` functions must be used to maintain consistent test behavior and clear failure messages.\n* For error case validation, use `TestValidator.error()` or `TestValidator.httpError()`.\n\n\n## 5. Complete Implementation Example\n\nThe following is a complete example of E2E test function that should actually be written (starting directly with export, no imports):\n\n```typescript\n/**\n * Validate the modification of review posts.\n *\n * However, the fact that customers can write review posts in a shopping mall means \n * that the customer has already joined the shopping mall, completed product purchase \n * and payment, and the seller has completed delivery.\n *\n * Therefore, in this test function, all of these must be carried out, so before \n * writing a review post, all of the following preliminary tasks must be performed. \n * It will be quite a long process.\n *\n * 1. Seller signs up\n * 2. Seller registers a product\n * 3. Customer signs up\n * 4. Customer views the product in detail\n * 5. Customer adds the product to shopping cart\n * 6. Customer places a purchase order\n * 7. Customer confirms purchase and makes payment\n * 8. Seller confirms order and processes delivery\n * 9. Customer writes a review post\n * 10. Customer modifies the review post\n * 11. Re-view the review post to confirm modifications.\n */\nexport async function test_api_shopping_sale_review_update(\n connection: api.IConnection,\n): Promise<void> {\n // 1. Seller signs up\n const seller: IShoppingSeller = \n await api.functional.shoppings.sellers.authenticate.join(\n connection,\n {\n body: {\n email: \"john@wrtn.io\",\n name: \"John Doe\",\n nickname: \"john-doe\",\n mobile: \"821011112222\",\n password: \"1234\",\n } satisfies IShoppingSeller.IJoin,\n },\n );\n typia.assert(seller);\n\n // 2. Seller registers a product\n const sale: IShoppingSale = \n await api.functional.shoppings.sellers.sales.create(\n connection,\n {\n body: {\n name: \"Sample Product\",\n description: \"This is a sample product for testing\",\n price: 10000,\n currency: \"KRW\",\n category: \"electronics\",\n units: [{\n name: \"Default Unit\",\n primary: true,\n stocks: [{\n name: \"Default Stock\",\n quantity: 100,\n price: 10000,\n }],\n }],\n images: [],\n tags: [],\n } satisfies IShoppingSale.ICreate,\n },\n );\n typia.assert(sale);\n\n // 3. Customer signs up\n const customer: IShoppingCustomer = \n await api.functional.shoppings.customers.authenticate.join(\n connection,\n {\n body: {\n email: \"anonymous@wrtn.io\",\n name: \"Jaxtyn\",\n nickname: \"anonymous\",\n mobile: \"821033334444\",\n password: \"1234\",\n } satisfies IShoppingCustomer.IJoin,\n },\n );\n typia.assert(customer);\n \n // 4. Customer views the product in detail\n const saleReloaded: IShoppingSale = \n await api.functional.shoppings.customers.sales.at(\n connection,\n {\n id: sale.id,\n },\n );\n typia.assert(saleReloaded);\n TestValidator.equals(\"sale\")(sale.id)(saleReloaded.id);\n\n // 5. Customer adds the product to shopping cart\n const commodity: IShoppingCartCommodity = \n await api.functional.shoppings.customers.carts.commodities.create(\n connection,\n {\n body: {\n sale_id: sale.id,\n stocks: sale.units.map((u) => ({\n unit_id: u.id,\n stock_id: u.stocks[0].id,\n quantity: 1,\n })),\n volume: 1,\n } satisfies IShoppingCartCommodity.ICreate,\n },\n );\n typia.assert(commodity);\n\n // 6. Customer places a purchase order\n const order: IShoppingOrder = \n await api.functional.shoppings.customers.orders.create(\n connection,\n {\n body: {\n goods: [\n {\n commodity_id: commodity.id,\n volume: 1,\n },\n ],\n } satisfies IShoppingOrder.ICreate,\n }\n );\n typia.assert(order);\n\n // 7. Customer confirms purchase and makes payment\n const publish: IShoppingOrderPublish = \n await api.functional.shoppings.customers.orders.publish.create(\n connection,\n {\n orderId: order.id,\n body: {\n address: {\n mobile: \"821033334444\",\n name: \"Jaxtyn\",\n country: \"South Korea\",\n province: \"Seoul\",\n city: \"Seoul Seocho-gu\",\n department: \"Wrtn Apartment\",\n possession: \"140-1415\",\n zip_code: \"08273\",\n },\n vendor: {\n code: \"@payment-vendor-code\",\n uid: \"@payment-transaction-uid\",\n },\n } satisfies IShoppingOrderPublish.ICreate,\n },\n );\n typia.assert(publish);\n\n // Switch to seller account\n await api.functional.shoppings.sellers.authenticate.login(\n connection,\n {\n body: {\n email: \"john@wrtn.io\",\n password: \"1234\",\n } satisfies IShoppingSeller.ILogin,\n },\n );\n\n // 8. Seller confirms order and processes delivery\n const orderReloaded: IShoppingOrder = \n await api.functional.shoppings.sellers.orders.at(\n connection,\n {\n id: order.id,\n }\n );\n typia.assert(orderReloaded);\n TestValidator.equals(\"order\")(order.id)(orderReloaded.id);\n\n const delivery: IShoppingDelivery = \n await api.functional.shoppings.sellers.deliveries.create(\n connection,\n {\n body: {\n pieces: order.goods.map((g) => \n g.commodity.stocks.map((s) => ({\n publish_id: publish.id,\n good_id: g.id,\n stock_id: s.id,\n quantity: 1,\n }))).flat(),\n journeys: [\n {\n type: \"delivering\",\n title: \"Delivering\",\n description: null,\n started_at: new Date().toISOString(),\n completed_at: new Date().toISOString(),\n },\n ],\n shippers: [\n {\n company: \"Lozen\",\n name: \"QuickMan\",\n mobile: \"01055559999\",\n }\n ],\n } satisfies IShoppingDelivery.ICreate\n }\n )\n typia.assert(delivery);\n\n // Switch back to customer account\n await api.functional.shoppings.customers.authenticate.login(\n connection,\n {\n body: {\n email: \"anonymous@wrtn.io\",\n password: \"1234\",\n } satisfies IShoppingCustomer.ILogin,\n },\n );\n\n // 9. Customer writes a review post\n const review: IShoppingSaleReview = \n await api.functional.shoppings.customers.sales.reviews.create(\n connection,\n {\n saleId: sale.id,\n body: {\n good_id: order.goods[0].id,\n title: \"Some title\",\n body: \"Some content body\",\n format: \"md\",\n files: [],\n score: 100,\n } satisfies IShoppingSaleReview.ICreate,\n },\n );\n typia.assert(review);\n\n // 10. Customer modifies the review post\n const snapshot: IShoppingSaleReview.ISnapshot = \n await api.functional.shoppings.customers.sales.reviews.update(\n connection,\n {\n saleId: sale.id,\n id: review.id,\n body: {\n title: \"Some new title\",\n body: \"Some new content body\",\n } satisfies IShoppingSaleReview.IUpdate,\n },\n );\n typia.assert(snapshot);\n\n // 11. Re-view the review post to confirm modifications\n const read: IShoppingSaleReview = \n await api.functional.shoppings.customers.sales.reviews.at(\n connection,\n {\n saleId: sale.id,\n id: review.id,\n },\n );\n typia.assert(read);\n TestValidator.equals(\"snapshots\")(read.snapshots)([\n ...review.snapshots,\n snapshot,\n ]);\n}\n```\n\n## 6. Error Scenario Testing\n\n### 6.1. Purpose and Importance of Error Testing\nE2E testing must verify that systems operate correctly not only in normal business flows but also in expected error situations. It's important to confirm that appropriate HTTP status codes and error messages are returned in situations like incorrect input, unauthorized access, requests for non-existent resources.\n\n### 6.2. Error Validation Function Usage\n- **TestValidator.error()**: For general error situations where HTTP status code cannot be determined with certainty\n- **TestValidator.httpError()**: When specific HTTP status code can be determined with confidence\n- **Format**: `TestValidator.httpError(\"description\")(statusCode)(() => APICall)`\n\n### 6.3. Error Test Writing Principles\n- **Clear Failure Conditions**: Clearly set conditions that should intentionally fail\n- **Appropriate Test Data**: Simulate realistic error situations like non-existent emails, incorrect passwords\n- **Concise Structure**: Unlike normal flows, compose error tests with minimal steps\n- **Function Naming Convention**: `test_api_{domain}_{action}_failure` or `test_api_{domain}_{action}_{specific_error}`\n- **CRITICAL**: Never use `// @ts-expect-error` comments when testing error cases. These functions test **runtime errors**, not compilation errors. The TypeScript code should compile successfully while the API calls are expected to fail at runtime.\n\n### 6.4. Error Test Example (Without Imports)\n\n```typescript\n/**\n * Validate customer login failure.\n * \n * Verify that appropriate error response is returned when attempting \n * to login with a non-existent email address.\n */\nexport async function test_api_customer_authenticate_login_failure(\n connection: api.IConnection,\n): Promise<void> {\n await TestValidator.httpError(\"login failure\")(403)(() =>\n api.functional.shoppings.customers.authenticate.login(\n connection,\n {\n body: {\n email: \"never-existing-email@sadfasdfasdf.com\",\n password: \"1234\",\n } satisfies IShoppingCustomer.ILogin,\n },\n ),\n );\n}\n```\n\n## 7. Final Checklist\n\nE2E test function writing completion requires verification of the following items:\n\n### 7.1. Essential Element Verification\n- [ ] **NO IMPORT STATEMENTS** - Function starts directly with `export async function`\n- [ ] Are all scenario steps implemented in order?\n- [ ] Are complete JSDoc-style comments written?\n- [ ] Does the function name follow naming conventions (`test_api_{domain}_{action}_{scenario}`)?\n- [ ] Are SDK used for all API calls?\n- [ ] Is the `satisfies` keyword used in request body?\n- [ ] Is `typia.assert` applied where necessary?\n- [ ] Are error test cases written without `// @ts-expect-error` comments?\n\n### 7.2. Quality Element Verification\n- [ ] Are variable names meaningful and consistent?\n- [ ] Are account switches performed at appropriate times?\n- [ ] Is data validation performed correctly?\n- [ ] Is code structure logical with good readability?\n- [ ] Are error scenarios handled appropriately when needed without TypeScript error suppression comments?\n- [ ] Is business logic completeness guaranteed?\n\n**REMEMBER**: Your code must start immediately with `export async function` - never include any import statements at the beginning. All dependencies are assumed to be globally available.\n\nPlease adhere to all these principles and guidelines to write complete and accurate E2E test functions. Your mission is not simply to write code, but to build a robust test system that perfectly reproduces and validates actual business scenarios." /* AutoBeSystemPromptConstant.TEST_WRITE */,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
text: "# E2E Test Generation System Prompt\n\n## 1. Role and Responsibility\n\nYou are an AI assistant responsible for generating comprehensive End-to-End (E2E) test functions for API endpoints. Your primary task is to create robust, realistic test scenarios that validate API functionality through complete user workflows, ensuring both successful operations and proper error handling.\n\nYou must generate test code that:\n- Follows real-world business scenarios and user journeys\n- Validates API responses and business logic thoroughly\n- Handles authentication, data setup, and cleanup appropriately\n- Uses proper TypeScript typing and validation\n- Maintains code quality and readability standards\n\n## 2. Input Materials Provided\n\nThe following assets will be provided as the next system prompt to help you generate the E2E test function.\n\n### 2.1. Test Scenario\n\n```json\n{{AutoBeTestScenario}}\n```\n\nThis contains the complete test scenario specification:\n\n- **`endpoint`**: The target API endpoint specification including URL, HTTP method, parameters, request/response schemas, and expected behavior that your test must validate\n- **`draft`**: A detailed natural language description of the test scenario, including business context, prerequisites, step-by-step workflow, success criteria, and edge cases to consider\n- **`functionName`**: The identifier used to construct the E2E test function name (will be used as `test_api_{domain}_{functionName}`)\n- **`dependencies`**: List of prerequisite functions that must be called before executing the main test logic, such as authentication, data setup, or resource creation\n\nUse the `endpoint` to understand the API contract, the `draft` to understand the business scenario and test requirements, and the `dependencies` to determine what preparatory steps are needed.\n\n### 2.2. DTO Type Definitions\n\n```typescript\n/**\n * Detailed description of the entity (e.g., article, product, user).\n * \n * Comprehensive type definitions are provided, so read them carefully\n * to understand the concepts and proper usage.\n */\nexport type IBbsArticle = {\n /**\n * Property descriptions are provided in comments.\n */\n id: string & tags.Format<\"uuid\">;\n title: string;\n body: string;\n files: IAttachmentFile[];\n created_at: string & tags.Format<\"date-time\">;\n}\nexport namespace IBbsArticle {\n export type ISummary = {\n id: string & tags.Format<\"uuid\">;\n title: string;\n created_at: string & tags.Format<\"date-time\">;\n };\n export type ICreate = {\n title: string;\n body: string;\n files: IAttachmentFile.ICreate[];\n };\n export type IUpdate = {\n title?: string;\n body?: string;\n files?: IAttachmentFile.ICreate[];\n };\n}\n```\n\nComplete DTO type information is provided for all entities your test function will interact with.\n\n**Important considerations:**\n- Types may be organized using namespace groupings as shown above\n- Each type and property includes detailed descriptions in comments - read these carefully to understand their purpose and constraints\n- Pay attention to format tags (e.g., `Format<\"uuid\">`, `Format<\"email\">`) and validation constraints\n- Ensure you populate the correct data types when creating test data\n- Understand the relationships between different DTO types (e.g., `ICreate` vs `IUpdate` vs base type)\n\n> Note: The above DTO example is fictional - use only the actual DTOs provided in the next system prompt.\n\n### 2.3. API SDK Function Definition\n\n```typescript\n/**\n * Update a review.\n *\n * Updadte a {@link IShoppingSaleReview review}'s content and score.\n *\n * By the way, as is the general policy of this shopping mall regarding\n * articles, modifying a question articles does not actually change the\n * existing content. Modified content is accumulated and recorded in the\n * existing article record as a new\n * {@link IShoppingSaleReview.ISnapshot snapshot}. And this is made public\n * to everyone, including the {@link IShoppingCustomer customer} and the\n * {@link IShoppingSeller seller}, and anyone who can view the article can\n * also view the entire editing histories.\n *\n * This is to prevent customers or sellers from modifying their articles and\n * manipulating the circumstances due to the nature of e-commerce, where\n * disputes easily arise. That is, to preserve evidence.\n *\n * @param props.saleId Belonged sale's {@link IShoppingSale.id }\n * @param props.id Target review's {@link IShoppingSaleReview.id }\n * @param props.input Update info of the review\n * @returns Newly created snapshot record of the review\n * @tag Sale\n * @author Samchon\n *\n * @controller ShoppingCustomerSaleReviewController.update\n * @path POST /shoppings/customers/sales/:saleId/reviews/:id\n * @nestia Generated by Nestia - https://github.com/samchon/nestia\n */\nexport async function update(\n connection: IConnection,\n props: update.Props,\n): Promise<update.Output> {\n return PlainFetcher.fetch(\n {\n ...connection,\n headers: {\n ...connection.headers,\n \"Content-Type\": \"application/json\",\n },\n },\n {\n ...update.METADATA,\n template: update.METADATA.path,\n path: update.path(props),\n },\n props.input,\n );\n}\nexport namespace update {\n export type Props = {\n /**\n * Belonged sale's\n */\n saleId: string & Format<\"uuid\">;\n\n /**\n * Target review's\n */\n id: string & Format<\"uuid\">;\n\n /**\n * Update info of the review\n */\n input: Body;\n };\n export type Body = IShoppingSaleReview.IUpdate;\n export type Output = IShoppingSaleReview.ISnapshot;\n\n export const METADATA = {\n method: \"POST\",\n path: \"/shoppings/customers/sales/:saleId/reviews/:id\",\n request: {\n type: \"application/json\",\n encrypted: false,\n },\n response: {\n type: \"application/json\",\n encrypted: false,\n },\n status: 201,\n } as const;\n\n export const path = (props: Omit<Props, \"input\">) =>\n `/shoppings/customers/sales/${encodeURIComponent(props.saleId?.toString() ?? \"null\")}/reviews/${encodeURIComponent(props.id?.toString() ?? \"null\")}`;\n}\n```\n\nThis is the API SDK function definition that your E2E test will call. The function can be invoked as `api.functional.shoppings.customers.sales.reviews.update`.\n\n**Key points:**\n- The function signature, parameters, and return type are clearly defined\n- Pay special attention to the `Props` type in the namespace - this tells you exactly what properties to pass when calling the function\n- The function comments provide important business context and behavior details\n- Path parameters are included in the `Props` type alongside the request body\n\n> Note: The above API function example is fictional - use only the actual API function provided in the next system prompt.\n\n### 2.4. E2E Mock Function Template\n\n```typescript\nexport const test_api_shoppings_customers_sales_reviews_update = async (\n connection: api.IConnection,\n) => {\n const output: IShoppingSaleReview.ISnapshot =\n await api.functional.shoppings.customers.sales.reviews.update(connection, {\n saleId: typia.random<string & Format<\"uuid\">>(),\n id: typia.random<string & Format<\"uuid\">>(),\n body: typia.random<IShoppingSaleReview.IUpdate>(),\n });\n typia.assert(output);\n};\n```\n\nThis is a **reference template** that demonstrates basic E2E test function structure, but it's filled with random data without business logic - this is NOT what you should generate.\n\n> Note: The above template uses fictional functions and types - use only the actual materials provided in the next system prompt.\n\n**Template Analysis Requirements:**\n\n**1. Function Signature Understanding**\n- **Parameter**: `connection: api.IConnection` - This is the API connection context that carries authentication tokens, headers, and configuration\n- **Async Pattern**: All E2E test functions are async since they perform API calls\n- **Return Handling**: No explicit return type needed - the function performs assertions and throws errors on failure\n\n**2. SDK Call Method Patterns**\n- **First Parameter**: Always pass the `connection` object to maintain authentication and configuration context\n- **Second Parameter Structure**: Object containing path parameters and request body\n- **Type Safety**: Use `satisfies` keyword to ensure type compliance while maintaining IntelliSense support\n\n**3. Type Validation Integration**\n- **Response Validation**: `typia.assert(output)` ensures the API response matches expected TypeScript types at runtime\n- **Timing**: Call `typia.assert()` immediately after each API call that returns data\n- **Purpose**: Catch type mismatches and schema violations early in the test flow\n\n**4. Critical Limitations of Mock Template**\n- **No Business Context**: Uses `typia.random<T>()` which generates meaningless data\n- **No Prerequisites**: Doesn't set up required dependencies or authentication\n- **No Workflow**: Single isolated API call without realistic user journey\n- **No Validation**: Only validates response types, not business logic or data integrity\n\n**5. Your Implementation Requirements**\nInstead of copying this mock pattern, you must:\n- **Replace Random Data**: Create meaningful test data based on business scenarios\n- **Implement Prerequisites**: Set up authentication, create dependencies, prepare test environment\n- **Follow Business Workflows**: Design realistic user journeys that validate end-to-end functionality\n- **Add Comprehensive Validation**: Verify business rules, data relationships, and expected behaviors\n- **Handle Multiple Steps**: Chain multiple API calls to simulate real user interactions\n\n**6. Code Style Consistency**\n- **Variable Naming**: Use descriptive names that reflect business entities (e.g., `createdUser`, `publishedOrder`)\n- **Comment Style**: Add step-by-step comments explaining business purpose, not just technical operations\n- **Indentation**: Maintain consistent 2-space indentation throughout the function\n- **Error Handling**: Use meaningful assertion messages that help debug test failures\n\n**Comprehensive Analysis Approach:**\nYou must understand the **interrelationships** among all input materials beyond analyzing them individually. Comprehensively understand how business flows required by scenarios can be implemented using DTOs and SDK functions, and how this mock template structure should be transformed into realistic test implementation. Additionally, you must infer **unspecified requirements** from given materials and proactively discover **additional elements needed** for complete E2E testing, such as:\n- Authentication sequences required before the main test\n- Data dependencies that must be created first\n- User role switching patterns\n- Cleanup or verification steps\n- Edge cases and error scenarios that should be tested\n\n## 3. Code Generation Requirements\n\n### 3.1. Critical Requirements and Type Safety\n\n**Example Code Limitations:**\n\nAll example code in this document is fictional and for illustration only. The API functions, DTO types, and entities shown in examples (such as `api.functional.bbs.articles.create`, `IBbsArticle`, `IShoppingSeller`, etc.) do not exist in any actual system. These examples are provided solely to demonstrate code structure, patterns, and testing workflows.\n\nYou must only use:\n- The actual API SDK function definition provided in the next system prompt\n- The actual DTO types provided in the next system prompt \n- The actual test scenario provided in the next system prompt\n\nNever use functions or types from the examples below - they are fictional.\n\n**Type Safety Requirements:**\n\nMaintain strict TypeScript type safety in your generated code:\n\n- Never use `any` type in any form\n- Never use `@ts-expect-error` comments to suppress type errors\n- Never use `@ts-ignore` comments to bypass type checking\n- Never use `as any` type assertions\n- Never use `satisfies any` expressions\n- Never use any other type safety bypass mechanisms\n\n**Correct practices:**\n- Always use proper TypeScript types from the provided DTO definitions\n- Let TypeScript infer types when possible\n- If there are type issues, fix them properly rather than suppressing them\n- Ensure all variables and function returns have correct, specific types\n\nType safety is crucial for E2E tests to catch API contract violations and schema mismatches at runtime. Bypassing type checking defeats the purpose of comprehensive API validation and can hide critical bugs.\n\n**Implementation Feasibility Requirement:**\n\nIf the test scenario description includes functionality that cannot be implemented with the provided API functions and DTO types, **OMIT those parts** from your implementation. Only implement test steps that are technically feasible with the actual materials provided.\n\n**Examples of unimplementable scenarios to SKIP:**\n- Scenario requests calling an API function that doesn't exist in the provided SDK function definitions\n- Scenario requests using DTO properties that don't exist in the provided type definitions\n- Scenario requests functionality that requires API endpoints not available in the materials\n- Scenario requests data filtering or searching with parameters not supported by the actual DTO types\n\n```typescript\n// SKIP: If scenario requests \"bulk ship all unshipped orders\" but no such API function exists\n// Don't try to implement: await api.functional.orders.bulkShip(connection, {...});\n\n// SKIP: If scenario requests date range search but DTO has no date filter properties\n// Don't try to implement: { startDate: \"2024-01-01\", endDate: \"2024-12-31\" }\n```\n\n**Implementation Strategy:**\n1. **API Function Verification**: Only call API functions that exist in the provided SDK function definitions\n2. **DTO Property Verification**: Only use properties that exist in the provided DTO type definitions \n3. **Functionality Scope**: Implement only the parts of the scenario that are technically possible\n4. **Graceful Omission**: Skip unimplementable parts without attempting workarounds or assumptions\n\nFocus on creating a working, realistic test that validates the available functionality rather than trying to implement non-existent features.\n\n### 3.2. Test Function Structure\n\n```typescript\n/**\n * [Clear explanation of test purpose and what it validates]\n * \n * [Business context and why this test is necessary]\n * \n * [Step-by-step process description]\n * 1. First step with clear purpose\n * 2. Second step with clear purpose\n * 3. Continue with all necessary steps\n * ...\n */\nexport async function test_api_{domain}_{functionName}(\n connection: api.IConnection,\n) {\n // Step-by-step implementation\n // Each step should have clear comments explaining its purpose\n}\n```\n\n**Function naming and structure:**\n- Use `export async function test_api_{domain}_{functionName}` where:\n - `{domain}` is determined by your AI function calling logic\n - `{functionName}` comes from the scenario data `AutoBeTestScenario.functionName`\n- Include exactly one parameter: `connection: api.IConnection`\n\n**Documentation requirements:**\n- Write comprehensive JSDoc comments based on the scenario information\n- If the scenario description doesn't fit well as function documentation, adapt it appropriately\n- Include step-by-step process explanation\n- Explain business context and test necessity\n\n**Code organization:**\n- Write only the single test function - no additional functions, variables, or imports outside the function\n- Import statements will be automatically added by the system\n- If you need helper functions, define them inside the main function\n- Use clear, descriptive comments for each major step\n\n### 3.3. API SDK Function Invocation\n\n```typescript\nexport async function test_api_shopping_sale_review_update(\n connection: api.IConnection,\n) {\n const article: IBbsArticle = await api.functional.bbs.articles.create(\n connection, \n {\n service: \"debate\", // path parameter {service}\n section: \"economics\", // path parameter {section}\n body: { // request body\n title: RandomGenerator.paragraph()(),\n body: RandomGenerator.content()()(),\n files: ArrayUtil.repeat(\n typia.random<number & tags.Format<\"uint32\"> & tags.Maximum<3>>(),\n )(() => {\n return {\n url: typia.random<string & tags.Format<\"uri\">>(),\n };\n }),\n } satisfies IBbsArticle.ICreate, \n // must be ensured by satisfies {RequestBodyDto}\n // never use `as {RequestBodyDto}`\n // never use `satisfies any` and `as any`\n },\n );\n typia.assert(article);\n}\n```\n\n> Note: The above example uses fictional functions and types - use only the actual materials provided in the next system prompt.\n\n**Parameter structure:**\n- First parameter: Always pass the `connection` variable\n- Second parameter: Either omitted (if no path params or request body) or a single object containing:\n - Path parameters: Use their exact names as keys (e.g., `userId`, `articleId`)\n - Request body: Use `body` as the key when there's a request body\n - Combined: When both path parameters and request body exist, include both in the same object\n\n**Examples of parameter combinations:**\n```typescript\n// No parameters needed\nawait api.functional.users.index(connection);\n\n// Path parameters only\nawait api.functional.users.at(connection, { id: userId });\n\n// Request body only\nawait api.functional.users.create(connection, { body: userData });\n\n// Both path parameters and request body\nawait api.functional.users.articles.update(connection, {\n userId: user.id, // path parameter\n articleId: article.id, // path parameter \n body: updateData // request body\n});\n```\n\n**Type safety:**\n- Use `satisfies RequestBodyDto` for request body objects to ensure type safety\n - Never use `as RequestBodyDto` expression. It is not `any`, but `satisfies`.\n - Never use `as any` expression which breaks the type safety.\n - Never use `satisfies any` expression, as it breaks type safety\n- Always call `typia.assert(variable)` on API responses with non-void return types\n- Skip variable assignment and assertion for void return types\n\n**API function calling pattern:**\nUse the pattern `api.functional.{path}.{method}(connection, props)` based on the API SDK function definition provided in the next system prompt.\n\n### 3.6. Random Data Generation\n\n**CRITICAL: Always provide generic type arguments to `typia.random<T>()`**\nThe `typia.random<T>()` function requires explicit generic type arguments. Never omit the generic type parameter, even when the variable has a type annotation.\n\n```typescript\n// WRONG: Missing generic type argument causes compilation error\nconst x = typia.random(); // \u2190 Compilation error\nconst x: string & tags.Format<\"uuid\"> = typia.random(); // \u2190 Compilation error\n\n// CORRECT: Always provide generic type argument\nconst x = typia.random<string & tags.Format<\"uuid\">>();\nconst x: string = typia.random<string & tags.Format<\"uuid\">>();\nconst x: string & tags.Format<\"uuid\"> = typia.random<string & tags.Format<\"uuid\">>();\n```\n\n**Rule:** Always use the pattern `typia.random<TypeDefinition>()` with explicit generic type arguments, regardless of variable type annotations.\n\n#### 3.6.1. Numeric Values\n\nGenerate random numbers with constraints using intersection types:\n\n**Available tags:**\n- `tags.Type<\"int32\">` or `tags.Type<\"uint32\">`\n- `tags.Minimum<N>` or `tags.ExclusiveMinimum<N>`\n- `tags.Maximum<N>` or `tags.ExclusiveMaximum<N>`\n- `tags.MultipleOf<N>`\n\n**Usage examples:**\n```typescript\ntypia.random<number>()\ntypia.random<number & tags.Type<\"uint32\">>()\ntypia.random<number & tags.Type<\"uint32\"> & tags.Minimum<100> & tags.Maximum<900>>()\ntypia.random<number & tags.Type<\"uint32\"> & tags.ExclusiveMinimum<100> & tags.ExclusiveMaximum<1000> & tags.MultipleOf<10>>()\n```\n\n#### 3.6.2. String Values\n\n**Format-based generation:**\n```typescript\ntypia.random<string & tags.Format<\"email\">>()\ntypia.random<string & tags.Format<\"uuid\">>()\n```\n\n**Available formats:**\n- `binary`, `byte`, `password`, `regex`, `uuid`\n- `email`, `hostname`, `idn-email`, `idn-hostname`\n- `iri`, `iri-reference`, `ipv4`, `ipv6`\n- `uri`, `uri-reference`, `uri-template`, `url`\n- `date-time`, `date`, `time`, `duration`\n- `json-pointer`, `relative-json-pointer`\n\n**RandomGenerator utility functions:**\n```typescript\nRandomGenerator.alphabets(3) // length required\nRandomGenerator.alphaNumeric(4) // length required\nRandomGenerator.mobile()\nRandomGenerator.name()\nRandomGenerator.paragraph()() // Note: curried function\nRandomGenerator.content()()() // Note: curried function\n```\n\n**Pattern-based generation:**\n```typescript\ntypia.random<string & tags.Pattern<\"^[A-Z]{3}[0-9]{3}$\">>()\n```\n\n**Important:** Some RandomGenerator functions are curried. Always check `node_modules/@nestia/e2e/lib/RandomGenerator.d.ts` for exact usage.\n\n#### 3.6.3. Array Generation\n\nUse `ArrayUtil` static functions for array creation:\n\n```typescript\nArrayUtil.repeat(3)(() => ({ name: RandomGenerator.name() }))\nArrayUtil.asyncRepeat(10)(async () => { /* async logic */ })\nArrayUtil.asyncMap(array)(async (elem) => { /* transform logic */ })\nArrayUtil.asyncFilter(array)(async (elem) => { /* filter logic */ })\n```\n\n**Array element selection:**\n```typescript\nRandomGenerator.pick(array) // Select random element\nRandomGenerator.sample(array)(3) // Select N random elements\n```\n\n**Important:** These are curried functions. Always check `node_modules/@nestia/e2e/lib/ArrayUtil.d.ts` for correct usage patterns.\n\n### 3.4. Authentication Handling\n\n```typescript\nexport async function test_api_shopping_sale_review_update(\n connection: api.IConnection,\n) {\n const seller: IShoppingSeller = \n await api.functional.shoppings.sellers.authenticate.join(\n connection,\n {\n body: {\n email: sellerEmail,\n password: \"1234\",\n nickname: RandomGenerator.name(),\n mobile: RandomGenerator.mobile(),\n } satisfies IShoppingSeller.IJoin,\n },\n );\n // Authentication token is automatically stored in connection.headers.Authorization\n typia.assert(seller);\n}\n```\n\n> Note: The above example uses fictional functions and types - use only the actual materials provided in the next system prompt.\n\n**Authentication behavior:**\n- When API functions return authentication tokens, the SDK automatically stores them in `connection.headers`\n- You don't need to manually handle token storage or header management\n- Simply call authentication APIs when needed and continue with authenticated requests\n- Token switching (e.g., between different user roles) is handled automatically by calling the appropriate authentication API functions\n\n**IMPORTANT: Use only actual authentication APIs**\nNever attempt to create helper functions like `create_fresh_user_connection()` or similar non-existent utilities. Always use the actual authentication API functions provided in the materials to handle user login, registration, and role switching.\n\n```typescript\n// CORRECT: Use actual authentication APIs for user switching\nawait api.functional.users.authenticate.login(connection, {\n body: { email: userEmail, password: \"password\" } satisfies IUser.ILogin,\n});\n\n// WRONG: Don't create or call non-existent helper functions\n// await create_fresh_user_connection(); \u2190 This function doesn't exist\n// await switch_to_admin_user(); \u2190 This function doesn't exist\n```\n\n### 3.5. Logic Validation and Assertions\n\n```typescript\nTestValidator.equals(\"x equals y\")(3)(3);\nTestValidator.notEquals(\"x and y are different\")(3)(4);\nTestValidator.predicate(\"assert condition\")(3 === 3);\nTestValidator.error(\"error must be thrown\")(() => {\n throw new Error(\"An error thrown\");\n});\n```\n\n**Available assertion functions:**\n- `TestValidator.equals(\"title\")(expected)(actual)`\n- `TestValidator.notEquals(\"title\")(expected)(actual)`\n- `TestValidator.predicate(\"title\")(booleanCondition)`\n- `TestValidator.error(\"title\")(async () => { /* code that should throw */ })`\n\n**Type-safe equality assertions:**\nWhen using `TestValidator.equals()` and `TestValidator.notEquals()`, be careful about parameter order. The generic type is determined by the first parameter, so the second parameter must be assignable to the first parameter's type.\n\n**IMPORTANT: Use actual-first, expected-second pattern**\nFor best type compatibility, use the actual value (from API responses or variables) as the first parameter and the expected value as the second parameter:\n\n```typescript\n// CORRECT: actual value first, expected value second\nconst member: IMember = await api.functional.membership.join(connection, ...);\nTestValidator.equals(\"no recommender\")(member.recommender)(null); // member.recommender is IRecommender | null, can accept null \u2713\n\n// WRONG: expected value first, actual value second - may cause type errors\nTestValidator.equals(\"no recommender\")(null)(member.recommender); // null cannot accept IRecommender | null \u2717\n\n// CORRECT: String comparison example\nTestValidator.equals(\"user ID matches\")(createdUser.id)(expectedId); // actual first, expected second \u2713\n\n// CORRECT: Object comparison example \nTestValidator.equals(\"user data matches\")(actualUser)(expectedUserData); // actual first, expected second \u2713\n```\n\n**Additional type compatibility examples:**\n```typescript\n// CORRECT: First parameter type can accept second parameter\nconst user = { id: \"123\", name: \"John\", email: \"john@example.com\" };\nconst userSummary = { id: \"123\", name: \"John\" };\n\nTestValidator.equals(\"user contains summary data\")(user)(userSummary); // user type can accept userSummary \u2713\nTestValidator.equals(\"user summary matches\")(userSummary)(user); // WRONG: userSummary cannot accept user with extra properties \u2717\n\n// CORRECT: Extract specific properties for comparison\nTestValidator.equals(\"user ID matches\")(user.id)(userSummary.id); // string = string \u2713\nTestValidator.equals(\"user name matches\")(user.name)(userSummary.name); // string = string \u2713\n\n// CORRECT: Union type parameter order\nconst value: string | null = getSomeValue();\nTestValidator.equals(\"value should be null\")(value)(null); // string | null can accept null \u2713\nTestValidator.equals(\"value should be null\")(null)(value); // WRONG: null cannot accept string | null \u2717\n```\n\n**Rule:** Use the pattern `TestValidator.equals(\"description\")(actualValue)(expectedValue)` where actualValue is typically from API responses and expectedValue is your test expectation. If type errors occur, check that the actual value's type can accept the expected value's type.\n\n**TestValidator curried function usage:**\nAll TestValidator functions are curried and must be called with separate function calls for each parameter:\n\n```typescript\n// CORRECT: Fully curried function calls\nTestValidator.equals(\"title\")(actualValue)(expectedValue);\nTestValidator.notEquals(\"title\")(actualValue)(expectedValue);\nTestValidator.predicate(\"title\")(booleanCondition);\nTestValidator.error(\"title\")(errorFunction);\n\n// WRONG: Don't pass all parameters at once\nTestValidator.equals(\"title\", actualValue, expectedValue);\nTestValidator.equals(\"title\")(actualValue, expectedValue);\n```\n\n**Custom assertions:**\nFor complex validation logic not covered by TestValidator, use standard conditional logic:\n```typescript\nif (condition) {\n throw new Error(\"Descriptive error message\");\n}\n```\n\n**TestValidator.error() type safety:**\nWhen using `TestValidator.error()` to test error conditions, maintain strict type safety even inside the error-testing function. Never use type safety bypass mechanisms like `any`, `@ts-ignore`, or `@ts-expect-error` within the error test block.\n\n**IMPORTANT: Skip TypeScript compilation error scenarios**\nIf the test scenario requires intentionally omitting required fields or creating TypeScript compilation errors to test validation, **DO NOT IMPLEMENT** these test cases. Focus only on runtime business logic errors that can occur with valid TypeScript code.\n\n**IMPORTANT: Simple error validation only**\nWhen using `TestValidator.error()`, only test whether an error occurs or not. Do NOT attempt to validate specific error messages, error types, or implement fallback closures for error message inspection. The function signature is simply:\n\n```typescript\n// CORRECT: Simple error occurrence testing\nTestValidator.error(\"duplicate email should fail\")(() => {\n return api.functional.users.create(connection, {\n body: {\n email: existingUser.email, // This will cause a runtime business logic error\n name: RandomGenerator.name(),\n password: \"validPassword123\",\n } satisfies IUser.ICreate,\n });\n});\n\n// WRONG: Don't validate error messages or use fallback closures\nTestValidator.error(\"limit validation error\")(\n async () => {\n await api.functional.bbs.categories.patch(connection, {\n body: { page: 1, limit: 1000000 } satisfies IBbsCategories.IRequest,\n });\n },\n (error) => { // \u2190 DON'T DO THIS - no fallback closure\n if (!error?.message?.toLowerCase().includes(\"limit\"))\n throw new Error(\"Error message validation\");\n },\n);\n\n// WRONG: Don't test TypeScript compilation errors - SKIP THESE SCENARIOS\nTestValidator.error(\"missing name fails\")(() => {\n return api.functional.users.create(connection, {\n body: {\n // name: intentionally omitted \u2190 DON'T DO THIS\n email: typia.random<string & tags.Format<\"email\">>(),\n password: \"validPassword123\",\n } as any, // \u2190 NEVER USE THIS\n });\n});\n```\n\n**Rule:** Only test scenarios that involve runtime errors with properly typed, valid TypeScript code. Skip any test scenarios that require type system violations, compilation errors, or detailed error message validation.\n\n**Important:** TestValidator functions are curried and must use the pattern shown above. Always check `node_modules/@nestia/e2e/lib/TestValidator.d.ts` for exact usage patterns.\n\n### 3.7. Complete Example\n\n```typescript\n/**\n * Validate the modification of review posts.\n *\n * However, the fact that customers can write review posts in a shopping mall means \n * that the customer has already joined the shopping mall, completed product purchase \n * and payment, and the seller has completed delivery.\n *\n * Therefore, in this test function, all of these must be carried out, so before \n * writing a review post, all of the following preliminary tasks must be performed. \n * It will be quite a long process.\n *\n * 1. Seller signs up\n * 2. Seller registers a product\n * 3. Customer signs up\n * 4. Customer views the product in detail\n * 5. Customer adds the product to shopping cart\n * 6. Customer places a purchase order\n * 7. Customer confirms purchase and makes payment\n * 8. Seller confirms order and processes delivery\n * 9. Customer writes a review post\n * 10. Customer modifies the review post\n * 11. Re-view the review post to confirm modifications.\n */\nexport async function test_api_shopping_sale_review_update(\n connection: api.IConnection,\n) {\n // 1. Seller signs up\n const sellerEmail: string = typia.random<string & tags.Format<\"email\">>();\n const seller: IShoppingSeller = \n await api.functional.shoppings.sellers.authenticate.join(\n connection,\n {\n body: {\n email: sellerEmail,\n password: \"1234\",\n nickname: RandomGenerator.name(),\n mobile: RandomGenerator.mobile(),\n } satisfies IShoppingSeller.IJoin,\n },\n );\n typia.assert(seller);\n\n // 2. Seller registers a product\n const sale: IShoppingSale = \n await api.functional.shoppings.sellers.sales.create(\n connection,\n {\n body: {\n name: RandomGenerator.paragraph()(),\n description: RandomGenerator.content()()(),\n price: 10000,\n currency: \"KRW\",\n category: typia.random<\"clothes\" | \"electronics\" | \"service\">(),\n units: [{\n name: RandomGenerator.name(),\n primary: true,\n stocks: [{\n name: RandomGenerator.name(),\n quantity: 100,\n price: 10000,\n }],\n }],\n images: [],\n tags: [],\n } satisfies IShoppingSale.ICreate,\n },\n );\n typia.assert(sale);\n\n // 3. Customer signs up\n const customerEmail: string = typia.random<string & tags.Format<\"email\">>();\n const customer: IShoppingCustomer = \n await api.functional.shoppings.customers.authenticate.join(\n connection,\n {\n body: {\n email: customerEmail,\n password: \"1234\",\n nickname: RandomGenerator.name(),\n mobile: RandomGenerator.mobile(),\n } satisfies IShoppingCustomer.IJoin,\n },\n );\n typia.assert(customer);\n \n // 4. Customer views the product in detail\n const saleReloaded: IShoppingSale = \n await api.functional.shoppings.customers.sales.at(\n connection,\n {\n id: sale.id,\n },\n );\n typia.assert(saleReloaded);\n TestValidator.equals(\"sale\")(sale.id)(saleReloaded.id);\n\n // 5. Customer adds the product to shopping cart\n const commodity: IShoppingCartCommodity = \n await api.functional.shoppings.customers.carts.commodities.create(\n connection,\n {\n body: {\n sale_id: sale.id,\n stocks: sale.units.map((u) => ({\n unit_id: u.id,\n stock_id: u.stocks[0].id,\n quantity: 1,\n })),\n volume: 1,\n } satisfies IShoppingCartCommodity.ICreate,\n },\n );\n typia.assert(commodity);\n\n // 6. Customer places a purchase order\n const order: IShoppingOrder = \n await api.functional.shoppings.customers.orders.create(\n connection,\n {\n body: {\n goods: [\n {\n commodity_id: commodity.id,\n volume: 1,\n },\n ],\n } satisfies IShoppingOrder.ICreate,\n }\n );\n typia.assert(order);\n\n // 7. Customer confirms purchase and makes payment\n const publish: IShoppingOrderPublish = \n await api.functional.shoppings.customers.orders.publish.create(\n connection,\n {\n orderId: order.id,\n body: {\n address: {\n mobile: RandomGenerator.mobile(),\n name: RandomGenerator.name(),\n country: \"South Korea\",\n province: \"Seoul\",\n city: \"Seoul Seocho-gu\",\n department: RandomGenerator.paragraph()(),\n possession: `${typia.random<number & tags.Format<\"uint32\">>()}-${typia.random<number & tags.Format<\"uint32\">>()}`,\n zip_code: typia.random<\n number \n & tags.Format<\"uint32\"> \n & tags.Minimum<10000> \n & tags.Maximum<99999>>()\n .toString(),\n },\n vendor: {\n code: \"@payment-vendor-code\",\n uid: \"@payment-transaction-uid\",\n },\n } satisfies IShoppingOrderPublish.ICreate,\n },\n );\n typia.assert(publish);\n\n // Switch to seller account\n await api.functional.shoppings.sellers.authenticate.login(\n connection,\n {\n body: {\n email: sellerEmail,\n password: \"1234\",\n } satisfies IShoppingSeller.ILogin,\n },\n );\n\n // 8. Seller confirms order and processes delivery\n const orderReloaded: IShoppingOrder = \n await api.functional.shoppings.sellers.orders.at(\n connection,\n {\n id: order.id,\n }\n );\n typia.assert(orderReloaded);\n TestValidator.equals(\"order\")(order.id)(orderReloaded.id);\n\n const delivery: IShoppingDelivery = \n await api.functional.shoppings.sellers.deliveries.create(\n connection,\n {\n body: {\n pieces: order.goods.map((g) => \n g.commodity.stocks.map((s) => ({\n publish_id: publish.id,\n good_id: g.id,\n stock_id: s.id,\n quantity: 1,\n }))).flat(),\n journeys: [\n {\n type: \"delivering\",\n title: \"Delivering\",\n description: null,\n started_at: new Date().toISOString(),\n completed_at: new Date().toISOString(),\n },\n ],\n shippers: [\n {\n company: \"Lozen\",\n name: \"QuickMan\",\n mobile: \"01055559999\",\n }\n ],\n } satisfies IShoppingDelivery.ICreate\n }\n );\n typia.assert(delivery);\n\n // Switch back to customer account\n await api.functional.shoppings.customers.authenticate.login(\n connection,\n {\n body: {\n email: customerEmail,\n password: \"1234\",\n } satisfies IShoppingCustomer.ILogin,\n },\n );\n\n // 9. Customer writes a review post\n const review: IShoppingSaleReview = \n await api.functional.shoppings.customers.sales.reviews.create(\n connection,\n {\n saleId: sale.id,\n body: {\n good_id: order.goods[0].id,\n title: \"Some title\",\n body: \"Some content body\",\n format: \"md\",\n files: [],\n score: 100,\n } satisfies IShoppingSaleReview.ICreate,\n },\n );\n typia.assert(review);\n\n // 10. Customer modifies the review post\n const snapshot: IShoppingSaleReview.ISnapshot = \n await api.functional.shoppings.customers.sales.reviews.update(\n connection,\n {\n saleId: sale.id,\n id: review.id,\n body: {\n title: \"Some new title\",\n body: \"Some new content body\",\n } satisfies IShoppingSaleReview.IUpdate,\n },\n );\n typia.assert(snapshot);\n\n // 11. Re-view the review post to confirm modifications\n const read: IShoppingSaleReview = \n await api.functional.shoppings.customers.sales.reviews.at(\n connection,\n {\n saleId: sale.id,\n id: review.id,\n },\n );\n typia.assert(read);\n TestValidator.equals(\"snapshots\")(read.snapshots)([\n ...review.snapshots,\n snapshot,\n ]);\n}\n```\n\n> Note: The above example uses fictional functions and types - use only the actual materials provided in the next system prompt.\n\nThis example demonstrates:\n- **Complete business workflow**: From user registration to final validation\n- **Multiple user roles**: Switching between seller and customer accounts\n- **Realistic data flow**: Each step depends on previous steps' results\n- **Proper validation**: Type assertions and business logic validation\n- **Clear documentation**: Step-by-step comments explaining each action\n- **Error handling**: Proper use of assertions and validations\n\n## 4. Quality Standards and Best Practices\n\n### 4.1. Code Quality\n\n- Write clean, readable, and maintainable code\n- Use meaningful variable names that reflect business entities and contexts\n- Follow TypeScript best practices and maintain strict type safety\n- Ensure proper error handling and comprehensive edge case coverage\n- Never include import statements - start directly with `export async function`\n\n### 4.2. Test Design\n\n- Create realistic business scenarios that mirror real user workflows\n- Implement complete user journeys from authentication to final validation\n- Test both successful operations and error conditions thoroughly\n- Validate all aspects of the API response and business logic\n- Include proper setup, execution, and cleanup steps\n- Handle data dependencies and resource management appropriately\n\n### 4.3. Data Management\n\n- Use appropriate random data generation for test inputs with proper constraints\n- Ensure data relationships are maintained correctly throughout the workflow\n- Validate data integrity at each step of the test flow\n- Implement secure test data generation practices\n- Clean up test data and resources when necessary\n- Avoid hardcoding sensitive information in test data\n\n### 4.4. Documentation\n\n- Provide comprehensive function documentation explaining business context\n- Explain the test purpose and why this specific test is necessary\n- Document each step of the test workflow with clear, descriptive comments\n- Include rationale for test design decisions and business rule validations\n- Use step-by-step comments that explain business purpose, not just technical operations\n\n## 5. Final Checklist\n\nBefore submitting your generated E2E test code, verify:\n\n**Function Structure:**\n- [ ] Function follows the correct naming convention: `test_api_{domain}_{functionName}`\n- [ ] Function has exactly one parameter: `connection: api.IConnection`\n- [ ] No import statements - code starts directly with `export async function`\n- [ ] No external imports or functions are defined outside the main function\n- [ ] All TestValidator functions use proper curried syntax\n\n**API Integration:**\n- [ ] All API calls use proper parameter structure and type safety\n- [ ] API function calling follows the exact SDK pattern from provided materials\n- [ ] Path parameters and request body are correctly structured in the second parameter\n- [ ] All API responses are properly validated with `typia.assert()`\n- [ ] Authentication is handled correctly without manual token management\n- [ ] Only actual authentication APIs are used (no helper functions)\n\n**Business Logic:**\n- [ ] Test follows a logical, realistic business workflow\n- [ ] Complete user journey from authentication to final validation\n- [ ] Proper data dependencies and setup procedures\n- [ ] Edge cases and error conditions are appropriately tested\n- [ ] Only implementable functionality is included (unimplementable parts are omitted)\n\n**Code Quality:**\n- [ ] Random data generation uses appropriate constraints and formats\n- [ ] All TestValidator assertions use actual-first, expected-second pattern\n- [ ] Code includes comprehensive documentation and comments\n- [ ] Variable naming is descriptive and follows business context\n- [ ] Simple error validation only (no complex error message checking)\n\n**Type Safety & Code Quality:**\n- [ ] **CRITICAL**: Only API functions and DTOs from the provided materials are used (not from examples)\n- [ ] **CRITICAL**: No fictional functions or types from examples are used\n- [ ] **CRITICAL**: No type safety violations (`any`, `@ts-ignore`, `@ts-expect-error`)\n- [ ] **CRITICAL**: All TestValidator functions use correct curried syntax\n- [ ] Follows proper TypeScript conventions and type safety practices\n\n**Performance & Security:**\n- [ ] Efficient resource usage and proper cleanup where necessary\n- [ ] Secure test data generation practices\n- [ ] No hardcoded sensitive information in test data\n\nGenerate your E2E test code following these guidelines to ensure comprehensive, maintainable, and reliable API testing." /* AutoBeSystemPromptConstant.TEST_WRITE */.replace("{{AutoBeTestScenario}}", JSON.stringify({
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
endpoint: {
|
|
21
|
+
description: "The API endpoint being tested.\n\nContains the complete endpoint specification including URL, method,\nparameters, and expected responses that will be validated by this test\nscenario.",
|
|
22
|
+
$ref: "#/$defs/AutoBeOpenApi.IEndpoint"
|
|
23
|
+
},
|
|
24
|
+
draft: {
|
|
25
|
+
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.",
|
|
26
|
+
type: "string"
|
|
27
|
+
},
|
|
28
|
+
functionName: {
|
|
29
|
+
description: "Name of the function being tested.\n\nThe identifier of the API function that this test case targets, used for\norganizing and tracking test results.",
|
|
30
|
+
type: "string"
|
|
31
|
+
},
|
|
32
|
+
dependencies: {
|
|
33
|
+
description: "Functions that must be called before running the main test.\n\nDependencies required to set up test data, authenticate users, create\nresources, or establish other conditions needed for the test to execute\nsuccessfully.",
|
|
34
|
+
type: "array",
|
|
35
|
+
items: {
|
|
36
|
+
$ref: "#/$defs/AutoBeTestScenarioDependency"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
required: [
|
|
41
|
+
"endpoint",
|
|
42
|
+
"draft",
|
|
43
|
+
"functionName",
|
|
44
|
+
"dependencies"
|
|
45
|
+
],
|
|
46
|
+
additionalProperties: false,
|
|
47
|
+
$defs: {
|
|
48
|
+
"AutoBeOpenApi.IEndpoint": {
|
|
49
|
+
description: "API endpoint information.",
|
|
50
|
+
type: "object",
|
|
51
|
+
properties: {
|
|
52
|
+
path: {
|
|
53
|
+
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.",
|
|
54
|
+
type: "string"
|
|
55
|
+
},
|
|
56
|
+
method: {
|
|
57
|
+
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",
|
|
58
|
+
oneOf: [
|
|
59
|
+
{
|
|
60
|
+
"const": "get"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"const": "post"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"const": "put"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"const": "delete"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"const": "patch"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
required: [
|
|
78
|
+
"path",
|
|
79
|
+
"method"
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
AutoBeTestScenarioDependency: {
|
|
83
|
+
description: "A dependency function that must be called before the main test.\n\nRepresents a prerequisite API call needed to prepare the system state for\nsuccessful test execution.",
|
|
84
|
+
type: "object",
|
|
85
|
+
properties: {
|
|
86
|
+
purpose: {
|
|
87
|
+
description: "Why this dependency is needed.\n\nExplains the role of this prerequisite function in setting up the\nconditions required for the main test to succeed.",
|
|
88
|
+
type: "string"
|
|
89
|
+
},
|
|
90
|
+
endpoint: {
|
|
91
|
+
description: "The API endpoint for this dependency function.\n\nComplete specification of the prerequisite function that needs to be\ncalled, including parameters and expected behavior.",
|
|
92
|
+
$ref: "#/$defs/AutoBeOpenApi.IEndpoint"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
required: [
|
|
96
|
+
"purpose",
|
|
97
|
+
"endpoint"
|
|
98
|
+
]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
})),
|
|
18
102
|
},
|
|
19
103
|
{
|
|
20
104
|
id: (0, uuid_1.v4)(),
|
|
21
105
|
created_at: new Date().toISOString(),
|
|
22
106
|
type: "systemMessage",
|
|
23
|
-
text:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
107
|
+
text: utils_1.StringUtil.trim `
|
|
108
|
+
Here is the list of input material composition.
|
|
109
|
+
|
|
110
|
+
Make e2e test functions based on the following information.
|
|
111
|
+
|
|
112
|
+
## Scenario Plan
|
|
113
|
+
|
|
114
|
+
Here is the scenario plan what you have to implement.
|
|
115
|
+
|
|
116
|
+
\`\`\`json
|
|
117
|
+
${JSON.stringify(scenario)}
|
|
118
|
+
\`\`\`
|
|
119
|
+
|
|
120
|
+
## DTO Definitions
|
|
121
|
+
|
|
122
|
+
You can use these DTO definitions.
|
|
123
|
+
|
|
124
|
+
Never use the DTO definitions that are not listed here.
|
|
125
|
+
|
|
126
|
+
${transformTestWriteHistories.structures(artifacts)}
|
|
127
|
+
|
|
128
|
+
## API (SDK) Functions
|
|
129
|
+
|
|
130
|
+
You can use these API functions.
|
|
131
|
+
|
|
132
|
+
Never use the functions that are not listed here.
|
|
133
|
+
|
|
134
|
+
${transformTestWriteHistories.functional(artifacts)}
|
|
135
|
+
|
|
136
|
+
## E2E Mockup Functions
|
|
137
|
+
|
|
138
|
+
Just reference, and never follow this code as it is.
|
|
139
|
+
|
|
140
|
+
\`\`\`json
|
|
141
|
+
${JSON.stringify(artifacts.e2e)}
|
|
142
|
+
\`\`\`
|
|
143
|
+
`,
|
|
55
144
|
},
|
|
56
145
|
];
|
|
57
|
-
}
|
|
58
|
-
|
|
146
|
+
}
|
|
147
|
+
(function (transformTestWriteHistories) {
|
|
148
|
+
function structures(artifacts) {
|
|
149
|
+
return utils_1.StringUtil.trim `
|
|
150
|
+
${Object.keys(artifacts.document.components.schemas)
|
|
151
|
+
.map((k) => `- ${k}`)
|
|
152
|
+
.join("\n")}
|
|
153
|
+
|
|
154
|
+
\`\`\`json
|
|
155
|
+
${JSON.stringify(artifacts.dto)}
|
|
156
|
+
\`\`\`
|
|
157
|
+
`;
|
|
158
|
+
}
|
|
159
|
+
transformTestWriteHistories.structures = structures;
|
|
160
|
+
function functional(artifacts) {
|
|
161
|
+
const document = (0, utils_1.transformOpenApiDocument)(artifacts.document);
|
|
162
|
+
const app = openapi_1.HttpMigration.application(document);
|
|
163
|
+
return utils_1.StringUtil.trim `
|
|
164
|
+
Method | Path | Function Accessor
|
|
165
|
+
-------|------|-------------------
|
|
166
|
+
${app.routes
|
|
167
|
+
.map((r) => [r.method, r.path, `api.functional.${r.accessor.join(".")}`].join(" | "))
|
|
168
|
+
.join("\n")}
|
|
169
|
+
|
|
170
|
+
\`\`\`json
|
|
171
|
+
${JSON.stringify(artifacts.sdk)}
|
|
172
|
+
\`\`\`
|
|
173
|
+
`;
|
|
174
|
+
}
|
|
175
|
+
transformTestWriteHistories.functional = functional;
|
|
176
|
+
})(transformTestWriteHistories || (exports.transformTestWriteHistories = transformTestWriteHistories = {}));
|
|
59
177
|
//# sourceMappingURL=transformTestWriteHistories.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transformTestWriteHistories.js","sourceRoot":"","sources":["../../../src/orchestrate/test/transformTestWriteHistories.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transformTestWriteHistories.js","sourceRoot":"","sources":["../../../src/orchestrate/test/transformTestWriteHistories.ts"],"names":[],"mappings":";;;;;AAcA,kEAyDC;AArED,yCAAqE;AACrE,8CAI0B;AAC1B,kDAA0B;AAC1B,+BAA0B;AAK1B,SAAgB,2BAA2B,CACzC,QAA4B,EAC5B,SAAuC;IAEvC,OAAO;QACL;YACE,EAAE,EAAE,IAAA,SAAE,GAAE;YACR,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,mq1CAAsC,OAAO,CACjD,wBAAwB,EACxB,IAAI,CAAC,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAAqD,CACpE;SACF;QACD;YACE,EAAE,EAAE,IAAA,SAAE,GAAE;YACR,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACpC,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,kBAAU,CAAC,IAAI,CAAA;;;;;;;;;;UAUjB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;;;;;;;;;UASxB,2BAA2B,CAAC,UAAU,CAAC,SAAS,CAAC;;;;;;;;UAQjD,2BAA2B,CAAC,UAAU,CAAC,SAAS,CAAC;;;;;;;UAOjD,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC;;OAEhC;SACF;KACF,CAAC;AACJ,CAAC;AACD,WAAiB,2BAA2B;IAC1C,SAAgB,UAAU,CAAC,SAAuC;QAChE,OAAO,kBAAU,CAAC,IAAI,CAAA;QAClB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC;aACjD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;aACpB,IAAI,CAAC,IAAI,CAAC;;;QAGX,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC;;KAEhC,CAAC;IACJ,CAAC;IAVe,sCAAU,aAUzB,CAAA;IAED,SAAgB,UAAU,CAAC,SAAuC;QAChE,MAAM,QAAQ,GAAsB,IAAA,gCAAwB,EAC1D,SAAS,CAAC,QAAQ,CACnB,CAAC;QACF,MAAM,GAAG,GAA4B,uBAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QACzE,OAAO,kBAAU,CAAC,IAAI,CAAA;;;QAGlB,GAAG,CAAC,MAAM;aACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACT,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAC/D,KAAK,CACN,CACF;aACA,IAAI,CAAC,IAAI,CAAC;;;QAGX,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC;;KAEhC,CAAC;IACJ,CAAC;IApBe,sCAAU,aAoBzB,CAAA;AACH,CAAC,EAlCgB,2BAA2B,2CAA3B,2BAA2B,QAkC3C"}
|
|
@@ -59,4 +59,15 @@ export interface IAutoBeConfig {
|
|
|
59
59
|
* @default System timezone or "UTC" if unavailable
|
|
60
60
|
*/
|
|
61
61
|
timezone?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Backoff strategy for retrying failed operations.
|
|
64
|
+
*
|
|
65
|
+
* Defines the logic for retrying failed operations when the agent encounters
|
|
66
|
+
* errors. This includes retrying function calls, API requests, and other
|
|
67
|
+
* operations that may fail due to temporary issues.
|
|
68
|
+
*/
|
|
69
|
+
backoffStrategy?: (props: {
|
|
70
|
+
count: number;
|
|
71
|
+
error: unknown;
|
|
72
|
+
}) => number;
|
|
62
73
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* @returns
|
|
6
|
-
*/
|
|
7
|
-
export declare function randomBackoffRetry<T>(fn: () => Promise<T>, options?: Partial<RetryOptions>): Promise<T>;
|
|
1
|
+
export declare function randomBackoffStrategy(props: {
|
|
2
|
+
count: number;
|
|
3
|
+
error: unknown;
|
|
4
|
+
}): number;
|
|
@@ -1,44 +1,23 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
lastError = err;
|
|
28
|
-
if (attempt === maxRetries - 1)
|
|
29
|
-
throw err;
|
|
30
|
-
if (!handleError(err))
|
|
31
|
-
throw err;
|
|
32
|
-
const tempDelay = Math.min(baseDelay * 2 ** attempt, maxDelay);
|
|
33
|
-
const delay = tempDelay * (1 + Math.random() * jitter);
|
|
34
|
-
yield new Promise((res) => setTimeout(res, delay));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
throw lastError;
|
|
38
|
-
});
|
|
3
|
+
exports.randomBackoffStrategy = randomBackoffStrategy;
|
|
4
|
+
function randomBackoffStrategy(props) {
|
|
5
|
+
const { count, error } = props;
|
|
6
|
+
if (count > 5) {
|
|
7
|
+
throw error;
|
|
8
|
+
}
|
|
9
|
+
if (isRetryError(error) === false) {
|
|
10
|
+
throw error;
|
|
11
|
+
}
|
|
12
|
+
const baseDelay = 4000;
|
|
13
|
+
const maxDelay = 60000;
|
|
14
|
+
const jitter = 0.8;
|
|
15
|
+
const tempDelay = Math.min(baseDelay * 2 ** count, maxDelay);
|
|
16
|
+
const delay = tempDelay * (1 + Math.random() * jitter);
|
|
17
|
+
return delay;
|
|
39
18
|
}
|
|
40
19
|
function isRetryError(error) {
|
|
41
|
-
var _a, _b, _c;
|
|
20
|
+
var _a, _b, _c, _d;
|
|
42
21
|
// 1) Quota exceeded → No retry
|
|
43
22
|
if ((error === null || error === void 0 ? void 0 : error.code) === "insufficient_quota" ||
|
|
44
23
|
((_a = error === null || error === void 0 ? void 0 : error.error) === null || _a === void 0 ? void 0 : _a.type) === "insufficient_quota") {
|
|
@@ -68,6 +47,9 @@ function isRetryError(error) {
|
|
|
68
47
|
if ((error === null || error === void 0 ? void 0 : error.message) === "terminated" || (error === null || error === void 0 ? void 0 : error.name) === "AbortError") {
|
|
69
48
|
return true;
|
|
70
49
|
}
|
|
50
|
+
if ((_d = error === null || error === void 0 ? void 0 : error.message) === null || _d === void 0 ? void 0 : _d.startsWith(`SyntaxError: Expected ',' or '}' after property value in JSON at position`)) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
71
53
|
return false;
|
|
72
54
|
}
|
|
73
55
|
//# sourceMappingURL=backoffRetry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backoffRetry.js","sourceRoot":"","sources":["../../src/utils/backoffRetry.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backoffRetry.js","sourceRoot":"","sources":["../../src/utils/backoffRetry.ts"],"names":[],"mappings":";;AAAA,sDAoBC;AApBD,SAAgB,qBAAqB,CAAC,KAGrC;IACC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAC/B,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,MAAM,KAAK,CAAC;IACd,CAAC;IAED,IAAI,YAAY,CAAC,KAAK,CAAC,KAAK,KAAK,EAAE,CAAC;QAClC,MAAM,KAAK,CAAC;IACd,CAAC;IAED,MAAM,SAAS,GAAG,IAAK,CAAC;IACxB,MAAM,QAAQ,GAAG,KAAM,CAAC;IACxB,MAAM,MAAM,GAAG,GAAG,CAAC;IACnB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,IAAI,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,SAAS,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC;IAEvD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,KAAU;;IAC9B,+BAA+B;IAC/B,IACE,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,MAAK,oBAAoB;QACpC,CAAA,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,0CAAE,IAAI,MAAK,oBAAoB,EAC3C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,gCAAgC;IAChC,IACE,CAAC,OAAO,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,MAAM,CAAA,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC;QAC1D,CAAA,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,0CAAE,IAAI,MAAK,cAAc,EACrC,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,cAAc;IACd,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,MAAM,MAAK,GAAG,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8BAA8B;IAC9B,MAAM,IAAI,GAAG,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,MAAI,MAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,KAAK,0CAAE,IAAI,CAAA,CAAC;IAC/C,IACE;QACE,gBAAgB;QAChB,yBAAyB;QACzB,WAAW;QACX,YAAY;QACZ,OAAO;KACR,CAAC,QAAQ,CAAC,IAAI,CAAC,EAChB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iBAAiB;IACjB,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,MAAK,YAAY,IAAI,CAAA,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,IAAI,MAAK,YAAY,EAAE,CAAC;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IACE,MAAC,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAkB,0CAAE,UAAU,CACpC,2EAA2E,CAC5E,EACD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function forceRetry<T>(task: () => Promise<T>, count?: number): Promise<T>;
|
|
@@ -9,11 +9,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
exports.forceRetry = forceRetry;
|
|
13
|
+
function forceRetry(task_1) {
|
|
14
|
+
return __awaiter(this, arguments, void 0, function* (task, count = 2) {
|
|
15
|
+
let error = undefined;
|
|
16
|
+
for (let i = 0; i <= count; ++i)
|
|
17
|
+
try {
|
|
18
|
+
return yield task();
|
|
19
|
+
}
|
|
20
|
+
catch (e) {
|
|
21
|
+
error = e;
|
|
22
|
+
}
|
|
23
|
+
throw error;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=forceRetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forceRetry.js","sourceRoot":"","sources":["../../src/utils/forceRetry.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,gCAYC;AAZD,SAAsB,UAAU;yDAC9B,IAAsB,EACtB,QAAgB,CAAC;QAEjB,IAAI,KAAK,GAAY,SAAS,CAAC;QAC/B,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,EAAE,CAAC;YACrC,IAAI,CAAC;gBACH,OAAO,MAAM,IAAI,EAAE,CAAC;YACtB,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,KAAK,GAAG,CAAC,CAAC;YACZ,CAAC;QACH,MAAM,KAAK,CAAC;IACd,CAAC;CAAA"}
|