From 08276b010fcf0cabb7e9c6a366db0e111508264c Mon Sep 17 00:00:00 2001 From: Behnam Tehrani Date: Tue, 25 Nov 2025 08:57:16 -0500 Subject: [PATCH 1/3] Chore: Add output schema to tools --- .../__tests__/essentials.test.ts | 28 ++-- .../src/modelcontextprotocol/essentials.ts | 35 +++-- .../transform/transformToolOutput.ts | 2 +- .../src/shared/business-unit/output-schema.ts | 24 +++ typescript/src/shared/business-unit/tools.ts | 11 ++ .../src/shared/cart-discount/output-schema.ts | 48 ++++++ typescript/src/shared/cart-discount/tools.ts | 8 + typescript/src/shared/cart/output-schema.ts | 146 ++++++++++++++++++ typescript/src/shared/cart/tools.ts | 11 +- .../src/shared/category/output-schema.ts | 44 ++++++ typescript/src/shared/category/tools.ts | 8 + .../src/shared/channel/output-schema.ts | 39 +++++ typescript/src/shared/channel/tools.ts | 8 + .../shared/custom-objects/output-schema.ts | 35 +++++ typescript/src/shared/custom-objects/tools.ts | 8 + .../shared/customer-group/output-schema.ts | 35 +++++ typescript/src/shared/customer-group/tools.ts | 8 + .../src/shared/customer/output-schema.ts | 56 +++++++ typescript/src/shared/customer/tools.ts | 8 + .../src/shared/discount-code/output-schema.ts | 47 ++++++ typescript/src/shared/discount-code/tools.ts | 8 + .../src/shared/extensions/output-schema.ts | 36 +++++ typescript/src/shared/extensions/tools.ts | 8 + .../src/shared/inventory/output-schema.ts | 42 +++++ typescript/src/shared/inventory/tools.ts | 8 + typescript/src/shared/order/output-schema.ts | 79 ++++++++++ typescript/src/shared/order/tools.ts | 8 + .../shared/payment-methods/output-schema.ts | 43 ++++++ .../src/shared/payment-methods/tools.ts | 8 + .../src/shared/payments/output-schema.ts | 41 +++++ typescript/src/shared/payments/tools.ts | 8 + .../shared/product-discount/output-schema.ts | 42 +++++ .../src/shared/product-discount/tools.ts | 8 + .../shared/product-search/output-schema.ts | 48 ++++++ typescript/src/shared/product-search/tools.ts | 2 + .../shared/product-selection/output-schema.ts | 37 +++++ .../src/shared/product-selection/tools.ts | 8 + .../shared/product-tailoring/output-schema.ts | 40 +++++ .../src/shared/product-tailoring/tools.ts | 8 + .../src/shared/product-type/output-schema.ts | 36 +++++ typescript/src/shared/product-type/tools.ts | 8 + .../src/shared/products/output-schema.ts | 49 ++++++ typescript/src/shared/products/tools.ts | 8 + .../src/shared/project/output-schema.ts | 28 ++++ typescript/src/shared/project/tools.ts | 6 + .../src/shared/quote-request/output-schema.ts | 60 +++++++ typescript/src/shared/quote-request/tools.ts | 8 + typescript/src/shared/quote/output-schema.ts | 62 ++++++++ typescript/src/shared/quote/tools.ts | 8 + .../shared/recurring-orders/output-schema.ts | 49 ++++++ .../src/shared/recurring-orders/tools.ts | 8 + .../src/shared/reviews/output-schema.ts | 43 ++++++ typescript/src/shared/reviews/tools.ts | 8 + .../shared/shipping-methods/output-schema.ts | 43 ++++++ .../src/shared/shipping-methods/tools.ts | 8 + .../shared/shopping-lists/output-schema.ts | 44 ++++++ typescript/src/shared/shopping-lists/tools.ts | 8 + .../src/shared/staged-quote/output-schema.ts | 44 ++++++ typescript/src/shared/staged-quote/tools.ts | 8 + .../shared/standalone-price/output-schema.ts | 46 ++++++ .../src/shared/standalone-price/tools.ts | 8 + typescript/src/shared/store/output-schema.ts | 39 +++++ typescript/src/shared/store/tools.ts | 8 + .../src/shared/subscriptions/output-schema.ts | 39 +++++ typescript/src/shared/subscriptions/tools.ts | 8 + .../src/shared/tax-category/output-schema.ts | 36 +++++ typescript/src/shared/tax-category/tools.ts | 8 + .../src/shared/transactions/output-schema.ts | 20 +++ typescript/src/shared/transactions/tools.ts | 6 + typescript/src/shared/zones/output-schema.ts | 47 ++++++ typescript/src/shared/zones/tools.ts | 8 + typescript/src/types/tools.ts | 1 + 72 files changed, 1874 insertions(+), 27 deletions(-) create mode 100644 typescript/src/shared/business-unit/output-schema.ts create mode 100644 typescript/src/shared/cart-discount/output-schema.ts create mode 100644 typescript/src/shared/cart/output-schema.ts create mode 100644 typescript/src/shared/category/output-schema.ts create mode 100644 typescript/src/shared/channel/output-schema.ts create mode 100644 typescript/src/shared/custom-objects/output-schema.ts create mode 100644 typescript/src/shared/customer-group/output-schema.ts create mode 100644 typescript/src/shared/customer/output-schema.ts create mode 100644 typescript/src/shared/discount-code/output-schema.ts create mode 100644 typescript/src/shared/extensions/output-schema.ts create mode 100644 typescript/src/shared/inventory/output-schema.ts create mode 100644 typescript/src/shared/order/output-schema.ts create mode 100644 typescript/src/shared/payment-methods/output-schema.ts create mode 100644 typescript/src/shared/payments/output-schema.ts create mode 100644 typescript/src/shared/product-discount/output-schema.ts create mode 100644 typescript/src/shared/product-search/output-schema.ts create mode 100644 typescript/src/shared/product-selection/output-schema.ts create mode 100644 typescript/src/shared/product-tailoring/output-schema.ts create mode 100644 typescript/src/shared/product-type/output-schema.ts create mode 100644 typescript/src/shared/products/output-schema.ts create mode 100644 typescript/src/shared/project/output-schema.ts create mode 100644 typescript/src/shared/quote-request/output-schema.ts create mode 100644 typescript/src/shared/quote/output-schema.ts create mode 100644 typescript/src/shared/recurring-orders/output-schema.ts create mode 100644 typescript/src/shared/reviews/output-schema.ts create mode 100644 typescript/src/shared/shipping-methods/output-schema.ts create mode 100644 typescript/src/shared/shopping-lists/output-schema.ts create mode 100644 typescript/src/shared/staged-quote/output-schema.ts create mode 100644 typescript/src/shared/standalone-price/output-schema.ts create mode 100644 typescript/src/shared/store/output-schema.ts create mode 100644 typescript/src/shared/subscriptions/output-schema.ts create mode 100644 typescript/src/shared/tax-category/output-schema.ts create mode 100644 typescript/src/shared/transactions/output-schema.ts create mode 100644 typescript/src/shared/zones/output-schema.ts diff --git a/typescript/src/modelcontextprotocol/__tests__/essentials.test.ts b/typescript/src/modelcontextprotocol/__tests__/essentials.test.ts index da4ad8c..1eba9a4 100644 --- a/typescript/src/modelcontextprotocol/__tests__/essentials.test.ts +++ b/typescript/src/modelcontextprotocol/__tests__/essentials.test.ts @@ -93,7 +93,7 @@ describe('CommercetoolsAgentEssentials (ModelContextProtocol)', () => { // Set up McpServer mock to handle the fact that CommercetoolsAgentEssentials extends it (McpServer as jest.Mock).mockImplementation(function (this: any) { - this.tool = mockToolMethod; + this.registerTool = mockToolMethod; }); mockCommercetoolsAPIInstance = new CommercetoolsAPI( @@ -192,14 +192,19 @@ describe('CommercetoolsAgentEssentials (ModelContextProtocol)', () => { // Check if registerTool was called with the correct parameters expect(mockToolMethod).toHaveBeenCalledWith( mockSharedToolsData[0].method, - mockSharedToolsData[0].description, - expect.any(Object), + expect.objectContaining({ + description: mockSharedToolsData[0].description, + inputSchema: expect.any(Object), + }), + expect.any(Function) // Handler function ); expect(mockToolMethod).toHaveBeenCalledWith( mockSharedToolsData[1].method, - mockSharedToolsData[1].description, - expect.any(Object), + expect.objectContaining({ + description: mockSharedToolsData[1].description, + inputSchema: expect.any(Object), + }), expect.any(Function) // Handler function ); }); @@ -220,7 +225,7 @@ describe('CommercetoolsAgentEssentials (ModelContextProtocol)', () => { // Get the handler from the mock call await new Promise(setImmediate); const toolCallArgs = mockToolMethod.mock.calls[0]; - const handler = toolCallArgs[3]; // The async handler function + const handler = toolCallArgs[2]; // The async handler function const toolMethod = toolCallArgs[0]; const handlerArg = {paramA: 'testValue'}; @@ -435,7 +440,7 @@ describe('CommercetoolsAgentEssentials (ModelContextProtocol)', () => { // Set up McpServer mock to handle the fact that CommercetoolsAgentEssentials extends it (McpServer as jest.Mock).mockImplementation(function (this: any) { - this.tool = _mockToolMethod; + this.registerTool = _mockToolMethod; }); _mockCommercetoolsAPIInstance = new CommercetoolsAPI( @@ -540,7 +545,6 @@ describe('CommercetoolsAgentEssentials (ModelContextProtocol)', () => { expect(_mockToolMethod).toHaveBeenCalledWith( 'mcpTool1', - expect.any(String), expect.any(Object), expect.any(Function) ); @@ -575,7 +579,6 @@ describe('CommercetoolsAgentEssentials (ModelContextProtocol)', () => { expect(_mockToolMethod).toHaveBeenCalledTimes(2); expect(_mockToolMethod).toHaveBeenCalledWith( 'custom-test-tool', - expect.any(String), expect.any(Object), expect.any(Function) ); @@ -690,7 +693,7 @@ describe('CommercetoolsAgentEssentials (ModelContextProtocol)', () => { // Set up McpServer mock to handle the fact that CommercetoolsAgentEssentials extends it (McpServer as jest.Mock).mockImplementation(function (this: any) { - this.tool = mockToolMethod; + this.registerTool = mockToolMethod; }); mockCommercetoolsAPIInstance = new CommercetoolsAPI( @@ -757,13 +760,11 @@ describe('CommercetoolsAgentEssentials (ModelContextProtocol)', () => { expect(mockToolMethod).toHaveBeenCalledTimes(2); expect(mockToolMethod).toHaveBeenCalledWith( 'mcpTool1', - expect.any(String), expect.any(Object), expect.any(Function) ); expect(mockToolMethod).toHaveBeenCalledWith( 'mcpTool2', - expect.any(String), expect.any(Object), expect.any(Function) ); @@ -860,19 +861,16 @@ describe('CommercetoolsAgentEssentials (ModelContextProtocol)', () => { expect(mockToolMethod).toHaveBeenCalledTimes(5); expect(mockToolMethod).toHaveBeenCalledWith( 'list_available_tools', - expect.any(String), expect.any(Object), expect.any(Function) ); expect(mockToolMethod).toHaveBeenCalledWith( 'inject_tools', - expect.any(String), expect.any(Object), expect.any(Function) ); expect(mockToolMethod).toHaveBeenCalledWith( 'execute_tool', - expect.any(String), expect.any(Object), expect.any(Function) ); diff --git a/typescript/src/modelcontextprotocol/essentials.ts b/typescript/src/modelcontextprotocol/essentials.ts index 0812043..de91a2f 100644 --- a/typescript/src/modelcontextprotocol/essentials.ts +++ b/typescript/src/modelcontextprotocol/essentials.ts @@ -14,6 +14,7 @@ import {Tool} from '../types/tools'; import {contextToBulkTools} from '../shared/bulk/tools'; import {DYNAMIC_TOOL_LOADING_THRESHOLD} from '../shared/constants'; import {transformToolOutput} from './transform'; +import {transformTitle} from './transform/transformToolOutput'; class CommercetoolsAgentEssentials extends McpServer { private authConfig: AuthConfig; @@ -167,10 +168,21 @@ class CommercetoolsAgentEssentials extends McpServer { private registerSingleTool(tool: Tool): void { const {method, execute} = tool; - this.tool( + this.registerTool( tool.method, - tool.description, - tool.parameters.shape, + { + description: tool.description, + inputSchema: tool.parameters.shape, + ...(this.configuration.context?.toolOutputFormat === 'json' && + tool.outputSchema && { + outputSchema: z.object({ + [transformTitle(tool.name)]: z.preprocess( + (val) => JSON.parse(val as string), + tool.outputSchema + ), + }).shape, + }), + }, async (args: Record) => { const result = await this.commercetoolsAPI.run(method, args, execute); return this.createToolResponse( @@ -189,11 +201,12 @@ class CommercetoolsAgentEssentials extends McpServer { filteredTools: Tool[] ): void { type ToolShape = z.infer; - - this.tool( + this.registerTool( injectTools.method, - injectTools.description, - injectTools.parameters.shape, + { + description: injectTools.description, + inputSchema: injectTools.parameters.shape, + }, async (arg: ToolShape) => { const toolsToInject = filteredTools.filter((tool) => arg.toolMethods.includes(tool.method) @@ -216,10 +229,12 @@ class CommercetoolsAgentEssentials extends McpServer { private registerExecuteTool(executeTool: Tool): void { type ToolShape = z.infer; - this.tool( + this.registerTool( executeTool.method, - executeTool.description, - executeTool.parameters.shape, + { + description: executeTool.description, + inputSchema: executeTool.parameters.shape, + }, async (args: ToolShape) => { try { const result = await this.commercetoolsAPI.run( diff --git a/typescript/src/modelcontextprotocol/transform/transformToolOutput.ts b/typescript/src/modelcontextprotocol/transform/transformToolOutput.ts index da069a2..3700604 100644 --- a/typescript/src/modelcontextprotocol/transform/transformToolOutput.ts +++ b/typescript/src/modelcontextprotocol/transform/transformToolOutput.ts @@ -58,7 +58,7 @@ export const transformToolOutput = (args: { transformedData ?? emptyObjectTransformValue); }; -const transformTitle = (title: string) => +export const transformTitle = (title: string) => `${transformPropertyName(title).toUpperCase()}`; /** diff --git a/typescript/src/shared/business-unit/output-schema.ts b/typescript/src/shared/business-unit/output-schema.ts new file mode 100644 index 0000000..2d385f0 --- /dev/null +++ b/typescript/src/shared/business-unit/output-schema.ts @@ -0,0 +1,24 @@ +import {z} from 'zod'; + +// Generated schemas for business-unit +// DO NOT EDIT - This file is auto-generated + +// Base BusinessUnit schema +export const businessUnitSchema = z.union([z.any(), z.any()]); + +// Paged BusinessUnitPagedQueryResponse schema +export const businessUnitPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readBusinessUnitOutputSchema = + businessUnitSchema || businessUnitPagedSchema; + +export const createBusinessUnitOutputSchema = businessUnitSchema; +export const updateBusinessUnitOutputSchema = businessUnitSchema; diff --git a/typescript/src/shared/business-unit/tools.ts b/typescript/src/shared/business-unit/tools.ts index 693a3c8..88795fa 100644 --- a/typescript/src/shared/business-unit/tools.ts +++ b/typescript/src/shared/business-unit/tools.ts @@ -9,6 +9,11 @@ import { createBusinessUnitParameters, updateBusinessUnitParameters, } from './parameters'; +import { + readBusinessUnitOutputSchema, + createBusinessUnitOutputSchema, + updateBusinessUnitOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {z} from 'zod'; import {Context} from '../../types/configuration'; @@ -28,6 +33,8 @@ const tools: Record = { 'business-unit': { read: true, }, + + outputSchema: readBusinessUnitOutputSchema, }, }, create_business_unit: { @@ -44,6 +51,8 @@ const tools: Record = { 'business-unit': { create: true, }, + + outputSchema: createBusinessUnitOutputSchema, }, }, update_business_unit: { @@ -60,6 +69,8 @@ const tools: Record = { 'business-unit': { update: true, }, + + outputSchema: updateBusinessUnitOutputSchema, }, }, }; diff --git a/typescript/src/shared/cart-discount/output-schema.ts b/typescript/src/shared/cart-discount/output-schema.ts new file mode 100644 index 0000000..63db2b3 --- /dev/null +++ b/typescript/src/shared/cart-discount/output-schema.ts @@ -0,0 +1,48 @@ +import {z} from 'zod'; + +// Generated schemas for cart-discount +// DO NOT EDIT - This file is auto-generated + +// Base CartDiscount schema +export const cartDiscountSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + name: z.any(), + key: z.string().optional(), + description: z.any().optional(), + value: z.any(), + cartPredicate: z.string(), + target: z.any().optional(), + sortOrder: z.string(), + stores: z.array(z.any()), + isActive: z.boolean(), + validFrom: z.string().optional(), + validUntil: z.string().optional(), + requiresDiscountCode: z.boolean(), + references: z.array(z.any()), + stackingMode: z.any(), + custom: z.any().optional(), + discountGroup: z.any().optional(), + }) + .strict(); + +// Paged CartDiscountPagedQueryResponse schema +export const cartDiscountPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readCartDiscountOutputSchema = + cartDiscountSchema || cartDiscountPagedSchema; +export const createCartDiscountOutputSchema = cartDiscountSchema; +export const updateCartDiscountOutputSchema = cartDiscountSchema; diff --git a/typescript/src/shared/cart-discount/tools.ts b/typescript/src/shared/cart-discount/tools.ts index 4c566ac..ad38d84 100644 --- a/typescript/src/shared/cart-discount/tools.ts +++ b/typescript/src/shared/cart-discount/tools.ts @@ -9,6 +9,11 @@ import { createCartDiscountParameters, updateCartDiscountParameters, } from './parameters'; +import { + readCartDiscountOutputSchema, + createCartDiscountOutputSchema, + updateCartDiscountOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -23,6 +28,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readCartDiscountOutputSchema, }, create_cart_discount: { method: 'create_cart_discount', @@ -34,6 +40,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createCartDiscountOutputSchema, }, update_cart_discount: { method: 'update_cart_discount', @@ -45,6 +52,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateCartDiscountOutputSchema, }, }; diff --git a/typescript/src/shared/cart/output-schema.ts b/typescript/src/shared/cart/output-schema.ts new file mode 100644 index 0000000..2474a1c --- /dev/null +++ b/typescript/src/shared/cart/output-schema.ts @@ -0,0 +1,146 @@ +import {z} from 'zod'; + +// Generated schemas for cart +// DO NOT EDIT - This file is auto-generated + +// Base Cart schema +export const cartSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + key: z + .string() + + .optional(), + customerId: z + .string() + + .optional(), + customerEmail: z + .string() + + .optional(), + customerGroup: z + .any() + + .optional(), + anonymousId: z + .string() + + .optional(), + businessUnit: z + .any() + + .optional(), + store: z + .any() + + .optional(), + lineItems: z.array(z.any()), + customLineItems: z.array(z.any()), + totalLineItemQuantity: z + .number() + + .optional(), + totalPrice: z.any(), + taxedPrice: z + .any() + + .optional(), + taxedShippingPrice: z + .any() + + .optional(), + discountOnTotalPrice: z + .any() + + .optional(), + taxMode: z.any(), + priceRoundingMode: z.any(), + taxRoundingMode: z.any(), + taxCalculationMode: z.any(), + inventoryMode: z.any(), + cartState: z.any(), + billingAddress: z + .any() + + .optional(), + shippingAddress: z + .any() + + .optional(), + shippingMode: z.any(), + shippingKey: z + .string() + + .optional(), + shippingInfo: z + .any() + + .optional(), + shippingRateInput: z + .any() + + .optional(), + shippingCustomFields: z + .any() + + .optional(), + shipping: z.array(z.any()), + itemShippingAddresses: z.array(z.any()), + discountCodes: z.array(z.any()), + directDiscounts: z.array(z.any()), + refusedGifts: z.array(z.any()), + paymentInfo: z + .any() + + .optional(), + country: z + .string() + + .optional(), + locale: z + .string() + + .optional(), + origin: z.any(), + custom: z.any().optional(), + discountTypeCombination: z + .any() + + .optional(), + deleteDaysAfterLastModification: z + .number() + + .optional(), + lastModifiedBy: z + .any() + + .optional(), + createdBy: z + .any() + + .optional(), + }) + .strict(); + +// Paged CartPagedQueryResponse schema +export const cartPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z + .number() + + .optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readCartOutputSchema = cartSchema || cartPagedSchema; +export const createCartOutputSchema = cartSchema; +export const replicateCartOutputSchema = cartSchema; +export const updateCartOutputSchema = cartSchema; diff --git a/typescript/src/shared/cart/tools.ts b/typescript/src/shared/cart/tools.ts index 2ff517c..e4f5dac 100644 --- a/typescript/src/shared/cart/tools.ts +++ b/typescript/src/shared/cart/tools.ts @@ -11,10 +11,15 @@ import { replicateCartParameters, updateCartParameters, } from './parameters'; +import { + readCartOutputSchema, + createCartOutputSchema, + replicateCartOutputSchema, + updateCartOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {z} from 'zod'; import {Context} from '../../types/configuration'; - const tools: Record = { read_cart: { method: 'read_cart', @@ -26,6 +31,7 @@ const tools: Record = { any, any >, + outputSchema: readCartOutputSchema, actions: { cart: { read: true, @@ -47,6 +53,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createCartOutputSchema, }, replicate_cart: { method: 'replicate_cart', @@ -63,6 +70,7 @@ const tools: Record = { create: true, }, }, + outputSchema: replicateCartOutputSchema, }, update_cart: { method: 'update_cart', @@ -79,6 +87,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateCartOutputSchema, }, }; diff --git a/typescript/src/shared/category/output-schema.ts b/typescript/src/shared/category/output-schema.ts new file mode 100644 index 0000000..8b815aa --- /dev/null +++ b/typescript/src/shared/category/output-schema.ts @@ -0,0 +1,44 @@ +import {z} from 'zod'; + +// Generated schemas for category +// DO NOT EDIT - This file is auto-generated + +// Base Category schema +export const categorySchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + name: z.any(), + slug: z.any(), + description: z.any().optional(), + ancestors: z.array(z.any()), + parent: z.any().optional(), + orderHint: z.string(), + externalId: z.string().optional(), + metaTitle: z.any().optional(), + metaDescription: z.any().optional(), + metaKeywords: z.any().optional(), + custom: z.any().optional(), + assets: z.array(z.any()).optional(), + key: z.string().optional(), + }) + .strict(); + +// Paged CategoryPagedQueryResponse schema +export const categoryPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readCategoryOutputSchema = categorySchema || categoryPagedSchema; +export const createCategoryOutputSchema = categorySchema; +export const updateCategoryOutputSchema = categorySchema; diff --git a/typescript/src/shared/category/tools.ts b/typescript/src/shared/category/tools.ts index a104fd6..82f523b 100644 --- a/typescript/src/shared/category/tools.ts +++ b/typescript/src/shared/category/tools.ts @@ -9,6 +9,11 @@ import { createCategoryParameters, updateCategoryParameters, } from './parameters'; +import { + readCategoryOutputSchema, + createCategoryOutputSchema, + updateCategoryOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -23,6 +28,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readCategoryOutputSchema, }, create_category: { method: 'create_category', @@ -34,6 +40,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createCategoryOutputSchema, }, update_category: { method: 'update_category', @@ -45,6 +52,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateCategoryOutputSchema, }, }; diff --git a/typescript/src/shared/channel/output-schema.ts b/typescript/src/shared/channel/output-schema.ts new file mode 100644 index 0000000..7ab47df --- /dev/null +++ b/typescript/src/shared/channel/output-schema.ts @@ -0,0 +1,39 @@ +import {z} from 'zod'; + +// Generated schemas for channel +// DO NOT EDIT - This file is auto-generated + +// Base Channel schema +export const channelSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + key: z.string(), + roles: z.array(z.any()), + name: z.any().optional(), + description: z.any().optional(), + address: z.any().optional(), + reviewRatingStatistics: z.any().optional(), + custom: z.any().optional(), + geoLocation: z.any().optional(), + }) + .strict(); + +// Paged ChannelPagedQueryResponse schema +export const channelPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readChannelOutputSchema = channelSchema || channelPagedSchema; +export const createChannelOutputSchema = channelSchema; +export const updateChannelOutputSchema = channelSchema; diff --git a/typescript/src/shared/channel/tools.ts b/typescript/src/shared/channel/tools.ts index 269c8db..b9f4a2c 100644 --- a/typescript/src/shared/channel/tools.ts +++ b/typescript/src/shared/channel/tools.ts @@ -9,6 +9,11 @@ import { createChannelParameters, updateChannelParameters, } from './parameters'; +import { + readChannelOutputSchema, + createChannelOutputSchema, + updateChannelOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -23,6 +28,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readChannelOutputSchema, }, create_channel: { method: 'create_channel', @@ -34,6 +40,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createChannelOutputSchema, }, update_channel: { method: 'update_channel', @@ -45,6 +52,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateChannelOutputSchema, }, }; diff --git a/typescript/src/shared/custom-objects/output-schema.ts b/typescript/src/shared/custom-objects/output-schema.ts new file mode 100644 index 0000000..6c9bc09 --- /dev/null +++ b/typescript/src/shared/custom-objects/output-schema.ts @@ -0,0 +1,35 @@ +import {z} from 'zod'; + +// Generated schemas for custom-objects +// DO NOT EDIT - This file is auto-generated + +// Base CustomObject schema +export const customObjectsSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + container: z.string(), + key: z.string(), + value: z.any(), + }) + .strict(); + +// Paged CustomObjectPagedQueryResponse schema +export const customObjectsPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readCustomObjectOutputSchema = + customObjectsSchema || customObjectsPagedSchema; +export const createCustomObjectOutputSchema = customObjectsSchema; +export const updateCustomObjectOutputSchema = customObjectsSchema; diff --git a/typescript/src/shared/custom-objects/tools.ts b/typescript/src/shared/custom-objects/tools.ts index 25320ef..5b075df 100644 --- a/typescript/src/shared/custom-objects/tools.ts +++ b/typescript/src/shared/custom-objects/tools.ts @@ -3,6 +3,11 @@ import { readCustomObjectParameters, updateCustomObjectParameters, } from './parameters'; +import { + readCustomObjectOutputSchema, + createCustomObjectOutputSchema, + updateCustomObjectOutputSchema, +} from './output-schema'; import { readCustomObjectPrompt, createCustomObjectPrompt, @@ -22,6 +27,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readCustomObjectOutputSchema, }, create_custom_object: { name: 'Create Custom Object', @@ -33,6 +39,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createCustomObjectOutputSchema, }, update_custom_object: { name: 'Update Custom Object', @@ -44,6 +51,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateCustomObjectOutputSchema, }, }; diff --git a/typescript/src/shared/customer-group/output-schema.ts b/typescript/src/shared/customer-group/output-schema.ts new file mode 100644 index 0000000..cccb332 --- /dev/null +++ b/typescript/src/shared/customer-group/output-schema.ts @@ -0,0 +1,35 @@ +import {z} from 'zod'; + +// Generated schemas for customer-group +// DO NOT EDIT - This file is auto-generated + +// Base CustomerGroup schema +export const customerGroupSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + key: z.string().optional(), + name: z.string(), + custom: z.any().optional(), + }) + .strict(); + +// Paged CustomerGroupPagedQueryResponse schema +export const customerGroupPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readCustomerGroupOutputSchema = + customerGroupSchema || customerGroupPagedSchema; +export const createCustomerGroupOutputSchema = customerGroupSchema; +export const updateCustomerGroupOutputSchema = customerGroupSchema; diff --git a/typescript/src/shared/customer-group/tools.ts b/typescript/src/shared/customer-group/tools.ts index 18070e7..b2b3a3c 100644 --- a/typescript/src/shared/customer-group/tools.ts +++ b/typescript/src/shared/customer-group/tools.ts @@ -13,6 +13,11 @@ import { updateCustomerGroupParameters, } from './parameters'; +import { + readCustomerGroupOutputSchema, + createCustomerGroupOutputSchema, + updateCustomerGroupOutputSchema, +} from './output-schema'; const tools: Record = { read_customer_group: { method: 'read_customer_group', @@ -29,6 +34,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readCustomerGroupOutputSchema, }, create_customer_group: { method: 'create_customer_group', @@ -45,6 +51,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createCustomerGroupOutputSchema, }, update_customer_group: { method: 'update_customer_group', @@ -61,6 +68,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateCustomerGroupOutputSchema, }, }; diff --git a/typescript/src/shared/customer/output-schema.ts b/typescript/src/shared/customer/output-schema.ts new file mode 100644 index 0000000..1b17b3c --- /dev/null +++ b/typescript/src/shared/customer/output-schema.ts @@ -0,0 +1,56 @@ +import {z} from 'zod'; + +// Generated schemas for customer +// DO NOT EDIT - This file is auto-generated + +// Base Customer schema +export const customerSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + key: z.string().optional(), + customerNumber: z.string().optional(), + externalId: z.string().optional(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + email: z.string(), + password: z.string().optional(), + firstName: z.string().optional(), + lastName: z.string().optional(), + middleName: z.string().optional(), + title: z.string().optional(), + dateOfBirth: z.string().optional(), + companyName: z.string().optional(), + vatId: z.string().optional(), + addresses: z.array(z.any()), + defaultShippingAddressId: z.string().optional(), + shippingAddressIds: z.array(z.string()).optional(), + defaultBillingAddressId: z.string().optional(), + billingAddressIds: z.array(z.string()).optional(), + isEmailVerified: z.boolean(), + customerGroup: z.any().optional(), + customerGroupAssignments: z.array(z.any()).optional(), + custom: z.any().optional(), + locale: z.string().optional(), + salutation: z.string().optional(), + stores: z.array(z.any()), + authenticationMode: z.any(), + }) + .strict(); + +// Paged CustomerPagedQueryResponse schema +export const customerPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const createCustomerOutputSchema = customerSchema; +export const readCustomerOutputSchema = customerSchema || customerPagedSchema; +export const updateCustomerOutputSchema = customerSchema; diff --git a/typescript/src/shared/customer/tools.ts b/typescript/src/shared/customer/tools.ts index 423ccdc..0f70cb1 100644 --- a/typescript/src/shared/customer/tools.ts +++ b/typescript/src/shared/customer/tools.ts @@ -9,6 +9,11 @@ import { readCustomerParameters, updateCustomerParameters, } from './parameters'; +import { + createCustomerOutputSchema, + readCustomerOutputSchema, + updateCustomerOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -23,6 +28,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createCustomerOutputSchema, }, read_customer: { method: 'read_customer', @@ -34,6 +40,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readCustomerOutputSchema, }, update_customer: { method: 'update_customer', @@ -45,6 +52,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateCustomerOutputSchema, }, }; diff --git a/typescript/src/shared/discount-code/output-schema.ts b/typescript/src/shared/discount-code/output-schema.ts new file mode 100644 index 0000000..347a204 --- /dev/null +++ b/typescript/src/shared/discount-code/output-schema.ts @@ -0,0 +1,47 @@ +import {z} from 'zod'; + +// Generated schemas for discount-code +// DO NOT EDIT - This file is auto-generated + +// Base DiscountCode schema +export const discountCodeSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + key: z.string().optional(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + name: z.any().optional(), + description: z.any().optional(), + code: z.string(), + cartDiscounts: z.array(z.any()), + cartPredicate: z.string().optional(), + isActive: z.boolean(), + references: z.array(z.any()), + maxApplications: z.number().optional(), + maxApplicationsPerCustomer: z.number().optional(), + custom: z.any().optional(), + groups: z.array(z.string()), + validFrom: z.string().optional(), + validUntil: z.string().optional(), + applicationVersion: z.number().optional(), + }) + .strict(); + +// Paged DiscountCodePagedQueryResponse schema +export const discountCodePagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readDiscountCodeOutputSchema = + discountCodeSchema || discountCodePagedSchema; +export const createDiscountCodeOutputSchema = discountCodeSchema; +export const updateDiscountCodeOutputSchema = discountCodeSchema; diff --git a/typescript/src/shared/discount-code/tools.ts b/typescript/src/shared/discount-code/tools.ts index a7d650e..91a8e2f 100644 --- a/typescript/src/shared/discount-code/tools.ts +++ b/typescript/src/shared/discount-code/tools.ts @@ -9,6 +9,11 @@ import { createDiscountCodeParameters, updateDiscountCodeParameters, } from './parameters'; +import { + readDiscountCodeOutputSchema, + createDiscountCodeOutputSchema, + updateDiscountCodeOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -23,6 +28,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readDiscountCodeOutputSchema, }, create_discount_code: { method: 'create_discount_code', @@ -34,6 +40,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createDiscountCodeOutputSchema, }, update_discount_code: { method: 'update_discount_code', @@ -45,6 +52,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateDiscountCodeOutputSchema, }, }; diff --git a/typescript/src/shared/extensions/output-schema.ts b/typescript/src/shared/extensions/output-schema.ts new file mode 100644 index 0000000..38b68b0 --- /dev/null +++ b/typescript/src/shared/extensions/output-schema.ts @@ -0,0 +1,36 @@ +import {z} from 'zod'; + +// Generated schemas for extensions +// DO NOT EDIT - This file is auto-generated + +// Base Extension schema +export const extensionsSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + key: z.string().optional(), + destination: z.any(), + triggers: z.array(z.any()), + timeoutInMs: z.number().optional(), + }) + .strict(); + +// Paged ExtensionPagedQueryResponse schema +export const extensionsPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readExtensionOutputSchema = + extensionsSchema || extensionsPagedSchema; +export const createExtensionOutputSchema = extensionsSchema; +export const updateExtensionOutputSchema = extensionsSchema; diff --git a/typescript/src/shared/extensions/tools.ts b/typescript/src/shared/extensions/tools.ts index b0a48c9..e3b083b 100644 --- a/typescript/src/shared/extensions/tools.ts +++ b/typescript/src/shared/extensions/tools.ts @@ -3,6 +3,11 @@ import { readExtensionParameters, updateExtensionParameters, } from './parameters'; +import { + readExtensionOutputSchema, + createExtensionOutputSchema, + updateExtensionOutputSchema, +} from './output-schema'; import { readExtensionPrompt, createExtensionPrompt, @@ -22,6 +27,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readExtensionOutputSchema, }, create_extension: { name: 'Create Extension', @@ -33,6 +39,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createExtensionOutputSchema, }, update_extension: { name: 'Update Extension', @@ -44,6 +51,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateExtensionOutputSchema, }, }; diff --git a/typescript/src/shared/inventory/output-schema.ts b/typescript/src/shared/inventory/output-schema.ts new file mode 100644 index 0000000..b5f1347 --- /dev/null +++ b/typescript/src/shared/inventory/output-schema.ts @@ -0,0 +1,42 @@ +import {z} from 'zod'; + +// Generated schemas for inventory +// DO NOT EDIT - This file is auto-generated + +// Base InventoryEntry schema +export const inventorySchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + key: z.string().optional(), + sku: z.string(), + supplyChannel: z.any().optional(), + quantityOnStock: z.number(), + availableQuantity: z.number(), + minCartQuantity: z.number().optional(), + maxCartQuantity: z.number().optional(), + restockableInDays: z.number().optional(), + expectedDelivery: z.string().optional(), + custom: z.any().optional(), + }) + .strict(); + +// Paged InventoryPagedQueryResponse schema +export const inventoryPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readInventoryOutputSchema = + inventorySchema || inventoryPagedSchema; +export const createInventoryOutputSchema = inventorySchema; +export const updateInventoryOutputSchema = inventorySchema; diff --git a/typescript/src/shared/inventory/tools.ts b/typescript/src/shared/inventory/tools.ts index 786a9e0..192ecaf 100644 --- a/typescript/src/shared/inventory/tools.ts +++ b/typescript/src/shared/inventory/tools.ts @@ -3,6 +3,11 @@ import { readInventoryParameters, updateInventoryParameters, } from './parameters'; +import { + readInventoryOutputSchema, + createInventoryOutputSchema, + updateInventoryOutputSchema, +} from './output-schema'; import { readInventoryPrompt, createInventoryPrompt, @@ -22,6 +27,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readInventoryOutputSchema, }, create_inventory: { name: 'Create Inventory', @@ -33,6 +39,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createInventoryOutputSchema, }, update_inventory: { name: 'Update Inventory', @@ -44,6 +51,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateInventoryOutputSchema, }, }; diff --git a/typescript/src/shared/order/output-schema.ts b/typescript/src/shared/order/output-schema.ts new file mode 100644 index 0000000..2fbbef5 --- /dev/null +++ b/typescript/src/shared/order/output-schema.ts @@ -0,0 +1,79 @@ +import {z} from 'zod'; + +// Generated schemas for order +// DO NOT EDIT - This file is auto-generated + +// Base Order schema +export const orderSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + orderNumber: z.string().optional(), + purchaseOrderNumber: z.string().optional(), + customerId: z.string().optional(), + customerEmail: z.string().optional(), + customerGroup: z.any().optional(), + anonymousId: z.string().optional(), + businessUnit: z.any().optional(), + store: z.any().optional(), + lineItems: z.array(z.any()), + customLineItems: z.array(z.any()), + totalPrice: z.any(), + taxedPrice: z.any().optional(), + taxedShippingPrice: z.any().optional(), + discountOnTotalPrice: z.any().optional(), + priceRoundingMode: z.any().optional(), + taxMode: z.any().optional(), + taxRoundingMode: z.any().optional(), + taxCalculationMode: z.any().optional(), + inventoryMode: z.any().optional(), + billingAddress: z.any().optional(), + shippingAddress: z.any().optional(), + shippingMode: z.any(), + shippingKey: z.string().optional(), + shippingInfo: z.any().optional(), + shippingRateInput: z.any().optional(), + shippingCustomFields: z.any().optional(), + shipping: z.array(z.any()), + itemShippingAddresses: z.array(z.any()).optional(), + discountCodes: z.array(z.any()).optional(), + directDiscounts: z.array(z.any()).optional(), + refusedGifts: z.array(z.any()), + paymentInfo: z.any().optional(), + country: z.string().optional(), + locale: z.string().optional(), + origin: z.any(), + cart: z.any().optional(), + quote: z.any().optional(), + recurringOrder: z.any().optional(), + orderState: z.any(), + shipmentState: z.any().optional(), + paymentState: z.any().optional(), + state: z.any().optional(), + syncInfo: z.array(z.any()), + returnInfo: z.array(z.any()).optional(), + discountTypeCombination: z.any().optional(), + lastMessageSequenceNumber: z.number().optional(), + custom: z.any().optional(), + completedAt: z.string().optional(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + }) + .strict(); + +// Paged OrderPagedQueryResponse schema +export const orderPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readOrderOutputSchema = orderSchema || orderPagedSchema; +export const createOrderOutputSchema = orderSchema; +export const updateOrderOutputSchema = orderSchema; diff --git a/typescript/src/shared/order/tools.ts b/typescript/src/shared/order/tools.ts index ffa6f33..b735d66 100644 --- a/typescript/src/shared/order/tools.ts +++ b/typescript/src/shared/order/tools.ts @@ -5,6 +5,11 @@ import { createOrderParameters, updateOrderParameters, } from './parameters'; +import { + readOrderOutputSchema, + createOrderOutputSchema, + updateOrderOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {z} from 'zod'; import {Context} from '../../types/configuration'; @@ -20,6 +25,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readOrderOutputSchema, }, create_order: { method: 'create_order', @@ -36,6 +42,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createOrderOutputSchema, }, update_order: { method: 'update_order', @@ -47,6 +54,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateOrderOutputSchema, }, }; diff --git a/typescript/src/shared/payment-methods/output-schema.ts b/typescript/src/shared/payment-methods/output-schema.ts new file mode 100644 index 0000000..68b808b --- /dev/null +++ b/typescript/src/shared/payment-methods/output-schema.ts @@ -0,0 +1,43 @@ +import {z} from 'zod'; + +// Generated schemas for payment-methods +// DO NOT EDIT - This file is auto-generated + +// Base PaymentMethod schema +export const paymentMethodsSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + key: z.string().optional(), + name: z.any().optional(), + customer: z.any().optional(), + businessUnit: z.any().optional(), + method: z.string().optional(), + paymentInterface: z.string().optional(), + interfaceAccount: z.string().optional(), + token: z.any().optional(), + paymentMethodStatus: z.any(), + default: z.boolean(), + custom: z.any().optional(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + }) + .strict(); + +// Paged PaymentMethodPagedQueryResponse schema +export const paymentMethodsPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readPaymentMethodsOutputSchema = + paymentMethodsSchema || paymentMethodsPagedSchema; +export const createPaymentMethodsOutputSchema = paymentMethodsSchema; +export const updatePaymentMethodsOutputSchema = paymentMethodsSchema; diff --git a/typescript/src/shared/payment-methods/tools.ts b/typescript/src/shared/payment-methods/tools.ts index 580e9f7..d3442b6 100644 --- a/typescript/src/shared/payment-methods/tools.ts +++ b/typescript/src/shared/payment-methods/tools.ts @@ -5,6 +5,11 @@ import { createPaymentMethodParameters, updatePaymentMethodParameters, } from './parameters'; +import { + readPaymentMethodsOutputSchema, + createPaymentMethodsOutputSchema, + updatePaymentMethodsOutputSchema, +} from './output-schema'; import { readPaymentMethodPrompt, createPaymentMethodPrompt, @@ -22,6 +27,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readPaymentMethodsOutputSchema, }, create_payment_methods: { method: 'create_payment_methods', @@ -33,6 +39,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createPaymentMethodsOutputSchema, }, update_payment_methods: { method: 'update_payment_methods', @@ -44,6 +51,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updatePaymentMethodsOutputSchema, }, }; diff --git a/typescript/src/shared/payments/output-schema.ts b/typescript/src/shared/payments/output-schema.ts new file mode 100644 index 0000000..bf09d87 --- /dev/null +++ b/typescript/src/shared/payments/output-schema.ts @@ -0,0 +1,41 @@ +import {z} from 'zod'; + +// Generated schemas for payments +// DO NOT EDIT - This file is auto-generated + +// Base Payment schema +export const paymentsSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + customer: z.any().optional(), + anonymousId: z.string().optional(), + interfaceId: z.string().optional(), + amountPlanned: z.any(), + paymentMethodInfo: z.any(), + paymentStatus: z.any(), + transactions: z.array(z.any()), + interfaceInteractions: z.array(z.any()), + custom: z.any().optional(), + key: z.string().optional(), + }) + .strict(); + +// Paged PaymentPagedQueryResponse schema +export const paymentsPagedSchema = z + .object({ + limit: z.number(), + count: z.number(), + total: z.number().optional(), + offset: z.number(), + results: z.array(z.any()), + }) + .strict(); + +export const readPaymentsOutputSchema = paymentsSchema || paymentsPagedSchema; +export const createPaymentsOutputSchema = paymentsSchema; +export const updatePaymentsOutputSchema = paymentsSchema; diff --git a/typescript/src/shared/payments/tools.ts b/typescript/src/shared/payments/tools.ts index c433ca3..f906060 100644 --- a/typescript/src/shared/payments/tools.ts +++ b/typescript/src/shared/payments/tools.ts @@ -3,6 +3,11 @@ import { createPaymentParameters, updatePaymentParameters, } from './parameters'; +import { + readPaymentsOutputSchema, + createPaymentsOutputSchema, + updatePaymentsOutputSchema, +} from './output-schema'; import { readPaymentPrompt, createPaymentPrompt, @@ -22,6 +27,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readPaymentsOutputSchema, }, create_payments: { name: 'Create Payment', @@ -33,6 +39,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createPaymentsOutputSchema, }, update_payments: { name: 'Update Payment', @@ -44,6 +51,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updatePaymentsOutputSchema, }, }; diff --git a/typescript/src/shared/product-discount/output-schema.ts b/typescript/src/shared/product-discount/output-schema.ts new file mode 100644 index 0000000..f8352e5 --- /dev/null +++ b/typescript/src/shared/product-discount/output-schema.ts @@ -0,0 +1,42 @@ +import {z} from 'zod'; + +// Generated schemas for product-discount +// DO NOT EDIT - This file is auto-generated + +// Base ProductDiscount schema +export const productDiscountSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + name: z.any(), + key: z.string().optional(), + description: z.any().optional(), + value: z.any(), + predicate: z.string(), + sortOrder: z.string(), + isActive: z.boolean(), + references: z.array(z.any()), + validFrom: z.string().optional(), + validUntil: z.string().optional(), + }) + .strict(); + +// Paged ProductDiscountPagedQueryResponse schema +export const productDiscountPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readProductDiscountOutputSchema = + productDiscountSchema || productDiscountPagedSchema; +export const createProductDiscountOutputSchema = productDiscountSchema; +export const updateProductDiscountOutputSchema = productDiscountSchema; diff --git a/typescript/src/shared/product-discount/tools.ts b/typescript/src/shared/product-discount/tools.ts index 4450ebe..1ba4bc1 100644 --- a/typescript/src/shared/product-discount/tools.ts +++ b/typescript/src/shared/product-discount/tools.ts @@ -9,6 +9,11 @@ import { createProductDiscountParameters, updateProductDiscountParameters, } from './parameters'; +import { + readProductDiscountOutputSchema, + createProductDiscountOutputSchema, + updateProductDiscountOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -23,6 +28,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readProductDiscountOutputSchema, }, create_product_discount: { method: 'create_product_discount', @@ -34,6 +40,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createProductDiscountOutputSchema, }, update_product_discount: { method: 'update_product_discount', @@ -45,6 +52,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateProductDiscountOutputSchema, }, }; diff --git a/typescript/src/shared/product-search/output-schema.ts b/typescript/src/shared/product-search/output-schema.ts new file mode 100644 index 0000000..b93453e --- /dev/null +++ b/typescript/src/shared/product-search/output-schema.ts @@ -0,0 +1,48 @@ +import {z} from 'zod'; + +// Generated schemas for product-search +// DO NOT EDIT - This file is auto-generated + +// Base ProductProjection schema +export const productSearchSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + key: z.string().optional(), + productType: z.any(), + name: z.any(), + description: z.any().optional(), + slug: z.any(), + categories: z.array(z.any()), + categoryOrderHints: z.any().optional(), + metaTitle: z.any().optional(), + metaDescription: z.any().optional(), + metaKeywords: z.any().optional(), + searchKeywords: z.any().optional(), + hasStagedChanges: z.boolean().optional(), + published: z.boolean().optional(), + masterVariant: z.any(), + variants: z.array(z.any()), + taxCategory: z.any().optional(), + state: z.any().optional(), + reviewRatingStatistics: z.any().optional(), + priceMode: z.any().optional(), + attributes: z.array(z.any()), + }) + .strict(); + +// Paged ProductProjectionPagedSearchResponse schema +export const productSearchPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + facets: z.any().optional(), + }) + .strict(); + +export const searchProductsOutputSchema = productSearchPagedSchema; diff --git a/typescript/src/shared/product-search/tools.ts b/typescript/src/shared/product-search/tools.ts index 50cc8d6..622fdeb 100644 --- a/typescript/src/shared/product-search/tools.ts +++ b/typescript/src/shared/product-search/tools.ts @@ -1,5 +1,6 @@ import {searchProductsPrompt} from './prompts'; import {searchProductsParameters} from './parameters'; +import {searchProductsOutputSchema} from './output-schema'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -14,6 +15,7 @@ const tools: Record = { read: true, }, }, + outputSchema: searchProductsOutputSchema, }, }; diff --git a/typescript/src/shared/product-selection/output-schema.ts b/typescript/src/shared/product-selection/output-schema.ts new file mode 100644 index 0000000..e791d79 --- /dev/null +++ b/typescript/src/shared/product-selection/output-schema.ts @@ -0,0 +1,37 @@ +import {z} from 'zod'; + +// Generated schemas for product-selection +// DO NOT EDIT - This file is auto-generated + +// Base ProductSelection schema +export const productSelectionSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + key: z.string().optional(), + name: z.any(), + productCount: z.number(), + mode: z.any(), + custom: z.any().optional(), + }) + .strict(); + +// Paged ProductSelectionPagedQueryResponse schema +export const productSelectionPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readProductSelectionOutputSchema = + productSelectionSchema || productSelectionPagedSchema; +export const createProductSelectionOutputSchema = productSelectionSchema; +export const updateProductSelectionOutputSchema = productSelectionSchema; diff --git a/typescript/src/shared/product-selection/tools.ts b/typescript/src/shared/product-selection/tools.ts index dc47532..3402266 100644 --- a/typescript/src/shared/product-selection/tools.ts +++ b/typescript/src/shared/product-selection/tools.ts @@ -9,6 +9,11 @@ import { createProductSelectionParameters, updateProductSelectionParameters, } from './parameters'; +import { + readProductSelectionOutputSchema, + createProductSelectionOutputSchema, + updateProductSelectionOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -23,6 +28,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readProductSelectionOutputSchema, }, create_product_selection: { method: 'create_product_selection', @@ -34,6 +40,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createProductSelectionOutputSchema, }, update_product_selection: { method: 'update_product_selection', @@ -45,6 +52,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateProductSelectionOutputSchema, }, }; diff --git a/typescript/src/shared/product-tailoring/output-schema.ts b/typescript/src/shared/product-tailoring/output-schema.ts new file mode 100644 index 0000000..109f175 --- /dev/null +++ b/typescript/src/shared/product-tailoring/output-schema.ts @@ -0,0 +1,40 @@ +import {z} from 'zod'; + +// Generated schemas for product-tailoring +// DO NOT EDIT - This file is auto-generated + +// Base ProductTailoring schema +export const productTailoringSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + key: z.string().optional(), + store: z.any(), + product: z.any(), + published: z.boolean(), + current: z.any(), + staged: z.any(), + hasStagedChanges: z.boolean(), + warnings: z.array(z.any()).optional(), + }) + .strict(); + +// Paged ProductTailoringPagedQueryResponse schema +export const productTailoringPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readProductTailoringOutputSchema = + productTailoringSchema || productTailoringPagedSchema; +export const createProductTailoringOutputSchema = productTailoringSchema; +export const updateProductTailoringOutputSchema = productTailoringSchema; diff --git a/typescript/src/shared/product-tailoring/tools.ts b/typescript/src/shared/product-tailoring/tools.ts index d236674..91c9d50 100644 --- a/typescript/src/shared/product-tailoring/tools.ts +++ b/typescript/src/shared/product-tailoring/tools.ts @@ -3,6 +3,11 @@ import { createProductTailoringParameters, updateProductTailoringParameters, } from './parameters'; +import { + readProductTailoringOutputSchema, + createProductTailoringOutputSchema, + updateProductTailoringOutputSchema, +} from './output-schema'; import { readProductTailoringPrompt, createProductTailoringPrompt, @@ -25,6 +30,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readProductTailoringOutputSchema, }, create_product_tailoring: { name: 'Create product tailoring', @@ -36,6 +42,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createProductTailoringOutputSchema, }, update_product_tailoring: { name: 'Update product tailoring', @@ -47,6 +54,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateProductTailoringOutputSchema, }, }; diff --git a/typescript/src/shared/product-type/output-schema.ts b/typescript/src/shared/product-type/output-schema.ts new file mode 100644 index 0000000..9e1b64e --- /dev/null +++ b/typescript/src/shared/product-type/output-schema.ts @@ -0,0 +1,36 @@ +import {z} from 'zod'; + +// Generated schemas for product-type +// DO NOT EDIT - This file is auto-generated + +// Base ProductType schema +export const productTypeSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + key: z.string().optional(), + name: z.string(), + description: z.string(), + attributes: z.array(z.any()).optional(), + }) + .strict(); + +// Paged ProductTypePagedQueryResponse schema +export const productTypePagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readProductTypeOutputSchema = + productTypeSchema || productTypePagedSchema; +export const createProductTypeOutputSchema = productTypeSchema; +export const updateProductTypeOutputSchema = productTypeSchema; diff --git a/typescript/src/shared/product-type/tools.ts b/typescript/src/shared/product-type/tools.ts index 50af5d9..8f15d9d 100644 --- a/typescript/src/shared/product-type/tools.ts +++ b/typescript/src/shared/product-type/tools.ts @@ -9,6 +9,11 @@ import { createProductTypeParameters, updateProductTypeParameters, } from './parameters'; +import { + readProductTypeOutputSchema, + createProductTypeOutputSchema, + updateProductTypeOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -23,6 +28,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readProductTypeOutputSchema, }, create_product_type: { method: 'create_product_type', @@ -34,6 +40,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createProductTypeOutputSchema, }, update_product_type: { method: 'update_product_type', @@ -45,6 +52,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateProductTypeOutputSchema, }, }; diff --git a/typescript/src/shared/products/output-schema.ts b/typescript/src/shared/products/output-schema.ts new file mode 100644 index 0000000..3c43b70 --- /dev/null +++ b/typescript/src/shared/products/output-schema.ts @@ -0,0 +1,49 @@ +import {z} from 'zod'; + +// Generated schemas for products +// DO NOT EDIT - This file is auto-generated + +// Base ProductProjection schema +export const productsSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + key: z.string().optional(), + productType: z.any(), + name: z.any(), + description: z.any().optional(), + slug: z.any(), + categories: z.array(z.any()), + categoryOrderHints: z.any().optional(), + metaTitle: z.any().optional(), + metaDescription: z.any().optional(), + metaKeywords: z.any().optional(), + searchKeywords: z.any().optional(), + hasStagedChanges: z.boolean().optional(), + published: z.boolean().optional(), + masterVariant: z.any(), + variants: z.array(z.any()), + taxCategory: z.any().optional(), + state: z.any().optional(), + reviewRatingStatistics: z.any().optional(), + priceMode: z.any().optional(), + attributes: z.array(z.any()), + }) + .strict(); + +// Paged ProductProjectionPagedQueryResponse schema +export const productsPagedSchema = z + .object({ + limit: z.number(), + count: z.number(), + total: z.number().optional(), + offset: z.number(), + results: z.array(z.any()), + }) + .strict(); + +export const listProductsOutputSchema = productsSchema || productsPagedSchema; +export const createProductOutputSchema = productsSchema; +export const updateProductOutputSchema = productsSchema; diff --git a/typescript/src/shared/products/tools.ts b/typescript/src/shared/products/tools.ts index 4907790..8091685 100644 --- a/typescript/src/shared/products/tools.ts +++ b/typescript/src/shared/products/tools.ts @@ -9,6 +9,11 @@ import { listProductsParameters, updateProductParameters, } from './parameters'; +import { + listProductsOutputSchema, + createProductOutputSchema, + updateProductOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -23,6 +28,7 @@ const tools: Record = { read: true, }, }, + outputSchema: listProductsOutputSchema, }, create_product: { method: 'create_product', @@ -34,6 +40,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createProductOutputSchema, }, update_product: { method: 'update_product', @@ -45,6 +52,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateProductOutputSchema, }, }; diff --git a/typescript/src/shared/project/output-schema.ts b/typescript/src/shared/project/output-schema.ts new file mode 100644 index 0000000..449b073 --- /dev/null +++ b/typescript/src/shared/project/output-schema.ts @@ -0,0 +1,28 @@ +import {z} from 'zod'; + +// Generated schemas for project +// DO NOT EDIT - This file is auto-generated + +// Base Project schema +export const projectSchema = z + .object({ + version: z.number(), + key: z.string(), + name: z.string(), + countries: z.array(z.string()), + currencies: z.array(z.string()), + languages: z.array(z.string()), + createdAt: z.string(), + trialUntil: z.string().optional(), + messages: z.any(), + carts: z.any(), + shoppingLists: z.any().optional(), + shippingRateInputType: z.any().optional(), + externalOAuth: z.any().optional(), + searchIndexing: z.any().optional(), + businessUnits: z.any().optional(), + }) + .strict(); + +export const readProjectOutputSchema = projectSchema; +export const updateProjectOutputSchema = projectSchema; diff --git a/typescript/src/shared/project/tools.ts b/typescript/src/shared/project/tools.ts index a4caea7..e82e74d 100644 --- a/typescript/src/shared/project/tools.ts +++ b/typescript/src/shared/project/tools.ts @@ -1,5 +1,9 @@ import {readProjectPrompt, updateProjectPrompt} from './prompts'; import {readProjectParameters, updateProjectParameters} from './parameters'; +import { + readProjectOutputSchema, + updateProjectOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -14,6 +18,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readProjectOutputSchema, }, update_project: { method: 'update_project', @@ -25,6 +30,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateProjectOutputSchema, }, }; diff --git a/typescript/src/shared/quote-request/output-schema.ts b/typescript/src/shared/quote-request/output-schema.ts new file mode 100644 index 0000000..6121739 --- /dev/null +++ b/typescript/src/shared/quote-request/output-schema.ts @@ -0,0 +1,60 @@ +import {z} from 'zod'; + +// Generated schemas for quote-request +// DO NOT EDIT - This file is auto-generated + +// Base QuoteRequest schema +export const quoteRequestSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + key: z.string().optional(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + quoteRequestState: z.any(), + comment: z.string().optional(), + customer: z.any(), + customerGroup: z.any().optional(), + store: z.any().optional(), + lineItems: z.array(z.any()), + customLineItems: z.array(z.any()), + totalPrice: z.any(), + taxedPrice: z.any().optional(), + shippingAddress: z.any().optional(), + billingAddress: z.any().optional(), + inventoryMode: z.any().optional(), + taxMode: z.any(), + priceRoundingMode: z.any(), + taxRoundingMode: z.any(), + taxCalculationMode: z.any(), + country: z.string().optional(), + shippingInfo: z.any().optional(), + paymentInfo: z.any().optional(), + shippingRateInput: z.any().optional(), + itemShippingAddresses: z.array(z.any()).optional(), + directDiscounts: z.array(z.any()).optional(), + custom: z.any().optional(), + state: z.any().optional(), + purchaseOrderNumber: z.string().optional(), + cart: z.any().optional(), + businessUnit: z.any().optional(), + }) + .strict(); + +// Paged QuoteRequestPagedQueryResponse schema +export const quoteRequestPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readQuoteRequestOutputSchema = + quoteRequestSchema || quoteRequestPagedSchema; +export const createQuoteRequestOutputSchema = quoteRequestSchema; +export const updateQuoteRequestOutputSchema = quoteRequestSchema; diff --git a/typescript/src/shared/quote-request/tools.ts b/typescript/src/shared/quote-request/tools.ts index b4213e6..d36db77 100644 --- a/typescript/src/shared/quote-request/tools.ts +++ b/typescript/src/shared/quote-request/tools.ts @@ -9,6 +9,11 @@ import { createQuoteRequestParameters, updateQuoteRequestParameters, } from './parameters'; +import { + readQuoteRequestOutputSchema, + createQuoteRequestOutputSchema, + updateQuoteRequestOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {z} from 'zod'; import {Context} from '../../types/configuration'; @@ -29,6 +34,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readQuoteRequestOutputSchema, }, create_quote_request: { method: 'create_quote_request', @@ -45,6 +51,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createQuoteRequestOutputSchema, }, update_quote_request: { method: 'update_quote_request', @@ -61,6 +68,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateQuoteRequestOutputSchema, }, }; diff --git a/typescript/src/shared/quote/output-schema.ts b/typescript/src/shared/quote/output-schema.ts new file mode 100644 index 0000000..23f2839 --- /dev/null +++ b/typescript/src/shared/quote/output-schema.ts @@ -0,0 +1,62 @@ +import {z} from 'zod'; + +// Generated schemas for quote +// DO NOT EDIT - This file is auto-generated + +// Base Quote schema +export const quoteSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + key: z.string().optional(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + quoteRequest: z.any(), + stagedQuote: z.any(), + customer: z.any().optional(), + customerGroup: z.any().optional(), + validTo: z.string().optional(), + sellerComment: z.string().optional(), + buyerComment: z.string().optional(), + store: z.any().optional(), + lineItems: z.array(z.any()), + customLineItems: z.array(z.any()), + totalPrice: z.any(), + taxedPrice: z.any().optional(), + shippingAddress: z.any().optional(), + billingAddress: z.any().optional(), + inventoryMode: z.any().optional(), + taxMode: z.any(), + priceRoundingMode: z.any(), + taxRoundingMode: z.any(), + taxCalculationMode: z.any(), + country: z.string().optional(), + shippingInfo: z.any().optional(), + paymentInfo: z.any().optional(), + shippingRateInput: z.any().optional(), + itemShippingAddresses: z.array(z.any()).optional(), + directDiscounts: z.array(z.any()).optional(), + custom: z.any().optional(), + quoteState: z.any(), + state: z.any().optional(), + purchaseOrderNumber: z.string().optional(), + businessUnit: z.any().optional(), + }) + .strict(); + +// Paged QuotePagedQueryResponse schema +export const quotePagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readQuoteOutputSchema = quoteSchema || quotePagedSchema; +export const createQuoteOutputSchema = quoteSchema; +export const updateQuoteOutputSchema = quoteSchema; diff --git a/typescript/src/shared/quote/tools.ts b/typescript/src/shared/quote/tools.ts index 411a86b..7920e6b 100644 --- a/typescript/src/shared/quote/tools.ts +++ b/typescript/src/shared/quote/tools.ts @@ -5,6 +5,11 @@ import { createQuoteParameters, updateQuoteParameters, } from './parameters'; +import { + readQuoteOutputSchema, + createQuoteOutputSchema, + updateQuoteOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {z} from 'zod'; import {Context} from '../../types/configuration'; @@ -25,6 +30,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readQuoteOutputSchema, }, create_quote: { method: 'create_quote', @@ -41,6 +47,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createQuoteOutputSchema, }, update_quote: { method: 'update_quote', @@ -57,6 +64,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateQuoteOutputSchema, }, }; diff --git a/typescript/src/shared/recurring-orders/output-schema.ts b/typescript/src/shared/recurring-orders/output-schema.ts new file mode 100644 index 0000000..52a812c --- /dev/null +++ b/typescript/src/shared/recurring-orders/output-schema.ts @@ -0,0 +1,49 @@ +import {z} from 'zod'; + +// Generated schemas for recurring-orders +// DO NOT EDIT - This file is auto-generated + +// Base RecurringOrder schema +export const recurringOrdersSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + key: z.string().optional(), + cart: z.any(), + originOrder: z.any(), + startsAt: z.string(), + resumesAt: z.string().optional(), + expiresAt: z.string().optional(), + lastOrderAt: z.string().optional(), + nextOrderAt: z.string().optional(), + skipConfiguration: z.any().optional(), + store: z.any().optional(), + businessUnit: z.any().optional(), + state: z.any().optional(), + recurringOrderState: z.any(), + schedule: z.any(), + customer: z.any().optional(), + customerEmail: z.string().optional(), + custom: z.any().optional(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + }) + .strict(); + +// Paged RecurringOrderPagedQueryResponse schema +export const recurringOrdersPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readRecurringOrdersOutputSchema = + recurringOrdersSchema || recurringOrdersPagedSchema; +export const createRecurringOrdersOutputSchema = recurringOrdersSchema; +export const updateRecurringOrdersOutputSchema = recurringOrdersSchema; diff --git a/typescript/src/shared/recurring-orders/tools.ts b/typescript/src/shared/recurring-orders/tools.ts index 732f882..9628c78 100644 --- a/typescript/src/shared/recurring-orders/tools.ts +++ b/typescript/src/shared/recurring-orders/tools.ts @@ -3,6 +3,11 @@ import { readRecurringOrderParameters, updateRecurringOrderParameters, } from './parameters'; +import { + readRecurringOrdersOutputSchema, + createRecurringOrdersOutputSchema, + updateRecurringOrdersOutputSchema, +} from './output-schema'; import { readRecurringOrderPrompt, createRecurringOrderPrompt, @@ -22,6 +27,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readRecurringOrdersOutputSchema, }, create_recurring_orders: { name: 'Create Recurring Orders', @@ -33,6 +39,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createRecurringOrdersOutputSchema, }, update_recurring_orders: { name: 'Update Recurring Orders', @@ -44,6 +51,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateRecurringOrdersOutputSchema, }, }; diff --git a/typescript/src/shared/reviews/output-schema.ts b/typescript/src/shared/reviews/output-schema.ts new file mode 100644 index 0000000..26b5599 --- /dev/null +++ b/typescript/src/shared/reviews/output-schema.ts @@ -0,0 +1,43 @@ +import {z} from 'zod'; + +// Generated schemas for reviews +// DO NOT EDIT - This file is auto-generated + +// Base Review schema +export const reviewsSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + key: z.string().optional(), + uniquenessValue: z.string().optional(), + locale: z.string().optional(), + authorName: z.string().optional(), + title: z.string().optional(), + text: z.string().optional(), + target: z.union([z.any(), z.any()]).optional(), + includedInStatistics: z.boolean(), + rating: z.number().optional(), + state: z.any().optional(), + customer: z.any().optional(), + custom: z.any().optional(), + }) + .strict(); + +// Paged ReviewPagedQueryResponse schema +export const reviewsPagedSchema = z + .object({ + limit: z.number(), + count: z.number(), + total: z.number().optional(), + offset: z.number(), + results: z.array(z.any()), + }) + .strict(); + +export const readReviewOutputSchema = reviewsSchema || reviewsPagedSchema; +export const createReviewOutputSchema = reviewsSchema; +export const updateReviewOutputSchema = reviewsSchema; diff --git a/typescript/src/shared/reviews/tools.ts b/typescript/src/shared/reviews/tools.ts index 3b4d859..2cde159 100644 --- a/typescript/src/shared/reviews/tools.ts +++ b/typescript/src/shared/reviews/tools.ts @@ -3,6 +3,11 @@ import { readReviewParameters, updateReviewParameters, } from './parameters'; +import { + readReviewOutputSchema, + createReviewOutputSchema, + updateReviewOutputSchema, +} from './output-schema'; import { readReviewPrompt, createReviewPrompt, @@ -22,6 +27,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readReviewOutputSchema, }, create_review: { name: 'Create Review', @@ -33,6 +39,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createReviewOutputSchema, }, update_review: { name: 'Update Review', @@ -44,6 +51,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateReviewOutputSchema, }, }; diff --git a/typescript/src/shared/shipping-methods/output-schema.ts b/typescript/src/shared/shipping-methods/output-schema.ts new file mode 100644 index 0000000..7370087 --- /dev/null +++ b/typescript/src/shared/shipping-methods/output-schema.ts @@ -0,0 +1,43 @@ +import {z} from 'zod'; + +// Generated schemas for shipping-methods +// DO NOT EDIT - This file is auto-generated + +// Base ShippingMethod schema +export const shippingMethodsSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + key: z.string().optional(), + name: z.string(), + localizedName: z.any().optional(), + description: z.string().optional(), + localizedDescription: z.any().optional(), + taxCategory: z.any(), + zoneRates: z.array(z.any()), + active: z.boolean(), + isDefault: z.boolean(), + predicate: z.string().optional(), + custom: z.any().optional(), + }) + .strict(); + +// Paged ShippingMethodPagedQueryResponse schema +export const shippingMethodsPagedSchema = z + .object({ + limit: z.number().optional(), + count: z.number(), + total: z.number().optional(), + offset: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readShippingMethodsOutputSchema = + shippingMethodsSchema || shippingMethodsPagedSchema; +export const createShippingMethodsOutputSchema = shippingMethodsSchema; +export const updateShippingMethodsOutputSchema = shippingMethodsSchema; diff --git a/typescript/src/shared/shipping-methods/tools.ts b/typescript/src/shared/shipping-methods/tools.ts index 5f18769..8e5a630 100644 --- a/typescript/src/shared/shipping-methods/tools.ts +++ b/typescript/src/shared/shipping-methods/tools.ts @@ -3,6 +3,11 @@ import { readShippingMethodParameters, updateShippingMethodParameters, } from './parameters'; +import { + readShippingMethodsOutputSchema, + createShippingMethodsOutputSchema, + updateShippingMethodsOutputSchema, +} from './output-schema'; import { readShippingMethodPrompt, createShippingMethodPrompt, @@ -22,6 +27,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readShippingMethodsOutputSchema, }, create_shipping_methods: { name: 'Create Shipping Method', @@ -33,6 +39,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createShippingMethodsOutputSchema, }, update_shipping_methods: { name: 'Update Shipping Method', @@ -44,6 +51,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateShippingMethodsOutputSchema, }, }; diff --git a/typescript/src/shared/shopping-lists/output-schema.ts b/typescript/src/shared/shopping-lists/output-schema.ts new file mode 100644 index 0000000..b1e2216 --- /dev/null +++ b/typescript/src/shared/shopping-lists/output-schema.ts @@ -0,0 +1,44 @@ +import {z} from 'zod'; + +// Generated schemas for shopping-lists +// DO NOT EDIT - This file is auto-generated + +// Base ShoppingList schema +export const shoppingListsSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + name: z.any(), + key: z.string().optional(), + customer: z.any().optional(), + slug: z.any().optional(), + description: z.any().optional(), + lineItems: z.array(z.any()), + textLineItems: z.array(z.any()), + deleteDaysAfterLastModification: z.number().optional(), + anonymousId: z.string().optional(), + store: z.any().optional(), + businessUnit: z.any().optional(), + custom: z.any().optional(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + }) + .strict(); + +// Paged ShoppingListPagedQueryResponse schema +export const shoppingListsPagedSchema = z + .object({ + limit: z.number(), + count: z.number(), + total: z.number().optional(), + offset: z.number(), + results: z.array(z.any()), + }) + .strict(); + +export const readShoppingListOutputSchema = + shoppingListsSchema || shoppingListsPagedSchema; +export const createShoppingListOutputSchema = shoppingListsSchema; +export const updateShoppingListOutputSchema = shoppingListsSchema; diff --git a/typescript/src/shared/shopping-lists/tools.ts b/typescript/src/shared/shopping-lists/tools.ts index c6c8077..4048e9c 100644 --- a/typescript/src/shared/shopping-lists/tools.ts +++ b/typescript/src/shared/shopping-lists/tools.ts @@ -3,6 +3,11 @@ import { readShoppingListParameters, updateShoppingListParameters, } from './parameters'; +import { + readShoppingListOutputSchema, + createShoppingListOutputSchema, + updateShoppingListOutputSchema, +} from './output-schema'; import { readShoppingListPrompt, createShoppingListPrompt, @@ -22,6 +27,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readShoppingListOutputSchema, }, create_shopping_list: { name: 'Create Shopping List', @@ -33,6 +39,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createShoppingListOutputSchema, }, update_shopping_list: { name: 'Update Shopping List', @@ -44,6 +51,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateShoppingListOutputSchema, }, }; diff --git a/typescript/src/shared/staged-quote/output-schema.ts b/typescript/src/shared/staged-quote/output-schema.ts new file mode 100644 index 0000000..bd3e9ab --- /dev/null +++ b/typescript/src/shared/staged-quote/output-schema.ts @@ -0,0 +1,44 @@ +import {z} from 'zod'; + +// Generated schemas for staged-quote +// DO NOT EDIT - This file is auto-generated + +// Base StagedQuote schema +export const stagedQuoteSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + key: z.string().optional(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + stagedQuoteState: z.any(), + customer: z.any().optional(), + quoteRequest: z.any(), + quotationCart: z.any(), + validTo: z.string().optional(), + sellerComment: z.string().optional(), + custom: z.any().optional(), + state: z.any().optional(), + purchaseOrderNumber: z.string().optional(), + businessUnit: z.any().optional(), + store: z.any().optional(), + }) + .strict(); + +// Paged StagedQuotePagedQueryResponse schema +export const stagedQuotePagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readStagedQuoteOutputSchema = + stagedQuoteSchema || stagedQuotePagedSchema; +export const createStagedQuoteOutputSchema = stagedQuoteSchema; +export const updateStagedQuoteOutputSchema = stagedQuoteSchema; diff --git a/typescript/src/shared/staged-quote/tools.ts b/typescript/src/shared/staged-quote/tools.ts index bd0aaf5..ffeb8ca 100644 --- a/typescript/src/shared/staged-quote/tools.ts +++ b/typescript/src/shared/staged-quote/tools.ts @@ -5,6 +5,11 @@ import { createStagedQuoteParameters, updateStagedQuoteParameters, } from './parameters'; +import { + readStagedQuoteOutputSchema, + createStagedQuoteOutputSchema, + updateStagedQuoteOutputSchema, +} from './output-schema'; import { readStagedQuotePrompt, createStagedQuotePrompt, @@ -22,6 +27,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readStagedQuoteOutputSchema, }, create_staged_quote: { method: 'create_staged_quote', @@ -33,6 +39,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createStagedQuoteOutputSchema, }, update_staged_quote: { method: 'update_staged_quote', @@ -44,6 +51,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateStagedQuoteOutputSchema, }, }; diff --git a/typescript/src/shared/standalone-price/output-schema.ts b/typescript/src/shared/standalone-price/output-schema.ts new file mode 100644 index 0000000..0c83fa0 --- /dev/null +++ b/typescript/src/shared/standalone-price/output-schema.ts @@ -0,0 +1,46 @@ +import {z} from 'zod'; + +// Generated schemas for standalone-price +// DO NOT EDIT - This file is auto-generated + +// Base StandalonePrice schema +export const standalonePriceSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + key: z.string().optional(), + sku: z.string(), + value: z.any(), + country: z.string().optional(), + customerGroup: z.any().optional(), + channel: z.any().optional(), + validFrom: z.string().optional(), + validUntil: z.string().optional(), + tiers: z.array(z.any()).optional(), + discounted: z.any().optional(), + custom: z.any().optional(), + staged: z.any().optional(), + active: z.boolean(), + recurrencePolicy: z.any().optional(), + }) + .strict(); + +// Paged StandalonePricePagedQueryResponse schema +export const standalonePricePagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readStandalonePriceOutputSchema = + standalonePriceSchema || standalonePricePagedSchema; +export const createStandalonePriceOutputSchema = standalonePriceSchema; +export const updateStandalonePriceOutputSchema = standalonePriceSchema; diff --git a/typescript/src/shared/standalone-price/tools.ts b/typescript/src/shared/standalone-price/tools.ts index 4adfbc7..d6dbff2 100644 --- a/typescript/src/shared/standalone-price/tools.ts +++ b/typescript/src/shared/standalone-price/tools.ts @@ -9,6 +9,11 @@ import { createStandalonePriceParameters, updateStandalonePriceParameters, } from './parameters'; +import { + readStandalonePriceOutputSchema, + createStandalonePriceOutputSchema, + updateStandalonePriceOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -23,6 +28,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readStandalonePriceOutputSchema, }, create_standalone_price: { method: 'create_standalone_price', @@ -34,6 +40,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createStandalonePriceOutputSchema, }, update_standalone_price: { method: 'update_standalone_price', @@ -45,6 +52,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateStandalonePriceOutputSchema, }, }; diff --git a/typescript/src/shared/store/output-schema.ts b/typescript/src/shared/store/output-schema.ts new file mode 100644 index 0000000..523a972 --- /dev/null +++ b/typescript/src/shared/store/output-schema.ts @@ -0,0 +1,39 @@ +import {z} from 'zod'; + +// Generated schemas for store +// DO NOT EDIT - This file is auto-generated + +// Base Store schema +export const storeSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + key: z.string(), + name: z.any().optional(), + languages: z.array(z.string()), + countries: z.array(z.any()), + distributionChannels: z.array(z.any()), + supplyChannels: z.array(z.any()), + productSelections: z.array(z.any()), + custom: z.any().optional(), + }) + .strict(); + +// Paged StorePagedQueryResponse schema +export const storePagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readStoreOutputSchema = storeSchema || storePagedSchema; +export const createStoreOutputSchema = storeSchema; +export const updateStoreOutputSchema = storeSchema; diff --git a/typescript/src/shared/store/tools.ts b/typescript/src/shared/store/tools.ts index eac082b..ee574f3 100644 --- a/typescript/src/shared/store/tools.ts +++ b/typescript/src/shared/store/tools.ts @@ -5,6 +5,11 @@ import { createStoreParameters, updateStoreParameters, } from './parameters'; +import { + readStoreOutputSchema, + createStoreOutputSchema, + updateStoreOutputSchema, +} from './output-schema'; import {Tool} from '../../types/tools'; import {z} from 'zod'; import {Context} from '../../types/configuration'; @@ -25,6 +30,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readStoreOutputSchema, }, create_store: { method: 'create_store', @@ -41,6 +47,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createStoreOutputSchema, }, update_store: { method: 'update_store', @@ -57,6 +64,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateStoreOutputSchema, }, }; diff --git a/typescript/src/shared/subscriptions/output-schema.ts b/typescript/src/shared/subscriptions/output-schema.ts new file mode 100644 index 0000000..9cc83d7 --- /dev/null +++ b/typescript/src/shared/subscriptions/output-schema.ts @@ -0,0 +1,39 @@ +import {z} from 'zod'; + +// Generated schemas for subscriptions +// DO NOT EDIT - This file is auto-generated + +// Base Subscription schema +export const subscriptionsSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + destination: z.any(), + key: z.string().optional(), + messages: z.array(z.any()), + changes: z.array(z.any()), + events: z.array(z.any()), + format: z.any(), + status: z.any(), + }) + .strict(); + +// Paged SubscriptionPagedQueryResponse schema +export const subscriptionsPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readSubscriptionOutputSchema = + subscriptionsSchema || subscriptionsPagedSchema; +export const createSubscriptionOutputSchema = subscriptionsSchema; +export const updateSubscriptionOutputSchema = subscriptionsSchema; diff --git a/typescript/src/shared/subscriptions/tools.ts b/typescript/src/shared/subscriptions/tools.ts index 1e49254..723a469 100644 --- a/typescript/src/shared/subscriptions/tools.ts +++ b/typescript/src/shared/subscriptions/tools.ts @@ -3,6 +3,11 @@ import { readSubscriptionParameters, updateSubscriptionParameters, } from './parameters'; +import { + readSubscriptionOutputSchema, + createSubscriptionOutputSchema, + updateSubscriptionOutputSchema, +} from './output-schema'; import { readSubscriptionPrompt, createSubscriptionPrompt, @@ -22,6 +27,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readSubscriptionOutputSchema, }, create_subscription: { name: 'Create Subscription', @@ -33,6 +39,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createSubscriptionOutputSchema, }, update_subscription: { name: 'Update Subscription', @@ -44,6 +51,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateSubscriptionOutputSchema, }, }; diff --git a/typescript/src/shared/tax-category/output-schema.ts b/typescript/src/shared/tax-category/output-schema.ts new file mode 100644 index 0000000..c134c39 --- /dev/null +++ b/typescript/src/shared/tax-category/output-schema.ts @@ -0,0 +1,36 @@ +import {z} from 'zod'; + +// Generated schemas for tax-category +// DO NOT EDIT - This file is auto-generated + +// Base TaxCategory schema +export const taxCategorySchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), + name: z.string(), + description: z.string().optional(), + rates: z.array(z.any()), + key: z.string().optional(), + }) + .strict(); + +// Paged TaxCategoryPagedQueryResponse schema +export const taxCategoryPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z.number().optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readTaxCategoryOutputSchema = + taxCategorySchema || taxCategoryPagedSchema; +export const createTaxCategoryOutputSchema = taxCategorySchema; +export const updateTaxCategoryOutputSchema = taxCategorySchema; diff --git a/typescript/src/shared/tax-category/tools.ts b/typescript/src/shared/tax-category/tools.ts index a3a6e60..519ba87 100644 --- a/typescript/src/shared/tax-category/tools.ts +++ b/typescript/src/shared/tax-category/tools.ts @@ -3,6 +3,11 @@ import { readTaxCategoryParameters, updateTaxCategoryParameters, } from './parameters'; +import { + readTaxCategoryOutputSchema, + createTaxCategoryOutputSchema, + updateTaxCategoryOutputSchema, +} from './output-schema'; import { readTaxCategoryPrompt, createTaxCategoryPrompt, @@ -22,6 +27,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readTaxCategoryOutputSchema, }, create_tax_category: { name: 'Create Tax Category', @@ -33,6 +39,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createTaxCategoryOutputSchema, }, update_tax_category: { name: 'Update Tax Category', @@ -44,6 +51,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateTaxCategoryOutputSchema, }, }; diff --git a/typescript/src/shared/transactions/output-schema.ts b/typescript/src/shared/transactions/output-schema.ts new file mode 100644 index 0000000..bac7a84 --- /dev/null +++ b/typescript/src/shared/transactions/output-schema.ts @@ -0,0 +1,20 @@ +import {z} from 'zod'; + +// Generated schemas for transactions +// DO NOT EDIT - This file is auto-generated + +// Base Transaction schema +export const transactionsSchema = z + .object({ + id: z.string(), + timestamp: z.string().optional(), + type: z.any(), + amount: z.any(), + interactionId: z.string().optional(), + state: z.any(), + custom: z.any().optional(), + }) + .strict(); + +export const readTransactionOutputSchema = transactionsSchema; +export const createTransactionOutputSchema = transactionsSchema; diff --git a/typescript/src/shared/transactions/tools.ts b/typescript/src/shared/transactions/tools.ts index bf78140..c0fd8f8 100644 --- a/typescript/src/shared/transactions/tools.ts +++ b/typescript/src/shared/transactions/tools.ts @@ -2,6 +2,10 @@ import { createTransactionParameters, readTransactionParameters, } from './parameters'; +import { + readTransactionOutputSchema, + createTransactionOutputSchema, +} from './output-schema'; import {readTransactionPrompt, createTransactionPrompt} from './prompts'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -17,6 +21,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readTransactionOutputSchema, }, create_transaction: { name: 'Create Transaction', @@ -28,6 +33,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createTransactionOutputSchema, }, }; diff --git a/typescript/src/shared/zones/output-schema.ts b/typescript/src/shared/zones/output-schema.ts new file mode 100644 index 0000000..1256dc1 --- /dev/null +++ b/typescript/src/shared/zones/output-schema.ts @@ -0,0 +1,47 @@ +import {z} from 'zod'; + +// Generated schemas for zones +// DO NOT EDIT - This file is auto-generated + +// Base Zone schema +export const zonesSchema = z + .object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z + .any() + + .optional(), + createdBy: z + .any() + + .optional(), + key: z + .string() + + .optional(), + name: z.string(), + description: z.string().optional(), + locations: z.array(z.any()), + }) + .strict(); + +// Paged ZonePagedQueryResponse schema +export const zonesPagedSchema = z + .object({ + limit: z.number(), + offset: z.number(), + count: z.number(), + total: z + .number() + + .optional(), + results: z.array(z.any()), + }) + .strict(); + +export const readZoneOutputSchema = zonesSchema || zonesPagedSchema; +export const createZoneOutputSchema = zonesSchema; +export const updateZoneOutputSchema = zonesSchema; diff --git a/typescript/src/shared/zones/tools.ts b/typescript/src/shared/zones/tools.ts index ed16027..d691a80 100644 --- a/typescript/src/shared/zones/tools.ts +++ b/typescript/src/shared/zones/tools.ts @@ -3,6 +3,11 @@ import { readZoneParameters, updateZoneParameters, } from './parameters'; +import { + readZoneOutputSchema, + createZoneOutputSchema, + updateZoneOutputSchema, +} from './output-schema'; import {readZonePrompt, createZonePrompt, updateZonePrompt} from './prompts'; import {Tool} from '../../types/tools'; import {Context} from '../../types/configuration'; @@ -18,6 +23,7 @@ const tools: Record = { read: true, }, }, + outputSchema: readZoneOutputSchema, }, create_zone: { name: 'Create Zone', @@ -29,6 +35,7 @@ const tools: Record = { create: true, }, }, + outputSchema: createZoneOutputSchema, }, update_zone: { name: 'Update Zone', @@ -40,6 +47,7 @@ const tools: Record = { update: true, }, }, + outputSchema: updateZoneOutputSchema, }, }; diff --git a/typescript/src/types/tools.ts b/typescript/src/types/tools.ts index 338c836..0beafeb 100644 --- a/typescript/src/types/tools.ts +++ b/typescript/src/types/tools.ts @@ -43,6 +43,7 @@ export type Tool = { name: string; description: string; parameters: z.ZodObject; + outputSchema?: z.ZodObject; execute?: (args: T, api?: ApiRoot) => Promise; actions: { [key: string]: { From cc19550fc531ee3ad3c37ad82fcc8f50413c32bf Mon Sep 17 00:00:00 2001 From: Behnam Tehrani Date: Tue, 25 Nov 2025 09:31:01 -0500 Subject: [PATCH 2/3] Refactor: Rename and implement output schema transformation for tools --- .../src/modelcontextprotocol/essentials.ts | 11 ++------ .../transform/transformToolOutput.ts | 27 +++++++++++++++++-- .../src/shared/business-unit/output-schema.ts | 3 --- .../src/shared/cart-discount/output-schema.ts | 3 --- typescript/src/shared/cart/output-schema.ts | 3 --- .../src/shared/category/output-schema.ts | 3 --- .../src/shared/channel/output-schema.ts | 3 --- .../shared/custom-objects/output-schema.ts | 3 --- .../shared/customer-group/output-schema.ts | 3 --- .../src/shared/customer/output-schema.ts | 3 --- .../src/shared/discount-code/output-schema.ts | 3 --- .../src/shared/extensions/output-schema.ts | 3 --- .../src/shared/inventory/output-schema.ts | 3 --- typescript/src/shared/order/output-schema.ts | 3 --- .../shared/payment-methods/output-schema.ts | 3 --- .../src/shared/payments/output-schema.ts | 3 --- .../shared/product-discount/output-schema.ts | 3 --- .../shared/product-search/output-schema.ts | 3 --- .../shared/product-selection/output-schema.ts | 3 --- .../shared/product-tailoring/output-schema.ts | 3 --- .../src/shared/product-type/output-schema.ts | 3 --- .../src/shared/products/output-schema.ts | 3 --- .../src/shared/project/output-schema.ts | 3 --- .../src/shared/quote-request/output-schema.ts | 3 --- typescript/src/shared/quote/output-schema.ts | 3 --- .../shared/recurring-orders/output-schema.ts | 3 --- .../src/shared/reviews/output-schema.ts | 3 --- .../shared/shipping-methods/output-schema.ts | 3 --- .../shared/shopping-lists/output-schema.ts | 3 --- .../src/shared/staged-quote/output-schema.ts | 3 --- .../shared/standalone-price/output-schema.ts | 3 --- typescript/src/shared/store/output-schema.ts | 3 --- .../src/shared/subscriptions/output-schema.ts | 3 --- .../src/shared/tax-category/output-schema.ts | 3 --- .../src/shared/transactions/output-schema.ts | 3 --- typescript/src/shared/zones/output-schema.ts | 3 --- 36 files changed, 27 insertions(+), 113 deletions(-) diff --git a/typescript/src/modelcontextprotocol/essentials.ts b/typescript/src/modelcontextprotocol/essentials.ts index de91a2f..e757e3e 100644 --- a/typescript/src/modelcontextprotocol/essentials.ts +++ b/typescript/src/modelcontextprotocol/essentials.ts @@ -14,7 +14,7 @@ import {Tool} from '../types/tools'; import {contextToBulkTools} from '../shared/bulk/tools'; import {DYNAMIC_TOOL_LOADING_THRESHOLD} from '../shared/constants'; import {transformToolOutput} from './transform'; -import {transformTitle} from './transform/transformToolOutput'; +import {transfromOutputSchema} from './transform/transformToolOutput'; class CommercetoolsAgentEssentials extends McpServer { private authConfig: AuthConfig; @@ -174,14 +174,7 @@ class CommercetoolsAgentEssentials extends McpServer { description: tool.description, inputSchema: tool.parameters.shape, ...(this.configuration.context?.toolOutputFormat === 'json' && - tool.outputSchema && { - outputSchema: z.object({ - [transformTitle(tool.name)]: z.preprocess( - (val) => JSON.parse(val as string), - tool.outputSchema - ), - }).shape, - }), + transfromOutputSchema(tool)), }, async (args: Record) => { const result = await this.commercetoolsAPI.run(method, args, execute); diff --git a/typescript/src/modelcontextprotocol/transform/transformToolOutput.ts b/typescript/src/modelcontextprotocol/transform/transformToolOutput.ts index 3700604..78e0b47 100644 --- a/typescript/src/modelcontextprotocol/transform/transformToolOutput.ts +++ b/typescript/src/modelcontextprotocol/transform/transformToolOutput.ts @@ -1,5 +1,6 @@ +import {Tool} from '../../types/tools'; import {transformPropertyName} from './transformPropertyName'; - +import {z} from 'zod'; const emptyObjectTransformValue = 'no properties'; const emptyArrayTransformValue = 'none'; @@ -13,6 +14,28 @@ const generateTabs = (tabCount: number) => { type Format = 'tabular' | 'json'; +/** + * Transforms the output schema of a tool to a JSON schema. + * + * @param {Tool} tool - The tool to transform the output schema of. + * + * @returns {Object} The transformed output schema. + */ +export const transfromOutputSchema = (tool: Tool) => { + if (!tool.outputSchema) { + return {}; + } + + return { + outputSchema: z.object({ + [transformTitle(tool.name)]: z.preprocess( + (val) => JSON.parse(val as string), + tool.outputSchema + ), + }).shape, + }; +}; + /** * A method to strigify tool output into a LLM friendly and optimised format. * @@ -58,7 +81,7 @@ export const transformToolOutput = (args: { transformedData ?? emptyObjectTransformValue); }; -export const transformTitle = (title: string) => +const transformTitle = (title: string) => `${transformPropertyName(title).toUpperCase()}`; /** diff --git a/typescript/src/shared/business-unit/output-schema.ts b/typescript/src/shared/business-unit/output-schema.ts index 2d385f0..8a5a6a3 100644 --- a/typescript/src/shared/business-unit/output-schema.ts +++ b/typescript/src/shared/business-unit/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for business-unit -// DO NOT EDIT - This file is auto-generated - // Base BusinessUnit schema export const businessUnitSchema = z.union([z.any(), z.any()]); diff --git a/typescript/src/shared/cart-discount/output-schema.ts b/typescript/src/shared/cart-discount/output-schema.ts index 63db2b3..ffe3d28 100644 --- a/typescript/src/shared/cart-discount/output-schema.ts +++ b/typescript/src/shared/cart-discount/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for cart-discount -// DO NOT EDIT - This file is auto-generated - // Base CartDiscount schema export const cartDiscountSchema = z .object({ diff --git a/typescript/src/shared/cart/output-schema.ts b/typescript/src/shared/cart/output-schema.ts index 2474a1c..f7c7c23 100644 --- a/typescript/src/shared/cart/output-schema.ts +++ b/typescript/src/shared/cart/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for cart -// DO NOT EDIT - This file is auto-generated - // Base Cart schema export const cartSchema = z .object({ diff --git a/typescript/src/shared/category/output-schema.ts b/typescript/src/shared/category/output-schema.ts index 8b815aa..666c988 100644 --- a/typescript/src/shared/category/output-schema.ts +++ b/typescript/src/shared/category/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for category -// DO NOT EDIT - This file is auto-generated - // Base Category schema export const categorySchema = z .object({ diff --git a/typescript/src/shared/channel/output-schema.ts b/typescript/src/shared/channel/output-schema.ts index 7ab47df..8f981d3 100644 --- a/typescript/src/shared/channel/output-schema.ts +++ b/typescript/src/shared/channel/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for channel -// DO NOT EDIT - This file is auto-generated - // Base Channel schema export const channelSchema = z .object({ diff --git a/typescript/src/shared/custom-objects/output-schema.ts b/typescript/src/shared/custom-objects/output-schema.ts index 6c9bc09..78a9691 100644 --- a/typescript/src/shared/custom-objects/output-schema.ts +++ b/typescript/src/shared/custom-objects/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for custom-objects -// DO NOT EDIT - This file is auto-generated - // Base CustomObject schema export const customObjectsSchema = z .object({ diff --git a/typescript/src/shared/customer-group/output-schema.ts b/typescript/src/shared/customer-group/output-schema.ts index cccb332..5026205 100644 --- a/typescript/src/shared/customer-group/output-schema.ts +++ b/typescript/src/shared/customer-group/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for customer-group -// DO NOT EDIT - This file is auto-generated - // Base CustomerGroup schema export const customerGroupSchema = z .object({ diff --git a/typescript/src/shared/customer/output-schema.ts b/typescript/src/shared/customer/output-schema.ts index 1b17b3c..c22b96d 100644 --- a/typescript/src/shared/customer/output-schema.ts +++ b/typescript/src/shared/customer/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for customer -// DO NOT EDIT - This file is auto-generated - // Base Customer schema export const customerSchema = z .object({ diff --git a/typescript/src/shared/discount-code/output-schema.ts b/typescript/src/shared/discount-code/output-schema.ts index 347a204..b91cfc6 100644 --- a/typescript/src/shared/discount-code/output-schema.ts +++ b/typescript/src/shared/discount-code/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for discount-code -// DO NOT EDIT - This file is auto-generated - // Base DiscountCode schema export const discountCodeSchema = z .object({ diff --git a/typescript/src/shared/extensions/output-schema.ts b/typescript/src/shared/extensions/output-schema.ts index 38b68b0..d4da07e 100644 --- a/typescript/src/shared/extensions/output-schema.ts +++ b/typescript/src/shared/extensions/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for extensions -// DO NOT EDIT - This file is auto-generated - // Base Extension schema export const extensionsSchema = z .object({ diff --git a/typescript/src/shared/inventory/output-schema.ts b/typescript/src/shared/inventory/output-schema.ts index b5f1347..25fa4e1 100644 --- a/typescript/src/shared/inventory/output-schema.ts +++ b/typescript/src/shared/inventory/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for inventory -// DO NOT EDIT - This file is auto-generated - // Base InventoryEntry schema export const inventorySchema = z .object({ diff --git a/typescript/src/shared/order/output-schema.ts b/typescript/src/shared/order/output-schema.ts index 2fbbef5..ac7dac9 100644 --- a/typescript/src/shared/order/output-schema.ts +++ b/typescript/src/shared/order/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for order -// DO NOT EDIT - This file is auto-generated - // Base Order schema export const orderSchema = z .object({ diff --git a/typescript/src/shared/payment-methods/output-schema.ts b/typescript/src/shared/payment-methods/output-schema.ts index 68b808b..a360b59 100644 --- a/typescript/src/shared/payment-methods/output-schema.ts +++ b/typescript/src/shared/payment-methods/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for payment-methods -// DO NOT EDIT - This file is auto-generated - // Base PaymentMethod schema export const paymentMethodsSchema = z .object({ diff --git a/typescript/src/shared/payments/output-schema.ts b/typescript/src/shared/payments/output-schema.ts index bf09d87..c8a8e5b 100644 --- a/typescript/src/shared/payments/output-schema.ts +++ b/typescript/src/shared/payments/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for payments -// DO NOT EDIT - This file is auto-generated - // Base Payment schema export const paymentsSchema = z .object({ diff --git a/typescript/src/shared/product-discount/output-schema.ts b/typescript/src/shared/product-discount/output-schema.ts index f8352e5..4d5518a 100644 --- a/typescript/src/shared/product-discount/output-schema.ts +++ b/typescript/src/shared/product-discount/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for product-discount -// DO NOT EDIT - This file is auto-generated - // Base ProductDiscount schema export const productDiscountSchema = z .object({ diff --git a/typescript/src/shared/product-search/output-schema.ts b/typescript/src/shared/product-search/output-schema.ts index b93453e..58c0548 100644 --- a/typescript/src/shared/product-search/output-schema.ts +++ b/typescript/src/shared/product-search/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for product-search -// DO NOT EDIT - This file is auto-generated - // Base ProductProjection schema export const productSearchSchema = z .object({ diff --git a/typescript/src/shared/product-selection/output-schema.ts b/typescript/src/shared/product-selection/output-schema.ts index e791d79..41f1aad 100644 --- a/typescript/src/shared/product-selection/output-schema.ts +++ b/typescript/src/shared/product-selection/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for product-selection -// DO NOT EDIT - This file is auto-generated - // Base ProductSelection schema export const productSelectionSchema = z .object({ diff --git a/typescript/src/shared/product-tailoring/output-schema.ts b/typescript/src/shared/product-tailoring/output-schema.ts index 109f175..633b040 100644 --- a/typescript/src/shared/product-tailoring/output-schema.ts +++ b/typescript/src/shared/product-tailoring/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for product-tailoring -// DO NOT EDIT - This file is auto-generated - // Base ProductTailoring schema export const productTailoringSchema = z .object({ diff --git a/typescript/src/shared/product-type/output-schema.ts b/typescript/src/shared/product-type/output-schema.ts index 9e1b64e..408d439 100644 --- a/typescript/src/shared/product-type/output-schema.ts +++ b/typescript/src/shared/product-type/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for product-type -// DO NOT EDIT - This file is auto-generated - // Base ProductType schema export const productTypeSchema = z .object({ diff --git a/typescript/src/shared/products/output-schema.ts b/typescript/src/shared/products/output-schema.ts index 3c43b70..9598229 100644 --- a/typescript/src/shared/products/output-schema.ts +++ b/typescript/src/shared/products/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for products -// DO NOT EDIT - This file is auto-generated - // Base ProductProjection schema export const productsSchema = z .object({ diff --git a/typescript/src/shared/project/output-schema.ts b/typescript/src/shared/project/output-schema.ts index 449b073..d3383ed 100644 --- a/typescript/src/shared/project/output-schema.ts +++ b/typescript/src/shared/project/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for project -// DO NOT EDIT - This file is auto-generated - // Base Project schema export const projectSchema = z .object({ diff --git a/typescript/src/shared/quote-request/output-schema.ts b/typescript/src/shared/quote-request/output-schema.ts index 6121739..6540c0c 100644 --- a/typescript/src/shared/quote-request/output-schema.ts +++ b/typescript/src/shared/quote-request/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for quote-request -// DO NOT EDIT - This file is auto-generated - // Base QuoteRequest schema export const quoteRequestSchema = z .object({ diff --git a/typescript/src/shared/quote/output-schema.ts b/typescript/src/shared/quote/output-schema.ts index 23f2839..4598f36 100644 --- a/typescript/src/shared/quote/output-schema.ts +++ b/typescript/src/shared/quote/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for quote -// DO NOT EDIT - This file is auto-generated - // Base Quote schema export const quoteSchema = z .object({ diff --git a/typescript/src/shared/recurring-orders/output-schema.ts b/typescript/src/shared/recurring-orders/output-schema.ts index 52a812c..221217a 100644 --- a/typescript/src/shared/recurring-orders/output-schema.ts +++ b/typescript/src/shared/recurring-orders/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for recurring-orders -// DO NOT EDIT - This file is auto-generated - // Base RecurringOrder schema export const recurringOrdersSchema = z .object({ diff --git a/typescript/src/shared/reviews/output-schema.ts b/typescript/src/shared/reviews/output-schema.ts index 26b5599..1e43c3c 100644 --- a/typescript/src/shared/reviews/output-schema.ts +++ b/typescript/src/shared/reviews/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for reviews -// DO NOT EDIT - This file is auto-generated - // Base Review schema export const reviewsSchema = z .object({ diff --git a/typescript/src/shared/shipping-methods/output-schema.ts b/typescript/src/shared/shipping-methods/output-schema.ts index 7370087..5fbd3d3 100644 --- a/typescript/src/shared/shipping-methods/output-schema.ts +++ b/typescript/src/shared/shipping-methods/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for shipping-methods -// DO NOT EDIT - This file is auto-generated - // Base ShippingMethod schema export const shippingMethodsSchema = z .object({ diff --git a/typescript/src/shared/shopping-lists/output-schema.ts b/typescript/src/shared/shopping-lists/output-schema.ts index b1e2216..aba6fea 100644 --- a/typescript/src/shared/shopping-lists/output-schema.ts +++ b/typescript/src/shared/shopping-lists/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for shopping-lists -// DO NOT EDIT - This file is auto-generated - // Base ShoppingList schema export const shoppingListsSchema = z .object({ diff --git a/typescript/src/shared/staged-quote/output-schema.ts b/typescript/src/shared/staged-quote/output-schema.ts index bd3e9ab..e151968 100644 --- a/typescript/src/shared/staged-quote/output-schema.ts +++ b/typescript/src/shared/staged-quote/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for staged-quote -// DO NOT EDIT - This file is auto-generated - // Base StagedQuote schema export const stagedQuoteSchema = z .object({ diff --git a/typescript/src/shared/standalone-price/output-schema.ts b/typescript/src/shared/standalone-price/output-schema.ts index 0c83fa0..78c983a 100644 --- a/typescript/src/shared/standalone-price/output-schema.ts +++ b/typescript/src/shared/standalone-price/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for standalone-price -// DO NOT EDIT - This file is auto-generated - // Base StandalonePrice schema export const standalonePriceSchema = z .object({ diff --git a/typescript/src/shared/store/output-schema.ts b/typescript/src/shared/store/output-schema.ts index 523a972..d4b5388 100644 --- a/typescript/src/shared/store/output-schema.ts +++ b/typescript/src/shared/store/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for store -// DO NOT EDIT - This file is auto-generated - // Base Store schema export const storeSchema = z .object({ diff --git a/typescript/src/shared/subscriptions/output-schema.ts b/typescript/src/shared/subscriptions/output-schema.ts index 9cc83d7..405887c 100644 --- a/typescript/src/shared/subscriptions/output-schema.ts +++ b/typescript/src/shared/subscriptions/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for subscriptions -// DO NOT EDIT - This file is auto-generated - // Base Subscription schema export const subscriptionsSchema = z .object({ diff --git a/typescript/src/shared/tax-category/output-schema.ts b/typescript/src/shared/tax-category/output-schema.ts index c134c39..cc3d404 100644 --- a/typescript/src/shared/tax-category/output-schema.ts +++ b/typescript/src/shared/tax-category/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for tax-category -// DO NOT EDIT - This file is auto-generated - // Base TaxCategory schema export const taxCategorySchema = z .object({ diff --git a/typescript/src/shared/transactions/output-schema.ts b/typescript/src/shared/transactions/output-schema.ts index bac7a84..c609f74 100644 --- a/typescript/src/shared/transactions/output-schema.ts +++ b/typescript/src/shared/transactions/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for transactions -// DO NOT EDIT - This file is auto-generated - // Base Transaction schema export const transactionsSchema = z .object({ diff --git a/typescript/src/shared/zones/output-schema.ts b/typescript/src/shared/zones/output-schema.ts index 1256dc1..11f4829 100644 --- a/typescript/src/shared/zones/output-schema.ts +++ b/typescript/src/shared/zones/output-schema.ts @@ -1,8 +1,5 @@ import {z} from 'zod'; -// Generated schemas for zones -// DO NOT EDIT - This file is auto-generated - // Base Zone schema export const zonesSchema = z .object({ From 2f5a4e47648375454d4ae4f291a36363c16007df Mon Sep 17 00:00:00 2001 From: Behnam Tehrani Date: Mon, 1 Dec 2025 13:51:40 -0500 Subject: [PATCH 3/3] tests --- .../src/shared/business-unit/output-schema.ts | 12 +- .../business-unit/test/output-schema.test.ts | 81 + .../business-unit/test/output.data.json | 192 ++ typescript/src/shared/business-unit/tools.ts | 9 +- .../src/shared/cart-discount/output-schema.ts | 3 +- .../cart-discount/test/output-schema.test.ts | 81 + .../cart-discount/test/output.data.json | 148 ++ typescript/src/shared/cart/output-schema.ts | 3 +- .../shared/cart/test/output-schema.test.ts | 81 + .../src/shared/cart/test/output.data.json | 708 ++++++ .../src/shared/category/output-schema.ts | 2 +- .../category/test/output-schema.test.ts | 81 + .../src/shared/category/test/output.data.json | 142 ++ .../src/shared/channel/output-schema.ts | 2 +- .../shared/channel/test/output-schema.test.ts | 81 + .../src/shared/channel/test/output.data.json | 103 + .../shared/custom-objects/output-schema.ts | 3 +- .../custom-objects/test/output-schema.test.ts | 81 + .../custom-objects/test/output.data.json | 83 + .../shared/customer-group/output-schema.ts | 3 +- .../customer-group/test/output-schema.test.ts | 81 + .../customer-group/test/output.data.json | 77 + .../src/shared/customer/output-schema.ts | 2 +- .../customer/test/output-schema.test.ts | 81 + .../src/shared/customer/test/output.data.json | 102 + .../src/shared/discount-code/output-schema.ts | 3 +- .../discount-code/test/output-schema.test.ts | 81 + .../discount-code/test/output.data.json | 133 ++ .../src/shared/extensions/output-schema.ts | 3 +- .../extensions/test/output-schema.test.ts | 81 + .../shared/extensions/test/output.data.json | 7 + .../src/shared/inventory/output-schema.ts | 3 +- .../inventory/test/output-schema.test.ts | 81 + .../shared/inventory/test/output.data.json | 74 + typescript/src/shared/order/output-schema.ts | 3 +- .../shared/order/test/output-schema.test.ts | 81 + .../src/shared/order/test/output.data.json | 804 +++++++ .../shared/payment-methods/output-schema.ts | 3 +- .../test/output-schema.test.ts | 81 + .../payment-methods/test/output.data.json | 7 + .../src/shared/payments/output-schema.ts | 2 +- .../payments/test/output-schema.test.ts | 81 + .../src/shared/payments/test/output.data.json | 130 ++ .../shared/product-discount/output-schema.ts | 3 +- .../test/output-schema.test.ts | 81 + .../product-discount/test/output.data.json | 140 ++ .../shared/product-selection/output-schema.ts | 3 +- .../test/output-schema.test.ts | 81 + .../product-selection/test/output.data.json | 91 + .../shared/product-tailoring/output-schema.ts | 3 +- .../test/output-schema.test.ts | 81 + .../product-tailoring/test/output.data.json | 6 + .../src/shared/product-type/output-schema.ts | 3 +- .../product-type/test/output-schema.test.ts | 81 + .../shared/product-type/test/output.data.json | 797 +++++++ .../src/shared/products/output-schema.ts | 3 +- .../products/test/output-schema.test.ts | 81 + .../src/shared/products/test/output.data.json | 1388 ++++++++++++ .../shared/project/test/output-schema.test.ts | 45 + .../src/shared/project/test/output.data.json | 98 + .../src/shared/quote-request/output-schema.ts | 3 +- .../quote-request/test/output-schema.test.ts | 81 + .../quote-request/test/output.data.json | 1495 +++++++++++++ typescript/src/shared/quote/output-schema.ts | 2 +- .../shared/quote/test/output-schema.test.ts | 81 + .../src/shared/quote/test/output.data.json | 1966 +++++++++++++++++ .../shared/recurring-orders/output-schema.ts | 3 +- .../test/output-schema.test.ts | 81 + .../recurring-orders/test/output.data.json | 7 + .../src/shared/reviews/output-schema.ts | 2 +- .../shared/reviews/test/output-schema.test.ts | 81 + .../src/shared/reviews/test/output.data.json | 7 + .../shared/shipping-methods/output-schema.ts | 3 +- .../test/output-schema.test.ts | 81 + .../shipping-methods/test/output.data.json | 223 ++ .../shared/shopping-lists/output-schema.ts | 3 +- .../shopping-lists/test/output-schema.test.ts | 81 + .../shopping-lists/test/output.data.json | 72 + .../src/shared/staged-quote/output-schema.ts | 3 +- .../staged-quote/test/output-schema.test.ts | 81 + .../shared/staged-quote/test/output.data.json | 132 ++ .../shared/standalone-price/output-schema.ts | 3 +- .../test/output-schema.test.ts | 81 + .../standalone-price/test/output.data.json | 131 ++ typescript/src/shared/store/output-schema.ts | 2 +- .../shared/store/test/output-schema.test.ts | 81 + .../src/shared/store/test/output.data.json | 142 ++ .../src/shared/subscriptions/output-schema.ts | 5 +- .../subscriptions/test/output-schema.test.ts | 81 + .../subscriptions/test/output.data.json | 122 + .../src/shared/tax-category/output-schema.ts | 3 +- .../tax-category/test/output-schema.test.ts | 81 + .../shared/tax-category/test/output.data.json | 581 +++++ .../src/shared/zone/test/output.data.json | 62 + typescript/src/shared/zones/output-schema.ts | 2 +- typescript/src/types/tools.ts | 2 +- 96 files changed, 12691 insertions(+), 61 deletions(-) create mode 100644 typescript/src/shared/business-unit/test/output-schema.test.ts create mode 100644 typescript/src/shared/business-unit/test/output.data.json create mode 100644 typescript/src/shared/cart-discount/test/output-schema.test.ts create mode 100644 typescript/src/shared/cart-discount/test/output.data.json create mode 100644 typescript/src/shared/cart/test/output-schema.test.ts create mode 100644 typescript/src/shared/cart/test/output.data.json create mode 100644 typescript/src/shared/category/test/output-schema.test.ts create mode 100644 typescript/src/shared/category/test/output.data.json create mode 100644 typescript/src/shared/channel/test/output-schema.test.ts create mode 100644 typescript/src/shared/channel/test/output.data.json create mode 100644 typescript/src/shared/custom-objects/test/output-schema.test.ts create mode 100644 typescript/src/shared/custom-objects/test/output.data.json create mode 100644 typescript/src/shared/customer-group/test/output-schema.test.ts create mode 100644 typescript/src/shared/customer-group/test/output.data.json create mode 100644 typescript/src/shared/customer/test/output-schema.test.ts create mode 100644 typescript/src/shared/customer/test/output.data.json create mode 100644 typescript/src/shared/discount-code/test/output-schema.test.ts create mode 100644 typescript/src/shared/discount-code/test/output.data.json create mode 100644 typescript/src/shared/extensions/test/output-schema.test.ts create mode 100644 typescript/src/shared/extensions/test/output.data.json create mode 100644 typescript/src/shared/inventory/test/output-schema.test.ts create mode 100644 typescript/src/shared/inventory/test/output.data.json create mode 100644 typescript/src/shared/order/test/output-schema.test.ts create mode 100644 typescript/src/shared/order/test/output.data.json create mode 100644 typescript/src/shared/payment-methods/test/output-schema.test.ts create mode 100644 typescript/src/shared/payment-methods/test/output.data.json create mode 100644 typescript/src/shared/payments/test/output-schema.test.ts create mode 100644 typescript/src/shared/payments/test/output.data.json create mode 100644 typescript/src/shared/product-discount/test/output-schema.test.ts create mode 100644 typescript/src/shared/product-discount/test/output.data.json create mode 100644 typescript/src/shared/product-selection/test/output-schema.test.ts create mode 100644 typescript/src/shared/product-selection/test/output.data.json create mode 100644 typescript/src/shared/product-tailoring/test/output-schema.test.ts create mode 100644 typescript/src/shared/product-tailoring/test/output.data.json create mode 100644 typescript/src/shared/product-type/test/output-schema.test.ts create mode 100644 typescript/src/shared/product-type/test/output.data.json create mode 100644 typescript/src/shared/products/test/output-schema.test.ts create mode 100644 typescript/src/shared/products/test/output.data.json create mode 100644 typescript/src/shared/project/test/output-schema.test.ts create mode 100644 typescript/src/shared/project/test/output.data.json create mode 100644 typescript/src/shared/quote-request/test/output-schema.test.ts create mode 100644 typescript/src/shared/quote-request/test/output.data.json create mode 100644 typescript/src/shared/quote/test/output-schema.test.ts create mode 100644 typescript/src/shared/quote/test/output.data.json create mode 100644 typescript/src/shared/recurring-orders/test/output-schema.test.ts create mode 100644 typescript/src/shared/recurring-orders/test/output.data.json create mode 100644 typescript/src/shared/reviews/test/output-schema.test.ts create mode 100644 typescript/src/shared/reviews/test/output.data.json create mode 100644 typescript/src/shared/shipping-methods/test/output-schema.test.ts create mode 100644 typescript/src/shared/shipping-methods/test/output.data.json create mode 100644 typescript/src/shared/shopping-lists/test/output-schema.test.ts create mode 100644 typescript/src/shared/shopping-lists/test/output.data.json create mode 100644 typescript/src/shared/staged-quote/test/output-schema.test.ts create mode 100644 typescript/src/shared/staged-quote/test/output.data.json create mode 100644 typescript/src/shared/standalone-price/test/output-schema.test.ts create mode 100644 typescript/src/shared/standalone-price/test/output.data.json create mode 100644 typescript/src/shared/store/test/output-schema.test.ts create mode 100644 typescript/src/shared/store/test/output.data.json create mode 100644 typescript/src/shared/subscriptions/test/output-schema.test.ts create mode 100644 typescript/src/shared/subscriptions/test/output.data.json create mode 100644 typescript/src/shared/tax-category/test/output-schema.test.ts create mode 100644 typescript/src/shared/tax-category/test/output.data.json create mode 100644 typescript/src/shared/zone/test/output.data.json diff --git a/typescript/src/shared/business-unit/output-schema.ts b/typescript/src/shared/business-unit/output-schema.ts index 8a5a6a3..f6f800a 100644 --- a/typescript/src/shared/business-unit/output-schema.ts +++ b/typescript/src/shared/business-unit/output-schema.ts @@ -1,7 +1,14 @@ import {z} from 'zod'; // Base BusinessUnit schema -export const businessUnitSchema = z.union([z.any(), z.any()]); +export const businessUnitSchema = z.object({ + id: z.string(), + version: z.number(), + createdAt: z.string(), + lastModifiedAt: z.string(), + lastModifiedBy: z.any().optional(), + createdBy: z.any().optional(), +}); // Paged BusinessUnitPagedQueryResponse schema export const businessUnitPagedSchema = z @@ -14,8 +21,7 @@ export const businessUnitPagedSchema = z }) .strict(); -export const readBusinessUnitOutputSchema = - businessUnitSchema || businessUnitPagedSchema; +export const readBusinessUnitOutputSchema = z.union([businessUnitSchema, businessUnitPagedSchema]); export const createBusinessUnitOutputSchema = businessUnitSchema; export const updateBusinessUnitOutputSchema = businessUnitSchema; diff --git a/typescript/src/shared/business-unit/test/output-schema.test.ts b/typescript/src/shared/business-unit/test/output-schema.test.ts new file mode 100644 index 0000000..53d2c44 --- /dev/null +++ b/typescript/src/shared/business-unit/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + businessUnitSchema, + businessUnitPagedSchema, + readBusinessUnitOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('BusinessUnit Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = businessUnitPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = businessUnitSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = businessUnitSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readBusinessUnitOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(businessUnitSchema).toBeDefined(); + expect(readBusinessUnitOutputSchema).toBeDefined(); + expect(businessUnitPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/business-unit/test/output.data.json b/typescript/src/shared/business-unit/test/output.data.json new file mode 100644 index 0000000..c19a98d --- /dev/null +++ b/typescript/src/shared/business-unit/test/output.data.json @@ -0,0 +1,192 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 168, + "results": [ + { + "id": "5cd42966-bc7f-498a-99ee-8fa3101518b7", + "version": 3, + "versionModifiedAt": "2023-09-13T15:45:34.301Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2022-09-23T13:33:57.527Z", + "lastModifiedAt": "2023-02-13T13:48:58.125Z", + "lastModifiedBy": { + "clientId": "1eyVB5_tTzMDPwSxppod3eyZ", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "key": "business_unit_asdasd_asdas_2334", + "name": "asdasd asdas 2334", + "contactEmail": "asd234sa@sdfsdgsds.cvads", + "addresses": [], + "shippingAddressIds": [], + "billingAddressIds": [], + "status": "Active", + "storeMode": "Explicit", + "stores": [ + { + "typeId": "store", + "key": "store_asdasd_asdas_2334" + } + ], + "associateMode": "Explicit", + "approvalRuleMode": "Explicit", + "unitType": "Company", + "associates": [ + { + "customer": { + "typeId": "customer", + "id": "f8020317-6943-4fda-b310-253f06c039b8" + }, + "associateRoleAssignments": [ + { + "associateRole": { + "typeId": "associate-role", + "key": "admin" + }, + "inheritance": "Disabled" + } + ] + } + ], + "topLevelUnit": { + "typeId": "business-unit", + "key": "business_unit_asdasd_asdas_2334" + } + }, + { + "id": "6b29f9be-b56d-410c-bf13-ac2ce40e7bd8", + "version": 7, + "versionModifiedAt": "2023-09-13T15:45:34.310Z", + "lastMessageSequenceNumber": 6, + "createdAt": "2022-09-23T19:39:26.192Z", + "lastModifiedAt": "2023-02-13T13:48:58.774Z", + "lastModifiedBy": { + "clientId": "1eyVB5_tTzMDPwSxppod3eyZ", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "key": "business_unit_foo", + "name": "Foo", + "contactEmail": "tom@foo.com", + "addresses": [], + "shippingAddressIds": [], + "billingAddressIds": [], + "status": "Inactive", + "storeMode": "Explicit", + "stores": [ + { + "typeId": "store", + "key": "store_foo" + } + ], + "associateMode": "Explicit", + "approvalRuleMode": "Explicit", + "unitType": "Company", + "associates": [ + { + "customer": { + "typeId": "customer", + "id": "f8a6a3b1-501b-476d-9c2a-3bd473f13bff" + }, + "associateRoleAssignments": [ + { + "associateRole": { + "typeId": "associate-role", + "key": "admin" + }, + "inheritance": "Disabled" + } + ] + }, + { + "customer": { + "typeId": "customer", + "id": "e518f147-d5af-4193-b76e-63a876a3ba96" + }, + "associateRoleAssignments": [ + { + "associateRole": { + "typeId": "associate-role", + "key": "admin" + }, + "inheritance": "Disabled" + }, + { + "associateRole": { + "typeId": "associate-role", + "key": "buyer" + }, + "inheritance": "Disabled" + } + ] + } + ], + "topLevelUnit": { + "typeId": "business-unit", + "key": "business_unit_foo" + } + }, + { + "id": "08ff9dde-03cd-4e18-ace9-a26cb8767cdd", + "version": 3, + "versionModifiedAt": "2023-09-13T15:45:34.300Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2022-10-06T18:09:41.880Z", + "lastModifiedAt": "2023-02-13T13:48:58.912Z", + "lastModifiedBy": { + "clientId": "1eyVB5_tTzMDPwSxppod3eyZ", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "key": "business_unit_nike", + "name": "Nike", + "contactEmail": "sam@ple.com", + "addresses": [], + "shippingAddressIds": [], + "billingAddressIds": [], + "status": "Active", + "storeMode": "Explicit", + "stores": [ + { + "typeId": "store", + "key": "store_nike" + } + ], + "associateMode": "Explicit", + "approvalRuleMode": "Explicit", + "unitType": "Company", + "associates": [ + { + "customer": { + "typeId": "customer", + "id": "ea830134-350d-49a2-8556-c815fdd7eac6" + }, + "associateRoleAssignments": [ + { + "associateRole": { + "typeId": "associate-role", + "key": "admin" + }, + "inheritance": "Disabled" + } + ] + } + ], + "topLevelUnit": { + "typeId": "business-unit", + "key": "business_unit_nike" + } + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/business-unit/tools.ts b/typescript/src/shared/business-unit/tools.ts index 88795fa..4bfb59c 100644 --- a/typescript/src/shared/business-unit/tools.ts +++ b/typescript/src/shared/business-unit/tools.ts @@ -33,9 +33,8 @@ const tools: Record = { 'business-unit': { read: true, }, - - outputSchema: readBusinessUnitOutputSchema, }, + outputSchema: readBusinessUnitOutputSchema, }, create_business_unit: { method: 'create_business_unit', @@ -51,9 +50,8 @@ const tools: Record = { 'business-unit': { create: true, }, - - outputSchema: createBusinessUnitOutputSchema, }, + outputSchema: createBusinessUnitOutputSchema, }, update_business_unit: { method: 'update_business_unit', @@ -69,9 +67,8 @@ const tools: Record = { 'business-unit': { update: true, }, - - outputSchema: updateBusinessUnitOutputSchema, }, + outputSchema: updateBusinessUnitOutputSchema, }, }; diff --git a/typescript/src/shared/cart-discount/output-schema.ts b/typescript/src/shared/cart-discount/output-schema.ts index ffe3d28..911b839 100644 --- a/typescript/src/shared/cart-discount/output-schema.ts +++ b/typescript/src/shared/cart-discount/output-schema.ts @@ -39,7 +39,6 @@ export const cartDiscountPagedSchema = z }) .strict(); -export const readCartDiscountOutputSchema = - cartDiscountSchema || cartDiscountPagedSchema; +export const readCartDiscountOutputSchema = z.union([cartDiscountSchema, cartDiscountPagedSchema]); export const createCartDiscountOutputSchema = cartDiscountSchema; export const updateCartDiscountOutputSchema = cartDiscountSchema; diff --git a/typescript/src/shared/cart-discount/test/output-schema.test.ts b/typescript/src/shared/cart-discount/test/output-schema.test.ts new file mode 100644 index 0000000..69ab413 --- /dev/null +++ b/typescript/src/shared/cart-discount/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + cartDiscountSchema, + cartDiscountPagedSchema, + readCartDiscountOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('CartDiscount Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = cartDiscountPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = cartDiscountSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = cartDiscountSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readCartDiscountOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(cartDiscountSchema).toBeDefined(); + expect(readCartDiscountOutputSchema).toBeDefined(); + expect(cartDiscountPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/cart-discount/test/output.data.json b/typescript/src/shared/cart-discount/test/output.data.json new file mode 100644 index 0000000..1d51f30 --- /dev/null +++ b/typescript/src/shared/cart-discount/test/output.data.json @@ -0,0 +1,148 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 20, + "results": [ + { + "id": "42c2810a-51fb-4e1f-8a50-c81594ef50b2", + "version": 7, + "versionModifiedAt": "2023-09-13T15:45:18.175Z", + "createdAt": "2022-10-03T17:24:42.061Z", + "lastModifiedAt": "2022-10-24T17:16:15.652Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "value": { + "type": "relative", + "permyriad": 500 + }, + "cartPredicate": "1 = 1", + "target": { + "type": "lineItems", + "predicate": "1 = 1" + }, + "name": { + "en-US": "behnam-test" + }, + "description": { + "en-US": "" + }, + "stackingMode": "Stacking", + "isActive": true, + "requiresDiscountCode": true, + "sortOrder": "0.1", + "references": [], + "stores": [], + "key": "behnam-test" + }, + { + "id": "7742059e-e03e-4ef1-9148-d1d85246deff", + "version": 8, + "versionModifiedAt": "2023-09-13T15:45:18.176Z", + "createdAt": "2022-10-24T15:59:45.355Z", + "lastModifiedAt": "2022-10-31T13:28:19.503Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "value": { + "type": "relative", + "permyriad": 1000 + }, + "cartPredicate": "1 = 1", + "target": { + "type": "lineItems", + "predicate": "1 = 1" + }, + "name": { + "en-US": "quote test" + }, + "description": { + "en-US": "" + }, + "stackingMode": "Stacking", + "isActive": false, + "requiresDiscountCode": false, + "sortOrder": "0.2", + "references": [], + "stores": [], + "key": "quote-10" + }, + { + "id": "3b303c63-57ee-418d-b527-939bbd91b06c", + "version": 13, + "versionModifiedAt": "2023-09-13T15:45:18.175Z", + "createdAt": "2022-10-25T21:39:02.214Z", + "lastModifiedAt": "2023-07-21T08:33:34.126Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "2efd184e-b6cf-412a-b0ca-396771d7cb5e" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "2b06b734-5b66-47fa-b3b2-67318555b9a9" + } + }, + "value": { + "type": "relative", + "permyriad": 5000 + }, + "cartPredicate": "1 = 1", + "target": { + "type": "multiBuyLineItems", + "predicate": "categories.id = (\"bcd77063-7387-4ccc-8264-abce96226a32\")", + "triggerQuantity": 2, + "discountedQuantity": 1, + "maxOccurrence": 1, + "selectionMode": "Cheapest" + }, + "name": { + "en-US": "Buy 1, Get 1 50%", + "af": "" + }, + "description": { + "en-US": "To redeem the offer: Add two qualifying items to cart. The cost of your lowest priced item will be discounted. ", + "af": "" + }, + "stackingMode": "Stacking", + "isActive": true, + "requiresDiscountCode": true, + "sortOrder": "0.15", + "references": [ + { + "typeId": "category", + "id": "bcd77063-7387-4ccc-8264-abce96226a32" + } + ], + "stores": [], + "key": "buy-one-get-one-50" + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/cart/output-schema.ts b/typescript/src/shared/cart/output-schema.ts index f7c7c23..012ae6b 100644 --- a/typescript/src/shared/cart/output-schema.ts +++ b/typescript/src/shared/cart/output-schema.ts @@ -3,6 +3,7 @@ import {z} from 'zod'; // Base Cart schema export const cartSchema = z .object({ + type: z.literal('Cart'), id: z.string(), version: z.number(), createdAt: z.string(), @@ -137,7 +138,7 @@ export const cartPagedSchema = z }) .strict(); -export const readCartOutputSchema = cartSchema || cartPagedSchema; +export const readCartOutputSchema = z.union([cartSchema, cartPagedSchema]); export const createCartOutputSchema = cartSchema; export const replicateCartOutputSchema = cartSchema; export const updateCartOutputSchema = cartSchema; diff --git a/typescript/src/shared/cart/test/output-schema.test.ts b/typescript/src/shared/cart/test/output-schema.test.ts new file mode 100644 index 0000000..0ad2c4f --- /dev/null +++ b/typescript/src/shared/cart/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + cartSchema, + cartPagedSchema, + readCartOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Cart Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = cartPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = cartSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = cartSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readCartOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(cartSchema).toBeDefined(); + expect(readCartOutputSchema).toBeDefined(); + expect(cartPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/cart/test/output.data.json b/typescript/src/shared/cart/test/output.data.json new file mode 100644 index 0000000..8db7f19 --- /dev/null +++ b/typescript/src/shared/cart/test/output.data.json @@ -0,0 +1,708 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 409, + "results": [ + { + "type": "Cart", + "id": "e33365d5-6099-45f9-83cd-e802b17540c4", + "version": 32, + "versionModifiedAt": "2023-09-13T15:45:35.121Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2022-10-20T15:32:58.560Z", + "lastModifiedAt": "2023-03-27T19:45:03.442Z", + "lastModifiedBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "lineItems": [ + { + "id": "ff51e703-09f4-410f-8cd6-c911b6893e8c", + "productId": "4ca24a28-ac53-407c-bc5c-63065986fec5", + "productKey": "B00EHNC5TK", + "productType": { + "typeId": "product-type", + "id": "7c8a90ff-4d2d-457e-afcf-0d6330276d0c", + "version": 15 + }, + "productSlug": { + "en-US": "Tylenol-Arthritis-Caplets-Bottle-Acetaminophen" + }, + "name": { + "en-US": "Tylenol Arthritis Pain 250 Caplets Bottle, 650mg Acetaminophen" + }, + "variant": { + "id": 1, + "sku": "B00EHNC5TK-1", + "prices": [ + { + "id": "dafccbf3-b463-454d-ba46-76c7d56458bf", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2600, + "fractionDigits": 2 + } + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/61RVkomhteL._AC_SX42-YzmTqGg3.jpg", + "dimensions": { + "w": 425, + "h": 707 + } + } + ], + "attributes": [], + "assets": [], + "availability": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 100, + "version": 3, + "id": "9a9f7d90-704f-4724-8b78-8fd279e74ed7" + } + }, + "price": { + "id": "dafccbf3-b463-454d-ba46-76c7d56458bf", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2600, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPricePerQuantity": [], + "distributionChannel": { + "typeId": "channel", + "id": "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6" + }, + "taxRate": { + "name": "standard", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "tjGc7iOO", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2022-10-19T18:55:02.878Z", + "lastModifiedAt": "2022-10-19T18:55:02.878Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2600, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2600, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2860, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 260, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + } + ], + "cartState": "Active", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2600, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2600, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2860, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 260, + "fractionDigits": 2 + }, + "name": "standard" + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 260, + "fractionDigits": 2 + } + }, + "country": "US", + "shippingMode": "Single", + "shippingAddress": { + "id": "1st-shipping-address", + "firstName": "Main", + "lastName": "Branch", + "streetName": "1 A", + "postalCode": "12354", + "city": "Buuuu", + "country": "US" + }, + "shipping": [], + "customLineItems": [], + "discountCodes": [], + "directDiscounts": [], + "inventoryMode": "ReserveOnOrder", + "priceRoundingMode": "HalfEven", + "taxMode": "Platform", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "refusedGifts": [], + "origin": "Quote", + "billingAddress": { + "id": "1st-shipping-address", + "firstName": "Main", + "lastName": "Branch", + "streetName": "1 A", + "postalCode": "12354", + "city": "Buuuu", + "country": "US" + }, + "itemShippingAddresses": [], + "store": { + "typeId": "store", + "key": "store_adidas" + }, + "businessUnit": { + "typeId": "business-unit", + "key": "business_unit_adidas" + }, + "discountTypeCombination": { + "type": "Stacking" + }, + "totalLineItemQuantity": 1 + }, + { + "type": "Cart", + "id": "9f031a50-8411-472b-8237-80880565e5a5", + "version": 8, + "versionModifiedAt": "2023-09-13T15:45:35.121Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2022-10-20T15:45:17.414Z", + "lastModifiedAt": "2022-10-25T14:20:41.431Z", + "lastModifiedBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "customerEmail": "adi@das.com", + "lineItems": [ + { + "id": "71c99615-1403-41d9-8e4b-6a37ba0c01fd", + "productId": "4ca24a28-ac53-407c-bc5c-63065986fec5", + "productKey": "B00EHNC5TK", + "productType": { + "typeId": "product-type", + "id": "7c8a90ff-4d2d-457e-afcf-0d6330276d0c", + "version": 15 + }, + "productSlug": { + "en-US": "Tylenol-Arthritis-Caplets-Bottle-Acetaminophen" + }, + "name": { + "en-US": "Tylenol Arthritis Pain 250 Caplets Bottle, 650mg Acetaminophen" + }, + "variant": { + "id": 1, + "sku": "B00EHNC5TK-1", + "prices": [ + { + "id": "dafccbf3-b463-454d-ba46-76c7d56458bf", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2600, + "fractionDigits": 2 + } + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/61RVkomhteL._AC_SX42-YzmTqGg3.jpg", + "dimensions": { + "w": 425, + "h": 707 + } + } + ], + "attributes": [], + "assets": [], + "availability": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 100, + "version": 3, + "id": "9a9f7d90-704f-4724-8b78-8fd279e74ed7" + } + }, + "price": { + "id": "dafccbf3-b463-454d-ba46-76c7d56458bf", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2600, + "fractionDigits": 2 + } + }, + "quantity": 2, + "discountedPricePerQuantity": [], + "distributionChannel": { + "typeId": "channel", + "id": "d5bbd9cd-db6a-4dd6-9bdb-e79c5109dcc4" + }, + "taxRate": { + "name": "standard", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "z821AAA9", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2022-10-18T19:55:41.998Z", + "lastModifiedAt": "2022-10-18T19:55:41.998Z", + "state": [ + { + "quantity": 2, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5200, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5200, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5720, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 520, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + } + ], + "cartState": "Ordered", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5200, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5200, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5720, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 520, + "fractionDigits": 2 + }, + "name": "standard" + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 520, + "fractionDigits": 2 + } + }, + "country": "US", + "shippingMode": "Single", + "shippingAddress": { + "id": "1st-shipping-address", + "firstName": "Main", + "lastName": "Branch", + "streetName": "1 A", + "postalCode": "12354", + "city": "Buuuu", + "country": "US" + }, + "shipping": [], + "customLineItems": [], + "discountCodes": [], + "directDiscounts": [], + "inventoryMode": "ReserveOnOrder", + "priceRoundingMode": "HalfEven", + "taxMode": "Platform", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "refusedGifts": [], + "origin": "Quote", + "billingAddress": { + "id": "1st-shipping-address", + "firstName": "Main", + "lastName": "Branch", + "streetName": "1 A", + "postalCode": "12354", + "city": "Buuuu", + "country": "US" + }, + "itemShippingAddresses": [], + "store": { + "typeId": "store", + "key": "store_west_coast" + }, + "businessUnit": { + "typeId": "business-unit", + "key": "business_unit_adidas" + }, + "discountTypeCombination": { + "type": "Stacking" + }, + "totalLineItemQuantity": 2 + }, + { + "type": "Cart", + "id": "fb0a9a42-00dd-4911-851b-7952ee34ab04", + "version": 6, + "versionModifiedAt": "2023-09-13T15:45:35.121Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2022-10-24T15:43:20.319Z", + "lastModifiedAt": "2022-10-24T20:29:23.145Z", + "lastModifiedBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "lineItems": [ + { + "id": "7782ec49-7a06-4f77-af49-3035297b2c86", + "productId": "77fa562a-1015-437b-9731-ad6b03f7cbb5", + "productKey": "B09DNXFCLM", + "productType": { + "typeId": "product-type", + "id": "7c8a90ff-4d2d-457e-afcf-0d6330276d0c", + "version": 15 + }, + "productSlug": { + "en-US": "Electric-Shoulder-Arthritis-Settings-Auto-Off" + }, + "name": { + "en-US": "Electric Heating pad for Back/Shoulder/Neck/Knee/Leg Pain, Cramps and Arthritis Relief, 6 Fast Heating Settings, Auto-Off, Machine Washable, Moist Dry Heat Options, Extra Large 12\"x24\"" + }, + "variant": { + "id": 1, + "sku": "B09DNXFCLM-1", + "prices": [ + { + "id": "ddc9123f-0ddf-4e2f-92c6-11f93160f1d9", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2999, + "fractionDigits": 2 + } + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/81rAOf-+RWL._AC_SX52-bHZM3LFR.jpg", + "dimensions": { + "w": 522, + "h": 687 + } + } + ], + "attributes": [], + "assets": [], + "availability": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 101, + "version": 1, + "id": "56375390-d46d-492f-beec-718e630d8921" + } + }, + "price": { + "id": "ddc9123f-0ddf-4e2f-92c6-11f93160f1d9", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2999, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2699, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "cart-discount", + "id": "7742059e-e03e-4ef1-9148-d1d85246deff" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 300, + "fractionDigits": 2 + } + } + ] + }, + "discountedPricePerQuantity": [ + { + "quantity": 1, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2699, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "cart-discount", + "id": "7742059e-e03e-4ef1-9148-d1d85246deff" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 300, + "fractionDigits": 2 + } + } + ] + } + } + ], + "distributionChannel": { + "typeId": "channel", + "id": "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6" + }, + "taxRate": { + "name": "standard", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "z821AAA9", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2022-10-19T19:39:57.009Z", + "lastModifiedAt": "2022-10-19T19:39:57.009Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2699, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2699, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2969, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 270, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + } + ], + "cartState": "Active", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2699, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2699, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2969, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 270, + "fractionDigits": 2 + }, + "name": "standard" + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 270, + "fractionDigits": 2 + } + }, + "country": "US", + "shippingMode": "Single", + "shippingAddress": { + "id": "1st-shipping-address", + "firstName": "KIRBY", + "lastName": "FIKE", + "streetName": "348 FOOTHILL DR 348 FOOTHILL DR", + "postalCode": "93015", + "city": "US", + "country": "US" + }, + "shipping": [], + "customLineItems": [], + "discountCodes": [], + "directDiscounts": [], + "inventoryMode": "ReserveOnOrder", + "priceRoundingMode": "HalfEven", + "taxMode": "Platform", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "refusedGifts": [], + "origin": "Quote", + "billingAddress": { + "id": "1st-shipping-address", + "firstName": "KIRBY", + "lastName": "FIKE", + "streetName": "348 FOOTHILL DR 348 FOOTHILL DR", + "postalCode": "93015", + "city": "US", + "country": "US" + }, + "itemShippingAddresses": [], + "store": { + "typeId": "store", + "key": "store_east_coast" + }, + "businessUnit": { + "typeId": "business-unit", + "key": "business_unit_business_unit_adidas_div_east_coast" + }, + "discountTypeCombination": { + "type": "Stacking" + }, + "totalLineItemQuantity": 1 + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/category/output-schema.ts b/typescript/src/shared/category/output-schema.ts index 666c988..6ceeb90 100644 --- a/typescript/src/shared/category/output-schema.ts +++ b/typescript/src/shared/category/output-schema.ts @@ -36,6 +36,6 @@ export const categoryPagedSchema = z }) .strict(); -export const readCategoryOutputSchema = categorySchema || categoryPagedSchema; +export const readCategoryOutputSchema = z.union([categorySchema, categoryPagedSchema]); export const createCategoryOutputSchema = categorySchema; export const updateCategoryOutputSchema = categorySchema; diff --git a/typescript/src/shared/category/test/output-schema.test.ts b/typescript/src/shared/category/test/output-schema.test.ts new file mode 100644 index 0000000..179a865 --- /dev/null +++ b/typescript/src/shared/category/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + categorySchema, + categoryPagedSchema, + readCategoryOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Category Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = categoryPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = categorySchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = categorySchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readCategoryOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(categorySchema).toBeDefined(); + expect(readCategoryOutputSchema).toBeDefined(); + expect(categoryPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/category/test/output.data.json b/typescript/src/shared/category/test/output.data.json new file mode 100644 index 0000000..b270946 --- /dev/null +++ b/typescript/src/shared/category/test/output.data.json @@ -0,0 +1,142 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 132, + "results": [ + { + "id": "bcd77063-7387-4ccc-8264-abce96226a32", + "version": 8, + "versionModifiedAt": "2023-09-13T15:45:34.176Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2022-10-13T18:13:30.953Z", + "lastModifiedAt": "2023-07-26T19:55:34.582Z", + "lastModifiedBy": { + "clientId": "1eyVB5_tTzMDPwSxppod3eyZ", + "isPlatformClient": false + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "key": "pain-relievers", + "name": { + "en-US": "Pain Relievers", + "es-MX": "Analgésicos" + }, + "slug": { + "en-US": "pain-relievers", + "es-MX": "pain-relievers" + }, + "ancestors": [ + { + "typeId": "category", + "id": "a6160a1b-0a82-41dd-8817-eabfba4582fc" + }, + { + "typeId": "category", + "id": "1e50afe7-4d56-4576-b76d-f6239201b570" + }, + { + "typeId": "category", + "id": "28910afa-19e6-416e-98a8-c072873ca7ce" + } + ], + "parent": { + "typeId": "category", + "id": "28910afa-19e6-416e-98a8-c072873ca7ce" + }, + "orderHint": "0.05", + "assets": [] + }, + { + "id": "aadc6743-9a20-4a55-be18-f5413e8cab23", + "version": 7, + "versionModifiedAt": "2023-09-13T15:45:34.167Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2022-11-09T14:14:26.027Z", + "lastModifiedAt": "2023-07-26T19:55:34.404Z", + "lastModifiedBy": { + "clientId": "1eyVB5_tTzMDPwSxppod3eyZ", + "isPlatformClient": false + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "4051df61-3ed3-4518-85f2-2d6a0725a007" + } + }, + "key": "ace", + "name": { + "en-US": "Ace", + "es-MX": "As" + }, + "slug": { + "en-US": "ace", + "es-MX": "ace" + }, + "ancestors": [ + { + "typeId": "category", + "id": "a6160a1b-0a82-41dd-8817-eabfba4582fc" + } + ], + "parent": { + "typeId": "category", + "id": "a6160a1b-0a82-41dd-8817-eabfba4582fc" + }, + "orderHint": ".45", + "assets": [] + }, + { + "id": "1e50afe7-4d56-4576-b76d-f6239201b570", + "version": 8, + "versionModifiedAt": "2023-09-13T15:45:34.167Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2022-12-05T00:30:09.617Z", + "lastModifiedAt": "2023-07-26T19:55:34.467Z", + "lastModifiedBy": { + "clientId": "1eyVB5_tTzMDPwSxppod3eyZ", + "isPlatformClient": false + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "2b06b734-5b66-47fa-b3b2-67318555b9a9" + } + }, + "key": "all-products", + "name": { + "en-US": "All Products", + "es-MX": "Todos los productos" + }, + "slug": { + "en-US": "all-products", + "es-MX": "all-products" + }, + "description": { + "en-US": "all products" + }, + "ancestors": [ + { + "typeId": "category", + "id": "a6160a1b-0a82-41dd-8817-eabfba4582fc" + } + ], + "parent": { + "typeId": "category", + "id": "a6160a1b-0a82-41dd-8817-eabfba4582fc" + }, + "orderHint": "1", + "metaTitle": { + "en-US": "all products" + }, + "assets": [] + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/channel/output-schema.ts b/typescript/src/shared/channel/output-schema.ts index 8f981d3..af16d3d 100644 --- a/typescript/src/shared/channel/output-schema.ts +++ b/typescript/src/shared/channel/output-schema.ts @@ -31,6 +31,6 @@ export const channelPagedSchema = z }) .strict(); -export const readChannelOutputSchema = channelSchema || channelPagedSchema; +export const readChannelOutputSchema = z.union([channelSchema, channelPagedSchema]); export const createChannelOutputSchema = channelSchema; export const updateChannelOutputSchema = channelSchema; diff --git a/typescript/src/shared/channel/test/output-schema.test.ts b/typescript/src/shared/channel/test/output-schema.test.ts new file mode 100644 index 0000000..d3de2eb --- /dev/null +++ b/typescript/src/shared/channel/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + channelSchema, + channelPagedSchema, + readChannelOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Channel Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = channelPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = channelSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = channelSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readChannelOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(channelSchema).toBeDefined(); + expect(readChannelOutputSchema).toBeDefined(); + expect(channelPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/channel/test/output.data.json b/typescript/src/shared/channel/test/output.data.json new file mode 100644 index 0000000..1420c37 --- /dev/null +++ b/typescript/src/shared/channel/test/output.data.json @@ -0,0 +1,103 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 22, + "results": [ + { + "id": "94f0286e-c720-400e-aff8-5e41422309d9", + "version": 11, + "versionModifiedAt": "2025-11-10T19:59:11.002Z", + "createdAt": "2022-09-19T19:53:59.266Z", + "lastModifiedAt": "2025-11-10T19:59:11.002Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "key": "default-channel", + "roles": [ + "InventorySupply", + "ProductDistribution" + ], + "name": { + "en-US": "The default channel for new store creation", + "es-MX": "Por Defecto" + }, + "geoLocation": { + "coordinates": [ + 100, + 10 + ], + "type": "Point" + } + }, + { + "id": "d5bbd9cd-db6a-4dd6-9bdb-e79c5109dcc4", + "version": 4, + "versionModifiedAt": "2023-09-13T15:45:31.651Z", + "createdAt": "2022-09-23T16:08:02.947Z", + "lastModifiedAt": "2022-10-13T15:44:24.636Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "key": "test-tier-2-channel", + "roles": [ + "InventorySupply", + "ProductDistribution" + ], + "name": { + "en-US": "Channel for higher price :}" + } + }, + { + "id": "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:31.651Z", + "createdAt": "2022-10-13T15:45:06.236Z", + "lastModifiedAt": "2022-10-13T15:45:06.236Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "key": "test-tier-3-channel", + "roles": [ + "InventorySupply", + "ProductDistribution" + ], + "name": { + "en-US": "Channel which misses some products" + } + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/custom-objects/output-schema.ts b/typescript/src/shared/custom-objects/output-schema.ts index 78a9691..a6e7b40 100644 --- a/typescript/src/shared/custom-objects/output-schema.ts +++ b/typescript/src/shared/custom-objects/output-schema.ts @@ -26,7 +26,6 @@ export const customObjectsPagedSchema = z }) .strict(); -export const readCustomObjectOutputSchema = - customObjectsSchema || customObjectsPagedSchema; +export const readCustomObjectOutputSchema = z.union([customObjectsSchema, customObjectsPagedSchema]); export const createCustomObjectOutputSchema = customObjectsSchema; export const updateCustomObjectOutputSchema = customObjectsSchema; diff --git a/typescript/src/shared/custom-objects/test/output-schema.test.ts b/typescript/src/shared/custom-objects/test/output-schema.test.ts new file mode 100644 index 0000000..d357e22 --- /dev/null +++ b/typescript/src/shared/custom-objects/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + customObjectsSchema, + customObjectsPagedSchema, + readCustomObjectOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('CustomObjects Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = customObjectsPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = customObjectsSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = customObjectsSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readCustomObjectOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(customObjectsSchema).toBeDefined(); + expect(readCustomObjectOutputSchema).toBeDefined(); + expect(customObjectsPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/custom-objects/test/output.data.json b/typescript/src/shared/custom-objects/test/output.data.json new file mode 100644 index 0000000..5154d89 --- /dev/null +++ b/typescript/src/shared/custom-objects/test/output.data.json @@ -0,0 +1,83 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 459, + "results": [ + { + "id": "a07e21fa-9d27-4976-8994-62807483fb97", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:34.472Z", + "createdAt": "2022-09-15T17:29:18.304Z", + "lastModifiedAt": "2022-09-15T17:29:18.304Z", + "lastModifiedBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "container": "commercetools-project-sync.runnerName.CategorySync.timestampGenerator", + "key": "timestampGenerator", + "value": "ab841bd4-5187-4c4b-ab91-7f5abd2ef14e" + }, + { + "id": "1951a79a-76b8-429f-a99b-0c6e42681d31", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:34.481Z", + "createdAt": "2022-09-15T17:29:18.304Z", + "lastModifiedAt": "2022-09-15T17:29:18.304Z", + "lastModifiedBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "container": "commercetools-project-sync.runnerName.ProductTypeSync.timestampGenerator", + "key": "timestampGenerator", + "value": "8b6b3e8c-ee42-4f7c-87af-b47e7c298dfb" + }, + { + "id": "21ed4494-2b15-4109-a233-0fe5d4ec5302", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:34.482Z", + "createdAt": "2022-09-15T17:29:20.398Z", + "lastModifiedAt": "2022-09-15T17:29:20.398Z", + "lastModifiedBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "container": "commercetools-sync-java.UnresolvedReferencesService.categoryDrafts", + "key": "47621dd0c4e96583979e8f05a7a5a579fefb44b6", + "value": { + "categoryDraft": { + "assets": [], + "externalId": "Beauty_Makeup_Nails", + "key": "Beauty_Makeup_Nails", + "name": { + "en": "Nails" + }, + "orderHint": "1.63E-05", + "parent": { + "key": "Beauty_Makeup" + }, + "slug": { + "en": "Beauty_Makeup_Nails", + "zh": "Beauty_Makeup_Nails" + } + }, + "missingReferencedCategoriesKeys": [ + "Beauty_Makeup" + ], + "key": "Beauty_Makeup_Nails" + } + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/customer-group/output-schema.ts b/typescript/src/shared/customer-group/output-schema.ts index 5026205..78fd6e2 100644 --- a/typescript/src/shared/customer-group/output-schema.ts +++ b/typescript/src/shared/customer-group/output-schema.ts @@ -26,7 +26,6 @@ export const customerGroupPagedSchema = z }) .strict(); -export const readCustomerGroupOutputSchema = - customerGroupSchema || customerGroupPagedSchema; +export const readCustomerGroupOutputSchema = z.union([customerGroupSchema, customerGroupPagedSchema]); export const createCustomerGroupOutputSchema = customerGroupSchema; export const updateCustomerGroupOutputSchema = customerGroupSchema; diff --git a/typescript/src/shared/customer-group/test/output-schema.test.ts b/typescript/src/shared/customer-group/test/output-schema.test.ts new file mode 100644 index 0000000..6029bfa --- /dev/null +++ b/typescript/src/shared/customer-group/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + customerGroupSchema, + customerGroupPagedSchema, + readCustomerGroupOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('CustomerGroup Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = customerGroupPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = customerGroupSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = customerGroupSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readCustomerGroupOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(customerGroupSchema).toBeDefined(); + expect(readCustomerGroupOutputSchema).toBeDefined(); + expect(customerGroupPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/customer-group/test/output.data.json b/typescript/src/shared/customer-group/test/output.data.json new file mode 100644 index 0000000..ec47042 --- /dev/null +++ b/typescript/src/shared/customer-group/test/output.data.json @@ -0,0 +1,77 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 14, + "results": [ + { + "id": "c8d589dc-ac74-477a-905c-8403e9503700", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:31.616Z", + "createdAt": "2022-11-08T13:18:03.559Z", + "lastModifiedAt": "2022-11-08T13:18:03.559Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "147fa1f6-e486-4d55-826a-dac81b0f17f3" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "147fa1f6-e486-4d55-826a-dac81b0f17f3" + } + }, + "name": "DSO", + "key": "DSO" + }, + { + "id": "adb3f26b-95f5-4789-babf-a08bad64ec00", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:31.606Z", + "createdAt": "2022-11-22T06:13:45.801Z", + "lastModifiedAt": "2022-11-22T06:13:45.801Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f1c38524-1874-4a36-8cc4-b0ed33dcf3e4" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f1c38524-1874-4a36-8cc4-b0ed33dcf3e4" + } + }, + "name": "Affiliates", + "key": "Aff" + }, + { + "id": "ca190f7c-2c29-4050-8a76-b56624f69f73", + "version": 3, + "versionModifiedAt": "2023-09-13T15:45:31.607Z", + "createdAt": "2022-11-22T06:21:59.133Z", + "lastModifiedAt": "2022-11-22T13:09:25.523Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f1c38524-1874-4a36-8cc4-b0ed33dcf3e4" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f1c38524-1874-4a36-8cc4-b0ed33dcf3e4" + } + }, + "name": "Laboratories", + "key": "LAB" + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/customer/output-schema.ts b/typescript/src/shared/customer/output-schema.ts index c22b96d..5026bf4 100644 --- a/typescript/src/shared/customer/output-schema.ts +++ b/typescript/src/shared/customer/output-schema.ts @@ -49,5 +49,5 @@ export const customerPagedSchema = z .strict(); export const createCustomerOutputSchema = customerSchema; -export const readCustomerOutputSchema = customerSchema || customerPagedSchema; +export const readCustomerOutputSchema = z.union([customerSchema, customerPagedSchema]); export const updateCustomerOutputSchema = customerSchema; diff --git a/typescript/src/shared/customer/test/output-schema.test.ts b/typescript/src/shared/customer/test/output-schema.test.ts new file mode 100644 index 0000000..10e0d3c --- /dev/null +++ b/typescript/src/shared/customer/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + customerSchema, + customerPagedSchema, + readCustomerOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Customer Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = customerPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = customerSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = customerSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readCustomerOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(customerSchema).toBeDefined(); + expect(readCustomerOutputSchema).toBeDefined(); + expect(customerPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/customer/test/output.data.json b/typescript/src/shared/customer/test/output.data.json new file mode 100644 index 0000000..e3a96b1 --- /dev/null +++ b/typescript/src/shared/customer/test/output.data.json @@ -0,0 +1,102 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 170, + "results": [ + { + "id": "e518f147-d5af-4193-b76e-63a876a3ba96", + "version": 7, + "versionModifiedAt": "2023-09-13T15:45:34.923Z", + "lastMessageSequenceNumber": 4, + "createdAt": "2022-09-21T21:53:07.044Z", + "lastModifiedAt": "2022-10-06T21:20:04.926Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "email": "abc@test.com", + "firstName": "abc", + "lastName": "test", + "middleName": "", + "title": "", + "salutation": "Mr.", + "companyName": "test company", + "password": "****y8E=", + "addresses": [], + "shippingAddressIds": [], + "billingAddressIds": [], + "isEmailVerified": true, + "customerGroupAssignments": [], + "stores": [], + "authenticationMode": "Password" + }, + { + "id": "97bf484c-dcc4-492b-87a9-b6517c52eb43", + "version": 3, + "versionModifiedAt": "2024-08-08T16:23:11.031Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2022-09-23T13:29:31.460Z", + "lastModifiedAt": "2024-08-08T16:23:11.031Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "email": "asdsa@sdfsdgs.cvads", + "lastName": "AS", + "companyName": "asdasd asdas", + "password": "****kV8=", + "addresses": [], + "shippingAddressIds": [], + "billingAddressIds": [], + "isEmailVerified": true, + "customerGroupAssignments": [], + "stores": [], + "authenticationMode": "Password" + }, + { + "id": "ffbe15e3-bc31-400d-9a72-e5ff1c030418", + "version": 3, + "versionModifiedAt": "2024-08-29T15:57:45.952Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2022-09-23T13:32:21.016Z", + "lastModifiedAt": "2024-08-29T15:57:45.952Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "email": "asdsa@sdfsdgsds.cvads", + "lastName": "tets", + "companyName": "asdasd asdas 23", + "password": "****kyk=", + "addresses": [], + "shippingAddressIds": [], + "billingAddressIds": [], + "isEmailVerified": true, + "customerGroupAssignments": [], + "stores": [], + "authenticationMode": "Password" + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/discount-code/output-schema.ts b/typescript/src/shared/discount-code/output-schema.ts index b91cfc6..ea9056d 100644 --- a/typescript/src/shared/discount-code/output-schema.ts +++ b/typescript/src/shared/discount-code/output-schema.ts @@ -38,7 +38,6 @@ export const discountCodePagedSchema = z }) .strict(); -export const readDiscountCodeOutputSchema = - discountCodeSchema || discountCodePagedSchema; +export const readDiscountCodeOutputSchema = z.union([discountCodeSchema, discountCodePagedSchema]); export const createDiscountCodeOutputSchema = discountCodeSchema; export const updateDiscountCodeOutputSchema = discountCodeSchema; diff --git a/typescript/src/shared/discount-code/test/output-schema.test.ts b/typescript/src/shared/discount-code/test/output-schema.test.ts new file mode 100644 index 0000000..d428147 --- /dev/null +++ b/typescript/src/shared/discount-code/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + discountCodeSchema, + discountCodePagedSchema, + readDiscountCodeOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('DiscountCode Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = discountCodePagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = discountCodeSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = discountCodeSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readDiscountCodeOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(discountCodeSchema).toBeDefined(); + expect(readDiscountCodeOutputSchema).toBeDefined(); + expect(discountCodePagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/discount-code/test/output.data.json b/typescript/src/shared/discount-code/test/output.data.json new file mode 100644 index 0000000..564a5f8 --- /dev/null +++ b/typescript/src/shared/discount-code/test/output.data.json @@ -0,0 +1,133 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 3, + "results": [ + { + "id": "139d8e84-ae67-4966-9ee7-ba0b36ac23b6", + "version": 5, + "versionModifiedAt": "2023-09-13T15:45:33.568Z", + "createdAt": "2022-10-03T17:26:45.085Z", + "lastModifiedAt": "2022-10-03T17:26:54.906Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "code": "-test", + "name": { + "en-US": "-test" + }, + "description": { + "en-US": "" + }, + "cartDiscounts": [ + { + "typeId": "cart-discount", + "id": "42c2810a-51fb-4e1f-8a50-c81594ef50b2" + } + ], + "isActive": true, + "references": [], + "applicationVersion": 2, + "groups": [] + }, + { + "id": "750e6621-7240-4758-aaf9-9b54b460652c", + "version": 6, + "versionModifiedAt": "2023-10-05T14:03:17.419Z", + "createdAt": "2023-10-03T19:27:28.734Z", + "lastModifiedAt": "2023-10-03T19:27:54.066Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "147fa1f6-e486-4d55-826a-dac81b0f17f3" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "147fa1f6-e486-4d55-826a-dac81b0f17f3" + } + }, + "code": "class20", + "name": { + "af": "", + "en-GB": "", + "en-US": "class20", + "es-MX": "" + }, + "description": { + "af": "", + "en-GB": "", + "en-US": "20% off Classes", + "es-MX": "" + }, + "cartDiscounts": [ + { + "typeId": "cart-discount", + "id": "8af706a0-17a7-4b81-8f34-dc6f949c2020" + } + ], + "isActive": true, + "references": [], + "applicationVersion": 4, + "groups": [] + }, + { + "id": "9dc898ea-d394-40ec-924b-55ed7bb90dd4", + "version": 3, + "versionModifiedAt": "2024-04-25T17:52:57.281Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2024-04-25T16:57:31.932Z", + "lastModifiedAt": "2024-04-25T16:57:47.185Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f372e4e3-4a11-469d-807a-d3622d00da99" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f372e4e3-4a11-469d-807a-d3622d00da99" + } + }, + "code": "ult130-10", + "name": { + "en-GB": "", + "en-US": "", + "es-MX": "" + }, + "description": { + "en-GB": "", + "en-US": "", + "es-MX": "" + }, + "cartDiscounts": [ + { + "typeId": "cart-discount", + "id": "06e630a9-cfd0-4789-9d07-32961832b07a" + } + ], + "isActive": true, + "references": [], + "applicationVersion": 1, + "groups": [] + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/extensions/output-schema.ts b/typescript/src/shared/extensions/output-schema.ts index d4da07e..04e04bd 100644 --- a/typescript/src/shared/extensions/output-schema.ts +++ b/typescript/src/shared/extensions/output-schema.ts @@ -27,7 +27,6 @@ export const extensionsPagedSchema = z }) .strict(); -export const readExtensionOutputSchema = - extensionsSchema || extensionsPagedSchema; +export const readExtensionOutputSchema = z.union([extensionsSchema, extensionsPagedSchema]); export const createExtensionOutputSchema = extensionsSchema; export const updateExtensionOutputSchema = extensionsSchema; diff --git a/typescript/src/shared/extensions/test/output-schema.test.ts b/typescript/src/shared/extensions/test/output-schema.test.ts new file mode 100644 index 0000000..7948ae5 --- /dev/null +++ b/typescript/src/shared/extensions/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + extensionsSchema, + extensionsPagedSchema, + readExtensionOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Extensions Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = extensionsPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = extensionsSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = extensionsSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readExtensionOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(extensionsSchema).toBeDefined(); + expect(readExtensionOutputSchema).toBeDefined(); + expect(extensionsPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/extensions/test/output.data.json b/typescript/src/shared/extensions/test/output.data.json new file mode 100644 index 0000000..9f5993c --- /dev/null +++ b/typescript/src/shared/extensions/test/output.data.json @@ -0,0 +1,7 @@ +{ + "limit": 3, + "offset": 0, + "count": 0, + "total": 0, + "results": [] +} \ No newline at end of file diff --git a/typescript/src/shared/inventory/output-schema.ts b/typescript/src/shared/inventory/output-schema.ts index 25fa4e1..38fbe28 100644 --- a/typescript/src/shared/inventory/output-schema.ts +++ b/typescript/src/shared/inventory/output-schema.ts @@ -33,7 +33,6 @@ export const inventoryPagedSchema = z }) .strict(); -export const readInventoryOutputSchema = - inventorySchema || inventoryPagedSchema; +export const readInventoryOutputSchema = z.union([inventorySchema, inventoryPagedSchema]); export const createInventoryOutputSchema = inventorySchema; export const updateInventoryOutputSchema = inventorySchema; diff --git a/typescript/src/shared/inventory/test/output-schema.test.ts b/typescript/src/shared/inventory/test/output-schema.test.ts new file mode 100644 index 0000000..fd9907b --- /dev/null +++ b/typescript/src/shared/inventory/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + inventorySchema, + inventoryPagedSchema, + readInventoryOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Inventory Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = inventoryPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = inventorySchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = inventorySchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readInventoryOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(inventorySchema).toBeDefined(); + expect(readInventoryOutputSchema).toBeDefined(); + expect(inventoryPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/inventory/test/output.data.json b/typescript/src/shared/inventory/test/output.data.json new file mode 100644 index 0000000..08c23aa --- /dev/null +++ b/typescript/src/shared/inventory/test/output.data.json @@ -0,0 +1,74 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 22984, + "results": [ + { + "id": "ff911c41-4784-4a09-829f-dc7acbc947a1", + "version": 4, + "versionModifiedAt": "2024-01-24T23:21:24.246Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2022-09-19T19:55:31.969Z", + "lastModifiedAt": "2024-01-24T23:21:24.246Z", + "lastModifiedBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "sku": "123", + "supplyChannel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + }, + "quantityOnStock": 472, + "availableQuantity": 472 + }, + { + "id": "5b25f16c-2e48-486e-a609-38f1aa582383", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:19.658Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2022-09-22T21:33:36.748Z", + "lastModifiedAt": "2022-09-22T21:33:36.748Z", + "lastModifiedBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "sku": "B08JVMGZ8Y-1", + "quantityOnStock": 101, + "availableQuantity": 101, + "restockableInDays": 7 + }, + { + "id": "26b9eb82-81ab-426d-93d8-ce4a1e7d70c4", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:19.658Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2022-09-22T21:33:36.905Z", + "lastModifiedAt": "2022-09-22T21:33:36.905Z", + "lastModifiedBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "sku": "B0B7BTJJTS-1", + "quantityOnStock": 101, + "availableQuantity": 101, + "restockableInDays": 7 + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/order/output-schema.ts b/typescript/src/shared/order/output-schema.ts index ac7dac9..cc26f9c 100644 --- a/typescript/src/shared/order/output-schema.ts +++ b/typescript/src/shared/order/output-schema.ts @@ -3,6 +3,7 @@ import {z} from 'zod'; // Base Order schema export const orderSchema = z .object({ + type: z.literal('Order'), id: z.string(), version: z.number(), createdAt: z.string(), @@ -71,6 +72,6 @@ export const orderPagedSchema = z }) .strict(); -export const readOrderOutputSchema = orderSchema || orderPagedSchema; +export const readOrderOutputSchema = z.union([orderSchema, orderPagedSchema]); export const createOrderOutputSchema = orderSchema; export const updateOrderOutputSchema = orderSchema; diff --git a/typescript/src/shared/order/test/output-schema.test.ts b/typescript/src/shared/order/test/output-schema.test.ts new file mode 100644 index 0000000..69f8ad7 --- /dev/null +++ b/typescript/src/shared/order/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + orderSchema, + orderPagedSchema, + readOrderOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Order Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = orderPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = orderSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = orderSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readOrderOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(orderSchema).toBeDefined(); + expect(readOrderOutputSchema).toBeDefined(); + expect(orderPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/order/test/output.data.json b/typescript/src/shared/order/test/output.data.json new file mode 100644 index 0000000..8459f85 --- /dev/null +++ b/typescript/src/shared/order/test/output.data.json @@ -0,0 +1,804 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 751, + "results": [ + { + "type": "Order", + "id": "ede78e22-c5b2-4679-a2ea-8b7a68ac4a24", + "version": 5, + "versionModifiedAt": "2024-02-15T19:28:15.558Z", + "lastMessageSequenceNumber": 4, + "createdAt": "2022-10-18T12:40:15.338Z", + "lastModifiedAt": "2024-02-15T19:28:15.558Z", + "lastModifiedBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "orderNumber": "67ed5eec-1398-48d7-944e-76de03d3c45e", + "customerId": "6c169f06-34b3-4c48-bbde-6da224c9768f", + "customerEmail": "adi@das.com", + "locale": "en-US", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 7300, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 7300, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 8030, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 730, + "fractionDigits": 2 + }, + "name": "standard" + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 730, + "fractionDigits": 2 + } + }, + "country": "US", + "orderState": "Open", + "syncInfo": [], + "returnInfo": [], + "priceRoundingMode": "HalfEven", + "taxMode": "Platform", + "inventoryMode": "ReserveOnOrder", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "origin": "Customer", + "shippingMode": "Single", + "shippingAddress": { + "id": "1st-shipping-address", + "firstName": "Main", + "lastName": "Branch", + "streetName": "1 A", + "postalCode": "12354", + "city": "Buuuu", + "country": "US" + }, + "shipping": [], + "discountTypeCombination": { + "type": "Stacking" + }, + "lineItems": [ + { + "id": "78bb1b3f-90b2-45f4-aca2-8cdec1a7207e", + "productId": "40f749bc-1df8-4cda-98da-5c441c10780e", + "productKey": "B074V2Y5ZJ", + "productType": { + "typeId": "product-type", + "id": "7c8a90ff-4d2d-457e-afcf-0d6330276d0c", + "version": 1 + }, + "productSlug": { + "en-US": "Tylenol-Extra-Strength-Rapid-Release" + }, + "name": { + "en-US": "Tylenol Extra Strength Rapid Release Gels 500 mg - Value Size 2 Pack ( 290 Count Each )" + }, + "variant": { + "id": 1, + "sku": "B074V2Y5ZJ-1", + "prices": [ + { + "id": "e09fd88d-6ef1-4467-8372-eaa1c261b455", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4700, + "fractionDigits": 2 + } + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/718IC-nNM+L._AC_SX42-Kk29cPtv.jpg", + "dimensions": { + "w": 425, + "h": 240 + } + } + ], + "attributes": [], + "assets": [], + "availability": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 101, + "version": 1, + "id": "d97f6474-21d8-4995-88aa-613c9f4e723e" + } + }, + "price": { + "id": "e09fd88d-6ef1-4467-8372-eaa1c261b455", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4700, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPricePerQuantity": [], + "distributionChannel": { + "typeId": "channel", + "id": "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6" + }, + "taxRate": { + "name": "standard", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "z821AAA9", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2022-10-13T20:36:39.681Z", + "lastModifiedAt": "2022-10-13T20:36:39.681Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4700, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4700, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5170, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 470, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + }, + { + "id": "5deeb070-5f50-4698-8f3a-98e1c0c9e449", + "productId": "4ca24a28-ac53-407c-bc5c-63065986fec5", + "productKey": "B00EHNC5TK", + "productType": { + "typeId": "product-type", + "id": "7c8a90ff-4d2d-457e-afcf-0d6330276d0c", + "version": 1 + }, + "productSlug": { + "en-US": "Tylenol-Arthritis-Caplets-Bottle-Acetaminophen" + }, + "name": { + "en-US": "Tylenol Arthritis Pain 250 Caplets Bottle, 650mg Acetaminophen" + }, + "variant": { + "id": 1, + "sku": "B00EHNC5TK-1", + "prices": [ + { + "id": "dafccbf3-b463-454d-ba46-76c7d56458bf", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2600, + "fractionDigits": 2 + } + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/61RVkomhteL._AC_SX42-YzmTqGg3.jpg", + "dimensions": { + "w": 425, + "h": 707 + } + } + ], + "attributes": [], + "assets": [], + "availability": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 101, + "version": 1, + "id": "9a9f7d90-704f-4724-8b78-8fd279e74ed7" + } + }, + "price": { + "id": "dafccbf3-b463-454d-ba46-76c7d56458bf", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2600, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPricePerQuantity": [], + "distributionChannel": { + "typeId": "channel", + "id": "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6" + }, + "taxRate": { + "name": "standard", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "z821AAA9", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2022-10-18T12:30:26.999Z", + "lastModifiedAt": "2022-10-18T12:30:26.999Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2600, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2600, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2860, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 260, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + } + ], + "customLineItems": [], + "transactionFee": true, + "discountCodes": [], + "directDiscounts": [], + "cart": { + "typeId": "cart", + "id": "5483ecef-b07c-4937-b12e-1d01d22e8c30" + }, + "billingAddress": { + "id": "1st-shipping-address", + "firstName": "Main", + "lastName": "Branch", + "streetName": "1 A", + "postalCode": "12354", + "city": "Buuuu", + "country": "US" + }, + "itemShippingAddresses": [], + "refusedGifts": [], + "store": { + "typeId": "store", + "key": "store_adidas" + }, + "businessUnit": { + "typeId": "business-unit", + "key": "business_unit_adidas" + } + }, + { + "type": "Order", + "id": "1693968f-205d-4773-ae08-b9fa9d4eec6a", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:18.661Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2022-10-18T13:00:56.678Z", + "lastModifiedAt": "2022-10-18T13:00:56.678Z", + "lastModifiedBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "orderNumber": "717cbeb6-c1db-4886-3ebf-2c66ab14cc20", + "customerId": "6c169f06-34b3-4c48-bbde-6da224c9768f", + "customerEmail": "adi@das.com", + "locale": "en-US", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2100, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2100, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2310, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 210, + "fractionDigits": 2 + }, + "name": "standard" + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 210, + "fractionDigits": 2 + } + }, + "country": "US", + "orderState": "Open", + "syncInfo": [], + "returnInfo": [], + "priceRoundingMode": "HalfEven", + "taxMode": "Platform", + "inventoryMode": "ReserveOnOrder", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "origin": "Customer", + "shippingMode": "Single", + "shippingAddress": { + "id": "1st-shipping-address", + "firstName": "Main", + "lastName": "Branch", + "streetName": "1 A", + "postalCode": "12354", + "city": "Buuuu", + "country": "US" + }, + "shipping": [], + "discountTypeCombination": { + "type": "Stacking" + }, + "lineItems": [ + { + "id": "0e39b1e0-4f14-47c4-afec-f49cef325f9e", + "productId": "a6ba835b-082d-403d-86f9-d618fadf817b", + "productKey": "B005FCOGJE", + "productType": { + "typeId": "product-type", + "id": "7c8a90ff-4d2d-457e-afcf-0d6330276d0c", + "version": 1 + }, + "productSlug": { + "en-US": "Tylenol-Extra-Strength-Pouches-Caplets" + }, + "name": { + "en-US": "Tylenol Extra Strength 50 Pouches of 2 Caplets Each" + }, + "variant": { + "id": 1, + "sku": "B005FCOGJE-1", + "prices": [ + { + "id": "e3db5cc6-a12a-46b3-a0c5-c76b16725c1c", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2100, + "fractionDigits": 2 + } + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/41s3NEBeQGL._AC_PIbu-e0ba-dwL.jpg", + "dimensions": { + "w": 324, + "h": 400 + } + } + ], + "attributes": [], + "assets": [], + "availability": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 101, + "version": 1, + "id": "413b61a9-fb68-41ed-9742-0314d7cab5a0" + } + }, + "price": { + "id": "e3db5cc6-a12a-46b3-a0c5-c76b16725c1c", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2100, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPricePerQuantity": [], + "distributionChannel": { + "typeId": "channel", + "id": "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6" + }, + "taxRate": { + "name": "standard", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "z821AAA9", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2022-10-18T13:00:30.800Z", + "lastModifiedAt": "2022-10-18T13:00:30.800Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2100, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2100, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2310, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 210, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + } + ], + "customLineItems": [], + "transactionFee": true, + "discountCodes": [], + "directDiscounts": [], + "cart": { + "typeId": "cart", + "id": "e95d144c-1d44-407f-82f5-35efc435523f" + }, + "billingAddress": { + "id": "1st-shipping-address", + "firstName": "Main", + "lastName": "Branch", + "streetName": "1 A", + "postalCode": "12354", + "city": "Buuuu", + "country": "US" + }, + "itemShippingAddresses": [], + "refusedGifts": [], + "store": { + "typeId": "store", + "key": "store_adidas" + }, + "businessUnit": { + "typeId": "business-unit", + "key": "business_unit_adidas" + } + }, + { + "type": "Order", + "id": "bfc8f914-1af1-49b7-a76a-6e500e312dfd", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:18.661Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2022-10-18T13:02:16.986Z", + "lastModifiedAt": "2022-10-18T13:02:16.986Z", + "lastModifiedBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "orderNumber": "4dc27abf-23f5-44ca-bf17-9d78a94cc3bd", + "customerId": "6c169f06-34b3-4c48-bbde-6da224c9768f", + "customerEmail": "adi@das.com", + "locale": "en-US", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2000, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2000, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2200, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 200, + "fractionDigits": 2 + }, + "name": "standard" + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 200, + "fractionDigits": 2 + } + }, + "country": "US", + "orderState": "Open", + "syncInfo": [], + "returnInfo": [], + "priceRoundingMode": "HalfEven", + "taxMode": "Platform", + "inventoryMode": "ReserveOnOrder", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "origin": "Customer", + "shippingMode": "Single", + "shippingAddress": { + "id": "1st-shipping-address", + "firstName": "Main", + "lastName": "Branch", + "streetName": "1 A", + "postalCode": "12354", + "city": "Buuuu", + "country": "US" + }, + "shipping": [], + "discountTypeCombination": { + "type": "Stacking" + }, + "lineItems": [ + { + "id": "74050ae3-d40a-4e4c-a654-e596d97f5832", + "productId": "edc5789d-e069-4334-ae63-c6ecb7a8c33d", + "productKey": "B07QSFJ8S2", + "productType": { + "typeId": "product-type", + "id": "7c8a90ff-4d2d-457e-afcf-0d6330276d0c", + "version": 1 + }, + "productSlug": { + "en-US": "Shoulder-Cervical-Traction-Alignment-Chiropractic" + }, + "name": { + "en-US": "Neck and Shoulder Relaxer, Cervical Traction Device for TMJ Pain Relief and Cervical Spine Alignment, Chiropractic Pillow Neck Stretcher(Blue)" + }, + "variant": { + "id": 1, + "sku": "B07QSFJ8S2-1", + "prices": [ + { + "id": "b56e9836-40ad-473e-be7d-87759d38c8c4", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2000, + "fractionDigits": 2 + } + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/71E1iRL3ynL._AC_SX52-IGktOfAK.jpg", + "dimensions": { + "w": 522, + "h": 523 + } + } + ], + "attributes": [], + "assets": [], + "availability": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 101, + "version": 1, + "id": "44c90ef6-e7b2-4892-ad81-a48eb6815efe" + } + }, + "price": { + "id": "b56e9836-40ad-473e-be7d-87759d38c8c4", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2000, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPricePerQuantity": [], + "distributionChannel": { + "typeId": "channel", + "id": "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6" + }, + "taxRate": { + "name": "standard", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "z821AAA9", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2022-10-18T13:02:06.832Z", + "lastModifiedAt": "2022-10-18T13:02:06.832Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2000, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2000, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2200, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 200, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + } + ], + "customLineItems": [], + "transactionFee": true, + "discountCodes": [], + "directDiscounts": [], + "cart": { + "typeId": "cart", + "id": "90abc636-f0a0-40c3-8244-1a39a0c9bb76" + }, + "billingAddress": { + "id": "1st-shipping-address", + "firstName": "Main", + "lastName": "Branch", + "streetName": "1 A", + "postalCode": "12354", + "city": "Buuuu", + "country": "US" + }, + "itemShippingAddresses": [], + "refusedGifts": [], + "store": { + "typeId": "store", + "key": "store_adidas" + }, + "businessUnit": { + "typeId": "business-unit", + "key": "business_unit_adidas" + } + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/payment-methods/output-schema.ts b/typescript/src/shared/payment-methods/output-schema.ts index a360b59..9ee6421 100644 --- a/typescript/src/shared/payment-methods/output-schema.ts +++ b/typescript/src/shared/payment-methods/output-schema.ts @@ -34,7 +34,6 @@ export const paymentMethodsPagedSchema = z }) .strict(); -export const readPaymentMethodsOutputSchema = - paymentMethodsSchema || paymentMethodsPagedSchema; +export const readPaymentMethodsOutputSchema = z.union([paymentMethodsSchema, paymentMethodsPagedSchema]); export const createPaymentMethodsOutputSchema = paymentMethodsSchema; export const updatePaymentMethodsOutputSchema = paymentMethodsSchema; diff --git a/typescript/src/shared/payment-methods/test/output-schema.test.ts b/typescript/src/shared/payment-methods/test/output-schema.test.ts new file mode 100644 index 0000000..0116c14 --- /dev/null +++ b/typescript/src/shared/payment-methods/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + paymentMethodsSchema, + paymentMethodsPagedSchema, + readPaymentMethodsOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('PaymentMethods Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = paymentMethodsPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = paymentMethodsSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = paymentMethodsSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readPaymentMethodsOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(paymentMethodsSchema).toBeDefined(); + expect(readPaymentMethodsOutputSchema).toBeDefined(); + expect(paymentMethodsPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/payment-methods/test/output.data.json b/typescript/src/shared/payment-methods/test/output.data.json new file mode 100644 index 0000000..9f5993c --- /dev/null +++ b/typescript/src/shared/payment-methods/test/output.data.json @@ -0,0 +1,7 @@ +{ + "limit": 3, + "offset": 0, + "count": 0, + "total": 0, + "results": [] +} \ No newline at end of file diff --git a/typescript/src/shared/payments/output-schema.ts b/typescript/src/shared/payments/output-schema.ts index c8a8e5b..c9ab307 100644 --- a/typescript/src/shared/payments/output-schema.ts +++ b/typescript/src/shared/payments/output-schema.ts @@ -33,6 +33,6 @@ export const paymentsPagedSchema = z }) .strict(); -export const readPaymentsOutputSchema = paymentsSchema || paymentsPagedSchema; +export const readPaymentsOutputSchema = z.union([paymentsSchema, paymentsPagedSchema]); export const createPaymentsOutputSchema = paymentsSchema; export const updatePaymentsOutputSchema = paymentsSchema; diff --git a/typescript/src/shared/payments/test/output-schema.test.ts b/typescript/src/shared/payments/test/output-schema.test.ts new file mode 100644 index 0000000..297415f --- /dev/null +++ b/typescript/src/shared/payments/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + paymentsSchema, + paymentsPagedSchema, + readPaymentsOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Payments Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = paymentsPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = paymentsSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = paymentsSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readPaymentsOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(paymentsSchema).toBeDefined(); + expect(readPaymentsOutputSchema).toBeDefined(); + expect(paymentsPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/payments/test/output.data.json b/typescript/src/shared/payments/test/output.data.json new file mode 100644 index 0000000..9fb6a03 --- /dev/null +++ b/typescript/src/shared/payments/test/output.data.json @@ -0,0 +1,130 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 8, + "results": [ + { + "id": "4830b60b-765a-47c9-a423-12ae87090175", + "version": 3, + "versionModifiedAt": "2024-04-25T20:39:10.613Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2024-04-25T20:02:34.045Z", + "lastModifiedAt": "2024-04-25T20:39:10.613Z", + "lastModifiedBy": { + "clientId": "ax-1-bpgYf5y4k1p3xflnbEn", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "ax-1-bpgYf5y4k1p3xflnbEn", + "isPlatformClient": false + }, + "key": "123456", + "interfaceId": "789011", + "amountPlanned": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 256728384, + "fractionDigits": 2 + }, + "paymentMethodInfo": { + "paymentInterface": "pago-anticipado-contado", + "method": "contado", + "name": { + "en": "Contado" + } + }, + "paymentStatus": {}, + "transactions": [ + { + "id": "7f9e4d07-1e08-4d93-ada4-7f6aea37e572", + "timestamp": "2015-10-20T08:54:24.000Z", + "type": "Charge", + "amount": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 233389440, + "fractionDigits": 2 + }, + "state": "Pending" + }, + { + "id": "06f1889a-bc24-4ab4-a312-6f384b75526c", + "type": "Authorization", + "amount": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 23338944, + "fractionDigits": 2 + }, + "state": "Initial" + } + ], + "interfaceInteractions": [] + }, + { + "id": "26a762af-9025-4e62-9935-d493f840df78", + "version": 1, + "versionModifiedAt": "2024-04-25T21:14:27.246Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2024-04-25T21:14:27.246Z", + "lastModifiedAt": "2024-04-25T21:14:27.246Z", + "lastModifiedBy": { + "clientId": "ax-1-bpgYf5y4k1p3xflnbEn", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "ax-1-bpgYf5y4k1p3xflnbEn", + "isPlatformClient": false + }, + "amountPlanned": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 0, + "fractionDigits": 2 + }, + "paymentMethodInfo": { + "paymentInterface": "STRIPE", + "method": "PAGO_CONTADO", + "name": { + "en": "Pago Contado" + } + }, + "paymentStatus": {}, + "transactions": [], + "interfaceInteractions": [] + }, + { + "id": "a60f0bfc-ad3a-4715-b3bc-fd75f4e667ef", + "version": 1, + "versionModifiedAt": "2024-04-25T21:15:29.984Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2024-04-25T21:15:29.984Z", + "lastModifiedAt": "2024-04-25T21:15:29.984Z", + "lastModifiedBy": { + "clientId": "ax-1-bpgYf5y4k1p3xflnbEn", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "ax-1-bpgYf5y4k1p3xflnbEn", + "isPlatformClient": false + }, + "amountPlanned": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 0, + "fractionDigits": 2 + }, + "paymentMethodInfo": { + "paymentInterface": "ERP", + "method": "PAGO_CONTADO", + "name": { + "en": "Pago Contado" + } + }, + "paymentStatus": {}, + "transactions": [], + "interfaceInteractions": [] + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/product-discount/output-schema.ts b/typescript/src/shared/product-discount/output-schema.ts index 4d5518a..86b3b7c 100644 --- a/typescript/src/shared/product-discount/output-schema.ts +++ b/typescript/src/shared/product-discount/output-schema.ts @@ -33,7 +33,6 @@ export const productDiscountPagedSchema = z }) .strict(); -export const readProductDiscountOutputSchema = - productDiscountSchema || productDiscountPagedSchema; +export const readProductDiscountOutputSchema = z.union([productDiscountSchema, productDiscountPagedSchema]); export const createProductDiscountOutputSchema = productDiscountSchema; export const updateProductDiscountOutputSchema = productDiscountSchema; diff --git a/typescript/src/shared/product-discount/test/output-schema.test.ts b/typescript/src/shared/product-discount/test/output-schema.test.ts new file mode 100644 index 0000000..8d408b6 --- /dev/null +++ b/typescript/src/shared/product-discount/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + productDiscountSchema, + productDiscountPagedSchema, + readProductDiscountOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('ProductDiscount Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = productDiscountPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = productDiscountSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = productDiscountSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readProductDiscountOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(productDiscountSchema).toBeDefined(); + expect(readProductDiscountOutputSchema).toBeDefined(); + expect(productDiscountPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/product-discount/test/output.data.json b/typescript/src/shared/product-discount/test/output.data.json new file mode 100644 index 0000000..9ee778e --- /dev/null +++ b/typescript/src/shared/product-discount/test/output.data.json @@ -0,0 +1,140 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 12, + "results": [ + { + "id": "a645634a-642b-4a9c-8188-42032520edd1", + "version": 6, + "versionModifiedAt": "2023-09-13T15:45:33.534Z", + "createdAt": "2023-02-14T14:17:02.018Z", + "lastModifiedAt": "2023-02-27T12:54:03.616Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "2efd184e-b6cf-412a-b0ca-396771d7cb5e" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "147fa1f6-e486-4d55-826a-dac81b0f17f3" + } + }, + "value": { + "type": "relative", + "permyriad": 1000 + }, + "predicate": "categories.id = (\"1809e313-5145-445b-b50e-c5ee07ab101a\") and (customerGroup.id = \"ca190f7c-2c29-4050-8a76-b56624f69f73\") and not(attributes.Measurement = \"10\")", + "name": { + "en-US": "Save 10% on Printers for Laboratoires Customer Group" + }, + "description": { + "en-US": "Save 10% on Printers" + }, + "isActive": false, + "sortOrder": "0.05", + "references": [ + { + "typeId": "category", + "id": "1809e313-5145-445b-b50e-c5ee07ab101a" + }, + { + "typeId": "customer-group", + "id": "ca190f7c-2c29-4050-8a76-b56624f69f73" + } + ] + }, + { + "id": "551d4ac9-e4e7-4e6a-902f-c8f5c70f2388", + "version": 7, + "versionModifiedAt": "2023-09-13T15:45:33.534Z", + "createdAt": "2023-03-13T16:30:09.321Z", + "lastModifiedAt": "2023-08-29T14:24:29.021Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "147fa1f6-e486-4d55-826a-dac81b0f17f3" + } + }, + "value": { + "type": "relative", + "permyriad": 1000 + }, + "predicate": "categories.id = (\"4808deb3-92dd-4285-8c26-36fd0e458744\")", + "name": { + "en-US": "Price Group 1 Save 10% on Office Supplies ", + "af": "", + "es-MX": "" + }, + "description": { + "en-US": "Save 10% on Office", + "af": "", + "es-MX": "" + }, + "isActive": false, + "sortOrder": "0.07", + "references": [ + { + "typeId": "category", + "id": "4808deb3-92dd-4285-8c26-36fd0e458744" + } + ] + }, + { + "id": "aea0bfe5-8d83-4cd1-81d2-23916053628d", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:33.534Z", + "createdAt": "2023-03-13T16:31:10.928Z", + "lastModifiedAt": "2023-03-13T16:31:10.928Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "147fa1f6-e486-4d55-826a-dac81b0f17f3" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "147fa1f6-e486-4d55-826a-dac81b0f17f3" + } + }, + "value": { + "type": "relative", + "permyriad": 1500 + }, + "predicate": "categories.id = (\"4808deb3-92dd-4285-8c26-36fd0e458744\") and customerGroup.id = \"fd6f7919-894d-4926-a63f-fe01bfe2f58b\"", + "name": { + "en-US": "Price Group 2 Save 15% on Office Supplies" + }, + "description": { + "en-US": "Save 10% on Office" + }, + "isActive": false, + "sortOrder": "0.06", + "references": [ + { + "typeId": "category", + "id": "4808deb3-92dd-4285-8c26-36fd0e458744" + }, + { + "typeId": "customer-group", + "id": "fd6f7919-894d-4926-a63f-fe01bfe2f58b" + } + ] + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/product-selection/output-schema.ts b/typescript/src/shared/product-selection/output-schema.ts index 41f1aad..3f2f859 100644 --- a/typescript/src/shared/product-selection/output-schema.ts +++ b/typescript/src/shared/product-selection/output-schema.ts @@ -28,7 +28,6 @@ export const productSelectionPagedSchema = z }) .strict(); -export const readProductSelectionOutputSchema = - productSelectionSchema || productSelectionPagedSchema; +export const readProductSelectionOutputSchema = z.union([productSelectionSchema, productSelectionPagedSchema]); export const createProductSelectionOutputSchema = productSelectionSchema; export const updateProductSelectionOutputSchema = productSelectionSchema; diff --git a/typescript/src/shared/product-selection/test/output-schema.test.ts b/typescript/src/shared/product-selection/test/output-schema.test.ts new file mode 100644 index 0000000..cf44750 --- /dev/null +++ b/typescript/src/shared/product-selection/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + productSelectionSchema, + productSelectionPagedSchema, + readProductSelectionOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('ProductSelection Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = productSelectionPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = productSelectionSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = productSelectionSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readProductSelectionOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(productSelectionSchema).toBeDefined(); + expect(readProductSelectionOutputSchema).toBeDefined(); + expect(productSelectionPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/product-selection/test/output.data.json b/typescript/src/shared/product-selection/test/output.data.json new file mode 100644 index 0000000..47e3aca --- /dev/null +++ b/typescript/src/shared/product-selection/test/output.data.json @@ -0,0 +1,91 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 20, + "results": [ + { + "id": "549e6621-defb-4539-a114-1eac075f86be", + "version": 143, + "versionModifiedAt": "2023-09-13T15:45:18.223Z", + "lastMessageSequenceNumber": 8, + "createdAt": "2022-09-23T16:02:29.390Z", + "lastModifiedAt": "2023-03-23T15:16:17.358Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "147fa1f6-e486-4d55-826a-dac81b0f17f3" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "name": { + "en-US": "tier 1" + }, + "productCount": 1, + "mode": "Individual" + }, + { + "id": "3141d1b8-abeb-4404-a060-a862128853cb", + "version": 3, + "versionModifiedAt": "2023-09-13T15:45:18.224Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2022-10-18T20:42:10.687Z", + "lastModifiedAt": "2022-10-18T20:42:27.301Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "key": "msd", + "name": { + "en-US": "McKesson Specialty Distribution" + }, + "productCount": 1, + "mode": "Individual" + }, + { + "id": "e2aedb29-613e-41bb-be58-3d0cadb6f9d0", + "version": 6, + "versionModifiedAt": "2023-09-13T15:45:18.223Z", + "lastMessageSequenceNumber": 5, + "createdAt": "2022-12-13T13:40:56.788Z", + "lastModifiedAt": "2022-12-13T13:52:44.639Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "b7b12d4b-c570-405f-a9c1-35933715c37f" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "e4a7384a-946f-4738-b234-b69feb044495" + } + }, + "key": "canon", + "name": { + "en-US": "canon" + }, + "productCount": 4, + "mode": "Individual" + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/product-tailoring/output-schema.ts b/typescript/src/shared/product-tailoring/output-schema.ts index 633b040..20e1e7f 100644 --- a/typescript/src/shared/product-tailoring/output-schema.ts +++ b/typescript/src/shared/product-tailoring/output-schema.ts @@ -31,7 +31,6 @@ export const productTailoringPagedSchema = z }) .strict(); -export const readProductTailoringOutputSchema = - productTailoringSchema || productTailoringPagedSchema; +export const readProductTailoringOutputSchema = z.union([productTailoringSchema, productTailoringPagedSchema]); export const createProductTailoringOutputSchema = productTailoringSchema; export const updateProductTailoringOutputSchema = productTailoringSchema; diff --git a/typescript/src/shared/product-tailoring/test/output-schema.test.ts b/typescript/src/shared/product-tailoring/test/output-schema.test.ts new file mode 100644 index 0000000..cb847f8 --- /dev/null +++ b/typescript/src/shared/product-tailoring/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + productTailoringSchema, + productTailoringPagedSchema, + readProductTailoringOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('ProductTailoring Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = productTailoringPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = productTailoringSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = productTailoringSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readProductTailoringOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(productTailoringSchema).toBeDefined(); + expect(readProductTailoringOutputSchema).toBeDefined(); + expect(productTailoringPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/product-tailoring/test/output.data.json b/typescript/src/shared/product-tailoring/test/output.data.json new file mode 100644 index 0000000..ba8bb49 --- /dev/null +++ b/typescript/src/shared/product-tailoring/test/output.data.json @@ -0,0 +1,6 @@ +{ + "limit": 3, + "offset": 0, + "count": 0, + "results": [] +} \ No newline at end of file diff --git a/typescript/src/shared/product-type/output-schema.ts b/typescript/src/shared/product-type/output-schema.ts index 408d439..d629e26 100644 --- a/typescript/src/shared/product-type/output-schema.ts +++ b/typescript/src/shared/product-type/output-schema.ts @@ -27,7 +27,6 @@ export const productTypePagedSchema = z }) .strict(); -export const readProductTypeOutputSchema = - productTypeSchema || productTypePagedSchema; +export const readProductTypeOutputSchema = z.union([productTypeSchema, productTypePagedSchema]); export const createProductTypeOutputSchema = productTypeSchema; export const updateProductTypeOutputSchema = productTypeSchema; diff --git a/typescript/src/shared/product-type/test/output-schema.test.ts b/typescript/src/shared/product-type/test/output-schema.test.ts new file mode 100644 index 0000000..787aaa3 --- /dev/null +++ b/typescript/src/shared/product-type/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + productTypeSchema, + productTypePagedSchema, + readProductTypeOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('ProductType Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = productTypePagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = productTypeSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = productTypeSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readProductTypeOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(productTypeSchema).toBeDefined(); + expect(readProductTypeOutputSchema).toBeDefined(); + expect(productTypePagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/product-type/test/output.data.json b/typescript/src/shared/product-type/test/output.data.json new file mode 100644 index 0000000..c92b062 --- /dev/null +++ b/typescript/src/shared/product-type/test/output.data.json @@ -0,0 +1,797 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 32, + "results": [ + { + "id": "00fec3ef-6ca0-4d02-94da-33238f7bca94", + "version": 3, + "versionModifiedAt": "2023-09-13T15:45:33.287Z", + "createdAt": "2022-09-16T16:21:25.023Z", + "lastModifiedAt": "2022-09-30T15:33:30.556Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "name": "Desktops", + "description": "Desktops", + "classifier": "Complex", + "attributes": [ + { + "name": "config", + "label": { + "en-US": "Config" + }, + "inputTip": { + "en-US": "device configuration" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "Unique", + "isSearchable": true, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + } + ], + "key": "desktops" + }, + { + "id": "7c8a90ff-4d2d-457e-afcf-0d6330276d0c", + "version": 61, + "versionModifiedAt": "2024-05-08T22:30:23.566Z", + "createdAt": "2022-10-13T18:15:50.081Z", + "lastModifiedAt": "2024-05-08T22:30:23.566Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f372e4e3-4a11-469d-807a-d3622d00da99" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "name": "Default", + "description": "Default", + "classifier": "Complex", + "attributes": [ + { + "name": "prescription", + "label": { + "en-US": "isRX" + }, + "inputTip": { + "en-US": "Requires a prescription" + }, + "isRequired": false, + "type": { + "name": "boolean" + }, + "attributeConstraint": "SameForAll", + "isSearchable": true, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "manufacturer-number", + "label": { + "en-US": "Manufacturer Number" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "SameForAll", + "isSearchable": true, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "brand", + "label": { + "en-US": "Brand" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "enum", + "values": [ + { + "key": "wholesale", + "label": "Wholesale" + }, + { + "key": "privateLabel", + "label": "Private Label" + } + ] + }, + "attributeConstraint": "SameForAll", + "isSearchable": true, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "narcotic", + "label": { + "en-US": "isNarcotic" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "boolean" + }, + "attributeConstraint": "SameForAll", + "isSearchable": true, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "product-alert-text", + "label": { + "en-US": "Alert Text" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "None", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "salesRank", + "label": { + "en-US": "Sales Rank" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "number" + }, + "attributeConstraint": "SameForAll", + "isSearchable": true, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "taste", + "label": { + "en-US": "Taste" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "CombinationUnique", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "return-eligible", + "label": { + "fr": "", + "en-GB": "", + "de": "", + "en-US": "Return Eligible", + "fr-CA": "" + }, + "inputTip": { + "fr": "", + "en-GB": "", + "de": "", + "en-US": "", + "fr-CA": "" + }, + "isRequired": false, + "type": { + "name": "boolean" + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "variant-selector-attributes", + "label": { + "en-US": "Variant selector attributes" + }, + "inputTip": { + "en-US": "Set of ordered attribute names which is used for displaying variant selector in FE" + }, + "isRequired": false, + "type": { + "name": "set", + "elementType": { + "name": "text" + } + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "package-size", + "label": { + "en-US": "Package size" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "number" + }, + "attributeConstraint": "CombinationUnique", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "test-att-enum", + "label": { + "en-US": "Just a test att" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "enum", + "values": [ + { + "key": "Foo", + "label": "Bar" + }, + { + "key": "Foo1", + "label": "Bar1" + } + ] + }, + "attributeConstraint": "CombinationUnique", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "color", + "label": { + "en-US": "Color" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "enum", + "values": [ + { + "key": "gray", + "label": "Gray" + }, + { + "key": "blue", + "label": "Blue" + }, + { + "key": "green", + "label": "Green" + } + ] + }, + "attributeConstraint": "CombinationUnique", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "release-date", + "label": { + "en-US": "Release date" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "date" + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "subscription", + "label": { + "en-US": "Subscription" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "reference", + "referenceTypeId": "product" + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "fabric", + "label": { + "en-US": "Fabric" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "MultiLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "retailPrice", + "label": { + "en-US": "Retail Price" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "whyMade", + "label": { + "en-US": "Why we made this" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "MultiLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "care", + "label": { + "en-US": "Care" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "MultiLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "defaultVariant", + "label": { + "en-US": "Default Variant (for PLP)" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "attribute-product-item-weight", + "label": { + "en-US": "Item Weight" + }, + "inputTip": { + "en-US": "Item Weight" + }, + "isRequired": false, + "type": { + "name": "number" + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "size_l", + "label": { + "af": "", + "en-GB": "", + "en-US": "size", + "es-MX": "" + }, + "inputTip": { + "af": "", + "en-GB": "", + "en-US": "size", + "es-MX": "" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "CombinationUnique", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "configurable", + "label": { + "af": "", + "en-GB": "", + "en-US": "Configurable", + "es-MX": "" + }, + "inputTip": { + "af": "", + "en-GB": "", + "en-US": "", + "es-MX": "" + }, + "isRequired": false, + "type": { + "name": "boolean" + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "components", + "label": { + "af": "", + "en-GB": "", + "en-US": "Components", + "es-MX": "" + }, + "inputTip": { + "af": "", + "en-GB": "", + "en-US": "", + "es-MX": "" + }, + "isRequired": false, + "type": { + "name": "set", + "elementType": { + "name": "reference", + "referenceTypeId": "product" + } + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "alternative-product", + "label": { + "af": "", + "en-GB": "", + "en-US": "Alternatives", + "es-MX": "" + }, + "inputTip": { + "af": "", + "en-GB": "", + "en-US": "", + "es-MX": "" + }, + "isRequired": false, + "type": { + "name": "set", + "elementType": { + "name": "reference", + "referenceTypeId": "product" + } + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "minimo", + "label": { + "en-GB": "", + "en-US": "", + "es-MX": "Minimo" + }, + "inputTip": { + "en-GB": "", + "en-US": "", + "es-MX": "" + }, + "isRequired": false, + "type": { + "name": "number" + }, + "attributeConstraint": "None", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "Service", + "label": { + "en-GB": "", + "en-US": "Service", + "es-MX": "" + }, + "inputTip": { + "en-GB": "", + "en-US": "", + "es-MX": "" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "Unique", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + } + ], + "key": "default" + }, + { + "id": "a4eebec3-5060-48f0-a567-23b2734e3ef4", + "version": 15, + "versionModifiedAt": "2023-09-13T15:45:33.287Z", + "createdAt": "2022-11-08T13:04:36.007Z", + "lastModifiedAt": "2023-02-09T16:39:34.536Z", + "lastModifiedBy": { + "isPlatformClient": true + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "147fa1f6-e486-4d55-826a-dac81b0f17f3" + } + }, + "name": "Medical Supplies", + "description": "Medical Supplies", + "classifier": "Complex", + "attributes": [ + { + "name": "Manufacturer", + "label": { + "en-US": "Manufacturer" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": true, + "type": { + "name": "text" + }, + "attributeConstraint": "SameForAll", + "isSearchable": true, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "Measurement", + "label": { + "en-US": "Measurement" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "None", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "Usage", + "label": { + "en-US": "Usage" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "text" + }, + "attributeConstraint": "None", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "Haz_Mat", + "label": { + "en-US": "Hazardous Material" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": true, + "type": { + "name": "boolean" + }, + "attributeConstraint": "SameForAll", + "isSearchable": true, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "UoM", + "label": { + "en-US": "Unit of Measure" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": true, + "type": { + "name": "text" + }, + "attributeConstraint": "CombinationUnique", + "isSearchable": true, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "Color", + "label": { + "en-US": "Color" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "enum", + "values": [ + { + "key": "Blue", + "label": "Blue" + }, + { + "key": "White", + "label": "White" + }, + { + "key": "Clear", + "label": "Clear" + } + ] + }, + "attributeConstraint": "CombinationUnique", + "isSearchable": true, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + }, + { + "name": "subscription", + "label": { + "en-US": "Subscription" + }, + "inputTip": { + "en-US": "" + }, + "isRequired": false, + "type": { + "name": "reference", + "referenceTypeId": "product" + }, + "attributeConstraint": "SameForAll", + "isSearchable": false, + "inputHint": "SingleLine", + "displayGroup": "Other", + "level": "Variant" + } + ] + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/products/output-schema.ts b/typescript/src/shared/products/output-schema.ts index 9598229..5b34690 100644 --- a/typescript/src/shared/products/output-schema.ts +++ b/typescript/src/shared/products/output-schema.ts @@ -41,6 +41,7 @@ export const productsPagedSchema = z }) .strict(); -export const listProductsOutputSchema = productsSchema || productsPagedSchema; +export const listProductsOutputSchema = z.union([productsSchema, productsPagedSchema]); +export const readProductsOutputSchema = z.union([productsSchema, productsPagedSchema]); export const createProductOutputSchema = productsSchema; export const updateProductOutputSchema = productsSchema; diff --git a/typescript/src/shared/products/test/output-schema.test.ts b/typescript/src/shared/products/test/output-schema.test.ts new file mode 100644 index 0000000..f2ed3e3 --- /dev/null +++ b/typescript/src/shared/products/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + productsSchema, + productsPagedSchema, + readProductsOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Products Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = productsPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = productsSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = productsSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readProductsOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(productsSchema).toBeDefined(); + expect(readProductsOutputSchema).toBeDefined(); + expect(productsPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/products/test/output.data.json b/typescript/src/shared/products/test/output.data.json new file mode 100644 index 0000000..02f3f19 --- /dev/null +++ b/typescript/src/shared/products/test/output.data.json @@ -0,0 +1,1388 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 262, + "results": [ + { + "id": "ad47acd6-418d-4200-82a6-b6f4cc6805c3", + "version": 540, + "productType": { + "typeId": "product-type", + "id": "b1a8984a-fae1-49d7-9805-2d0c16e25092" + }, + "name": { + "en-US": "WeatherMaker® Single-Packaged Rooftop Units with EcoBlue™ Technology\n50FC" + }, + "description": { + "en-US": "Electric Heat / Electric Cooling & Cooling Only with Ecoblue™ Technology\n3 to 6 Nominal Tons\n\nExclusive, new EcoBlue™ Technology was designed to improve performance and efficiency while decreasing maintenance and installation costs. The industry’s first beltless direct-drive vane axial fan for rooftop units* is just one of many technological advances that prove that not all rooftop units are created equal. Other enhancements include a new control board and coil technology, permanently lubricated motor bearings, tool-less filter access doors and more – all available on this multiefficiency offering.\n\n*Available on select models", + "en-GB": "test" + }, + "categories": [ + { + "typeId": "category", + "id": "3d0257c8-2598-48db-922a-9f568eb449cf" + } + ], + "categoryOrderHints": {}, + "slug": { + "en-US": "50fc" + }, + "masterVariant": { + "id": 1, + "sku": "50fc-1", + "prices": [ + { + "id": "eac4e22b-a38b-4aa5-9d2c-0956dd830197", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 9999998, + "fractionDigits": 2 + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 9799998, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + }, + { + "id": "0e018c8f-8ea4-4f50-aad4-3561ad999f39", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 49999995, + "fractionDigits": 2 + }, + "country": "MX", + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 48999995, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + } + ], + "images": [ + { + "url": "https://images.carriercms.com/image/upload/w_1280,q_auto,f_auto/v1547744612/carrier/commercial-hvac/products/packaged-outdoor/carrier-50fc-single-packaged-rooftop-a.jpg", + "dimensions": { + "w": 0, + "h": 0 + } + } + ], + "attributes": [ + { + "name": "size", + "value": 3 + }, + { + "name": "variant-selector-attributes", + "value": [ + "size" + ] + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 919, + "version": 3, + "id": "892bded4-60d4-43b6-ba9a-84930826ce90", + "channels": { + "d5bbd9cd-db6a-4dd6-9bdb-e79c5109dcc4": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 695, + "version": 3, + "id": "fb47f021-2d3d-426d-a9b9-b6fa38f641fb" + }, + "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 908, + "version": 3, + "id": "091c6cc0-9246-4ecf-872a-24031c761a02" + }, + "d902cb4e-e0f1-47e3-87c3-871e483c528d": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 242, + "version": 3, + "id": "a09f4fee-e43f-4028-a71c-5902226db22d" + }, + "25d4298e-477b-4743-a19c-0e7df6856ed8": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 826, + "version": 1, + "id": "289d634e-bae1-4b8f-bf8f-2a434c768ab4" + }, + "02bc4d74-7daa-4e48-badf-2e5ffd9c1a38": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 151, + "version": 3, + "id": "3a38eb7a-f02e-48e9-b1aa-a5fca2a86c0b" + }, + "94f0286e-c720-400e-aff8-5e41422309d9": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 296, + "version": 3, + "id": "4d91937d-e2ae-4237-9a08-a2000007db15" + }, + "73298866-5cf5-4718-978f-e83563647e87": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 413, + "version": 1, + "id": "5a8cd8de-2f30-47c2-b33d-5b4e839a4928" + }, + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 174, + "version": 3, + "id": "ec11f2cf-e8ec-4c50-bce8-98d2a010276b" + }, + "528e6fbb-47b5-4aa6-9add-cd869921332c": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 250, + "version": 3, + "id": "80dbe29a-e031-436a-a670-1fd60de75518" + }, + "79e9cbbe-024a-4d3c-bad4-ba4e521f2e39": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 975, + "version": 3, + "id": "7d832ea4-f511-4edb-a4e5-d856fbf4dda2" + }, + "5e62a55f-4b4e-4bea-ad42-273b378050e5": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 542, + "version": 3, + "id": "36f8cabc-4a23-4a75-8152-e39aad73d2b7" + }, + "e8004306-debf-43ab-a1b3-431336c54449": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 250, + "version": 3, + "id": "41f5f252-223b-4964-b007-8ac4cffc070c" + }, + "5c2efb2f-71ba-4c3c-8a78-b9105b757189": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 1068, + "version": 3, + "id": "54980cff-9a69-47d3-a257-aca16e301be6" + }, + "c3a700cf-76b7-4a63-a139-71680ac0e920": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 349, + "version": 1, + "id": "d9b62ac5-9d15-43bb-8c7f-f2b6c12be9e4" + } + } + } + }, + "variants": [ + { + "id": 2, + "sku": "50fc-2", + "prices": [ + { + "id": "aab7858e-bc22-4832-a6b7-4a7343ead90a", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 9999999, + "fractionDigits": 2 + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 9799999, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + }, + { + "id": "7f005dfa-b99b-4428-b937-e121e27aeacf", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 49999995, + "fractionDigits": 2 + }, + "country": "MX", + "channel": { + "typeId": "channel", + "id": "94f0286e-c720-400e-aff8-5e41422309d9" + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 48999995, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + } + ], + "images": [ + { + "url": "https://images.carriercms.com/image/upload/w_1280,q_auto,f_auto/v1547744612/carrier/commercial-hvac/products/packaged-outdoor/carrier-50fc-single-packaged-rooftop-a.jpg", + "dimensions": { + "w": 0, + "h": 0 + } + } + ], + "attributes": [ + { + "name": "size", + "value": 4 + }, + { + "name": "variant-selector-attributes", + "value": [ + "size" + ] + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 954, + "version": 3, + "id": "b5d6098f-8dd7-4c40-bed9-b6c1ee31cfc4", + "channels": { + "d5bbd9cd-db6a-4dd6-9bdb-e79c5109dcc4": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 466, + "version": 3, + "id": "fd42ec37-5ed6-4bdc-8024-8271760191dd" + }, + "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 464, + "version": 3, + "id": "c036434f-19d5-44a5-8c1e-ee2242845843" + }, + "d902cb4e-e0f1-47e3-87c3-871e483c528d": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 523, + "version": 3, + "id": "a5fed892-c3da-4055-9d92-6be92db4596a" + }, + "25d4298e-477b-4743-a19c-0e7df6856ed8": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 597, + "version": 1, + "id": "9d8d2897-391a-40dd-8de2-f9511a6e3c32" + }, + "02bc4d74-7daa-4e48-badf-2e5ffd9c1a38": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 790, + "version": 3, + "id": "26687de9-0fd8-4b92-8029-8d765d536c49" + }, + "94f0286e-c720-400e-aff8-5e41422309d9": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 648, + "version": 3, + "id": "c9054447-507f-4e53-a573-c81e80a1bf51" + }, + "73298866-5cf5-4718-978f-e83563647e87": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 569, + "version": 1, + "id": "209571c5-4da7-4046-95e6-91674d4ae367" + }, + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 225, + "version": 3, + "id": "6722408c-b25e-4f84-96af-4ad45614ec51" + }, + "528e6fbb-47b5-4aa6-9add-cd869921332c": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 328, + "version": 3, + "id": "049a4ab0-6ffa-43fe-8a58-9f384fc5e7fc" + }, + "79e9cbbe-024a-4d3c-bad4-ba4e521f2e39": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 874, + "version": 3, + "id": "ae66aebb-130b-43e7-b61e-1a3a20de1c89" + }, + "5e62a55f-4b4e-4bea-ad42-273b378050e5": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 997, + "version": 3, + "id": "4e70357d-8819-41a9-a162-0e939d4bfba5" + }, + "e8004306-debf-43ab-a1b3-431336c54449": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 711, + "version": 3, + "id": "b0d086d9-d53a-428d-b7d9-b5605237d9f0" + }, + "5c2efb2f-71ba-4c3c-8a78-b9105b757189": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 616, + "version": 3, + "id": "b270b6a0-dff7-45ca-9059-dada0bb594c3" + }, + "c3a700cf-76b7-4a63-a139-71680ac0e920": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 1087, + "version": 1, + "id": "dff68446-d73b-4248-a388-19c13244ab44" + } + } + } + }, + { + "id": 3, + "sku": "50fc-3", + "prices": [ + { + "id": "f26bf9a4-6e31-4292-8a04-7db1299c7858", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 9999999, + "fractionDigits": 2 + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 9799999, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + }, + { + "id": "474d9184-10f5-4096-8636-f247eaf42e49", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 49999995, + "fractionDigits": 2 + }, + "country": "MX", + "channel": { + "typeId": "channel", + "id": "94f0286e-c720-400e-aff8-5e41422309d9" + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 48999995, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + } + ], + "images": [ + { + "url": "https://images.carriercms.com/image/upload/w_1280,q_auto,f_auto/v1547744612/carrier/commercial-hvac/products/packaged-outdoor/carrier-50fc-single-packaged-rooftop-a.jpg", + "dimensions": { + "w": 0, + "h": 0 + } + } + ], + "attributes": [ + { + "name": "size", + "value": 5 + }, + { + "name": "variant-selector-attributes", + "value": [ + "size" + ] + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 168, + "version": 3, + "id": "cf59a79b-59d8-43a8-a62a-0ede665558ae", + "channels": { + "d5bbd9cd-db6a-4dd6-9bdb-e79c5109dcc4": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 828, + "version": 3, + "id": "98d61699-4461-45a8-b5fd-fc1ce5c92479" + }, + "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 163, + "version": 3, + "id": "c8f35046-e3df-4c47-954b-83823f108007" + }, + "d902cb4e-e0f1-47e3-87c3-871e483c528d": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 485, + "version": 3, + "id": "3eba477a-78bc-4f13-8675-70d993e76999" + }, + "25d4298e-477b-4743-a19c-0e7df6856ed8": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 475, + "version": 1, + "id": "01d22d80-3082-49d8-83ec-6a8794ff3482" + }, + "02bc4d74-7daa-4e48-badf-2e5ffd9c1a38": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 320, + "version": 3, + "id": "83bff2c8-f713-42f9-a9c7-b1f5e1dc6969" + }, + "94f0286e-c720-400e-aff8-5e41422309d9": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 133, + "version": 3, + "id": "ae12b668-92af-4b8a-90f5-5bccb5336a7d" + }, + "73298866-5cf5-4718-978f-e83563647e87": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 727, + "version": 1, + "id": "7e15dc70-71d8-4029-a4e4-15355d6b096f" + }, + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 594, + "version": 3, + "id": "22e7b991-cb27-4828-a9b7-fbdf7e03926d" + }, + "528e6fbb-47b5-4aa6-9add-cd869921332c": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 430, + "version": 3, + "id": "f8c83f3f-1d36-4a96-a6e3-f15e02a5b0e7" + }, + "79e9cbbe-024a-4d3c-bad4-ba4e521f2e39": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 544, + "version": 3, + "id": "2db98ee0-178b-4ee8-9149-84c688242d2a" + }, + "5e62a55f-4b4e-4bea-ad42-273b378050e5": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 110, + "version": 3, + "id": "a4eb62f7-1f8b-49b6-bec5-150b1fe35014" + }, + "e8004306-debf-43ab-a1b3-431336c54449": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 528, + "version": 3, + "id": "b9a933db-029c-4fe9-82af-76254dbebfb2" + }, + "5c2efb2f-71ba-4c3c-8a78-b9105b757189": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 474, + "version": 3, + "id": "70817d70-05d9-497e-ac0a-354fa4997d76" + }, + "c3a700cf-76b7-4a63-a139-71680ac0e920": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 478, + "version": 1, + "id": "b6243ef5-71c9-482c-9b61-62959d8884b7" + } + } + } + }, + { + "id": 4, + "sku": "50fc-4", + "prices": [ + { + "id": "75f9a6f9-5509-427d-b982-56b2c866542a", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 9999999, + "fractionDigits": 2 + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 9799999, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + }, + { + "id": "3562c773-5993-4a79-aaae-9c0434273388", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 49999995, + "fractionDigits": 2 + }, + "country": "MX", + "channel": { + "typeId": "channel", + "id": "94f0286e-c720-400e-aff8-5e41422309d9" + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 48999995, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + } + ], + "images": [ + { + "url": "https://images.carriercms.com/image/upload/w_1280,q_auto,f_auto/v1547744612/carrier/commercial-hvac/products/packaged-outdoor/carrier-50fc-single-packaged-rooftop-a.jpg", + "dimensions": { + "w": 0, + "h": 0 + } + } + ], + "attributes": [ + { + "name": "size", + "value": 6 + }, + { + "name": "variant-selector-attributes", + "value": [ + "size" + ] + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 228, + "version": 3, + "id": "e3891d12-6709-4647-923d-9a0dbb1d4428", + "channels": { + "d5bbd9cd-db6a-4dd6-9bdb-e79c5109dcc4": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 538, + "version": 3, + "id": "3a78e5a4-c236-4e90-8013-eff213652b00" + }, + "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 863, + "version": 3, + "id": "34aa8cc3-14b6-4ebd-a24f-2d472ca36ad8" + }, + "d902cb4e-e0f1-47e3-87c3-871e483c528d": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 1079, + "version": 3, + "id": "13e88cdf-b481-469a-90eb-d128a1270548" + }, + "25d4298e-477b-4743-a19c-0e7df6856ed8": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 662, + "version": 1, + "id": "6927879c-9b9c-45cc-bec5-1115d090c0a2" + }, + "02bc4d74-7daa-4e48-badf-2e5ffd9c1a38": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 570, + "version": 3, + "id": "33afe95e-241e-4951-9fd1-75ddcecda339" + }, + "94f0286e-c720-400e-aff8-5e41422309d9": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 517, + "version": 3, + "id": "0c9aaa07-eef8-42fe-9b2f-e3b93e1c22ea" + }, + "73298866-5cf5-4718-978f-e83563647e87": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 1063, + "version": 1, + "id": "6f06c4a8-60ff-4a36-9ff7-39f155f088aa" + }, + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 781, + "version": 3, + "id": "63bc75f5-6a06-4351-9a61-b613b77790da" + }, + "528e6fbb-47b5-4aa6-9add-cd869921332c": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 1047, + "version": 3, + "id": "c55de16d-bd18-449b-a014-425230d7e92e" + }, + "79e9cbbe-024a-4d3c-bad4-ba4e521f2e39": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 494, + "version": 3, + "id": "5a56e3d0-3a0c-4779-bf00-8dfc4fb2ee7d" + }, + "5e62a55f-4b4e-4bea-ad42-273b378050e5": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 565, + "version": 3, + "id": "8b7c507f-1c1e-4193-ad5e-8f1ab417b9d8" + }, + "e8004306-debf-43ab-a1b3-431336c54449": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 993, + "version": 3, + "id": "21403ab4-cb62-43c9-a0ba-f6a16a4c5510" + }, + "5c2efb2f-71ba-4c3c-8a78-b9105b757189": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 981, + "version": 3, + "id": "8460cad8-b385-4a6c-a007-aa2434612fdb" + }, + "c3a700cf-76b7-4a63-a139-71680ac0e920": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 239, + "version": 1, + "id": "ec67e435-14d8-4328-826d-633c957abac2" + } + } + } + } + ], + "searchKeywords": {}, + "attributes": [], + "hasStagedChanges": false, + "published": true, + "key": "50fc", + "taxCategory": { + "typeId": "tax-category", + "id": "1aba7f86-aa97-4649-8cac-fcde18798699" + }, + "priceMode": "Embedded", + "createdAt": "2023-05-25T16:04:11.055Z", + "lastModifiedAt": "2024-11-28T14:38:14.922Z" + }, + { + "id": "1f078064-a184-4a00-bc08-79cf47d2bec1", + "version": 84, + "productType": { + "typeId": "product-type", + "id": "b8d9e350-5a7d-41ce-9c39-8ed263c98cb9" + }, + "name": { + "en-US": "GS1 Class with Volume Pricing" + }, + "description": { + "en-US": "This is an important class" + }, + "categories": [ + { + "typeId": "category", + "id": "99aed617-e242-4c2f-91a3-69ce77d88ef1" + }, + { + "typeId": "category", + "id": "08c26d69-314c-4672-8406-1d9a67634bc2" + } + ], + "categoryOrderHints": {}, + "slug": { + "en-US": "gs1-class-with-volume-pricing" + }, + "metaTitle": { + "en-US": "", + "af": "" + }, + "metaDescription": { + "en-US": "", + "af": "" + }, + "masterVariant": { + "id": 1, + "sku": "class1", + "key": "class1", + "prices": [ + { + "id": "6060b569-6f16-45a0-9258-daf1c3264cea", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 40015, + "fractionDigits": 2 + }, + "country": "US", + "channel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 39215, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + }, + { + "id": "14500a42-fbbf-442d-bfff-128edea9bfaa", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 200000, + "fractionDigits": 2 + }, + "country": "MX", + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 196000, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + }, + { + "id": "b0d82290-c906-4194-9f81-02768bd55c7c", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 3500, + "fractionDigits": 2 + }, + "country": "US", + "channel": { + "typeId": "channel", + "id": "94f0286e-c720-400e-aff8-5e41422309d9" + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 3430, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/class-49UCqOYR.jpg", + "dimensions": { + "w": 212, + "h": 140 + } + } + ], + "attributes": [ + { + "name": "seats", + "value": 2 + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 1042, + "version": 11, + "id": "bb9420d6-8996-40f1-8767-f61dd8e33e34", + "channels": { + "d5bbd9cd-db6a-4dd6-9bdb-e79c5109dcc4": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 773, + "version": 1, + "id": "0ec41d5a-0635-4be3-98e5-addb06bd18b9" + }, + "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 545, + "version": 1, + "id": "89bf0e4b-e603-4b1f-8270-f3e70f6c8fa8" + }, + "d902cb4e-e0f1-47e3-87c3-871e483c528d": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 890, + "version": 1, + "id": "89cc6472-ed1b-4599-a7ec-98cf4cca6d4c" + }, + "25d4298e-477b-4743-a19c-0e7df6856ed8": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 872, + "version": 1, + "id": "7f26e7cf-c4ba-49f8-a94e-4bc86f1c727b" + }, + "02bc4d74-7daa-4e48-badf-2e5ffd9c1a38": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 355, + "version": 1, + "id": "0916c47d-7774-4c00-bc2b-14a5cc921eb0" + }, + "94f0286e-c720-400e-aff8-5e41422309d9": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 964, + "version": 1, + "id": "1ce78cf3-7009-4efe-878d-75a6e28487d8" + }, + "73298866-5cf5-4718-978f-e83563647e87": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 169, + "version": 1, + "id": "2679cb97-95a5-4f7d-998a-327686f21f8e" + }, + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 845, + "version": 1, + "id": "be102f2b-4830-4256-9472-1bbd0ceb67ea" + }, + "528e6fbb-47b5-4aa6-9add-cd869921332c": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 953, + "version": 1, + "id": "db88edea-0b29-4d24-b98c-fc6cdeff2c50" + }, + "79e9cbbe-024a-4d3c-bad4-ba4e521f2e39": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 822, + "version": 1, + "id": "6bcf9033-3a61-4d44-a6fe-ff694c7d4b64" + }, + "5e62a55f-4b4e-4bea-ad42-273b378050e5": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 959, + "version": 1, + "id": "e651982b-e1b6-4ea4-85d0-96f60248d52a" + }, + "e8004306-debf-43ab-a1b3-431336c54449": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 205, + "version": 1, + "id": "164897f5-edd4-40f2-ab38-0bd8892cdf8f" + }, + "5c2efb2f-71ba-4c3c-8a78-b9105b757189": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 156, + "version": 1, + "id": "f9613d49-d178-4cdd-b22c-364efcc4b217" + }, + "c3a700cf-76b7-4a63-a139-71680ac0e920": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 731, + "version": 1, + "id": "6261580a-ffff-4ece-befd-022bed9d80a5" + } + } + } + }, + "variants": [], + "searchKeywords": {}, + "attributes": [], + "hasStagedChanges": true, + "published": true, + "key": "gs1cl", + "taxCategory": { + "typeId": "tax-category", + "id": "1aba7f86-aa97-4649-8cac-fcde18798699" + }, + "priceMode": "Embedded", + "createdAt": "2023-05-08T18:35:37.492Z", + "lastModifiedAt": "2024-10-07T17:46:25.436Z" + }, + { + "id": "3d02d683-3f86-4f00-b144-97d67f339f80", + "version": 100, + "productType": { + "typeId": "product-type", + "id": "e524d54b-17d4-4eb1-855a-107f6e46fe40" + }, + "name": { + "en-US": "Date" + }, + "description": { + "en-US": "asdas" + }, + "categories": [], + "categoryOrderHints": {}, + "slug": { + "en-US": "date" + }, + "metaTitle": { + "en-US": "", + "af": "" + }, + "metaDescription": { + "en-US": "", + "af": "" + }, + "masterVariant": { + "id": 1, + "sku": "15/4/2023", + "prices": [ + { + "id": "acb3bc36-dd99-4afd-a0c7-3b2989ca771e", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2380, + "fractionDigits": 2 + }, + "country": "US", + "channel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2332, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + }, + { + "id": "87b0f427-6178-4fac-9b7f-874228049fb2", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 0, + "fractionDigits": 2 + }, + "country": "MX", + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 0, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + } + ], + "images": [], + "attributes": [], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 779, + "version": 3, + "id": "ac8502ab-b468-45e6-8ad5-ff142d65367f", + "channels": { + "d5bbd9cd-db6a-4dd6-9bdb-e79c5109dcc4": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 1070, + "version": 1, + "id": "1df98677-5dac-486c-b227-f8efd3727af5" + }, + "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 779, + "version": 1, + "id": "11482d1a-3f26-4c19-81f2-a1fc4c1b54df" + }, + "d902cb4e-e0f1-47e3-87c3-871e483c528d": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 287, + "version": 1, + "id": "d93f2ab0-56ce-4f06-a2a7-6cfe821b4cc9" + }, + "25d4298e-477b-4743-a19c-0e7df6856ed8": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 299, + "version": 1, + "id": "901bf483-89ad-4350-9126-c22c8e9a07f8" + }, + "02bc4d74-7daa-4e48-badf-2e5ffd9c1a38": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 797, + "version": 1, + "id": "d341c07c-8817-4f9a-8640-9beaa7b18954" + }, + "94f0286e-c720-400e-aff8-5e41422309d9": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 849, + "version": 1, + "id": "a3021977-5857-4fe6-9a0b-863cdeace14f" + }, + "73298866-5cf5-4718-978f-e83563647e87": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 1003, + "version": 1, + "id": "45b91240-9c98-40a5-8d1c-246550d47adb" + }, + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 680, + "version": 1, + "id": "6bd2d82e-7acd-4202-b723-ee2818843ac8" + }, + "528e6fbb-47b5-4aa6-9add-cd869921332c": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 346, + "version": 1, + "id": "ba9e021a-b824-41c3-880e-bc8bf0a8e576" + }, + "79e9cbbe-024a-4d3c-bad4-ba4e521f2e39": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 610, + "version": 1, + "id": "4f357dd4-c406-49ff-8f8a-61b0d75f932d" + }, + "5e62a55f-4b4e-4bea-ad42-273b378050e5": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 957, + "version": 1, + "id": "95734773-7f4b-493e-b93b-0c5b7b8eef4e" + }, + "e8004306-debf-43ab-a1b3-431336c54449": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 565, + "version": 1, + "id": "e8c355d6-29a6-4d5d-96f2-7fd43e7a2da7" + }, + "5c2efb2f-71ba-4c3c-8a78-b9105b757189": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 418, + "version": 1, + "id": "a6f34b9e-9e7d-4fcc-bb3c-1a4e5abc7b66" + }, + "c3a700cf-76b7-4a63-a139-71680ac0e920": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 504, + "version": 1, + "id": "1ac535f1-1305-4b2b-845a-dfccfa4ad425" + } + } + } + }, + "variants": [ + { + "id": 2, + "sku": "30/5/2023", + "prices": [ + { + "id": "0135b8fe-f9a5-4891-b736-b91f5500d654", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 500, + "fractionDigits": 2 + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 490, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + }, + { + "id": "2a846a70-0ef3-4d74-9f6f-0f37bef9f0ab", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 2500, + "fractionDigits": 2 + }, + "country": "MX", + "channel": { + "typeId": "channel", + "id": "94f0286e-c720-400e-aff8-5e41422309d9" + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 2450, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + } + } + ], + "images": [], + "attributes": [], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 294, + "version": 3, + "id": "30fc66c1-b19d-4c7b-b208-5612d1c96cb1", + "channels": { + "d5bbd9cd-db6a-4dd6-9bdb-e79c5109dcc4": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 699, + "version": 1, + "id": "0a13500b-aa93-40c7-a751-6f89e9d51a4f" + }, + "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 357, + "version": 1, + "id": "987e5f35-6de5-4648-95c0-61dcaafe2e85" + }, + "d902cb4e-e0f1-47e3-87c3-871e483c528d": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 166, + "version": 1, + "id": "eec78c71-96ce-4579-b397-96205eb597d7" + }, + "25d4298e-477b-4743-a19c-0e7df6856ed8": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 534, + "version": 1, + "id": "22a90e25-47b3-4a88-964d-5fce81f5f251" + }, + "02bc4d74-7daa-4e48-badf-2e5ffd9c1a38": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 1087, + "version": 1, + "id": "a74677d8-51ff-43f9-8229-238076b73e04" + }, + "94f0286e-c720-400e-aff8-5e41422309d9": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 270, + "version": 1, + "id": "abf78ba5-8908-4a0e-9a53-0b6cd00197ad" + }, + "73298866-5cf5-4718-978f-e83563647e87": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 398, + "version": 1, + "id": "dbb98ac7-7c9b-478e-8ccd-402a6a60351d" + }, + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 608, + "version": 1, + "id": "58e2e7ae-3ac8-4ac1-9b5b-d98a7d6e97a2" + }, + "528e6fbb-47b5-4aa6-9add-cd869921332c": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 484, + "version": 1, + "id": "b8e05880-da15-43dd-9ba9-e56d62475c59" + }, + "79e9cbbe-024a-4d3c-bad4-ba4e521f2e39": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 841, + "version": 1, + "id": "a0253469-f5b5-4e61-89f3-e537f97c389a" + }, + "5e62a55f-4b4e-4bea-ad42-273b378050e5": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 534, + "version": 1, + "id": "7e76543a-4ef5-4d19-b552-88ab48dcf24f" + }, + "e8004306-debf-43ab-a1b3-431336c54449": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 733, + "version": 1, + "id": "4e3ea033-91c1-4cae-92cc-3b6abc8a52a8" + }, + "5c2efb2f-71ba-4c3c-8a78-b9105b757189": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 779, + "version": 1, + "id": "ce341182-f5f3-43f9-bfa9-efc6004b2ef9" + }, + "c3a700cf-76b7-4a63-a139-71680ac0e920": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 599, + "version": 1, + "id": "a2f48a01-7dc4-4d57-8ef2-8a481f062ad7" + } + } + } + } + ], + "searchKeywords": {}, + "attributes": [], + "hasStagedChanges": false, + "published": true, + "taxCategory": { + "typeId": "tax-category", + "id": "1aba7f86-aa97-4649-8cac-fcde18798699" + }, + "priceMode": "Embedded", + "createdAt": "2023-05-04T19:39:06.500Z", + "lastModifiedAt": "2024-10-07T17:46:25.357Z" + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/project/test/output-schema.test.ts b/typescript/src/shared/project/test/output-schema.test.ts new file mode 100644 index 0000000..f0ee93d --- /dev/null +++ b/typescript/src/shared/project/test/output-schema.test.ts @@ -0,0 +1,45 @@ +import { + projectSchema, + + readProjectOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Project Output Schema', () => { + describe('Entity Schema', () => { + it('should validate real API response', () => { + const result = projectSchema.passthrough().safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required fields', () => { + expect(outputData).toBeDefined(); + expect(outputData).not.toBeNull(); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate entity response', () => { + const result = readProjectOutputSchema.passthrough().safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(projectSchema).toBeDefined(); + expect(readProjectOutputSchema).toBeDefined(); + + }); + }); +}); diff --git a/typescript/src/shared/project/test/output.data.json b/typescript/src/shared/project/test/output.data.json new file mode 100644 index 0000000..53c190a --- /dev/null +++ b/typescript/src/shared/project/test/output.data.json @@ -0,0 +1,98 @@ +{ + "key": "composable-b2b-demo", + "name": "composable b2b demo", + "countries": [ + "US", + "MX" + ], + "currencies": [ + "USD", + "EUR", + "MXN", + "CRC" + ], + "languages": [ + "en-US", + "es-MX", + "en-GB" + ], + "createdAt": "2022-09-14T18:31:46.647Z", + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "lastModifiedAt": "2025-11-14T12:48:40.438Z", + "lastModifiedBy": { + "isPlatformClient": true + }, + "messages": { + "enabled": false, + "deleteDaysAfterCreation": 15 + }, + "carts": { + "deleteDaysAfterLastModification": 90, + "allowAddingUnpublishedProducts": false, + "countryTaxRateFallbackEnabled": false, + "cartDiscountCache": { + "enabled": false + }, + "totalPriceDiscountDoesNotReduceExternalTax": false, + "loadParsedDiscountsEnabled": false, + "taxRoundingMode": "HalfEven", + "priceRoundingMode": "HalfEven" + }, + "shoppingLists": { + "deleteDaysAfterLastModification": 360 + }, + "version": 82, + "searchIndexing": { + "products": { + "status": "Activated", + "lastModifiedAt": "2022-09-15T17:33:19.594Z", + "lastModifiedBy": { + "isPlatformClient": true + } + }, + "productsSearch": { + "status": "Activated", + "lastModifiedAt": "2024-04-19T18:35:40.458Z", + "lastModifiedBy": { + "isPlatformClient": true + } + }, + "orders": { + "status": "Deactivated", + "lastModifiedAt": "2025-11-14T12:48:40.436Z", + "lastModifiedBy": { + "isPlatformClient": true + } + }, + "customers": { + "status": "Deactivated", + "lastModifiedAt": "2025-11-09T09:00:07.676Z", + "lastModifiedBy": { + "isPlatformClient": true + } + }, + "businessUnits": { + "status": "Activated", + "lastModifiedAt": "2025-07-18T15:53:29.168Z", + "lastModifiedBy": { + "isPlatformClient": true + } + } + }, + "businessUnits": { + "myBusinessUnitStatusOnCreation": "Active" + }, + "discounts": { + "productVsCartDiscountCombination": "Stacking", + "discountCombinationMode": "Stacking" + }, + "inventory": { + "releaseExpiredReservations": true + } +} \ No newline at end of file diff --git a/typescript/src/shared/quote-request/output-schema.ts b/typescript/src/shared/quote-request/output-schema.ts index 6540c0c..f6864b3 100644 --- a/typescript/src/shared/quote-request/output-schema.ts +++ b/typescript/src/shared/quote-request/output-schema.ts @@ -51,7 +51,6 @@ export const quoteRequestPagedSchema = z }) .strict(); -export const readQuoteRequestOutputSchema = - quoteRequestSchema || quoteRequestPagedSchema; +export const readQuoteRequestOutputSchema = z.union([quoteRequestSchema, quoteRequestPagedSchema]); export const createQuoteRequestOutputSchema = quoteRequestSchema; export const updateQuoteRequestOutputSchema = quoteRequestSchema; diff --git a/typescript/src/shared/quote-request/test/output-schema.test.ts b/typescript/src/shared/quote-request/test/output-schema.test.ts new file mode 100644 index 0000000..10f105e --- /dev/null +++ b/typescript/src/shared/quote-request/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + quoteRequestSchema, + quoteRequestPagedSchema, + readQuoteRequestOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('QuoteRequest Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = quoteRequestPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = quoteRequestSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = quoteRequestSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readQuoteRequestOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(quoteRequestSchema).toBeDefined(); + expect(readQuoteRequestOutputSchema).toBeDefined(); + expect(quoteRequestPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/quote-request/test/output.data.json b/typescript/src/shared/quote-request/test/output.data.json new file mode 100644 index 0000000..badbb0b --- /dev/null +++ b/typescript/src/shared/quote-request/test/output.data.json @@ -0,0 +1,1495 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 63, + "results": [ + { + "id": "d57f5d52-822d-4919-a6e4-0245acef4d80", + "version": 2, + "versionModifiedAt": "2024-02-14T21:05:50.546Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2024-02-14T21:05:29.723Z", + "lastModifiedAt": "2024-02-14T21:05:50.546Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "createdBy": { + "clientId": "1eyVB5_tTzMDPwSxppod3eyZ", + "isPlatformClient": false, + "associate": { + "typeId": "customer", + "id": "55937787-4eb1-43a7-9065-fac78a757e90" + } + }, + "quoteRequestState": "Accepted", + "comment": "5% discount", + "customer": { + "typeId": "customer", + "id": "55937787-4eb1-43a7-9065-fac78a757e90" + }, + "lineItems": [ + { + "id": "153ceddc-6c9a-4db0-ace4-2da1437d54b9", + "productId": "b738be74-941f-4f4f-9d2a-07304eef8c1a", + "productKey": "xps-15", + "productType": { + "typeId": "product-type", + "id": "d284835b-6d15-497f-ac59-59381951494f", + "version": 7 + }, + "productSlug": { + "en-US": "xps-15-laptop" + }, + "name": { + "en-US": "XPS 15 Laptop" + }, + "variant": { + "id": 1, + "sku": "xps-15", + "key": "xps-15", + "prices": [ + { + "id": "b9e33c10-4af1-4591-b300-80ec7a09b1e0", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 89999, + "fractionDigits": 2 + } + }, + { + "id": "8ca1a382-e441-4554-aeac-4cdf7669876c", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 1640000, + "fractionDigits": 2 + } + }, + { + "id": "5bf17a0c-c72b-42e7-a208-3dc855888f00", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 79999, + "fractionDigits": 2 + }, + "channel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + }, + "tiers": [ + { + "minimumQuantity": 10, + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 69999, + "fractionDigits": 2 + } + } + ] + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/Screenshot%202023-04-1-KqT3Xyq6.png", + "dimensions": { + "w": 569, + "h": 413 + } + } + ], + "attributes": [ + { + "name": "components", + "value": [ + { + "typeId": "product", + "id": "dcce0343-0288-425b-ac48-6567642a112a" + }, + { + "typeId": "product", + "id": "586d4aa7-99ac-44ca-b361-cbeaea55e9f2" + }, + { + "typeId": "product", + "id": "23410ba0-0a67-48a9-8e6d-2bfb7a9c555c" + }, + { + "typeId": "product", + "id": "b595608e-4b31-4d3a-9650-843191ec9daa" + }, + { + "typeId": "product", + "id": "1cc79ac5-59e7-4407-b0bd-78dc2b72b56e" + } + ] + }, + { + "name": "salesRank", + "value": 100 + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 479, + "version": 19, + "id": "dd232ed2-6162-4010-a0cd-9d7c786bcb9b", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 347, + "version": 1, + "id": "4b317d0a-916d-4122-9a66-8784d6a6d0d3" + } + } + } + }, + "price": { + "id": "b9e33c10-4af1-4591-b300-80ec7a09b1e0", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 89999, + "fractionDigits": 2 + } + }, + "quantity": 10, + "discountedPricePerQuantity": [], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T21:05:20.928Z", + "lastModifiedAt": "2024-02-14T21:05:20.928Z", + "state": [ + { + "quantity": 10, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 899990, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 899990, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 989989, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 89999, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + } + ], + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 899990, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 899990, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 989989, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 89999, + "fractionDigits": 2 + }, + "name": "10% incl." + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 89999, + "fractionDigits": 2 + } + }, + "country": "US", + "customLineItems": [], + "directDiscounts": [], + "inventoryMode": "ReserveOnOrder", + "priceRoundingMode": "HalfEven", + "taxMode": "Platform", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "billingAddress": { + "city": "Collinsville", + "country": "US" + }, + "itemShippingAddresses": [], + "shippingAddress": { + "city": "Collinsville", + "country": "US" + }, + "store": { + "typeId": "store", + "key": "hospital-pharmacy-mwd-54321" + }, + "businessUnit": { + "typeId": "business-unit", + "key": "abc-hospital-pharmacy-3" + }, + "cart": { + "typeId": "cart", + "id": "6c103e20-366e-43c6-8ea3-2438a04170e7" + } + }, + { + "id": "a2690ed8-5361-4be0-b881-d54a88af5314", + "version": 2, + "versionModifiedAt": "2024-02-14T21:08:20.505Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2024-02-14T21:07:56.885Z", + "lastModifiedAt": "2024-02-14T21:08:20.505Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "quoteRequestState": "Accepted", + "comment": "5% off", + "customer": { + "typeId": "customer", + "id": "55937787-4eb1-43a7-9065-fac78a757e90" + }, + "lineItems": [ + { + "id": "2aa15d0a-dff2-4f43-b822-37fbfdbae9ea", + "productId": "b738be74-941f-4f4f-9d2a-07304eef8c1a", + "productKey": "xps-15", + "productType": { + "typeId": "product-type", + "id": "d284835b-6d15-497f-ac59-59381951494f", + "version": 7 + }, + "productSlug": { + "en-US": "xps-15-laptop" + }, + "name": { + "en-US": "XPS 15 Laptop" + }, + "variant": { + "id": 1, + "sku": "xps-15", + "key": "xps-15", + "prices": [ + { + "id": "b9e33c10-4af1-4591-b300-80ec7a09b1e0", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 89999, + "fractionDigits": 2 + } + }, + { + "id": "8ca1a382-e441-4554-aeac-4cdf7669876c", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 1640000, + "fractionDigits": 2 + } + }, + { + "id": "5bf17a0c-c72b-42e7-a208-3dc855888f00", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 79999, + "fractionDigits": 2 + }, + "channel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + } + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/Screenshot%202023-04-1-KqT3Xyq6.png", + "dimensions": { + "w": 569, + "h": 413 + } + } + ], + "attributes": [ + { + "name": "components", + "value": [ + { + "typeId": "product", + "id": "dcce0343-0288-425b-ac48-6567642a112a" + }, + { + "typeId": "product", + "id": "586d4aa7-99ac-44ca-b361-cbeaea55e9f2" + }, + { + "typeId": "product", + "id": "23410ba0-0a67-48a9-8e6d-2bfb7a9c555c" + }, + { + "typeId": "product", + "id": "b595608e-4b31-4d3a-9650-843191ec9daa" + }, + { + "typeId": "product", + "id": "1cc79ac5-59e7-4407-b0bd-78dc2b72b56e" + } + ] + }, + { + "name": "salesRank", + "value": 100 + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 479, + "version": 19, + "id": "dd232ed2-6162-4010-a0cd-9d7c786bcb9b", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 347, + "version": 1, + "id": "4b317d0a-916d-4122-9a66-8784d6a6d0d3" + } + } + } + }, + "price": { + "id": "5bf17a0c-c72b-42e7-a208-3dc855888f00", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 69999, + "fractionDigits": 2 + }, + "channel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + }, + "tiers": [ + { + "minimumQuantity": 10, + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 69999, + "fractionDigits": 2 + } + } + ] + }, + "quantity": 10, + "discountedPricePerQuantity": [], + "supplyChannel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + }, + "distributionChannel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + }, + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T20:38:35.846Z", + "lastModifiedAt": "2024-02-14T20:41:50.273Z", + "state": [ + { + "quantity": 10, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 699990, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 699990, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 769989, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 69999, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + }, + { + "id": "ed1a26ab-6b24-4e40-ad2b-f47835ad9dbd", + "productId": "dcce0343-0288-425b-ac48-6567642a112a", + "productType": { + "typeId": "product-type", + "id": "e524d54b-17d4-4eb1-855a-107f6e46fe40", + "version": 4 + }, + "productSlug": { + "en-US": "processor" + }, + "name": { + "en-US": "Processor" + }, + "variant": { + "id": 1, + "sku": "i7-13-gen-18", + "prices": [ + { + "id": "8ff00ba8-e33f-43d0-8253-a688dae212ef", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 19999, + "fractionDigits": 2 + } + }, + { + "id": "6bb5a3ce-958f-45bc-9101-b7e632104af4", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 99995, + "fractionDigits": 2 + }, + "country": "MX" + } + ], + "images": [], + "attributes": [ + { + "name": "option", + "value": "13th Gen Intel® Core™ i7-13700H (18-core)" + }, + { + "name": "variant-selector-attributes", + "value": [ + "option" + ] + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 480, + "version": 17, + "id": "623ad83b-896b-46c4-8f84-699d6a4f59e8", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 641, + "version": 1, + "id": "a167e813-9e84-42bf-bda4-aaf4d31f014b" + } + } + } + }, + "price": { + "id": "8ff00ba8-e33f-43d0-8253-a688dae212ef", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 19999, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPricePerQuantity": [], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T20:38:36.146Z", + "lastModifiedAt": "2024-02-14T20:38:36.146Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 19999, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 19999, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 21999, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 2000, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [], + "custom": { + "type": { + "typeId": "type", + "id": "7f027541-b95e-4073-958f-230e8f81364b" + }, + "fields": { + "parentId": "2aa15d0a-dff2-4f43-b822-37fbfdbae9ea" + } + } + }, + { + "id": "a466181e-217c-4892-9bff-98c0fbed682c", + "productId": "b595608e-4b31-4d3a-9650-843191ec9daa", + "productType": { + "typeId": "product-type", + "id": "e524d54b-17d4-4eb1-855a-107f6e46fe40", + "version": 4 + }, + "productSlug": { + "en-US": "video-card" + }, + "name": { + "en-US": "Video Card" + }, + "variant": { + "id": 3, + "sku": "nvidia-rtx-3050", + "prices": [ + { + "id": "2375fa7d-4603-429c-8eeb-ef9fd44e69c6", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4900, + "fractionDigits": 2 + } + } + ], + "images": [], + "attributes": [ + { + "name": "variant-selector-attributes", + "value": [ + "option" + ] + }, + { + "name": "option", + "value": "NVIDIA® GeForce RTX 3050, 4GB GDDR6, 40W" + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 701, + "version": 54, + "id": "c648c63f-1b49-48de-972c-77d7ef83c479", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 218, + "version": 1, + "id": "fc81f1a0-b6dd-4633-a3f3-8d209e32d7ef" + } + } + } + }, + "price": { + "id": "2375fa7d-4603-429c-8eeb-ef9fd44e69c6", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4900, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPricePerQuantity": [], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T20:38:36.154Z", + "lastModifiedAt": "2024-02-14T20:38:36.154Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4900, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4900, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5390, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 490, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [], + "custom": { + "type": { + "typeId": "type", + "id": "7f027541-b95e-4073-958f-230e8f81364b" + }, + "fields": { + "parentId": "2aa15d0a-dff2-4f43-b822-37fbfdbae9ea" + } + } + }, + { + "id": "77405be7-7c4e-407e-b522-bbf282723738", + "productId": "23410ba0-0a67-48a9-8e6d-2bfb7a9c555c", + "productType": { + "typeId": "product-type", + "id": "e524d54b-17d4-4eb1-855a-107f6e46fe40", + "version": 4 + }, + "productSlug": { + "en-US": "memory" + }, + "name": { + "en-US": "Memory" + }, + "variant": { + "id": 2, + "sku": "16gb-4800", + "prices": [ + { + "id": "45a67b91-92fc-4608-8c61-942862f3a457", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5000, + "fractionDigits": 2 + }, + "country": "US" + } + ], + "images": [], + "attributes": [ + { + "name": "variant-selector-attributes", + "value": [ + "option" + ] + }, + { + "name": "option", + "value": "16GB, 2x8GB, DDR5, 4800MHz" + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 268, + "version": 50, + "id": "26f9f15c-1839-41ec-b0f3-a1c277548ffc", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 131, + "version": 1, + "id": "9f5de57f-33f7-4c2c-9a25-a7cb9b6451bf" + } + } + } + }, + "price": { + "id": "45a67b91-92fc-4608-8c61-942862f3a457", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5000, + "fractionDigits": 2 + }, + "country": "US" + }, + "quantity": 1, + "discountedPricePerQuantity": [], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T20:38:36.157Z", + "lastModifiedAt": "2024-02-14T20:38:36.157Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5000, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5000, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5500, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 500, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [], + "custom": { + "type": { + "typeId": "type", + "id": "7f027541-b95e-4073-958f-230e8f81364b" + }, + "fields": { + "parentId": "2aa15d0a-dff2-4f43-b822-37fbfdbae9ea" + } + } + }, + { + "id": "3a813b5d-6771-4c3e-8a4d-349e5a7cd315", + "productId": "586d4aa7-99ac-44ca-b361-cbeaea55e9f2", + "productType": { + "typeId": "product-type", + "id": "e524d54b-17d4-4eb1-855a-107f6e46fe40", + "version": 4 + }, + "productSlug": { + "en-US": "operating-system" + }, + "name": { + "en-US": "Operating System" + }, + "variant": { + "id": 1, + "sku": "windows-11-home", + "prices": [ + { + "id": "b856bd9e-61e3-4cfc-a394-7054e67159c5", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + }, + { + "id": "14f4b3a1-c1c5-4a86-9ef7-c3e3bcc464c4", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 0, + "fractionDigits": 2 + }, + "country": "MX" + } + ], + "images": [], + "attributes": [ + { + "name": "variant-selector-attributes", + "value": [ + "option" + ] + }, + { + "name": "option", + "value": "Windows 11 Home, English" + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 676, + "version": 29, + "id": "845bcac1-b999-48d7-9ea9-a4768b693712", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 521, + "version": 1, + "id": "421603a1-9493-4e8a-a14e-c6a66c870c76" + } + } + } + }, + "price": { + "id": "b856bd9e-61e3-4cfc-a394-7054e67159c5", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPricePerQuantity": [], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T20:38:36.161Z", + "lastModifiedAt": "2024-02-14T20:38:36.161Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [], + "custom": { + "type": { + "typeId": "type", + "id": "7f027541-b95e-4073-958f-230e8f81364b" + }, + "fields": { + "parentId": "2aa15d0a-dff2-4f43-b822-37fbfdbae9ea" + } + } + }, + { + "id": "abe9d6cf-6fff-438a-8e6b-2356ceae8c95", + "productId": "1cc79ac5-59e7-4407-b0bd-78dc2b72b56e", + "productType": { + "typeId": "product-type", + "id": "e524d54b-17d4-4eb1-855a-107f6e46fe40", + "version": 4 + }, + "productSlug": { + "en-US": "hard-drive" + }, + "name": { + "en-US": "Hard Drive" + }, + "variant": { + "id": 1, + "sku": "hd-512", + "prices": [ + { + "id": "2df232a8-d48a-4bd2-8a47-92a54cf3b35d", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + }, + { + "id": "2ca732c8-b59a-4661-b84f-68872cf3492d", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 0, + "fractionDigits": 2 + }, + "country": "MX" + } + ], + "images": [], + "attributes": [ + { + "name": "option", + "value": "512 GB M.2, PCIe NVMe, SSD" + }, + { + "name": "variant-selector-attributes", + "value": [ + "option" + ] + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 978, + "version": 25, + "id": "dcae50a3-2bf1-4ee2-8e07-4749d43b879f", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 731, + "version": 1, + "id": "248432ee-1497-47f1-932d-2b6b59dc4bc3" + } + } + } + }, + "price": { + "id": "2df232a8-d48a-4bd2-8a47-92a54cf3b35d", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPricePerQuantity": [], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T20:38:36.164Z", + "lastModifiedAt": "2024-02-14T20:38:36.164Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [], + "custom": { + "type": { + "typeId": "type", + "id": "7f027541-b95e-4073-958f-230e8f81364b" + }, + "fields": { + "parentId": "2aa15d0a-dff2-4f43-b822-37fbfdbae9ea" + } + } + } + ], + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 729889, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 729889, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 802878, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 72989, + "fractionDigits": 2 + }, + "name": "10% incl." + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 72989, + "fractionDigits": 2 + } + }, + "country": "US", + "customLineItems": [], + "directDiscounts": [], + "inventoryMode": "ReserveOnOrder", + "priceRoundingMode": "HalfEven", + "taxMode": "Platform", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "billingAddress": { + "country": "US" + }, + "itemShippingAddresses": [], + "shippingAddress": { + "country": "US" + }, + "store": { + "typeId": "store", + "key": "hospital-pharmacy-mwd-54321" + }, + "businessUnit": { + "typeId": "business-unit", + "key": "corporate-retail-abc" + }, + "cart": { + "typeId": "cart", + "id": "583e5580-24da-40e7-8776-d0c437e93489" + } + }, + { + "id": "8e037898-f899-46c7-982b-ccc181db3d20", + "version": 2, + "versionModifiedAt": "2024-02-15T18:50:46.294Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2024-02-15T18:50:03.413Z", + "lastModifiedAt": "2024-02-15T18:50:46.294Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "quoteRequestState": "Accepted", + "comment": "5% off", + "customer": { + "typeId": "customer", + "id": "55937787-4eb1-43a7-9065-fac78a757e90" + }, + "lineItems": [ + { + "id": "a381e269-5a22-4e99-a7d7-5323c76c198d", + "productId": "e98b617d-3ddc-4bac-8cdf-82e8490c5a33", + "productKey": "pixma-g6050-key", + "productType": { + "typeId": "product-type", + "id": "7c8a90ff-4d2d-457e-afcf-0d6330276d0c", + "version": 59 + }, + "productSlug": { + "en-US": "pixma-g6050" + }, + "name": { + "en-US": "Canon PIXMA G6050 3-in-1 Refillable MegaTank Printer" + }, + "variant": { + "id": 1, + "sku": "pixma-g6050-001", + "prices": [ + { + "id": "953fc01e-44f8-48b1-b788-525e47db9476", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 29999, + "fractionDigits": 2 + } + }, + { + "id": "c402512b-4759-4ec3-9ca4-7ec4e38dd8b2", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 25000, + "fractionDigits": 2 + }, + "customerGroup": { + "typeId": "customer-group", + "id": "bd90ec2d-b605-4624-abd8-6e946a53076d" + } + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/3113C002_pixma-g6020-SDBWlX04.jpeg", + "dimensions": { + "w": 800, + "h": 800 + } + } + ], + "attributes": [ + { + "name": "return-eligible", + "value": false + }, + { + "name": "salesRank", + "value": 1 + }, + { + "name": "manufacturer-number", + "value": "123456" + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 737, + "version": 25, + "id": "4abbdf29-c313-454f-979b-6500d608754e", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 180, + "version": 1, + "id": "98ee7ad4-0266-4b4b-9e87-cd6c2d07cfc9" + } + } + } + }, + "price": { + "id": "953fc01e-44f8-48b1-b788-525e47db9476", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 29999, + "fractionDigits": 2 + } + }, + "quantity": 10, + "discountedPricePerQuantity": [], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-15T18:49:41.755Z", + "lastModifiedAt": "2024-02-15T18:49:41.755Z", + "state": [ + { + "quantity": 10, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 299990, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 299990, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 329989, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 29999, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + } + ], + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 299990, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 299990, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 329989, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 29999, + "fractionDigits": 2 + }, + "name": "10% incl." + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 29999, + "fractionDigits": 2 + } + }, + "country": "US", + "customLineItems": [], + "directDiscounts": [], + "inventoryMode": "ReserveOnOrder", + "priceRoundingMode": "HalfEven", + "taxMode": "Platform", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "billingAddress": { + "country": "US" + }, + "itemShippingAddresses": [], + "shippingAddress": { + "country": "US" + }, + "store": { + "typeId": "store", + "key": "hospital-pharmacy-mwd-54321" + }, + "businessUnit": { + "typeId": "business-unit", + "key": "corporate-retail-abc" + }, + "cart": { + "typeId": "cart", + "id": "330bf460-4b7c-484b-a150-7651dfa1fedb" + } + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/quote/output-schema.ts b/typescript/src/shared/quote/output-schema.ts index 4598f36..f9ae909 100644 --- a/typescript/src/shared/quote/output-schema.ts +++ b/typescript/src/shared/quote/output-schema.ts @@ -54,6 +54,6 @@ export const quotePagedSchema = z }) .strict(); -export const readQuoteOutputSchema = quoteSchema || quotePagedSchema; +export const readQuoteOutputSchema = z.union([quoteSchema, quotePagedSchema]); export const createQuoteOutputSchema = quoteSchema; export const updateQuoteOutputSchema = quoteSchema; diff --git a/typescript/src/shared/quote/test/output-schema.test.ts b/typescript/src/shared/quote/test/output-schema.test.ts new file mode 100644 index 0000000..12b9add --- /dev/null +++ b/typescript/src/shared/quote/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + quoteSchema, + quotePagedSchema, + readQuoteOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Quote Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = quotePagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = quoteSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = quoteSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readQuoteOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(quoteSchema).toBeDefined(); + expect(readQuoteOutputSchema).toBeDefined(); + expect(quotePagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/quote/test/output.data.json b/typescript/src/shared/quote/test/output.data.json new file mode 100644 index 0000000..1a6987d --- /dev/null +++ b/typescript/src/shared/quote/test/output.data.json @@ -0,0 +1,1966 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 55, + "results": [ + { + "id": "9e8a91d9-4afd-44cb-a208-c29070dbd33f", + "version": 2, + "versionModifiedAt": "2024-02-14T21:06:50.451Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2024-02-14T21:06:11.098Z", + "lastModifiedAt": "2024-02-14T21:06:50.451Z", + "lastModifiedBy": { + "clientId": "1eyVB5_tTzMDPwSxppod3eyZ", + "isPlatformClient": false, + "associate": { + "typeId": "customer", + "id": "55937787-4eb1-43a7-9065-fac78a757e90" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "quoteState": "Accepted", + "quoteRequest": { + "typeId": "quote-request", + "id": "d57f5d52-822d-4919-a6e4-0245acef4d80" + }, + "stagedQuote": { + "typeId": "staged-quote", + "id": "42295e5e-75dd-49cf-923a-57fecff0ea52" + }, + "customer": { + "typeId": "customer", + "id": "55937787-4eb1-43a7-9065-fac78a757e90" + }, + "lineItems": [ + { + "id": "b4b23722-f37e-4275-8bd2-03110db2b439", + "productId": "b738be74-941f-4f4f-9d2a-07304eef8c1a", + "productKey": "xps-15", + "productType": { + "typeId": "product-type", + "id": "d284835b-6d15-497f-ac59-59381951494f", + "version": 7 + }, + "productSlug": { + "en-US": "xps-15-laptop" + }, + "name": { + "en-US": "XPS 15 Laptop" + }, + "variant": { + "id": 1, + "sku": "xps-15", + "key": "xps-15", + "prices": [ + { + "id": "b9e33c10-4af1-4591-b300-80ec7a09b1e0", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 89999, + "fractionDigits": 2 + } + }, + { + "id": "8ca1a382-e441-4554-aeac-4cdf7669876c", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 1640000, + "fractionDigits": 2 + } + }, + { + "id": "5bf17a0c-c72b-42e7-a208-3dc855888f00", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 79999, + "fractionDigits": 2 + }, + "channel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + }, + "tiers": [ + { + "minimumQuantity": 10, + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 69999, + "fractionDigits": 2 + } + } + ] + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/Screenshot%202023-04-1-KqT3Xyq6.png", + "dimensions": { + "w": 569, + "h": 413 + } + } + ], + "attributes": [ + { + "name": "components", + "value": [ + { + "typeId": "product", + "id": "dcce0343-0288-425b-ac48-6567642a112a" + }, + { + "typeId": "product", + "id": "586d4aa7-99ac-44ca-b361-cbeaea55e9f2" + }, + { + "typeId": "product", + "id": "23410ba0-0a67-48a9-8e6d-2bfb7a9c555c" + }, + { + "typeId": "product", + "id": "b595608e-4b31-4d3a-9650-843191ec9daa" + }, + { + "typeId": "product", + "id": "1cc79ac5-59e7-4407-b0bd-78dc2b72b56e" + } + ] + }, + { + "name": "salesRank", + "value": 100 + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 479, + "version": 19, + "id": "dd232ed2-6162-4010-a0cd-9d7c786bcb9b", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 347, + "version": 1, + "id": "4b317d0a-916d-4122-9a66-8784d6a6d0d3" + } + } + } + }, + "price": { + "id": "b9e33c10-4af1-4591-b300-80ec7a09b1e0", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 89999, + "fractionDigits": 2 + } + }, + "quantity": 10, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 85499, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "cf790fba-9200-4fd9-a3dd-f6696b59cb29" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4500, + "fractionDigits": 2 + } + } + ] + }, + "discountedPricePerQuantity": [ + { + "quantity": 10, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 85499, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "cf790fba-9200-4fd9-a3dd-f6696b59cb29" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4500, + "fractionDigits": 2 + } + } + ] + } + } + ], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T21:05:20.928Z", + "lastModifiedAt": "2024-02-14T21:05:20.928Z", + "state": [ + { + "quantity": 10, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 854990, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 854990, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 940489, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 85499, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + } + ], + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 854990, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 854990, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 940489, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 85499, + "fractionDigits": 2 + }, + "name": "10% incl." + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 85499, + "fractionDigits": 2 + } + }, + "country": "US", + "customLineItems": [], + "directDiscounts": [ + { + "id": "cf790fba-9200-4fd9-a3dd-f6696b59cb29", + "value": { + "type": "relative", + "permyriad": 500 + }, + "target": { + "type": "lineItems", + "predicate": "1 = 1" + }, + "references": [] + }, + { + "id": "7828f3c8-d707-416a-97e7-45f3db66e7b2", + "value": { + "type": "relative", + "permyriad": 500 + }, + "target": { + "type": "customLineItems", + "predicate": "1 = 1" + }, + "references": [] + } + ], + "inventoryMode": "ReserveOnOrder", + "priceRoundingMode": "HalfEven", + "taxMode": "Platform", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "billingAddress": { + "city": "Collinsville", + "country": "US" + }, + "itemShippingAddresses": [], + "shippingAddress": { + "city": "Collinsville", + "country": "US" + }, + "store": { + "typeId": "store", + "key": "hospital-pharmacy-mwd-54321" + }, + "businessUnit": { + "typeId": "business-unit", + "key": "abc-hospital-pharmacy-3" + }, + "sellerComment": "" + }, + { + "id": "55a63dcd-ee98-4d1b-aef3-6dad6de58898", + "version": 2, + "versionModifiedAt": "2024-02-14T21:11:45.593Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2024-02-14T21:08:46.816Z", + "lastModifiedAt": "2024-02-14T21:11:45.593Z", + "lastModifiedBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "quoteState": "Accepted", + "quoteRequest": { + "typeId": "quote-request", + "id": "a2690ed8-5361-4be0-b881-d54a88af5314" + }, + "stagedQuote": { + "typeId": "staged-quote", + "id": "1ed652d6-f719-461b-9921-524c7d1a66b0" + }, + "customer": { + "typeId": "customer", + "id": "55937787-4eb1-43a7-9065-fac78a757e90" + }, + "lineItems": [ + { + "id": "5d70c8e4-2359-47ff-9455-45c972a3423e", + "productId": "b738be74-941f-4f4f-9d2a-07304eef8c1a", + "productKey": "xps-15", + "productType": { + "typeId": "product-type", + "id": "d284835b-6d15-497f-ac59-59381951494f", + "version": 7 + }, + "productSlug": { + "en-US": "xps-15-laptop" + }, + "name": { + "en-US": "XPS 15 Laptop" + }, + "variant": { + "id": 1, + "sku": "xps-15", + "key": "xps-15", + "prices": [ + { + "id": "b9e33c10-4af1-4591-b300-80ec7a09b1e0", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 89999, + "fractionDigits": 2 + } + }, + { + "id": "8ca1a382-e441-4554-aeac-4cdf7669876c", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 1640000, + "fractionDigits": 2 + } + }, + { + "id": "5bf17a0c-c72b-42e7-a208-3dc855888f00", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 79999, + "fractionDigits": 2 + }, + "channel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + } + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/Screenshot%202023-04-1-KqT3Xyq6.png", + "dimensions": { + "w": 569, + "h": 413 + } + } + ], + "attributes": [ + { + "name": "components", + "value": [ + { + "typeId": "product", + "id": "dcce0343-0288-425b-ac48-6567642a112a" + }, + { + "typeId": "product", + "id": "586d4aa7-99ac-44ca-b361-cbeaea55e9f2" + }, + { + "typeId": "product", + "id": "23410ba0-0a67-48a9-8e6d-2bfb7a9c555c" + }, + { + "typeId": "product", + "id": "b595608e-4b31-4d3a-9650-843191ec9daa" + }, + { + "typeId": "product", + "id": "1cc79ac5-59e7-4407-b0bd-78dc2b72b56e" + } + ] + }, + { + "name": "salesRank", + "value": 100 + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 479, + "version": 19, + "id": "dd232ed2-6162-4010-a0cd-9d7c786bcb9b", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 347, + "version": 1, + "id": "4b317d0a-916d-4122-9a66-8784d6a6d0d3" + } + } + } + }, + "price": { + "id": "5bf17a0c-c72b-42e7-a208-3dc855888f00", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 69999, + "fractionDigits": 2 + }, + "channel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + }, + "tiers": [ + { + "minimumQuantity": 10, + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 69999, + "fractionDigits": 2 + } + } + ] + }, + "quantity": 10, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 66499, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 3500, + "fractionDigits": 2 + } + } + ] + }, + "discountedPricePerQuantity": [ + { + "quantity": 10, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 66499, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 3500, + "fractionDigits": 2 + } + } + ] + } + } + ], + "supplyChannel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + }, + "distributionChannel": { + "typeId": "channel", + "id": "e1d8d389-3c47-4334-80d8-90b2e9e28ef3" + }, + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T20:38:35.846Z", + "lastModifiedAt": "2024-02-14T20:41:50.273Z", + "state": [ + { + "quantity": 10, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 664990, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 664990, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 731489, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 66499, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + }, + { + "id": "7006c4a6-27cd-4ee4-acb3-1c886d8e6dde", + "productId": "dcce0343-0288-425b-ac48-6567642a112a", + "productType": { + "typeId": "product-type", + "id": "e524d54b-17d4-4eb1-855a-107f6e46fe40", + "version": 4 + }, + "productSlug": { + "en-US": "processor" + }, + "name": { + "en-US": "Processor" + }, + "variant": { + "id": 1, + "sku": "i7-13-gen-18", + "prices": [ + { + "id": "8ff00ba8-e33f-43d0-8253-a688dae212ef", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 19999, + "fractionDigits": 2 + } + }, + { + "id": "6bb5a3ce-958f-45bc-9101-b7e632104af4", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 99995, + "fractionDigits": 2 + }, + "country": "MX" + } + ], + "images": [], + "attributes": [ + { + "name": "option", + "value": "13th Gen Intel® Core™ i7-13700H (18-core)" + }, + { + "name": "variant-selector-attributes", + "value": [ + "option" + ] + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 480, + "version": 17, + "id": "623ad83b-896b-46c4-8f84-699d6a4f59e8", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 641, + "version": 1, + "id": "a167e813-9e84-42bf-bda4-aaf4d31f014b" + } + } + } + }, + "price": { + "id": "8ff00ba8-e33f-43d0-8253-a688dae212ef", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 19999, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 18999, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 1000, + "fractionDigits": 2 + } + } + ] + }, + "discountedPricePerQuantity": [ + { + "quantity": 1, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 18999, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 1000, + "fractionDigits": 2 + } + } + ] + } + } + ], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T20:38:36.146Z", + "lastModifiedAt": "2024-02-14T20:38:36.146Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 18999, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 18999, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 20899, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 1900, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [], + "custom": { + "type": { + "typeId": "type", + "id": "7f027541-b95e-4073-958f-230e8f81364b" + }, + "fields": { + "parentId": "2aa15d0a-dff2-4f43-b822-37fbfdbae9ea" + } + } + }, + { + "id": "351dc77b-4bd9-4a64-9886-05ba8fbca6d7", + "productId": "b595608e-4b31-4d3a-9650-843191ec9daa", + "productType": { + "typeId": "product-type", + "id": "e524d54b-17d4-4eb1-855a-107f6e46fe40", + "version": 4 + }, + "productSlug": { + "en-US": "video-card" + }, + "name": { + "en-US": "Video Card" + }, + "variant": { + "id": 3, + "sku": "nvidia-rtx-3050", + "prices": [ + { + "id": "2375fa7d-4603-429c-8eeb-ef9fd44e69c6", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4900, + "fractionDigits": 2 + } + } + ], + "images": [], + "attributes": [ + { + "name": "variant-selector-attributes", + "value": [ + "option" + ] + }, + { + "name": "option", + "value": "NVIDIA® GeForce RTX 3050, 4GB GDDR6, 40W" + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 701, + "version": 54, + "id": "c648c63f-1b49-48de-972c-77d7ef83c479", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 218, + "version": 1, + "id": "fc81f1a0-b6dd-4633-a3f3-8d209e32d7ef" + } + } + } + }, + "price": { + "id": "2375fa7d-4603-429c-8eeb-ef9fd44e69c6", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4900, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4655, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 245, + "fractionDigits": 2 + } + } + ] + }, + "discountedPricePerQuantity": [ + { + "quantity": 1, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4655, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 245, + "fractionDigits": 2 + } + } + ] + } + } + ], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T20:38:36.154Z", + "lastModifiedAt": "2024-02-14T20:38:36.154Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4655, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4655, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5120, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 465, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [], + "custom": { + "type": { + "typeId": "type", + "id": "7f027541-b95e-4073-958f-230e8f81364b" + }, + "fields": { + "parentId": "2aa15d0a-dff2-4f43-b822-37fbfdbae9ea" + } + } + }, + { + "id": "0f275815-b5e6-42c5-a9e3-87541dd7fa49", + "productId": "23410ba0-0a67-48a9-8e6d-2bfb7a9c555c", + "productType": { + "typeId": "product-type", + "id": "e524d54b-17d4-4eb1-855a-107f6e46fe40", + "version": 4 + }, + "productSlug": { + "en-US": "memory" + }, + "name": { + "en-US": "Memory" + }, + "variant": { + "id": 2, + "sku": "16gb-4800", + "prices": [ + { + "id": "45a67b91-92fc-4608-8c61-942862f3a457", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5000, + "fractionDigits": 2 + }, + "country": "US" + } + ], + "images": [], + "attributes": [ + { + "name": "variant-selector-attributes", + "value": [ + "option" + ] + }, + { + "name": "option", + "value": "16GB, 2x8GB, DDR5, 4800MHz" + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 268, + "version": 50, + "id": "26f9f15c-1839-41ec-b0f3-a1c277548ffc", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 131, + "version": 1, + "id": "9f5de57f-33f7-4c2c-9a25-a7cb9b6451bf" + } + } + } + }, + "price": { + "id": "45a67b91-92fc-4608-8c61-942862f3a457", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5000, + "fractionDigits": 2 + }, + "country": "US" + }, + "quantity": 1, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4750, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 250, + "fractionDigits": 2 + } + } + ] + }, + "discountedPricePerQuantity": [ + { + "quantity": 1, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4750, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 250, + "fractionDigits": 2 + } + } + ] + } + } + ], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T20:38:36.157Z", + "lastModifiedAt": "2024-02-14T20:38:36.157Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4750, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 4750, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 5225, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 475, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [], + "custom": { + "type": { + "typeId": "type", + "id": "7f027541-b95e-4073-958f-230e8f81364b" + }, + "fields": { + "parentId": "2aa15d0a-dff2-4f43-b822-37fbfdbae9ea" + } + } + }, + { + "id": "44da6ade-3c15-4af5-a026-43dfe0ff2ff3", + "productId": "586d4aa7-99ac-44ca-b361-cbeaea55e9f2", + "productType": { + "typeId": "product-type", + "id": "e524d54b-17d4-4eb1-855a-107f6e46fe40", + "version": 4 + }, + "productSlug": { + "en-US": "operating-system" + }, + "name": { + "en-US": "Operating System" + }, + "variant": { + "id": 1, + "sku": "windows-11-home", + "prices": [ + { + "id": "b856bd9e-61e3-4cfc-a394-7054e67159c5", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + }, + { + "id": "14f4b3a1-c1c5-4a86-9ef7-c3e3bcc464c4", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 0, + "fractionDigits": 2 + }, + "country": "MX" + } + ], + "images": [], + "attributes": [ + { + "name": "variant-selector-attributes", + "value": [ + "option" + ] + }, + { + "name": "option", + "value": "Windows 11 Home, English" + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 676, + "version": 29, + "id": "845bcac1-b999-48d7-9ea9-a4768b693712", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 521, + "version": 1, + "id": "421603a1-9493-4e8a-a14e-c6a66c870c76" + } + } + } + }, + "price": { + "id": "b856bd9e-61e3-4cfc-a394-7054e67159c5", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + } + ] + }, + "discountedPricePerQuantity": [ + { + "quantity": 1, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + } + ] + } + } + ], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T20:38:36.161Z", + "lastModifiedAt": "2024-02-14T20:38:36.161Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [], + "custom": { + "type": { + "typeId": "type", + "id": "7f027541-b95e-4073-958f-230e8f81364b" + }, + "fields": { + "parentId": "2aa15d0a-dff2-4f43-b822-37fbfdbae9ea" + } + } + }, + { + "id": "45df0764-1097-471b-b0a2-9bef3f62e490", + "productId": "1cc79ac5-59e7-4407-b0bd-78dc2b72b56e", + "productType": { + "typeId": "product-type", + "id": "e524d54b-17d4-4eb1-855a-107f6e46fe40", + "version": 4 + }, + "productSlug": { + "en-US": "hard-drive" + }, + "name": { + "en-US": "Hard Drive" + }, + "variant": { + "id": 1, + "sku": "hd-512", + "prices": [ + { + "id": "2df232a8-d48a-4bd2-8a47-92a54cf3b35d", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + }, + { + "id": "2ca732c8-b59a-4661-b84f-68872cf3492d", + "value": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 0, + "fractionDigits": 2 + }, + "country": "MX" + } + ], + "images": [], + "attributes": [ + { + "name": "option", + "value": "512 GB M.2, PCIe NVMe, SSD" + }, + { + "name": "variant-selector-attributes", + "value": [ + "option" + ] + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 978, + "version": 25, + "id": "dcae50a3-2bf1-4ee2-8e07-4749d43b879f", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 731, + "version": 1, + "id": "248432ee-1497-47f1-932d-2b6b59dc4bc3" + } + } + } + }, + "price": { + "id": "2df232a8-d48a-4bd2-8a47-92a54cf3b35d", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + }, + "quantity": 1, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + } + ] + }, + "discountedPricePerQuantity": [ + { + "quantity": 1, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + } + ] + } + } + ], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-14T20:38:36.164Z", + "lastModifiedAt": "2024-02-14T20:38:36.164Z", + "state": [ + { + "quantity": 1, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [], + "custom": { + "type": { + "typeId": "type", + "id": "7f027541-b95e-4073-958f-230e8f81364b" + }, + "fields": { + "parentId": "2aa15d0a-dff2-4f43-b822-37fbfdbae9ea" + } + } + } + ], + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 693394, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 693394, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 762733, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 69339, + "fractionDigits": 2 + }, + "name": "10% incl." + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 69339, + "fractionDigits": 2 + } + }, + "country": "US", + "customLineItems": [], + "directDiscounts": [ + { + "id": "8754c276-7248-4823-bd65-25a6eaecb8cd", + "value": { + "type": "relative", + "permyriad": 500 + }, + "target": { + "type": "lineItems", + "predicate": "1 = 1" + }, + "references": [] + }, + { + "id": "77001683-beac-45ec-aae5-82908f656abb", + "value": { + "type": "relative", + "permyriad": 500 + }, + "target": { + "type": "customLineItems", + "predicate": "1 = 1" + }, + "references": [] + } + ], + "inventoryMode": "ReserveOnOrder", + "priceRoundingMode": "HalfEven", + "taxMode": "Platform", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "billingAddress": { + "country": "US" + }, + "itemShippingAddresses": [], + "shippingAddress": { + "country": "US" + }, + "store": { + "typeId": "store", + "key": "hospital-pharmacy-mwd-54321" + }, + "businessUnit": { + "typeId": "business-unit", + "key": "corporate-retail-abc" + }, + "sellerComment": "" + }, + { + "id": "e61d99ce-37d5-423d-ab8c-47890e5aa0a7", + "version": 2, + "versionModifiedAt": "2024-02-15T18:54:10.194Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2024-02-15T18:51:11.983Z", + "lastModifiedAt": "2024-02-15T18:54:10.194Z", + "lastModifiedBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "quoteState": "Accepted", + "quoteRequest": { + "typeId": "quote-request", + "id": "8e037898-f899-46c7-982b-ccc181db3d20" + }, + "stagedQuote": { + "typeId": "staged-quote", + "id": "2c9e8c94-6a43-4b75-8944-1b04ef92b941" + }, + "customer": { + "typeId": "customer", + "id": "55937787-4eb1-43a7-9065-fac78a757e90" + }, + "lineItems": [ + { + "id": "cf132700-c309-4fb8-b88e-2902387c2d0c", + "productId": "e98b617d-3ddc-4bac-8cdf-82e8490c5a33", + "productKey": "pixma-g6050-key", + "productType": { + "typeId": "product-type", + "id": "7c8a90ff-4d2d-457e-afcf-0d6330276d0c", + "version": 59 + }, + "productSlug": { + "en-US": "pixma-g6050" + }, + "name": { + "en-US": "Canon PIXMA G6050 3-in-1 Refillable MegaTank Printer" + }, + "variant": { + "id": 1, + "sku": "pixma-g6050-001", + "prices": [ + { + "id": "953fc01e-44f8-48b1-b788-525e47db9476", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 29999, + "fractionDigits": 2 + } + }, + { + "id": "c402512b-4759-4ec3-9ca4-7ec4e38dd8b2", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 25000, + "fractionDigits": 2 + }, + "customerGroup": { + "typeId": "customer-group", + "id": "bd90ec2d-b605-4624-abd8-6e946a53076d" + } + } + ], + "images": [ + { + "url": "https://efa2cc0dcbc20c919217-dbc413f6fc6aec98e00c8f16a9b5af63.ssl.cf1.rackcdn.com/3113C002_pixma-g6020-SDBWlX04.jpeg", + "dimensions": { + "w": 800, + "h": 800 + } + } + ], + "attributes": [ + { + "name": "return-eligible", + "value": false + }, + { + "name": "salesRank", + "value": 1 + }, + { + "name": "manufacturer-number", + "value": "123456" + } + ], + "assets": [], + "availability": { + "isOnStock": true, + "availableQuantity": 737, + "version": 25, + "id": "4abbdf29-c313-454f-979b-6500d608754e", + "channels": { + "e1d8d389-3c47-4334-80d8-90b2e9e28ef3": { + "isOnStock": true, + "restockableInDays": 7, + "availableQuantity": 180, + "version": 1, + "id": "98ee7ad4-0266-4b4b-9e87-cd6c2d07cfc9" + } + } + } + }, + "price": { + "id": "953fc01e-44f8-48b1-b788-525e47db9476", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 29999, + "fractionDigits": 2 + } + }, + "quantity": 10, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 28499, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "e630b5f6-06b3-4282-b799-e6936bed3030" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 1500, + "fractionDigits": 2 + } + } + ] + }, + "discountedPricePerQuantity": [ + { + "quantity": 10, + "discountedPrice": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 28499, + "fractionDigits": 2 + }, + "includedDiscounts": [ + { + "discount": { + "typeId": "direct-discount", + "id": "e630b5f6-06b3-4282-b799-e6936bed3030" + }, + "discountedAmount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 1500, + "fractionDigits": 2 + } + } + ] + } + } + ], + "taxRate": { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + "perMethodTaxRate": [], + "addedAt": "2024-02-15T18:49:41.755Z", + "lastModifiedAt": "2024-02-15T18:49:41.755Z", + "state": [ + { + "quantity": 10, + "state": { + "typeId": "state", + "id": "0bf0a49d-ef00-4576-8e0c-9e26486adce2" + } + } + ], + "priceMode": "Platform", + "lineItemMode": "Standard", + "priceRoundingMode": "HalfEven", + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 284990, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 284990, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 313489, + "fractionDigits": 2 + }, + "taxPortions": [], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 28499, + "fractionDigits": 2 + } + }, + "taxedPricePortions": [] + } + ], + "totalPrice": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 284990, + "fractionDigits": 2 + }, + "taxedPrice": { + "totalNet": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 284990, + "fractionDigits": 2 + }, + "totalGross": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 313489, + "fractionDigits": 2 + }, + "taxPortions": [ + { + "rate": 0.1, + "amount": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 28499, + "fractionDigits": 2 + }, + "name": "10% incl." + } + ], + "totalTax": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 28499, + "fractionDigits": 2 + } + }, + "country": "US", + "customLineItems": [], + "directDiscounts": [ + { + "id": "e630b5f6-06b3-4282-b799-e6936bed3030", + "value": { + "type": "relative", + "permyriad": 500 + }, + "target": { + "type": "lineItems", + "predicate": "1 = 1" + }, + "references": [] + }, + { + "id": "30171f0e-4526-4fad-85fe-f1e20b7fc966", + "value": { + "type": "relative", + "permyriad": 500 + }, + "target": { + "type": "customLineItems", + "predicate": "1 = 1" + }, + "references": [] + } + ], + "inventoryMode": "ReserveOnOrder", + "priceRoundingMode": "HalfEven", + "taxMode": "Platform", + "taxRoundingMode": "HalfEven", + "taxCalculationMode": "LineItemLevel", + "billingAddress": { + "country": "US" + }, + "itemShippingAddresses": [], + "shippingAddress": { + "country": "US" + }, + "store": { + "typeId": "store", + "key": "hospital-pharmacy-mwd-54321" + }, + "businessUnit": { + "typeId": "business-unit", + "key": "corporate-retail-abc" + }, + "sellerComment": "" + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/recurring-orders/output-schema.ts b/typescript/src/shared/recurring-orders/output-schema.ts index 221217a..5631e36 100644 --- a/typescript/src/shared/recurring-orders/output-schema.ts +++ b/typescript/src/shared/recurring-orders/output-schema.ts @@ -40,7 +40,6 @@ export const recurringOrdersPagedSchema = z }) .strict(); -export const readRecurringOrdersOutputSchema = - recurringOrdersSchema || recurringOrdersPagedSchema; +export const readRecurringOrdersOutputSchema = z.union([recurringOrdersSchema, recurringOrdersPagedSchema]); export const createRecurringOrdersOutputSchema = recurringOrdersSchema; export const updateRecurringOrdersOutputSchema = recurringOrdersSchema; diff --git a/typescript/src/shared/recurring-orders/test/output-schema.test.ts b/typescript/src/shared/recurring-orders/test/output-schema.test.ts new file mode 100644 index 0000000..cf59a81 --- /dev/null +++ b/typescript/src/shared/recurring-orders/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + recurringOrdersSchema, + recurringOrdersPagedSchema, + readRecurringOrdersOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('RecurringOrders Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = recurringOrdersPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = recurringOrdersSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = recurringOrdersSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readRecurringOrdersOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(recurringOrdersSchema).toBeDefined(); + expect(readRecurringOrdersOutputSchema).toBeDefined(); + expect(recurringOrdersPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/recurring-orders/test/output.data.json b/typescript/src/shared/recurring-orders/test/output.data.json new file mode 100644 index 0000000..9f5993c --- /dev/null +++ b/typescript/src/shared/recurring-orders/test/output.data.json @@ -0,0 +1,7 @@ +{ + "limit": 3, + "offset": 0, + "count": 0, + "total": 0, + "results": [] +} \ No newline at end of file diff --git a/typescript/src/shared/reviews/output-schema.ts b/typescript/src/shared/reviews/output-schema.ts index 1e43c3c..9355e1a 100644 --- a/typescript/src/shared/reviews/output-schema.ts +++ b/typescript/src/shared/reviews/output-schema.ts @@ -35,6 +35,6 @@ export const reviewsPagedSchema = z }) .strict(); -export const readReviewOutputSchema = reviewsSchema || reviewsPagedSchema; +export const readReviewOutputSchema = z.union([reviewsSchema, reviewsPagedSchema]); export const createReviewOutputSchema = reviewsSchema; export const updateReviewOutputSchema = reviewsSchema; diff --git a/typescript/src/shared/reviews/test/output-schema.test.ts b/typescript/src/shared/reviews/test/output-schema.test.ts new file mode 100644 index 0000000..577664b --- /dev/null +++ b/typescript/src/shared/reviews/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + reviewsSchema, + reviewsPagedSchema, + readReviewOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Reviews Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = reviewsPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = reviewsSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = reviewsSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readReviewOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(reviewsSchema).toBeDefined(); + expect(readReviewOutputSchema).toBeDefined(); + expect(reviewsPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/reviews/test/output.data.json b/typescript/src/shared/reviews/test/output.data.json new file mode 100644 index 0000000..9f5993c --- /dev/null +++ b/typescript/src/shared/reviews/test/output.data.json @@ -0,0 +1,7 @@ +{ + "limit": 3, + "offset": 0, + "count": 0, + "total": 0, + "results": [] +} \ No newline at end of file diff --git a/typescript/src/shared/shipping-methods/output-schema.ts b/typescript/src/shared/shipping-methods/output-schema.ts index 5fbd3d3..ac84d6a 100644 --- a/typescript/src/shared/shipping-methods/output-schema.ts +++ b/typescript/src/shared/shipping-methods/output-schema.ts @@ -34,7 +34,6 @@ export const shippingMethodsPagedSchema = z }) .strict(); -export const readShippingMethodsOutputSchema = - shippingMethodsSchema || shippingMethodsPagedSchema; +export const readShippingMethodsOutputSchema = z.union([shippingMethodsSchema, shippingMethodsPagedSchema]); export const createShippingMethodsOutputSchema = shippingMethodsSchema; export const updateShippingMethodsOutputSchema = shippingMethodsSchema; diff --git a/typescript/src/shared/shipping-methods/test/output-schema.test.ts b/typescript/src/shared/shipping-methods/test/output-schema.test.ts new file mode 100644 index 0000000..5c28637 --- /dev/null +++ b/typescript/src/shared/shipping-methods/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + shippingMethodsSchema, + shippingMethodsPagedSchema, + readShippingMethodsOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('ShippingMethods Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = shippingMethodsPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = shippingMethodsSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = shippingMethodsSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readShippingMethodsOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(shippingMethodsSchema).toBeDefined(); + expect(readShippingMethodsOutputSchema).toBeDefined(); + expect(shippingMethodsPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/shipping-methods/test/output.data.json b/typescript/src/shared/shipping-methods/test/output.data.json new file mode 100644 index 0000000..72b77ae --- /dev/null +++ b/typescript/src/shared/shipping-methods/test/output.data.json @@ -0,0 +1,223 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 4, + "results": [ + { + "id": "cbfb398d-5778-46d7-9d1f-89602e896271", + "version": 30, + "versionModifiedAt": "2024-04-11T21:12:27.763Z", + "createdAt": "2022-09-14T19:50:38.452Z", + "lastModifiedAt": "2024-04-11T21:12:27.763Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f372e4e3-4a11-469d-807a-d3622d00da99" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "name": "Standard Shipping", + "localizedName": { + "en-US": "Standard Shipping", + "es-MX": "Envio Estandar" + }, + "taxCategory": { + "typeId": "tax-category", + "id": "1aba7f86-aa97-4649-8cac-fcde18798699" + }, + "zoneRates": [ + { + "zone": { + "typeId": "zone", + "id": "48fa59c2-8a86-4fe1-a830-171807b160ec" + }, + "shippingRates": [ + { + "price": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 0, + "fractionDigits": 2 + }, + "tiers": [] + } + ] + }, + { + "zone": { + "typeId": "zone", + "id": "c9228005-324c-49c6-bb3b-fd48764940f0" + }, + "shippingRates": [ + { + "price": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 150000, + "fractionDigits": 2 + }, + "freeAbove": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 150000000, + "fractionDigits": 2 + }, + "tiers": [] + } + ] + } + ], + "active": true, + "isDefault": true, + "key": "standard", + "references": [] + }, + { + "id": "fceb039b-0a9f-4fba-a724-68414bbd3810", + "version": 38, + "versionModifiedAt": "2024-06-28T15:55:37.902Z", + "createdAt": "2023-02-22T17:22:55.186Z", + "lastModifiedAt": "2024-06-28T15:55:37.902Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f372e4e3-4a11-469d-807a-d3622d00da99" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f1c38524-1874-4a36-8cc4-b0ed33dcf3e4" + } + }, + "name": "FedEx Freight", + "localizedName": { + "en-US": "FedEx Freight", + "es-MX": "Envió Premium" + }, + "taxCategory": { + "typeId": "tax-category", + "id": "1aba7f86-aa97-4649-8cac-fcde18798699" + }, + "zoneRates": [ + { + "zone": { + "typeId": "zone", + "id": "c9228005-324c-49c6-bb3b-fd48764940f0" + }, + "shippingRates": [ + { + "price": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 200000, + "fractionDigits": 2 + }, + "freeAbove": { + "type": "centPrecision", + "currencyCode": "MXN", + "centAmount": 200000000000, + "fractionDigits": 2 + }, + "tiers": [] + } + ] + }, + { + "zone": { + "typeId": "zone", + "id": "48fa59c2-8a86-4fe1-a830-171807b160ec" + }, + "shippingRates": [ + { + "price": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 10000, + "fractionDigits": 2 + }, + "freeAbove": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 500000, + "fractionDigits": 2 + }, + "tiers": [] + } + ] + } + ], + "active": true, + "isDefault": false, + "predicate": "1 = 1", + "references": [] + }, + { + "id": "6ac66a48-23ab-43f3-a35c-0d98257b5c89", + "version": 1, + "versionModifiedAt": "2024-05-09T19:26:02.082Z", + "createdAt": "2024-05-09T19:26:02.082Z", + "lastModifiedAt": "2024-05-09T19:26:02.082Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f372e4e3-4a11-469d-807a-d3622d00da99" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f372e4e3-4a11-469d-807a-d3622d00da99" + } + }, + "name": "Custom Method", + "localizedName": { + "en-US": "Custom Method" + }, + "taxCategory": { + "typeId": "tax-category", + "id": "1aba7f86-aa97-4649-8cac-fcde18798699" + }, + "zoneRates": [ + { + "zone": { + "typeId": "zone", + "id": "48fa59c2-8a86-4fe1-a830-171807b160ec" + }, + "shippingRates": [ + { + "price": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 1500, + "fractionDigits": 2 + }, + "tiers": [] + } + ] + } + ], + "active": true, + "isDefault": false, + "predicate": "customer.id=\"ba4807dd-1a7a-4900-bb39-6c9301e326ce\"", + "references": [ + { + "typeId": "customer", + "id": "ba4807dd-1a7a-4900-bb39-6c9301e326ce" + } + ] + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/shopping-lists/output-schema.ts b/typescript/src/shared/shopping-lists/output-schema.ts index aba6fea..a457b95 100644 --- a/typescript/src/shared/shopping-lists/output-schema.ts +++ b/typescript/src/shared/shopping-lists/output-schema.ts @@ -35,7 +35,6 @@ export const shoppingListsPagedSchema = z }) .strict(); -export const readShoppingListOutputSchema = - shoppingListsSchema || shoppingListsPagedSchema; +export const readShoppingListOutputSchema = z.union([shoppingListsSchema, shoppingListsPagedSchema]); export const createShoppingListOutputSchema = shoppingListsSchema; export const updateShoppingListOutputSchema = shoppingListsSchema; diff --git a/typescript/src/shared/shopping-lists/test/output-schema.test.ts b/typescript/src/shared/shopping-lists/test/output-schema.test.ts new file mode 100644 index 0000000..148a17a --- /dev/null +++ b/typescript/src/shared/shopping-lists/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + shoppingListsSchema, + shoppingListsPagedSchema, + readShoppingListOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('ShoppingLists Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = shoppingListsPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = shoppingListsSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = shoppingListsSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readShoppingListOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(shoppingListsSchema).toBeDefined(); + expect(readShoppingListOutputSchema).toBeDefined(); + expect(shoppingListsPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/shopping-lists/test/output.data.json b/typescript/src/shared/shopping-lists/test/output.data.json new file mode 100644 index 0000000..221fd94 --- /dev/null +++ b/typescript/src/shared/shopping-lists/test/output.data.json @@ -0,0 +1,72 @@ +{ + "limit": 3, + "offset": 0, + "count": 1, + "total": 1, + "results": [ + { + "id": "445de124-990b-4a1a-9c28-c889277b60aa", + "version": 5, + "versionModifiedAt": "2025-04-25T13:38:24.613Z", + "lastMessageSequenceNumber": 2, + "createdAt": "2025-04-25T13:37:36.825Z", + "lastModifiedAt": "2025-04-25T13:38:24.613Z", + "lastModifiedBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "name": { + "en-US": "test2" + }, + "description": { + "en-US": "asd" + }, + "customer": { + "typeId": "customer", + "id": "00b6aced-c6e7-4b6f-9d0c-9bc8b7577205" + }, + "lineItems": [ + { + "id": "cc566502-32d9-4fc5-b8c3-cf83db54af9f", + "productId": "e98b617d-3ddc-4bac-8cdf-82e8490c5a33", + "name": { + "en-US": "Canon PIXMA G6050 3-in-1 Refillable MegaTank Printer" + }, + "productType": { + "typeId": "product-type", + "id": "7c8a90ff-4d2d-457e-afcf-0d6330276d0c" + }, + "published": true, + "variantId": 1, + "quantity": 1, + "addedAt": "2025-04-25T13:37:37.592Z" + }, + { + "id": "6e1994dc-ffa8-4182-9aed-2455a3e53576", + "productId": "9b9ff61d-71b8-4663-94b1-f6c56bf9cc6e", + "name": { + "en-US": "Tylenol Specialty" + }, + "productType": { + "typeId": "product-type", + "id": "7c8a90ff-4d2d-457e-afcf-0d6330276d0c" + }, + "published": true, + "variantId": 1, + "quantity": 1, + "addedAt": "2025-04-25T13:38:24.604Z" + } + ], + "textLineItems": [], + "deleteDaysAfterLastModification": 360, + "store": { + "typeId": "store", + "key": "store_test" + } + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/staged-quote/output-schema.ts b/typescript/src/shared/staged-quote/output-schema.ts index e151968..b950eb0 100644 --- a/typescript/src/shared/staged-quote/output-schema.ts +++ b/typescript/src/shared/staged-quote/output-schema.ts @@ -35,7 +35,6 @@ export const stagedQuotePagedSchema = z }) .strict(); -export const readStagedQuoteOutputSchema = - stagedQuoteSchema || stagedQuotePagedSchema; +export const readStagedQuoteOutputSchema = z.union([stagedQuoteSchema, stagedQuotePagedSchema]); export const createStagedQuoteOutputSchema = stagedQuoteSchema; export const updateStagedQuoteOutputSchema = stagedQuoteSchema; diff --git a/typescript/src/shared/staged-quote/test/output-schema.test.ts b/typescript/src/shared/staged-quote/test/output-schema.test.ts new file mode 100644 index 0000000..b7618c1 --- /dev/null +++ b/typescript/src/shared/staged-quote/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + stagedQuoteSchema, + stagedQuotePagedSchema, + readStagedQuoteOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('StagedQuote Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = stagedQuotePagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = stagedQuoteSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = stagedQuoteSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readStagedQuoteOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(stagedQuoteSchema).toBeDefined(); + expect(readStagedQuoteOutputSchema).toBeDefined(); + expect(stagedQuotePagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/staged-quote/test/output.data.json b/typescript/src/shared/staged-quote/test/output.data.json new file mode 100644 index 0000000..2551cfb --- /dev/null +++ b/typescript/src/shared/staged-quote/test/output.data.json @@ -0,0 +1,132 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 56, + "results": [ + { + "id": "42295e5e-75dd-49cf-923a-57fecff0ea52", + "version": 3, + "versionModifiedAt": "2024-02-14T21:06:11.254Z", + "lastMessageSequenceNumber": 3, + "createdAt": "2024-02-14T21:05:52.478Z", + "lastModifiedAt": "2024-02-14T21:06:11.254Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "quotationCart": { + "typeId": "cart", + "id": "b31ef9b3-dcd1-409e-bed0-c1c4b871668f" + }, + "quoteRequest": { + "typeId": "quote-request", + "id": "d57f5d52-822d-4919-a6e4-0245acef4d80" + }, + "customer": { + "typeId": "customer", + "id": "55937787-4eb1-43a7-9065-fac78a757e90" + }, + "stagedQuoteState": "Sent", + "sellerComment": "", + "businessUnit": { + "typeId": "business-unit", + "key": "abc-hospital-pharmacy-3" + } + }, + { + "id": "1ed652d6-f719-461b-9921-524c7d1a66b0", + "version": 3, + "versionModifiedAt": "2024-02-14T21:08:46.982Z", + "lastMessageSequenceNumber": 3, + "createdAt": "2024-02-14T21:08:22.555Z", + "lastModifiedAt": "2024-02-14T21:08:46.982Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "quotationCart": { + "typeId": "cart", + "id": "f20c90ca-5154-452c-ab24-813f232acf18" + }, + "quoteRequest": { + "typeId": "quote-request", + "id": "a2690ed8-5361-4be0-b881-d54a88af5314" + }, + "customer": { + "typeId": "customer", + "id": "55937787-4eb1-43a7-9065-fac78a757e90" + }, + "stagedQuoteState": "Sent", + "sellerComment": "", + "businessUnit": { + "typeId": "business-unit", + "key": "corporate-retail-abc" + } + }, + { + "id": "2c9e8c94-6a43-4b75-8944-1b04ef92b941", + "version": 3, + "versionModifiedAt": "2024-02-15T18:51:12.149Z", + "lastMessageSequenceNumber": 3, + "createdAt": "2024-02-15T18:50:48.724Z", + "lastModifiedAt": "2024-02-15T18:51:12.149Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "quotationCart": { + "typeId": "cart", + "id": "3d189a31-c7a3-4787-9e14-0bdc95830f80" + }, + "quoteRequest": { + "typeId": "quote-request", + "id": "8e037898-f899-46c7-982b-ccc181db3d20" + }, + "customer": { + "typeId": "customer", + "id": "55937787-4eb1-43a7-9065-fac78a757e90" + }, + "stagedQuoteState": "Sent", + "sellerComment": "", + "businessUnit": { + "typeId": "business-unit", + "key": "corporate-retail-abc" + }, + "store": { + "typeId": "store", + "key": "hospital-pharmacy-mwd-54321" + } + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/standalone-price/output-schema.ts b/typescript/src/shared/standalone-price/output-schema.ts index 78c983a..7476f98 100644 --- a/typescript/src/shared/standalone-price/output-schema.ts +++ b/typescript/src/shared/standalone-price/output-schema.ts @@ -37,7 +37,6 @@ export const standalonePricePagedSchema = z }) .strict(); -export const readStandalonePriceOutputSchema = - standalonePriceSchema || standalonePricePagedSchema; +export const readStandalonePriceOutputSchema = z.union([standalonePriceSchema, standalonePricePagedSchema]); export const createStandalonePriceOutputSchema = standalonePriceSchema; export const updateStandalonePriceOutputSchema = standalonePriceSchema; diff --git a/typescript/src/shared/standalone-price/test/output-schema.test.ts b/typescript/src/shared/standalone-price/test/output-schema.test.ts new file mode 100644 index 0000000..49260d8 --- /dev/null +++ b/typescript/src/shared/standalone-price/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + standalonePriceSchema, + standalonePricePagedSchema, + readStandalonePriceOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('StandalonePrice Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = standalonePricePagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = standalonePriceSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = standalonePriceSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readStandalonePriceOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(standalonePriceSchema).toBeDefined(); + expect(readStandalonePriceOutputSchema).toBeDefined(); + expect(standalonePricePagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/standalone-price/test/output.data.json b/typescript/src/shared/standalone-price/test/output.data.json new file mode 100644 index 0000000..1f0967e --- /dev/null +++ b/typescript/src/shared/standalone-price/test/output.data.json @@ -0,0 +1,131 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 13, + "results": [ + { + "id": "65dc5c62-3b4b-44f0-8d19-256335a33727", + "version": 7, + "versionModifiedAt": "2024-10-07T17:46:28.216Z", + "lastMessageSequenceNumber": 7, + "createdAt": "2024-02-20T19:57:51.349Z", + "lastModifiedAt": "2024-10-07T17:46:28.216Z", + "lastModifiedBy": { + "isPlatformClient": true + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "sku": "green-hat-1", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 1200, + "fractionDigits": 2 + }, + "channel": { + "typeId": "channel", + "id": "04b3d1df-ef8a-4e56-abbf-2eb87d6d85a6" + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 1176, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + }, + "active": true + }, + { + "id": "2bc58020-f57a-4155-b3f8-4cd36b585d30", + "version": 7, + "versionModifiedAt": "2024-10-07T17:46:28.223Z", + "lastMessageSequenceNumber": 7, + "createdAt": "2024-02-29T15:17:10.633Z", + "lastModifiedAt": "2024-10-07T17:46:28.223Z", + "lastModifiedBy": { + "isPlatformClient": true + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "sku": "green-hat-1", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 22200, + "fractionDigits": 2 + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 21756, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + }, + "active": true + }, + { + "id": "1a35b473-61a2-4aef-bbc3-614128ac745e", + "version": 5, + "versionModifiedAt": "2024-10-07T17:46:28.696Z", + "lastMessageSequenceNumber": 5, + "createdAt": "2024-03-19T19:58:59.459Z", + "lastModifiedAt": "2024-10-07T17:46:28.696Z", + "lastModifiedBy": { + "isPlatformClient": true + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "f372e4e3-4a11-469d-807a-d3622d00da99" + } + }, + "sku": "WF-100", + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 10000, + "fractionDigits": 2 + }, + "key": "dmu", + "channel": { + "typeId": "channel", + "id": "8972835e-38e5-4142-8736-80c88ed0d670" + }, + "discounted": { + "value": { + "type": "centPrecision", + "currencyCode": "USD", + "centAmount": 9800, + "fractionDigits": 2 + }, + "discount": { + "typeId": "product-discount", + "id": "cb8207b9-ca5f-4f6b-9380-50d61417e1a1" + } + }, + "active": true + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/store/output-schema.ts b/typescript/src/shared/store/output-schema.ts index d4b5388..18e528d 100644 --- a/typescript/src/shared/store/output-schema.ts +++ b/typescript/src/shared/store/output-schema.ts @@ -31,6 +31,6 @@ export const storePagedSchema = z }) .strict(); -export const readStoreOutputSchema = storeSchema || storePagedSchema; +export const readStoreOutputSchema = z.union([storeSchema, storePagedSchema]); export const createStoreOutputSchema = storeSchema; export const updateStoreOutputSchema = storeSchema; diff --git a/typescript/src/shared/store/test/output-schema.test.ts b/typescript/src/shared/store/test/output-schema.test.ts new file mode 100644 index 0000000..8eafe8b --- /dev/null +++ b/typescript/src/shared/store/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + storeSchema, + storePagedSchema, + readStoreOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Store Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = storePagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = storeSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = storeSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readStoreOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(storeSchema).toBeDefined(); + expect(readStoreOutputSchema).toBeDefined(); + expect(storePagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/store/test/output.data.json b/typescript/src/shared/store/test/output.data.json new file mode 100644 index 0000000..83de1f3 --- /dev/null +++ b/typescript/src/shared/store/test/output.data.json @@ -0,0 +1,142 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 162, + "results": [ + { + "id": "942de367-3337-45cf-8552-87f3dc1447f5", + "version": 5, + "versionModifiedAt": "2023-09-13T15:45:33.339Z", + "lastMessageSequenceNumber": 3, + "createdAt": "2022-09-19T19:53:38.369Z", + "lastModifiedAt": "2023-01-04T18:59:04.423Z", + "lastModifiedBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "key": "store1", + "name": { + "en-US": "Store 1" + }, + "languages": [], + "distributionChannels": [ + { + "typeId": "channel", + "id": "94f0286e-c720-400e-aff8-5e41422309d9" + } + ], + "supplyChannels": [ + { + "typeId": "channel", + "id": "94f0286e-c720-400e-aff8-5e41422309d9" + } + ], + "custom": { + "type": { + "typeId": "type", + "id": "d4975219-9a37-42f7-a697-17b0baaf2ae6" + }, + "fields": { + "rootCategory": { + "typeId": "category", + "id": "1e50afe7-4d56-4576-b76d-f6239201b570" + } + } + }, + "productSelections": [], + "countries": [] + }, + { + "id": "220bf12e-7a4b-4f85-9b37-166d296cf891", + "version": 3, + "versionModifiedAt": "2023-09-13T15:45:33.338Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2022-09-21T21:53:07.936Z", + "lastModifiedAt": "2023-01-04T18:59:04.562Z", + "lastModifiedBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "key": "store_vandelay_industries", + "name": { + "en-US": "Vandelay Industries" + }, + "languages": [], + "distributionChannels": [], + "supplyChannels": [], + "custom": { + "type": { + "typeId": "type", + "id": "d4975219-9a37-42f7-a697-17b0baaf2ae6" + }, + "fields": { + "rootCategory": { + "typeId": "category", + "id": "1e50afe7-4d56-4576-b76d-f6239201b570" + } + } + }, + "productSelections": [], + "countries": [] + }, + { + "id": "642fb219-2c9b-47d1-a33c-017a6d4d882f", + "version": 3, + "versionModifiedAt": "2023-09-13T15:45:33.339Z", + "lastMessageSequenceNumber": 1, + "createdAt": "2022-09-22T20:42:35.882Z", + "lastModifiedAt": "2023-01-04T18:59:04.746Z", + "lastModifiedBy": { + "clientId": "fnpedlR_fvQNBbvM4XvBvNcO", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "key": "store_qwe", + "name": { + "en-US": "qwe" + }, + "languages": [], + "distributionChannels": [ + { + "typeId": "channel", + "id": "94f0286e-c720-400e-aff8-5e41422309d9" + } + ], + "supplyChannels": [ + { + "typeId": "channel", + "id": "94f0286e-c720-400e-aff8-5e41422309d9" + } + ], + "custom": { + "type": { + "typeId": "type", + "id": "d4975219-9a37-42f7-a697-17b0baaf2ae6" + }, + "fields": { + "rootCategory": { + "typeId": "category", + "id": "1e50afe7-4d56-4576-b76d-f6239201b570" + } + } + }, + "productSelections": [], + "countries": [] + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/subscriptions/output-schema.ts b/typescript/src/shared/subscriptions/output-schema.ts index 405887c..0638902 100644 --- a/typescript/src/shared/subscriptions/output-schema.ts +++ b/typescript/src/shared/subscriptions/output-schema.ts @@ -12,8 +12,6 @@ export const subscriptionsSchema = z destination: z.any(), key: z.string().optional(), messages: z.array(z.any()), - changes: z.array(z.any()), - events: z.array(z.any()), format: z.any(), status: z.any(), }) @@ -30,7 +28,6 @@ export const subscriptionsPagedSchema = z }) .strict(); -export const readSubscriptionOutputSchema = - subscriptionsSchema || subscriptionsPagedSchema; +export const readSubscriptionOutputSchema = z.union([subscriptionsSchema, subscriptionsPagedSchema]); export const createSubscriptionOutputSchema = subscriptionsSchema; export const updateSubscriptionOutputSchema = subscriptionsSchema; diff --git a/typescript/src/shared/subscriptions/test/output-schema.test.ts b/typescript/src/shared/subscriptions/test/output-schema.test.ts new file mode 100644 index 0000000..48a7458 --- /dev/null +++ b/typescript/src/shared/subscriptions/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + subscriptionsSchema, + subscriptionsPagedSchema, + readSubscriptionOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('Subscriptions Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = subscriptionsPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = subscriptionsSchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = subscriptionsSchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readSubscriptionOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(subscriptionsSchema).toBeDefined(); + expect(readSubscriptionOutputSchema).toBeDefined(); + expect(subscriptionsPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/subscriptions/test/output.data.json b/typescript/src/shared/subscriptions/test/output.data.json new file mode 100644 index 0000000..b662df2 --- /dev/null +++ b/typescript/src/shared/subscriptions/test/output.data.json @@ -0,0 +1,122 @@ +{ + "limit": 3, + "offset": 0, + "count": 3, + "total": 4, + "results": [ + { + "id": "b9e7dec8-8d83-40a2-bbe2-c2b5a4ecbba6", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:35.081Z", + "createdAt": "2022-10-17T14:44:36.838Z", + "lastModifiedAt": "2022-10-17T14:44:36.838Z", + "lastModifiedBy": { + "isPlatformClient": true + }, + "createdBy": { + "isPlatformClient": true + }, + "destination": { + "type": "GoogleCloudPubSub", + "projectId": "ct-sales-207211", + "topic": "customer-created" + }, + "messages": [ + { + "resourceTypeId": "customer", + "types": [ + "CustomerCreated" + ] + } + ], + "changes": [], + "format": { + "type": "Platform" + }, + "status": "Healthy", + "key": "customer-auto-verify" + }, + { + "id": "aa2421cd-23f7-46ec-9e35-48ef37c9608d", + "version": 1, + "versionModifiedAt": "2023-11-09T19:35:07.030Z", + "createdAt": "2023-11-09T19:35:07.030Z", + "lastModifiedAt": "2023-11-09T19:35:07.030Z", + "lastModifiedBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "createdBy": { + "clientId": "pyWxXbSIBd1w8cs0VH0RVAcv", + "isPlatformClient": false + }, + "destination": { + "type": "GoogleCloudPubSub", + "projectId": "ct-connectors-preview", + "topic": "event-0d1da28a-cb95-4e1c-9478-b305810adb3e-notification-manager" + }, + "messages": [ + { + "resourceTypeId": "staged-quote", + "types": [ + "StagedQuoteCreated" + ] + }, + { + "resourceTypeId": "quote-request", + "types": [ + "QuoteRequestStateChanged" + ] + }, + { + "resourceTypeId": "quote", + "types": [ + "QuoteCreated" + ] + } + ], + "changes": [], + "format": { + "type": "Platform" + }, + "status": "Healthy", + "key": "twilio-notifications" + }, + { + "id": "14563658-f18a-4ac6-92f7-0db7e30065d8", + "version": 8, + "versionModifiedAt": "2025-09-15T17:09:00.018Z", + "createdAt": "2024-03-20T20:40:50.112Z", + "lastModifiedAt": "2025-09-15T17:09:00.018Z", + "lastModifiedBy": { + "isPlatformClient": true + }, + "createdBy": { + "clientId": "ax-1-bpgYf5y4k1p3xflnbEn", + "isPlatformClient": false + }, + "destination": { + "type": "GoogleCloudPubSub", + "projectId": "ct-sales-207211", + "topic": "uri-pubsub" + }, + "messages": [], + "changes": [ + { + "resourceTypeId": "order" + }, + { + "resourceTypeId": "product" + }, + { + "resourceTypeId": "customer" + } + ], + "format": { + "type": "Platform" + }, + "status": "ConfigurationErrorDeliveryStopped", + "key": "b2b-subscription" + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/tax-category/output-schema.ts b/typescript/src/shared/tax-category/output-schema.ts index cc3d404..0a1b81b 100644 --- a/typescript/src/shared/tax-category/output-schema.ts +++ b/typescript/src/shared/tax-category/output-schema.ts @@ -27,7 +27,6 @@ export const taxCategoryPagedSchema = z }) .strict(); -export const readTaxCategoryOutputSchema = - taxCategorySchema || taxCategoryPagedSchema; +export const readTaxCategoryOutputSchema = z.union([taxCategorySchema, taxCategoryPagedSchema]); export const createTaxCategoryOutputSchema = taxCategorySchema; export const updateTaxCategoryOutputSchema = taxCategorySchema; diff --git a/typescript/src/shared/tax-category/test/output-schema.test.ts b/typescript/src/shared/tax-category/test/output-schema.test.ts new file mode 100644 index 0000000..25403fe --- /dev/null +++ b/typescript/src/shared/tax-category/test/output-schema.test.ts @@ -0,0 +1,81 @@ +import { + taxCategorySchema, + taxCategoryPagedSchema, + readTaxCategoryOutputSchema, +} from '../output-schema'; +import outputData from './output.data.json'; + +describe('TaxCategory Output Schema', () => { + describe('Paged Response Schema', () => { + it('should validate real API paged response', () => { + const result = taxCategoryPagedSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + + it('should have required paged fields', () => { + expect(outputData).toHaveProperty('limit'); + expect(outputData).toHaveProperty('offset'); + expect(outputData).toHaveProperty('count'); + expect(outputData).toHaveProperty('results'); + expect(Array.isArray((outputData as any).results)).toBe(true); + }); + }); + + describe('Individual Entity Schema', () => { + it('should validate individual entities from results', () => { + const results = (outputData as any).results; + + if (results && results.length > 0) { + const firstEntity = results[0]; + const result = taxCategorySchema.passthrough().safeParse(firstEntity); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + } else { + console.warn('No results in output data to validate individual entities'); + } + }); + + it('should validate all entities in results array', () => { + const results = (outputData as any).results || []; + + results.forEach((entity: any, index: number) => { + const result = taxCategorySchema.passthrough().safeParse(entity); + + if (!result.success) { + console.error(`Entity ${index} validation errors:`, JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + }); + + describe('Read Output Schema (Union)', () => { + it('should validate paged response', () => { + const result = readTaxCategoryOutputSchema.safeParse(outputData); + + if (!result.success) { + console.error('Validation errors:', JSON.stringify(result.error.format(), null, 2)); + } + + expect(result.success).toBe(true); + }); + }); + + describe('Schema Structure', () => { + it('should be a valid Zod schema', () => { + expect(taxCategorySchema).toBeDefined(); + expect(readTaxCategoryOutputSchema).toBeDefined(); + expect(taxCategoryPagedSchema).toBeDefined(); + }); + }); +}); diff --git a/typescript/src/shared/tax-category/test/output.data.json b/typescript/src/shared/tax-category/test/output.data.json new file mode 100644 index 0000000..2eca1d0 --- /dev/null +++ b/typescript/src/shared/tax-category/test/output.data.json @@ -0,0 +1,581 @@ +{ + "limit": 3, + "offset": 0, + "count": 1, + "total": 1, + "results": [ + { + "id": "1aba7f86-aa97-4649-8cac-fcde18798699", + "version": 188, + "versionModifiedAt": "2023-09-13T15:45:31.749Z", + "createdAt": "2022-09-14T19:50:09.602Z", + "lastModifiedAt": "2023-07-26T18:39:54.764Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "name": "standard", + "description": "", + "rates": [ + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "id": "HF-csJaY", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "AL", + "id": "MEZCLASr", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "AK", + "id": "1yj7Ejrm", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "AS", + "id": "S3e8z2ch", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "AZ", + "id": "pYzPHY4x", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "AR", + "id": "415UUKJ5", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "CA", + "id": "a6wnH1J3", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "CO", + "id": "xVyUo7CD", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "CT", + "id": "oRlipPRO", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "DE", + "id": "WyP5RGVN", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "DC", + "id": "pblyKPWd", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "FM", + "id": "cIxqqZm9", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "FL", + "id": "QQI1XRGb", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "GA", + "id": "226nOUaQ", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "GU", + "id": "en83K40z", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "HI", + "id": "dZgL8usC", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "ID", + "id": "U75MLNIV", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "IL", + "id": "5UbCnlHT", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "IN", + "id": "oxSU3ayp", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "IA", + "id": "IUXWx8xl", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "KS", + "id": "4EkaoqMI", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "KY", + "id": "DXYmA5tR", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "LA", + "id": "glYTs3un", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "ME", + "id": "zJl_8wv7", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "MH", + "id": "Ug-JIWl-", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "MD", + "id": "4PDXFA_R", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "MA", + "id": "dh75P7eA", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "MI", + "id": "fNeo6NyP", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "MN", + "id": "CtJlpRIU", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "MS", + "id": "WBv04VuU", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "MO", + "id": "mCbksC8-", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "MT", + "id": "vHb6RQcj", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "NE", + "id": "NpIaVYSX", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "NV", + "id": "oxL9KROr", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "NH", + "id": "86skLDk6", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "NJ", + "id": "zMfgTgVz", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "NM", + "id": "ADk37o50", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "NY", + "id": "QLA2Eoj6", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "NC", + "id": "kyqc-wwW", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "ND", + "id": "9XROw1qG", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "MP", + "id": "PidhcfB8", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "OH", + "id": "3amOd7jz", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "OK", + "id": "0mV861-S", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "OR", + "id": "XUOJA6yA", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "PW", + "id": "8Z_q3TdU", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "PA", + "id": "yzwTtxqU", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "PR", + "id": "cwSF_A4y", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "RI", + "id": "sr6sR3t7", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "SC", + "id": "H-f9GP4b", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "SD", + "id": "DlDRjvL9", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "TN", + "id": "2hUZA3rL", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "TX", + "id": "ggBldxeG", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "UT", + "id": "lywbNFhS", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "VT", + "id": "nZzlqLcb", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "VI", + "id": "KKvt7bXt", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "VA", + "id": "FJFL74z5", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "WA", + "id": "npgwRJvE", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "WV", + "id": "XEHMLplu", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "WI", + "id": "-FXG_HuU", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "US", + "state": "WY", + "id": "EDwxH8Lv", + "subRates": [] + }, + { + "name": "10% incl.", + "amount": 0.1, + "includedInPrice": false, + "country": "MX", + "id": "hgQJYycc", + "subRates": [] + } + ], + "key": "standard" + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/zone/test/output.data.json b/typescript/src/shared/zone/test/output.data.json new file mode 100644 index 0000000..5682226 --- /dev/null +++ b/typescript/src/shared/zone/test/output.data.json @@ -0,0 +1,62 @@ +{ + "limit": 3, + "offset": 0, + "count": 2, + "total": 2, + "results": [ + { + "id": "48fa59c2-8a86-4fe1-a830-171807b160ec", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:19.579Z", + "createdAt": "2022-09-14T19:39:33.429Z", + "lastModifiedAt": "2022-09-14T19:39:33.429Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "cf7f6e32-2446-46a3-b05d-c705bb2c0d0e" + } + }, + "name": "US", + "locations": [ + { + "country": "US" + } + ] + }, + { + "id": "c9228005-324c-49c6-bb3b-fd48764940f0", + "version": 2, + "versionModifiedAt": "2023-09-13T15:45:19.579Z", + "createdAt": "2023-07-26T18:39:31.289Z", + "lastModifiedAt": "2023-07-26T18:39:31.289Z", + "lastModifiedBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "createdBy": { + "isPlatformClient": true, + "user": { + "typeId": "user", + "id": "dedf67a6-f66d-4baf-81b7-ea6ba36e748f" + } + }, + "name": "MX", + "locations": [ + { + "country": "MX" + } + ] + } + ] +} \ No newline at end of file diff --git a/typescript/src/shared/zones/output-schema.ts b/typescript/src/shared/zones/output-schema.ts index 11f4829..e76f7bf 100644 --- a/typescript/src/shared/zones/output-schema.ts +++ b/typescript/src/shared/zones/output-schema.ts @@ -39,6 +39,6 @@ export const zonesPagedSchema = z }) .strict(); -export const readZoneOutputSchema = zonesSchema || zonesPagedSchema; +export const readZoneOutputSchema = z.union([zonesSchema, zonesPagedSchema]); export const createZoneOutputSchema = zonesSchema; export const updateZoneOutputSchema = zonesSchema; diff --git a/typescript/src/types/tools.ts b/typescript/src/types/tools.ts index 0beafeb..f26d96d 100644 --- a/typescript/src/types/tools.ts +++ b/typescript/src/types/tools.ts @@ -43,7 +43,7 @@ export type Tool = { name: string; description: string; parameters: z.ZodObject; - outputSchema?: z.ZodObject; + outputSchema?: z.ZodObject | z.ZodUnion<[z.ZodObject, z.ZodObject]>; execute?: (args: T, api?: ApiRoot) => Promise; actions: { [key: string]: {