@tonytang99/integration-canonical 1.0.0 → 1.1.0

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 (38) hide show
  1. package/README.md +414 -1
  2. package/dist/index.d.ts +5 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +80 -15
  5. package/dist/index.js.map +1 -1
  6. package/dist/schemas/customer.d.ts +746 -0
  7. package/dist/schemas/customer.d.ts.map +1 -0
  8. package/dist/schemas/customer.js +282 -0
  9. package/dist/schemas/customer.js.map +1 -0
  10. package/dist/schemas/index.d.ts +13 -0
  11. package/dist/schemas/index.d.ts.map +1 -0
  12. package/dist/schemas/index.js +33 -0
  13. package/dist/schemas/index.js.map +1 -0
  14. package/dist/schemas/inventory.d.ts +1642 -0
  15. package/dist/schemas/inventory.d.ts.map +1 -0
  16. package/dist/schemas/inventory.js +302 -0
  17. package/dist/schemas/inventory.js.map +1 -0
  18. package/dist/schemas/order.d.ts +1339 -0
  19. package/dist/schemas/order.d.ts.map +1 -0
  20. package/dist/schemas/order.js +310 -0
  21. package/dist/schemas/order.js.map +1 -0
  22. package/dist/schemas/product.d.ts +717 -0
  23. package/dist/schemas/product.d.ts.map +1 -0
  24. package/dist/schemas/product.js +303 -0
  25. package/dist/schemas/product.js.map +1 -0
  26. package/dist/slots.d.ts +572 -0
  27. package/dist/slots.d.ts.map +1 -0
  28. package/dist/slots.js +20 -0
  29. package/dist/slots.js.map +1 -0
  30. package/dist/types/common.d.ts +284 -0
  31. package/dist/types/common.d.ts.map +1 -0
  32. package/dist/types/common.js +401 -0
  33. package/dist/types/common.js.map +1 -0
  34. package/dist/types/enrichments.d.ts +378 -0
  35. package/dist/types/enrichments.d.ts.map +1 -0
  36. package/dist/types/enrichments.js +96 -0
  37. package/dist/types/enrichments.js.map +1 -0
  38. package/package.json +2 -1
@@ -0,0 +1,284 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Currency codes following ISO 4217
4
+ * Common currencies for e-commerce
5
+ */
6
+ export declare const CurrencyCode: z.ZodEnum<["USD", "EUR", "GBP", "AUD", "CAD", "NZD", "JPY", "CNY", "INR", "SGD", "HKD", "MXN", "BRL", "ZAR"]>;
7
+ export type CurrencyCode = z.infer<typeof CurrencyCode>;
8
+ /**
9
+ * Money representation using minor units (cents)
10
+ *
11
+ * Examples:
12
+ * - $19.99 USD = { amount: 1999, currency: 'USD' }
13
+ * - €50.00 EUR = { amount: 5000, currency: 'EUR' }
14
+ * - ¥1000 JPY = { amount: 1000, currency: 'JPY' } (JPY has no minor units)
15
+ *
16
+ * @property amount - Amount in minor units (cents). Always an integer.
17
+ * @property currency - ISO 4217 currency code
18
+ */
19
+ export declare const MoneySchema: z.ZodObject<{
20
+ amount: z.ZodNumber;
21
+ currency: z.ZodEnum<["USD", "EUR", "GBP", "AUD", "CAD", "NZD", "JPY", "CNY", "INR", "SGD", "HKD", "MXN", "BRL", "ZAR"]>;
22
+ }, "strip", z.ZodTypeAny, {
23
+ amount: number;
24
+ currency: "USD" | "EUR" | "GBP" | "AUD" | "CAD" | "NZD" | "JPY" | "CNY" | "INR" | "SGD" | "HKD" | "MXN" | "BRL" | "ZAR";
25
+ }, {
26
+ amount: number;
27
+ currency: "USD" | "EUR" | "GBP" | "AUD" | "CAD" | "NZD" | "JPY" | "CNY" | "INR" | "SGD" | "HKD" | "MXN" | "BRL" | "ZAR";
28
+ }>;
29
+ export type Money = z.infer<typeof MoneySchema>;
30
+ /**
31
+ * Helper functions for Money
32
+ */
33
+ export declare const MoneyHelper: {
34
+ /**
35
+ * Create Money from major units (dollars)
36
+ * @example MoneyHelper.fromMajor(19.99, 'USD') // { amount: 1999, currency: 'USD' }
37
+ */
38
+ fromMajor(majorAmount: number, currency: CurrencyCode): Money;
39
+ /**
40
+ * Convert Money to major units (dollars)
41
+ * @example MoneyHelper.toMajor({ amount: 1999, currency: 'USD' }) // 19.99
42
+ */
43
+ toMajor(money: Money): number;
44
+ /**
45
+ * Get number of minor units (decimal places) for a currency
46
+ */
47
+ getMinorUnits(currency: CurrencyCode): number;
48
+ /**
49
+ * Format Money for display
50
+ * @example MoneyHelper.format({ amount: 1999, currency: 'USD' }) // "$19.99"
51
+ */
52
+ format(money: Money, locale?: string): string;
53
+ /**
54
+ * Add two Money values (must be same currency)
55
+ */
56
+ add(a: Money, b: Money): Money;
57
+ /**
58
+ * Subtract two Money values (must be same currency)
59
+ */
60
+ subtract(a: Money, b: Money): Money;
61
+ /**
62
+ * Multiply Money by a scalar
63
+ */
64
+ multiply(money: Money, multiplier: number): Money;
65
+ /**
66
+ * Check if money is zero
67
+ */
68
+ isZero(money: Money): boolean;
69
+ /**
70
+ * Check if money is positive
71
+ */
72
+ isPositive(money: Money): boolean;
73
+ /**
74
+ * Check if money is negative
75
+ */
76
+ isNegative(money: Money): boolean;
77
+ /**
78
+ * Get absolute value
79
+ */
80
+ abs(money: Money): Money;
81
+ /**
82
+ * Create zero money
83
+ */
84
+ zero(currency: CurrencyCode): Money;
85
+ };
86
+ /**
87
+ * Country codes following ISO 3166-1 alpha-2
88
+ */
89
+ export declare const CountryCode: z.ZodEnum<["US", "CA", "GB", "AU", "NZ", "DE", "FR", "IT", "ES", "NL", "BE", "CH", "AT", "SE", "NO", "DK", "FI", "IE", "PT", "PL", "CZ", "JP", "CN", "IN", "SG", "HK", "MX", "BR", "ZA"]>;
90
+ export type CountryCode = z.infer<typeof CountryCode>;
91
+ /**
92
+ * Address type classification
93
+ */
94
+ export declare const AddressType: z.ZodEnum<["billing", "shipping", "both"]>;
95
+ export type AddressType = z.infer<typeof AddressType>;
96
+ /**
97
+ * Base address schema with all common fields
98
+ * Designed to accommodate addresses from BigCommerce, MYOB, Adobe Commerce, etc.
99
+ */
100
+ export declare const AddressSchema: z.ZodObject<{
101
+ street1: z.ZodString;
102
+ street2: z.ZodOptional<z.ZodString>;
103
+ street3: z.ZodOptional<z.ZodString>;
104
+ city: z.ZodString;
105
+ state: z.ZodOptional<z.ZodString>;
106
+ stateCode: z.ZodOptional<z.ZodString>;
107
+ postalCode: z.ZodString;
108
+ country: z.ZodString;
109
+ countryCode: z.ZodOptional<z.ZodEnum<["US", "CA", "GB", "AU", "NZ", "DE", "FR", "IT", "ES", "NL", "BE", "CH", "AT", "SE", "NO", "DK", "FI", "IE", "PT", "PL", "CZ", "JP", "CN", "IN", "SG", "HK", "MX", "BR", "ZA"]>>;
110
+ company: z.ZodOptional<z.ZodString>;
111
+ firstName: z.ZodOptional<z.ZodString>;
112
+ lastName: z.ZodOptional<z.ZodString>;
113
+ phone: z.ZodOptional<z.ZodString>;
114
+ email: z.ZodOptional<z.ZodString>;
115
+ type: z.ZodOptional<z.ZodEnum<["billing", "shipping", "both"]>>;
116
+ isDefault: z.ZodOptional<z.ZodBoolean>;
117
+ isResidential: z.ZodOptional<z.ZodBoolean>;
118
+ isValidated: z.ZodOptional<z.ZodBoolean>;
119
+ validationSource: z.ZodOptional<z.ZodString>;
120
+ }, "strip", z.ZodTypeAny, {
121
+ street1: string;
122
+ city: string;
123
+ postalCode: string;
124
+ country: string;
125
+ type?: "billing" | "shipping" | "both" | undefined;
126
+ street2?: string | undefined;
127
+ street3?: string | undefined;
128
+ state?: string | undefined;
129
+ stateCode?: string | undefined;
130
+ countryCode?: "US" | "CA" | "GB" | "AU" | "NZ" | "DE" | "FR" | "IT" | "ES" | "NL" | "BE" | "CH" | "AT" | "SE" | "NO" | "DK" | "FI" | "IE" | "PT" | "PL" | "CZ" | "JP" | "CN" | "IN" | "SG" | "HK" | "MX" | "BR" | "ZA" | undefined;
131
+ company?: string | undefined;
132
+ firstName?: string | undefined;
133
+ lastName?: string | undefined;
134
+ phone?: string | undefined;
135
+ email?: string | undefined;
136
+ isDefault?: boolean | undefined;
137
+ isResidential?: boolean | undefined;
138
+ isValidated?: boolean | undefined;
139
+ validationSource?: string | undefined;
140
+ }, {
141
+ street1: string;
142
+ city: string;
143
+ postalCode: string;
144
+ country: string;
145
+ type?: "billing" | "shipping" | "both" | undefined;
146
+ street2?: string | undefined;
147
+ street3?: string | undefined;
148
+ state?: string | undefined;
149
+ stateCode?: string | undefined;
150
+ countryCode?: "US" | "CA" | "GB" | "AU" | "NZ" | "DE" | "FR" | "IT" | "ES" | "NL" | "BE" | "CH" | "AT" | "SE" | "NO" | "DK" | "FI" | "IE" | "PT" | "PL" | "CZ" | "JP" | "CN" | "IN" | "SG" | "HK" | "MX" | "BR" | "ZA" | undefined;
151
+ company?: string | undefined;
152
+ firstName?: string | undefined;
153
+ lastName?: string | undefined;
154
+ phone?: string | undefined;
155
+ email?: string | undefined;
156
+ isDefault?: boolean | undefined;
157
+ isResidential?: boolean | undefined;
158
+ isValidated?: boolean | undefined;
159
+ validationSource?: string | undefined;
160
+ }>;
161
+ export type Address = z.infer<typeof AddressSchema>;
162
+ /**
163
+ * Minimal address schema for cases where full address isn't required
164
+ */
165
+ export declare const MinimalAddressSchema: z.ZodObject<{
166
+ street1: z.ZodString;
167
+ city: z.ZodString;
168
+ postalCode: z.ZodString;
169
+ country: z.ZodString;
170
+ }, "strip", z.ZodTypeAny, {
171
+ street1: string;
172
+ city: string;
173
+ postalCode: string;
174
+ country: string;
175
+ }, {
176
+ street1: string;
177
+ city: string;
178
+ postalCode: string;
179
+ country: string;
180
+ }>;
181
+ export type MinimalAddress = z.infer<typeof MinimalAddressSchema>;
182
+ /**
183
+ * Helper functions for Address
184
+ */
185
+ export declare const AddressHelper: {
186
+ /**
187
+ * Format address as a multi-line string
188
+ */
189
+ format(address: Address): string;
190
+ /**
191
+ * Format address as a single line
192
+ */
193
+ formatSingleLine(address: Address): string;
194
+ /**
195
+ * Check if two addresses are similar (fuzzy match)
196
+ */
197
+ areSimilar(a: Address, b: Address): boolean;
198
+ /**
199
+ * Create a minimal address from full address
200
+ */
201
+ toMinimal(address: Address): MinimalAddress;
202
+ /**
203
+ * Validate postal code format for specific countries
204
+ */
205
+ isValidPostalCode(postalCode: string, countryCode: CountryCode): boolean;
206
+ /**
207
+ * Get full name from address
208
+ */
209
+ getFullName(address: Address): string | null;
210
+ /**
211
+ * Check if address is complete (has all required fields)
212
+ */
213
+ isComplete(address: Partial<Address>): boolean;
214
+ /**
215
+ * Create a copy of address with specific type
216
+ */
217
+ withType(address: Address, type: AddressType): Address;
218
+ };
219
+ /**
220
+ * Phone number schema with international support
221
+ */
222
+ export declare const PhoneNumberSchema: z.ZodObject<{
223
+ number: z.ZodString;
224
+ countryCode: z.ZodOptional<z.ZodString>;
225
+ extension: z.ZodOptional<z.ZodString>;
226
+ type: z.ZodOptional<z.ZodEnum<["mobile", "home", "work", "fax", "other"]>>;
227
+ }, "strip", z.ZodTypeAny, {
228
+ number: string;
229
+ type?: "mobile" | "home" | "work" | "fax" | "other" | undefined;
230
+ countryCode?: string | undefined;
231
+ extension?: string | undefined;
232
+ }, {
233
+ number: string;
234
+ type?: "mobile" | "home" | "work" | "fax" | "other" | undefined;
235
+ countryCode?: string | undefined;
236
+ extension?: string | undefined;
237
+ }>;
238
+ export type PhoneNumber = z.infer<typeof PhoneNumberSchema>;
239
+ /**
240
+ * Helper functions for PhoneNumber
241
+ */
242
+ export declare const PhoneNumberHelper: {
243
+ /**
244
+ * Format phone number for display
245
+ */
246
+ format(phone: PhoneNumber): string;
247
+ /**
248
+ * Parse phone number string into components
249
+ */
250
+ parse(phoneString: string): PhoneNumber;
251
+ };
252
+ export declare const WeightUnit: z.ZodEnum<["g", "kg", "oz", "lb"]>;
253
+ export type WeightUnit = z.infer<typeof WeightUnit>;
254
+ export declare const WeightSchema: z.ZodObject<{
255
+ value: z.ZodNumber;
256
+ unit: z.ZodEnum<["g", "kg", "oz", "lb"]>;
257
+ }, "strip", z.ZodTypeAny, {
258
+ value: number;
259
+ unit: "g" | "kg" | "oz" | "lb";
260
+ }, {
261
+ value: number;
262
+ unit: "g" | "kg" | "oz" | "lb";
263
+ }>;
264
+ export type Weight = z.infer<typeof WeightSchema>;
265
+ export declare const DimensionUnit: z.ZodEnum<["cm", "m", "mm", "in", "ft"]>;
266
+ export type DimensionUnit = z.infer<typeof DimensionUnit>;
267
+ export declare const DimensionsSchema: z.ZodObject<{
268
+ length: z.ZodNumber;
269
+ width: z.ZodNumber;
270
+ height: z.ZodNumber;
271
+ unit: z.ZodEnum<["cm", "m", "mm", "in", "ft"]>;
272
+ }, "strip", z.ZodTypeAny, {
273
+ length: number;
274
+ unit: "cm" | "m" | "mm" | "in" | "ft";
275
+ width: number;
276
+ height: number;
277
+ }, {
278
+ length: number;
279
+ unit: "cm" | "m" | "mm" | "in" | "ft";
280
+ width: number;
281
+ height: number;
282
+ }>;
283
+ export type Dimensions = z.infer<typeof DimensionsSchema>;
284
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/types/common.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,401 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DimensionsSchema = exports.DimensionUnit = exports.WeightSchema = exports.WeightUnit = exports.PhoneNumberHelper = exports.PhoneNumberSchema = exports.AddressHelper = exports.MinimalAddressSchema = exports.AddressSchema = exports.AddressType = exports.CountryCode = exports.MoneyHelper = exports.MoneySchema = exports.CurrencyCode = void 0;
4
+ // packages/canonical/src/types/common.ts
5
+ const zod_1 = require("zod");
6
+ // ============================================================================
7
+ // MONEY SCHEMA
8
+ // ============================================================================
9
+ /**
10
+ * Currency codes following ISO 4217
11
+ * Common currencies for e-commerce
12
+ */
13
+ exports.CurrencyCode = zod_1.z.enum([
14
+ 'USD', // US Dollar
15
+ 'EUR', // Euro
16
+ 'GBP', // British Pound
17
+ 'AUD', // Australian Dollar
18
+ 'CAD', // Canadian Dollar
19
+ 'NZD', // New Zealand Dollar
20
+ 'JPY', // Japanese Yen
21
+ 'CNY', // Chinese Yuan
22
+ 'INR', // Indian Rupee
23
+ 'SGD', // Singapore Dollar
24
+ 'HKD', // Hong Kong Dollar
25
+ 'MXN', // Mexican Peso
26
+ 'BRL', // Brazilian Real
27
+ 'ZAR', // South African Rand
28
+ ]);
29
+ /**
30
+ * Money representation using minor units (cents)
31
+ *
32
+ * Examples:
33
+ * - $19.99 USD = { amount: 1999, currency: 'USD' }
34
+ * - €50.00 EUR = { amount: 5000, currency: 'EUR' }
35
+ * - ¥1000 JPY = { amount: 1000, currency: 'JPY' } (JPY has no minor units)
36
+ *
37
+ * @property amount - Amount in minor units (cents). Always an integer.
38
+ * @property currency - ISO 4217 currency code
39
+ */
40
+ exports.MoneySchema = zod_1.z.object({
41
+ amount: zod_1.z.number().int('Amount must be in minor units (cents)'),
42
+ currency: exports.CurrencyCode,
43
+ });
44
+ /**
45
+ * Helper functions for Money
46
+ */
47
+ exports.MoneyHelper = {
48
+ /**
49
+ * Create Money from major units (dollars)
50
+ * @example MoneyHelper.fromMajor(19.99, 'USD') // { amount: 1999, currency: 'USD' }
51
+ */
52
+ fromMajor(majorAmount, currency) {
53
+ const minorUnits = this.getMinorUnits(currency);
54
+ return {
55
+ amount: Math.round(majorAmount * Math.pow(10, minorUnits)),
56
+ currency,
57
+ };
58
+ },
59
+ /**
60
+ * Convert Money to major units (dollars)
61
+ * @example MoneyHelper.toMajor({ amount: 1999, currency: 'USD' }) // 19.99
62
+ */
63
+ toMajor(money) {
64
+ const minorUnits = this.getMinorUnits(money.currency);
65
+ return money.amount / Math.pow(10, minorUnits);
66
+ },
67
+ /**
68
+ * Get number of minor units (decimal places) for a currency
69
+ */
70
+ getMinorUnits(currency) {
71
+ // Most currencies have 2 decimal places
72
+ const noDecimalCurrencies = ['JPY', 'KRW']; // Japanese Yen, Korean Won
73
+ return noDecimalCurrencies.includes(currency) ? 0 : 2;
74
+ },
75
+ /**
76
+ * Format Money for display
77
+ * @example MoneyHelper.format({ amount: 1999, currency: 'USD' }) // "$19.99"
78
+ */
79
+ format(money, locale = 'en-US') {
80
+ const major = this.toMajor(money);
81
+ return new Intl.NumberFormat(locale, {
82
+ style: 'currency',
83
+ currency: money.currency,
84
+ }).format(major);
85
+ },
86
+ /**
87
+ * Add two Money values (must be same currency)
88
+ */
89
+ add(a, b) {
90
+ if (a.currency !== b.currency) {
91
+ throw new Error(`Cannot add different currencies: ${a.currency} and ${b.currency}`);
92
+ }
93
+ return {
94
+ amount: a.amount + b.amount,
95
+ currency: a.currency,
96
+ };
97
+ },
98
+ /**
99
+ * Subtract two Money values (must be same currency)
100
+ */
101
+ subtract(a, b) {
102
+ if (a.currency !== b.currency) {
103
+ throw new Error(`Cannot subtract different currencies: ${a.currency} and ${b.currency}`);
104
+ }
105
+ return {
106
+ amount: a.amount - b.amount,
107
+ currency: a.currency,
108
+ };
109
+ },
110
+ /**
111
+ * Multiply Money by a scalar
112
+ */
113
+ multiply(money, multiplier) {
114
+ return {
115
+ amount: Math.round(money.amount * multiplier),
116
+ currency: money.currency,
117
+ };
118
+ },
119
+ /**
120
+ * Check if money is zero
121
+ */
122
+ isZero(money) {
123
+ return money.amount === 0;
124
+ },
125
+ /**
126
+ * Check if money is positive
127
+ */
128
+ isPositive(money) {
129
+ return money.amount > 0;
130
+ },
131
+ /**
132
+ * Check if money is negative
133
+ */
134
+ isNegative(money) {
135
+ return money.amount < 0;
136
+ },
137
+ /**
138
+ * Get absolute value
139
+ */
140
+ abs(money) {
141
+ return {
142
+ amount: Math.abs(money.amount),
143
+ currency: money.currency,
144
+ };
145
+ },
146
+ /**
147
+ * Create zero money
148
+ */
149
+ zero(currency) {
150
+ return {
151
+ amount: 0,
152
+ currency,
153
+ };
154
+ },
155
+ };
156
+ // ============================================================================
157
+ // ADDRESS SCHEMA
158
+ // ============================================================================
159
+ /**
160
+ * Country codes following ISO 3166-1 alpha-2
161
+ */
162
+ exports.CountryCode = zod_1.z.enum([
163
+ 'US', // United States
164
+ 'CA', // Canada
165
+ 'GB', // United Kingdom
166
+ 'AU', // Australia
167
+ 'NZ', // New Zealand
168
+ 'DE', // Germany
169
+ 'FR', // France
170
+ 'IT', // Italy
171
+ 'ES', // Spain
172
+ 'NL', // Netherlands
173
+ 'BE', // Belgium
174
+ 'CH', // Switzerland
175
+ 'AT', // Austria
176
+ 'SE', // Sweden
177
+ 'NO', // Norway
178
+ 'DK', // Denmark
179
+ 'FI', // Finland
180
+ 'IE', // Ireland
181
+ 'PT', // Portugal
182
+ 'PL', // Poland
183
+ 'CZ', // Czech Republic
184
+ 'JP', // Japan
185
+ 'CN', // China
186
+ 'IN', // India
187
+ 'SG', // Singapore
188
+ 'HK', // Hong Kong
189
+ 'MX', // Mexico
190
+ 'BR', // Brazil
191
+ 'ZA', // South Africa
192
+ ]);
193
+ /**
194
+ * Address type classification
195
+ */
196
+ exports.AddressType = zod_1.z.enum([
197
+ 'billing',
198
+ 'shipping',
199
+ 'both',
200
+ ]);
201
+ /**
202
+ * Base address schema with all common fields
203
+ * Designed to accommodate addresses from BigCommerce, MYOB, Adobe Commerce, etc.
204
+ */
205
+ exports.AddressSchema = zod_1.z.object({
206
+ // Primary address lines
207
+ street1: zod_1.z.string().min(1, 'Street address is required'),
208
+ street2: zod_1.z.string().optional(),
209
+ street3: zod_1.z.string().optional(), // Some systems support 3 lines
210
+ // Location details
211
+ city: zod_1.z.string().min(1, 'City is required'),
212
+ state: zod_1.z.string().optional(), // State/Province/Region
213
+ stateCode: zod_1.z.string().optional(), // State code (e.g., 'CA', 'NSW')
214
+ postalCode: zod_1.z.string().min(1, 'Postal code is required'),
215
+ country: zod_1.z.string().min(1, 'Country is required'),
216
+ countryCode: exports.CountryCode.optional(),
217
+ // Contact information (optional at address level)
218
+ company: zod_1.z.string().optional(),
219
+ firstName: zod_1.z.string().optional(),
220
+ lastName: zod_1.z.string().optional(),
221
+ phone: zod_1.z.string().optional(),
222
+ email: zod_1.z.string().email().optional(),
223
+ // Address metadata
224
+ type: exports.AddressType.optional(),
225
+ isDefault: zod_1.z.boolean().optional(),
226
+ isResidential: zod_1.z.boolean().optional(),
227
+ // Validation/verification flags
228
+ isValidated: zod_1.z.boolean().optional(),
229
+ validationSource: zod_1.z.string().optional(),
230
+ });
231
+ /**
232
+ * Minimal address schema for cases where full address isn't required
233
+ */
234
+ exports.MinimalAddressSchema = zod_1.z.object({
235
+ street1: zod_1.z.string(),
236
+ city: zod_1.z.string(),
237
+ postalCode: zod_1.z.string(),
238
+ country: zod_1.z.string(),
239
+ });
240
+ /**
241
+ * Helper functions for Address
242
+ */
243
+ exports.AddressHelper = {
244
+ /**
245
+ * Format address as a multi-line string
246
+ */
247
+ format(address) {
248
+ const lines = [];
249
+ // Name/Company line
250
+ if (address.company) {
251
+ lines.push(address.company);
252
+ }
253
+ if (address.firstName || address.lastName) {
254
+ lines.push([address.firstName, address.lastName].filter(Boolean).join(' '));
255
+ }
256
+ // Street lines
257
+ lines.push(address.street1);
258
+ if (address.street2)
259
+ lines.push(address.street2);
260
+ if (address.street3)
261
+ lines.push(address.street3);
262
+ // City, State, Postal Code
263
+ const cityLine = [
264
+ address.city,
265
+ address.stateCode || address.state,
266
+ address.postalCode,
267
+ ].filter(Boolean).join(', ');
268
+ lines.push(cityLine);
269
+ // Country
270
+ lines.push(address.country);
271
+ return lines.join('\n');
272
+ },
273
+ /**
274
+ * Format address as a single line
275
+ */
276
+ formatSingleLine(address) {
277
+ return this.format(address).replace(/\n/g, ', ');
278
+ },
279
+ /**
280
+ * Check if two addresses are similar (fuzzy match)
281
+ */
282
+ areSimilar(a, b) {
283
+ const normalize = (str) => str.toLowerCase().replace(/[^a-z0-9]/g, '');
284
+ return (normalize(a.street1) === normalize(b.street1) &&
285
+ normalize(a.city) === normalize(b.city) &&
286
+ normalize(a.postalCode) === normalize(b.postalCode) &&
287
+ normalize(a.country) === normalize(b.country));
288
+ },
289
+ /**
290
+ * Create a minimal address from full address
291
+ */
292
+ toMinimal(address) {
293
+ return {
294
+ street1: address.street1,
295
+ city: address.city,
296
+ postalCode: address.postalCode,
297
+ country: address.country,
298
+ };
299
+ },
300
+ /**
301
+ * Validate postal code format for specific countries
302
+ */
303
+ isValidPostalCode(postalCode, countryCode) {
304
+ const patterns = {
305
+ US: /^\d{5}(-\d{4})?$/, // 12345 or 12345-6789
306
+ CA: /^[A-Z]\d[A-Z] \d[A-Z]\d$/i, // A1A 1A1
307
+ GB: /^[A-Z]{1,2}\d{1,2}[A-Z]? \d[A-Z]{2}$/i, // SW1A 1AA
308
+ AU: /^\d{4}$/, // 2000
309
+ DE: /^\d{5}$/, // 12345
310
+ FR: /^\d{5}$/, // 75001
311
+ JP: /^\d{3}-\d{4}$/, // 123-4567
312
+ };
313
+ const pattern = patterns[countryCode];
314
+ return pattern ? pattern.test(postalCode) : true; // Default to valid if no pattern
315
+ },
316
+ /**
317
+ * Get full name from address
318
+ */
319
+ getFullName(address) {
320
+ if (!address.firstName && !address.lastName) {
321
+ return null;
322
+ }
323
+ return [address.firstName, address.lastName].filter(Boolean).join(' ');
324
+ },
325
+ /**
326
+ * Check if address is complete (has all required fields)
327
+ */
328
+ isComplete(address) {
329
+ return !!(address.street1 &&
330
+ address.city &&
331
+ address.postalCode &&
332
+ address.country);
333
+ },
334
+ /**
335
+ * Create a copy of address with specific type
336
+ */
337
+ withType(address, type) {
338
+ return {
339
+ ...address,
340
+ type,
341
+ };
342
+ },
343
+ };
344
+ // ============================================================================
345
+ // PHONE NUMBER SCHEMA
346
+ // ============================================================================
347
+ /**
348
+ * Phone number schema with international support
349
+ */
350
+ exports.PhoneNumberSchema = zod_1.z.object({
351
+ number: zod_1.z.string().min(1, 'Phone number is required'),
352
+ countryCode: zod_1.z.string().optional(), // e.g., '+1', '+44'
353
+ extension: zod_1.z.string().optional(),
354
+ type: zod_1.z.enum(['mobile', 'home', 'work', 'fax', 'other']).optional(),
355
+ });
356
+ /**
357
+ * Helper functions for PhoneNumber
358
+ */
359
+ exports.PhoneNumberHelper = {
360
+ /**
361
+ * Format phone number for display
362
+ */
363
+ format(phone) {
364
+ let formatted = phone.countryCode ? `${phone.countryCode} ${phone.number}` : phone.number;
365
+ if (phone.extension) {
366
+ formatted += ` ext. ${phone.extension}`;
367
+ }
368
+ return formatted;
369
+ },
370
+ /**
371
+ * Parse phone number string into components
372
+ */
373
+ parse(phoneString) {
374
+ // Simple parsing - in production, use libphonenumber-js
375
+ const match = phoneString.match(/^(\+\d+)?\s*([\d\s\-\(\)]+?)(?:\s*(?:ext|x)\s*(\d+))?$/i);
376
+ if (!match) {
377
+ return { number: phoneString };
378
+ }
379
+ return {
380
+ countryCode: match[1] || undefined,
381
+ number: match[2].replace(/[\s\-\(\)]/g, ''),
382
+ extension: match[3] || undefined,
383
+ };
384
+ },
385
+ };
386
+ // ============================================================================
387
+ // WEIGHT & DIMENSIONS
388
+ // ============================================================================
389
+ exports.WeightUnit = zod_1.z.enum(['g', 'kg', 'oz', 'lb']);
390
+ exports.WeightSchema = zod_1.z.object({
391
+ value: zod_1.z.number().min(0),
392
+ unit: exports.WeightUnit,
393
+ });
394
+ exports.DimensionUnit = zod_1.z.enum(['cm', 'm', 'mm', 'in', 'ft']);
395
+ exports.DimensionsSchema = zod_1.z.object({
396
+ length: zod_1.z.number().min(0),
397
+ width: zod_1.z.number().min(0),
398
+ height: zod_1.z.number().min(0),
399
+ unit: exports.DimensionUnit,
400
+ });
401
+ //# sourceMappingURL=common.js.map