@juo/blocks 1.12.0-alpha.0 → 1.12.0-alpha.1
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/{ExtensionRoot-9XfhG8YM.js → ExtensionRoot-Z2DlF9X6.js} +14 -3
- package/dist/block-Bh3z0B3y.js +971 -0
- package/dist/block.d.ts +50 -0
- package/dist/block.d.ts.map +1 -1
- package/dist/block.devtools.test.d.ts +2 -0
- package/dist/block.devtools.test.d.ts.map +1 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.devtools.test.d.ts +2 -0
- package/dist/context.devtools.test.d.ts.map +1 -0
- package/dist/core.js +822 -186
- package/dist/editor/components.d.ts.map +1 -1
- package/dist/editor/main.d.ts +4 -0
- package/dist/editor/main.d.ts.map +1 -1
- package/dist/editor/main.test.d.ts +2 -0
- package/dist/editor/main.test.d.ts.map +1 -0
- package/dist/editor.js +19 -2
- package/dist/{juo-workflow-CkyZRq60.js → juo-workflow-D3c29mxb.js} +52 -871
- package/dist/main.d.ts +2 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/overlay-wrapper.d.ts +68 -0
- package/dist/overlay-wrapper.d.ts.map +1 -0
- package/dist/registry.devtools.test.d.ts +2 -0
- package/dist/registry.devtools.test.d.ts.map +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/orders/adapter.d.ts +2 -1
- package/dist/services/orders/adapter.d.ts.map +1 -1
- package/dist/services/orders/types.d.ts +8 -0
- package/dist/services/orders/types.d.ts.map +1 -1
- package/dist/services/product/adapter.d.ts +23 -1
- package/dist/services/product/adapter.d.ts.map +1 -1
- package/dist/services/product/adapter.test.d.ts +2 -0
- package/dist/services/product/adapter.test.d.ts.map +1 -0
- package/dist/services/product/productService.d.ts.map +1 -1
- package/dist/services/product/types.d.ts +66 -0
- package/dist/services/product/types.d.ts.map +1 -1
- package/dist/services/schedules/adapter.d.ts +4 -1
- package/dist/services/schedules/adapter.d.ts.map +1 -1
- package/dist/services/schedules/adapter.test.d.ts +2 -0
- package/dist/services/schedules/adapter.test.d.ts.map +1 -0
- package/dist/services/schedules/index.d.ts +3 -3
- package/dist/services/schedules/index.d.ts.map +1 -1
- package/dist/services/schedules/schedulesService.d.ts +4 -3
- package/dist/services/schedules/schedulesService.d.ts.map +1 -1
- package/dist/services/schedules/schedulesService.test.d.ts +2 -0
- package/dist/services/schedules/schedulesService.test.d.ts.map +1 -0
- package/dist/services/schedules/types.d.ts +66 -12
- package/dist/services/schedules/types.d.ts.map +1 -1
- package/dist/services/settings/index.d.ts +3 -0
- package/dist/services/settings/index.d.ts.map +1 -0
- package/dist/services/settings/settingsService.d.ts +7 -0
- package/dist/services/settings/settingsService.d.ts.map +1 -0
- package/dist/services/settings/settingsService.test.d.ts +2 -0
- package/dist/services/settings/settingsService.test.d.ts.map +1 -0
- package/dist/services/settings/types.d.ts +35 -0
- package/dist/services/settings/types.d.ts.map +1 -0
- package/dist/services/shop/index.d.ts +3 -0
- package/dist/services/shop/index.d.ts.map +1 -0
- package/dist/services/shop/shopService.d.ts +12 -0
- package/dist/services/shop/shopService.d.ts.map +1 -0
- package/dist/services/shop/shopService.test.d.ts +2 -0
- package/dist/services/shop/shopService.test.d.ts.map +1 -0
- package/dist/services/shop/types.d.ts +7 -0
- package/dist/services/shop/types.d.ts.map +1 -0
- package/dist/services/subscription/adapter.d.ts +29 -1
- package/dist/services/subscription/adapter.d.ts.map +1 -1
- package/dist/services/subscription/adapter.test.d.ts +2 -0
- package/dist/services/subscription/adapter.test.d.ts.map +1 -0
- package/dist/services/subscription/subscriptionService.d.ts.map +1 -1
- package/dist/services/subscription/types.d.ts +162 -1
- package/dist/services/subscription/types.d.ts.map +1 -1
- package/dist/services/subscription/types.test.d.ts +2 -0
- package/dist/services/subscription/types.test.d.ts.map +1 -0
- package/dist/theme-state.d.ts +2 -1
- package/dist/theme-state.d.ts.map +1 -1
- package/dist/theme-state.params.test.d.ts +2 -0
- package/dist/theme-state.params.test.d.ts.map +1 -0
- package/dist/theme-state.translations.test.d.ts +2 -0
- package/dist/theme-state.translations.test.d.ts.map +1 -0
- package/dist/vue/block.d.ts.map +1 -1
- package/dist/vue.js +23 -3
- package/dist/web-components/ExtensionRoot.d.ts +1 -0
- package/dist/web-components/ExtensionRoot.d.ts.map +1 -1
- package/dist/web-components-editor.js +3 -2
- package/dist/web-components-runtime.js +3 -2
- package/package.json +3 -2
package/dist/core.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
3
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
-
import { c as createContext, d, w, r as registerBlock, E, u } from "./
|
|
5
|
-
import { B, C,
|
|
4
|
+
import { c as createContext, d, w, a as defineBlock, b as createBlockInstance, r as registerBlock, E, u } from "./block-Bh3z0B3y.js";
|
|
5
|
+
import { B, C, e, S, _, f, g, h, i, j, k, l, m, n, o, p, q, s, t, v, x, y, z, A, D, F } from "./block-Bh3z0B3y.js";
|
|
6
|
+
import { D as D2, T, a, W, c, b, d as d2, e as e2, g as g2, h as h2, i as i2 } from "./juo-workflow-D3c29mxb.js";
|
|
6
7
|
import { reportBlockWarning, reportBlockError } from "./observability.js";
|
|
7
8
|
function createState() {
|
|
8
9
|
const discountCode = d(null);
|
|
@@ -72,6 +73,49 @@ function createState() {
|
|
|
72
73
|
};
|
|
73
74
|
}
|
|
74
75
|
const StateContext = createContext("state");
|
|
76
|
+
const OVERLAY_WRAPPER_SCHEMA = {
|
|
77
|
+
type: "object",
|
|
78
|
+
properties: {
|
|
79
|
+
props: {
|
|
80
|
+
type: "object",
|
|
81
|
+
properties: {
|
|
82
|
+
layout: {
|
|
83
|
+
type: "string",
|
|
84
|
+
enum: ["modal", "sidebar"]
|
|
85
|
+
},
|
|
86
|
+
canAbort: {
|
|
87
|
+
type: "boolean"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
required: ["layout"],
|
|
91
|
+
additionalProperties: false
|
|
92
|
+
},
|
|
93
|
+
slots: {
|
|
94
|
+
type: "object",
|
|
95
|
+
properties: {
|
|
96
|
+
content: {}
|
|
97
|
+
},
|
|
98
|
+
additionalProperties: false
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
required: ["props", "slots"],
|
|
102
|
+
additionalProperties: false
|
|
103
|
+
};
|
|
104
|
+
function defineOverlayWrapper(opts) {
|
|
105
|
+
const layout = opts.layout ?? "sidebar";
|
|
106
|
+
const canAbort = opts.canAbort ?? true;
|
|
107
|
+
return defineBlock(opts.name, {
|
|
108
|
+
group: "internal",
|
|
109
|
+
schema: OVERLAY_WRAPPER_SCHEMA,
|
|
110
|
+
initialValue: () => ({
|
|
111
|
+
props: { layout, canAbort },
|
|
112
|
+
slots: {
|
|
113
|
+
content: [createBlockInstance(opts.content)]
|
|
114
|
+
}
|
|
115
|
+
}),
|
|
116
|
+
renderer: () => null
|
|
117
|
+
});
|
|
118
|
+
}
|
|
75
119
|
function isLocalhostOrigin(origin) {
|
|
76
120
|
try {
|
|
77
121
|
const url = new URL(origin);
|
|
@@ -132,7 +176,7 @@ async function loadBlockRegistry(options = {}) {
|
|
|
132
176
|
if ("registerBlocks" in module && typeof module.registerBlocks === "function") {
|
|
133
177
|
module.registerBlocks();
|
|
134
178
|
} else {
|
|
135
|
-
Object.entries(module).forEach(([
|
|
179
|
+
Object.entries(module).forEach(([_2, item]) => {
|
|
136
180
|
if (typeof item === "object" && item != null) {
|
|
137
181
|
registerBlock(item);
|
|
138
182
|
}
|
|
@@ -187,8 +231,8 @@ function createApiCustomerAdapter(fetcher) {
|
|
|
187
231
|
_tag: "Success",
|
|
188
232
|
data: { id: data.id, name, email: data.email }
|
|
189
233
|
};
|
|
190
|
-
} catch (
|
|
191
|
-
return { _tag: "Failure", error:
|
|
234
|
+
} catch (e3) {
|
|
235
|
+
return { _tag: "Failure", error: e3 };
|
|
192
236
|
}
|
|
193
237
|
}
|
|
194
238
|
};
|
|
@@ -206,7 +250,7 @@ const PARAMS = {
|
|
|
206
250
|
function uuid() {
|
|
207
251
|
return ("10000000-1000-4000-8000" + -1e11).replace(
|
|
208
252
|
/[018]/g,
|
|
209
|
-
(
|
|
253
|
+
(c2) => (c2 ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c2 / 4).toString(16)
|
|
210
254
|
);
|
|
211
255
|
}
|
|
212
256
|
function createMockLoginAdapter() {
|
|
@@ -276,8 +320,8 @@ function createApiLoginAdapter(fetcher, opts) {
|
|
|
276
320
|
lang
|
|
277
321
|
);
|
|
278
322
|
return { _tag: "Success", data: void 0 };
|
|
279
|
-
} catch (
|
|
280
|
-
return { _tag: "Failure", error:
|
|
323
|
+
} catch (e3) {
|
|
324
|
+
return { _tag: "Failure", error: e3 };
|
|
281
325
|
}
|
|
282
326
|
},
|
|
283
327
|
async authenticate(params) {
|
|
@@ -311,8 +355,8 @@ function createApiLoginAdapter(fetcher, opts) {
|
|
|
311
355
|
throw new Error(`Unexpected response: ${res.statusText}`);
|
|
312
356
|
}
|
|
313
357
|
return { _tag: "Success", data: await res.json() };
|
|
314
|
-
} catch (
|
|
315
|
-
return { _tag: "Failure", error:
|
|
358
|
+
} catch (e3) {
|
|
359
|
+
return { _tag: "Failure", error: e3 };
|
|
316
360
|
}
|
|
317
361
|
},
|
|
318
362
|
getAuthorizeUrl({ connection, state, shop }) {
|
|
@@ -576,10 +620,56 @@ function createLoginService(init) {
|
|
|
576
620
|
}
|
|
577
621
|
const LoginServiceContext = createContext("services/login");
|
|
578
622
|
function createMockOrdersAdapter() {
|
|
623
|
+
const mockOrders = [
|
|
624
|
+
{
|
|
625
|
+
id: "10001",
|
|
626
|
+
createdAt: "2024-10-15T09:30:00Z",
|
|
627
|
+
placedAt: "2024-10-15T09:30:00Z",
|
|
628
|
+
currencyCode: "USD",
|
|
629
|
+
totalPrice: 89.97,
|
|
630
|
+
financialStatus: "PAID",
|
|
631
|
+
fulfillmentStatus: "FULFILLED",
|
|
632
|
+
lines: [
|
|
633
|
+
{
|
|
634
|
+
id: "line_1",
|
|
635
|
+
title: "Monthly Coffee Subscription",
|
|
636
|
+
quantity: 1,
|
|
637
|
+
variantImage: null,
|
|
638
|
+
customAttributes: [
|
|
639
|
+
{ key: "roast", value: "dark" },
|
|
640
|
+
{ key: "size", value: "1lb" }
|
|
641
|
+
]
|
|
642
|
+
}
|
|
643
|
+
],
|
|
644
|
+
customAttributes: [
|
|
645
|
+
{ key: "order_type", value: "subscription_renewal" },
|
|
646
|
+
{ key: "gift_wrap", value: "false" }
|
|
647
|
+
]
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
id: "10002",
|
|
651
|
+
createdAt: "2024-09-20T14:15:00Z",
|
|
652
|
+
placedAt: "2024-09-20T14:15:00Z",
|
|
653
|
+
currencyCode: "USD",
|
|
654
|
+
totalPrice: 45.99,
|
|
655
|
+
financialStatus: "PAID",
|
|
656
|
+
fulfillmentStatus: "PARTIALLY_FULFILLED",
|
|
657
|
+
lines: [
|
|
658
|
+
{
|
|
659
|
+
id: "line_2",
|
|
660
|
+
title: "Premium Tea Set",
|
|
661
|
+
quantity: 2,
|
|
662
|
+
variantImage: null,
|
|
663
|
+
customAttributes: []
|
|
664
|
+
}
|
|
665
|
+
],
|
|
666
|
+
customAttributes: []
|
|
667
|
+
}
|
|
668
|
+
];
|
|
579
669
|
return {
|
|
580
670
|
async getOrders() {
|
|
581
671
|
return {
|
|
582
|
-
items:
|
|
672
|
+
items: mockOrders,
|
|
583
673
|
pageInfo: {
|
|
584
674
|
hasNextPage: false,
|
|
585
675
|
hasPrevPage: false,
|
|
@@ -743,6 +833,18 @@ function createMockProductAdapter() {
|
|
|
743
833
|
);
|
|
744
834
|
return product == null ? null : processProduct(product);
|
|
745
835
|
},
|
|
836
|
+
async getProductsByIds() {
|
|
837
|
+
return [];
|
|
838
|
+
},
|
|
839
|
+
async getBoxVariants() {
|
|
840
|
+
return [];
|
|
841
|
+
},
|
|
842
|
+
async getAvailableProducts() {
|
|
843
|
+
return [];
|
|
844
|
+
},
|
|
845
|
+
async getBox() {
|
|
846
|
+
return null;
|
|
847
|
+
},
|
|
746
848
|
async search(opts) {
|
|
747
849
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
748
850
|
let filteredProducts = [...products];
|
|
@@ -880,6 +982,85 @@ function createApiProductAdapter(fetcher, opts = { currencyCode: "USD" }) {
|
|
|
880
982
|
}
|
|
881
983
|
};
|
|
882
984
|
}
|
|
985
|
+
},
|
|
986
|
+
async getProductsByIds({ ids }) {
|
|
987
|
+
const params = new URLSearchParams();
|
|
988
|
+
for (const id of ids) params.append("ids", id);
|
|
989
|
+
const res = await fetcher(`/customer/products/by-ids?${params.toString()}`);
|
|
990
|
+
if (!res.ok) return [];
|
|
991
|
+
const data = await res.json();
|
|
992
|
+
return (data ?? []).map((p2) => ({
|
|
993
|
+
id: p2.id,
|
|
994
|
+
title: p2.title ?? "",
|
|
995
|
+
featuredImage: p2.featuredImage ? { url: p2.featuredImage.url, altText: p2.featuredImage.altText } : null,
|
|
996
|
+
hasOnlyDefaultVariant: true,
|
|
997
|
+
collections: []
|
|
998
|
+
}));
|
|
999
|
+
},
|
|
1000
|
+
async getBoxVariants({ ids, subscriptionId }) {
|
|
1001
|
+
const params = new URLSearchParams();
|
|
1002
|
+
for (const id of ids) params.append("ids", id);
|
|
1003
|
+
params.set("subscriptionId", subscriptionId);
|
|
1004
|
+
const res = await fetcher(`/customer/products/variants?${params.toString()}`);
|
|
1005
|
+
if (!res.ok) return [];
|
|
1006
|
+
const data = await res.json();
|
|
1007
|
+
return (data ?? []).map((p2) => {
|
|
1008
|
+
var _a;
|
|
1009
|
+
return {
|
|
1010
|
+
id: p2.id,
|
|
1011
|
+
title: p2.title,
|
|
1012
|
+
description: p2.description ?? "",
|
|
1013
|
+
featuredImage: p2.featuredImage,
|
|
1014
|
+
hasOnlyDefaultVariant: p2.hasOnlyDefaultVariant ?? (((_a = p2.variants) == null ? void 0 : _a.length) ?? 0) <= 1,
|
|
1015
|
+
variants: (p2.variants ?? []).map((v2) => ({
|
|
1016
|
+
id: v2.id,
|
|
1017
|
+
availableForSale: v2.availableForSale,
|
|
1018
|
+
title: v2.title,
|
|
1019
|
+
currentPrice: v2.currentPrice,
|
|
1020
|
+
basePrice: v2.basePrice,
|
|
1021
|
+
image: v2.image,
|
|
1022
|
+
recurring: v2.recurring
|
|
1023
|
+
}))
|
|
1024
|
+
};
|
|
1025
|
+
});
|
|
1026
|
+
},
|
|
1027
|
+
async getAvailableProducts({ subscriptionId, lineId, q: q2, mode, action, pagination }) {
|
|
1028
|
+
const params = new URLSearchParams();
|
|
1029
|
+
params.set("action", action);
|
|
1030
|
+
if (q2) params.set("q", q2);
|
|
1031
|
+
if (mode) params.set("mode", mode);
|
|
1032
|
+
if (pagination && "after" in pagination) params.set("after", pagination.after);
|
|
1033
|
+
if (pagination && "before" in pagination) params.set("before", pagination.before);
|
|
1034
|
+
const res = await fetcher(
|
|
1035
|
+
`/customer/subscriptions/${subscriptionId}/lines/${lineId}/available-products?${params.toString()}`
|
|
1036
|
+
);
|
|
1037
|
+
if (!res.ok) return [];
|
|
1038
|
+
const data = await res.json();
|
|
1039
|
+
return (data ?? []).map((p2) => {
|
|
1040
|
+
var _a;
|
|
1041
|
+
return {
|
|
1042
|
+
id: p2.id,
|
|
1043
|
+
title: p2.title,
|
|
1044
|
+
description: p2.description ?? "",
|
|
1045
|
+
featuredImage: p2.featuredImage,
|
|
1046
|
+
hasOnlyDefaultVariant: p2.hasOnlyDefaultVariant ?? (((_a = p2.variants) == null ? void 0 : _a.length) ?? 0) <= 1,
|
|
1047
|
+
variants: (p2.variants ?? []).map((v2) => ({
|
|
1048
|
+
id: v2.id,
|
|
1049
|
+
availableForSale: v2.availableForSale,
|
|
1050
|
+
title: v2.title,
|
|
1051
|
+
currentPrice: v2.currentPrice,
|
|
1052
|
+
basePrice: v2.basePrice,
|
|
1053
|
+
image: v2.image,
|
|
1054
|
+
recurring: v2.recurring
|
|
1055
|
+
}))
|
|
1056
|
+
};
|
|
1057
|
+
});
|
|
1058
|
+
},
|
|
1059
|
+
async getBox({ id }) {
|
|
1060
|
+
const res = await fetcher(`/customer/boxes/${id}`);
|
|
1061
|
+
if (!res.ok) return null;
|
|
1062
|
+
const data = await res.json();
|
|
1063
|
+
return { id, ...data };
|
|
883
1064
|
}
|
|
884
1065
|
};
|
|
885
1066
|
}
|
|
@@ -894,7 +1075,11 @@ function createProductService(adapter) {
|
|
|
894
1075
|
},
|
|
895
1076
|
async search(opts) {
|
|
896
1077
|
return adapter.search(opts);
|
|
897
|
-
}
|
|
1078
|
+
},
|
|
1079
|
+
getProductsByIds: (ids) => adapter.getProductsByIds({ ids }),
|
|
1080
|
+
getBoxVariants: (ids, subscriptionId) => adapter.getBoxVariants({ ids, subscriptionId }),
|
|
1081
|
+
getAvailableProducts: (params) => adapter.getAvailableProducts(params),
|
|
1082
|
+
getBox: (id) => adapter.getBox({ id })
|
|
898
1083
|
};
|
|
899
1084
|
}
|
|
900
1085
|
function routeNameTableFromPages(pages) {
|
|
@@ -949,66 +1134,135 @@ function createMockRouterService() {
|
|
|
949
1134
|
}).routerService;
|
|
950
1135
|
}
|
|
951
1136
|
function futureDateStr(daysFromNow) {
|
|
952
|
-
const
|
|
953
|
-
|
|
954
|
-
return
|
|
1137
|
+
const d3 = /* @__PURE__ */ new Date();
|
|
1138
|
+
d3.setDate(d3.getDate() + daysFromNow);
|
|
1139
|
+
return d3.toISOString().split("T")[0] ?? "";
|
|
955
1140
|
}
|
|
956
1141
|
function createMockSchedulesAdapter() {
|
|
957
1142
|
let orders = [
|
|
958
1143
|
{
|
|
959
|
-
id: "
|
|
1144
|
+
id: "sched_1",
|
|
1145
|
+
customerId: "customer_1",
|
|
960
1146
|
subscriptionId: "sub_1",
|
|
1147
|
+
date: "2026-05-22T12:00:00Z",
|
|
1148
|
+
skipped: false,
|
|
1149
|
+
currencyCode: "USD",
|
|
1150
|
+
subtotal: 2999,
|
|
1151
|
+
deliveryPrice: 500,
|
|
1152
|
+
cycleIndex: 4,
|
|
961
1153
|
deliveryDate: futureDateStr(7),
|
|
1154
|
+
status: "scheduled",
|
|
962
1155
|
items: [
|
|
963
1156
|
{
|
|
964
|
-
id: "
|
|
965
|
-
productId: "p-beauty-1",
|
|
966
|
-
variantId: "v-beauty-1",
|
|
967
|
-
quantity: 1,
|
|
1157
|
+
id: "sched_item_1",
|
|
968
1158
|
title: "Rose Face Serum",
|
|
969
|
-
|
|
1159
|
+
subtitle: null,
|
|
1160
|
+
imageUrl: "https://images.unsplash.com/photo-1611930022073-b7a4ba5fcccd?w=200",
|
|
1161
|
+
variantId: "variant_1",
|
|
1162
|
+
quantity: 1,
|
|
1163
|
+
price: 2999,
|
|
1164
|
+
totalPrice: 2999,
|
|
1165
|
+
variantImage: null,
|
|
1166
|
+
variantAvailableForSale: true,
|
|
1167
|
+
subscriptionId: "sub_1",
|
|
1168
|
+
subscriptionLineId: "item_1",
|
|
1169
|
+
productId: "product_1",
|
|
1170
|
+
parentProductId: null,
|
|
1171
|
+
parentLineId: null,
|
|
1172
|
+
isVirtual: false,
|
|
1173
|
+
isUpsell: false,
|
|
1174
|
+
isOneTime: false,
|
|
1175
|
+
customAttributes: []
|
|
970
1176
|
},
|
|
971
1177
|
{
|
|
972
|
-
id: "
|
|
973
|
-
productId: "p-beauty-2",
|
|
974
|
-
variantId: "v-beauty-2",
|
|
975
|
-
quantity: 1,
|
|
1178
|
+
id: "sched_item_2",
|
|
976
1179
|
title: "Vitamin C Moisturizer",
|
|
977
|
-
|
|
1180
|
+
subtitle: null,
|
|
1181
|
+
imageUrl: "https://images.unsplash.com/photo-1556228578-8c89e6adf883?w=200",
|
|
1182
|
+
variantId: "variant_2",
|
|
1183
|
+
quantity: 1,
|
|
1184
|
+
price: 2999,
|
|
1185
|
+
totalPrice: 2999,
|
|
1186
|
+
variantImage: null,
|
|
1187
|
+
variantAvailableForSale: true,
|
|
1188
|
+
subscriptionId: "sub_1",
|
|
1189
|
+
subscriptionLineId: "item_2",
|
|
1190
|
+
productId: "product_2",
|
|
1191
|
+
parentProductId: null,
|
|
1192
|
+
parentLineId: null,
|
|
1193
|
+
isVirtual: false,
|
|
1194
|
+
isUpsell: false,
|
|
1195
|
+
isOneTime: false,
|
|
1196
|
+
customAttributes: []
|
|
978
1197
|
}
|
|
979
1198
|
],
|
|
980
|
-
|
|
1199
|
+
discounts: []
|
|
981
1200
|
},
|
|
982
1201
|
{
|
|
983
|
-
id: "
|
|
1202
|
+
id: "sched_2",
|
|
1203
|
+
customerId: "customer_1",
|
|
984
1204
|
subscriptionId: "sub_1",
|
|
985
|
-
|
|
1205
|
+
date: "2026-05-22T12:00:00Z",
|
|
1206
|
+
skipped: false,
|
|
1207
|
+
currencyCode: "USD",
|
|
1208
|
+
subtotal: 2999,
|
|
1209
|
+
deliveryPrice: 500,
|
|
1210
|
+
cycleIndex: 4,
|
|
1211
|
+
deliveryDate: futureDateStr(7),
|
|
1212
|
+
status: "scheduled",
|
|
986
1213
|
items: [
|
|
987
1214
|
{
|
|
988
|
-
id: "
|
|
989
|
-
productId: "p-beauty-1",
|
|
990
|
-
variantId: "v-beauty-1",
|
|
991
|
-
quantity: 1,
|
|
1215
|
+
id: "sched_item_3",
|
|
992
1216
|
title: "Rose Face Serum",
|
|
993
|
-
|
|
1217
|
+
subtitle: null,
|
|
1218
|
+
imageUrl: "https://images.unsplash.com/photo-1611930022073-b7a4ba5fcccd?w=200",
|
|
1219
|
+
variantId: "variant_1",
|
|
1220
|
+
quantity: 1,
|
|
1221
|
+
price: 2999,
|
|
1222
|
+
totalPrice: 2999,
|
|
1223
|
+
variantImage: null,
|
|
1224
|
+
variantAvailableForSale: true,
|
|
1225
|
+
subscriptionId: "sub_1",
|
|
1226
|
+
subscriptionLineId: "item_1",
|
|
1227
|
+
productId: "product_1",
|
|
1228
|
+
parentProductId: null,
|
|
1229
|
+
parentLineId: null,
|
|
1230
|
+
isVirtual: false,
|
|
1231
|
+
isUpsell: false,
|
|
1232
|
+
isOneTime: false,
|
|
1233
|
+
customAttributes: []
|
|
994
1234
|
},
|
|
995
1235
|
{
|
|
996
|
-
id: "
|
|
997
|
-
productId: "p-beauty-3",
|
|
998
|
-
variantId: "v-beauty-3",
|
|
999
|
-
quantity: 1,
|
|
1236
|
+
id: "sched_item_4",
|
|
1000
1237
|
title: "Hyaluronic Acid Serum",
|
|
1001
|
-
|
|
1238
|
+
subtitle: null,
|
|
1239
|
+
imageUrl: "https://images.unsplash.com/photo-1621232201696-ba6c9db10a97?w=200",
|
|
1240
|
+
variantId: "variant_3",
|
|
1241
|
+
quantity: 1,
|
|
1242
|
+
price: 2999,
|
|
1243
|
+
totalPrice: 2999,
|
|
1244
|
+
variantImage: null,
|
|
1245
|
+
variantAvailableForSale: true,
|
|
1246
|
+
subscriptionId: "sub_1",
|
|
1247
|
+
subscriptionLineId: "item_3",
|
|
1248
|
+
productId: "product_3",
|
|
1249
|
+
parentProductId: null,
|
|
1250
|
+
parentLineId: null,
|
|
1251
|
+
isVirtual: false,
|
|
1252
|
+
isUpsell: false,
|
|
1253
|
+
isOneTime: false,
|
|
1254
|
+
customAttributes: []
|
|
1002
1255
|
}
|
|
1003
1256
|
],
|
|
1004
|
-
|
|
1257
|
+
discounts: []
|
|
1005
1258
|
}
|
|
1006
1259
|
];
|
|
1007
1260
|
let adjustments = [];
|
|
1008
1261
|
return {
|
|
1009
|
-
async getUpcomingOrders(
|
|
1262
|
+
async getUpcomingOrders(params) {
|
|
1010
1263
|
await new Promise((r) => setTimeout(r, 200));
|
|
1011
|
-
|
|
1264
|
+
const filtered = params.subscriptionId ? orders.filter((o2) => o2.subscriptionId === params.subscriptionId) : orders;
|
|
1265
|
+
return { _tag: "Success", data: filtered.slice(0, params.count) };
|
|
1012
1266
|
},
|
|
1013
1267
|
async getAdjustments() {
|
|
1014
1268
|
await new Promise((r) => setTimeout(r, 200));
|
|
@@ -1058,14 +1312,16 @@ function createMockSchedulesAdapter() {
|
|
|
1058
1312
|
}
|
|
1059
1313
|
function createApiSchedulesAdapter(fetcher) {
|
|
1060
1314
|
return {
|
|
1061
|
-
async getUpcomingOrders(count) {
|
|
1315
|
+
async getUpcomingOrders({ count, subscriptionId }) {
|
|
1062
1316
|
try {
|
|
1063
|
-
const
|
|
1317
|
+
const params = new URLSearchParams({ count: String(count) });
|
|
1318
|
+
if (subscriptionId) params.set("query", `id:"${subscriptionId}"`);
|
|
1319
|
+
const res = await fetcher(`/customer/v1/schedules/?${params.toString()}`);
|
|
1064
1320
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1065
1321
|
const data = await res.json();
|
|
1066
1322
|
return { _tag: "Success", data: data.orders };
|
|
1067
|
-
} catch (
|
|
1068
|
-
return { _tag: "Failure", error:
|
|
1323
|
+
} catch (e3) {
|
|
1324
|
+
return { _tag: "Failure", error: e3 };
|
|
1069
1325
|
}
|
|
1070
1326
|
},
|
|
1071
1327
|
async getAdjustments() {
|
|
@@ -1080,8 +1336,8 @@ function createApiSchedulesAdapter(fetcher) {
|
|
|
1080
1336
|
newDate: a2.newDate
|
|
1081
1337
|
}));
|
|
1082
1338
|
return { _tag: "Success", data: adjustments };
|
|
1083
|
-
} catch (
|
|
1084
|
-
return { _tag: "Failure", error:
|
|
1339
|
+
} catch (e3) {
|
|
1340
|
+
return { _tag: "Failure", error: e3 };
|
|
1085
1341
|
}
|
|
1086
1342
|
},
|
|
1087
1343
|
async skipOrder({ cycle, date }) {
|
|
@@ -1100,8 +1356,8 @@ function createApiSchedulesAdapter(fetcher) {
|
|
|
1100
1356
|
});
|
|
1101
1357
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1102
1358
|
return { _tag: "Success", data: void 0 };
|
|
1103
|
-
} catch (
|
|
1104
|
-
return { _tag: "Failure", error:
|
|
1359
|
+
} catch (e3) {
|
|
1360
|
+
return { _tag: "Failure", error: e3 };
|
|
1105
1361
|
}
|
|
1106
1362
|
},
|
|
1107
1363
|
async changeDateAdjustment({ newDate, currentDate }) {
|
|
@@ -1126,8 +1382,8 @@ function createApiSchedulesAdapter(fetcher) {
|
|
|
1126
1382
|
});
|
|
1127
1383
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1128
1384
|
return { _tag: "Success", data: void 0 };
|
|
1129
|
-
} catch (
|
|
1130
|
-
return { _tag: "Failure", error:
|
|
1385
|
+
} catch (e3) {
|
|
1386
|
+
return { _tag: "Failure", error: e3 };
|
|
1131
1387
|
}
|
|
1132
1388
|
},
|
|
1133
1389
|
async removeAdjustment({ adjustmentId }) {
|
|
@@ -1138,61 +1394,143 @@ function createApiSchedulesAdapter(fetcher) {
|
|
|
1138
1394
|
);
|
|
1139
1395
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1140
1396
|
return { _tag: "Success", data: void 0 };
|
|
1141
|
-
} catch (
|
|
1142
|
-
return { _tag: "Failure", error:
|
|
1397
|
+
} catch (e3) {
|
|
1398
|
+
return { _tag: "Failure", error: e3 };
|
|
1143
1399
|
}
|
|
1144
1400
|
}
|
|
1145
1401
|
};
|
|
1146
1402
|
}
|
|
1147
1403
|
const SchedulesServiceContext = createContext("services/schedules");
|
|
1148
1404
|
function createSchedulesService(adapter, opts) {
|
|
1149
|
-
const
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1405
|
+
const current = d(null);
|
|
1406
|
+
const currentLoading = d(false);
|
|
1407
|
+
const hasPendingBilling = (opts == null ? void 0 : opts.hasPendingBilling) ?? d(false);
|
|
1408
|
+
let reloadToken = 0;
|
|
1409
|
+
async function getUpcomingOrder() {
|
|
1410
|
+
const result = await adapter.getUpcomingOrders({ count: 1 });
|
|
1411
|
+
if (result._tag === "Failure") return result;
|
|
1412
|
+
return { _tag: "Success", data: result.data[0] ?? null };
|
|
1413
|
+
}
|
|
1414
|
+
async function getUpcomingOrders(count) {
|
|
1415
|
+
return adapter.getUpcomingOrders({ count });
|
|
1416
|
+
}
|
|
1417
|
+
async function reloadCurrent(subscriptionId) {
|
|
1418
|
+
var _a;
|
|
1419
|
+
const token = ++reloadToken;
|
|
1420
|
+
currentLoading.value = true;
|
|
1421
|
+
const count = Math.max(((_a = current.value) == null ? void 0 : _a.length) ?? 0, 3);
|
|
1422
|
+
const result = await adapter.getUpcomingOrders({
|
|
1423
|
+
count,
|
|
1424
|
+
subscriptionId
|
|
1425
|
+
});
|
|
1426
|
+
if (token !== reloadToken) return;
|
|
1427
|
+
currentLoading.value = false;
|
|
1153
1428
|
if (result._tag === "Success") {
|
|
1154
|
-
|
|
1429
|
+
current.value = result.data;
|
|
1155
1430
|
}
|
|
1156
1431
|
}
|
|
1157
1432
|
return {
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
upcoming.value = result.data;
|
|
1164
|
-
return { _tag: "Success", data: result.data[0] ?? null };
|
|
1165
|
-
},
|
|
1166
|
-
async getUpcomingOrders(count) {
|
|
1167
|
-
const result = await adapter.getUpcomingOrders(count);
|
|
1168
|
-
if (result._tag === "Success") {
|
|
1169
|
-
upcoming.value = result.data;
|
|
1170
|
-
}
|
|
1171
|
-
return result;
|
|
1172
|
-
},
|
|
1433
|
+
current,
|
|
1434
|
+
currentLoading,
|
|
1435
|
+
hasPendingBilling,
|
|
1436
|
+
getUpcomingOrder,
|
|
1437
|
+
getUpcomingOrders,
|
|
1173
1438
|
async getAdjustments() {
|
|
1174
1439
|
return adapter.getAdjustments();
|
|
1175
1440
|
},
|
|
1176
1441
|
async skipOrder(params) {
|
|
1177
1442
|
const result = await adapter.skipOrder(params);
|
|
1178
1443
|
if (result._tag === "Success") {
|
|
1179
|
-
await
|
|
1444
|
+
await reloadCurrent(params.subscriptionId);
|
|
1180
1445
|
}
|
|
1181
1446
|
return result;
|
|
1182
1447
|
},
|
|
1183
1448
|
async changeDateAdjustment(params) {
|
|
1184
1449
|
const result = await adapter.changeDateAdjustment(params);
|
|
1185
1450
|
if (result._tag === "Success") {
|
|
1186
|
-
await
|
|
1451
|
+
await reloadCurrent(params.subscriptionId);
|
|
1187
1452
|
}
|
|
1188
1453
|
return result;
|
|
1189
1454
|
},
|
|
1190
1455
|
async removeAdjustment(params) {
|
|
1191
1456
|
return adapter.removeAdjustment(params);
|
|
1457
|
+
},
|
|
1458
|
+
reloadCurrent
|
|
1459
|
+
};
|
|
1460
|
+
}
|
|
1461
|
+
const SettingsServiceContext = createContext("services/settings");
|
|
1462
|
+
function createSettingsService(initial = {}) {
|
|
1463
|
+
const current = d(initial);
|
|
1464
|
+
return {
|
|
1465
|
+
current,
|
|
1466
|
+
get(key) {
|
|
1467
|
+
return current.value[key];
|
|
1192
1468
|
}
|
|
1193
1469
|
};
|
|
1194
1470
|
}
|
|
1471
|
+
function createShopService(options) {
|
|
1472
|
+
const contactEmail = d(options.getContactEmail());
|
|
1473
|
+
const service = { contactEmail };
|
|
1474
|
+
return service;
|
|
1475
|
+
}
|
|
1476
|
+
const ShopServiceContext = createContext("services/shop");
|
|
1195
1477
|
function createMockSubscriptionAdapter(options = {}) {
|
|
1478
|
+
const richBase = (id, itemId, renewalId) => ({
|
|
1479
|
+
id,
|
|
1480
|
+
customerId: "customer_1",
|
|
1481
|
+
items: [
|
|
1482
|
+
{
|
|
1483
|
+
id: itemId,
|
|
1484
|
+
productId: "product_1",
|
|
1485
|
+
variantId: "variant_1",
|
|
1486
|
+
quantity: 2,
|
|
1487
|
+
price: { amount: "29.99", currencyCode: "USD" },
|
|
1488
|
+
nextDeliveryDate: /* @__PURE__ */ new Date("2025-11-15"),
|
|
1489
|
+
isUpsell: false,
|
|
1490
|
+
isVirtual: false,
|
|
1491
|
+
nextBillingDate: "2025-11-15T00:00:00Z",
|
|
1492
|
+
currentPrice: { amount: "29.99", currencyCode: "USD" },
|
|
1493
|
+
lineDiscountedPrice: { amount: "26.99", currencyCode: "USD" },
|
|
1494
|
+
variantAvailableForSale: true
|
|
1495
|
+
}
|
|
1496
|
+
],
|
|
1497
|
+
discounts: [
|
|
1498
|
+
{
|
|
1499
|
+
id: "discount_1",
|
|
1500
|
+
type: "percentage",
|
|
1501
|
+
value: 10,
|
|
1502
|
+
code: "SAVE10",
|
|
1503
|
+
description: "10% off subscription"
|
|
1504
|
+
}
|
|
1505
|
+
],
|
|
1506
|
+
status: "active",
|
|
1507
|
+
nextDeliveryDate: /* @__PURE__ */ new Date("2025-11-15"),
|
|
1508
|
+
frequency: "1 MONTH",
|
|
1509
|
+
createdAt: "2024-10-01T00:00:00Z",
|
|
1510
|
+
updatedAt: "2024-10-14T00:00:00Z",
|
|
1511
|
+
billingPolicy: { intervalCount: 1, interval: "MONTH", minCycles: 6 },
|
|
1512
|
+
deliveryPolicy: {
|
|
1513
|
+
intervalCount: 1,
|
|
1514
|
+
interval: "MONTH",
|
|
1515
|
+
anchors: [{ day: 15, type: "MONTHDAY" }]
|
|
1516
|
+
},
|
|
1517
|
+
nextBillingDate: "2025-11-15T00:00:00Z",
|
|
1518
|
+
nextBillingAttempt: { date: "2025-11-15T00:00:00Z", attempt: 1, ready: true },
|
|
1519
|
+
lastBillingAttempt: { date: "2025-10-15T00:00:00Z", ready: true },
|
|
1520
|
+
nextFulfillment: "2025-11-17T00:00:00Z",
|
|
1521
|
+
estimatedOrderDate: "2025-11-13T00:00:00Z",
|
|
1522
|
+
customerPaymentMethod: {
|
|
1523
|
+
id: "pm_1",
|
|
1524
|
+
instrument: { type: "credit_card", brand: "visa", maskedNumber: "************4242" },
|
|
1525
|
+
active: true,
|
|
1526
|
+
isRecurring: true
|
|
1527
|
+
},
|
|
1528
|
+
requiredBillingCyclesLeft: 3,
|
|
1529
|
+
renewal: { id: renewalId, isInActiveProcessState: false },
|
|
1530
|
+
lastPaymentStatus: "succeeded",
|
|
1531
|
+
pausePeriod: null,
|
|
1532
|
+
isEditable: true
|
|
1533
|
+
});
|
|
1196
1534
|
const mockSubscriptions = [
|
|
1197
1535
|
{
|
|
1198
1536
|
id: "sub_1",
|
|
@@ -1205,8 +1543,18 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1205
1543
|
quantity: 2,
|
|
1206
1544
|
price: { amount: "29.99", currencyCode: "USD" },
|
|
1207
1545
|
nextDeliveryDate: /* @__PURE__ */ new Date("2025-11-15"),
|
|
1546
|
+
isUpsell: false,
|
|
1547
|
+
isVirtual: false,
|
|
1548
|
+
nextBillingDate: "2025-11-15T00:00:00Z",
|
|
1549
|
+
currentPrice: { amount: "29.99", currencyCode: "USD" },
|
|
1550
|
+
lineDiscountedPrice: { amount: "26.99", currencyCode: "USD" },
|
|
1551
|
+
variantAvailableForSale: true,
|
|
1208
1552
|
billingPolicy: { intervalCount: 1, interval: "MONTH" },
|
|
1209
|
-
deliveryPolicy: { intervalCount: 1, interval: "MONTH" }
|
|
1553
|
+
deliveryPolicy: { intervalCount: 1, interval: "MONTH" },
|
|
1554
|
+
customAttributes: [
|
|
1555
|
+
{ key: "roast_level", value: "medium" },
|
|
1556
|
+
{ key: "grind_type", value: "whole_bean" }
|
|
1557
|
+
]
|
|
1210
1558
|
}
|
|
1211
1559
|
],
|
|
1212
1560
|
discounts: [
|
|
@@ -1222,7 +1570,33 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1222
1570
|
nextDeliveryDate: /* @__PURE__ */ new Date("2025-11-15"),
|
|
1223
1571
|
frequency: "1 MONTH",
|
|
1224
1572
|
createdAt: "2024-10-01T00:00:00Z",
|
|
1225
|
-
updatedAt: "2024-10-14T00:00:00Z"
|
|
1573
|
+
updatedAt: "2024-10-14T00:00:00Z",
|
|
1574
|
+
billingPolicy: { intervalCount: 1, interval: "MONTH", minCycles: 6 },
|
|
1575
|
+
deliveryPolicy: {
|
|
1576
|
+
intervalCount: 1,
|
|
1577
|
+
interval: "MONTH",
|
|
1578
|
+
anchors: [{ day: 15, type: "MONTHDAY" }]
|
|
1579
|
+
},
|
|
1580
|
+
nextBillingDate: "2025-11-15T00:00:00Z",
|
|
1581
|
+
nextBillingAttempt: { date: "2025-11-15T00:00:00Z", attempt: 1, ready: true },
|
|
1582
|
+
lastBillingAttempt: { date: "2025-10-15T00:00:00Z", ready: true },
|
|
1583
|
+
nextFulfillment: "2025-11-17T00:00:00Z",
|
|
1584
|
+
estimatedOrderDate: "2025-11-13T00:00:00Z",
|
|
1585
|
+
customerPaymentMethod: {
|
|
1586
|
+
id: "pm_1",
|
|
1587
|
+
instrument: { type: "credit_card", brand: "visa", maskedNumber: "************4242" },
|
|
1588
|
+
active: true,
|
|
1589
|
+
isRecurring: true
|
|
1590
|
+
},
|
|
1591
|
+
requiredBillingCyclesLeft: 3,
|
|
1592
|
+
renewal: { id: "ren_1", isInActiveProcessState: false },
|
|
1593
|
+
lastPaymentStatus: "succeeded",
|
|
1594
|
+
pausePeriod: null,
|
|
1595
|
+
isEditable: true,
|
|
1596
|
+
customAttributes: [
|
|
1597
|
+
{ key: "subscription_tier", value: "premium" },
|
|
1598
|
+
{ key: "gift_message", value: "Enjoy your coffee!" }
|
|
1599
|
+
]
|
|
1226
1600
|
},
|
|
1227
1601
|
{
|
|
1228
1602
|
id: "sub_2",
|
|
@@ -1236,7 +1610,8 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1236
1610
|
price: { amount: "49.99", currencyCode: "USD" },
|
|
1237
1611
|
nextDeliveryDate: /* @__PURE__ */ new Date("2025-11-20"),
|
|
1238
1612
|
billingPolicy: { intervalCount: 2, interval: "WEEK" },
|
|
1239
|
-
deliveryPolicy: { intervalCount: 2, interval: "WEEK" }
|
|
1613
|
+
deliveryPolicy: { intervalCount: 2, interval: "WEEK" },
|
|
1614
|
+
customAttributes: []
|
|
1240
1615
|
}
|
|
1241
1616
|
],
|
|
1242
1617
|
discounts: [],
|
|
@@ -1244,7 +1619,32 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1244
1619
|
nextDeliveryDate: /* @__PURE__ */ new Date("2025-11-20"),
|
|
1245
1620
|
frequency: "2 WEEK",
|
|
1246
1621
|
createdAt: "2024-09-15T00:00:00Z",
|
|
1247
|
-
updatedAt: "2024-10-10T00:00:00Z"
|
|
1622
|
+
updatedAt: "2024-10-10T00:00:00Z",
|
|
1623
|
+
customAttributes: []
|
|
1624
|
+
},
|
|
1625
|
+
// Per-status fixtures: groundwork for the deferred editor preview picker
|
|
1626
|
+
// (docs/superpowers/specs/2026-06-17-renewalsummary-parity-and-mock-groundwork-design.md §9).
|
|
1627
|
+
// Not consumed yet — the editor still seeds the active sub_1 via getDefaultSubscriptionId().
|
|
1628
|
+
{
|
|
1629
|
+
...richBase("sub_paused", "item_paused", "ren_paused"),
|
|
1630
|
+
status: "paused",
|
|
1631
|
+
pausePeriod: { start: "2025-11-01T00:00:00Z", end: "2026-01-01T00:00:00Z" }
|
|
1632
|
+
},
|
|
1633
|
+
{
|
|
1634
|
+
...richBase("sub_canceled", "item_canceled", "ren_canceled"),
|
|
1635
|
+
status: "canceled",
|
|
1636
|
+
pausePeriod: null
|
|
1637
|
+
},
|
|
1638
|
+
{
|
|
1639
|
+
...richBase("sub_failed", "item_failed", "ren_failed"),
|
|
1640
|
+
status: "failed",
|
|
1641
|
+
lastPaymentStatus: "failed",
|
|
1642
|
+
pausePeriod: null
|
|
1643
|
+
},
|
|
1644
|
+
{
|
|
1645
|
+
...richBase("sub_expired", "item_expired", "ren_expired"),
|
|
1646
|
+
status: "expired",
|
|
1647
|
+
pausePeriod: null
|
|
1248
1648
|
}
|
|
1249
1649
|
];
|
|
1250
1650
|
const mockUpsellProducts = [
|
|
@@ -1314,6 +1714,17 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1314
1714
|
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
1315
1715
|
return { _tag: "Success", data: void 0 };
|
|
1316
1716
|
},
|
|
1717
|
+
async updateItem() {
|
|
1718
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
1719
|
+
return { _tag: "Success", data: void 0 };
|
|
1720
|
+
},
|
|
1721
|
+
async skipLineItem() {
|
|
1722
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
1723
|
+
return { _tag: "Success", data: void 0 };
|
|
1724
|
+
},
|
|
1725
|
+
async updateBoxItems() {
|
|
1726
|
+
return { _tag: "Success", data: void 0 };
|
|
1727
|
+
},
|
|
1317
1728
|
async addDiscount() {
|
|
1318
1729
|
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
1319
1730
|
const behavior = options.addDiscountBehavior ?? { kind: "success" };
|
|
@@ -1422,6 +1833,49 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1422
1833
|
]
|
|
1423
1834
|
};
|
|
1424
1835
|
},
|
|
1836
|
+
async getLastOrder(params) {
|
|
1837
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
1838
|
+
const subscription = mockSubscriptions.find((sub) => sub.id === params.subscriptionId);
|
|
1839
|
+
if (!subscription) return { _tag: "Success", data: null };
|
|
1840
|
+
return {
|
|
1841
|
+
_tag: "Success",
|
|
1842
|
+
data: {
|
|
1843
|
+
id: `mock_last_order_${params.subscriptionId}`,
|
|
1844
|
+
createdAt: "2026-04-22T12:00:00Z"
|
|
1845
|
+
}
|
|
1846
|
+
};
|
|
1847
|
+
},
|
|
1848
|
+
async renewNow(_params) {
|
|
1849
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
1850
|
+
return { _tag: "Success", data: { result: "success" } };
|
|
1851
|
+
},
|
|
1852
|
+
async changeFrequency(params) {
|
|
1853
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
1854
|
+
const subscription = mockSubscriptions.find((sub) => sub.id === params.subscriptionId);
|
|
1855
|
+
if (!subscription) {
|
|
1856
|
+
return { _tag: "Failure", error: "Subscription not found" };
|
|
1857
|
+
}
|
|
1858
|
+
if (typeof params.plan === "string") {
|
|
1859
|
+
subscription.frequency = `1 ${params.plan}`;
|
|
1860
|
+
} else {
|
|
1861
|
+
subscription.frequency = `${params.plan.intervalCount} ${params.plan.interval}`;
|
|
1862
|
+
if (subscription.billingPolicy) {
|
|
1863
|
+
subscription.billingPolicy = { ...subscription.billingPolicy, ...params.plan };
|
|
1864
|
+
}
|
|
1865
|
+
if (subscription.deliveryPolicy) {
|
|
1866
|
+
subscription.deliveryPolicy = { ...subscription.deliveryPolicy, ...params.plan };
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
subscription.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
1870
|
+
return {
|
|
1871
|
+
_tag: "Success",
|
|
1872
|
+
data: {
|
|
1873
|
+
...subscription,
|
|
1874
|
+
items: subscription.items.map((item) => ({ ...item })),
|
|
1875
|
+
discounts: subscription.discounts.map((d3) => ({ ...d3 }))
|
|
1876
|
+
}
|
|
1877
|
+
};
|
|
1878
|
+
},
|
|
1425
1879
|
async getDefaultSubscriptionId() {
|
|
1426
1880
|
var _a;
|
|
1427
1881
|
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
@@ -1437,6 +1891,26 @@ function createMockSubscriptionAdapter(options = {}) {
|
|
|
1437
1891
|
}
|
|
1438
1892
|
};
|
|
1439
1893
|
}
|
|
1894
|
+
function normalizeInstrumentType(type) {
|
|
1895
|
+
return type.replace(/-/g, "_");
|
|
1896
|
+
}
|
|
1897
|
+
function mapPaymentMethod(rawPm) {
|
|
1898
|
+
if (!rawPm) return null;
|
|
1899
|
+
if (typeof rawPm === "string") {
|
|
1900
|
+
return { id: rawPm };
|
|
1901
|
+
}
|
|
1902
|
+
return {
|
|
1903
|
+
id: rawPm.id ?? "",
|
|
1904
|
+
...rawPm.instrument != null ? {
|
|
1905
|
+
instrument: {
|
|
1906
|
+
...rawPm.instrument,
|
|
1907
|
+
type: normalizeInstrumentType(rawPm.instrument.type)
|
|
1908
|
+
}
|
|
1909
|
+
} : {},
|
|
1910
|
+
...rawPm.active != null ? { active: rawPm.active } : {},
|
|
1911
|
+
...rawPm.isRecurring != null ? { isRecurring: rawPm.isRecurring } : {}
|
|
1912
|
+
};
|
|
1913
|
+
}
|
|
1440
1914
|
function mapSubscription(raw) {
|
|
1441
1915
|
var _a, _b;
|
|
1442
1916
|
const status = raw.status === "merged" ? "canceled" : raw.status;
|
|
@@ -1445,6 +1919,7 @@ function mapSubscription(raw) {
|
|
|
1445
1919
|
return {
|
|
1446
1920
|
id: raw.id,
|
|
1447
1921
|
customerId: "",
|
|
1922
|
+
serial: raw.serial,
|
|
1448
1923
|
items: (raw.items ?? []).map(
|
|
1449
1924
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1450
1925
|
(item) => ({
|
|
@@ -1458,31 +1933,44 @@ function mapSubscription(raw) {
|
|
|
1458
1933
|
},
|
|
1459
1934
|
nextDeliveryDate: item.nextDeliveryDate ? new Date(item.nextDeliveryDate) : null,
|
|
1460
1935
|
billingPolicy: item.billingPolicy ?? raw.billingPolicy ?? null,
|
|
1461
|
-
deliveryPolicy: item.deliveryPolicy ?? raw.deliveryPolicy ?? null
|
|
1936
|
+
deliveryPolicy: item.deliveryPolicy ?? raw.deliveryPolicy ?? null,
|
|
1937
|
+
// Map human-readable titles from the v1 SubscriptionItemResource
|
|
1938
|
+
title: item.title,
|
|
1939
|
+
variantTitle: item.subtitle ?? void 0,
|
|
1940
|
+
// recurringCycleLimit === 1 means the item charges exactly once (one-time upsell)
|
|
1941
|
+
isOneTime: item.recurringCycleLimit === 1
|
|
1462
1942
|
})
|
|
1463
1943
|
),
|
|
1464
1944
|
discounts: (raw.discounts ?? []).map(
|
|
1465
1945
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1466
|
-
(
|
|
1946
|
+
(d3) => {
|
|
1467
1947
|
var _a2, _b2, _c;
|
|
1468
1948
|
return {
|
|
1469
|
-
id:
|
|
1470
|
-
type: ((_a2 =
|
|
1471
|
-
value: ((_b2 =
|
|
1472
|
-
code:
|
|
1473
|
-
description:
|
|
1949
|
+
id: d3.id,
|
|
1950
|
+
type: ((_a2 = d3.value) == null ? void 0 : _a2.type) === "fixed-amount" || d3.type === "fixed_amount" ? "fixed_amount" : "percentage",
|
|
1951
|
+
value: ((_b2 = d3.value) == null ? void 0 : _b2.amount) ?? ((_c = d3.value) == null ? void 0 : _c.percentage) ?? d3.value ?? 0,
|
|
1952
|
+
code: d3.title ?? d3.code ?? "",
|
|
1953
|
+
description: d3.description ?? ""
|
|
1474
1954
|
};
|
|
1475
1955
|
}
|
|
1476
1956
|
),
|
|
1477
1957
|
status,
|
|
1478
1958
|
nextDeliveryDate: raw.nextBillingDate ? new Date(raw.nextBillingDate) : raw.nextDeliveryDate ? new Date(raw.nextDeliveryDate) : null,
|
|
1959
|
+
// Map nextBillingDate as the raw ISO string for ProductSelect skip() and other consumers
|
|
1960
|
+
nextBillingDate: raw.nextBillingDate ?? null,
|
|
1961
|
+
// Map customerPaymentMethod — note: arrives as bare id (not expanded) since the
|
|
1962
|
+
// subscriptions endpoint does not support ?expand=paymentMethod; instrument digits
|
|
1963
|
+
// remain a data gap pending backend API extension.
|
|
1964
|
+
customerPaymentMethod: mapPaymentMethod(raw.paymentMethod),
|
|
1479
1965
|
frequency,
|
|
1480
1966
|
createdAt: raw.createdAt,
|
|
1481
|
-
updatedAt: raw.updatedAt
|
|
1967
|
+
updatedAt: raw.updatedAt,
|
|
1968
|
+
billingPolicy: raw.billingPolicy ?? null,
|
|
1969
|
+
deliveryPolicy: raw.deliveryPolicy ?? null
|
|
1482
1970
|
};
|
|
1483
1971
|
}
|
|
1484
1972
|
function createApiSubscriptionAdapter(fetcher) {
|
|
1485
|
-
|
|
1973
|
+
const adapter = {
|
|
1486
1974
|
async search(options) {
|
|
1487
1975
|
var _a;
|
|
1488
1976
|
try {
|
|
@@ -1513,8 +2001,8 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1513
2001
|
}
|
|
1514
2002
|
}
|
|
1515
2003
|
};
|
|
1516
|
-
} catch (
|
|
1517
|
-
return { _tag: "Failure", error:
|
|
2004
|
+
} catch (e3) {
|
|
2005
|
+
return { _tag: "Failure", error: e3 };
|
|
1518
2006
|
}
|
|
1519
2007
|
},
|
|
1520
2008
|
async getById(id) {
|
|
@@ -1526,8 +2014,8 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1526
2014
|
const body = await res.json();
|
|
1527
2015
|
const raw = body.data[0];
|
|
1528
2016
|
return { _tag: "Success", data: raw ? mapSubscription(raw) : null };
|
|
1529
|
-
} catch (
|
|
1530
|
-
return { _tag: "Failure", error:
|
|
2017
|
+
} catch (e3) {
|
|
2018
|
+
return { _tag: "Failure", error: e3 };
|
|
1531
2019
|
}
|
|
1532
2020
|
},
|
|
1533
2021
|
async addItem({ subscriptionId, item }) {
|
|
@@ -1542,8 +2030,8 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1542
2030
|
);
|
|
1543
2031
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1544
2032
|
return { _tag: "Success", data: void 0 };
|
|
1545
|
-
} catch (
|
|
1546
|
-
return { _tag: "Failure", error:
|
|
2033
|
+
} catch (e3) {
|
|
2034
|
+
return { _tag: "Failure", error: e3 };
|
|
1547
2035
|
}
|
|
1548
2036
|
},
|
|
1549
2037
|
async removeItem({ subscriptionId, itemId }) {
|
|
@@ -1554,8 +2042,62 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1554
2042
|
);
|
|
1555
2043
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1556
2044
|
return { _tag: "Success", data: void 0 };
|
|
1557
|
-
} catch (
|
|
1558
|
-
return { _tag: "Failure", error:
|
|
2045
|
+
} catch (e3) {
|
|
2046
|
+
return { _tag: "Failure", error: e3 };
|
|
2047
|
+
}
|
|
2048
|
+
},
|
|
2049
|
+
async updateItem({ subscriptionId, lineId, update }) {
|
|
2050
|
+
try {
|
|
2051
|
+
const body = {
|
|
2052
|
+
...update.variantId !== void 0 ? { productVariantId: update.variantId } : {},
|
|
2053
|
+
...update.quantity !== void 0 ? { quantity: update.quantity } : {},
|
|
2054
|
+
...update.billingPolicy !== void 0 ? { billingPolicy: update.billingPolicy } : {},
|
|
2055
|
+
...update.shippingMethodHandle !== void 0 ? { shippingMethodHandle: update.shippingMethodHandle } : {}
|
|
2056
|
+
};
|
|
2057
|
+
const res = await fetcher(
|
|
2058
|
+
`/customer/subscriptions/${subscriptionId}/lines/${lineId}`,
|
|
2059
|
+
{
|
|
2060
|
+
method: "PUT",
|
|
2061
|
+
headers: { "Content-Type": "application/json" },
|
|
2062
|
+
body: JSON.stringify(body)
|
|
2063
|
+
}
|
|
2064
|
+
);
|
|
2065
|
+
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
2066
|
+
return { _tag: "Success", data: void 0 };
|
|
2067
|
+
} catch (e3) {
|
|
2068
|
+
return { _tag: "Failure", error: e3 };
|
|
2069
|
+
}
|
|
2070
|
+
},
|
|
2071
|
+
async skipLineItem({ subscriptionId, lineId, nextBillingDate }) {
|
|
2072
|
+
try {
|
|
2073
|
+
const res = await fetcher(
|
|
2074
|
+
`/customer/subscriptions/${subscriptionId}/lines/${lineId}`,
|
|
2075
|
+
{
|
|
2076
|
+
method: "PUT",
|
|
2077
|
+
headers: { "Content-Type": "application/json" },
|
|
2078
|
+
body: JSON.stringify({ nextBillingDate })
|
|
2079
|
+
}
|
|
2080
|
+
);
|
|
2081
|
+
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
2082
|
+
return { _tag: "Success", data: void 0 };
|
|
2083
|
+
} catch (e3) {
|
|
2084
|
+
return { _tag: "Failure", error: e3 };
|
|
2085
|
+
}
|
|
2086
|
+
},
|
|
2087
|
+
async updateBoxItems({ subscriptionId, parentId, items, shippingMethodHandle }) {
|
|
2088
|
+
try {
|
|
2089
|
+
const res = await fetcher(
|
|
2090
|
+
`/customer/subscriptions/${subscriptionId}/update-box-products`,
|
|
2091
|
+
{
|
|
2092
|
+
method: "POST",
|
|
2093
|
+
headers: { "Content-Type": "application/json" },
|
|
2094
|
+
body: JSON.stringify({ parentId, items, shippingMethodHandle })
|
|
2095
|
+
}
|
|
2096
|
+
);
|
|
2097
|
+
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
2098
|
+
return { _tag: "Success", data: void 0 };
|
|
2099
|
+
} catch (e3) {
|
|
2100
|
+
return { _tag: "Failure", error: e3 };
|
|
1559
2101
|
}
|
|
1560
2102
|
},
|
|
1561
2103
|
async addDiscount({ subscriptionId, code }) {
|
|
@@ -1570,8 +2112,8 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1570
2112
|
);
|
|
1571
2113
|
if (!res.ok) return { _tag: "Failure", error: { kind: "NETWORK", message: `HTTP ${res.status}` } };
|
|
1572
2114
|
return { _tag: "Success", data: void 0 };
|
|
1573
|
-
} catch (
|
|
1574
|
-
return { _tag: "Failure", error: { kind: "UNKNOWN", message:
|
|
2115
|
+
} catch (e3) {
|
|
2116
|
+
return { _tag: "Failure", error: { kind: "UNKNOWN", message: e3 instanceof Error ? e3.message : void 0 } };
|
|
1575
2117
|
}
|
|
1576
2118
|
},
|
|
1577
2119
|
async removeDiscount({ subscriptionId, discountId }) {
|
|
@@ -1582,8 +2124,8 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1582
2124
|
);
|
|
1583
2125
|
if (!res.ok) return { _tag: "Failure", error: { kind: "NETWORK", message: `HTTP ${res.status}` } };
|
|
1584
2126
|
return { _tag: "Success", data: void 0 };
|
|
1585
|
-
} catch (
|
|
1586
|
-
return { _tag: "Failure", error: { kind: "UNKNOWN", message:
|
|
2127
|
+
} catch (e3) {
|
|
2128
|
+
return { _tag: "Failure", error: { kind: "UNKNOWN", message: e3 instanceof Error ? e3.message : void 0 } };
|
|
1587
2129
|
}
|
|
1588
2130
|
},
|
|
1589
2131
|
// Uses PATCH /customer/v1/subscriptions/{id} — the dedicated /reschedule route does not exist.
|
|
@@ -1600,8 +2142,8 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1600
2142
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1601
2143
|
const data = await res.json();
|
|
1602
2144
|
return { _tag: "Success", data: mapSubscription(data) };
|
|
1603
|
-
} catch (
|
|
1604
|
-
return { _tag: "Failure", error:
|
|
2145
|
+
} catch (e3) {
|
|
2146
|
+
return { _tag: "Failure", error: e3 };
|
|
1605
2147
|
}
|
|
1606
2148
|
},
|
|
1607
2149
|
async resume({ subscriptionId }) {
|
|
@@ -1613,8 +2155,8 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1613
2155
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1614
2156
|
const data = await res.json();
|
|
1615
2157
|
return { _tag: "Success", data: mapSubscription(data) };
|
|
1616
|
-
} catch (
|
|
1617
|
-
return { _tag: "Failure", error:
|
|
2158
|
+
} catch (e3) {
|
|
2159
|
+
return { _tag: "Failure", error: e3 };
|
|
1618
2160
|
}
|
|
1619
2161
|
},
|
|
1620
2162
|
async pause({ subscriptionId }) {
|
|
@@ -1626,8 +2168,8 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1626
2168
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1627
2169
|
const data = await res.json();
|
|
1628
2170
|
return { _tag: "Success", data: mapSubscription(data) };
|
|
1629
|
-
} catch (
|
|
1630
|
-
return { _tag: "Failure", error:
|
|
2171
|
+
} catch (e3) {
|
|
2172
|
+
return { _tag: "Failure", error: e3 };
|
|
1631
2173
|
}
|
|
1632
2174
|
},
|
|
1633
2175
|
async reactivate({ subscriptionId }) {
|
|
@@ -1639,8 +2181,8 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1639
2181
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1640
2182
|
const data = await res.json();
|
|
1641
2183
|
return { _tag: "Success", data: mapSubscription(data) };
|
|
1642
|
-
} catch (
|
|
1643
|
-
return { _tag: "Failure", error:
|
|
2184
|
+
} catch (e3) {
|
|
2185
|
+
return { _tag: "Failure", error: e3 };
|
|
1644
2186
|
}
|
|
1645
2187
|
},
|
|
1646
2188
|
async cancel({ subscriptionId, reason }) {
|
|
@@ -1656,8 +2198,8 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1656
2198
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1657
2199
|
const data = await res.json();
|
|
1658
2200
|
return { _tag: "Success", data: mapSubscription(data) };
|
|
1659
|
-
} catch (
|
|
1660
|
-
return { _tag: "Failure", error:
|
|
2201
|
+
} catch (e3) {
|
|
2202
|
+
return { _tag: "Failure", error: e3 };
|
|
1661
2203
|
}
|
|
1662
2204
|
},
|
|
1663
2205
|
// Legacy endpoint — no /customer/v1/subscriptions/{id}/plans exists yet.
|
|
@@ -1669,8 +2211,8 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1669
2211
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1670
2212
|
const data = await res.json();
|
|
1671
2213
|
return { _tag: "Success", data };
|
|
1672
|
-
} catch (
|
|
1673
|
-
return { _tag: "Failure", error:
|
|
2214
|
+
} catch (e3) {
|
|
2215
|
+
return { _tag: "Failure", error: e3 };
|
|
1674
2216
|
}
|
|
1675
2217
|
},
|
|
1676
2218
|
// Legacy endpoint — no /customer/v1 equivalent exists yet.
|
|
@@ -1682,8 +2224,8 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1682
2224
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1683
2225
|
const data = await res.json();
|
|
1684
2226
|
return { _tag: "Success", data: (data == null ? void 0 : data.id) ?? null };
|
|
1685
|
-
} catch (
|
|
1686
|
-
return { _tag: "Failure", error:
|
|
2227
|
+
} catch (e3) {
|
|
2228
|
+
return { _tag: "Failure", error: e3 };
|
|
1687
2229
|
}
|
|
1688
2230
|
},
|
|
1689
2231
|
// Legacy endpoint — no /customer/v1/subscriptions/{id}/upsells exists yet.
|
|
@@ -1695,21 +2237,23 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1695
2237
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1696
2238
|
const data = await res.json();
|
|
1697
2239
|
const products = data.map((p2) => {
|
|
1698
|
-
var _a, _b, _c, _d, _e;
|
|
2240
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
1699
2241
|
return {
|
|
1700
2242
|
id: p2.id,
|
|
1701
2243
|
variantId: ((_b = (_a = p2.variants) == null ? void 0 : _a[0]) == null ? void 0 : _b.id) ?? "",
|
|
1702
2244
|
title: p2.title ?? "",
|
|
1703
2245
|
imageUrl: ((_c = p2.featuredImage) == null ? void 0 : _c.url) ?? void 0,
|
|
1704
2246
|
price: {
|
|
1705
|
-
amount: String(((_e = (_d = p2.variants) == null ? void 0 : _d[0]) == null ? void 0 : _e.
|
|
1706
|
-
currencyCode: p2.currencyCode ?? ""
|
|
1707
|
-
}
|
|
2247
|
+
amount: String(((_f = (_e = (_d = p2.variants) == null ? void 0 : _d[0]) == null ? void 0 : _e.currentPrice) == null ? void 0 : _f.amount) ?? 0),
|
|
2248
|
+
currencyCode: ((_i = (_h = (_g = p2.variants) == null ? void 0 : _g[0]) == null ? void 0 : _h.currentPrice) == null ? void 0 : _i.currencyCode) ?? ""
|
|
2249
|
+
},
|
|
2250
|
+
// recurring comes from the upsell rule on variants[0]; present in PreparedProductSchema
|
|
2251
|
+
recurring: (_k = (_j = p2.variants) == null ? void 0 : _j[0]) == null ? void 0 : _k.recurring
|
|
1708
2252
|
};
|
|
1709
2253
|
});
|
|
1710
2254
|
return { _tag: "Success", data: products };
|
|
1711
|
-
} catch (
|
|
1712
|
-
return { _tag: "Failure", error:
|
|
2255
|
+
} catch (e3) {
|
|
2256
|
+
return { _tag: "Failure", error: e3 };
|
|
1713
2257
|
}
|
|
1714
2258
|
},
|
|
1715
2259
|
// Legacy endpoint — no /customer/v1/subscriptions/{id}/upsells POST exists yet.
|
|
@@ -1729,11 +2273,73 @@ function createApiSubscriptionAdapter(fetcher) {
|
|
|
1729
2273
|
);
|
|
1730
2274
|
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
1731
2275
|
return { _tag: "Success", data: void 0 };
|
|
1732
|
-
} catch (
|
|
1733
|
-
return { _tag: "Failure", error:
|
|
2276
|
+
} catch (e3) {
|
|
2277
|
+
return { _tag: "Failure", error: e3 };
|
|
2278
|
+
}
|
|
2279
|
+
},
|
|
2280
|
+
// Legacy endpoint — no /customer/v1 equivalent exists yet.
|
|
2281
|
+
async getLastOrder({ subscriptionId }) {
|
|
2282
|
+
try {
|
|
2283
|
+
const res = await fetcher(
|
|
2284
|
+
`/customer/subscriptions/${subscriptionId}/last-order`
|
|
2285
|
+
);
|
|
2286
|
+
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
2287
|
+
const data = await res.json();
|
|
2288
|
+
if (!data) return { _tag: "Success", data: null };
|
|
2289
|
+
return {
|
|
2290
|
+
_tag: "Success",
|
|
2291
|
+
data: { id: data.id, createdAt: data.createdAt }
|
|
2292
|
+
};
|
|
2293
|
+
} catch (e3) {
|
|
2294
|
+
return { _tag: "Failure", error: e3 };
|
|
2295
|
+
}
|
|
2296
|
+
},
|
|
2297
|
+
// Legacy endpoints, split by stage (see SubscriptionService.renewNow docs):
|
|
2298
|
+
// retry → POST /customer/subscriptions/{id}/retry
|
|
2299
|
+
// renewalId → POST /customer/renewals/{renewalId}/renew
|
|
2300
|
+
// default → POST /customer/subscriptions/{id}/order-now
|
|
2301
|
+
async renewNow({ subscriptionId, renewalId, retry }) {
|
|
2302
|
+
try {
|
|
2303
|
+
const url = retry ? `/customer/subscriptions/${subscriptionId}/retry` : renewalId ? `/customer/renewals/${renewalId}/renew` : `/customer/subscriptions/${subscriptionId}/order-now`;
|
|
2304
|
+
const res = await fetcher(url, { method: "POST" });
|
|
2305
|
+
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
2306
|
+
const body = res.status === 204 ? null : await res.json();
|
|
2307
|
+
return {
|
|
2308
|
+
_tag: "Success",
|
|
2309
|
+
data: {
|
|
2310
|
+
nextActionUrl: (body == null ? void 0 : body.nextActionUrl) ?? void 0,
|
|
2311
|
+
result: (body == null ? void 0 : body.result) ?? "success"
|
|
2312
|
+
}
|
|
2313
|
+
};
|
|
2314
|
+
} catch (e3) {
|
|
2315
|
+
return { _tag: "Failure", error: e3 };
|
|
2316
|
+
}
|
|
2317
|
+
},
|
|
2318
|
+
// Legacy endpoint — POST /plan returns 204; re-fetch to return the updated subscription.
|
|
2319
|
+
async changeFrequency({ subscriptionId, plan }) {
|
|
2320
|
+
try {
|
|
2321
|
+
const res = await fetcher(
|
|
2322
|
+
`/customer/subscriptions/${subscriptionId}/plan`,
|
|
2323
|
+
{
|
|
2324
|
+
method: "POST",
|
|
2325
|
+
headers: { "Content-Type": "application/json" },
|
|
2326
|
+
body: JSON.stringify({ plan })
|
|
2327
|
+
}
|
|
2328
|
+
);
|
|
2329
|
+
if (!res.ok) return { _tag: "Failure", error: `HTTP ${res.status}` };
|
|
2330
|
+
const refreshed = await adapter.getById(subscriptionId);
|
|
2331
|
+
if (refreshed._tag === "Failure") return refreshed;
|
|
2332
|
+
if (refreshed.data) return { _tag: "Success", data: refreshed.data };
|
|
2333
|
+
return {
|
|
2334
|
+
_tag: "Failure",
|
|
2335
|
+
error: "Subscription not found after frequency change"
|
|
2336
|
+
};
|
|
2337
|
+
} catch (e3) {
|
|
2338
|
+
return { _tag: "Failure", error: e3 };
|
|
1734
2339
|
}
|
|
1735
2340
|
}
|
|
1736
2341
|
};
|
|
2342
|
+
return adapter;
|
|
1737
2343
|
}
|
|
1738
2344
|
const SubscriptionServiceContext = createContext("services/subscription");
|
|
1739
2345
|
function getCurrentSubscriptionId() {
|
|
@@ -1758,57 +2364,74 @@ function getCurrentSubscriptionId() {
|
|
|
1758
2364
|
function createSubscriptionService(adapter) {
|
|
1759
2365
|
const current = d(null);
|
|
1760
2366
|
const hasPendingBilling = d(false);
|
|
1761
|
-
const
|
|
1762
|
-
const
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
}
|
|
1768
|
-
}
|
|
1769
|
-
async function refreshAfterDiscountChange(subscriptionId) {
|
|
1770
|
-
await refreshCurrent(subscriptionId);
|
|
1771
|
-
discountsChangedAtSignal.value = discountsChangedAtSignal.value + 1;
|
|
2367
|
+
const discountsChangedAt = d(0);
|
|
2368
|
+
const itemsChangedAt = d(0);
|
|
2369
|
+
const lastOrder = d(null);
|
|
2370
|
+
async function refreshAfterDiscountChange() {
|
|
2371
|
+
await reload();
|
|
2372
|
+
discountsChangedAt.value = discountsChangedAt.value + 1;
|
|
1772
2373
|
}
|
|
1773
|
-
async function refreshAfterItemChange(
|
|
1774
|
-
await
|
|
1775
|
-
|
|
2374
|
+
async function refreshAfterItemChange() {
|
|
2375
|
+
await reload();
|
|
2376
|
+
itemsChangedAt.value = itemsChangedAt.value + 1;
|
|
1776
2377
|
}
|
|
1777
2378
|
function subscriptionIdFromCurrent() {
|
|
1778
2379
|
var _a;
|
|
1779
2380
|
return ((_a = current.value) == null ? void 0 : _a.id) ?? null;
|
|
1780
2381
|
}
|
|
1781
|
-
|
|
2382
|
+
async function reload() {
|
|
2383
|
+
var _a, _b;
|
|
2384
|
+
const id = (_a = current.value) == null ? void 0 : _a.id;
|
|
2385
|
+
if (!id) return;
|
|
2386
|
+
const [subResult, lastOrderResult] = await Promise.all([
|
|
2387
|
+
adapter.getById(id),
|
|
2388
|
+
adapter.getLastOrder({ subscriptionId: id })
|
|
2389
|
+
]);
|
|
2390
|
+
if (((_b = current.value) == null ? void 0 : _b.id) !== id) return;
|
|
2391
|
+
if (subResult._tag === "Success") current.value = subResult.data;
|
|
2392
|
+
if (lastOrderResult._tag === "Success") lastOrder.value = lastOrderResult.data;
|
|
2393
|
+
}
|
|
2394
|
+
const service = {
|
|
1782
2395
|
current,
|
|
1783
2396
|
hasPendingBilling,
|
|
1784
|
-
discountsChangedAt
|
|
1785
|
-
itemsChangedAt
|
|
1786
|
-
|
|
1787
|
-
|
|
2397
|
+
discountsChangedAt,
|
|
2398
|
+
itemsChangedAt,
|
|
2399
|
+
lastOrder,
|
|
2400
|
+
search: adapter.search,
|
|
2401
|
+
getById: adapter.getById,
|
|
2402
|
+
getCurrentSubscriptionId,
|
|
2403
|
+
addItem: async (subscriptionId, item) => {
|
|
2404
|
+
const result = await adapter.addItem({ subscriptionId, item });
|
|
1788
2405
|
if (result._tag === "Success") {
|
|
1789
|
-
|
|
2406
|
+
await refreshAfterItemChange();
|
|
1790
2407
|
}
|
|
1791
2408
|
return result;
|
|
1792
2409
|
},
|
|
1793
|
-
async
|
|
1794
|
-
const result = await adapter.
|
|
1795
|
-
if (result._tag === "Success"
|
|
1796
|
-
|
|
2410
|
+
removeItem: async (subscriptionId, itemId) => {
|
|
2411
|
+
const result = await adapter.removeItem({ subscriptionId, itemId });
|
|
2412
|
+
if (result._tag === "Success") {
|
|
2413
|
+
await refreshAfterItemChange();
|
|
1797
2414
|
}
|
|
1798
2415
|
return result;
|
|
1799
2416
|
},
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
const result = await adapter.addItem({ subscriptionId, item });
|
|
2417
|
+
updateItem: async (subscriptionId, lineId, update) => {
|
|
2418
|
+
const result = await adapter.updateItem({ subscriptionId, lineId, update });
|
|
1803
2419
|
if (result._tag === "Success") {
|
|
1804
|
-
await refreshAfterItemChange(
|
|
2420
|
+
await refreshAfterItemChange();
|
|
1805
2421
|
}
|
|
1806
2422
|
return result;
|
|
1807
2423
|
},
|
|
1808
|
-
|
|
1809
|
-
const result = await adapter.
|
|
2424
|
+
skipLineItem: async (subscriptionId, lineId, nextBillingDate) => {
|
|
2425
|
+
const result = await adapter.skipLineItem({ subscriptionId, lineId, nextBillingDate });
|
|
2426
|
+
if (result._tag === "Success") {
|
|
2427
|
+
await refreshAfterItemChange();
|
|
2428
|
+
}
|
|
2429
|
+
return result;
|
|
2430
|
+
},
|
|
2431
|
+
updateBoxItems: async (subscriptionId, params) => {
|
|
2432
|
+
const result = await adapter.updateBoxItems({ subscriptionId, ...params });
|
|
1810
2433
|
if (result._tag === "Success") {
|
|
1811
|
-
await refreshAfterItemChange(
|
|
2434
|
+
await refreshAfterItemChange();
|
|
1812
2435
|
}
|
|
1813
2436
|
return result;
|
|
1814
2437
|
},
|
|
@@ -1822,7 +2445,7 @@ function createSubscriptionService(adapter) {
|
|
|
1822
2445
|
}
|
|
1823
2446
|
const result = await adapter.addDiscount({ subscriptionId: id, code });
|
|
1824
2447
|
if (result._tag === "Success") {
|
|
1825
|
-
await refreshAfterDiscountChange(
|
|
2448
|
+
await refreshAfterDiscountChange();
|
|
1826
2449
|
}
|
|
1827
2450
|
return result;
|
|
1828
2451
|
},
|
|
@@ -1839,7 +2462,7 @@ function createSubscriptionService(adapter) {
|
|
|
1839
2462
|
discountId
|
|
1840
2463
|
});
|
|
1841
2464
|
if (result._tag === "Success") {
|
|
1842
|
-
await refreshAfterDiscountChange(
|
|
2465
|
+
await refreshAfterDiscountChange();
|
|
1843
2466
|
}
|
|
1844
2467
|
return result;
|
|
1845
2468
|
},
|
|
@@ -1848,11 +2471,15 @@ function createSubscriptionService(adapter) {
|
|
|
1848
2471
|
pause: (subscriptionId) => adapter.pause({ subscriptionId }),
|
|
1849
2472
|
reactivate: (subscriptionId) => adapter.reactivate({ subscriptionId }),
|
|
1850
2473
|
cancel: (subscriptionId, reason) => adapter.cancel({ subscriptionId, reason }),
|
|
2474
|
+
renewNow: (params) => adapter.renewNow(params),
|
|
2475
|
+
changeFrequency: (subscriptionId, plan) => adapter.changeFrequency({ subscriptionId, plan }),
|
|
2476
|
+
reload,
|
|
1851
2477
|
getAvailablePlans: (subscriptionId) => adapter.getAvailablePlans({ subscriptionId }),
|
|
1852
2478
|
getDefaultSubscriptionId: () => adapter.getDefaultSubscriptionId(),
|
|
1853
2479
|
getUpsellProducts: (params) => adapter.getUpsellProducts ? adapter.getUpsellProducts(params) : Promise.resolve({ _tag: "Success", data: [] }),
|
|
1854
2480
|
addUpsellProduct: (params) => adapter.addUpsellProduct ? adapter.addUpsellProduct(params) : Promise.resolve({ _tag: "Success", data: void 0 })
|
|
1855
2481
|
};
|
|
2482
|
+
return service;
|
|
1856
2483
|
}
|
|
1857
2484
|
const DISCOUNT_REJECTION_REASONS = [
|
|
1858
2485
|
"INVALID_CODE",
|
|
@@ -2120,9 +2747,9 @@ export {
|
|
|
2120
2747
|
AuthenticationErrorReason,
|
|
2121
2748
|
B as BlockWrapperEvent,
|
|
2122
2749
|
C as ContextProvideEvent,
|
|
2123
|
-
|
|
2750
|
+
e as ContextRequestEvent,
|
|
2124
2751
|
CustomerServiceContext,
|
|
2125
|
-
|
|
2752
|
+
D2 as DEFAULT_GLOBAL_STYLES,
|
|
2126
2753
|
DISCOUNT_REJECTION_REASONS,
|
|
2127
2754
|
LoginServiceContext,
|
|
2128
2755
|
OrdersServiceContext,
|
|
@@ -2130,24 +2757,28 @@ export {
|
|
|
2130
2757
|
RouterServiceContext,
|
|
2131
2758
|
SchedulesServiceContext,
|
|
2132
2759
|
S as SelectedBlockContext,
|
|
2760
|
+
SettingsServiceContext,
|
|
2761
|
+
ShopServiceContext,
|
|
2133
2762
|
u as Signal,
|
|
2134
2763
|
StateContext,
|
|
2135
2764
|
SubscriptionServiceContext,
|
|
2136
2765
|
T as ThemeStateContext,
|
|
2137
|
-
|
|
2766
|
+
a as TranslationContext,
|
|
2138
2767
|
W as WorkflowServiceContext,
|
|
2139
|
-
|
|
2140
|
-
f as
|
|
2768
|
+
_ as __recordDevtoolsInstance,
|
|
2769
|
+
f as __recordDevtoolsPropSetter,
|
|
2770
|
+
g as attachEmptyTracking,
|
|
2771
|
+
h as backfillInstanceDefaults,
|
|
2141
2772
|
w as computed,
|
|
2142
2773
|
createApiCustomerAdapter,
|
|
2143
2774
|
createApiLoginAdapter,
|
|
2144
2775
|
createApiProductAdapter,
|
|
2145
2776
|
createApiSchedulesAdapter,
|
|
2146
2777
|
createApiSubscriptionAdapter,
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2778
|
+
createBlockInstance,
|
|
2779
|
+
i as createBlockInstanceFromJSON,
|
|
2780
|
+
j as createBlockInstanceFromObject,
|
|
2781
|
+
k as createCeRenderer,
|
|
2151
2782
|
createContext,
|
|
2152
2783
|
createCustomerService,
|
|
2153
2784
|
createLoginService,
|
|
@@ -2163,33 +2794,38 @@ export {
|
|
|
2163
2794
|
createProductService,
|
|
2164
2795
|
createRouterService,
|
|
2165
2796
|
createSchedulesService,
|
|
2166
|
-
|
|
2797
|
+
l as createSelectedBlock,
|
|
2798
|
+
createSettingsService,
|
|
2799
|
+
createShopService,
|
|
2167
2800
|
createState,
|
|
2168
2801
|
createSubscriptionService,
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2802
|
+
c as createThemeState,
|
|
2803
|
+
b as createTranslationService,
|
|
2804
|
+
d2 as createWorkflowApiAdapter,
|
|
2805
|
+
e2 as createWorkflowService,
|
|
2806
|
+
defineBlock,
|
|
2807
|
+
m as defineBlockRuntime,
|
|
2808
|
+
defineOverlayWrapper,
|
|
2175
2809
|
E as effect,
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2810
|
+
g2 as getDefaultBlockForAction,
|
|
2811
|
+
n as getDefinedBlocks,
|
|
2812
|
+
o as getDevtoolsBlockState,
|
|
2813
|
+
h2 as hasDefaultBlockForAction,
|
|
2814
|
+
p as hasRenderedContent,
|
|
2815
|
+
i2 as indexOverrides,
|
|
2816
|
+
q as injectContext,
|
|
2817
|
+
s as isEditorPreview,
|
|
2818
|
+
t as isStubDefinition,
|
|
2184
2819
|
loadBlockRegistry,
|
|
2185
2820
|
loginService,
|
|
2186
|
-
|
|
2187
|
-
|
|
2821
|
+
v as onRegisterBlock,
|
|
2822
|
+
x as provideContext,
|
|
2188
2823
|
registerBlock,
|
|
2189
|
-
|
|
2824
|
+
y as serializeBlocks,
|
|
2825
|
+
z as setDevtoolsBlockProp,
|
|
2190
2826
|
d as signal,
|
|
2191
|
-
|
|
2192
|
-
|
|
2827
|
+
A as subscribeContext,
|
|
2828
|
+
D as untracked,
|
|
2193
2829
|
waitForDevBlocksUrl,
|
|
2194
|
-
|
|
2830
|
+
F as withWrapper
|
|
2195
2831
|
};
|