@juo/blocks 1.12.0-alpha.2 → 1.12.0-alpha.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/core.js +515 -378
- package/dist/services/product/adapter.d.ts.map +1 -1
- package/dist/services/schedules/adapter.d.ts +23 -1
- package/dist/services/schedules/adapter.d.ts.map +1 -1
- package/dist/services/subscription/adapter.d.ts +9 -0
- package/dist/services/subscription/adapter.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/core.js
CHANGED
|
@@ -761,7 +761,7 @@ function createMockProductAdapter() {
|
|
|
761
761
|
id: "sample-1",
|
|
762
762
|
title: "Hydrating Gel Cleanser for Face and Eye Area",
|
|
763
763
|
featuredImage: {
|
|
764
|
-
url: "https://
|
|
764
|
+
url: "https://placehold.co/400x400?text=Product+1"
|
|
765
765
|
},
|
|
766
766
|
hasOnlyDefaultVariant: true,
|
|
767
767
|
variants: [
|
|
@@ -769,7 +769,7 @@ function createMockProductAdapter() {
|
|
|
769
769
|
id: "sample-1-1",
|
|
770
770
|
title: "150 ml bottle",
|
|
771
771
|
image: {
|
|
772
|
-
url: "https://
|
|
772
|
+
url: "https://placehold.co/400x400?text=Product+1"
|
|
773
773
|
},
|
|
774
774
|
price: {
|
|
775
775
|
amount: "12.49",
|
|
@@ -795,7 +795,7 @@ function createMockProductAdapter() {
|
|
|
795
795
|
id: "sample-2",
|
|
796
796
|
title: "More COLLAGEN",
|
|
797
797
|
featuredImage: {
|
|
798
|
-
url: "https://
|
|
798
|
+
url: "https://placehold.co/400x400?text=Product+2"
|
|
799
799
|
},
|
|
800
800
|
hasOnlyDefaultVariant: true,
|
|
801
801
|
variants: [
|
|
@@ -803,7 +803,7 @@ function createMockProductAdapter() {
|
|
|
803
803
|
id: "sample-2-1",
|
|
804
804
|
title: "blackcurrant",
|
|
805
805
|
image: {
|
|
806
|
-
url: "https://
|
|
806
|
+
url: "https://placehold.co/400x400?text=Product+2"
|
|
807
807
|
},
|
|
808
808
|
price: {
|
|
809
809
|
amount: "12.49",
|
|
@@ -824,7 +824,7 @@ function createMockProductAdapter() {
|
|
|
824
824
|
id: "sample-3",
|
|
825
825
|
title: "Gentle deodorant for underarms and bust",
|
|
826
826
|
featuredImage: {
|
|
827
|
-
url: "https://
|
|
827
|
+
url: "https://placehold.co/400x400?text=Product+3"
|
|
828
828
|
},
|
|
829
829
|
hasOnlyDefaultVariant: false,
|
|
830
830
|
variants: [
|
|
@@ -832,7 +832,7 @@ function createMockProductAdapter() {
|
|
|
832
832
|
id: "sample-3-1",
|
|
833
833
|
title: "Green tea and jasmine",
|
|
834
834
|
image: {
|
|
835
|
-
url: "https://
|
|
835
|
+
url: "https://placehold.co/400x400?text=Product+3a"
|
|
836
836
|
},
|
|
837
837
|
price: {
|
|
838
838
|
amount: "6.7",
|
|
@@ -850,7 +850,7 @@ function createMockProductAdapter() {
|
|
|
850
850
|
id: "sample-3-2",
|
|
851
851
|
title: "Lavender and mint",
|
|
852
852
|
image: {
|
|
853
|
-
url: "https://
|
|
853
|
+
url: "https://placehold.co/400x400?text=Product+3b"
|
|
854
854
|
},
|
|
855
855
|
price: {
|
|
856
856
|
amount: "7.5",
|
|
@@ -882,6 +882,48 @@ function createMockProductAdapter() {
|
|
|
882
882
|
}
|
|
883
883
|
};
|
|
884
884
|
}
|
|
885
|
+
function toAvailableProduct(product) {
|
|
886
|
+
return {
|
|
887
|
+
id: product.id,
|
|
888
|
+
title: product.title,
|
|
889
|
+
description: `Sample description for ${product.title}.`,
|
|
890
|
+
featuredImage: product.featuredImage ?? void 0,
|
|
891
|
+
hasOnlyDefaultVariant: product.hasOnlyDefaultVariant,
|
|
892
|
+
variants: product.variants.map((variant) => {
|
|
893
|
+
var _a, _b, _c;
|
|
894
|
+
const base = Number.parseFloat(variant.price.amount);
|
|
895
|
+
const sub = (_b = (_a = variant.purchaseOptions) == null ? void 0 : _a[0]) == null ? void 0 : _b.price.amount;
|
|
896
|
+
const current = sub == null ? base : Number.parseFloat(sub);
|
|
897
|
+
return {
|
|
898
|
+
id: variant.id,
|
|
899
|
+
availableForSale: true,
|
|
900
|
+
title: variant.title,
|
|
901
|
+
currentPrice: { amount: current, currencyCode: variant.price.currencyCode },
|
|
902
|
+
basePrice: { amount: base, currencyCode: variant.price.currencyCode },
|
|
903
|
+
image: variant.image ?? void 0,
|
|
904
|
+
recurring: (((_c = variant.purchaseOptions) == null ? void 0 : _c.length) ?? 0) > 0
|
|
905
|
+
};
|
|
906
|
+
})
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
const sampleBox = {
|
|
910
|
+
id: "sample-box-1",
|
|
911
|
+
title: "Build Your Own Box",
|
|
912
|
+
minProductsCount: 3,
|
|
913
|
+
parentProduct: "sample-1",
|
|
914
|
+
tiers: [
|
|
915
|
+
{ value: 5, threshold: 3 },
|
|
916
|
+
{ value: 10, threshold: 5 }
|
|
917
|
+
],
|
|
918
|
+
variants: products.map((product) => ({
|
|
919
|
+
id: product.id,
|
|
920
|
+
variants: product.variants.map((variant) => ({ id: variant.id }))
|
|
921
|
+
})),
|
|
922
|
+
freeVariants: [],
|
|
923
|
+
thresholdType: "LINES_COUNT",
|
|
924
|
+
type: "PERCENTAGE",
|
|
925
|
+
restrictQuantityToTiers: false
|
|
926
|
+
};
|
|
885
927
|
return {
|
|
886
928
|
async getById(id) {
|
|
887
929
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -895,17 +937,26 @@ function createMockProductAdapter() {
|
|
|
895
937
|
);
|
|
896
938
|
return product == null ? null : processProduct(product);
|
|
897
939
|
},
|
|
898
|
-
async getProductsByIds() {
|
|
899
|
-
|
|
940
|
+
async getProductsByIds({ ids }) {
|
|
941
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
942
|
+
return products.filter((product) => ids.includes(product.id)).map(({ variants: _variants, ...product }) => product);
|
|
900
943
|
},
|
|
901
|
-
async getBoxVariants() {
|
|
902
|
-
|
|
944
|
+
async getBoxVariants({ ids }) {
|
|
945
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
946
|
+
return products.filter((product) => ids.includes(product.id)).map(toAvailableProduct);
|
|
903
947
|
},
|
|
904
|
-
async getAvailableProducts() {
|
|
905
|
-
|
|
948
|
+
async getAvailableProducts({ q: q2 }) {
|
|
949
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
950
|
+
const queryLower = q2 == null ? void 0 : q2.toLowerCase();
|
|
951
|
+
return products.filter(
|
|
952
|
+
(product) => !queryLower || product.title.toLowerCase().includes(queryLower) || product.variants.some(
|
|
953
|
+
(variant) => variant.title.toLowerCase().includes(queryLower)
|
|
954
|
+
)
|
|
955
|
+
).map(toAvailableProduct);
|
|
906
956
|
},
|
|
907
|
-
async getBox() {
|
|
908
|
-
|
|
957
|
+
async getBox({ id }) {
|
|
958
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
959
|
+
return id === sampleBox.id ? sampleBox : null;
|
|
909
960
|
},
|
|
910
961
|
async search(opts) {
|
|
911
962
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
@@ -1195,347 +1246,6 @@ function createMockRouterService() {
|
|
|
1195
1246
|
}
|
|
1196
1247
|
}).routerService;
|
|
1197
1248
|
}
|
|
1198
|
-
function futureDateStr(daysFromNow) {
|
|
1199
|
-
const d3 = /* @__PURE__ */ new Date();
|
|
1200
|
-
d3.setDate(d3.getDate() + daysFromNow);
|
|
1201
|
-
return d3.toISOString().split("T")[0] ?? "";
|
|
1202
|
-
}
|
|
1203
|
-
function createMockSchedulesAdapter() {
|
|
1204
|
-
let orders = [
|
|
1205
|
-
{
|
|
1206
|
-
id: "sched_1",
|
|
1207
|
-
customerId: "customer_1",
|
|
1208
|
-
subscriptionId: "sub_1",
|
|
1209
|
-
date: "2026-05-22T12:00:00Z",
|
|
1210
|
-
skipped: false,
|
|
1211
|
-
currencyCode: "USD",
|
|
1212
|
-
subtotal: 2999,
|
|
1213
|
-
deliveryPrice: 500,
|
|
1214
|
-
cycleIndex: 4,
|
|
1215
|
-
deliveryDate: futureDateStr(7),
|
|
1216
|
-
status: "scheduled",
|
|
1217
|
-
items: [
|
|
1218
|
-
{
|
|
1219
|
-
id: "sched_item_1",
|
|
1220
|
-
title: "Rose Face Serum",
|
|
1221
|
-
subtitle: null,
|
|
1222
|
-
imageUrl: "https://images.unsplash.com/photo-1611930022073-b7a4ba5fcccd?w=200",
|
|
1223
|
-
variantId: "variant_1",
|
|
1224
|
-
quantity: 1,
|
|
1225
|
-
price: 2999,
|
|
1226
|
-
totalPrice: 2999,
|
|
1227
|
-
variantImage: null,
|
|
1228
|
-
variantAvailableForSale: true,
|
|
1229
|
-
subscriptionId: "sub_1",
|
|
1230
|
-
subscriptionLineId: "item_1",
|
|
1231
|
-
productId: "product_1",
|
|
1232
|
-
parentProductId: null,
|
|
1233
|
-
parentLineId: null,
|
|
1234
|
-
isVirtual: false,
|
|
1235
|
-
isUpsell: false,
|
|
1236
|
-
isOneTime: false,
|
|
1237
|
-
customAttributes: []
|
|
1238
|
-
},
|
|
1239
|
-
{
|
|
1240
|
-
id: "sched_item_2",
|
|
1241
|
-
title: "Vitamin C Moisturizer",
|
|
1242
|
-
subtitle: null,
|
|
1243
|
-
imageUrl: "https://images.unsplash.com/photo-1556228578-8c89e6adf883?w=200",
|
|
1244
|
-
variantId: "variant_2",
|
|
1245
|
-
quantity: 1,
|
|
1246
|
-
price: 2999,
|
|
1247
|
-
totalPrice: 2999,
|
|
1248
|
-
variantImage: null,
|
|
1249
|
-
variantAvailableForSale: true,
|
|
1250
|
-
subscriptionId: "sub_1",
|
|
1251
|
-
subscriptionLineId: "item_2",
|
|
1252
|
-
productId: "product_2",
|
|
1253
|
-
parentProductId: null,
|
|
1254
|
-
parentLineId: null,
|
|
1255
|
-
isVirtual: false,
|
|
1256
|
-
isUpsell: false,
|
|
1257
|
-
isOneTime: false,
|
|
1258
|
-
customAttributes: []
|
|
1259
|
-
}
|
|
1260
|
-
],
|
|
1261
|
-
discounts: []
|
|
1262
|
-
},
|
|
1263
|
-
{
|
|
1264
|
-
id: "sched_2",
|
|
1265
|
-
customerId: "customer_1",
|
|
1266
|
-
subscriptionId: "sub_1",
|
|
1267
|
-
date: "2026-05-22T12:00:00Z",
|
|
1268
|
-
skipped: false,
|
|
1269
|
-
currencyCode: "USD",
|
|
1270
|
-
subtotal: 2999,
|
|
1271
|
-
deliveryPrice: 500,
|
|
1272
|
-
cycleIndex: 4,
|
|
1273
|
-
deliveryDate: futureDateStr(7),
|
|
1274
|
-
status: "scheduled",
|
|
1275
|
-
items: [
|
|
1276
|
-
{
|
|
1277
|
-
id: "sched_item_3",
|
|
1278
|
-
title: "Rose Face Serum",
|
|
1279
|
-
subtitle: null,
|
|
1280
|
-
imageUrl: "https://images.unsplash.com/photo-1611930022073-b7a4ba5fcccd?w=200",
|
|
1281
|
-
variantId: "variant_1",
|
|
1282
|
-
quantity: 1,
|
|
1283
|
-
price: 2999,
|
|
1284
|
-
totalPrice: 2999,
|
|
1285
|
-
variantImage: null,
|
|
1286
|
-
variantAvailableForSale: true,
|
|
1287
|
-
subscriptionId: "sub_1",
|
|
1288
|
-
subscriptionLineId: "item_1",
|
|
1289
|
-
productId: "product_1",
|
|
1290
|
-
parentProductId: null,
|
|
1291
|
-
parentLineId: null,
|
|
1292
|
-
isVirtual: false,
|
|
1293
|
-
isUpsell: false,
|
|
1294
|
-
isOneTime: false,
|
|
1295
|
-
customAttributes: []
|
|
1296
|
-
},
|
|
1297
|
-
{
|
|
1298
|
-
id: "sched_item_4",
|
|
1299
|
-
title: "Hyaluronic Acid Serum",
|
|
1300
|
-
subtitle: null,
|
|
1301
|
-
imageUrl: "https://images.unsplash.com/photo-1621232201696-ba6c9db10a97?w=200",
|
|
1302
|
-
variantId: "variant_3",
|
|
1303
|
-
quantity: 1,
|
|
1304
|
-
price: 2999,
|
|
1305
|
-
totalPrice: 2999,
|
|
1306
|
-
variantImage: null,
|
|
1307
|
-
variantAvailableForSale: true,
|
|
1308
|
-
subscriptionId: "sub_1",
|
|
1309
|
-
subscriptionLineId: "item_3",
|
|
1310
|
-
productId: "product_3",
|
|
1311
|
-
parentProductId: null,
|
|
1312
|
-
parentLineId: null,
|
|
1313
|
-
isVirtual: false,
|
|
1314
|
-
isUpsell: false,
|
|
1315
|
-
isOneTime: false,
|
|
1316
|
-
customAttributes: []
|
|
1317
|
-
}
|
|
1318
|
-
],
|
|
1319
|
-
discounts: []
|
|
1320
|
-
}
|
|
1321
|
-
];
|
|
1322
|
-
let adjustments = [];
|
|
1323
|
-
return {
|
|
1324
|
-
async getUpcomingOrders(params) {
|
|
1325
|
-
await new Promise((r) => setTimeout(r, 200));
|
|
1326
|
-
const filtered = params.subscriptionId ? orders.filter((o2) => o2.subscriptionId === params.subscriptionId) : orders;
|
|
1327
|
-
return { _tag: "Success", data: filtered.slice(0, params.count) };
|
|
1328
|
-
},
|
|
1329
|
-
async getAdjustments() {
|
|
1330
|
-
await new Promise((r) => setTimeout(r, 200));
|
|
1331
|
-
return { _tag: "Success", data: [...adjustments] };
|
|
1332
|
-
},
|
|
1333
|
-
async skipOrder({ subscriptionId }) {
|
|
1334
|
-
await new Promise((r) => setTimeout(r, 300));
|
|
1335
|
-
const order = orders.find(
|
|
1336
|
-
(o2) => o2.subscriptionId === subscriptionId && o2.status === "scheduled"
|
|
1337
|
-
);
|
|
1338
|
-
if (!order) return { _tag: "Failure", error: "No scheduled order found" };
|
|
1339
|
-
orders = orders.map(
|
|
1340
|
-
(o2) => o2.id === order.id ? { ...o2, status: "skipped" } : o2
|
|
1341
|
-
);
|
|
1342
|
-
const adj = {
|
|
1343
|
-
id: `adj-${Date.now()}`,
|
|
1344
|
-
subscriptionId,
|
|
1345
|
-
type: "skip"
|
|
1346
|
-
};
|
|
1347
|
-
adjustments = [...adjustments, adj];
|
|
1348
|
-
return { _tag: "Success", data: void 0 };
|
|
1349
|
-
},
|
|
1350
|
-
async changeDateAdjustment({ subscriptionId, newDate }) {
|
|
1351
|
-
await new Promise((r) => setTimeout(r, 300));
|
|
1352
|
-
const order = orders.find(
|
|
1353
|
-
(o2) => o2.subscriptionId === subscriptionId && o2.status === "scheduled"
|
|
1354
|
-
);
|
|
1355
|
-
if (!order) return { _tag: "Failure", error: "No scheduled order found" };
|
|
1356
|
-
orders = orders.map(
|
|
1357
|
-
(o2) => o2.id === order.id ? { ...o2, deliveryDate: newDate } : o2
|
|
1358
|
-
);
|
|
1359
|
-
const adj = {
|
|
1360
|
-
id: `adj-${Date.now()}`,
|
|
1361
|
-
subscriptionId,
|
|
1362
|
-
type: "date_change",
|
|
1363
|
-
newDate
|
|
1364
|
-
};
|
|
1365
|
-
adjustments = [...adjustments, adj];
|
|
1366
|
-
return { _tag: "Success", data: void 0 };
|
|
1367
|
-
},
|
|
1368
|
-
async removeAdjustment({ adjustmentId }) {
|
|
1369
|
-
await new Promise((r) => setTimeout(r, 200));
|
|
1370
|
-
adjustments = adjustments.filter((a3) => a3.id !== adjustmentId);
|
|
1371
|
-
return { _tag: "Success", data: void 0 };
|
|
1372
|
-
}
|
|
1373
|
-
};
|
|
1374
|
-
}
|
|
1375
|
-
function createApiSchedulesAdapter(fetcher) {
|
|
1376
|
-
return {
|
|
1377
|
-
async getUpcomingOrders({ count, subscriptionId }) {
|
|
1378
|
-
try {
|
|
1379
|
-
const params = new URLSearchParams({ count: String(count) });
|
|
1380
|
-
if (subscriptionId) params.set("query", `id:"${subscriptionId}"`);
|
|
1381
|
-
const res = await fetcher(`/customer/v1/schedules/?${params.toString()}`);
|
|
1382
|
-
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1383
|
-
const data = await res.json();
|
|
1384
|
-
return { _tag: "Success", data: data.orders };
|
|
1385
|
-
} catch (e2) {
|
|
1386
|
-
return { _tag: "Failure", error: e2 };
|
|
1387
|
-
}
|
|
1388
|
-
},
|
|
1389
|
-
async getAdjustments() {
|
|
1390
|
-
try {
|
|
1391
|
-
const res = await fetcher(`/customer/v1/schedules/adjustments`);
|
|
1392
|
-
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1393
|
-
const data = await res.json();
|
|
1394
|
-
const adjustments = data.data.map((a3) => ({
|
|
1395
|
-
id: a3.id,
|
|
1396
|
-
subscriptionId: a3.subscriptionId ?? "",
|
|
1397
|
-
type: a3.type === "CHANGE_DATE" ? "date_change" : "skip",
|
|
1398
|
-
newDate: a3.newDate
|
|
1399
|
-
}));
|
|
1400
|
-
return { _tag: "Success", data: adjustments };
|
|
1401
|
-
} catch (e2) {
|
|
1402
|
-
return { _tag: "Failure", error: e2 };
|
|
1403
|
-
}
|
|
1404
|
-
},
|
|
1405
|
-
async skipOrder({ cycle, date }) {
|
|
1406
|
-
if (cycle == null && date == null) {
|
|
1407
|
-
return { _tag: "Failure", error: "Either cycle or date is required for skipOrder" };
|
|
1408
|
-
}
|
|
1409
|
-
try {
|
|
1410
|
-
const matcher = cycle != null ? { type: "CYCLE", input: { cycle } } : { type: "DATE", input: { date: new Date(date).toISOString() } };
|
|
1411
|
-
const res = await fetcher(`/customer/v1/schedules/adjustments`, {
|
|
1412
|
-
method: "POST",
|
|
1413
|
-
headers: { "Content-Type": "application/json" },
|
|
1414
|
-
body: JSON.stringify({
|
|
1415
|
-
matcher,
|
|
1416
|
-
action: { type: "SKIP_ORDER", input: { reason: "" } }
|
|
1417
|
-
})
|
|
1418
|
-
});
|
|
1419
|
-
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1420
|
-
return { _tag: "Success", data: void 0 };
|
|
1421
|
-
} catch (e2) {
|
|
1422
|
-
return { _tag: "Failure", error: e2 };
|
|
1423
|
-
}
|
|
1424
|
-
},
|
|
1425
|
-
async changeDateAdjustment({ newDate, currentDate }) {
|
|
1426
|
-
if (currentDate == null) {
|
|
1427
|
-
return {
|
|
1428
|
-
_tag: "Failure",
|
|
1429
|
-
error: "currentDate is required for changeDateAdjustment"
|
|
1430
|
-
};
|
|
1431
|
-
}
|
|
1432
|
-
try {
|
|
1433
|
-
const matcher = { type: "DATE", input: { date: new Date(currentDate).toISOString() } };
|
|
1434
|
-
const res = await fetcher(`/customer/v1/schedules/adjustments`, {
|
|
1435
|
-
method: "POST",
|
|
1436
|
-
headers: { "Content-Type": "application/json" },
|
|
1437
|
-
body: JSON.stringify({
|
|
1438
|
-
matcher,
|
|
1439
|
-
action: {
|
|
1440
|
-
type: "CHANGE_DATE",
|
|
1441
|
-
input: { newDate: new Date(newDate).toISOString() }
|
|
1442
|
-
}
|
|
1443
|
-
})
|
|
1444
|
-
});
|
|
1445
|
-
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1446
|
-
return { _tag: "Success", data: void 0 };
|
|
1447
|
-
} catch (e2) {
|
|
1448
|
-
return { _tag: "Failure", error: e2 };
|
|
1449
|
-
}
|
|
1450
|
-
},
|
|
1451
|
-
async removeAdjustment({ adjustmentId }) {
|
|
1452
|
-
try {
|
|
1453
|
-
const res = await fetcher(
|
|
1454
|
-
`/customer/v1/schedules/adjustments/${adjustmentId}`,
|
|
1455
|
-
{ method: "DELETE" }
|
|
1456
|
-
);
|
|
1457
|
-
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1458
|
-
return { _tag: "Success", data: void 0 };
|
|
1459
|
-
} catch (e2) {
|
|
1460
|
-
return { _tag: "Failure", error: e2 };
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
};
|
|
1464
|
-
}
|
|
1465
|
-
const SchedulesServiceContext = createContext("services/schedules");
|
|
1466
|
-
function createSchedulesService(adapter, opts) {
|
|
1467
|
-
const current = d(null);
|
|
1468
|
-
const currentLoading = d(false);
|
|
1469
|
-
const hasPendingBilling = (opts == null ? void 0 : opts.hasPendingBilling) ?? d(false);
|
|
1470
|
-
let reloadToken = 0;
|
|
1471
|
-
async function getUpcomingOrder() {
|
|
1472
|
-
const result = await adapter.getUpcomingOrders({ count: 1 });
|
|
1473
|
-
if (result._tag === "Failure") return result;
|
|
1474
|
-
return { _tag: "Success", data: result.data[0] ?? null };
|
|
1475
|
-
}
|
|
1476
|
-
async function getUpcomingOrders(count) {
|
|
1477
|
-
return adapter.getUpcomingOrders({ count });
|
|
1478
|
-
}
|
|
1479
|
-
async function reloadCurrent(subscriptionId) {
|
|
1480
|
-
var _a;
|
|
1481
|
-
const token = ++reloadToken;
|
|
1482
|
-
currentLoading.value = true;
|
|
1483
|
-
const count = Math.max(((_a = current.value) == null ? void 0 : _a.length) ?? 0, 3);
|
|
1484
|
-
const result = await adapter.getUpcomingOrders({
|
|
1485
|
-
count,
|
|
1486
|
-
subscriptionId
|
|
1487
|
-
});
|
|
1488
|
-
if (token !== reloadToken) return;
|
|
1489
|
-
currentLoading.value = false;
|
|
1490
|
-
if (result._tag === "Success") {
|
|
1491
|
-
current.value = result.data;
|
|
1492
|
-
}
|
|
1493
|
-
}
|
|
1494
|
-
return {
|
|
1495
|
-
current,
|
|
1496
|
-
currentLoading,
|
|
1497
|
-
hasPendingBilling,
|
|
1498
|
-
getUpcomingOrder,
|
|
1499
|
-
getUpcomingOrders,
|
|
1500
|
-
async getAdjustments() {
|
|
1501
|
-
return adapter.getAdjustments();
|
|
1502
|
-
},
|
|
1503
|
-
async skipOrder(params) {
|
|
1504
|
-
const result = await adapter.skipOrder(params);
|
|
1505
|
-
if (result._tag === "Success") {
|
|
1506
|
-
await reloadCurrent(params.subscriptionId);
|
|
1507
|
-
}
|
|
1508
|
-
return result;
|
|
1509
|
-
},
|
|
1510
|
-
async changeDateAdjustment(params) {
|
|
1511
|
-
const result = await adapter.changeDateAdjustment(params);
|
|
1512
|
-
if (result._tag === "Success") {
|
|
1513
|
-
await reloadCurrent(params.subscriptionId);
|
|
1514
|
-
}
|
|
1515
|
-
return result;
|
|
1516
|
-
},
|
|
1517
|
-
async removeAdjustment(params) {
|
|
1518
|
-
return adapter.removeAdjustment(params);
|
|
1519
|
-
},
|
|
1520
|
-
reloadCurrent
|
|
1521
|
-
};
|
|
1522
|
-
}
|
|
1523
|
-
const SettingsServiceContext = createContext("services/settings");
|
|
1524
|
-
function createSettingsService(initial = {}) {
|
|
1525
|
-
const current = d(initial);
|
|
1526
|
-
return {
|
|
1527
|
-
current,
|
|
1528
|
-
get(key) {
|
|
1529
|
-
return current.value[key];
|
|
1530
|
-
}
|
|
1531
|
-
};
|
|
1532
|
-
}
|
|
1533
|
-
function createShopService(options) {
|
|
1534
|
-
const contactEmail = d(options.getContactEmail());
|
|
1535
|
-
const service = { contactEmail };
|
|
1536
|
-
return service;
|
|
1537
|
-
}
|
|
1538
|
-
const ShopServiceContext = createContext("services/shop");
|
|
1539
1249
|
function createMockSubscriptionAdapter(options = {}) {
|
|
1540
1250
|
const richBase = (id, itemId, renewalId) => ({
|
|
1541
1251
|
id,
|
|
@@ -1543,17 +1253,25 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1543
1253
|
items: [
|
|
1544
1254
|
{
|
|
1545
1255
|
id: itemId,
|
|
1546
|
-
|
|
1547
|
-
|
|
1256
|
+
// Aligned with the mock product catalog (createMockProductAdapter):
|
|
1257
|
+
// sample-3 "Gentle deodorant", variant sample-3-1 "Green tea and jasmine",
|
|
1258
|
+
// recurring price 5.36 EUR (10% off → 4.82 with SAVE10).
|
|
1259
|
+
productId: "sample-3",
|
|
1260
|
+
variantId: "sample-3-1",
|
|
1548
1261
|
quantity: 2,
|
|
1549
|
-
price: { amount: "
|
|
1262
|
+
price: { amount: "5.36", currencyCode: "EUR" },
|
|
1550
1263
|
nextDeliveryDate: /* @__PURE__ */ new Date("2025-11-15"),
|
|
1551
1264
|
isUpsell: false,
|
|
1552
1265
|
isVirtual: false,
|
|
1553
1266
|
nextBillingDate: "2025-11-15T00:00:00Z",
|
|
1554
|
-
currentPrice: { amount: "
|
|
1555
|
-
lineDiscountedPrice: { amount: "
|
|
1556
|
-
variantAvailableForSale: true
|
|
1267
|
+
currentPrice: { amount: "5.36", currencyCode: "EUR" },
|
|
1268
|
+
lineDiscountedPrice: { amount: "4.82", currencyCode: "EUR" },
|
|
1269
|
+
variantAvailableForSale: true,
|
|
1270
|
+
title: "Gentle deodorant for underarms and bust",
|
|
1271
|
+
variantTitle: "Green tea and jasmine",
|
|
1272
|
+
variantImage: { url: "https://placehold.co/400x400?text=Product+3a" },
|
|
1273
|
+
billingPolicy: { intervalCount: 1, interval: "MONTH" },
|
|
1274
|
+
deliveryPolicy: { intervalCount: 1, interval: "MONTH" }
|
|
1557
1275
|
}
|
|
1558
1276
|
],
|
|
1559
1277
|
discounts: [
|
|
@@ -1600,22 +1318,27 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1600
1318
|
items: [
|
|
1601
1319
|
{
|
|
1602
1320
|
id: "item_1",
|
|
1603
|
-
|
|
1604
|
-
|
|
1321
|
+
// Aligned with the mock product catalog (createMockProductAdapter):
|
|
1322
|
+
// sample-1 "Hydrating Gel Cleanser" (default variant), recurring price
|
|
1323
|
+
// 9.99 EUR (10% off → 8.99 with SAVE10).
|
|
1324
|
+
productId: "sample-1",
|
|
1325
|
+
variantId: "sample-1-1",
|
|
1605
1326
|
quantity: 2,
|
|
1606
|
-
price: { amount: "
|
|
1327
|
+
price: { amount: "9.99", currencyCode: "EUR" },
|
|
1607
1328
|
nextDeliveryDate: /* @__PURE__ */ new Date("2025-11-15"),
|
|
1608
1329
|
isUpsell: false,
|
|
1609
1330
|
isVirtual: false,
|
|
1610
1331
|
nextBillingDate: "2025-11-15T00:00:00Z",
|
|
1611
|
-
currentPrice: { amount: "
|
|
1612
|
-
lineDiscountedPrice: { amount: "
|
|
1332
|
+
currentPrice: { amount: "9.99", currencyCode: "EUR" },
|
|
1333
|
+
lineDiscountedPrice: { amount: "8.99", currencyCode: "EUR" },
|
|
1613
1334
|
variantAvailableForSale: true,
|
|
1335
|
+
title: "Hydrating Gel Cleanser for Face and Eye Area",
|
|
1336
|
+
variantImage: { url: "https://placehold.co/400x400?text=Product+1" },
|
|
1614
1337
|
billingPolicy: { intervalCount: 1, interval: "MONTH" },
|
|
1615
1338
|
deliveryPolicy: { intervalCount: 1, interval: "MONTH" },
|
|
1616
1339
|
customAttributes: [
|
|
1617
|
-
{ key: "
|
|
1618
|
-
{ key: "
|
|
1340
|
+
{ key: "skin_type", value: "combination" },
|
|
1341
|
+
{ key: "fragrance", value: "fragrance_free" }
|
|
1619
1342
|
]
|
|
1620
1343
|
}
|
|
1621
1344
|
],
|
|
@@ -1657,7 +1380,7 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1657
1380
|
isEditable: true,
|
|
1658
1381
|
customAttributes: [
|
|
1659
1382
|
{ key: "subscription_tier", value: "premium" },
|
|
1660
|
-
{ key: "gift_message", value: "Enjoy your
|
|
1383
|
+
{ key: "gift_message", value: "Enjoy your skincare routine!" }
|
|
1661
1384
|
]
|
|
1662
1385
|
},
|
|
1663
1386
|
{
|
|
@@ -1666,11 +1389,15 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1666
1389
|
items: [
|
|
1667
1390
|
{
|
|
1668
1391
|
id: "item_2",
|
|
1669
|
-
|
|
1670
|
-
|
|
1392
|
+
// Aligned with the mock product catalog (createMockProductAdapter):
|
|
1393
|
+
// sample-2 "More COLLAGEN" (default variant), recurring price 10.99 EUR.
|
|
1394
|
+
productId: "sample-2",
|
|
1395
|
+
variantId: "sample-2-1",
|
|
1671
1396
|
quantity: 1,
|
|
1672
|
-
price: { amount: "
|
|
1397
|
+
price: { amount: "10.99", currencyCode: "EUR" },
|
|
1673
1398
|
nextDeliveryDate: /* @__PURE__ */ new Date("2025-11-20"),
|
|
1399
|
+
title: "More COLLAGEN",
|
|
1400
|
+
variantImage: { url: "https://placehold.co/400x400?text=Product+2" },
|
|
1674
1401
|
billingPolicy: { intervalCount: 2, interval: "WEEK" },
|
|
1675
1402
|
deliveryPolicy: { intervalCount: 2, interval: "WEEK" },
|
|
1676
1403
|
customAttributes: []
|
|
@@ -1730,8 +1457,15 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1730
1457
|
return {
|
|
1731
1458
|
async getById(id) {
|
|
1732
1459
|
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
1733
|
-
const subscription = mockSubscriptions.find((sub) => sub.id === id)
|
|
1734
|
-
return {
|
|
1460
|
+
const subscription = mockSubscriptions.find((sub) => sub.id === id);
|
|
1461
|
+
return {
|
|
1462
|
+
_tag: "Success",
|
|
1463
|
+
data: subscription ? {
|
|
1464
|
+
...subscription,
|
|
1465
|
+
items: subscription.items.map((item) => ({ ...item })),
|
|
1466
|
+
discounts: subscription.discounts.map((d3) => ({ ...d3 }))
|
|
1467
|
+
} : null
|
|
1468
|
+
};
|
|
1735
1469
|
},
|
|
1736
1470
|
async search(options2 = {}) {
|
|
1737
1471
|
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
@@ -1768,16 +1502,58 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1768
1502
|
}
|
|
1769
1503
|
};
|
|
1770
1504
|
},
|
|
1771
|
-
async addItem() {
|
|
1505
|
+
async addItem({ subscriptionId, item }) {
|
|
1506
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1772
1507
|
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
1508
|
+
const subscription = mockSubscriptions.find((sub) => sub.id === subscriptionId);
|
|
1509
|
+
if (!subscription) {
|
|
1510
|
+
return { _tag: "Failure", error: "Subscription not found" };
|
|
1511
|
+
}
|
|
1512
|
+
const currencyCode = ((_a = subscription.items[0]) == null ? void 0 : _a.price.currencyCode) ?? "USD";
|
|
1513
|
+
const product = await ((_b = options.productAdapter) == null ? void 0 : _b.getByVariantId(item.variantId)) ?? await ((_c = options.productAdapter) == null ? void 0 : _c.getById(item.variantId)) ?? null;
|
|
1514
|
+
const variant = (product == null ? void 0 : product.variants.items.find((v2) => v2.id === item.variantId)) ?? (product == null ? void 0 : product.variants.items[0]);
|
|
1515
|
+
const linePrice = ((_e = (_d = variant == null ? void 0 : variant.purchaseOptions) == null ? void 0 : _d[0]) == null ? void 0 : _e.price) ?? (variant == null ? void 0 : variant.price);
|
|
1516
|
+
subscription.items.push({
|
|
1517
|
+
id: `item_${Date.now()}_${subscription.items.length}`,
|
|
1518
|
+
productId: (product == null ? void 0 : product.id) ?? "",
|
|
1519
|
+
variantId: item.variantId,
|
|
1520
|
+
quantity: item.quantity,
|
|
1521
|
+
price: linePrice ? { ...linePrice } : { amount: "0.00", currencyCode },
|
|
1522
|
+
...linePrice ? { currentPrice: { ...linePrice } } : {},
|
|
1523
|
+
title: (product == null ? void 0 : product.title) ?? `Product ${item.variantId}`,
|
|
1524
|
+
...variant && product && !product.hasOnlyDefaultVariant ? { variantTitle: variant.title } : {},
|
|
1525
|
+
...(variant == null ? void 0 : variant.image) ? { variantImage: variant.image } : {},
|
|
1526
|
+
variantAvailableForSale: true,
|
|
1527
|
+
billingPolicy: ((_f = subscription.items[0]) == null ? void 0 : _f.billingPolicy) ?? subscription.billingPolicy ?? null,
|
|
1528
|
+
deliveryPolicy: ((_g = subscription.items[0]) == null ? void 0 : _g.deliveryPolicy) ?? subscription.deliveryPolicy ?? null
|
|
1529
|
+
});
|
|
1530
|
+
subscription.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1773
1531
|
return { _tag: "Success", data: void 0 };
|
|
1774
1532
|
},
|
|
1775
|
-
async removeItem() {
|
|
1533
|
+
async removeItem({ subscriptionId, itemId }) {
|
|
1776
1534
|
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
1535
|
+
const subscription = mockSubscriptions.find((sub) => sub.id === subscriptionId);
|
|
1536
|
+
if (!subscription) {
|
|
1537
|
+
return { _tag: "Failure", error: "Subscription not found" };
|
|
1538
|
+
}
|
|
1539
|
+
subscription.items = subscription.items.filter((i3) => i3.id !== itemId);
|
|
1540
|
+
subscription.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1777
1541
|
return { _tag: "Success", data: void 0 };
|
|
1778
1542
|
},
|
|
1779
|
-
async updateItem() {
|
|
1543
|
+
async updateItem({ subscriptionId, lineId, update }) {
|
|
1780
1544
|
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
1545
|
+
const subscription = mockSubscriptions.find((sub) => sub.id === subscriptionId);
|
|
1546
|
+
if (!subscription) {
|
|
1547
|
+
return { _tag: "Failure", error: "Subscription not found" };
|
|
1548
|
+
}
|
|
1549
|
+
const item = subscription.items.find((i3) => i3.id === lineId);
|
|
1550
|
+
if (!item) {
|
|
1551
|
+
return { _tag: "Failure", error: "Line item not found" };
|
|
1552
|
+
}
|
|
1553
|
+
if (update.variantId !== void 0) item.variantId = update.variantId;
|
|
1554
|
+
if (update.quantity !== void 0) item.quantity = update.quantity;
|
|
1555
|
+
if (update.billingPolicy !== void 0) item.billingPolicy = update.billingPolicy;
|
|
1556
|
+
subscription.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1781
1557
|
return { _tag: "Success", data: void 0 };
|
|
1782
1558
|
},
|
|
1783
1559
|
async skipLineItem() {
|
|
@@ -2403,6 +2179,367 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
2403
2179
|
};
|
|
2404
2180
|
return adapter;
|
|
2405
2181
|
}
|
|
2182
|
+
const DELIVERY_PRICE_CENTS = 500;
|
|
2183
|
+
const DELIVERY_OFFSET_DAYS = 2;
|
|
2184
|
+
function toCents(amount) {
|
|
2185
|
+
const n2 = Number.parseFloat(amount ?? "0");
|
|
2186
|
+
return Number.isFinite(n2) ? Math.round(n2 * 100) : 0;
|
|
2187
|
+
}
|
|
2188
|
+
function addInterval(date, interval, units) {
|
|
2189
|
+
const d3 = new Date(date);
|
|
2190
|
+
switch (interval) {
|
|
2191
|
+
case "DAY":
|
|
2192
|
+
d3.setDate(d3.getDate() + units);
|
|
2193
|
+
break;
|
|
2194
|
+
case "WEEK":
|
|
2195
|
+
d3.setDate(d3.getDate() + units * 7);
|
|
2196
|
+
break;
|
|
2197
|
+
case "YEAR":
|
|
2198
|
+
d3.setFullYear(d3.getFullYear() + units);
|
|
2199
|
+
break;
|
|
2200
|
+
default:
|
|
2201
|
+
d3.setMonth(d3.getMonth() + units);
|
|
2202
|
+
break;
|
|
2203
|
+
}
|
|
2204
|
+
return d3;
|
|
2205
|
+
}
|
|
2206
|
+
function mapItem(sub, item, cycle) {
|
|
2207
|
+
var _a, _b;
|
|
2208
|
+
const price = toCents(((_a = item.currentPrice) == null ? void 0 : _a.amount) ?? item.price.amount);
|
|
2209
|
+
return {
|
|
2210
|
+
id: `${sub.id}_cycle_${cycle}_${item.id}`,
|
|
2211
|
+
title: item.title ?? `Product ${item.variantId}`,
|
|
2212
|
+
subtitle: item.variantTitle ?? null,
|
|
2213
|
+
imageUrl: (_b = item.variantImage) == null ? void 0 : _b.url,
|
|
2214
|
+
variantId: item.variantId,
|
|
2215
|
+
quantity: item.quantity,
|
|
2216
|
+
price,
|
|
2217
|
+
totalPrice: price * item.quantity,
|
|
2218
|
+
variantImage: item.variantImage ?? null,
|
|
2219
|
+
variantAvailableForSale: item.variantAvailableForSale ?? true,
|
|
2220
|
+
subscriptionId: sub.id,
|
|
2221
|
+
subscriptionLineId: item.id,
|
|
2222
|
+
productId: item.productId,
|
|
2223
|
+
parentProductId: item.parentProductId ?? null,
|
|
2224
|
+
parentLineId: item.parentLineId ?? null,
|
|
2225
|
+
isVirtual: item.isVirtual ?? false,
|
|
2226
|
+
isUpsell: item.isUpsell ?? false,
|
|
2227
|
+
isOneTime: item.isOneTime ?? false,
|
|
2228
|
+
customAttributes: (item.customAttributes ?? []).map((a3) => ({
|
|
2229
|
+
name: a3.key,
|
|
2230
|
+
value: a3.value
|
|
2231
|
+
}))
|
|
2232
|
+
};
|
|
2233
|
+
}
|
|
2234
|
+
function projectUpcomingOrders(sub, count) {
|
|
2235
|
+
var _a, _b;
|
|
2236
|
+
if (sub.status !== "active") return [];
|
|
2237
|
+
const billing = sub.billingPolicy ?? ((_a = sub.items[0]) == null ? void 0 : _a.billingPolicy) ?? { interval: "MONTH", intervalCount: 1 };
|
|
2238
|
+
const baseStr = sub.nextBillingDate ?? (sub.nextDeliveryDate ? sub.nextDeliveryDate.toISOString() : null);
|
|
2239
|
+
const base = baseStr ? new Date(baseStr) : /* @__PURE__ */ new Date();
|
|
2240
|
+
const currencyCode = ((_b = sub.items[0]) == null ? void 0 : _b.price.currencyCode) ?? "USD";
|
|
2241
|
+
const orders = [];
|
|
2242
|
+
for (let cycle = 0; cycle < count; cycle++) {
|
|
2243
|
+
const billingDate = addInterval(
|
|
2244
|
+
base,
|
|
2245
|
+
billing.interval,
|
|
2246
|
+
cycle * billing.intervalCount
|
|
2247
|
+
);
|
|
2248
|
+
const deliveryDate = addInterval(billingDate, "DAY", DELIVERY_OFFSET_DAYS);
|
|
2249
|
+
const items = sub.items.map((item) => mapItem(sub, item, cycle));
|
|
2250
|
+
const subtotal = items.reduce((sum, it) => sum + it.totalPrice, 0);
|
|
2251
|
+
orders.push({
|
|
2252
|
+
id: `${sub.id}_cycle_${cycle}`,
|
|
2253
|
+
customerId: sub.customerId,
|
|
2254
|
+
subscriptionId: sub.id,
|
|
2255
|
+
date: billingDate.toISOString(),
|
|
2256
|
+
skipped: false,
|
|
2257
|
+
currencyCode,
|
|
2258
|
+
subtotal,
|
|
2259
|
+
deliveryPrice: DELIVERY_PRICE_CENTS,
|
|
2260
|
+
cycleIndex: cycle,
|
|
2261
|
+
deliveryDate: deliveryDate.toISOString(),
|
|
2262
|
+
status: "scheduled",
|
|
2263
|
+
items,
|
|
2264
|
+
discounts: sub.discounts.map((d3) => ({
|
|
2265
|
+
id: d3.id,
|
|
2266
|
+
title: d3.code,
|
|
2267
|
+
type: d3.type,
|
|
2268
|
+
value: d3.value
|
|
2269
|
+
}))
|
|
2270
|
+
});
|
|
2271
|
+
}
|
|
2272
|
+
return orders;
|
|
2273
|
+
}
|
|
2274
|
+
function applyAdjustments(orders, adjustments) {
|
|
2275
|
+
return orders.map((order) => {
|
|
2276
|
+
let next = order;
|
|
2277
|
+
for (const adj of adjustments) {
|
|
2278
|
+
if (adj.subscriptionId !== order.subscriptionId) continue;
|
|
2279
|
+
if (adj.cycle !== order.cycleIndex) continue;
|
|
2280
|
+
if (adj.type === "skip") {
|
|
2281
|
+
next = { ...next, skipped: true, status: "skipped" };
|
|
2282
|
+
} else if (adj.type === "date_change" && adj.newDate) {
|
|
2283
|
+
next = { ...next, date: adj.newDate, deliveryDate: adj.newDate };
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
return next;
|
|
2287
|
+
});
|
|
2288
|
+
}
|
|
2289
|
+
function createMockSchedulesAdapter(subscriptions = createMockSubscriptionAdapter()) {
|
|
2290
|
+
const RESOLVE_DEPTH = 12;
|
|
2291
|
+
let adjustments = [];
|
|
2292
|
+
async function subscriptionsToProject(subscriptionId) {
|
|
2293
|
+
if (subscriptionId) {
|
|
2294
|
+
const res = await subscriptions.getById(subscriptionId);
|
|
2295
|
+
return res._tag === "Success" && res.data ? [res.data] : [];
|
|
2296
|
+
}
|
|
2297
|
+
const all = [];
|
|
2298
|
+
let pagination;
|
|
2299
|
+
for (let guard = 0; guard < 50; guard++) {
|
|
2300
|
+
const res = await subscriptions.search(pagination ? { pagination } : {});
|
|
2301
|
+
if (res._tag !== "Success") break;
|
|
2302
|
+
all.push(...res.data.items);
|
|
2303
|
+
const { hasNextPage, endCursor } = res.data.pageInfo;
|
|
2304
|
+
if (!hasNextPage || !endCursor) break;
|
|
2305
|
+
pagination = { after: endCursor };
|
|
2306
|
+
}
|
|
2307
|
+
return all;
|
|
2308
|
+
}
|
|
2309
|
+
function resolveCycle(orders, opts) {
|
|
2310
|
+
if (opts.cycle != null) return opts.cycle;
|
|
2311
|
+
if (opts.date) {
|
|
2312
|
+
const target = new Date(opts.date).toISOString().split("T")[0];
|
|
2313
|
+
const match = orders.find(
|
|
2314
|
+
(o2) => o2.deliveryDate.split("T")[0] === target || o2.date.split("T")[0] === target
|
|
2315
|
+
);
|
|
2316
|
+
if (match) return match.cycleIndex;
|
|
2317
|
+
}
|
|
2318
|
+
const firstScheduled = orders.find((o2) => o2.status === "scheduled");
|
|
2319
|
+
return (firstScheduled == null ? void 0 : firstScheduled.cycleIndex) ?? null;
|
|
2320
|
+
}
|
|
2321
|
+
async function recordAdjustment(subscriptionId, opts, build) {
|
|
2322
|
+
const res = await subscriptions.getById(subscriptionId);
|
|
2323
|
+
const sub = res._tag === "Success" ? res.data : null;
|
|
2324
|
+
if (!sub) return { _tag: "Failure", error: "No scheduled order found" };
|
|
2325
|
+
const orders = applyAdjustments(
|
|
2326
|
+
projectUpcomingOrders(sub, RESOLVE_DEPTH),
|
|
2327
|
+
adjustments
|
|
2328
|
+
);
|
|
2329
|
+
const cycle = resolveCycle(orders, opts);
|
|
2330
|
+
if (cycle == null) {
|
|
2331
|
+
return { _tag: "Failure", error: "No scheduled order found" };
|
|
2332
|
+
}
|
|
2333
|
+
adjustments = [...adjustments, build(cycle)];
|
|
2334
|
+
return { _tag: "Success", data: void 0 };
|
|
2335
|
+
}
|
|
2336
|
+
return {
|
|
2337
|
+
async getUpcomingOrders({ count, subscriptionId }) {
|
|
2338
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
2339
|
+
const subs = await subscriptionsToProject(subscriptionId);
|
|
2340
|
+
const orders = subs.flatMap(
|
|
2341
|
+
(sub) => applyAdjustments(projectUpcomingOrders(sub, count), adjustments)
|
|
2342
|
+
).sort((a3, b3) => a3.date.localeCompare(b3.date));
|
|
2343
|
+
return { _tag: "Success", data: orders.slice(0, count) };
|
|
2344
|
+
},
|
|
2345
|
+
async getAdjustments() {
|
|
2346
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
2347
|
+
return { _tag: "Success", data: [...adjustments] };
|
|
2348
|
+
},
|
|
2349
|
+
async skipOrder({ subscriptionId, cycle, date }) {
|
|
2350
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
2351
|
+
return recordAdjustment(subscriptionId, { cycle, date }, (resolved) => ({
|
|
2352
|
+
id: `adj-${Date.now()}`,
|
|
2353
|
+
subscriptionId,
|
|
2354
|
+
type: "skip",
|
|
2355
|
+
cycle: resolved
|
|
2356
|
+
}));
|
|
2357
|
+
},
|
|
2358
|
+
async changeDateAdjustment({ subscriptionId, newDate, currentDate }) {
|
|
2359
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
2360
|
+
return recordAdjustment(
|
|
2361
|
+
subscriptionId,
|
|
2362
|
+
{ date: currentDate },
|
|
2363
|
+
(resolved) => ({
|
|
2364
|
+
id: `adj-${Date.now()}`,
|
|
2365
|
+
subscriptionId,
|
|
2366
|
+
type: "date_change",
|
|
2367
|
+
cycle: resolved,
|
|
2368
|
+
newDate
|
|
2369
|
+
})
|
|
2370
|
+
);
|
|
2371
|
+
},
|
|
2372
|
+
async removeAdjustment({ adjustmentId }) {
|
|
2373
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
2374
|
+
adjustments = adjustments.filter((a3) => a3.id !== adjustmentId);
|
|
2375
|
+
return { _tag: "Success", data: void 0 };
|
|
2376
|
+
}
|
|
2377
|
+
};
|
|
2378
|
+
}
|
|
2379
|
+
function createApiSchedulesAdapter(fetcher) {
|
|
2380
|
+
return {
|
|
2381
|
+
async getUpcomingOrders({ count, subscriptionId }) {
|
|
2382
|
+
try {
|
|
2383
|
+
const params = new URLSearchParams({ count: String(count) });
|
|
2384
|
+
if (subscriptionId) params.set("query", `id:"${subscriptionId}"`);
|
|
2385
|
+
const res = await fetcher(`/customer/v1/schedules/?${params.toString()}`);
|
|
2386
|
+
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
2387
|
+
const data = await res.json();
|
|
2388
|
+
return { _tag: "Success", data: data.orders };
|
|
2389
|
+
} catch (e2) {
|
|
2390
|
+
return { _tag: "Failure", error: e2 };
|
|
2391
|
+
}
|
|
2392
|
+
},
|
|
2393
|
+
async getAdjustments() {
|
|
2394
|
+
try {
|
|
2395
|
+
const res = await fetcher(`/customer/v1/schedules/adjustments`);
|
|
2396
|
+
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
2397
|
+
const data = await res.json();
|
|
2398
|
+
const adjustments = data.data.map((a3) => ({
|
|
2399
|
+
id: a3.id,
|
|
2400
|
+
subscriptionId: a3.subscriptionId ?? "",
|
|
2401
|
+
type: a3.type === "CHANGE_DATE" ? "date_change" : "skip",
|
|
2402
|
+
newDate: a3.newDate
|
|
2403
|
+
}));
|
|
2404
|
+
return { _tag: "Success", data: adjustments };
|
|
2405
|
+
} catch (e2) {
|
|
2406
|
+
return { _tag: "Failure", error: e2 };
|
|
2407
|
+
}
|
|
2408
|
+
},
|
|
2409
|
+
async skipOrder({ cycle, date }) {
|
|
2410
|
+
if (cycle == null && date == null) {
|
|
2411
|
+
return { _tag: "Failure", error: "Either cycle or date is required for skipOrder" };
|
|
2412
|
+
}
|
|
2413
|
+
try {
|
|
2414
|
+
const matcher = cycle != null ? { type: "CYCLE", input: { cycle } } : { type: "DATE", input: { date: new Date(date).toISOString() } };
|
|
2415
|
+
const res = await fetcher(`/customer/v1/schedules/adjustments`, {
|
|
2416
|
+
method: "POST",
|
|
2417
|
+
headers: { "Content-Type": "application/json" },
|
|
2418
|
+
body: JSON.stringify({
|
|
2419
|
+
matcher,
|
|
2420
|
+
action: { type: "SKIP_ORDER", input: { reason: "" } }
|
|
2421
|
+
})
|
|
2422
|
+
});
|
|
2423
|
+
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
2424
|
+
return { _tag: "Success", data: void 0 };
|
|
2425
|
+
} catch (e2) {
|
|
2426
|
+
return { _tag: "Failure", error: e2 };
|
|
2427
|
+
}
|
|
2428
|
+
},
|
|
2429
|
+
async changeDateAdjustment({ newDate, currentDate }) {
|
|
2430
|
+
if (currentDate == null) {
|
|
2431
|
+
return {
|
|
2432
|
+
_tag: "Failure",
|
|
2433
|
+
error: "currentDate is required for changeDateAdjustment"
|
|
2434
|
+
};
|
|
2435
|
+
}
|
|
2436
|
+
try {
|
|
2437
|
+
const matcher = { type: "DATE", input: { date: new Date(currentDate).toISOString() } };
|
|
2438
|
+
const res = await fetcher(`/customer/v1/schedules/adjustments`, {
|
|
2439
|
+
method: "POST",
|
|
2440
|
+
headers: { "Content-Type": "application/json" },
|
|
2441
|
+
body: JSON.stringify({
|
|
2442
|
+
matcher,
|
|
2443
|
+
action: {
|
|
2444
|
+
type: "CHANGE_DATE",
|
|
2445
|
+
input: { newDate: new Date(newDate).toISOString() }
|
|
2446
|
+
}
|
|
2447
|
+
})
|
|
2448
|
+
});
|
|
2449
|
+
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
2450
|
+
return { _tag: "Success", data: void 0 };
|
|
2451
|
+
} catch (e2) {
|
|
2452
|
+
return { _tag: "Failure", error: e2 };
|
|
2453
|
+
}
|
|
2454
|
+
},
|
|
2455
|
+
async removeAdjustment({ adjustmentId }) {
|
|
2456
|
+
try {
|
|
2457
|
+
const res = await fetcher(
|
|
2458
|
+
`/customer/v1/schedules/adjustments/${adjustmentId}`,
|
|
2459
|
+
{ method: "DELETE" }
|
|
2460
|
+
);
|
|
2461
|
+
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
2462
|
+
return { _tag: "Success", data: void 0 };
|
|
2463
|
+
} catch (e2) {
|
|
2464
|
+
return { _tag: "Failure", error: e2 };
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
};
|
|
2468
|
+
}
|
|
2469
|
+
const SchedulesServiceContext = createContext("services/schedules");
|
|
2470
|
+
function createSchedulesService(adapter, opts) {
|
|
2471
|
+
const current = d(null);
|
|
2472
|
+
const currentLoading = d(false);
|
|
2473
|
+
const hasPendingBilling = (opts == null ? void 0 : opts.hasPendingBilling) ?? d(false);
|
|
2474
|
+
let reloadToken = 0;
|
|
2475
|
+
async function getUpcomingOrder() {
|
|
2476
|
+
const result = await adapter.getUpcomingOrders({ count: 1 });
|
|
2477
|
+
if (result._tag === "Failure") return result;
|
|
2478
|
+
return { _tag: "Success", data: result.data[0] ?? null };
|
|
2479
|
+
}
|
|
2480
|
+
async function getUpcomingOrders(count) {
|
|
2481
|
+
return adapter.getUpcomingOrders({ count });
|
|
2482
|
+
}
|
|
2483
|
+
async function reloadCurrent(subscriptionId) {
|
|
2484
|
+
var _a;
|
|
2485
|
+
const token = ++reloadToken;
|
|
2486
|
+
currentLoading.value = true;
|
|
2487
|
+
const count = Math.max(((_a = current.value) == null ? void 0 : _a.length) ?? 0, 3);
|
|
2488
|
+
const result = await adapter.getUpcomingOrders({
|
|
2489
|
+
count,
|
|
2490
|
+
subscriptionId
|
|
2491
|
+
});
|
|
2492
|
+
if (token !== reloadToken) return;
|
|
2493
|
+
currentLoading.value = false;
|
|
2494
|
+
if (result._tag === "Success") {
|
|
2495
|
+
current.value = result.data;
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
return {
|
|
2499
|
+
current,
|
|
2500
|
+
currentLoading,
|
|
2501
|
+
hasPendingBilling,
|
|
2502
|
+
getUpcomingOrder,
|
|
2503
|
+
getUpcomingOrders,
|
|
2504
|
+
async getAdjustments() {
|
|
2505
|
+
return adapter.getAdjustments();
|
|
2506
|
+
},
|
|
2507
|
+
async skipOrder(params) {
|
|
2508
|
+
const result = await adapter.skipOrder(params);
|
|
2509
|
+
if (result._tag === "Success") {
|
|
2510
|
+
await reloadCurrent(params.subscriptionId);
|
|
2511
|
+
}
|
|
2512
|
+
return result;
|
|
2513
|
+
},
|
|
2514
|
+
async changeDateAdjustment(params) {
|
|
2515
|
+
const result = await adapter.changeDateAdjustment(params);
|
|
2516
|
+
if (result._tag === "Success") {
|
|
2517
|
+
await reloadCurrent(params.subscriptionId);
|
|
2518
|
+
}
|
|
2519
|
+
return result;
|
|
2520
|
+
},
|
|
2521
|
+
async removeAdjustment(params) {
|
|
2522
|
+
return adapter.removeAdjustment(params);
|
|
2523
|
+
},
|
|
2524
|
+
reloadCurrent
|
|
2525
|
+
};
|
|
2526
|
+
}
|
|
2527
|
+
const SettingsServiceContext = createContext("services/settings");
|
|
2528
|
+
function createSettingsService(initial = {}) {
|
|
2529
|
+
const current = d(initial);
|
|
2530
|
+
return {
|
|
2531
|
+
current,
|
|
2532
|
+
get(key) {
|
|
2533
|
+
return current.value[key];
|
|
2534
|
+
}
|
|
2535
|
+
};
|
|
2536
|
+
}
|
|
2537
|
+
function createShopService(options) {
|
|
2538
|
+
const contactEmail = d(options.getContactEmail());
|
|
2539
|
+
const service = { contactEmail };
|
|
2540
|
+
return service;
|
|
2541
|
+
}
|
|
2542
|
+
const ShopServiceContext = createContext("services/shop");
|
|
2406
2543
|
const SubscriptionServiceContext = createContext("services/subscription");
|
|
2407
2544
|
function getCurrentSubscriptionId() {
|
|
2408
2545
|
if (typeof window === "undefined") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/services/product/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,OAAO,EAAkB,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5F;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAE3D,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAEzE,MAAM,CAAC,IAAI,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KACrD,GAAG,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAElD,gBAAgB,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAEhE,cAAc,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAE/F,oBAAoB,CAAC,MAAM,EAAE;QAC3B,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,IAAI,CAAC,EAAE,cAAc,GAAG,gBAAgB,CAAC;QACzC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;QACvB,UAAU,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KACrD,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAEhC,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;CACrD;AAED,wBAAgB,wBAAwB,IAAI,cAAc,
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/services/product/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,OAAO,EAAkB,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5F;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAE3D,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAEzE,MAAM,CAAC,IAAI,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KACrD,GAAG,OAAO,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAElD,gBAAgB,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAEhE,cAAc,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAE/F,oBAAoB,CAAC,MAAM,EAAE;QAC3B,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,MAAM,CAAC;QACf,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,IAAI,CAAC,EAAE,cAAc,GAAG,gBAAgB,CAAC;QACzC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;QACvB,UAAU,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,GAAG;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KACrD,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAEhC,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;CACrD;AAED,wBAAgB,wBAAwB,IAAI,cAAc,CAmRzD;AAoED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,UAAU,EACnB,IAAI,GAAE;IAAE,YAAY,EAAE,MAAM,CAAA;CAA4B,GACvD,cAAc,CA4JhB"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { ApiFetcher, Result } from '../../utils';
|
|
2
|
+
import { SubscriptionAdapter } from '../subscription/adapter';
|
|
3
|
+
import { Subscription } from '../subscription/types';
|
|
2
4
|
import { ScheduleAdjustment, ScheduleOrder } from './types';
|
|
3
5
|
export interface SchedulesAdapter {
|
|
4
6
|
getUpcomingOrders(params: {
|
|
@@ -20,6 +22,26 @@ export interface SchedulesAdapter {
|
|
|
20
22
|
adjustmentId: string;
|
|
21
23
|
}): Promise<Result>;
|
|
22
24
|
}
|
|
23
|
-
|
|
25
|
+
/** Subscription state the schedules mock projects orders from. */
|
|
26
|
+
type SubscriptionSource = Pick<SubscriptionAdapter, "getById" | "search">;
|
|
27
|
+
/**
|
|
28
|
+
* Project the next `count` upcoming orders for a subscription by stepping its
|
|
29
|
+
* `nextBillingDate` forward one billing interval at a time. Only active
|
|
30
|
+
* subscriptions have upcoming orders; everything else projects to nothing.
|
|
31
|
+
*/
|
|
32
|
+
export declare function projectUpcomingOrders(sub: Subscription, count: number): ScheduleOrder[];
|
|
33
|
+
/**
|
|
34
|
+
* Mock schedules adapter that PROJECTS upcoming orders from a subscription
|
|
35
|
+
* source rather than holding its own static fixtures. Pass the same
|
|
36
|
+
* subscription adapter instance the SubscriptionService uses so item
|
|
37
|
+
* add/remove/update mutations flow through to the projected schedule. When no
|
|
38
|
+
* source is given it owns a fresh mock subscription adapter (used by unit tests).
|
|
39
|
+
*
|
|
40
|
+
* Skip / date-change actions are stored as an adjustments overlay applied on
|
|
41
|
+
* top of the projection — mirroring the real API (`getAdjustments` + a derived
|
|
42
|
+
* order list) rather than mutating a baked order array.
|
|
43
|
+
*/
|
|
44
|
+
export declare function createMockSchedulesAdapter(subscriptions?: SubscriptionSource): SchedulesAdapter;
|
|
24
45
|
export declare function createApiSchedulesAdapter(fetcher: ApiFetcher): SchedulesAdapter;
|
|
46
|
+
export {};
|
|
25
47
|
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/services/schedules/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/services/schedules/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAiC,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAqB,MAAM,SAAS,CAAC;AAEpF,MAAM,WAAW,gBAAgB;IAC/B,iBAAiB,CAAC,MAAM,EAAE;QACxB,KAAK,EAAE,MAAM,CAAC;QACd,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACrC,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC;IACxD,SAAS,CAAC,MAAM,EAAE;QAChB,cAAc,EAAE,MAAM,CAAC;QACvB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpB,oBAAoB,CAAC,MAAM,EAAE;QAC3B,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC;QAChB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpB,gBAAgB,CAAC,MAAM,EAAE;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACrE;AAED,kEAAkE;AAClE,KAAK,kBAAkB,GAAG,IAAI,CAAC,mBAAmB,EAAE,SAAS,GAAG,QAAQ,CAAC,CAAC;AA8D1E;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,YAAY,EACjB,KAAK,EAAE,MAAM,GACZ,aAAa,EAAE,CA4CjB;AAsBD;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,aAAa,GAAE,kBAAoD,GAClE,gBAAgB,CAgHlB;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,UAAU,GAAG,gBAAgB,CAoG/E"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ApiFetcher, PaginatedList, Result } from '../../utils';
|
|
2
2
|
import { Subscription, SellingPlan, SellingPlanInterval, SearchOptions, PostableSubscriptionItem, UpdateSubscriptionItem, UpdateBoxItem, LastOrder, RenewNowResult, UpsellProduct } from './types';
|
|
3
3
|
import { ApplyDiscountError, DiscountRejectionReason, RemoveDiscountError } from './discountErrors';
|
|
4
|
+
import { ProductAdapter } from '../product/adapter';
|
|
4
5
|
/**
|
|
5
6
|
* Adapter interface for subscription.
|
|
6
7
|
* Implementations should handle API calls, error handling, and data transformation.
|
|
@@ -108,6 +109,14 @@ export interface MockSubscriptionAdapterOptions {
|
|
|
108
109
|
kind: "error";
|
|
109
110
|
error: "NETWORK" | "UNKNOWN" | "SUBSCRIPTION_NOT_FOUND" | "DISCOUNT_NOT_FOUND";
|
|
110
111
|
};
|
|
112
|
+
/**
|
|
113
|
+
* Optional product source used by `addItem` to resolve a real title/price for
|
|
114
|
+
* an added line. Without it, added lines fall back to a placeholder title and
|
|
115
|
+
* a 0.00 price (the two mock stores are otherwise independent). Pass the same
|
|
116
|
+
* `createMockProductAdapter()` instance that backs the ProductService so the
|
|
117
|
+
* added line matches what the product picker showed.
|
|
118
|
+
*/
|
|
119
|
+
productAdapter?: Pick<ProductAdapter, "getByVariantId" | "getById">;
|
|
111
120
|
}
|
|
112
121
|
export declare function createMockSubscriptionAdapter(options?: MockSubscriptionAdapterOptions): SubscriptionAdapter;
|
|
113
122
|
export declare function createApiSubscriptionAdapter(fetcher: ApiFetcher): SubscriptionAdapter;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/services/subscription/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,mBAAmB,EACnB,aAAa,EACb,wBAAwB,EACxB,sBAAsB,EACtB,aAAa,EACb,SAAS,EACT,cAAc,EACd,aAAa,EACd,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EACV,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/services/subscription/adapter.ts"],"names":[],"mappings":"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"}
|