@final-commerce/common 2.5.0 → 2.5.1-online.2
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 +200 -4
- package/dist/index.d.ts +200 -4
- package/dist/index.js +468 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +438 -2
- package/dist/index.mjs.map +1 -1
- package/dist/pos-types/index.d.mts +10 -1
- package/dist/pos-types/index.d.ts +10 -1
- package/dist/pos-types/index.js +1 -0
- package/dist/pos-types/index.js.map +1 -1
- package/dist/pos-types/index.mjs +1 -0
- package/dist/pos-types/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -200,6 +200,7 @@ var OrderPlatform = /* @__PURE__ */ ((OrderPlatform2) => {
|
|
|
200
200
|
OrderPlatform2["POS"] = "in-store";
|
|
201
201
|
OrderPlatform2["WOO_COMMERCE"] = "woo-commerce";
|
|
202
202
|
OrderPlatform2["PUBLIC_API"] = "public-api";
|
|
203
|
+
OrderPlatform2["ONLINE_STORE"] = "online-store";
|
|
203
204
|
return OrderPlatform2;
|
|
204
205
|
})(OrderPlatform || {});
|
|
205
206
|
var CustomerPlatform = /* @__PURE__ */ ((CustomerPlatform2) => {
|
|
@@ -485,6 +486,50 @@ var ResourceAvailabilityState = /* @__PURE__ */ ((ResourceAvailabilityState2) =>
|
|
|
485
486
|
return ResourceAvailabilityState2;
|
|
486
487
|
})(ResourceAvailabilityState || {});
|
|
487
488
|
|
|
489
|
+
// enums/shipping.enum.ts
|
|
490
|
+
var ShippingZoneKind = /* @__PURE__ */ ((ShippingZoneKind2) => {
|
|
491
|
+
ShippingZoneKind2["COUNTRY"] = "country";
|
|
492
|
+
ShippingZoneKind2["PROVINCE"] = "province";
|
|
493
|
+
ShippingZoneKind2["CITY"] = "city";
|
|
494
|
+
ShippingZoneKind2["EVERYWHERE"] = "everywhere";
|
|
495
|
+
return ShippingZoneKind2;
|
|
496
|
+
})(ShippingZoneKind || {});
|
|
497
|
+
var ShippingOptionType = /* @__PURE__ */ ((ShippingOptionType2) => {
|
|
498
|
+
ShippingOptionType2["SHIP"] = "ship";
|
|
499
|
+
ShippingOptionType2["PICKUP"] = "pickup";
|
|
500
|
+
return ShippingOptionType2;
|
|
501
|
+
})(ShippingOptionType || {});
|
|
502
|
+
var ShippingRateType = /* @__PURE__ */ ((ShippingRateType2) => {
|
|
503
|
+
ShippingRateType2["FLAT"] = "flat";
|
|
504
|
+
return ShippingRateType2;
|
|
505
|
+
})(ShippingRateType || {});
|
|
506
|
+
var ShippingChannel = /* @__PURE__ */ ((ShippingChannel2) => {
|
|
507
|
+
ShippingChannel2["WEB"] = "web";
|
|
508
|
+
ShippingChannel2["POS"] = "pos";
|
|
509
|
+
return ShippingChannel2;
|
|
510
|
+
})(ShippingChannel || {});
|
|
511
|
+
var ShippingNoOptionReason = /* @__PURE__ */ ((ShippingNoOptionReason2) => {
|
|
512
|
+
ShippingNoOptionReason2["INCOMPLETE"] = "INCOMPLETE";
|
|
513
|
+
ShippingNoOptionReason2["ADDRESS_MISMATCH"] = "ADDRESS_MISMATCH";
|
|
514
|
+
ShippingNoOptionReason2["NO_COVERAGE"] = "NO_COVERAGE";
|
|
515
|
+
ShippingNoOptionReason2["BLOCKED"] = "BLOCKED";
|
|
516
|
+
ShippingNoOptionReason2["NO_OPTION"] = "NO_OPTION";
|
|
517
|
+
return ShippingNoOptionReason2;
|
|
518
|
+
})(ShippingNoOptionReason || {});
|
|
519
|
+
var ShippingZoneError = /* @__PURE__ */ ((ShippingZoneError2) => {
|
|
520
|
+
ShippingZoneError2["NO_PLACES"] = "NO_PLACES";
|
|
521
|
+
ShippingZoneError2["INVALID_PLACE"] = "INVALID_PLACE";
|
|
522
|
+
ShippingZoneError2["DUPLICATE_PLACE"] = "DUPLICATE_PLACE";
|
|
523
|
+
ShippingZoneError2["NO_WEBSITE_OPTION"] = "NO_WEBSITE_OPTION";
|
|
524
|
+
ShippingZoneError2["INVALID_PRICE"] = "INVALID_PRICE";
|
|
525
|
+
ShippingZoneError2["INVALID_DAYS"] = "INVALID_DAYS";
|
|
526
|
+
ShippingZoneError2["INVALID_TIERS"] = "INVALID_TIERS";
|
|
527
|
+
ShippingZoneError2["NO_CHANNEL"] = "NO_CHANNEL";
|
|
528
|
+
ShippingZoneError2["PICKUP_WITHOUT_STORE"] = "PICKUP_WITHOUT_STORE";
|
|
529
|
+
ShippingZoneError2["MISSING_NAME"] = "MISSING_NAME";
|
|
530
|
+
return ShippingZoneError2;
|
|
531
|
+
})(ShippingZoneError || {});
|
|
532
|
+
|
|
488
533
|
// utils/currency.util.ts
|
|
489
534
|
var CURRENCY_CONFIG = {
|
|
490
535
|
// Major currencies with 2 decimal places
|
|
@@ -3003,7 +3048,9 @@ function buildGrid(rule, timeZone, from, to, now, busy = []) {
|
|
|
3003
3048
|
const start = startAt.getTime();
|
|
3004
3049
|
if (start < askedFrom || start >= askedTo) return false;
|
|
3005
3050
|
if (start < notBefore || start > notAfter) return false;
|
|
3006
|
-
return !blocked.some(
|
|
3051
|
+
return !blocked.some(
|
|
3052
|
+
({ from: blockFrom, to: blockTo }) => start < blockTo && bufferEndAt.getTime() > blockFrom
|
|
3053
|
+
);
|
|
3007
3054
|
}).sort((first, second) => +first.startAt - +second.startAt);
|
|
3008
3055
|
}
|
|
3009
3056
|
function slotsForWindow(grid, startAt, endAt) {
|
|
@@ -3122,7 +3169,14 @@ function buildAvailability({
|
|
|
3122
3169
|
for (const slot of slots2) {
|
|
3123
3170
|
const { taken, foreignProductId } = occupancyIn(mine, productId, slot.startAt, slot.bufferEndAt, shared);
|
|
3124
3171
|
const free = foreignProductId ? 0 : Math.max(capacity - taken, 0);
|
|
3125
|
-
const entry = byInstant.get(+slot.startAt) ?? {
|
|
3172
|
+
const entry = byInstant.get(+slot.startAt) ?? {
|
|
3173
|
+
...slot,
|
|
3174
|
+
capacity: 0,
|
|
3175
|
+
booked: 0,
|
|
3176
|
+
free: 0,
|
|
3177
|
+
resources: [],
|
|
3178
|
+
dayKey: shopDayKey(slot.startAt, resource.timeZone)
|
|
3179
|
+
};
|
|
3126
3180
|
entry.capacity += capacity;
|
|
3127
3181
|
entry.booked += foreignProductId ? capacity : taken;
|
|
3128
3182
|
entry.free += free;
|
|
@@ -3195,19 +3249,376 @@ function planWindow({ rule, timeZone, presence, startAt, endAt, now, busy = [] }
|
|
|
3195
3249
|
}
|
|
3196
3250
|
var holdExpiresAt = (rule, now) => new Date(now.getTime() + (rule.window.holdMinutes ?? DEFAULT_HOLD_MINUTES) * 6e4);
|
|
3197
3251
|
|
|
3252
|
+
// shipping/fold-text.ts
|
|
3253
|
+
function foldText(value) {
|
|
3254
|
+
return value.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().replace(/&/g, " and ").replace(/[^a-z0-9]+/g, " ").trim();
|
|
3255
|
+
}
|
|
3256
|
+
|
|
3257
|
+
// shipping/countries.ts
|
|
3258
|
+
var NOT_COUNTRIES = /* @__PURE__ */ new Set(["AC", "CP", "CQ", "DG", "EA", "EU", "EZ", "IC", "QO", "TA", "UN", "XA", "XB", "ZZ"]);
|
|
3259
|
+
var ALIASES = {
|
|
3260
|
+
usa: "US",
|
|
3261
|
+
"united states of america": "US",
|
|
3262
|
+
uk: "GB",
|
|
3263
|
+
"great britain": "GB",
|
|
3264
|
+
england: "GB",
|
|
3265
|
+
uae: "AE",
|
|
3266
|
+
can: "CA",
|
|
3267
|
+
mex: "MX",
|
|
3268
|
+
aus: "AU",
|
|
3269
|
+
gbr: "GB"
|
|
3270
|
+
};
|
|
3271
|
+
var NAME_LOCALES = ["en", "fr"];
|
|
3272
|
+
function regionNames(locale) {
|
|
3273
|
+
try {
|
|
3274
|
+
return new Intl.DisplayNames([locale], { type: "region", fallback: "none" });
|
|
3275
|
+
} catch {
|
|
3276
|
+
return null;
|
|
3277
|
+
}
|
|
3278
|
+
}
|
|
3279
|
+
function canonicalCode(code) {
|
|
3280
|
+
try {
|
|
3281
|
+
return new Intl.Locale(`und-${code}`).maximize().region ?? code;
|
|
3282
|
+
} catch {
|
|
3283
|
+
return code;
|
|
3284
|
+
}
|
|
3285
|
+
}
|
|
3286
|
+
function allCodes() {
|
|
3287
|
+
const names = regionNames("en");
|
|
3288
|
+
if (!names) return [];
|
|
3289
|
+
const codes2 = [];
|
|
3290
|
+
for (let a = 65; a <= 90; a++) {
|
|
3291
|
+
for (let b = 65; b <= 90; b++) {
|
|
3292
|
+
const code = String.fromCharCode(a, b);
|
|
3293
|
+
if (!NOT_COUNTRIES.has(code) && names.of(code) && canonicalCode(code) === code) codes2.push(code);
|
|
3294
|
+
}
|
|
3295
|
+
}
|
|
3296
|
+
return codes2;
|
|
3297
|
+
}
|
|
3298
|
+
var lookup = null;
|
|
3299
|
+
var codes = null;
|
|
3300
|
+
function countryCodes() {
|
|
3301
|
+
codes ??= allCodes();
|
|
3302
|
+
return codes;
|
|
3303
|
+
}
|
|
3304
|
+
function countryLookup() {
|
|
3305
|
+
if (lookup) return lookup;
|
|
3306
|
+
lookup = new Map(Object.entries(ALIASES));
|
|
3307
|
+
for (const locale of NAME_LOCALES) {
|
|
3308
|
+
const names = regionNames(locale);
|
|
3309
|
+
if (!names) continue;
|
|
3310
|
+
for (const code of countryCodes()) {
|
|
3311
|
+
const name = names.of(code);
|
|
3312
|
+
if (name) lookup.set(foldText(name), code);
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
return lookup;
|
|
3316
|
+
}
|
|
3317
|
+
function normalizeCountry(value) {
|
|
3318
|
+
const text = (value ?? "").trim();
|
|
3319
|
+
if (!text) return void 0;
|
|
3320
|
+
const upper = text.toUpperCase();
|
|
3321
|
+
if (upper.length === 2) {
|
|
3322
|
+
if (NOT_COUNTRIES.has(upper)) return void 0;
|
|
3323
|
+
const code = canonicalCode(upper);
|
|
3324
|
+
if (countryCodes().includes(code)) return code;
|
|
3325
|
+
}
|
|
3326
|
+
return countryLookup().get(foldText(text));
|
|
3327
|
+
}
|
|
3328
|
+
function listCountries(locale = "en") {
|
|
3329
|
+
const names = regionNames(locale) ?? regionNames("en");
|
|
3330
|
+
return countryCodes().map((code) => ({ code, name: names?.of(code) ?? code })).sort((a, b) => a.name.localeCompare(b.name, locale));
|
|
3331
|
+
}
|
|
3332
|
+
|
|
3333
|
+
// shipping/provinces.ts
|
|
3334
|
+
var CANADA_PROVINCES = [
|
|
3335
|
+
{ code: "AB", name: "Alberta", nameFr: "Alberta", postalLetters: ["T"] },
|
|
3336
|
+
{ code: "BC", name: "British Columbia", nameFr: "Colombie-Britannique", postalLetters: ["V"] },
|
|
3337
|
+
{ code: "MB", name: "Manitoba", nameFr: "Manitoba", postalLetters: ["R"] },
|
|
3338
|
+
{ code: "NB", name: "New Brunswick", nameFr: "Nouveau-Brunswick", postalLetters: ["E"] },
|
|
3339
|
+
{
|
|
3340
|
+
code: "NL",
|
|
3341
|
+
name: "Newfoundland and Labrador",
|
|
3342
|
+
nameFr: "Terre-Neuve-et-Labrador",
|
|
3343
|
+
postalLetters: ["A"],
|
|
3344
|
+
aliases: ["NF", "LB", "Newfoundland", "Labrador"]
|
|
3345
|
+
},
|
|
3346
|
+
{ code: "NS", name: "Nova Scotia", nameFr: "Nouvelle-\xC9cosse", postalLetters: ["B"] },
|
|
3347
|
+
{ code: "NT", name: "Northwest Territories", nameFr: "Territoires du Nord-Ouest", postalLetters: ["X"] },
|
|
3348
|
+
{ code: "NU", name: "Nunavut", nameFr: "Nunavut", postalLetters: ["X"] },
|
|
3349
|
+
{ code: "ON", name: "Ontario", nameFr: "Ontario", postalLetters: ["K", "L", "M", "N", "P"] },
|
|
3350
|
+
{
|
|
3351
|
+
code: "PE",
|
|
3352
|
+
name: "Prince Edward Island",
|
|
3353
|
+
nameFr: "\xCEle-du-Prince-\xC9douard",
|
|
3354
|
+
postalLetters: ["C"],
|
|
3355
|
+
aliases: ["PEI"]
|
|
3356
|
+
},
|
|
3357
|
+
{ code: "QC", name: "Quebec", nameFr: "Qu\xE9bec", postalLetters: ["G", "H", "J"], aliases: ["PQ"] },
|
|
3358
|
+
{ code: "SK", name: "Saskatchewan", nameFr: "Saskatchewan", postalLetters: ["S"] },
|
|
3359
|
+
{ code: "YT", name: "Yukon", nameFr: "Yukon", postalLetters: ["Y"], aliases: ["YK"] }
|
|
3360
|
+
];
|
|
3361
|
+
var PROVINCES_BY_COUNTRY = { CA: CANADA_PROVINCES };
|
|
3362
|
+
var lookups = /* @__PURE__ */ new Map();
|
|
3363
|
+
function provinceLookup(country) {
|
|
3364
|
+
const provinces = PROVINCES_BY_COUNTRY[country];
|
|
3365
|
+
if (!provinces) return void 0;
|
|
3366
|
+
let lookup2 = lookups.get(country);
|
|
3367
|
+
if (!lookup2) {
|
|
3368
|
+
lookup2 = /* @__PURE__ */ new Map();
|
|
3369
|
+
for (const p of provinces) {
|
|
3370
|
+
for (const label of [p.code, p.name, p.nameFr, ...p.aliases ?? []]) lookup2.set(foldText(label), p.code);
|
|
3371
|
+
}
|
|
3372
|
+
lookups.set(country, lookup2);
|
|
3373
|
+
}
|
|
3374
|
+
return lookup2;
|
|
3375
|
+
}
|
|
3376
|
+
function normalizeProvince(country, value) {
|
|
3377
|
+
if (!country || !value?.trim()) return void 0;
|
|
3378
|
+
return provinceLookup(country)?.get(foldText(value));
|
|
3379
|
+
}
|
|
3380
|
+
function listProvinces(country) {
|
|
3381
|
+
return PROVINCES_BY_COUNTRY[country] ?? [];
|
|
3382
|
+
}
|
|
3383
|
+
function provincesForPostCode(country, postCode) {
|
|
3384
|
+
const letter = postCode?.charAt(0);
|
|
3385
|
+
if (!country || !letter) return [];
|
|
3386
|
+
return listProvinces(country).filter((p) => p.postalLetters.includes(letter)).map((p) => p.code);
|
|
3387
|
+
}
|
|
3388
|
+
|
|
3389
|
+
// shipping/normalize.ts
|
|
3390
|
+
var EVERYWHERE_KEY = "*";
|
|
3391
|
+
function normalizeCityKey(value) {
|
|
3392
|
+
const words = foldText(value ?? "").split(" ").filter(Boolean).map((word) => word === "saint" ? "st" : word === "sainte" ? "ste" : word);
|
|
3393
|
+
return words.length ? words.join("") : void 0;
|
|
3394
|
+
}
|
|
3395
|
+
function normalizePostCode(value) {
|
|
3396
|
+
const compact = (value ?? "").replace(/[^0-9a-z]/gi, "").toUpperCase();
|
|
3397
|
+
return compact || void 0;
|
|
3398
|
+
}
|
|
3399
|
+
function normalizeAddress(address) {
|
|
3400
|
+
if (!address) return {};
|
|
3401
|
+
const country = normalizeCountry(address.country);
|
|
3402
|
+
const postCode = normalizePostCode(address.postCode ?? address.postalCode ?? address.zip);
|
|
3403
|
+
const fromPostCode = provincesForPostCode(country, postCode);
|
|
3404
|
+
const province = normalizeProvince(country, address.state ?? address.province) ?? (fromPostCode.length === 1 ? fromPostCode[0] : void 0);
|
|
3405
|
+
return { country, province, cityKey: normalizeCityKey(address.city), postCode };
|
|
3406
|
+
}
|
|
3407
|
+
function postCodeMatchesProvince(address) {
|
|
3408
|
+
const candidates = provincesForPostCode(address.country, address.postCode);
|
|
3409
|
+
if (!address.province || candidates.length === 0) return true;
|
|
3410
|
+
return candidates.includes(address.province);
|
|
3411
|
+
}
|
|
3412
|
+
function placeKey(place) {
|
|
3413
|
+
const country = normalizeCountry(place.country);
|
|
3414
|
+
if (!country) return void 0;
|
|
3415
|
+
if (!place.province) return country;
|
|
3416
|
+
const province = normalizeProvince(country, place.province);
|
|
3417
|
+
if (!province) return void 0;
|
|
3418
|
+
if (!place.city) return `${country}-${province}`;
|
|
3419
|
+
const city = normalizeCityKey(place.city);
|
|
3420
|
+
return city ? `${country}-${province}/${city}` : void 0;
|
|
3421
|
+
}
|
|
3422
|
+
function addressPlaceKeys(address) {
|
|
3423
|
+
const keys = [];
|
|
3424
|
+
if (address.country && address.province && address.cityKey) {
|
|
3425
|
+
keys.push(`${address.country}-${address.province}/${address.cityKey}`);
|
|
3426
|
+
}
|
|
3427
|
+
if (address.country && address.province) keys.push(`${address.country}-${address.province}`);
|
|
3428
|
+
if (address.country) keys.push(address.country);
|
|
3429
|
+
keys.push(EVERYWHERE_KEY);
|
|
3430
|
+
return keys;
|
|
3431
|
+
}
|
|
3432
|
+
|
|
3433
|
+
// shipping/resolve.ts
|
|
3434
|
+
function resolveShipping({ zones, address, itemsTotal, channel }) {
|
|
3435
|
+
const shipsToCountries = countriesShippedTo(zones);
|
|
3436
|
+
const none = (reason, zone2) => ({
|
|
3437
|
+
zoneId: zone2?.id ?? null,
|
|
3438
|
+
options: [],
|
|
3439
|
+
reason,
|
|
3440
|
+
message: zone2?.message?.trim() || null,
|
|
3441
|
+
shipsToCountries
|
|
3442
|
+
});
|
|
3443
|
+
const normalized = normalizeAddress(address);
|
|
3444
|
+
if (!normalized.country) return none("INCOMPLETE" /* INCOMPLETE */);
|
|
3445
|
+
if (!postCodeMatchesProvince(normalized)) return none("ADDRESS_MISMATCH" /* ADDRESS_MISMATCH */);
|
|
3446
|
+
const zone = findZone(zones, addressPlaceKeys(normalized));
|
|
3447
|
+
if (!zone) return none("NO_COVERAGE" /* NO_COVERAGE */);
|
|
3448
|
+
const offered = zone.options.filter((option) => isOffered(option, zone, channel));
|
|
3449
|
+
if (offered.length === 0) {
|
|
3450
|
+
return none(zone.ships ? "NO_OPTION" /* NO_OPTION */ : "BLOCKED" /* BLOCKED */, zone);
|
|
3451
|
+
}
|
|
3452
|
+
const quotes = offered.map((option) => quote(option, zone.id, itemsTotal));
|
|
3453
|
+
const ship = quotes.filter((q) => q.type === "ship" /* SHIP */).sort((a, b) => a.amount - b.amount);
|
|
3454
|
+
const pickup = quotes.filter((q) => q.type === "pickup" /* PICKUP */).sort((a, b) => a.amount - b.amount);
|
|
3455
|
+
return {
|
|
3456
|
+
zoneId: zone.id,
|
|
3457
|
+
options: [...ship, ...pickup],
|
|
3458
|
+
reason: null,
|
|
3459
|
+
message: zone.ships ? null : zone.message?.trim() || null,
|
|
3460
|
+
shipsToCountries
|
|
3461
|
+
};
|
|
3462
|
+
}
|
|
3463
|
+
function findZone(zones, keys) {
|
|
3464
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
3465
|
+
for (const zone of zones) {
|
|
3466
|
+
for (const key of zoneKeys(zone)) if (!byKey.has(key)) byKey.set(key, zone);
|
|
3467
|
+
}
|
|
3468
|
+
for (const key of keys) {
|
|
3469
|
+
const zone = byKey.get(key);
|
|
3470
|
+
if (zone) return zone;
|
|
3471
|
+
}
|
|
3472
|
+
return void 0;
|
|
3473
|
+
}
|
|
3474
|
+
function zoneKeys(zone) {
|
|
3475
|
+
if (zone.kind === "everywhere" /* EVERYWHERE */) return [EVERYWHERE_KEY];
|
|
3476
|
+
return zone.places.map(placeKey).filter((key) => Boolean(key));
|
|
3477
|
+
}
|
|
3478
|
+
function isOffered(option, zone, channel) {
|
|
3479
|
+
if (!option.channels.some((c) => c === channel)) return false;
|
|
3480
|
+
if (option.type === "pickup" /* PICKUP */) return channel !== "pos" /* POS */;
|
|
3481
|
+
return zone.ships;
|
|
3482
|
+
}
|
|
3483
|
+
function priceForTotal(option, itemsTotal) {
|
|
3484
|
+
const tiers = [...option.priceByTotal ?? []].sort((a, b) => a.from - b.from);
|
|
3485
|
+
let price = option.price;
|
|
3486
|
+
for (const tier of tiers) if (itemsTotal >= tier.from) price = tier.price;
|
|
3487
|
+
if (option.freeOver != null && itemsTotal >= option.freeOver) return 0;
|
|
3488
|
+
return price;
|
|
3489
|
+
}
|
|
3490
|
+
function quote(option, zoneId, itemsTotal) {
|
|
3491
|
+
const amount = priceForTotal(option, itemsTotal);
|
|
3492
|
+
const freeOver = option.freeOver ?? null;
|
|
3493
|
+
return {
|
|
3494
|
+
optionId: option.id,
|
|
3495
|
+
zoneId,
|
|
3496
|
+
type: option.type,
|
|
3497
|
+
name: option.name?.trim() || null,
|
|
3498
|
+
amount,
|
|
3499
|
+
amountToFree: freeOver != null && amount > 0 ? freeOver - itemsTotal : null,
|
|
3500
|
+
minDays: option.minDays ?? null,
|
|
3501
|
+
maxDays: option.maxDays ?? null,
|
|
3502
|
+
outletId: option.outletId ?? null
|
|
3503
|
+
};
|
|
3504
|
+
}
|
|
3505
|
+
function countriesShippedTo(zones) {
|
|
3506
|
+
const countries = /* @__PURE__ */ new Set();
|
|
3507
|
+
for (const zone of zones) {
|
|
3508
|
+
if (!zone.ships) continue;
|
|
3509
|
+
for (const key of zoneKeys(zone)) if (key !== EVERYWHERE_KEY) countries.add(key.slice(0, 2));
|
|
3510
|
+
}
|
|
3511
|
+
return [...countries].sort();
|
|
3512
|
+
}
|
|
3513
|
+
|
|
3514
|
+
// shipping/validate.ts
|
|
3515
|
+
function validateShippingZone(zone) {
|
|
3516
|
+
const problems = [...placeProblems(zone)];
|
|
3517
|
+
for (const option of zone.options) problems.push(...optionProblems(option));
|
|
3518
|
+
const reachesWebsite = zone.options.some((option) => option.channels.includes("web" /* WEB */));
|
|
3519
|
+
if (zone.ships && !reachesWebsite) problems.push({ code: "NO_WEBSITE_OPTION" /* NO_WEBSITE_OPTION */ });
|
|
3520
|
+
return problems;
|
|
3521
|
+
}
|
|
3522
|
+
function placeProblems(zone) {
|
|
3523
|
+
if (zone.kind === "everywhere" /* EVERYWHERE */) {
|
|
3524
|
+
return zone.places.length ? [{ code: "INVALID_PLACE" /* INVALID_PLACE */ }] : [];
|
|
3525
|
+
}
|
|
3526
|
+
if (zone.places.length === 0) return [{ code: "NO_PLACES" /* NO_PLACES */ }];
|
|
3527
|
+
if (!zone.places.every((place) => fitsKind(place, zone.kind))) return [{ code: "INVALID_PLACE" /* INVALID_PLACE */ }];
|
|
3528
|
+
const keys = zone.places.map(placeKey);
|
|
3529
|
+
if (keys.some((key) => !key)) return [{ code: "INVALID_PLACE" /* INVALID_PLACE */ }];
|
|
3530
|
+
if (new Set(keys).size !== keys.length) return [{ code: "DUPLICATE_PLACE" /* DUPLICATE_PLACE */ }];
|
|
3531
|
+
return [];
|
|
3532
|
+
}
|
|
3533
|
+
function fitsKind(place, kind) {
|
|
3534
|
+
const hasProvince = Boolean(place.province?.trim());
|
|
3535
|
+
const hasCity = Boolean(place.city?.trim());
|
|
3536
|
+
if (kind === "country" /* COUNTRY */) return !hasProvince && !hasCity;
|
|
3537
|
+
if (kind === "province" /* PROVINCE */) return hasProvince && !hasCity;
|
|
3538
|
+
if (kind === "city" /* CITY */) return hasProvince && hasCity;
|
|
3539
|
+
return false;
|
|
3540
|
+
}
|
|
3541
|
+
var isAmount = (value) => Number.isInteger(value) && value >= 0;
|
|
3542
|
+
var isDays = (value) => value == null || isAmount(value);
|
|
3543
|
+
function optionProblems(option) {
|
|
3544
|
+
const problems = [];
|
|
3545
|
+
const isPickup = option.type === "pickup" /* PICKUP */;
|
|
3546
|
+
if (!isAmount(option.price) || option.freeOver != null && !isAmount(option.freeOver)) {
|
|
3547
|
+
problems.push("INVALID_PRICE" /* INVALID_PRICE */);
|
|
3548
|
+
}
|
|
3549
|
+
if (!isPickup && !option.name?.trim()) problems.push("MISSING_NAME" /* MISSING_NAME */);
|
|
3550
|
+
if (!isDays(option.minDays) || !isDays(option.maxDays) || (option.minDays ?? 0) > (option.maxDays ?? Infinity)) {
|
|
3551
|
+
problems.push("INVALID_DAYS" /* INVALID_DAYS */);
|
|
3552
|
+
}
|
|
3553
|
+
if (!tiersAreValid(option)) problems.push("INVALID_TIERS" /* INVALID_TIERS */);
|
|
3554
|
+
if (option.channels.length === 0) problems.push("NO_CHANNEL" /* NO_CHANNEL */);
|
|
3555
|
+
if (isPickup && !option.outletId) problems.push("PICKUP_WITHOUT_STORE" /* PICKUP_WITHOUT_STORE */);
|
|
3556
|
+
return problems.map((code) => ({ code, optionId: option.id }));
|
|
3557
|
+
}
|
|
3558
|
+
function tiersAreValid(option) {
|
|
3559
|
+
const tiers = option.priceByTotal ?? [];
|
|
3560
|
+
const froms = tiers.map((tier) => tier.from);
|
|
3561
|
+
return tiers.every((tier) => Number.isInteger(tier.from) && tier.from > 0 && isAmount(tier.price)) && new Set(froms).size === froms.length;
|
|
3562
|
+
}
|
|
3563
|
+
|
|
3198
3564
|
// constants/adyen.constants.ts
|
|
3199
3565
|
var ADYEN_ROLLOUT_COUNTRY_CODES = /* @__PURE__ */ new Set(["CA"]);
|
|
3200
3566
|
function isAdyenRolloutCountry(alpha2) {
|
|
3201
3567
|
return ADYEN_ROLLOUT_COUNTRY_CODES.has(alpha2);
|
|
3202
3568
|
}
|
|
3569
|
+
var AFFIRM_PRICE_PLANS = ["core", "standard", "signature"];
|
|
3570
|
+
function isAffirmPricePlan(value) {
|
|
3571
|
+
return typeof value === "string" && AFFIRM_PRICE_PLANS.includes(value);
|
|
3572
|
+
}
|
|
3573
|
+
var AFFIRM_COUNTRY_CODES = /* @__PURE__ */ new Set(["CA"]);
|
|
3574
|
+
function isAffirmCountry(alpha2) {
|
|
3575
|
+
return !!alpha2 && AFFIRM_COUNTRY_CODES.has(alpha2.toUpperCase());
|
|
3576
|
+
}
|
|
3577
|
+
var BNPL_METHOD_STATUS = {
|
|
3578
|
+
ACTIVE: "active",
|
|
3579
|
+
PENDING: "pending",
|
|
3580
|
+
UNAVAILABLE: "unavailable",
|
|
3581
|
+
UNKNOWN: "unknown"
|
|
3582
|
+
};
|
|
3583
|
+
var BNPL_SKIP_REASON = {
|
|
3584
|
+
PENDING: "pending",
|
|
3585
|
+
NO_SUPPORT_EMAIL: "no_support_email",
|
|
3586
|
+
NO_CURRENCY: "no_currency",
|
|
3587
|
+
NO_BUSINESS_LINE: "no_business_line"
|
|
3588
|
+
};
|
|
3589
|
+
|
|
3590
|
+
// pos-types/active/ProcessorType.ts
|
|
3591
|
+
var ProcessorType = /* @__PURE__ */ ((ProcessorType2) => {
|
|
3592
|
+
ProcessorType2["FINAL_PAY"] = "Terminal";
|
|
3593
|
+
ProcessorType2["TAP_TO_PAY"] = "TapToPay";
|
|
3594
|
+
ProcessorType2["MOTO"] = "Moto";
|
|
3595
|
+
ProcessorType2["CLOUD"] = "Cloud";
|
|
3596
|
+
ProcessorType2["BLUETOOTH"] = "Bluetooth";
|
|
3597
|
+
ProcessorType2["CASH"] = "Cash";
|
|
3598
|
+
ProcessorType2["CUSTOM_PAY"] = "CustomPay";
|
|
3599
|
+
ProcessorType2["VENDARA"] = "Vendara";
|
|
3600
|
+
ProcessorType2["REDEEM"] = "Redeem";
|
|
3601
|
+
ProcessorType2["INTEGRATION"] = "Integration";
|
|
3602
|
+
ProcessorType2["PAYMENT_LINK"] = "PaymentLink";
|
|
3603
|
+
ProcessorType2["ONLINE_PAYMENT"] = "OnlinePayment";
|
|
3604
|
+
return ProcessorType2;
|
|
3605
|
+
})(ProcessorType || {});
|
|
3606
|
+
|
|
3607
|
+
// constants/payment-channel.constants.ts
|
|
3608
|
+
var PAYMENT_CHANNELS = ["inPerson", "online"];
|
|
3203
3609
|
export {
|
|
3204
3610
|
ADYEN_ROLLOUT_COUNTRY_CODES,
|
|
3611
|
+
AFFIRM_COUNTRY_CODES,
|
|
3612
|
+
AFFIRM_PRICE_PLANS,
|
|
3205
3613
|
AttributeType,
|
|
3614
|
+
BNPL_METHOD_STATUS,
|
|
3615
|
+
BNPL_SKIP_REASON,
|
|
3206
3616
|
BookingRatePeriod,
|
|
3207
3617
|
BookingResourceKind,
|
|
3208
3618
|
BookingResourceStatus,
|
|
3209
3619
|
BookingRulesError,
|
|
3210
3620
|
BookingType,
|
|
3621
|
+
CANADA_PROVINCES,
|
|
3211
3622
|
CONDITION_OPERATORS,
|
|
3212
3623
|
COUNTRY_CURRENCIES,
|
|
3213
3624
|
CURRENCY_CONFIG,
|
|
@@ -3224,6 +3635,7 @@ export {
|
|
|
3224
3635
|
DualWriteStrategy,
|
|
3225
3636
|
EUFixedRates,
|
|
3226
3637
|
EUROPE,
|
|
3638
|
+
EVERYWHERE_KEY,
|
|
3227
3639
|
ExtensionCategory,
|
|
3228
3640
|
FINANCIAL_INVARIANTS,
|
|
3229
3641
|
FULFILLMENT_STATES,
|
|
@@ -3245,6 +3657,7 @@ export {
|
|
|
3245
3657
|
OtherFixedRates,
|
|
3246
3658
|
OwnerType,
|
|
3247
3659
|
PATH_MODES,
|
|
3660
|
+
PAYMENT_CHANNELS,
|
|
3248
3661
|
PAYMENT_STATES,
|
|
3249
3662
|
POS_VALID_INITIAL_STATES,
|
|
3250
3663
|
PaymentMethod,
|
|
@@ -3254,6 +3667,7 @@ export {
|
|
|
3254
3667
|
PricingLevel,
|
|
3255
3668
|
PricingPlanEnum,
|
|
3256
3669
|
PricingRegionEnum,
|
|
3670
|
+
ProcessorType,
|
|
3257
3671
|
ProductStatus,
|
|
3258
3672
|
ProductType,
|
|
3259
3673
|
PublicationAvailability,
|
|
@@ -3272,6 +3686,12 @@ export {
|
|
|
3272
3686
|
SYSTEM_FAMILY_IDS,
|
|
3273
3687
|
SYSTEM_UNITS,
|
|
3274
3688
|
SYSTEM_UNIT_IDS,
|
|
3689
|
+
ShippingChannel,
|
|
3690
|
+
ShippingNoOptionReason,
|
|
3691
|
+
ShippingOptionType,
|
|
3692
|
+
ShippingRateType,
|
|
3693
|
+
ShippingZoneError,
|
|
3694
|
+
ShippingZoneKind,
|
|
3275
3695
|
StationStatus,
|
|
3276
3696
|
StripeCurrencyCode,
|
|
3277
3697
|
StripeStatus,
|
|
@@ -3279,6 +3699,7 @@ export {
|
|
|
3279
3699
|
TopMetericsSort,
|
|
3280
3700
|
UserTypes,
|
|
3281
3701
|
addAmounts,
|
|
3702
|
+
addressPlaceKeys,
|
|
3282
3703
|
amountToString,
|
|
3283
3704
|
assertUnitSane,
|
|
3284
3705
|
availableIn,
|
|
@@ -3330,6 +3751,8 @@ export {
|
|
|
3330
3751
|
holdExpiresAt,
|
|
3331
3752
|
inferStatesFromLegacyStatus,
|
|
3332
3753
|
isAdyenRolloutCountry,
|
|
3754
|
+
isAffirmCountry,
|
|
3755
|
+
isAffirmPricePlan,
|
|
3333
3756
|
isConditionOperator,
|
|
3334
3757
|
isFulfillmentState,
|
|
3335
3758
|
isPaymentState,
|
|
@@ -3337,19 +3760,31 @@ export {
|
|
|
3337
3760
|
isSystemFamilyCode,
|
|
3338
3761
|
isValidQuantity,
|
|
3339
3762
|
isWhole,
|
|
3763
|
+
listCountries,
|
|
3764
|
+
listProvinces,
|
|
3340
3765
|
mapToLegacyStatus,
|
|
3341
3766
|
maxPrecisionFor,
|
|
3342
3767
|
mergeFragment,
|
|
3343
3768
|
multiplyAmount,
|
|
3769
|
+
normalizeAddress,
|
|
3770
|
+
normalizeCityKey,
|
|
3771
|
+
normalizeCountry,
|
|
3344
3772
|
normalizeMongoIdString,
|
|
3773
|
+
normalizePostCode,
|
|
3774
|
+
normalizeProvince,
|
|
3345
3775
|
occupancyIn,
|
|
3346
3776
|
parseAmountToMinorUnits,
|
|
3347
3777
|
parseCurrencyCode,
|
|
3348
3778
|
parseStripeCurrencyCode,
|
|
3779
|
+
placeKey,
|
|
3349
3780
|
planWindow,
|
|
3781
|
+
postCodeMatchesProvince,
|
|
3350
3782
|
presentAt,
|
|
3783
|
+
priceForTotal,
|
|
3784
|
+
provincesForPostCode,
|
|
3351
3785
|
removeFragment,
|
|
3352
3786
|
resolveFamily,
|
|
3787
|
+
resolveShipping,
|
|
3353
3788
|
resolveTemplate,
|
|
3354
3789
|
resolveUnit,
|
|
3355
3790
|
roundToPrecision,
|
|
@@ -3365,6 +3800,7 @@ export {
|
|
|
3365
3800
|
toMinorUnits,
|
|
3366
3801
|
validateConfig,
|
|
3367
3802
|
validateFragmentCompatibility,
|
|
3803
|
+
validateShippingZone,
|
|
3368
3804
|
violatesFinancialInvariant,
|
|
3369
3805
|
windowEndsAt,
|
|
3370
3806
|
withinPresence
|