@final-commerce/common 2.5.1-online.1 → 2.5.1-online.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +144 -1
- package/dist/index.d.ts +144 -1
- package/dist/index.js +403 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +381 -0
- package/dist/index.mjs.map +1 -1
- package/dist/pos-types/index.d.mts +33 -1
- package/dist/pos-types/index.d.ts +33 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -30,6 +30,7 @@ __export(index_exports, {
|
|
|
30
30
|
BookingResourceStatus: () => BookingResourceStatus,
|
|
31
31
|
BookingRulesError: () => BookingRulesError,
|
|
32
32
|
BookingType: () => BookingType,
|
|
33
|
+
CANADA_PROVINCES: () => CANADA_PROVINCES,
|
|
33
34
|
CONDITION_OPERATORS: () => CONDITION_OPERATORS,
|
|
34
35
|
COUNTRY_CURRENCIES: () => COUNTRY_CURRENCIES,
|
|
35
36
|
CURRENCY_CONFIG: () => CURRENCY_CONFIG,
|
|
@@ -46,6 +47,7 @@ __export(index_exports, {
|
|
|
46
47
|
DualWriteStrategy: () => DualWriteStrategy,
|
|
47
48
|
EUFixedRates: () => EUFixedRates,
|
|
48
49
|
EUROPE: () => EUROPE,
|
|
50
|
+
EVERYWHERE_KEY: () => EVERYWHERE_KEY,
|
|
49
51
|
ExtensionCategory: () => ExtensionCategory,
|
|
50
52
|
FINANCIAL_INVARIANTS: () => FINANCIAL_INVARIANTS,
|
|
51
53
|
FULFILLMENT_STATES: () => FULFILLMENT_STATES,
|
|
@@ -96,6 +98,12 @@ __export(index_exports, {
|
|
|
96
98
|
SYSTEM_FAMILY_IDS: () => SYSTEM_FAMILY_IDS,
|
|
97
99
|
SYSTEM_UNITS: () => SYSTEM_UNITS,
|
|
98
100
|
SYSTEM_UNIT_IDS: () => SYSTEM_UNIT_IDS,
|
|
101
|
+
ShippingChannel: () => ShippingChannel,
|
|
102
|
+
ShippingNoOptionReason: () => ShippingNoOptionReason,
|
|
103
|
+
ShippingOptionType: () => ShippingOptionType,
|
|
104
|
+
ShippingRateType: () => ShippingRateType,
|
|
105
|
+
ShippingZoneError: () => ShippingZoneError,
|
|
106
|
+
ShippingZoneKind: () => ShippingZoneKind,
|
|
99
107
|
StationStatus: () => StationStatus,
|
|
100
108
|
StripeCurrencyCode: () => StripeCurrencyCode,
|
|
101
109
|
StripeStatus: () => StripeStatus,
|
|
@@ -103,6 +111,7 @@ __export(index_exports, {
|
|
|
103
111
|
TopMetericsSort: () => TopMetericsSort,
|
|
104
112
|
UserTypes: () => UserTypes,
|
|
105
113
|
addAmounts: () => addAmounts,
|
|
114
|
+
addressPlaceKeys: () => addressPlaceKeys,
|
|
106
115
|
amountToString: () => amountToString,
|
|
107
116
|
assertUnitSane: () => assertUnitSane,
|
|
108
117
|
availableIn: () => availableIn,
|
|
@@ -163,19 +172,31 @@ __export(index_exports, {
|
|
|
163
172
|
isSystemFamilyCode: () => isSystemFamilyCode,
|
|
164
173
|
isValidQuantity: () => isValidQuantity,
|
|
165
174
|
isWhole: () => isWhole,
|
|
175
|
+
listCountries: () => listCountries,
|
|
176
|
+
listProvinces: () => listProvinces,
|
|
166
177
|
mapToLegacyStatus: () => mapToLegacyStatus,
|
|
167
178
|
maxPrecisionFor: () => maxPrecisionFor,
|
|
168
179
|
mergeFragment: () => mergeFragment,
|
|
169
180
|
multiplyAmount: () => multiplyAmount,
|
|
181
|
+
normalizeAddress: () => normalizeAddress,
|
|
182
|
+
normalizeCityKey: () => normalizeCityKey,
|
|
183
|
+
normalizeCountry: () => normalizeCountry,
|
|
170
184
|
normalizeMongoIdString: () => normalizeMongoIdString,
|
|
185
|
+
normalizePostCode: () => normalizePostCode,
|
|
186
|
+
normalizeProvince: () => normalizeProvince,
|
|
171
187
|
occupancyIn: () => occupancyIn,
|
|
172
188
|
parseAmountToMinorUnits: () => parseAmountToMinorUnits,
|
|
173
189
|
parseCurrencyCode: () => parseCurrencyCode,
|
|
174
190
|
parseStripeCurrencyCode: () => parseStripeCurrencyCode,
|
|
191
|
+
placeKey: () => placeKey,
|
|
175
192
|
planWindow: () => planWindow,
|
|
193
|
+
postCodeMatchesProvince: () => postCodeMatchesProvince,
|
|
176
194
|
presentAt: () => presentAt,
|
|
195
|
+
priceForTotal: () => priceForTotal,
|
|
196
|
+
provincesForPostCode: () => provincesForPostCode,
|
|
177
197
|
removeFragment: () => removeFragment,
|
|
178
198
|
resolveFamily: () => resolveFamily,
|
|
199
|
+
resolveShipping: () => resolveShipping,
|
|
179
200
|
resolveTemplate: () => resolveTemplate,
|
|
180
201
|
resolveUnit: () => resolveUnit,
|
|
181
202
|
roundToPrecision: () => roundToPrecision,
|
|
@@ -191,6 +212,7 @@ __export(index_exports, {
|
|
|
191
212
|
toMinorUnits: () => toMinorUnits,
|
|
192
213
|
validateConfig: () => validateConfig,
|
|
193
214
|
validateFragmentCompatibility: () => validateFragmentCompatibility,
|
|
215
|
+
validateShippingZone: () => validateShippingZone,
|
|
194
216
|
violatesFinancialInvariant: () => violatesFinancialInvariant,
|
|
195
217
|
windowEndsAt: () => windowEndsAt,
|
|
196
218
|
withinPresence: () => withinPresence
|
|
@@ -685,6 +707,50 @@ var ResourceAvailabilityState = /* @__PURE__ */ ((ResourceAvailabilityState2) =>
|
|
|
685
707
|
return ResourceAvailabilityState2;
|
|
686
708
|
})(ResourceAvailabilityState || {});
|
|
687
709
|
|
|
710
|
+
// enums/shipping.enum.ts
|
|
711
|
+
var ShippingZoneKind = /* @__PURE__ */ ((ShippingZoneKind2) => {
|
|
712
|
+
ShippingZoneKind2["COUNTRY"] = "country";
|
|
713
|
+
ShippingZoneKind2["PROVINCE"] = "province";
|
|
714
|
+
ShippingZoneKind2["CITY"] = "city";
|
|
715
|
+
ShippingZoneKind2["EVERYWHERE"] = "everywhere";
|
|
716
|
+
return ShippingZoneKind2;
|
|
717
|
+
})(ShippingZoneKind || {});
|
|
718
|
+
var ShippingOptionType = /* @__PURE__ */ ((ShippingOptionType2) => {
|
|
719
|
+
ShippingOptionType2["SHIP"] = "ship";
|
|
720
|
+
ShippingOptionType2["PICKUP"] = "pickup";
|
|
721
|
+
return ShippingOptionType2;
|
|
722
|
+
})(ShippingOptionType || {});
|
|
723
|
+
var ShippingRateType = /* @__PURE__ */ ((ShippingRateType2) => {
|
|
724
|
+
ShippingRateType2["FLAT"] = "flat";
|
|
725
|
+
return ShippingRateType2;
|
|
726
|
+
})(ShippingRateType || {});
|
|
727
|
+
var ShippingChannel = /* @__PURE__ */ ((ShippingChannel2) => {
|
|
728
|
+
ShippingChannel2["WEB"] = "web";
|
|
729
|
+
ShippingChannel2["POS"] = "pos";
|
|
730
|
+
return ShippingChannel2;
|
|
731
|
+
})(ShippingChannel || {});
|
|
732
|
+
var ShippingNoOptionReason = /* @__PURE__ */ ((ShippingNoOptionReason2) => {
|
|
733
|
+
ShippingNoOptionReason2["INCOMPLETE"] = "INCOMPLETE";
|
|
734
|
+
ShippingNoOptionReason2["ADDRESS_MISMATCH"] = "ADDRESS_MISMATCH";
|
|
735
|
+
ShippingNoOptionReason2["NO_COVERAGE"] = "NO_COVERAGE";
|
|
736
|
+
ShippingNoOptionReason2["BLOCKED"] = "BLOCKED";
|
|
737
|
+
ShippingNoOptionReason2["NO_OPTION"] = "NO_OPTION";
|
|
738
|
+
return ShippingNoOptionReason2;
|
|
739
|
+
})(ShippingNoOptionReason || {});
|
|
740
|
+
var ShippingZoneError = /* @__PURE__ */ ((ShippingZoneError2) => {
|
|
741
|
+
ShippingZoneError2["NO_PLACES"] = "NO_PLACES";
|
|
742
|
+
ShippingZoneError2["INVALID_PLACE"] = "INVALID_PLACE";
|
|
743
|
+
ShippingZoneError2["DUPLICATE_PLACE"] = "DUPLICATE_PLACE";
|
|
744
|
+
ShippingZoneError2["NO_WEBSITE_OPTION"] = "NO_WEBSITE_OPTION";
|
|
745
|
+
ShippingZoneError2["INVALID_PRICE"] = "INVALID_PRICE";
|
|
746
|
+
ShippingZoneError2["INVALID_DAYS"] = "INVALID_DAYS";
|
|
747
|
+
ShippingZoneError2["INVALID_TIERS"] = "INVALID_TIERS";
|
|
748
|
+
ShippingZoneError2["NO_CHANNEL"] = "NO_CHANNEL";
|
|
749
|
+
ShippingZoneError2["PICKUP_WITHOUT_STORE"] = "PICKUP_WITHOUT_STORE";
|
|
750
|
+
ShippingZoneError2["MISSING_NAME"] = "MISSING_NAME";
|
|
751
|
+
return ShippingZoneError2;
|
|
752
|
+
})(ShippingZoneError || {});
|
|
753
|
+
|
|
688
754
|
// utils/currency.util.ts
|
|
689
755
|
var CURRENCY_CONFIG = {
|
|
690
756
|
// Major currencies with 2 decimal places
|
|
@@ -3404,6 +3470,321 @@ function planWindow({ rule, timeZone, presence, startAt, endAt, now, busy = [] }
|
|
|
3404
3470
|
}
|
|
3405
3471
|
var holdExpiresAt = (rule, now) => new Date(now.getTime() + (rule.window.holdMinutes ?? DEFAULT_HOLD_MINUTES) * 6e4);
|
|
3406
3472
|
|
|
3473
|
+
// shipping/fold-text.ts
|
|
3474
|
+
function foldText(value) {
|
|
3475
|
+
return value.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/&/g, " and ").replace(/[^a-z0-9]+/g, " ").trim();
|
|
3476
|
+
}
|
|
3477
|
+
|
|
3478
|
+
// shipping/countries.ts
|
|
3479
|
+
var NOT_COUNTRIES = /* @__PURE__ */ new Set(["AC", "CP", "CQ", "DG", "EA", "EU", "EZ", "IC", "QO", "TA", "UN", "XA", "XB", "ZZ"]);
|
|
3480
|
+
var ALIASES = {
|
|
3481
|
+
canada: "CA",
|
|
3482
|
+
"united states": "US",
|
|
3483
|
+
usa: "US",
|
|
3484
|
+
"united states of america": "US",
|
|
3485
|
+
uk: "GB",
|
|
3486
|
+
"great britain": "GB",
|
|
3487
|
+
england: "GB",
|
|
3488
|
+
uae: "AE",
|
|
3489
|
+
can: "CA",
|
|
3490
|
+
mex: "MX",
|
|
3491
|
+
aus: "AU",
|
|
3492
|
+
gbr: "GB"
|
|
3493
|
+
};
|
|
3494
|
+
var NAME_LOCALES = ["en", "fr"];
|
|
3495
|
+
function regionNames(locale) {
|
|
3496
|
+
try {
|
|
3497
|
+
return new Intl.DisplayNames([locale], { type: "region", fallback: "none" });
|
|
3498
|
+
} catch {
|
|
3499
|
+
return null;
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3502
|
+
function canonicalCode(code) {
|
|
3503
|
+
try {
|
|
3504
|
+
return new Intl.Locale(`und-${code}`).maximize().region ?? code;
|
|
3505
|
+
} catch {
|
|
3506
|
+
return code;
|
|
3507
|
+
}
|
|
3508
|
+
}
|
|
3509
|
+
function allCodes() {
|
|
3510
|
+
const names = regionNames("en");
|
|
3511
|
+
if (!names) return [];
|
|
3512
|
+
const codes2 = [];
|
|
3513
|
+
for (let a = 65; a <= 90; a++) {
|
|
3514
|
+
for (let b = 65; b <= 90; b++) {
|
|
3515
|
+
const code = String.fromCharCode(a, b);
|
|
3516
|
+
if (!NOT_COUNTRIES.has(code) && names.of(code) && canonicalCode(code) === code) codes2.push(code);
|
|
3517
|
+
}
|
|
3518
|
+
}
|
|
3519
|
+
return codes2;
|
|
3520
|
+
}
|
|
3521
|
+
var lookup = null;
|
|
3522
|
+
var codes = null;
|
|
3523
|
+
function countryCodes() {
|
|
3524
|
+
codes ??= allCodes();
|
|
3525
|
+
return codes;
|
|
3526
|
+
}
|
|
3527
|
+
function countryLookup() {
|
|
3528
|
+
if (lookup) return lookup;
|
|
3529
|
+
lookup = new Map(Object.entries(ALIASES));
|
|
3530
|
+
for (const locale of NAME_LOCALES) {
|
|
3531
|
+
const names = regionNames(locale);
|
|
3532
|
+
if (!names) continue;
|
|
3533
|
+
for (const code of countryCodes()) {
|
|
3534
|
+
const name = names.of(code);
|
|
3535
|
+
if (name) lookup.set(foldText(name), code);
|
|
3536
|
+
}
|
|
3537
|
+
}
|
|
3538
|
+
return lookup;
|
|
3539
|
+
}
|
|
3540
|
+
function normalizeCountry(value) {
|
|
3541
|
+
const text = (value ?? "").trim();
|
|
3542
|
+
if (!text) return void 0;
|
|
3543
|
+
const upper = text.toUpperCase();
|
|
3544
|
+
if (upper.length === 2) {
|
|
3545
|
+
if (NOT_COUNTRIES.has(upper)) return void 0;
|
|
3546
|
+
if (countryCodes().length === 0) return /^[A-Z]{2}$/.test(upper) ? upper : void 0;
|
|
3547
|
+
const code = canonicalCode(upper);
|
|
3548
|
+
if (countryCodes().includes(code)) return code;
|
|
3549
|
+
}
|
|
3550
|
+
return countryLookup().get(foldText(text));
|
|
3551
|
+
}
|
|
3552
|
+
function listCountries(locale = "en") {
|
|
3553
|
+
const names = regionNames(locale) ?? regionNames("en");
|
|
3554
|
+
return countryCodes().map((code) => ({ code, name: names?.of(code) ?? code })).sort((a, b) => a.name.localeCompare(b.name, locale));
|
|
3555
|
+
}
|
|
3556
|
+
|
|
3557
|
+
// shipping/provinces.ts
|
|
3558
|
+
var CANADA_PROVINCES = [
|
|
3559
|
+
{ code: "AB", name: "Alberta", nameFr: "Alberta", postalLetters: ["T"] },
|
|
3560
|
+
{ code: "BC", name: "British Columbia", nameFr: "Colombie-Britannique", postalLetters: ["V"] },
|
|
3561
|
+
{ code: "MB", name: "Manitoba", nameFr: "Manitoba", postalLetters: ["R"] },
|
|
3562
|
+
{ code: "NB", name: "New Brunswick", nameFr: "Nouveau-Brunswick", postalLetters: ["E"] },
|
|
3563
|
+
{
|
|
3564
|
+
code: "NL",
|
|
3565
|
+
name: "Newfoundland and Labrador",
|
|
3566
|
+
nameFr: "Terre-Neuve-et-Labrador",
|
|
3567
|
+
postalLetters: ["A"],
|
|
3568
|
+
aliases: ["NF", "LB", "Newfoundland", "Labrador"]
|
|
3569
|
+
},
|
|
3570
|
+
{ code: "NS", name: "Nova Scotia", nameFr: "Nouvelle-\xC9cosse", postalLetters: ["B"] },
|
|
3571
|
+
{ code: "NT", name: "Northwest Territories", nameFr: "Territoires du Nord-Ouest", postalLetters: ["X"] },
|
|
3572
|
+
{ code: "NU", name: "Nunavut", nameFr: "Nunavut", postalLetters: ["X"] },
|
|
3573
|
+
{ code: "ON", name: "Ontario", nameFr: "Ontario", postalLetters: ["K", "L", "M", "N", "P"] },
|
|
3574
|
+
{
|
|
3575
|
+
code: "PE",
|
|
3576
|
+
name: "Prince Edward Island",
|
|
3577
|
+
nameFr: "\xCEle-du-Prince-\xC9douard",
|
|
3578
|
+
postalLetters: ["C"],
|
|
3579
|
+
aliases: ["PEI"]
|
|
3580
|
+
},
|
|
3581
|
+
{ code: "QC", name: "Quebec", nameFr: "Qu\xE9bec", postalLetters: ["G", "H", "J"], aliases: ["PQ"] },
|
|
3582
|
+
{ code: "SK", name: "Saskatchewan", nameFr: "Saskatchewan", postalLetters: ["S"] },
|
|
3583
|
+
{ code: "YT", name: "Yukon", nameFr: "Yukon", postalLetters: ["Y"], aliases: ["YK"] }
|
|
3584
|
+
];
|
|
3585
|
+
var PROVINCES_BY_COUNTRY = { CA: CANADA_PROVINCES };
|
|
3586
|
+
var lookups = /* @__PURE__ */ new Map();
|
|
3587
|
+
function provinceLookup(country) {
|
|
3588
|
+
const provinces = PROVINCES_BY_COUNTRY[country];
|
|
3589
|
+
if (!provinces) return void 0;
|
|
3590
|
+
let lookup2 = lookups.get(country);
|
|
3591
|
+
if (!lookup2) {
|
|
3592
|
+
lookup2 = /* @__PURE__ */ new Map();
|
|
3593
|
+
for (const p of provinces) {
|
|
3594
|
+
for (const label of [p.code, p.name, p.nameFr, ...p.aliases ?? []]) lookup2.set(foldText(label), p.code);
|
|
3595
|
+
}
|
|
3596
|
+
lookups.set(country, lookup2);
|
|
3597
|
+
}
|
|
3598
|
+
return lookup2;
|
|
3599
|
+
}
|
|
3600
|
+
function normalizeProvince(country, value) {
|
|
3601
|
+
if (!country || !value?.trim()) return void 0;
|
|
3602
|
+
return provinceLookup(country)?.get(foldText(value));
|
|
3603
|
+
}
|
|
3604
|
+
function listProvinces(country) {
|
|
3605
|
+
return PROVINCES_BY_COUNTRY[country] ?? [];
|
|
3606
|
+
}
|
|
3607
|
+
function provincesForPostCode(country, postCode) {
|
|
3608
|
+
const letter = postCode?.charAt(0);
|
|
3609
|
+
if (!country || !letter) return [];
|
|
3610
|
+
return listProvinces(country).filter((p) => p.postalLetters.includes(letter)).map((p) => p.code);
|
|
3611
|
+
}
|
|
3612
|
+
|
|
3613
|
+
// shipping/normalize.ts
|
|
3614
|
+
var EVERYWHERE_KEY = "*";
|
|
3615
|
+
function normalizeCityKey(value) {
|
|
3616
|
+
const words = foldText(value ?? "").split(" ").filter(Boolean).map((word) => word === "saint" ? "st" : word === "sainte" ? "ste" : word);
|
|
3617
|
+
return words.length ? words.join("") : void 0;
|
|
3618
|
+
}
|
|
3619
|
+
function normalizePostCode(value) {
|
|
3620
|
+
const compact = (value ?? "").replace(/[^0-9a-z]/gi, "").toUpperCase();
|
|
3621
|
+
return compact || void 0;
|
|
3622
|
+
}
|
|
3623
|
+
function normalizeAddress(address) {
|
|
3624
|
+
if (!address) return {};
|
|
3625
|
+
const country = normalizeCountry(address.country);
|
|
3626
|
+
const postCode = normalizePostCode(address.postCode ?? address.postalCode ?? address.zip);
|
|
3627
|
+
const fromPostCode = provincesForPostCode(country, postCode);
|
|
3628
|
+
const province = normalizeProvince(country, address.state ?? address.province) ?? (fromPostCode.length === 1 ? fromPostCode[0] : void 0);
|
|
3629
|
+
return { country, province, cityKey: normalizeCityKey(address.city), postCode };
|
|
3630
|
+
}
|
|
3631
|
+
function postCodeMatchesProvince(address) {
|
|
3632
|
+
const candidates = provincesForPostCode(address.country, address.postCode);
|
|
3633
|
+
if (!address.province || candidates.length === 0) return true;
|
|
3634
|
+
return candidates.includes(address.province);
|
|
3635
|
+
}
|
|
3636
|
+
function placeKey(place) {
|
|
3637
|
+
const country = normalizeCountry(place.country);
|
|
3638
|
+
if (!country) return void 0;
|
|
3639
|
+
if (!place.province) return country;
|
|
3640
|
+
const province = normalizeProvince(country, place.province);
|
|
3641
|
+
if (!province) return void 0;
|
|
3642
|
+
if (!place.city) return `${country}-${province}`;
|
|
3643
|
+
const city = normalizeCityKey(place.city);
|
|
3644
|
+
return city ? `${country}-${province}/${city}` : void 0;
|
|
3645
|
+
}
|
|
3646
|
+
function addressPlaceKeys(address) {
|
|
3647
|
+
const keys = [];
|
|
3648
|
+
if (address.country && address.province && address.cityKey) {
|
|
3649
|
+
keys.push(`${address.country}-${address.province}/${address.cityKey}`);
|
|
3650
|
+
}
|
|
3651
|
+
if (address.country && address.province) keys.push(`${address.country}-${address.province}`);
|
|
3652
|
+
if (address.country) keys.push(address.country);
|
|
3653
|
+
keys.push(EVERYWHERE_KEY);
|
|
3654
|
+
return keys;
|
|
3655
|
+
}
|
|
3656
|
+
|
|
3657
|
+
// shipping/resolve.ts
|
|
3658
|
+
function resolveShipping({ zones, address, itemsTotal, channel }) {
|
|
3659
|
+
const shipsToCountries = countriesShippedTo(zones);
|
|
3660
|
+
const none = (reason, zone2) => ({
|
|
3661
|
+
zoneId: zone2?.id ?? null,
|
|
3662
|
+
options: [],
|
|
3663
|
+
reason,
|
|
3664
|
+
message: zone2?.message?.trim() || null,
|
|
3665
|
+
shipsToCountries
|
|
3666
|
+
});
|
|
3667
|
+
const normalized = normalizeAddress(address);
|
|
3668
|
+
if (!normalized.country) return none("INCOMPLETE" /* INCOMPLETE */);
|
|
3669
|
+
if (!postCodeMatchesProvince(normalized)) return none("ADDRESS_MISMATCH" /* ADDRESS_MISMATCH */);
|
|
3670
|
+
const zone = findZone(zones, addressPlaceKeys(normalized));
|
|
3671
|
+
if (!zone) return none("NO_COVERAGE" /* NO_COVERAGE */);
|
|
3672
|
+
const offered = zone.options.filter((option) => isOffered(option, zone, channel));
|
|
3673
|
+
if (offered.length === 0) {
|
|
3674
|
+
return none(zone.ships ? "NO_OPTION" /* NO_OPTION */ : "BLOCKED" /* BLOCKED */, zone);
|
|
3675
|
+
}
|
|
3676
|
+
const quotes = offered.map((option) => quote(option, zone.id, itemsTotal));
|
|
3677
|
+
const ship = quotes.filter((q) => q.type === "ship" /* SHIP */).sort((a, b) => a.amount - b.amount);
|
|
3678
|
+
const pickup = quotes.filter((q) => q.type === "pickup" /* PICKUP */).sort((a, b) => a.amount - b.amount);
|
|
3679
|
+
return {
|
|
3680
|
+
zoneId: zone.id,
|
|
3681
|
+
options: [...ship, ...pickup],
|
|
3682
|
+
reason: null,
|
|
3683
|
+
message: zone.ships ? null : zone.message?.trim() || null,
|
|
3684
|
+
shipsToCountries
|
|
3685
|
+
};
|
|
3686
|
+
}
|
|
3687
|
+
function findZone(zones, keys) {
|
|
3688
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
3689
|
+
for (const zone of zones) {
|
|
3690
|
+
for (const key of zoneKeys(zone)) if (!byKey.has(key)) byKey.set(key, zone);
|
|
3691
|
+
}
|
|
3692
|
+
for (const key of keys) {
|
|
3693
|
+
const zone = byKey.get(key);
|
|
3694
|
+
if (zone) return zone;
|
|
3695
|
+
}
|
|
3696
|
+
return void 0;
|
|
3697
|
+
}
|
|
3698
|
+
function zoneKeys(zone) {
|
|
3699
|
+
if (zone.kind === "everywhere" /* EVERYWHERE */) return [EVERYWHERE_KEY];
|
|
3700
|
+
return zone.places.map(placeKey).filter((key) => Boolean(key));
|
|
3701
|
+
}
|
|
3702
|
+
function isOffered(option, zone, channel) {
|
|
3703
|
+
if (!option.channels.some((c) => c === channel)) return false;
|
|
3704
|
+
if (option.type === "pickup" /* PICKUP */) return channel !== "pos" /* POS */;
|
|
3705
|
+
return zone.ships;
|
|
3706
|
+
}
|
|
3707
|
+
function priceForTotal(option, itemsTotal) {
|
|
3708
|
+
const tiers = [...option.priceByTotal ?? []].sort((a, b) => a.from - b.from);
|
|
3709
|
+
let price = option.price;
|
|
3710
|
+
for (const tier of tiers) if (itemsTotal >= tier.from) price = tier.price;
|
|
3711
|
+
if (option.freeOver != null && itemsTotal >= option.freeOver) return 0;
|
|
3712
|
+
return price;
|
|
3713
|
+
}
|
|
3714
|
+
function quote(option, zoneId, itemsTotal) {
|
|
3715
|
+
const amount = priceForTotal(option, itemsTotal);
|
|
3716
|
+
const freeOver = option.freeOver ?? null;
|
|
3717
|
+
return {
|
|
3718
|
+
optionId: option.id,
|
|
3719
|
+
zoneId,
|
|
3720
|
+
type: option.type,
|
|
3721
|
+
name: option.name?.trim() || null,
|
|
3722
|
+
amount,
|
|
3723
|
+
amountToFree: freeOver != null && amount > 0 ? freeOver - itemsTotal : null,
|
|
3724
|
+
minDays: option.minDays ?? null,
|
|
3725
|
+
maxDays: option.maxDays ?? null,
|
|
3726
|
+
outletId: option.outletId ?? null
|
|
3727
|
+
};
|
|
3728
|
+
}
|
|
3729
|
+
function countriesShippedTo(zones) {
|
|
3730
|
+
const countries = /* @__PURE__ */ new Set();
|
|
3731
|
+
for (const zone of zones) {
|
|
3732
|
+
if (!zone.ships) continue;
|
|
3733
|
+
for (const key of zoneKeys(zone)) if (key !== EVERYWHERE_KEY) countries.add(key.slice(0, 2));
|
|
3734
|
+
}
|
|
3735
|
+
return [...countries].sort();
|
|
3736
|
+
}
|
|
3737
|
+
|
|
3738
|
+
// shipping/validate.ts
|
|
3739
|
+
function validateShippingZone(zone) {
|
|
3740
|
+
const problems = [...placeProblems(zone)];
|
|
3741
|
+
for (const option of zone.options) problems.push(...optionProblems(option));
|
|
3742
|
+
const reachesWebsite = zone.options.some((option) => option.channels.includes("web" /* WEB */));
|
|
3743
|
+
if (zone.ships && !reachesWebsite) problems.push({ code: "NO_WEBSITE_OPTION" /* NO_WEBSITE_OPTION */ });
|
|
3744
|
+
return problems;
|
|
3745
|
+
}
|
|
3746
|
+
function placeProblems(zone) {
|
|
3747
|
+
if (zone.kind === "everywhere" /* EVERYWHERE */) {
|
|
3748
|
+
return zone.places.length ? [{ code: "INVALID_PLACE" /* INVALID_PLACE */ }] : [];
|
|
3749
|
+
}
|
|
3750
|
+
if (zone.places.length === 0) return [{ code: "NO_PLACES" /* NO_PLACES */ }];
|
|
3751
|
+
if (!zone.places.every((place) => fitsKind(place, zone.kind))) return [{ code: "INVALID_PLACE" /* INVALID_PLACE */ }];
|
|
3752
|
+
const keys = zone.places.map(placeKey);
|
|
3753
|
+
if (keys.some((key) => !key)) return [{ code: "INVALID_PLACE" /* INVALID_PLACE */ }];
|
|
3754
|
+
if (new Set(keys).size !== keys.length) return [{ code: "DUPLICATE_PLACE" /* DUPLICATE_PLACE */ }];
|
|
3755
|
+
return [];
|
|
3756
|
+
}
|
|
3757
|
+
function fitsKind(place, kind) {
|
|
3758
|
+
const hasProvince = Boolean(place.province?.trim());
|
|
3759
|
+
const hasCity = Boolean(place.city?.trim());
|
|
3760
|
+
if (kind === "country" /* COUNTRY */) return !hasProvince && !hasCity;
|
|
3761
|
+
if (kind === "province" /* PROVINCE */) return hasProvince && !hasCity;
|
|
3762
|
+
if (kind === "city" /* CITY */) return hasProvince && hasCity;
|
|
3763
|
+
return false;
|
|
3764
|
+
}
|
|
3765
|
+
var isAmount = (value) => Number.isInteger(value) && value >= 0;
|
|
3766
|
+
var isDays = (value) => value == null || isAmount(value);
|
|
3767
|
+
function optionProblems(option) {
|
|
3768
|
+
const problems = [];
|
|
3769
|
+
const isPickup = option.type === "pickup" /* PICKUP */;
|
|
3770
|
+
if (!isAmount(option.price) || option.freeOver != null && !isAmount(option.freeOver)) {
|
|
3771
|
+
problems.push("INVALID_PRICE" /* INVALID_PRICE */);
|
|
3772
|
+
}
|
|
3773
|
+
if (!isPickup && !option.name?.trim()) problems.push("MISSING_NAME" /* MISSING_NAME */);
|
|
3774
|
+
if (!isDays(option.minDays) || !isDays(option.maxDays) || (option.minDays ?? 0) > (option.maxDays ?? Infinity)) {
|
|
3775
|
+
problems.push("INVALID_DAYS" /* INVALID_DAYS */);
|
|
3776
|
+
}
|
|
3777
|
+
if (!tiersAreValid(option)) problems.push("INVALID_TIERS" /* INVALID_TIERS */);
|
|
3778
|
+
if (option.channels.length === 0) problems.push("NO_CHANNEL" /* NO_CHANNEL */);
|
|
3779
|
+
if (isPickup && !option.outletId) problems.push("PICKUP_WITHOUT_STORE" /* PICKUP_WITHOUT_STORE */);
|
|
3780
|
+
return problems.map((code) => ({ code, optionId: option.id }));
|
|
3781
|
+
}
|
|
3782
|
+
function tiersAreValid(option) {
|
|
3783
|
+
const tiers = option.priceByTotal ?? [];
|
|
3784
|
+
const froms = tiers.map((tier) => tier.from);
|
|
3785
|
+
return tiers.every((tier) => Number.isInteger(tier.from) && tier.from > 0 && isAmount(tier.price)) && new Set(froms).size === froms.length;
|
|
3786
|
+
}
|
|
3787
|
+
|
|
3407
3788
|
// constants/adyen.constants.ts
|
|
3408
3789
|
var ADYEN_ROLLOUT_COUNTRY_CODES = /* @__PURE__ */ new Set(["CA"]);
|
|
3409
3790
|
function isAdyenRolloutCountry(alpha2) {
|
|
@@ -3462,6 +3843,7 @@ var PAYMENT_CHANNELS = ["inPerson", "online"];
|
|
|
3462
3843
|
BookingResourceStatus,
|
|
3463
3844
|
BookingRulesError,
|
|
3464
3845
|
BookingType,
|
|
3846
|
+
CANADA_PROVINCES,
|
|
3465
3847
|
CONDITION_OPERATORS,
|
|
3466
3848
|
COUNTRY_CURRENCIES,
|
|
3467
3849
|
CURRENCY_CONFIG,
|
|
@@ -3478,6 +3860,7 @@ var PAYMENT_CHANNELS = ["inPerson", "online"];
|
|
|
3478
3860
|
DualWriteStrategy,
|
|
3479
3861
|
EUFixedRates,
|
|
3480
3862
|
EUROPE,
|
|
3863
|
+
EVERYWHERE_KEY,
|
|
3481
3864
|
ExtensionCategory,
|
|
3482
3865
|
FINANCIAL_INVARIANTS,
|
|
3483
3866
|
FULFILLMENT_STATES,
|
|
@@ -3528,6 +3911,12 @@ var PAYMENT_CHANNELS = ["inPerson", "online"];
|
|
|
3528
3911
|
SYSTEM_FAMILY_IDS,
|
|
3529
3912
|
SYSTEM_UNITS,
|
|
3530
3913
|
SYSTEM_UNIT_IDS,
|
|
3914
|
+
ShippingChannel,
|
|
3915
|
+
ShippingNoOptionReason,
|
|
3916
|
+
ShippingOptionType,
|
|
3917
|
+
ShippingRateType,
|
|
3918
|
+
ShippingZoneError,
|
|
3919
|
+
ShippingZoneKind,
|
|
3531
3920
|
StationStatus,
|
|
3532
3921
|
StripeCurrencyCode,
|
|
3533
3922
|
StripeStatus,
|
|
@@ -3535,6 +3924,7 @@ var PAYMENT_CHANNELS = ["inPerson", "online"];
|
|
|
3535
3924
|
TopMetericsSort,
|
|
3536
3925
|
UserTypes,
|
|
3537
3926
|
addAmounts,
|
|
3927
|
+
addressPlaceKeys,
|
|
3538
3928
|
amountToString,
|
|
3539
3929
|
assertUnitSane,
|
|
3540
3930
|
availableIn,
|
|
@@ -3595,19 +3985,31 @@ var PAYMENT_CHANNELS = ["inPerson", "online"];
|
|
|
3595
3985
|
isSystemFamilyCode,
|
|
3596
3986
|
isValidQuantity,
|
|
3597
3987
|
isWhole,
|
|
3988
|
+
listCountries,
|
|
3989
|
+
listProvinces,
|
|
3598
3990
|
mapToLegacyStatus,
|
|
3599
3991
|
maxPrecisionFor,
|
|
3600
3992
|
mergeFragment,
|
|
3601
3993
|
multiplyAmount,
|
|
3994
|
+
normalizeAddress,
|
|
3995
|
+
normalizeCityKey,
|
|
3996
|
+
normalizeCountry,
|
|
3602
3997
|
normalizeMongoIdString,
|
|
3998
|
+
normalizePostCode,
|
|
3999
|
+
normalizeProvince,
|
|
3603
4000
|
occupancyIn,
|
|
3604
4001
|
parseAmountToMinorUnits,
|
|
3605
4002
|
parseCurrencyCode,
|
|
3606
4003
|
parseStripeCurrencyCode,
|
|
4004
|
+
placeKey,
|
|
3607
4005
|
planWindow,
|
|
4006
|
+
postCodeMatchesProvince,
|
|
3608
4007
|
presentAt,
|
|
4008
|
+
priceForTotal,
|
|
4009
|
+
provincesForPostCode,
|
|
3609
4010
|
removeFragment,
|
|
3610
4011
|
resolveFamily,
|
|
4012
|
+
resolveShipping,
|
|
3611
4013
|
resolveTemplate,
|
|
3612
4014
|
resolveUnit,
|
|
3613
4015
|
roundToPrecision,
|
|
@@ -3623,6 +4025,7 @@ var PAYMENT_CHANNELS = ["inPerson", "online"];
|
|
|
3623
4025
|
toMinorUnits,
|
|
3624
4026
|
validateConfig,
|
|
3625
4027
|
validateFragmentCompatibility,
|
|
4028
|
+
validateShippingZone,
|
|
3626
4029
|
violatesFinancialInvariant,
|
|
3627
4030
|
windowEndsAt,
|
|
3628
4031
|
withinPresence
|