@cimplify/sdk 0.44.14 → 0.44.18

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 (85) hide show
  1. package/dist/advanced.d.mts +1 -1
  2. package/dist/advanced.d.ts +1 -1
  3. package/dist/advanced.js +22 -21
  4. package/dist/advanced.mjs +3 -2
  5. package/dist/{chunk-OMAP327U.js → chunk-3FS3ZDKX.js} +62 -61
  6. package/dist/chunk-53J2WE4S.js +657 -0
  7. package/dist/{chunk-3WD6U5RD.mjs → chunk-5OK3YDZC.mjs} +4 -3
  8. package/dist/{chunk-V2O5AO7I.js → chunk-BN2CXGMO.js} +5 -246
  9. package/dist/chunk-CCSONJCO.js +8824 -0
  10. package/dist/{chunk-BAWKQRIB.js → chunk-HBRCVJL4.js} +22 -21
  11. package/dist/chunk-MJBSVUHO.mjs +8822 -0
  12. package/dist/{chunk-6TVQQYQ5.mjs → chunk-NRT6PVW5.mjs} +4 -231
  13. package/dist/chunk-QBQCMQ4F.js +271 -0
  14. package/dist/chunk-VDH3O7UB.mjs +604 -0
  15. package/dist/chunk-XPXAZXF2.mjs +250 -0
  16. package/dist/{chunk-EZK2FXTM.mjs → chunk-XZPO5GEM.mjs} +2 -1
  17. package/dist/cli/commands/deploy.mjs +9 -1
  18. package/dist/client-B_Ei3ENB.d.mts +86 -0
  19. package/dist/client-Bep2FooI.d.ts +86 -0
  20. package/dist/{client-lvLvB1_K.d.ts → client-D6ZisKco.d.ts} +7 -0
  21. package/dist/{client-CkGlXZRd.d.mts → client-Dh-bHyhU.d.mts} +7 -0
  22. package/dist/index.d.mts +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +145 -144
  25. package/dist/index.mjs +4 -3
  26. package/dist/mock/cli.mjs +2 -1
  27. package/dist/mock/library.js +2 -1
  28. package/dist/mock/library.mjs +2 -1
  29. package/dist/mock/msw.js +2 -1
  30. package/dist/mock/msw.mjs +2 -1
  31. package/dist/react.d.mts +1 -1
  32. package/dist/react.d.ts +1 -1
  33. package/dist/react.js +81 -80
  34. package/dist/react.mjs +4 -3
  35. package/dist/server-CWpUlLOQ.d.mts +1003 -0
  36. package/dist/server-CWpUlLOQ.d.ts +1003 -0
  37. package/dist/server.d.mts +2 -2
  38. package/dist/server.d.ts +2 -2
  39. package/dist/server.js +6 -5
  40. package/dist/server.mjs +4 -3
  41. package/dist/testing/msw.d.mts +17 -0
  42. package/dist/testing/msw.d.ts +17 -0
  43. package/dist/testing/msw.js +42 -0
  44. package/dist/testing/msw.mjs +40 -0
  45. package/dist/testing/suite.d.mts +85 -0
  46. package/dist/testing/suite.d.ts +85 -0
  47. package/dist/testing/suite.js +174 -0
  48. package/dist/testing/suite.mjs +170 -0
  49. package/dist/testing.d.mts +1885 -0
  50. package/dist/testing.d.ts +1885 -0
  51. package/dist/testing.js +261 -0
  52. package/dist/testing.mjs +51 -0
  53. package/dist/utils.js +29 -28
  54. package/dist/utils.mjs +2 -1
  55. package/package.json +28 -4
  56. package/templates/storefront-bakery/__tests__/brand.test.ts +4 -0
  57. package/templates/storefront-bakery/__tests__/cart-flow.test.ts +4 -0
  58. package/templates/storefront-bakery/__tests__/contract.test.ts +4 -0
  59. package/templates/storefront-bakery/package.json +11 -3
  60. package/templates/storefront-bakery/vitest.config.ts +9 -0
  61. package/templates/storefront-fashion/__tests__/brand.test.ts +4 -0
  62. package/templates/storefront-fashion/__tests__/cart-flow.test.ts +4 -0
  63. package/templates/storefront-fashion/__tests__/contract.test.ts +4 -0
  64. package/templates/storefront-fashion/package.json +11 -3
  65. package/templates/storefront-fashion/vitest.config.ts +9 -0
  66. package/templates/storefront-grocery/__tests__/brand.test.ts +4 -0
  67. package/templates/storefront-grocery/__tests__/cart-flow.test.ts +4 -0
  68. package/templates/storefront-grocery/__tests__/contract.test.ts +4 -0
  69. package/templates/storefront-grocery/package.json +11 -3
  70. package/templates/storefront-grocery/vitest.config.ts +9 -0
  71. package/templates/storefront-restaurant/__tests__/brand.test.ts +4 -0
  72. package/templates/storefront-restaurant/__tests__/cart-flow.test.ts +4 -0
  73. package/templates/storefront-restaurant/__tests__/contract.test.ts +4 -0
  74. package/templates/storefront-restaurant/package.json +11 -3
  75. package/templates/storefront-restaurant/vitest.config.ts +9 -0
  76. package/templates/storefront-retail/__tests__/brand.test.ts +4 -0
  77. package/templates/storefront-retail/__tests__/cart-flow.test.ts +4 -0
  78. package/templates/storefront-retail/__tests__/contract.test.ts +4 -0
  79. package/templates/storefront-retail/package.json +11 -3
  80. package/templates/storefront-retail/vitest.config.ts +9 -0
  81. package/templates/storefront-services/__tests__/brand.test.ts +4 -0
  82. package/templates/storefront-services/__tests__/cart-flow.test.ts +4 -0
  83. package/templates/storefront-services/__tests__/contract.test.ts +4 -0
  84. package/templates/storefront-services/package.json +11 -3
  85. package/templates/storefront-services/vitest.config.ts +9 -0
@@ -0,0 +1,657 @@
1
+ 'use strict';
2
+
3
+ var chunk3FS3ZDKX_js = require('./chunk-3FS3ZDKX.js');
4
+ var chunkCCSONJCO_js = require('./chunk-CCSONJCO.js');
5
+ var zod = require('zod');
6
+
7
+ var cimplifyRegistry = zod.z.registry();
8
+ function registerSchema(schema, meta) {
9
+ cimplifyRegistry.add(schema, meta);
10
+ return schema;
11
+ }
12
+ var MoneySchema = registerSchema(
13
+ zod.z.string().regex(/^-?\d+\.\d{2}$/, 'Money must be a decimal string with exactly 2 decimals (e.g. "12.50")'),
14
+ { id: "Money", description: "Strict 2-decimal money string", version: "1.0.0" }
15
+ );
16
+ var MoneyLooseSchema = registerSchema(
17
+ zod.z.string().regex(/^-?\d+(\.\d+)?$/, "Must be a decimal string"),
18
+ { id: "MoneyLoose", description: "Decimal string with arbitrary precision", version: "1.0.0" }
19
+ );
20
+ var IsoDateTimeSchema = registerSchema(zod.z.iso.datetime(), {
21
+ id: "IsoDateTime",
22
+ description: "ISO 8601 date-time",
23
+ version: "1.0.0"
24
+ });
25
+ var TimestampSchema = registerSchema(
26
+ zod.z.union([zod.z.iso.datetime(), zod.z.string().min(1)]),
27
+ {
28
+ id: "Timestamp",
29
+ description: "ISO 8601 or any non-empty string (boundary use)",
30
+ version: "1.0.0"
31
+ }
32
+ );
33
+ var CurrencyCodeSchema = registerSchema(
34
+ zod.z.string().length(3, "currency must be a 3-letter ISO 4217 code").regex(/^[A-Z]{3}$/, "currency must be uppercase letters"),
35
+ { id: "CurrencyCode", description: "ISO 4217 currency code", version: "1.0.0" }
36
+ );
37
+ var CountryCodeSchema = registerSchema(
38
+ zod.z.string().length(2, "countryCode must be ISO 3166-1 alpha-2").regex(/^[A-Z]{2}$/, "countryCode must be uppercase letters"),
39
+ { id: "CountryCode", description: "ISO 3166-1 alpha-2 country code", version: "1.0.0" }
40
+ );
41
+ var LocaleSchema = registerSchema(
42
+ zod.z.string().regex(/^[a-z]{2}(_[A-Z]{2})?$/, "locale must look like 'en' or 'en_GH'"),
43
+ { id: "Locale", description: "BCP-47-ish locale", version: "1.0.0" }
44
+ );
45
+ var PhoneE164Schema = registerSchema(
46
+ zod.z.string().regex(/^\+?[0-9]{7,15}$/, "phoneTel should be E.164-ish digits (7\u201315)"),
47
+ { id: "PhoneE164", description: "E.164-ish phone number", version: "1.0.0" }
48
+ );
49
+ var SeedNameSchema = registerSchema(
50
+ zod.z.enum([
51
+ "default",
52
+ "empty",
53
+ "reesa-storefront",
54
+ "restaurant",
55
+ "retail",
56
+ "services",
57
+ "grocery",
58
+ "fashion"
59
+ ]),
60
+ { id: "SeedName", description: "Mock seed identifier", version: "1.0.0" }
61
+ );
62
+ var ProductTypeSchema = registerSchema(
63
+ zod.z.enum(["product", "service", "digital", "bundle", "composite"]),
64
+ { id: "ProductType", description: "Product type discriminator", version: "1.0.0" }
65
+ );
66
+ var LineTypeSchema = registerSchema(
67
+ zod.z.enum(["simple", "service", "digital", "bundle", "composite"]),
68
+ { id: "LineType", description: "Cart line type discriminator", version: "1.0.0" }
69
+ );
70
+ var ServiceStatusSchema = registerSchema(
71
+ zod.z.enum(["pending", "confirmed", "completed", "cancelled"]),
72
+ { id: "ServiceStatus", description: "Service booking status", version: "1.0.0" }
73
+ );
74
+ var SchemaViolationError = class extends Error {
75
+ constructor(message, label, issues) {
76
+ super(message);
77
+ this.label = label;
78
+ this.issues = issues;
79
+ this.name = "SchemaViolationError";
80
+ }
81
+ toJSON() {
82
+ return {
83
+ type: "https://cimplify.io/errors/schema-violation",
84
+ title: "Schema Violation",
85
+ status: 422,
86
+ detail: `${this.label} did not match its schema`,
87
+ errors: this.issues
88
+ };
89
+ }
90
+ };
91
+ function makeAssertion(schema, label) {
92
+ return (value) => {
93
+ const result = schema.safeParse(value);
94
+ if (!result.success) {
95
+ const pretty = zod.z.prettifyError(result.error);
96
+ const issues = result.error.issues.map((i) => ({
97
+ path: i.path.map(String),
98
+ message: i.message,
99
+ code: i.code
100
+ }));
101
+ throw new SchemaViolationError(
102
+ `${label} schema violation:
103
+ ${pretty}`,
104
+ label,
105
+ issues
106
+ );
107
+ }
108
+ };
109
+ }
110
+ var BrandSocialSchema = zod.z.object({
111
+ label: zod.z.string().min(1),
112
+ href: zod.z.string().url(),
113
+ icon: zod.z.string().optional()
114
+ });
115
+ var BrandNavLinkSchema = zod.z.object({
116
+ label: zod.z.string().min(1),
117
+ href: zod.z.string().min(1)
118
+ });
119
+ var BrandPolicySectionSchema = zod.z.object({
120
+ heading: zod.z.string().min(1),
121
+ body: zod.z.union([
122
+ zod.z.string().min(1),
123
+ zod.z.object({ intro: zod.z.string(), bullets: zod.z.array(zod.z.string()).min(1) })
124
+ ])
125
+ });
126
+ var BrandPolicyPageSchema = zod.z.object({
127
+ eyebrow: zod.z.string(),
128
+ title: zod.z.string().min(1),
129
+ lastUpdated: zod.z.string().min(1),
130
+ sections: zod.z.array(BrandPolicySectionSchema).min(1)
131
+ });
132
+ var BrandContactSchema = zod.z.object({
133
+ email: zod.z.string().email(),
134
+ phone: zod.z.string().min(1),
135
+ phoneTel: PhoneE164Schema,
136
+ streetAddress: zod.z.string().min(1),
137
+ city: zod.z.string().min(1),
138
+ countryCode: CountryCodeSchema,
139
+ hours: zod.z.string().optional()
140
+ });
141
+ var BrandHeroSchema = zod.z.object({
142
+ badge: zod.z.string().optional(),
143
+ title: zod.z.string().min(1),
144
+ subtitle: zod.z.string().min(1),
145
+ primaryCta: BrandNavLinkSchema.optional(),
146
+ secondaryCta: BrandNavLinkSchema.optional()
147
+ });
148
+ var BrandFaqSchema = zod.z.object({
149
+ eyebrow: zod.z.string().optional(),
150
+ title: zod.z.string().min(1),
151
+ sections: zod.z.array(
152
+ zod.z.object({
153
+ title: zod.z.string(),
154
+ items: zod.z.array(zod.z.object({ q: zod.z.string(), a: zod.z.string() }))
155
+ })
156
+ )
157
+ });
158
+ var BrandSchema = registerSchema(
159
+ zod.z.object({
160
+ // Identity
161
+ name: zod.z.string().min(1),
162
+ shortName: zod.z.string().min(1),
163
+ microTag: zod.z.string(),
164
+ description: zod.z.string().min(20, "description should be at least 20 characters"),
165
+ schemaType: zod.z.string().min(1),
166
+ currency: CurrencyCodeSchema,
167
+ locale: LocaleSchema,
168
+ contact: BrandContactSchema,
169
+ socials: zod.z.array(BrandSocialSchema),
170
+ header: zod.z.object({ nav: zod.z.array(BrandNavLinkSchema).min(1) }),
171
+ hero: BrandHeroSchema,
172
+ // Optional sections — render conditionally when present
173
+ trustItems: zod.z.array(zod.z.object({ title: zod.z.string().min(1), body: zod.z.string().min(1) })).optional(),
174
+ brandStrip: zod.z.object({ headline: zod.z.string(), logos: zod.z.array(zod.z.string()).min(1) }).optional(),
175
+ promo: zod.z.object({
176
+ eyebrow: zod.z.string().optional(),
177
+ title: zod.z.string().min(1),
178
+ cta: BrandNavLinkSchema
179
+ }).optional(),
180
+ // Standalone policy pages
181
+ terms: BrandPolicyPageSchema,
182
+ privacy: BrandPolicyPageSchema,
183
+ shipping: BrandPolicyPageSchema,
184
+ returns: BrandPolicyPageSchema,
185
+ accessibility: BrandPolicyPageSchema,
186
+ // Misc
187
+ newsletter: zod.z.object({
188
+ eyebrow: zod.z.string().optional(),
189
+ title: zod.z.string().min(1),
190
+ body: zod.z.string()
191
+ }),
192
+ about: zod.z.object({
193
+ eyebrow: zod.z.string().optional(),
194
+ title: zod.z.string().min(1),
195
+ body: zod.z.union([zod.z.string(), zod.z.array(zod.z.string())])
196
+ }),
197
+ faq: BrandFaqSchema,
198
+ account: zod.z.object({
199
+ eyebrow: zod.z.string().optional(),
200
+ title: zod.z.string().min(1),
201
+ signin: zod.z.object({ eyebrow: zod.z.string().optional(), title: zod.z.string().min(1) }).optional(),
202
+ signup: zod.z.object({ eyebrow: zod.z.string().optional(), title: zod.z.string().min(1) }).optional()
203
+ }),
204
+ contactPage: zod.z.object({
205
+ eyebrow: zod.z.string().optional(),
206
+ title: zod.z.string().min(1),
207
+ body: zod.z.string()
208
+ }),
209
+ trackOrder: zod.z.object({
210
+ eyebrow: zod.z.string().optional(),
211
+ title: zod.z.string().min(1),
212
+ body: zod.z.string()
213
+ }),
214
+ footer: zod.z.object({
215
+ sitemap: zod.z.array(zod.z.unknown()).optional(),
216
+ poweredBy: zod.z.string().optional()
217
+ }),
218
+ llms: zod.z.object({ summary: zod.z.string().min(20) }),
219
+ mock: zod.z.object({
220
+ seed: SeedNameSchema,
221
+ businessId: zod.z.string().regex(/^bus_/, "businessId should start with 'bus_'")
222
+ })
223
+ }),
224
+ {
225
+ id: "Brand",
226
+ description: "Single-source-of-truth contract for lib/brand.ts in storefront templates",
227
+ version: "1.0.0"
228
+ }
229
+ );
230
+ var assertBrand = makeAssertion(BrandSchema, "brand");
231
+ var BundleSelectionInputSchema = zod.z.object({
232
+ component_id: zod.z.string(),
233
+ variant_id: zod.z.string().optional(),
234
+ quantity: zod.z.number().int().positive(),
235
+ scheduled_start: zod.z.string().optional(),
236
+ scheduled_end: zod.z.string().optional()
237
+ });
238
+ var CompositeSelectionInputSchema = zod.z.object({
239
+ component_id: zod.z.string().optional(),
240
+ source_product_id: zod.z.string().optional(),
241
+ source_stock_id: zod.z.string().optional(),
242
+ source_type: zod.z.enum(["product", "stock", "add_on", "standalone"]).optional(),
243
+ quantity: zod.z.number().int().positive().optional()
244
+ });
245
+ var CustomerInputValueSchema = zod.z.object({
246
+ field_id: zod.z.string(),
247
+ field_name: zod.z.string().optional(),
248
+ field_type: zod.z.string().optional(),
249
+ value: zod.z.unknown()
250
+ });
251
+ var AddItemPayloadSchema = registerSchema(
252
+ zod.z.object({
253
+ item_id: zod.z.string().min(1),
254
+ quantity: zod.z.number().int().positive(),
255
+ variant_id: zod.z.string().optional(),
256
+ quote_id: zod.z.string().optional(),
257
+ add_on_options: zod.z.array(zod.z.string()).optional(),
258
+ bundle_selections: zod.z.array(BundleSelectionInputSchema).optional(),
259
+ composite_selections: zod.z.array(CompositeSelectionInputSchema).optional(),
260
+ scheduled_start: zod.z.string().optional(),
261
+ scheduled_end: zod.z.string().optional(),
262
+ staff_id: zod.z.string().optional(),
263
+ resource_id: zod.z.string().optional(),
264
+ special_instructions: zod.z.string().optional(),
265
+ customer_inputs: zod.z.array(CustomerInputValueSchema).optional(),
266
+ billing_plan_id: zod.z.string().optional(),
267
+ metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional()
268
+ }),
269
+ {
270
+ id: "AddItemPayload",
271
+ description: "POST /cart/items request body \u2014 strict on shape, lenient on optional fields",
272
+ version: "1.0.0"
273
+ }
274
+ );
275
+ var assertAddItemPayload = makeAssertion(AddItemPayloadSchema, "payload");
276
+ var VariantDisplayAttributeSchema = zod.z.object({
277
+ axis_id: zod.z.string(),
278
+ axis_name: zod.z.string(),
279
+ value_id: zod.z.string(),
280
+ value_name: zod.z.string()
281
+ });
282
+ var VariantInfoSchema = registerSchema(
283
+ zod.z.object({
284
+ id: zod.z.string(),
285
+ name: zod.z.string(),
286
+ sku: zod.z.string().optional(),
287
+ price_adjustment: MoneySchema,
288
+ display_attributes: zod.z.array(VariantDisplayAttributeSchema).optional(),
289
+ images: zod.z.array(zod.z.string()).optional()
290
+ }),
291
+ {
292
+ id: "VariantInfo",
293
+ description: "Variant axis values + display attributes \u2014 emitted on cart line items",
294
+ version: "1.0.0"
295
+ }
296
+ );
297
+ var VariantDetailsSchema = zod.z.object({
298
+ variant_id: zod.z.string(),
299
+ sku: zod.z.string().optional(),
300
+ properties: zod.z.record(zod.z.string(), zod.z.string())
301
+ });
302
+ var ChosenPriceSchema = zod.z.object({
303
+ base_price: MoneySchema,
304
+ final_price: MoneySchema,
305
+ markup_percentage: MoneySchema,
306
+ markup_amount: MoneySchema,
307
+ markup_discount_percentage: MoneySchema,
308
+ markup_discount_amount: MoneySchema
309
+ });
310
+ var AddOnDetailsSchema = zod.z.object({
311
+ selected_options: zod.z.array(zod.z.unknown()),
312
+ total_add_on_price: MoneySchema,
313
+ add_ons: zod.z.array(zod.z.unknown())
314
+ });
315
+ var BundleResolvedSchema = zod.z.looseObject({
316
+ bundle_id: zod.z.string(),
317
+ selections: zod.z.array(zod.z.unknown())
318
+ });
319
+ var CompositeResolvedSchema = zod.z.looseObject({
320
+ composite_id: zod.z.string(),
321
+ selections: zod.z.array(zod.z.unknown()),
322
+ breakdown: zod.z.object({
323
+ base_price: MoneySchema,
324
+ components_total: MoneySchema,
325
+ final_price: MoneySchema,
326
+ tier_applied: zod.z.string().optional()
327
+ }).optional()
328
+ });
329
+ var DiscountDetailsSchema = zod.z.object({
330
+ applied_count: zod.z.number().int().nonnegative(),
331
+ total_amount: MoneySchema,
332
+ discount_ids: zod.z.array(zod.z.string())
333
+ });
334
+ var CartItemSchema = registerSchema(
335
+ zod.z.looseObject({
336
+ id: zod.z.string(),
337
+ cart_id: zod.z.string(),
338
+ item_id: zod.z.string(),
339
+ quantity: zod.z.number().int().nonnegative(),
340
+ line_key: zod.z.string(),
341
+ line_type: LineTypeSchema,
342
+ name: zod.z.string(),
343
+ description: zod.z.string().optional(),
344
+ image_url: zod.z.string().optional(),
345
+ category_id: zod.z.string().optional(),
346
+ category_name: zod.z.string().optional(),
347
+ is_available: zod.z.boolean(),
348
+ variant_id: zod.z.string().optional(),
349
+ variant_name: zod.z.string().optional(),
350
+ variant_info: VariantInfoSchema.optional(),
351
+ variant_details: VariantDetailsSchema.optional(),
352
+ base_price: MoneySchema,
353
+ add_ons_price: MoneySchema,
354
+ total_price: MoneySchema,
355
+ item_discount_amount: MoneySchema,
356
+ price_info: ChosenPriceSchema,
357
+ add_on_option_ids: zod.z.array(zod.z.string()),
358
+ add_on_ids: zod.z.array(zod.z.string()),
359
+ add_on_details: AddOnDetailsSchema,
360
+ add_on_options: zod.z.array(zod.z.unknown()),
361
+ add_ons: zod.z.array(zod.z.unknown()),
362
+ scheduled_start: zod.z.string().optional(),
363
+ scheduled_end: zod.z.string().optional(),
364
+ staff_id: zod.z.string().optional(),
365
+ resource_id: zod.z.string().optional(),
366
+ service_status: ServiceStatusSchema.optional(),
367
+ confirmation_code: zod.z.string().optional(),
368
+ special_instructions: zod.z.string().optional(),
369
+ customer_inputs: zod.z.array(CustomerInputValueSchema).optional(),
370
+ bundle_selections: zod.z.unknown().optional(),
371
+ bundle_resolved: BundleResolvedSchema.optional(),
372
+ composite_selections: zod.z.unknown().optional(),
373
+ composite_resolved: CompositeResolvedSchema.optional(),
374
+ billing_plan_id: zod.z.string().optional(),
375
+ applied_discount_ids: zod.z.array(zod.z.string()),
376
+ discount_details: DiscountDetailsSchema.optional(),
377
+ metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
378
+ created_at: TimestampSchema,
379
+ updated_at: TimestampSchema
380
+ }),
381
+ {
382
+ id: "CartItem",
383
+ description: "Cart line item \u2014 loose so backend additions don't break old SDK clients",
384
+ version: "1.0.0"
385
+ }
386
+ );
387
+ var assertCartItem = makeAssertion(CartItemSchema, "cartItem");
388
+ var CartPricingSchema = registerSchema(
389
+ zod.z.object({
390
+ subtotal: MoneySchema,
391
+ total_discounts: MoneySchema,
392
+ tax_amount: MoneySchema,
393
+ service_charge: MoneySchema,
394
+ total_price: MoneySchema,
395
+ currency: CurrencyCodeSchema,
396
+ tax_rate: MoneySchema.optional(),
397
+ service_charge_rate: MoneySchema.optional()
398
+ }),
399
+ {
400
+ id: "CartPricing",
401
+ description: "Cart-level pricing roll-up \u2014 subtotal, tax, service, total",
402
+ version: "1.0.0"
403
+ }
404
+ );
405
+ var CartSchema = registerSchema(
406
+ zod.z.looseObject({
407
+ id: zod.z.string(),
408
+ business_id: zod.z.string(),
409
+ items: zod.z.array(CartItemSchema),
410
+ pricing: CartPricingSchema,
411
+ customer_info: zod.z.object({
412
+ name: zod.z.string(),
413
+ email: zod.z.string().optional(),
414
+ phone: zod.z.string().optional(),
415
+ address: zod.z.string().optional()
416
+ }),
417
+ created_at: TimestampSchema,
418
+ updated_at: TimestampSchema,
419
+ expires_at: TimestampSchema,
420
+ status: zod.z.string(),
421
+ source: zod.z.string(),
422
+ channel: zod.z.string()
423
+ }),
424
+ {
425
+ id: "Cart",
426
+ description: "Full cart envelope \u2014 loose for forward-compat with backend additions",
427
+ version: "1.0.0"
428
+ }
429
+ );
430
+ var assertCart = makeAssertion(CartSchema, "cart");
431
+ var CheckoutCustomerSchema = zod.z.object({
432
+ name: zod.z.string().min(1),
433
+ email: zod.z.string().email(),
434
+ phone: zod.z.string().min(1),
435
+ notes: zod.z.string().optional(),
436
+ save_details: zod.z.boolean().optional()
437
+ });
438
+ var CheckoutBodySchema = registerSchema(
439
+ zod.z.object({
440
+ cart_id: zod.z.string().min(1),
441
+ location_id: zod.z.string().optional(),
442
+ customer: CheckoutCustomerSchema,
443
+ order_type: zod.z.string().min(1),
444
+ address_info: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
445
+ payment_method: zod.z.string().min(1),
446
+ mobile_money_details: zod.z.object({ phone_number: zod.z.string(), provider: zod.z.string() }).optional(),
447
+ special_instructions: zod.z.string().optional(),
448
+ metadata: zod.z.record(zod.z.string(), zod.z.unknown()).optional(),
449
+ pay_currency: zod.z.string().optional(),
450
+ fx_quote_id: zod.z.string().optional()
451
+ }),
452
+ {
453
+ id: "CheckoutBody",
454
+ description: "POST /checkout request body",
455
+ version: "1.0.0"
456
+ }
457
+ );
458
+ var assertCheckoutBody = makeAssertion(CheckoutBodySchema, "checkoutBody");
459
+ var AuthorizationTypeSchema = zod.z.enum(["otp", "pin", "phone", "birthday", "address"]);
460
+ var NextActionSchema = zod.z.discriminatedUnion("type", [
461
+ zod.z.object({ type: zod.z.literal("none") }),
462
+ zod.z.object({ type: zod.z.literal("redirect"), authorization_url: zod.z.string() }),
463
+ zod.z.object({
464
+ type: zod.z.literal("authorization"),
465
+ authorization_type: zod.z.string(),
466
+ display_text: zod.z.string().optional()
467
+ })
468
+ ]);
469
+ var CheckoutResponseSchema = registerSchema(
470
+ zod.z.looseObject({
471
+ order_id: zod.z.string().min(1),
472
+ order_number: zod.z.string().min(1),
473
+ payment_status: zod.z.string().min(1),
474
+ payment_reference: zod.z.string().optional(),
475
+ requires_authorization: zod.z.boolean(),
476
+ authorization_type: AuthorizationTypeSchema.optional(),
477
+ next_action: NextActionSchema,
478
+ provider: zod.z.string().optional(),
479
+ authorization_url: zod.z.string().optional(),
480
+ display_text: zod.z.string().optional(),
481
+ bill_token: zod.z.string().optional(),
482
+ client_secret: zod.z.string().optional(),
483
+ public_key: zod.z.string().optional()
484
+ }),
485
+ {
486
+ id: "CheckoutResponse",
487
+ description: "POST /checkout response \u2014 loose for payment-provider field additions",
488
+ version: "1.0.0"
489
+ }
490
+ );
491
+ var assertCheckoutResponse = makeAssertion(CheckoutResponseSchema, "checkout");
492
+
493
+ // src/testing/client.ts
494
+ var TEST_BASE_URL = "http://test.local";
495
+ async function toForwardedRequest(input, init) {
496
+ if (input instanceof Request) {
497
+ return {
498
+ method: init?.method ?? input.method,
499
+ headers: new Headers(init?.headers ?? input.headers),
500
+ body: init?.body ?? (["GET", "HEAD"].includes(input.method) ? void 0 : await input.text())
501
+ };
502
+ }
503
+ return {
504
+ method: init?.method ?? "GET",
505
+ headers: new Headers(init?.headers ?? {}),
506
+ body: init?.body ?? void 0
507
+ };
508
+ }
509
+ function createTestClient(options = {}) {
510
+ const mock = chunkCCSONJCO_js.createMockApp(options);
511
+ let sessionToken;
512
+ const fetchImpl = async (input, init) => {
513
+ const url = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
514
+ if (!url.startsWith(TEST_BASE_URL)) {
515
+ return globalThis.fetch(input, init);
516
+ }
517
+ const path = url.slice(TEST_BASE_URL.length);
518
+ const fwd = await toForwardedRequest(input, init);
519
+ if (sessionToken) fwd.headers.set("x-session-token", sessionToken);
520
+ const res = await mock.request(path, {
521
+ method: fwd.method,
522
+ headers: fwd.headers,
523
+ body: fwd.body
524
+ });
525
+ const echoed = res.headers.get("x-session-token");
526
+ if (echoed) sessionToken = echoed;
527
+ return res;
528
+ };
529
+ const client = chunk3FS3ZDKX_js.createCimplifyClient({
530
+ baseUrl: TEST_BASE_URL,
531
+ publicKey: "test-public-key",
532
+ suppressPublicKeyWarning: true,
533
+ fetch: fetchImpl
534
+ });
535
+ return {
536
+ client,
537
+ mock,
538
+ reset: () => {
539
+ mock.deps.resetAll();
540
+ sessionToken = void 0;
541
+ },
542
+ dispose: () => {
543
+ mock.deps.resetAll();
544
+ sessionToken = void 0;
545
+ }
546
+ };
547
+ }
548
+ async function pickProduct(client, opts) {
549
+ const list = await client.catalogue.getProducts();
550
+ if (!list.ok) throw list.error;
551
+ const body = list.value;
552
+ const products = body.items ?? [];
553
+ if (products.length === 0) throw new Error("No products in catalogue (wrong seed?)");
554
+ if (opts.slug) {
555
+ const found = products.find((p) => p.slug === opts.slug);
556
+ if (!found) throw new Error(`Product slug "${opts.slug}" not found in catalogue`);
557
+ return found;
558
+ }
559
+ return products.find((p) => p.type === "product") ?? products[0];
560
+ }
561
+ var fixtures = {
562
+ /**
563
+ * Add the first available product (or a named one) to the cart.
564
+ * Picks the first variant if the product has variants.
565
+ */
566
+ async addFirstProduct(client, opts = {}) {
567
+ const product = await pickProduct(client, opts);
568
+ let variantId;
569
+ if (opts.withVariant !== false) {
570
+ const variants = await client.catalogue.getVariants(product.id);
571
+ if (variants.ok && variants.value.length > 0) {
572
+ variantId = variants.value[0]?.id;
573
+ }
574
+ }
575
+ const res = await client.cart.addItem({
576
+ item_id: product.id,
577
+ quantity: 1,
578
+ variant_id: variantId
579
+ });
580
+ if (!res.ok) throw res.error;
581
+ return { product, variantId };
582
+ },
583
+ /** A minimal valid customer object for checkout. */
584
+ customer(overrides = {}) {
585
+ return {
586
+ name: overrides.name ?? "Test Customer",
587
+ email: overrides.email ?? "test@example.com",
588
+ phone: overrides.phone ?? "+233244000000"
589
+ };
590
+ },
591
+ /**
592
+ * Run the full guest auth flow (request OTP → verify) and return
593
+ * the new session token. The mock's permissive auth mode echoes
594
+ * the code in `request_otp`, so we don't need to read it.
595
+ */
596
+ async authenticate(client, contact = "test@example.com", code = "123456") {
597
+ const req = await client.auth.requestOtp(contact);
598
+ if (!req.ok) throw req.error;
599
+ const verify = await client.auth.verifyOtp(contact, code);
600
+ if (!verify.ok) throw verify.error;
601
+ const value = verify.value;
602
+ return { token: value.session_token ?? "", customerId: value.customer_id ?? "" };
603
+ }
604
+ };
605
+
606
+ exports.AddItemPayloadSchema = AddItemPayloadSchema;
607
+ exports.AddOnDetailsSchema = AddOnDetailsSchema;
608
+ exports.AuthorizationTypeSchema = AuthorizationTypeSchema;
609
+ exports.BrandContactSchema = BrandContactSchema;
610
+ exports.BrandFaqSchema = BrandFaqSchema;
611
+ exports.BrandHeroSchema = BrandHeroSchema;
612
+ exports.BrandNavLinkSchema = BrandNavLinkSchema;
613
+ exports.BrandPolicyPageSchema = BrandPolicyPageSchema;
614
+ exports.BrandPolicySectionSchema = BrandPolicySectionSchema;
615
+ exports.BrandSchema = BrandSchema;
616
+ exports.BrandSocialSchema = BrandSocialSchema;
617
+ exports.BundleResolvedSchema = BundleResolvedSchema;
618
+ exports.BundleSelectionInputSchema = BundleSelectionInputSchema;
619
+ exports.CartItemSchema = CartItemSchema;
620
+ exports.CartPricingSchema = CartPricingSchema;
621
+ exports.CartSchema = CartSchema;
622
+ exports.CheckoutBodySchema = CheckoutBodySchema;
623
+ exports.CheckoutCustomerSchema = CheckoutCustomerSchema;
624
+ exports.CheckoutResponseSchema = CheckoutResponseSchema;
625
+ exports.ChosenPriceSchema = ChosenPriceSchema;
626
+ exports.CompositeResolvedSchema = CompositeResolvedSchema;
627
+ exports.CompositeSelectionInputSchema = CompositeSelectionInputSchema;
628
+ exports.CountryCodeSchema = CountryCodeSchema;
629
+ exports.CurrencyCodeSchema = CurrencyCodeSchema;
630
+ exports.CustomerInputValueSchema = CustomerInputValueSchema;
631
+ exports.DiscountDetailsSchema = DiscountDetailsSchema;
632
+ exports.IsoDateTimeSchema = IsoDateTimeSchema;
633
+ exports.LineTypeSchema = LineTypeSchema;
634
+ exports.LocaleSchema = LocaleSchema;
635
+ exports.MoneyLooseSchema = MoneyLooseSchema;
636
+ exports.MoneySchema = MoneySchema;
637
+ exports.NextActionSchema = NextActionSchema;
638
+ exports.PhoneE164Schema = PhoneE164Schema;
639
+ exports.ProductTypeSchema = ProductTypeSchema;
640
+ exports.SchemaViolationError = SchemaViolationError;
641
+ exports.SeedNameSchema = SeedNameSchema;
642
+ exports.ServiceStatusSchema = ServiceStatusSchema;
643
+ exports.TimestampSchema = TimestampSchema;
644
+ exports.VariantDetailsSchema = VariantDetailsSchema;
645
+ exports.VariantDisplayAttributeSchema = VariantDisplayAttributeSchema;
646
+ exports.VariantInfoSchema = VariantInfoSchema;
647
+ exports.assertAddItemPayload = assertAddItemPayload;
648
+ exports.assertBrand = assertBrand;
649
+ exports.assertCart = assertCart;
650
+ exports.assertCartItem = assertCartItem;
651
+ exports.assertCheckoutBody = assertCheckoutBody;
652
+ exports.assertCheckoutResponse = assertCheckoutResponse;
653
+ exports.cimplifyRegistry = cimplifyRegistry;
654
+ exports.createTestClient = createTestClient;
655
+ exports.fixtures = fixtures;
656
+ exports.makeAssertion = makeAssertion;
657
+ exports.registerSchema = registerSchema;
@@ -1,5 +1,5 @@
1
- import { safe, generateIdempotencyKey, CatalogueQueries, CartOperations, CheckoutService, OrderQueries, LinkService, AuthService, BusinessService, InventoryService, SchedulingService, LiteService, FxService, createElements } from './chunk-EZK2FXTM.mjs';
2
- import { CimplifyError, ErrorCode, IdempotencyMismatchError, enrichError } from './chunk-6TVQQYQ5.mjs';
1
+ import { safe, generateIdempotencyKey, CatalogueQueries, CartOperations, CheckoutService, OrderQueries, LinkService, AuthService, BusinessService, InventoryService, SchedulingService, LiteService, FxService, createElements } from './chunk-XZPO5GEM.mjs';
2
+ import { CimplifyError, ErrorCode, IdempotencyMismatchError, enrichError } from './chunk-XPXAZXF2.mjs';
3
3
 
4
4
  // src/activity.ts
5
5
  var ActivityService = class {
@@ -391,6 +391,7 @@ var CimplifyClient = class {
391
391
  this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;
392
392
  this.retryDelay = config.retryDelay ?? DEFAULT_RETRY_DELAY_MS;
393
393
  this.hooks = config.hooks ?? {};
394
+ this.fetchImpl = (config.fetch ?? globalThis.fetch).bind(globalThis);
394
395
  this.accessToken = this.loadAccessToken();
395
396
  this.sessionToken = this.loadSessionToken();
396
397
  if (!this.publicKey && !config.suppressPublicKeyWarning) {
@@ -595,7 +596,7 @@ var CimplifyClient = class {
595
596
  try {
596
597
  const controller = new AbortController();
597
598
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
598
- const response = await fetch(url, {
599
+ const response = await this.fetchImpl(url, {
599
600
  ...options,
600
601
  signal: controller.signal
601
602
  });