@moonbase.sh/storefront-api 2.3.0 → 2.4.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.
- package/dist/index.cjs +101 -53
- package/dist/index.d.cts +13905 -5554
- package/dist/index.d.ts +13905 -5554
- package/dist/index.js +101 -53
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -20,6 +20,7 @@ __export(schemas_exports2, {
|
|
|
20
20
|
offerConditionSchema: () => offerConditionSchema,
|
|
21
21
|
storefrontBundleSchema: () => storefrontBundleSchema,
|
|
22
22
|
storefrontOfferSchema: () => storefrontOfferSchema,
|
|
23
|
+
storefrontOfferTargetSchema: () => storefrontOfferTargetSchema,
|
|
23
24
|
storefrontProductSchema: () => storefrontProductSchema,
|
|
24
25
|
storefrontSchema: () => storefrontSchema,
|
|
25
26
|
taxEstimateSchema: () => taxEstimateSchema
|
|
@@ -236,13 +237,36 @@ var cartContainsItemsConditionSchema = z3.object({
|
|
|
236
237
|
relevantItemVariations: z3.record(z3.string(), z3.string().array())
|
|
237
238
|
});
|
|
238
239
|
var offerConditionSchema = z3.discriminatedUnion("type", [cartContainsItemsConditionSchema]);
|
|
240
|
+
var offerTargetItemSchema = z3.union([storefrontProductSchema, storefrontBundleSchema]);
|
|
241
|
+
var storefrontOfferTargetSchema = z3.object({
|
|
242
|
+
// The product or bundle the offer applies to.
|
|
243
|
+
item: offerTargetItemSchema,
|
|
244
|
+
// The pricing variation IDs the offer is restricted to; an empty list means all variations.
|
|
245
|
+
variations: z3.string().array()
|
|
246
|
+
});
|
|
247
|
+
function legacyOfferTargets(target, targetVariations) {
|
|
248
|
+
if (!target)
|
|
249
|
+
return [];
|
|
250
|
+
const items = Array.isArray(target) ? target : [target];
|
|
251
|
+
return items.map((item) => ({ item, variations: items.length === 1 ? targetVariations != null ? targetVariations : [] : [] }));
|
|
252
|
+
}
|
|
239
253
|
var storefrontOfferSchema = z3.object({
|
|
240
254
|
id: z3.string(),
|
|
241
|
-
target
|
|
242
|
-
|
|
255
|
+
// Each target pairs a product/bundle with the pricing variations the offer applies to (an empty
|
|
256
|
+
// list means all variations). This is the model to consume.
|
|
257
|
+
targets: z3.array(storefrontOfferTargetSchema).optional(),
|
|
258
|
+
// Legacy fields, kept optional only so old cached storefront responses still parse. The API now
|
|
259
|
+
// exposes the unified `targets` model; we derive `targets` from these when a response predates it.
|
|
260
|
+
// `.catch` guards against the deprecated shape drifting: a malformed legacy field is ignored
|
|
261
|
+
// rather than failing the whole response (newer responses carry `targets` anyway).
|
|
262
|
+
target: singleOrMultiple(offerTargetItemSchema).optional().catch(void 0),
|
|
263
|
+
targetVariations: z3.string().array().optional().catch(void 0),
|
|
243
264
|
condition: offerConditionSchema,
|
|
244
265
|
discount: discountSchema
|
|
245
|
-
})
|
|
266
|
+
}).transform(({ target, targetVariations, targets, ...rest }) => ({
|
|
267
|
+
...rest,
|
|
268
|
+
targets: targets != null ? targets : legacyOfferTargets(target, targetVariations)
|
|
269
|
+
}));
|
|
246
270
|
var taxEstimateSchema = z3.object({
|
|
247
271
|
rate: z3.number(),
|
|
248
272
|
mode: z3.enum(["Exclusive", "Inclusive"]),
|
|
@@ -464,11 +488,11 @@ async function handleResponseProblem(response, logger) {
|
|
|
464
488
|
throw new NotAuthorizedError();
|
|
465
489
|
}
|
|
466
490
|
let problemDetails;
|
|
491
|
+
const body = await response.text();
|
|
467
492
|
try {
|
|
468
|
-
|
|
469
|
-
problemDetails = problemDetailsSchema.parse(json);
|
|
493
|
+
problemDetails = problemDetailsSchema.parse(JSON.parse(body));
|
|
470
494
|
} catch (err) {
|
|
471
|
-
logger.warn("Could not handle response", { response, err, content:
|
|
495
|
+
logger.warn("Could not handle response", { response, err, content: body });
|
|
472
496
|
throw new Error("An unknown problem occurred");
|
|
473
497
|
}
|
|
474
498
|
logger.debug("The response indicates a problem", problemDetails);
|
|
@@ -532,7 +556,8 @@ var connectionUrlSchema = z8.object({
|
|
|
532
556
|
var userSchema = z8.object({
|
|
533
557
|
id: z8.string(),
|
|
534
558
|
email: z8.string(),
|
|
535
|
-
|
|
559
|
+
// Nullable: customers created via import may have no name.
|
|
560
|
+
name: z8.string().nullable(),
|
|
536
561
|
tenantId: z8.string(),
|
|
537
562
|
address: addressSchema.optional(),
|
|
538
563
|
phone: z8.string().optional(),
|
|
@@ -861,6 +886,9 @@ var ProductEndpoints = class {
|
|
|
861
886
|
}
|
|
862
887
|
};
|
|
863
888
|
|
|
889
|
+
// src/inventory/subscriptions/endpoints.ts
|
|
890
|
+
import { z as z14 } from "zod";
|
|
891
|
+
|
|
864
892
|
// src/utils/api.ts
|
|
865
893
|
function objectToQuery(obj) {
|
|
866
894
|
return Object.entries(obj != null ? obj : {}).filter(([_, value]) => value !== void 0).map(([key, value]) => `${key}=${encodeURIComponent(value instanceof Date ? value.toISOString() : value)}`).join("&");
|
|
@@ -986,9 +1014,6 @@ var MoonbaseApi = class {
|
|
|
986
1014
|
}
|
|
987
1015
|
};
|
|
988
1016
|
|
|
989
|
-
// src/inventory/subscriptions/endpoints.ts
|
|
990
|
-
import { z as z14 } from "zod";
|
|
991
|
-
|
|
992
1017
|
// src/inventory/subscriptions/schemas.ts
|
|
993
1018
|
var schemas_exports8 = {};
|
|
994
1019
|
__export(schemas_exports8, {
|
|
@@ -997,15 +1022,6 @@ __export(schemas_exports8, {
|
|
|
997
1022
|
});
|
|
998
1023
|
import { z as z13 } from "zod";
|
|
999
1024
|
|
|
1000
|
-
// src/inventory/subscriptions/models.ts
|
|
1001
|
-
var SubscriptionStatus = /* @__PURE__ */ ((SubscriptionStatus2) => {
|
|
1002
|
-
SubscriptionStatus2["Active"] = "Active";
|
|
1003
|
-
SubscriptionStatus2["Expired"] = "Expired";
|
|
1004
|
-
SubscriptionStatus2["Cancelled"] = "Cancelled";
|
|
1005
|
-
SubscriptionStatus2["Completed"] = "Completed";
|
|
1006
|
-
return SubscriptionStatus2;
|
|
1007
|
-
})(SubscriptionStatus || {});
|
|
1008
|
-
|
|
1009
1025
|
// src/orders/schemas.ts
|
|
1010
1026
|
var schemas_exports7 = {};
|
|
1011
1027
|
__export(schemas_exports7, {
|
|
@@ -1142,6 +1158,15 @@ var orderSchema = z12.discriminatedUnion("status", [
|
|
|
1142
1158
|
completedOrderSchema
|
|
1143
1159
|
]);
|
|
1144
1160
|
|
|
1161
|
+
// src/inventory/subscriptions/models.ts
|
|
1162
|
+
var SubscriptionStatus = /* @__PURE__ */ ((SubscriptionStatus2) => {
|
|
1163
|
+
SubscriptionStatus2["Active"] = "Active";
|
|
1164
|
+
SubscriptionStatus2["Expired"] = "Expired";
|
|
1165
|
+
SubscriptionStatus2["Cancelled"] = "Cancelled";
|
|
1166
|
+
SubscriptionStatus2["Completed"] = "Completed";
|
|
1167
|
+
return SubscriptionStatus2;
|
|
1168
|
+
})(SubscriptionStatus || {});
|
|
1169
|
+
|
|
1145
1170
|
// src/inventory/subscriptions/schemas.ts
|
|
1146
1171
|
var baseMilestoneProgressEventSchema = z13.object({
|
|
1147
1172
|
milestoneId: z13.string(),
|
|
@@ -1317,6 +1342,36 @@ var StorefrontEndpoints = class {
|
|
|
1317
1342
|
}
|
|
1318
1343
|
};
|
|
1319
1344
|
|
|
1345
|
+
// src/utils/logger.ts
|
|
1346
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
1347
|
+
LogLevel2[LogLevel2["Debug"] = 0] = "Debug";
|
|
1348
|
+
LogLevel2[LogLevel2["Information"] = 1] = "Information";
|
|
1349
|
+
LogLevel2[LogLevel2["Warn"] = 2] = "Warn";
|
|
1350
|
+
LogLevel2[LogLevel2["Error"] = 3] = "Error";
|
|
1351
|
+
return LogLevel2;
|
|
1352
|
+
})(LogLevel || {});
|
|
1353
|
+
var ConsoleLogger = class {
|
|
1354
|
+
constructor(level = 2 /* Warn */) {
|
|
1355
|
+
this.level = level;
|
|
1356
|
+
}
|
|
1357
|
+
debug(message, ...optionalParams) {
|
|
1358
|
+
if (this.level <= 0 /* Debug */)
|
|
1359
|
+
console.debug(message, ...optionalParams);
|
|
1360
|
+
}
|
|
1361
|
+
log(message, ...optionalParams) {
|
|
1362
|
+
if (this.level <= 1 /* Information */)
|
|
1363
|
+
console.log(message, ...optionalParams);
|
|
1364
|
+
}
|
|
1365
|
+
warn(message, ...optionalParams) {
|
|
1366
|
+
if (this.level <= 2 /* Warn */)
|
|
1367
|
+
console.warn(message, ...optionalParams);
|
|
1368
|
+
}
|
|
1369
|
+
error(message, ...optionalParams) {
|
|
1370
|
+
if (this.level <= 3 /* Error */)
|
|
1371
|
+
console.error(message, ...optionalParams);
|
|
1372
|
+
}
|
|
1373
|
+
};
|
|
1374
|
+
|
|
1320
1375
|
// src/utils/store.ts
|
|
1321
1376
|
var LocalStorageStore = class {
|
|
1322
1377
|
get(key) {
|
|
@@ -1364,7 +1419,8 @@ var InMemoryStore = class {
|
|
|
1364
1419
|
}
|
|
1365
1420
|
}
|
|
1366
1421
|
listen(key, callback) {
|
|
1367
|
-
if (!this.listeners[key])
|
|
1422
|
+
if (!this.listeners[key])
|
|
1423
|
+
this.listeners[key] = [];
|
|
1368
1424
|
this.listeners[key].push(callback);
|
|
1369
1425
|
}
|
|
1370
1426
|
};
|
|
@@ -1408,7 +1464,8 @@ var _TokenStore = class _TokenStore {
|
|
|
1408
1464
|
setUser(user) {
|
|
1409
1465
|
const identity = user;
|
|
1410
1466
|
if (!identity.accessToken || !identity.refreshToken) {
|
|
1411
|
-
if (!this.tokens)
|
|
1467
|
+
if (!this.tokens)
|
|
1468
|
+
return null;
|
|
1412
1469
|
this.tokens = {
|
|
1413
1470
|
...user,
|
|
1414
1471
|
accessToken: this.tokens.accessToken,
|
|
@@ -1538,32 +1595,6 @@ var VoucherEndpoints = class {
|
|
|
1538
1595
|
}
|
|
1539
1596
|
};
|
|
1540
1597
|
|
|
1541
|
-
// src/utils/logger.ts
|
|
1542
|
-
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
1543
|
-
LogLevel2[LogLevel2["Debug"] = 0] = "Debug";
|
|
1544
|
-
LogLevel2[LogLevel2["Information"] = 1] = "Information";
|
|
1545
|
-
LogLevel2[LogLevel2["Warn"] = 2] = "Warn";
|
|
1546
|
-
LogLevel2[LogLevel2["Error"] = 3] = "Error";
|
|
1547
|
-
return LogLevel2;
|
|
1548
|
-
})(LogLevel || {});
|
|
1549
|
-
var ConsoleLogger = class {
|
|
1550
|
-
constructor(level = 2 /* Warn */) {
|
|
1551
|
-
this.level = level;
|
|
1552
|
-
}
|
|
1553
|
-
debug(message, ...optionalParams) {
|
|
1554
|
-
if (this.level <= 0 /* Debug */) console.debug(message, ...optionalParams);
|
|
1555
|
-
}
|
|
1556
|
-
log(message, ...optionalParams) {
|
|
1557
|
-
if (this.level <= 1 /* Information */) console.log(message, ...optionalParams);
|
|
1558
|
-
}
|
|
1559
|
-
warn(message, ...optionalParams) {
|
|
1560
|
-
if (this.level <= 2 /* Warn */) console.warn(message, ...optionalParams);
|
|
1561
|
-
}
|
|
1562
|
-
error(message, ...optionalParams) {
|
|
1563
|
-
if (this.level <= 3 /* Error */) console.error(message, ...optionalParams);
|
|
1564
|
-
}
|
|
1565
|
-
};
|
|
1566
|
-
|
|
1567
1598
|
// src/schemas.ts
|
|
1568
1599
|
var schemas_exports12 = {};
|
|
1569
1600
|
__export(schemas_exports12, {
|
|
@@ -1614,7 +1645,7 @@ var MoneyCollectionUtils = class {
|
|
|
1614
1645
|
var OfferUtils = class _OfferUtils {
|
|
1615
1646
|
static eligible(offer, order) {
|
|
1616
1647
|
switch (offer.condition.type) {
|
|
1617
|
-
case "CartContainsItems":
|
|
1648
|
+
case "CartContainsItems": {
|
|
1618
1649
|
const relevantItems = order.items.filter(
|
|
1619
1650
|
(i) => i.type === "Product" && offer.condition.relevantItemVariations[`Product/${i.productId}`] && offer.condition.relevantItemVariations[`Product/${i.productId}`].includes(i.variationId) || i.type === "Bundle" && offer.condition.relevantItemVariations[`Bundle/${i.bundleId}`] && offer.condition.relevantItemVariations[`Bundle/${i.bundleId}`].includes(i.variationId)
|
|
1620
1651
|
);
|
|
@@ -1626,6 +1657,7 @@ var OfferUtils = class _OfferUtils {
|
|
|
1626
1657
|
return offer.condition.relevantItemVariations[`Product/${productId}`] && offer.condition.relevantItemVariations[`Product/${productId}`].includes(variationId);
|
|
1627
1658
|
});
|
|
1628
1659
|
return relevantItems.length + relevantReplacedItems.length >= offer.condition.minimumItems;
|
|
1660
|
+
}
|
|
1629
1661
|
}
|
|
1630
1662
|
console.warn("Unsupported offer condition found:", offer.condition);
|
|
1631
1663
|
return false;
|
|
@@ -1634,11 +1666,27 @@ var OfferUtils = class _OfferUtils {
|
|
|
1634
1666
|
// a. Not be owned, or all targets need to be owned
|
|
1635
1667
|
// b. Not already in the cart
|
|
1636
1668
|
static relevantTargets(offer, cartItems) {
|
|
1637
|
-
if (
|
|
1638
|
-
const allOwned = offer.
|
|
1639
|
-
return offer.
|
|
1669
|
+
if (offer.targets.length > 1) {
|
|
1670
|
+
const allOwned = offer.targets.every((t) => t.item.owned);
|
|
1671
|
+
return offer.targets.filter((t) => (allOwned || !t.item.owned) && !cartItems.some((l) => l.type === t.item.type && t.item.id === (l.type === "Product" ? l.productId : l.bundleId)));
|
|
1640
1672
|
}
|
|
1641
|
-
return
|
|
1673
|
+
return offer.targets;
|
|
1674
|
+
}
|
|
1675
|
+
// The pricing variations a target restricts the offer to. An empty (or missing) variation list
|
|
1676
|
+
// means the offer is not narrowed to specific variations, in which case we keep the established
|
|
1677
|
+
// single default-variation upsell.
|
|
1678
|
+
static targetedVariations(target) {
|
|
1679
|
+
var _a;
|
|
1680
|
+
const { item, variations } = target;
|
|
1681
|
+
if (variations.length === 0)
|
|
1682
|
+
return item.defaultVariation ? [item.defaultVariation] : [];
|
|
1683
|
+
const itemVariations = (_a = item.variations) != null ? _a : item.defaultVariation ? [item.defaultVariation] : [];
|
|
1684
|
+
return itemVariations.filter((v) => variations.includes(v.id));
|
|
1685
|
+
}
|
|
1686
|
+
// Expands the relevant targets into one `{ target, variation }` entry per targeted variation, so
|
|
1687
|
+
// an offer targeting several variations (or several products) surfaces each as its own upsell row.
|
|
1688
|
+
static relevantTargetVariations(offer, cartItems) {
|
|
1689
|
+
return _OfferUtils.relevantTargets(offer, cartItems).flatMap((target) => _OfferUtils.targetedVariations(target).map((variation) => ({ target: target.item, variation })));
|
|
1642
1690
|
}
|
|
1643
1691
|
static applyToVariation(offer, variation) {
|
|
1644
1692
|
const discount = DiscountUtils.apply(offer.discount, variation.price);
|
|
@@ -1649,7 +1697,7 @@ var OfferUtils = class _OfferUtils {
|
|
|
1649
1697
|
};
|
|
1650
1698
|
}
|
|
1651
1699
|
static targetContainsBundle(offer, bundleId) {
|
|
1652
|
-
|
|
1700
|
+
return offer.targets.some((t) => t.item.type === "Bundle" && t.item.id === bundleId);
|
|
1653
1701
|
}
|
|
1654
1702
|
};
|
|
1655
1703
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moonbase.sh/storefront-api",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.4.0",
|
|
5
5
|
"description": "Package to let you build storefronts with Moonbase.sh as payment and delivery provider",
|
|
6
6
|
"author": "Tobias Lønnerød Madsen <m@dsen.tv>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -26,6 +26,9 @@
|
|
|
26
26
|
"build": "tsup src/index.ts --format esm,cjs --dts",
|
|
27
27
|
"dev": "tsup src/index.ts --format esm,cjs --watch --dts",
|
|
28
28
|
"version": "npm version",
|
|
29
|
-
"
|
|
29
|
+
"type-check": "tsc --noEmit -p tsconfig.typecheck.json",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"test:watch": "vitest",
|
|
32
|
+
"test:integration": "TEST_INTEGRATION=true vitest run"
|
|
30
33
|
}
|
|
31
34
|
}
|