@unchainedshop/api 4.8.0 → 4.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/lib/chat/generateImageHandler.js +5 -6
  2. package/lib/express/createMCPMiddleware.js +1 -1
  3. package/lib/fastify/mcpHandler.js +1 -1
  4. package/lib/loaders/buildTextMap.js +13 -15
  5. package/lib/mcp/tools/assortment/assortmentManagement.d.ts +2 -2
  6. package/lib/mcp/tools/assortment/assortmentManagement.js +2 -2
  7. package/lib/mcp/tools/assortment/handlers/getAssortment.js +1 -1
  8. package/lib/mcp/tools/assortment/schemas.d.ts +141 -322
  9. package/lib/mcp/tools/assortment/schemas.js +96 -179
  10. package/lib/mcp/tools/filter/filterManagement.d.ts +2 -2
  11. package/lib/mcp/tools/filter/filterManagement.js +2 -2
  12. package/lib/mcp/tools/filter/schemas.d.ts +75 -184
  13. package/lib/mcp/tools/filter/schemas.js +51 -87
  14. package/lib/mcp/tools/localization/localizationManagement.d.ts +2 -2
  15. package/lib/mcp/tools/localization/localizationManagement.js +2 -2
  16. package/lib/mcp/tools/localization/schemas.d.ts +47 -110
  17. package/lib/mcp/tools/localization/schemas.js +36 -51
  18. package/lib/mcp/tools/order/orderManagement.d.ts +2 -2
  19. package/lib/mcp/tools/order/orderManagement.js +2 -2
  20. package/lib/mcp/tools/order/schemas.d.ts +75 -184
  21. package/lib/mcp/tools/order/schemas.js +51 -113
  22. package/lib/mcp/tools/product/handlers/getProduct.js +1 -1
  23. package/lib/mcp/tools/product/productManagement.d.ts +2 -2
  24. package/lib/mcp/tools/product/productManagement.js +2 -2
  25. package/lib/mcp/tools/product/schemas.d.ts +317 -642
  26. package/lib/mcp/tools/product/schemas.js +191 -287
  27. package/lib/mcp/tools/provider/providerManagement.d.ts +2 -2
  28. package/lib/mcp/tools/provider/providerManagement.js +2 -2
  29. package/lib/mcp/tools/provider/schemas.d.ts +47 -142
  30. package/lib/mcp/tools/provider/schemas.js +32 -67
  31. package/lib/mcp/tools/quotation/quotationManagement.d.ts +2 -2
  32. package/lib/mcp/tools/quotation/quotationManagement.js +2 -2
  33. package/lib/mcp/tools/quotation/schemas.d.ts +40 -111
  34. package/lib/mcp/tools/quotation/schemas.js +29 -54
  35. package/lib/mcp/tools/system/schemas.d.ts +84 -179
  36. package/lib/mcp/tools/system/schemas.js +67 -188
  37. package/lib/mcp/tools/system/systemManagement.d.ts +1 -1
  38. package/lib/mcp/tools/system/systemManagement.js +1 -1
  39. package/lib/mcp/tools/users/schemas.d.ts +163 -296
  40. package/lib/mcp/tools/users/schemas.js +71 -152
  41. package/lib/mcp/tools/users/usersManagement.d.ts +2 -2
  42. package/lib/mcp/tools/users/usersManagement.js +2 -2
  43. package/lib/mcp/utils/sharedSchemas.d.ts +39 -28
  44. package/lib/mcp/utils/sharedSchemas.js +47 -28
  45. package/lib/resolvers/mutations/accounts/changePassword.js +1 -4
  46. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
- import { z } from 'zod';
1
+ import { z } from 'zod/v4-mini';
2
2
  import { SortDirection } from '@unchainedshop/utils';
3
3
  import { ProductType, ProductVariationType } from '@unchainedshop/core-products';
4
- import { PaginationSchema, SortingSchema, SearchSchema, LocalizationTextSchema, } from "../../utils/sharedSchemas.js";
4
+ import { PaginationSchema, SortingSchema, SearchSchema, LocalizationTextSchema, createManagementSchemaFromValidators, } from "../../utils/sharedSchemas.js";
5
5
  export const productTypeKeys = Object.keys(ProductType);
6
6
  export const productVariationTypeKeys = Object.keys(ProductVariationType);
7
7
  export const sortDirectionKeys = Object.keys(SortDirection);
@@ -14,395 +14,299 @@ export const ProductPlanConfigurationIntervalEnum = z.enum([
14
14
  'YEARS',
15
15
  ]);
16
16
  export const UpdateProductPlanInputSchema = z.object({
17
- usageCalculationType: ProductPlanUsageCalculationTypeEnum.describe('The billing usage calculation method'),
18
- billingInterval: ProductPlanConfigurationIntervalEnum.describe('The interval unit for billing cycles'),
19
- billingIntervalCount: z.number().int().positive().describe('Number of billing intervals per cycle'),
20
- trialInterval: ProductPlanConfigurationIntervalEnum.optional().describe('Optional trial period interval'),
21
- trialIntervalCount: z.number().int().positive().optional().describe('Number of trial intervals'),
17
+ usageCalculationType: ProductPlanUsageCalculationTypeEnum.check(z.describe('The billing usage calculation method')),
18
+ billingInterval: ProductPlanConfigurationIntervalEnum.check(z.describe('The interval unit for billing cycles')),
19
+ billingIntervalCount: z.int().check(z.positive(), z.describe('Number of billing intervals per cycle')),
20
+ trialInterval: z
21
+ .optional(ProductPlanConfigurationIntervalEnum)
22
+ .check(z.describe('Optional trial period interval')),
23
+ trialIntervalCount: z
24
+ .optional(z.int().check(z.positive()))
25
+ .check(z.describe('Number of trial intervals')),
22
26
  });
23
- export const ProductTextInputSchema = LocalizationTextSchema.extend({
24
- slug: z.string().optional().describe('URL slug'),
25
- description: z.string().optional().describe('Markdown description'),
26
- vendor: z.string().optional().describe('Vendor name'),
27
- brand: z.string().optional().describe('Brand name'),
28
- labels: z.array(z.string()).optional().describe('Labels or tags'),
29
- }).describe('Product localized text data');
30
- export const ProductVariationTextInputSchema = LocalizationTextSchema.describe('Product variation localized text data');
31
- export const ProductMediaTextInputSchema = LocalizationTextSchema.describe('Product media localized text data');
27
+ export const ProductTextInputSchema = z
28
+ .extend(LocalizationTextSchema, {
29
+ slug: z.optional(z.string()).check(z.describe('URL slug')),
30
+ description: z.optional(z.string()).check(z.describe('Markdown description')),
31
+ vendor: z.optional(z.string()).check(z.describe('Vendor name')),
32
+ brand: z.optional(z.string()).check(z.describe('Brand name')),
33
+ labels: z.optional(z.array(z.string())).check(z.describe('Labels or tags')),
34
+ })
35
+ .check(z.describe('Product localized text data'));
36
+ export const ProductVariationTextInputSchema = LocalizationTextSchema.check(z.describe('Product variation localized text data'));
37
+ export const ProductMediaTextInputSchema = LocalizationTextSchema.check(z.describe('Product media localized text data'));
32
38
  export const ProductAssignmentVectorSchema = z.object({
33
- key: z.string().min(1).describe('Attribute key (e.g., "Color", "Size")'),
34
- value: z.string().min(1).describe('Attribute value (e.g., "Red", "M")'),
39
+ key: z.string().check(z.minLength(1), z.describe('Attribute key (e.g., "Color", "Size")')),
40
+ value: z.string().check(z.minLength(1), z.describe('Attribute value (e.g., "Red", "M")')),
35
41
  });
36
42
  export const ProductSchema = z.object({
37
- type: z.enum(productTypeKeys).optional().describe('Product type (required for CREATE)'),
38
- tags: z.array(z.string().min(1).toLowerCase()).optional().describe('Tags (lowercased strings)'),
39
- sequence: z.number().int().optional().describe('Sorting sequence'),
40
- meta: z.record(z.any(), z.any()).optional().describe('Custom metadata as key-value pairs'),
41
- plan: UpdateProductPlanInputSchema.optional().describe('Plan configuration - ONLY for PLAN_PRODUCT'),
43
+ type: z.optional(z.enum(productTypeKeys)).check(z.describe('Product type (required for CREATE)')),
44
+ tags: z
45
+ .optional(z.array(z.string().check(z.minLength(1), z.toLowerCase())))
46
+ .check(z.describe('Tags (lowercased strings)')),
47
+ sequence: z.optional(z.int()).check(z.describe('Sorting sequence')),
48
+ meta: z.optional(z.record(z.any(), z.any())).check(z.describe('Custom metadata as key-value pairs')),
49
+ plan: z
50
+ .optional(UpdateProductPlanInputSchema)
51
+ .check(z.describe('Plan configuration - ONLY for PLAN_PRODUCT')),
42
52
  warehousing: z
43
- .object({
44
- sku: z.string().min(1).optional().describe('Stock keeping unit'),
45
- baseUnit: z.string().min(1).optional().describe('Base unit (e.g., "piece", "kg")'),
46
- })
47
- .optional()
48
- .describe('Warehousing details - ONLY for SIMPLE_PRODUCT'),
53
+ .optional(z.object({
54
+ sku: z.optional(z.string().check(z.minLength(1))).check(z.describe('Stock keeping unit')),
55
+ baseUnit: z
56
+ .optional(z.string().check(z.minLength(1)))
57
+ .check(z.describe('Base unit (e.g., "piece", "kg")')),
58
+ }))
59
+ .check(z.describe('Warehousing details - ONLY for SIMPLE_PRODUCT')),
49
60
  supply: z
50
- .object({
51
- weightInGram: z.number().int().positive().optional().describe('Weight in grams'),
52
- heightInMillimeters: z.number().int().positive().optional().describe('Height in millimeters'),
53
- lengthInMillimeters: z.number().int().positive().optional().describe('Length in millimeters'),
54
- widthInMillimeters: z.number().int().positive().optional().describe('Width in millimeters'),
55
- })
56
- .optional()
57
- .describe('Supply attributes - ONLY for SIMPLE_PRODUCT'),
61
+ .optional(z.object({
62
+ weightInGram: z.optional(z.int().check(z.positive())).check(z.describe('Weight in grams')),
63
+ heightInMillimeters: z
64
+ .optional(z.int().check(z.positive()))
65
+ .check(z.describe('Height in millimeters')),
66
+ lengthInMillimeters: z
67
+ .optional(z.int().check(z.positive()))
68
+ .check(z.describe('Length in millimeters')),
69
+ widthInMillimeters: z
70
+ .optional(z.int().check(z.positive()))
71
+ .check(z.describe('Width in millimeters')),
72
+ }))
73
+ .check(z.describe('Supply attributes - ONLY for SIMPLE_PRODUCT')),
58
74
  tokenization: z
59
- .object({
60
- contractAddress: z.string().min(1).describe('Blockchain contract address'),
61
- contractStandard: z.string().describe('Smart contract standard (e.g., ERC-721)'),
62
- tokenId: z.string().min(1).describe('Unique token identifier'),
63
- supply: z.number().int().positive().describe('Total supply of the token'),
75
+ .optional(z.object({
76
+ contractAddress: z.string().check(z.minLength(1), z.describe('Blockchain contract address')),
77
+ contractStandard: z.string().check(z.describe('Smart contract standard (e.g., ERC-721)')),
78
+ tokenId: z.string().check(z.minLength(1), z.describe('Unique token identifier')),
79
+ supply: z.int().check(z.positive(), z.describe('Total supply of the token')),
64
80
  ercMetadataProperties: z
65
- .record(z.any(), z.any())
66
- .optional()
67
- .describe('Optional ERC metadata properties'),
68
- })
69
- .optional()
70
- .describe('Tokenization details - ONLY for TOKENIZED_PRODUCT'),
81
+ .optional(z.record(z.any(), z.any()))
82
+ .check(z.describe('Optional ERC metadata properties')),
83
+ }))
84
+ .check(z.describe('Tokenization details - ONLY for TOKENIZED_PRODUCT')),
71
85
  commerce: z
72
- .object({
86
+ .optional(z.object({
73
87
  pricing: z
74
88
  .array(z.object({
75
- amount: z.number().int().describe('Price amount in smallest currency unit.'),
89
+ amount: z.int().check(z.describe('Price amount in smallest currency unit.')),
76
90
  maxQuantity: z
77
- .number()
78
- .int()
79
- .optional()
80
- .describe('Optional maximum quantity for this price tier'),
81
- isTaxable: z.boolean().optional().describe('Whether tax applies to this price'),
82
- isNetPrice: z.boolean().optional().describe('Whether this is a net price (without tax)'),
91
+ .optional(z.int())
92
+ .check(z.describe('Optional maximum quantity for this price tier')),
93
+ isTaxable: z.optional(z.boolean()).check(z.describe('Whether tax applies to this price')),
94
+ isNetPrice: z
95
+ .optional(z.boolean())
96
+ .check(z.describe('Whether this is a net price (without tax)')),
83
97
  currencyCode: z
84
98
  .string()
85
- .min(3)
86
- .max(3)
87
- .describe('ISO currency code (e.g., USD, EUR). Must match an available currency from the shop currencies resource. If it does not exist, prompt the user to add the currency. NEVER add it automatically unless explicitly specified by the user.'),
99
+ .check(z.minLength(3), z.maxLength(3), z.describe('ISO currency code (e.g., USD, EUR). Must match an available currency from the shop currencies resource. If it does not exist, prompt the user to add the currency. NEVER add it automatically unless explicitly specified by the user.')),
88
100
  countryCode: z
89
101
  .string()
90
- .min(2)
91
- .max(2)
92
- .describe('ISO country code (e.g., US, DE). Must match an available country from the shop countries resource. If it does not exist, prompt the user to add the country. NEVER add it automatically unless explicitly specified by the user.'),
102
+ .check(z.minLength(2), z.maxLength(2), z.describe('ISO country code (e.g., US, DE). Must match an available country from the shop countries resource. If it does not exist, prompt the user to add the country. NEVER add it automatically unless explicitly specified by the user.')),
93
103
  }))
94
- .nonempty()
95
- .describe('List of price configurations. Use only countryCode and currencyCode values from the shop resources.'),
96
- })
97
- .optional()
98
- .describe('Commerce info - Available for ALL except CONFIGURABLE_PRODUCT. Use only registered countries and currencies from shop resources.'),
104
+ .check(z.minLength(1), z.describe('List of price configurations. Use only countryCode and currencyCode values from the shop resources.')),
105
+ }))
106
+ .check(z.describe('Commerce info - Available for ALL except CONFIGURABLE_PRODUCT. Use only registered countries and currencies from shop resources.')),
99
107
  });
100
108
  export const actionValidators = {
101
109
  CREATE: z.object({
102
- product: ProductSchema.extend({
103
- type: z.enum(productTypeKeys).describe('Product type (required for CREATE)'),
104
- }).describe('Product data with type required'),
105
- texts: z.array(ProductTextInputSchema).optional().describe('Localized product text entries'),
110
+ product: z
111
+ .extend(ProductSchema, {
112
+ type: z.enum(productTypeKeys).check(z.describe('Product type (required for CREATE)')),
113
+ })
114
+ .check(z.describe('Product data with type required')),
115
+ texts: z
116
+ .optional(z.array(ProductTextInputSchema))
117
+ .check(z.describe('Localized product text entries')),
106
118
  }),
107
119
  UPDATE: z.object({
108
- productId: z.string().min(1).describe('Product ID'),
109
- product: ProductSchema.describe('Product data to update'),
120
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
121
+ product: ProductSchema.check(z.describe('Product data to update')),
110
122
  }),
111
123
  REMOVE: z.object({
112
124
  productId: z
113
125
  .string()
114
- .min(1)
115
- .describe('Product ID, (the product status to remove must be inactive or in DRAFT state other wise it will throw error) so if it is active please unpublish it first before removing the product'),
126
+ .check(z.minLength(1), z.describe('Product ID, (the product status to remove must be inactive or in DRAFT state other wise it will throw error) so if it is active please unpublish it first before removing the product')),
116
127
  }),
117
128
  GET: z
118
129
  .object({
119
- productId: z.string().min(1).optional().describe('Product ID'),
120
- slug: z.string().optional().describe('Product slug'),
121
- sku: z.string().optional().describe('Product SKU'),
130
+ productId: z.optional(z.string().check(z.minLength(1))).check(z.describe('Product ID')),
131
+ slug: z.optional(z.string()).check(z.describe('Product slug')),
132
+ sku: z.optional(z.string()).check(z.describe('Product SKU')),
122
133
  })
123
- .refine((data) => data.productId || data.slug || data.sku, {
134
+ .check(z.refine((data) => data.productId || data.slug || data.sku, {
124
135
  message: 'Either productId, slug, or sku is required',
125
- }),
136
+ })),
126
137
  LIST: z.object({
127
138
  ...PaginationSchema,
128
139
  ...SortingSchema,
129
140
  ...SearchSchema,
130
- tags: z.array(z.string().min(1).toLowerCase()).optional().describe('Filter by tags'),
131
- slugs: z.array(z.string().min(1)).optional().describe('Filter by product slugs'),
132
- includeDrafts: z.boolean().optional().describe('Include draft/unpublished products'),
141
+ tags: z
142
+ .optional(z.array(z.string().check(z.minLength(1), z.toLowerCase())))
143
+ .check(z.describe('Filter by tags')),
144
+ slugs: z
145
+ .optional(z.array(z.string().check(z.minLength(1))))
146
+ .check(z.describe('Filter by product slugs')),
147
+ includeDrafts: z.optional(z.boolean()).check(z.describe('Include draft/unpublished products')),
133
148
  }),
134
149
  COUNT: z.object({
135
150
  ...SearchSchema,
136
- tags: z.array(z.string().min(1).toLowerCase()).optional().describe('Filter by tags'),
137
- slugs: z.array(z.string().min(1)).optional().describe('Filter by product slugs'),
138
- includeDrafts: z.boolean().optional().describe('Include draft/unpublished products'),
151
+ tags: z
152
+ .optional(z.array(z.string().check(z.minLength(1), z.toLowerCase())))
153
+ .check(z.describe('Filter by tags')),
154
+ slugs: z
155
+ .optional(z.array(z.string().check(z.minLength(1))))
156
+ .check(z.describe('Filter by product slugs')),
157
+ includeDrafts: z.optional(z.boolean()).check(z.describe('Include draft/unpublished products')),
139
158
  }),
140
159
  UPDATE_STATUS: z.object({
141
- productId: z.string().min(1).describe('Product ID'),
142
- statusAction: z.enum(['PUBLISH', 'UNPUBLISH']).describe('Status action'),
160
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
161
+ statusAction: z.enum(['PUBLISH', 'UNPUBLISH']).check(z.describe('Status action')),
143
162
  }),
144
163
  ADD_MEDIA: z.object({
145
- productId: z.string().min(1).describe('Product ID'),
146
- mediaName: z.string().min(1).describe('Media file name'),
147
- url: z.string().url().describe('Media URL'),
164
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
165
+ mediaName: z.string().check(z.minLength(1), z.describe('Media file name')),
166
+ url: z.url().check(z.describe('Media URL')),
148
167
  }),
149
168
  REMOVE_MEDIA: z.object({
150
- productMediaId: z.string().min(1).describe('Product media ID'),
169
+ productMediaId: z.string().check(z.minLength(1), z.describe('Product media ID')),
151
170
  }),
152
171
  REORDER_MEDIA: z.object({
153
172
  sortKeys: z
154
173
  .array(z.object({
155
- productMediaId: z.string().min(1).describe('Media asset ID'),
156
- sortKey: z.number().int().describe('New sort position'),
174
+ productMediaId: z.string().check(z.minLength(1), z.describe('Media asset ID')),
175
+ sortKey: z.int().check(z.describe('New sort position')),
157
176
  }))
158
- .nonempty()
159
- .describe('Sort keys'),
177
+ .check(z.minLength(1), z.describe('Sort keys')),
160
178
  }),
161
179
  GET_MEDIA: z.object({
162
- productId: z.string().min(1).describe('Product ID'),
163
- tags: z.array(z.string().min(1).toLowerCase()).optional().describe('Filter by tags'),
180
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
181
+ tags: z
182
+ .optional(z.array(z.string().check(z.minLength(1), z.toLowerCase())))
183
+ .check(z.describe('Filter by tags')),
164
184
  ...PaginationSchema,
165
185
  }),
166
186
  UPDATE_MEDIA_TEXTS: z.object({
167
- productMediaId: z.string().min(1).describe('Product media ID'),
168
- mediaTexts: z.array(ProductMediaTextInputSchema).describe('Media texts'),
187
+ productMediaId: z.string().check(z.minLength(1), z.describe('Product media ID')),
188
+ mediaTexts: z.array(ProductMediaTextInputSchema).check(z.describe('Media texts')),
169
189
  }),
170
190
  CREATE_VARIATION: z.object({
171
- productId: z.string().min(1).describe('Product ID'),
191
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
172
192
  variation: z
173
193
  .object({
174
- key: z.string().min(1).describe('Unique variation key (e.g., "Color", "Size")'),
175
- type: z.enum(productVariationTypeKeys).describe('Variation type'),
194
+ key: z
195
+ .string()
196
+ .check(z.minLength(1), z.describe('Unique variation key (e.g., "Color", "Size")')),
197
+ type: z.enum(productVariationTypeKeys).check(z.describe('Variation type')),
176
198
  })
177
- .describe('Variation definition'),
178
- variationTexts: z.array(ProductVariationTextInputSchema).optional().describe('Variation texts'),
199
+ .check(z.describe('Variation definition')),
200
+ variationTexts: z
201
+ .optional(z.array(ProductVariationTextInputSchema))
202
+ .check(z.describe('Variation texts')),
179
203
  }),
180
204
  REMOVE_VARIATION: z.object({
181
- productVariationId: z.string().min(1).describe('Product variation ID'),
205
+ productVariationId: z.string().check(z.minLength(1), z.describe('Product variation ID')),
182
206
  }),
183
207
  ADD_VARIATION_OPTION: z.object({
184
- productVariationId: z.string().min(1).describe('Product variation ID'),
185
- option: z.string().min(1).describe('Option value'),
186
- variationTexts: z.array(ProductVariationTextInputSchema).optional().describe('Variation texts'),
208
+ productVariationId: z.string().check(z.minLength(1), z.describe('Product variation ID')),
209
+ option: z.string().check(z.minLength(1), z.describe('Option value')),
210
+ variationTexts: z
211
+ .optional(z.array(ProductVariationTextInputSchema))
212
+ .check(z.describe('Variation texts')),
187
213
  }),
188
214
  REMOVE_VARIATION_OPTION: z.object({
189
- productVariationId: z.string().min(1).describe('Product variation ID'),
190
- productVariationOptionValue: z.string().min(1).describe('Option value'),
215
+ productVariationId: z.string().check(z.minLength(1), z.describe('Product variation ID')),
216
+ productVariationOptionValue: z.string().check(z.minLength(1), z.describe('Option value')),
191
217
  }),
192
218
  UPDATE_VARIATION_TEXTS: z.object({
193
- productVariationId: z.string().min(1).describe('Product variation ID'),
194
- variationTexts: z.array(ProductVariationTextInputSchema).describe('Variation texts'),
195
- productVariationOptionValue: z.string().min(1).optional().describe('Option value'),
219
+ productVariationId: z.string().check(z.minLength(1), z.describe('Product variation ID')),
220
+ variationTexts: z.array(ProductVariationTextInputSchema).check(z.describe('Variation texts')),
221
+ productVariationOptionValue: z
222
+ .optional(z.string().check(z.minLength(1)))
223
+ .check(z.describe('Option value')),
196
224
  }),
197
225
  GET_VARIATION_PRODUCTS: z.object({
198
- productId: z.string().min(1).describe('Product ID'),
199
- vectors: z.array(ProductAssignmentVectorSchema).describe('Variation vectors'),
200
- includeInactive: z.boolean().optional().default(true).describe('Include inactive products'),
226
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
227
+ vectors: z.array(ProductAssignmentVectorSchema).check(z.describe('Variation vectors')),
228
+ includeInactive: z._default(z.boolean(), true).check(z.describe('Include inactive products')),
201
229
  }),
202
230
  GET_ASSIGNMENTS: z.object({
203
- productId: z.string().min(1).describe('Product ID'),
204
- includeInactive: z.boolean().optional().describe('Include inactive assignments'),
231
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
232
+ includeInactive: z.optional(z.boolean()).check(z.describe('Include inactive assignments')),
205
233
  }),
206
234
  ADD_ASSIGNMENT: z.object({
207
- proxyId: z.string().min(1).describe('Proxy product ID'),
208
- assignProductId: z.string().min(1).describe('Product to assign'),
209
- vectors: z.array(ProductAssignmentVectorSchema).describe('Variation vectors'),
235
+ proxyId: z.string().check(z.minLength(1), z.describe('Proxy product ID')),
236
+ assignProductId: z.string().check(z.minLength(1), z.describe('Product to assign')),
237
+ vectors: z.array(ProductAssignmentVectorSchema).check(z.describe('Variation vectors')),
210
238
  }),
211
239
  REMOVE_ASSIGNMENT: z.object({
212
- proxyId: z.string().min(1).describe('Proxy product ID'),
213
- vectors: z.array(ProductAssignmentVectorSchema).describe('Variation vectors'),
240
+ proxyId: z.string().check(z.minLength(1), z.describe('Proxy product ID')),
241
+ vectors: z.array(ProductAssignmentVectorSchema).check(z.describe('Variation vectors')),
214
242
  }),
215
243
  ADD_BUNDLE_ITEM: z.object({
216
- bundleId: z.string().min(1).describe('Bundle product ID'),
217
- bundleProductId: z.string().min(1).describe('Product to add to bundle'),
218
- quantity: z.number().int().positive().default(1).describe('Quantity'),
244
+ bundleId: z.string().check(z.minLength(1), z.describe('Bundle product ID')),
245
+ bundleProductId: z.string().check(z.minLength(1), z.describe('Product to add to bundle')),
246
+ quantity: z._default(z.int().check(z.positive()), 1).check(z.describe('Quantity')),
219
247
  }),
220
248
  REMOVE_BUNDLE_ITEM: z.object({
221
- bundleId: z.string().min(1).describe('Bundle product ID'),
222
- index: z.number().int().min(0).describe('Bundle item index'),
249
+ bundleId: z.string().check(z.minLength(1), z.describe('Bundle product ID')),
250
+ index: z.int().check(z.gte(0), z.describe('Bundle item index')),
223
251
  }),
224
252
  GET_BUNDLE_ITEMS: z.object({
225
- bundleId: z.string().min(1).describe('Bundle product ID'),
253
+ bundleId: z.string().check(z.minLength(1), z.describe('Bundle product ID')),
226
254
  }),
227
255
  GET_CATALOG_PRICE: z.object({
228
- productId: z.string().min(1).describe('Product ID'),
229
- quantity: z.number().int().positive().optional().describe('Quantity'),
230
- currencyCode: z.string().min(3).max(3).optional().describe('ISO currency code'),
256
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
257
+ quantity: z.optional(z.int().check(z.positive())).check(z.describe('Quantity')),
258
+ currencyCode: z
259
+ .optional(z.string().check(z.minLength(3), z.maxLength(3)))
260
+ .check(z.describe('ISO currency code')),
231
261
  }),
232
262
  SIMULATE_PRICE: z.object({
233
- productId: z.string().min(1).describe('Product ID'),
234
- vectors: z.array(ProductAssignmentVectorSchema).optional().describe('Variation vectors'),
235
- quantity: z.number().int().positive().optional().describe('Quantity'),
236
- currencyCode: z.string().min(3).max(3).optional().describe('ISO currency code'),
237
- useNetPrice: z.boolean().optional().describe('Whether to use net price'),
263
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
264
+ vectors: z.optional(z.array(ProductAssignmentVectorSchema)).check(z.describe('Variation vectors')),
265
+ quantity: z.optional(z.int().check(z.positive())).check(z.describe('Quantity')),
266
+ currencyCode: z
267
+ .optional(z.string().check(z.minLength(3), z.maxLength(3)))
268
+ .check(z.describe('ISO currency code')),
269
+ useNetPrice: z.optional(z.boolean()).check(z.describe('Whether to use net price')),
238
270
  }),
239
271
  SIMULATE_PRICE_RANGE: z.object({
240
- productId: z.string().min(1).describe('Product ID'),
241
- vectors: z.array(ProductAssignmentVectorSchema).optional().describe('Variation vectors'),
242
- quantity: z.number().int().positive().optional().describe('Quantity'),
243
- currencyCode: z.string().min(3).max(3).optional().describe('ISO currency code'),
244
- useNetPrice: z.boolean().optional().describe('Whether to use net price'),
272
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
273
+ vectors: z.optional(z.array(ProductAssignmentVectorSchema)).check(z.describe('Variation vectors')),
274
+ quantity: z.optional(z.int().check(z.positive())).check(z.describe('Quantity')),
275
+ currencyCode: z
276
+ .optional(z.string().check(z.minLength(3), z.maxLength(3)))
277
+ .check(z.describe('ISO currency code')),
278
+ useNetPrice: z.optional(z.boolean()).check(z.describe('Whether to use net price')),
245
279
  }),
246
280
  GET_PRODUCT_TEXTS: z.object({
247
- productId: z.string().min(1).describe('Product ID'),
281
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
248
282
  }),
249
283
  GET_VARIATION_TEXTS: z.object({
250
- productVariationId: z.string().min(1).describe('Product variation ID'),
251
- productVariationOptionValue: z.string().min(1).optional().describe('Option value'),
284
+ productVariationId: z.string().check(z.minLength(1), z.describe('Product variation ID')),
285
+ productVariationOptionValue: z
286
+ .optional(z.string().check(z.minLength(1)))
287
+ .check(z.describe('Option value')),
252
288
  }),
253
289
  GET_MEDIA_TEXTS: z.object({
254
- productMediaId: z.string().min(1).describe('Product media ID'),
290
+ productMediaId: z.string().check(z.minLength(1), z.describe('Product media ID')),
255
291
  }),
256
292
  GET_REVIEWS: z.object({
257
- productId: z.string().min(1).describe('Product ID'),
293
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
258
294
  ...PaginationSchema,
259
295
  ...SortingSchema,
260
296
  ...SearchSchema,
261
297
  }),
262
298
  COUNT_REVIEWS: z.object({
263
- productId: z.string().min(1).describe('Product ID'),
299
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
264
300
  ...SearchSchema,
265
301
  }),
266
302
  GET_SIBLINGS: z.object({
267
- productId: z.string().min(1).describe('Product ID'),
268
- assortmentId: z.string().optional().describe('Assortment ID'),
269
- includeInactive: z.boolean().optional().describe('Include inactive products'),
303
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
304
+ assortmentId: z.optional(z.string()).check(z.describe('Assortment ID')),
305
+ includeInactive: z.optional(z.boolean()).check(z.describe('Include inactive products')),
270
306
  }),
271
307
  UPDATE_PRODUCT_TEXTS: z.object({
272
- productId: z.string().min(1).describe('Product ID'),
273
- texts: z.array(ProductTextInputSchema).describe('Product texts to update'),
308
+ productId: z.string().check(z.minLength(1), z.describe('Product ID')),
309
+ texts: z.array(ProductTextInputSchema).check(z.describe('Product texts to update')),
274
310
  }),
275
311
  };
276
- export const ProductManagementSchema = {
277
- action: z
278
- .enum([
279
- 'CREATE',
280
- 'UPDATE',
281
- 'REMOVE',
282
- 'GET',
283
- 'LIST',
284
- 'COUNT',
285
- 'UPDATE_STATUS',
286
- 'ADD_MEDIA',
287
- 'REMOVE_MEDIA',
288
- 'REORDER_MEDIA',
289
- 'GET_MEDIA',
290
- 'UPDATE_MEDIA_TEXTS',
291
- 'CREATE_VARIATION',
292
- 'REMOVE_VARIATION',
293
- 'ADD_VARIATION_OPTION',
294
- 'REMOVE_VARIATION_OPTION',
295
- 'ADD_ASSIGNMENT',
296
- 'REMOVE_ASSIGNMENT',
297
- 'GET_ASSIGNMENTS',
298
- 'GET_VARIATION_PRODUCTS',
299
- 'UPDATE_VARIATION_TEXTS',
300
- 'ADD_BUNDLE_ITEM',
301
- 'REMOVE_BUNDLE_ITEM',
302
- 'GET_BUNDLE_ITEMS',
303
- 'SIMULATE_PRICE',
304
- 'SIMULATE_PRICE_RANGE',
305
- 'GET_CATALOG_PRICE',
306
- 'GET_PRODUCT_TEXTS',
307
- 'GET_MEDIA_TEXTS',
308
- 'GET_VARIATION_TEXTS',
309
- 'GET_REVIEWS',
310
- 'COUNT_REVIEWS',
311
- 'GET_SIBLINGS',
312
- 'UPDATE_PRODUCT_TEXTS',
313
- ])
314
- .describe('Product management action to perform'),
315
- productId: z
316
- .string()
317
- .min(1)
318
- .optional()
319
- .describe('Product ID (required for most actions except CREATE, LIST, COUNT)'),
320
- slug: z.string().optional().describe('Product slug (alternative to productId for GET action)'),
321
- sku: z.string().optional().describe('Product SKU (alternative to productId for GET action)'),
322
- productMediaId: z
323
- .string()
324
- .min(1)
325
- .optional()
326
- .describe('Product media ID (required for media-specific actions)'),
327
- productVariationId: z
328
- .string()
329
- .min(1)
330
- .optional()
331
- .describe('Product variation ID (required for variation-specific actions)'),
332
- product: ProductSchema.optional().describe('Product data object for CREATE/UPDATE actions'),
333
- texts: z
334
- .array(ProductTextInputSchema)
335
- .optional()
336
- .describe('Localized product text entries for CREATE action'),
337
- statusAction: z
338
- .enum(['PUBLISH', 'UNPUBLISH'])
339
- .optional()
340
- .describe('Status action for UPDATE_STATUS action'),
341
- mediaName: z.string().min(1).optional().describe('Media file name for ADD_MEDIA action'),
342
- url: z.string().url().optional().describe('Media URL for ADD_MEDIA action'),
343
- sortKeys: z
344
- .array(z.object({
345
- productMediaId: z.string().min(1).describe('Media asset ID'),
346
- sortKey: z.number().int().describe('New sort position'),
347
- }))
348
- .optional()
349
- .describe('Sort keys for REORDER_MEDIA action'),
350
- mediaTexts: z
351
- .array(ProductMediaTextInputSchema)
352
- .optional()
353
- .describe('Media text updates for UPDATE_MEDIA_TEXTS action'),
354
- tags: z.array(z.string()).optional().describe('Media tags filter for GET_MEDIA action'),
355
- variation: z
356
- .object({
357
- key: z.string().min(1).describe('Unique variation key (e.g., "Color", "Size")'),
358
- type: z.enum(productVariationTypeKeys).describe('Variation type from ProductVariationType enum'),
359
- })
360
- .optional()
361
- .describe('Variation definition for CREATE_VARIATION action'),
362
- option: z
363
- .string()
364
- .min(1)
365
- .optional()
366
- .describe('Option value for ADD_VARIATION_OPTION action (e.g., "Red", "Large")'),
367
- productVariationOptionValue: z
368
- .string()
369
- .min(1)
370
- .optional()
371
- .describe('Option value for REMOVE_VARIATION_OPTION action'),
372
- variationTexts: z
373
- .array(ProductVariationTextInputSchema)
374
- .optional()
375
- .describe('Variation text updates for UPDATE_VARIATION_TEXTS action'),
376
- assignProductId: z
377
- .string()
378
- .min(1)
379
- .optional()
380
- .describe('Product to assign (ADD_ASSIGNMENT/REMOVE_ASSIGNMENT actions)'),
381
- proxyId: z.string().min(1).optional().describe('CONFIGURABLE_PRODUCT ID for assignments'),
382
- vectors: z
383
- .array(ProductAssignmentVectorSchema)
384
- .optional()
385
- .describe('Complete variation combination vectors'),
386
- includeInactive: z.boolean().optional().describe('Include inactive variants in results'),
387
- bundleId: z
388
- .string()
389
- .min(1)
390
- .optional()
391
- .describe('Bundle product ID for ADD_BUNDLE_ITEM/REMOVE_BUNDLE_ITEM actions'),
392
- bundleProductId: z
393
- .string()
394
- .min(1)
395
- .optional()
396
- .describe('Product to add to bundle for ADD_BUNDLE_ITEM action'),
397
- index: z.number().int().min(0).optional().describe('Bundle item index for REMOVE_BUNDLE_ITEM action'),
398
- quantity: z.number().int().positive().optional().describe('Quantity for pricing calculations'),
399
- currencyCode: z.string().min(3).max(3).optional().describe('ISO currency code for pricing'),
400
- useNetPrice: z.boolean().optional().describe('Whether to use net price in calculations'),
401
- ...PaginationSchema,
402
- ...SortingSchema,
403
- ...SearchSchema,
404
- includeDrafts: z.boolean().optional().describe('Include draft products in results'),
405
- productIds: z.array(z.string()).optional().describe('Filter by specific product IDs'),
406
- assortmentId: z.string().optional().describe('Filter by assortment ID (for GET_SIBLINGS action)'),
407
- };
408
- export const ProductManagementZodSchema = z.object(ProductManagementSchema);
312
+ export const ProductManagementSchema = createManagementSchemaFromValidators(actionValidators);
@@ -1,6 +1,6 @@
1
1
  import type { Context } from '../../../context.ts';
2
- import { ProviderManagementSchema, ProviderManagementZodSchema, type ProviderManagementParams } from './schemas.ts';
3
- export { ProviderManagementSchema, ProviderManagementZodSchema };
2
+ import { ProviderManagementSchema, type ProviderManagementParams } from './schemas.ts';
3
+ export { ProviderManagementSchema };
4
4
  export type { ProviderManagementParams };
5
5
  export declare function providerManagement(context: Context, params: ProviderManagementParams): Promise<{
6
6
  content: {
@@ -1,8 +1,8 @@
1
1
  import { log } from '@unchainedshop/logger';
2
- import { actionValidators, ProviderManagementSchema, ProviderManagementZodSchema, } from "./schemas.js";
2
+ import { actionValidators, ProviderManagementSchema, } from "./schemas.js";
3
3
  import actionHandlers from "./handlers/index.js";
4
4
  import { createMcpErrorResponse, createMcpResponse } from "../../utils/sharedSchemas.js";
5
- export { ProviderManagementSchema, ProviderManagementZodSchema };
5
+ export { ProviderManagementSchema };
6
6
  export async function providerManagement(context, params) {
7
7
  const { action, ...actionParams } = params;
8
8
  log('MCP providerManagement', { userId: context.userId, params });