@zappie/sdk 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +55 -313
- package/dist/cart/errors.js +13 -0
- package/dist/cart/errors.js.map +7 -0
- package/dist/cart/index.js +768 -0
- package/dist/cart/index.js.map +7 -0
- package/dist/cart/item.js +12 -1
- package/dist/cart/item.js.map +7 -1
- package/dist/cart/preview.js +32 -0
- package/dist/cart/preview.js.map +7 -0
- package/dist/cart/price.js +25 -0
- package/dist/cart/price.js.map +7 -0
- package/dist/cart/quote-client.js +76 -0
- package/dist/cart/quote-client.js.map +7 -0
- package/dist/cart/quote-response.js +178 -0
- package/dist/cart/quote-response.js.map +7 -0
- package/dist/cart/reconcile.js +108 -0
- package/dist/cart/reconcile.js.map +7 -0
- package/dist/cart/source-menu.js +21 -0
- package/dist/cart/source-menu.js.map +7 -0
- package/dist/cart/storage.js +174 -0
- package/dist/cart/storage.js.map +7 -0
- package/dist/cart/types.js +1 -0
- package/dist/cart/types.js.map +7 -0
- package/dist/cart/validate.js +265 -0
- package/dist/cart/validate.js.map +7 -0
- package/dist/cart/wire.js +42 -0
- package/dist/cart/wire.js.map +7 -0
- package/dist/cart/working-set.js +80 -0
- package/dist/cart/working-set.js.map +7 -0
- package/dist/checkout/client.js +102 -0
- package/dist/checkout/client.js.map +7 -0
- package/dist/checkout/error.js +21 -0
- package/dist/checkout/error.js.map +7 -0
- package/dist/checkout/index.js +13 -1
- package/dist/checkout/index.js.map +7 -1
- package/dist/checkout/readiness.js +36 -0
- package/dist/checkout/readiness.js.map +7 -0
- package/dist/checkout/sdk.js +9 -0
- package/dist/checkout/sdk.js.map +7 -0
- package/dist/checkout/session.js +58 -0
- package/dist/checkout/session.js.map +7 -0
- package/dist/checkout/types.js +1 -0
- package/dist/checkout/types.js.map +7 -0
- package/dist/client.js +253 -0
- package/dist/client.js.map +7 -0
- package/dist/config/index.js +13 -1
- package/dist/config/index.js.map +7 -0
- package/dist/config.js +28 -0
- package/dist/config.js.map +7 -0
- package/dist/customer/client.js +149 -0
- package/dist/customer/client.js.map +7 -0
- package/dist/customer/error.js +20 -0
- package/dist/customer/error.js.map +7 -0
- package/dist/customer/index.js +8 -3
- package/dist/customer/index.js.map +7 -1
- package/dist/customer/navigation.js +45 -0
- package/dist/customer/navigation.js.map +7 -0
- package/dist/customer/react.js +67 -2
- package/dist/customer/react.js.map +7 -1
- package/dist/customer/request.js +37 -0
- package/dist/customer/request.js.map +7 -0
- package/dist/customer/sdk.js +6 -0
- package/dist/customer/sdk.js.map +7 -0
- package/dist/customer/types.js +1 -0
- package/dist/customer/types.js.map +7 -0
- package/dist/customer/watch-order.js +80 -0
- package/dist/customer/watch-order.js.map +7 -0
- package/dist/debug.js +78 -1
- package/dist/debug.js.map +7 -1
- package/dist/errors.js +69 -0
- package/dist/errors.js.map +7 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +29 -1
- package/dist/index.js.map +7 -1
- package/dist/internal/abort.js +29 -0
- package/dist/internal/abort.js.map +7 -0
- package/dist/internal/cache.js +142 -0
- package/dist/internal/cache.js.map +7 -0
- package/dist/internal/customer-http.js +74 -0
- package/dist/internal/customer-http.js.map +7 -0
- package/dist/internal/digest.js +15 -0
- package/dist/internal/digest.js.map +7 -0
- package/dist/internal/emitter.js +27 -0
- package/dist/internal/emitter.js.map +7 -0
- package/dist/internal/money-math.js +30 -0
- package/dist/internal/money-math.js.map +7 -0
- package/dist/internal.js +9 -1
- package/dist/internal.js.map +7 -1
- package/dist/models.js +1 -0
- package/dist/models.js.map +7 -0
- package/dist/money.js +58 -0
- package/dist/money.js.map +7 -0
- package/dist/persist/catalogue.js +206 -2
- package/dist/persist/catalogue.js.map +7 -1
- package/dist/places/client.js +97 -0
- package/dist/places/client.js.map +7 -0
- package/dist/places/error.js +20 -0
- package/dist/places/error.js.map +7 -0
- package/dist/places/index.js +8 -1
- package/dist/places/index.js.map +7 -1
- package/dist/places/request.js +40 -0
- package/dist/places/request.js.map +7 -0
- package/dist/places/sdk.js +10 -0
- package/dist/places/sdk.js.map +7 -0
- package/dist/places/search.js +80 -0
- package/dist/places/search.js.map +7 -0
- package/dist/places/types.js +1 -0
- package/dist/places/types.js.map +7 -0
- package/dist/react/cart.js +30 -0
- package/dist/react/cart.js.map +7 -0
- package/dist/react/hooks.js +91 -0
- package/dist/react/hooks.js.map +7 -0
- package/dist/react/index.js +18 -1
- package/dist/react/index.js.map +7 -1
- package/dist/react/provider.js +34 -0
- package/dist/react/provider.js.map +7 -0
- package/dist/server/index.js +32 -2
- package/dist/server/index.js.map +7 -1
- package/dist/server/storefront-url/build-v1.js +75 -0
- package/dist/server/storefront-url/build-v1.js.map +7 -0
- package/dist/server/storefront-url/build-v2.js +79 -0
- package/dist/server/storefront-url/build-v2.js.map +7 -0
- package/dist/server/storefront-url/build.js +19 -0
- package/dist/server/storefront-url/build.js.map +7 -0
- package/dist/server/storefront-url/contract.js +25 -0
- package/dist/server/storefront-url/contract.js.map +7 -0
- package/dist/server/storefront-url/index.js +16 -0
- package/dist/server/storefront-url/index.js.map +7 -0
- package/dist/server/storefront-url/installation.js +58 -0
- package/dist/server/storefront-url/installation.js.map +7 -0
- package/dist/server/storefront-url/params.js +72 -0
- package/dist/server/storefront-url/params.js.map +7 -0
- package/dist/server/storefront-url/parse-v1.js +135 -0
- package/dist/server/storefront-url/parse-v1.js.map +7 -0
- package/dist/server/storefront-url/parse-v2.js +139 -0
- package/dist/server/storefront-url/parse-v2.js.map +7 -0
- package/dist/server/storefront-url/parse.js +9 -0
- package/dist/server/storefront-url/parse.js.map +7 -0
- package/dist/server/storefront-url/redirect.js +30 -0
- package/dist/server/storefront-url/redirect.js.map +7 -0
- package/dist/server/storefront-url/sign-in.js +17 -0
- package/dist/server/storefront-url/sign-in.js.map +7 -0
- package/dist/server/storefront-url/types.js +55 -0
- package/dist/server/storefront-url/types.js.map +7 -0
- package/dist/server/storefront-url/url.js +61 -0
- package/dist/server/storefront-url/url.js.map +7 -0
- package/dist/server/webhook.js +96 -0
- package/dist/server/webhook.js.map +7 -0
- package/dist/site-config/helpers.js +59 -0
- package/dist/site-config/helpers.js.map +7 -0
- package/dist/site-config/sections.js +105 -0
- package/dist/site-config/sections.js.map +7 -0
- package/dist/site-config/types.js +31 -0
- package/dist/site-config/types.js.map +7 -0
- package/dist/site-config/validate.js +165 -0
- package/dist/site-config/validate.js.map +7 -0
- package/dist/template/index.js +46 -3
- package/dist/template/index.js.map +7 -1
- package/dist/template/react.js +81 -2
- package/dist/template/react.js.map +7 -1
- package/dist/testing/index.js +451 -2
- package/dist/testing/index.js.map +7 -1
- package/dist/transport/category-page.js +21 -2
- package/dist/transport/category-page.js.map +7 -1
- package/dist/transport/mappers.js +326 -0
- package/dist/transport/mappers.js.map +7 -0
- package/dist/transport/rest.js +313 -0
- package/dist/transport/rest.js.map +7 -0
- package/dist/transport/search.js +32 -2
- package/dist/transport/search.js.map +7 -1
- package/dist/transport/selected-menu.js +79 -2
- package/dist/transport/selected-menu.js.map +7 -1
- package/dist/transport/store.js +120 -2
- package/dist/transport/store.js.map +7 -1
- package/dist/transport/types.js +1 -0
- package/dist/transport/types.js.map +7 -0
- package/dist/url/index.js +16 -2
- package/dist/url/index.js.map +7 -1
- package/dist/visits/index.js +62 -1
- package/dist/visits/index.js.map +7 -1
- package/dist/visits/page-views.js +103 -0
- package/dist/visits/page-views.js.map +7 -0
- package/package.json +5 -4
- package/dist/cart/quote.js +0 -1
- package/dist/cart/quote.js.map +0 -1
- package/dist/chunk-I55A5QXJ.js +0 -2
- package/dist/chunk-I55A5QXJ.js.map +0 -1
- package/dist/chunk-VG7NKIKR.js +0 -2
- package/dist/chunk-VG7NKIKR.js.map +0 -1
package/dist/client.js
ADDED
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { createCart } from "./cart/index.js";
|
|
3
|
+
import { createWorkingSet } from "./cart/working-set.js";
|
|
4
|
+
import { API_VERSION, validateConfig } from "./config.js";
|
|
5
|
+
import { ZappieError } from "./errors.js";
|
|
6
|
+
import { Cache } from "./internal/cache.js";
|
|
7
|
+
import { createEmitter } from "./internal/emitter.js";
|
|
8
|
+
import { format } from "./money.js";
|
|
9
|
+
import { RestTransport } from "./transport/rest.js";
|
|
10
|
+
function buildClient(input, secret = false) {
|
|
11
|
+
const mode = validateConfig(input, secret);
|
|
12
|
+
const config = Object.freeze({
|
|
13
|
+
...input,
|
|
14
|
+
version: input.version ?? API_VERSION,
|
|
15
|
+
telemetry: input.telemetry ?? true
|
|
16
|
+
});
|
|
17
|
+
const transport = input.transport ?? new RestTransport({
|
|
18
|
+
...input.baseUrl ? { baseUrl: input.baseUrl } : {},
|
|
19
|
+
...input.fetch ? { fetch: input.fetch } : {}
|
|
20
|
+
});
|
|
21
|
+
const events = createEmitter();
|
|
22
|
+
const cache = new Cache((error) => events.emit("error", { error }));
|
|
23
|
+
const ctx = (signal) => ({
|
|
24
|
+
key: config.key,
|
|
25
|
+
version: config.version,
|
|
26
|
+
...signal ? { signal } : {}
|
|
27
|
+
});
|
|
28
|
+
const store = {
|
|
29
|
+
get: (opts = {}) => cache.get(
|
|
30
|
+
"store",
|
|
31
|
+
async (signal) => ({ value: await transport.getStore(ctx(signal)) }),
|
|
32
|
+
opts.signal
|
|
33
|
+
),
|
|
34
|
+
peek: () => cache.snapshot("store").value
|
|
35
|
+
};
|
|
36
|
+
const resolveBranch = (value, requested) => {
|
|
37
|
+
const selected = requested ?? config.branch;
|
|
38
|
+
const branch = selected ? value.branches.find((b) => b.id === selected || b.slug === selected) : value.branches.find((b) => b.isDefault) ?? value.branches[0];
|
|
39
|
+
if (!branch) {
|
|
40
|
+
throw new ZappieError(
|
|
41
|
+
"branch_not_found",
|
|
42
|
+
"No matching storefront branch",
|
|
43
|
+
{ param: "branch" }
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
return branch;
|
|
47
|
+
};
|
|
48
|
+
let hydratedBranch;
|
|
49
|
+
const branchKey = (requested) => {
|
|
50
|
+
const value = store.peek();
|
|
51
|
+
if (value) {
|
|
52
|
+
return resolveBranch(value, requested).id;
|
|
53
|
+
}
|
|
54
|
+
const selected = requested ?? config.branch;
|
|
55
|
+
if (hydratedBranch && (selected === void 0 || selected === config.branch || selected === hydratedBranch)) {
|
|
56
|
+
return hydratedBranch;
|
|
57
|
+
}
|
|
58
|
+
return selected ?? "default";
|
|
59
|
+
};
|
|
60
|
+
const menuKey = (requested) => `menu:${branchKey(requested)}`;
|
|
61
|
+
const menu = {
|
|
62
|
+
async search(query, opts = {}) {
|
|
63
|
+
if (!transport.search) {
|
|
64
|
+
throw new ZappieError(
|
|
65
|
+
"invalid_request",
|
|
66
|
+
"Transport does not support search"
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
const branch = resolveBranch(await store.get(opts), opts.branch);
|
|
70
|
+
return transport.search({
|
|
71
|
+
...ctx(opts.signal),
|
|
72
|
+
branchId: branch.id,
|
|
73
|
+
query,
|
|
74
|
+
...opts.cursor ? { cursor: opts.cursor } : {}
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
async get(opts = {}) {
|
|
78
|
+
const branch = resolveBranch(await store.get(opts), opts.branch);
|
|
79
|
+
return cache.get(
|
|
80
|
+
`menu:${branch.id}${opts.metadataOnly ? ":partial" : ""}`,
|
|
81
|
+
async (signal, entry) => {
|
|
82
|
+
const response = await transport.getMenu({
|
|
83
|
+
...ctx(signal),
|
|
84
|
+
branchId: branch.id,
|
|
85
|
+
...opts.metadataOnly ? { metadataOnly: true } : {},
|
|
86
|
+
...entry.etag ? { ifNoneMatch: entry.etag } : {}
|
|
87
|
+
});
|
|
88
|
+
if ("notModified" in response) {
|
|
89
|
+
if (!entry.value) {
|
|
90
|
+
throw new ZappieError(
|
|
91
|
+
"server_error",
|
|
92
|
+
"Received 304 without a cached menu"
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
value: entry.value,
|
|
97
|
+
...response.etag ?? entry.etag ? { etag: response.etag ?? entry.etag } : {}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (!opts.metadataOnly && response.menu.completeness === "partial") {
|
|
101
|
+
throw new ZappieError(
|
|
102
|
+
"server_error",
|
|
103
|
+
"Partial catalogue cannot satisfy a complete read"
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
if (response.menu.branchId !== branch.id) {
|
|
107
|
+
throw new ZappieError(
|
|
108
|
+
"server_error",
|
|
109
|
+
"Menu belongs to a different branch"
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
value: response.menu,
|
|
114
|
+
etag: response.etag ?? response.menu.version,
|
|
115
|
+
onStored: () => {
|
|
116
|
+
if (entry.value && entry.value.version !== response.menu.version) {
|
|
117
|
+
events.emit("menu:updated", {
|
|
118
|
+
branchId: branch.id,
|
|
119
|
+
version: response.menu.version
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
},
|
|
125
|
+
opts.signal
|
|
126
|
+
);
|
|
127
|
+
},
|
|
128
|
+
peek: (branch) => cache.snapshot(menuKey(branch)).value ?? cache.snapshot(`${menuKey(branch)}:partial`).value,
|
|
129
|
+
async page(menuId, categoryId, opts = {}) {
|
|
130
|
+
if (!transport.getCategoryPage) {
|
|
131
|
+
throw new ZappieError(
|
|
132
|
+
"invalid_request",
|
|
133
|
+
"Transport does not support category pages"
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
const branch = resolveBranch(await store.get(opts), opts.branch);
|
|
137
|
+
return transport.getCategoryPage({
|
|
138
|
+
...ctx(opts.signal),
|
|
139
|
+
branchId: branch.id,
|
|
140
|
+
menuId,
|
|
141
|
+
categoryId,
|
|
142
|
+
...opts.cursor ? { cursor: opts.cursor } : {}
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
async version(opts = {}) {
|
|
146
|
+
const branch = resolveBranch(await store.get(opts), opts.branch);
|
|
147
|
+
return transport.getMenuVersion({
|
|
148
|
+
...ctx(opts.signal),
|
|
149
|
+
branchId: branch.id
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
async item(id, opts = {}) {
|
|
153
|
+
const branch = resolveBranch(await store.get(opts), opts.branch);
|
|
154
|
+
if (!menu.peek(branch.id) || menu.peek(branch.id)?.completeness === "partial") {
|
|
155
|
+
await menu.get({ ...opts, metadataOnly: true });
|
|
156
|
+
}
|
|
157
|
+
return readItem(id, branch.id, false, opts.signal);
|
|
158
|
+
},
|
|
159
|
+
hydrate(value) {
|
|
160
|
+
hydratedBranch ?? (hydratedBranch = value.branchId);
|
|
161
|
+
const previous = cache.snapshot(`menu:${value.branchId}`).value;
|
|
162
|
+
cache.set(
|
|
163
|
+
`menu:${value.branchId}${value.completeness === "partial" ? ":partial" : ""}`,
|
|
164
|
+
value,
|
|
165
|
+
value.version
|
|
166
|
+
);
|
|
167
|
+
if (previous && previous.version !== value.version) {
|
|
168
|
+
events.emit("menu:updated", {
|
|
169
|
+
branchId: value.branchId,
|
|
170
|
+
version: value.version
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
const itemValues = /* @__PURE__ */ new Map();
|
|
176
|
+
const peekItem = (id, branch) => itemValues.get(`${branch}:${id}`);
|
|
177
|
+
const readItem = async (id, branch, fresh = false, signal) => {
|
|
178
|
+
const complete = cache.snapshot(`menu:${branch}`).value;
|
|
179
|
+
if (!fresh && complete && Object.hasOwn(complete.items, id)) {
|
|
180
|
+
return complete.items[id];
|
|
181
|
+
}
|
|
182
|
+
const load = (requestSignal = signal) => transport.getItem({
|
|
183
|
+
...ctx(requestSignal),
|
|
184
|
+
branchId: branch,
|
|
185
|
+
itemId: id
|
|
186
|
+
});
|
|
187
|
+
try {
|
|
188
|
+
const value = fresh ? await load() : await cache.get(
|
|
189
|
+
`item:${branch}:${id}`,
|
|
190
|
+
async (requestSignal) => ({ value: await load(requestSignal) }),
|
|
191
|
+
signal
|
|
192
|
+
);
|
|
193
|
+
if (fresh) {
|
|
194
|
+
cache.set(`item:${branch}:${id}`, value);
|
|
195
|
+
}
|
|
196
|
+
itemValues.set(`${branch}:${id}`, value);
|
|
197
|
+
return value;
|
|
198
|
+
} catch (error) {
|
|
199
|
+
if (error.code === "item_not_found") {
|
|
200
|
+
itemValues.delete(`${branch}:${id}`);
|
|
201
|
+
cache.set(`item:${branch}:${id}`, void 0);
|
|
202
|
+
}
|
|
203
|
+
throw error;
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
const workingSet = createWorkingSet({
|
|
207
|
+
menu,
|
|
208
|
+
store,
|
|
209
|
+
transport,
|
|
210
|
+
context: ctx,
|
|
211
|
+
peekItem,
|
|
212
|
+
readItem
|
|
213
|
+
});
|
|
214
|
+
const { cart, setLegacyReader, cartCatalogue } = createCart({
|
|
215
|
+
workingSet,
|
|
216
|
+
config,
|
|
217
|
+
menu,
|
|
218
|
+
store,
|
|
219
|
+
transport,
|
|
220
|
+
context: ctx,
|
|
221
|
+
events
|
|
222
|
+
});
|
|
223
|
+
return Object.freeze({
|
|
224
|
+
cart,
|
|
225
|
+
config,
|
|
226
|
+
mode,
|
|
227
|
+
store,
|
|
228
|
+
menu,
|
|
229
|
+
format,
|
|
230
|
+
on: events.on,
|
|
231
|
+
_internal: {
|
|
232
|
+
cartCatalogue,
|
|
233
|
+
setLegacyReader,
|
|
234
|
+
transport,
|
|
235
|
+
cache,
|
|
236
|
+
emit: events.emit,
|
|
237
|
+
menuKey,
|
|
238
|
+
hydrateStore: (value) => cache.set("store", value)
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
function createZappie(config) {
|
|
243
|
+
const client = buildClient(config);
|
|
244
|
+
if (client.mode === "test" && typeof window !== "undefined") {
|
|
245
|
+
void import("./debug.js").then(({ installDebug }) => installDebug(client));
|
|
246
|
+
}
|
|
247
|
+
return client;
|
|
248
|
+
}
|
|
249
|
+
export {
|
|
250
|
+
buildClient,
|
|
251
|
+
createZappie
|
|
252
|
+
};
|
|
253
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/client.ts"],
|
|
4
|
+
"sourcesContent": ["import { createCart } from \"./cart\";\nimport { createWorkingSet } from \"./cart/working-set\";\nimport type { ZappieConfig } from \"./config\";\nimport { API_VERSION, validateConfig } from \"./config\";\nimport { ZappieError } from \"./errors\";\nimport { Cache } from \"./internal/cache\";\nimport type { ZappieEvents } from \"./internal/emitter\";\nimport { createEmitter } from \"./internal/emitter\";\nimport type { Branch, CategoryPage, Item, Menu, Store } from \"./models\";\nimport { format } from \"./money\";\nimport { RestTransport } from \"./transport/rest\";\nimport type { MenuVersion, SearchPage } from \"./transport/types\";\n/** Optional branch selection and cancellation for resource reads. */\nexport type ReadOptions = { branch?: string; signal?: AbortSignal };\n/** Read-only store resource. */\nexport interface StoreResource {\n get(opts?: { signal?: AbortSignal }): Promise<Store>;\n peek(): Store | undefined;\n}\n/** Read-only branch catalogue and item resources. */\nexport interface MenuResource {\n search(\n query: string,\n opts?: ReadOptions & { cursor?: string },\n ): Promise<SearchPage>;\n get(opts?: ReadOptions & { metadataOnly?: boolean }): Promise<Menu>;\n page(\n menuId: string,\n categoryId: string,\n opts?: ReadOptions & { cursor?: string },\n ): Promise<CategoryPage>;\n peek(branch?: string): Menu | undefined;\n version(opts?: ReadOptions): Promise<MenuVersion>;\n item(id: string, opts?: ReadOptions): Promise<Item>;\n hydrate(menu: Menu): void;\n}\n/** A storefront client and its isolated resource state. */\nexport type Zappie = ReturnType<typeof buildClient>;\nexport function buildClient(input: ZappieConfig, secret = false) {\n const mode = validateConfig(input, secret);\n const config = Object.freeze({\n ...input,\n version: input.version ?? API_VERSION,\n telemetry: input.telemetry ?? true,\n });\n const transport =\n input.transport ??\n new RestTransport({\n ...(input.baseUrl ? { baseUrl: input.baseUrl } : {}),\n ...(input.fetch ? { fetch: input.fetch } : {}),\n });\n const events = createEmitter();\n const cache = new Cache((error) => events.emit(\"error\", { error }));\n const ctx = (signal?: AbortSignal) => ({\n key: config.key,\n version: config.version,\n ...(signal ? { signal } : {}),\n });\n const store: StoreResource = {\n get: (opts = {}) =>\n cache.get(\n \"store\",\n async (signal) => ({ value: await transport.getStore(ctx(signal)) }),\n opts.signal,\n ),\n peek: () => cache.snapshot<Store>(\"store\").value,\n };\n const resolveBranch = (value: Store, requested?: string): Branch => {\n const selected = requested ?? config.branch;\n const branch = selected\n ? value.branches.find((b) => b.id === selected || b.slug === selected)\n : (value.branches.find((b) => b.isDefault) ?? value.branches[0]);\n if (!branch) {\n throw new ZappieError(\n \"branch_not_found\",\n \"No matching storefront branch\",\n { param: \"branch\" },\n );\n }\n return branch;\n };\n let hydratedBranch: string | undefined;\n const branchKey = (requested?: string) => {\n const value = store.peek();\n if (value) {\n return resolveBranch(value, requested).id;\n }\n // A slug can't be resolved without the store. A hydrated menu is the configured\n // branch's, so a read for that branch (by slug or id) uses it rather than missing.\n const selected = requested ?? config.branch;\n if (\n hydratedBranch &&\n (selected === undefined ||\n selected === config.branch ||\n selected === hydratedBranch)\n ) {\n return hydratedBranch;\n }\n return selected ?? \"default\";\n };\n const menuKey = (requested?: string) => `menu:${branchKey(requested)}`;\n const menu: MenuResource = {\n async search(query, opts = {}) {\n if (!transport.search) {\n throw new ZappieError(\n \"invalid_request\",\n \"Transport does not support search\",\n );\n }\n const branch = resolveBranch(await store.get(opts), opts.branch);\n return transport.search({\n ...ctx(opts.signal),\n branchId: branch.id,\n query,\n ...(opts.cursor ? { cursor: opts.cursor } : {}),\n });\n },\n async get(opts = {}) {\n const branch = resolveBranch(await store.get(opts), opts.branch);\n return cache.get<Menu>(\n `menu:${branch.id}${opts.metadataOnly ? \":partial\" : \"\"}`,\n async (signal, entry) => {\n const response = await transport.getMenu({\n ...ctx(signal),\n branchId: branch.id,\n ...(opts.metadataOnly ? { metadataOnly: true } : {}),\n ...(entry.etag ? { ifNoneMatch: entry.etag } : {}),\n });\n if (\"notModified\" in response) {\n if (!entry.value) {\n throw new ZappieError(\n \"server_error\",\n \"Received 304 without a cached menu\",\n );\n }\n return {\n value: entry.value,\n ...((response.etag ?? entry.etag)\n ? { etag: response.etag ?? entry.etag }\n : {}),\n };\n }\n if (!opts.metadataOnly && response.menu.completeness === \"partial\") {\n throw new ZappieError(\n \"server_error\",\n \"Partial catalogue cannot satisfy a complete read\",\n );\n }\n if (response.menu.branchId !== branch.id) {\n throw new ZappieError(\n \"server_error\",\n \"Menu belongs to a different branch\",\n );\n }\n return {\n value: response.menu,\n etag: response.etag ?? response.menu.version,\n onStored: () => {\n if (\n entry.value &&\n entry.value.version !== response.menu.version\n ) {\n events.emit(\"menu:updated\", {\n branchId: branch.id,\n version: response.menu.version,\n });\n }\n },\n };\n },\n opts.signal,\n );\n },\n peek: (branch) =>\n cache.snapshot<Menu>(menuKey(branch)).value ??\n cache.snapshot<Menu>(`${menuKey(branch)}:partial`).value,\n async page(menuId, categoryId, opts = {}) {\n if (!transport.getCategoryPage) {\n throw new ZappieError(\n \"invalid_request\",\n \"Transport does not support category pages\",\n );\n }\n const branch = resolveBranch(await store.get(opts), opts.branch);\n return transport.getCategoryPage({\n ...ctx(opts.signal),\n branchId: branch.id,\n menuId,\n categoryId,\n ...(opts.cursor ? { cursor: opts.cursor } : {}),\n });\n },\n async version(opts = {}) {\n const branch = resolveBranch(await store.get(opts), opts.branch);\n return transport.getMenuVersion({\n ...ctx(opts.signal),\n branchId: branch.id,\n });\n },\n async item(id, opts = {}) {\n const branch = resolveBranch(await store.get(opts), opts.branch);\n if (\n !menu.peek(branch.id) ||\n menu.peek(branch.id)?.completeness === \"partial\"\n ) {\n await menu.get({ ...opts, metadataOnly: true });\n }\n return readItem(id, branch.id, false, opts.signal);\n },\n hydrate(value) {\n hydratedBranch ??= value.branchId;\n const previous = cache.snapshot<Menu>(`menu:${value.branchId}`).value;\n cache.set(\n `menu:${value.branchId}${value.completeness === \"partial\" ? \":partial\" : \"\"}`,\n value,\n value.version,\n );\n if (previous && previous.version !== value.version) {\n events.emit(\"menu:updated\", {\n branchId: value.branchId,\n version: value.version,\n });\n }\n },\n };\n const itemValues = new Map<string, Item>();\n const peekItem = (id: string, branch: string) =>\n itemValues.get(`${branch}:${id}`);\n const readItem = async (\n id: string,\n branch: string,\n fresh = false,\n signal?: AbortSignal,\n ) => {\n const complete = cache.snapshot<Menu>(`menu:${branch}`).value;\n if (!fresh && complete && Object.hasOwn(complete.items, id)) {\n return complete.items[id]!;\n }\n const load = (requestSignal = signal) =>\n transport.getItem({\n ...ctx(requestSignal),\n branchId: branch,\n itemId: id,\n });\n try {\n const value = fresh\n ? await load()\n : await cache.get(\n `item:${branch}:${id}`,\n async (requestSignal) => ({ value: await load(requestSignal) }),\n signal,\n );\n if (fresh) {\n cache.set(`item:${branch}:${id}`, value);\n }\n itemValues.set(`${branch}:${id}`, value);\n return value;\n } catch (error) {\n if ((error as { code?: string }).code === \"item_not_found\") {\n itemValues.delete(`${branch}:${id}`);\n cache.set(`item:${branch}:${id}`, undefined);\n }\n throw error;\n }\n };\n const workingSet = createWorkingSet({\n menu,\n store,\n transport,\n context: ctx,\n peekItem,\n readItem,\n });\n const { cart, setLegacyReader, cartCatalogue } = createCart({\n workingSet,\n config,\n menu,\n store,\n transport,\n context: ctx,\n events,\n });\n return Object.freeze({\n cart,\n config,\n mode,\n store,\n menu,\n format,\n on: events.on,\n _internal: {\n cartCatalogue,\n setLegacyReader,\n transport,\n cache,\n emit: events.emit,\n menuKey,\n hydrateStore: (value: Store) => cache.set(\"store\", value),\n },\n });\n}\n/** Create a client with your publishable key. Requests start when you read a resource. */\nexport function createZappie(config: ZappieConfig) {\n const client = buildClient(config);\n if (client.mode === \"test\" && typeof window !== \"undefined\") {\n void import(\"./debug\").then(({ installDebug }) => installDebug(client));\n }\n return client;\n}\nexport type { ZappieEvents };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/config/index.js
CHANGED
|
@@ -1 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
// src/site-config/index.ts
|
|
2
|
+
import { DEFAULT_BUDGETS, GLOBAL_PACKAGE_ALLOWLIST } from "../site-config/types.js";
|
|
3
|
+
import { validateConfig } from "../site-config/validate.js";
|
|
4
|
+
function defineConfig(config) {
|
|
5
|
+
return config;
|
|
6
|
+
}
|
|
7
|
+
export {
|
|
8
|
+
DEFAULT_BUDGETS,
|
|
9
|
+
GLOBAL_PACKAGE_ALLOWLIST,
|
|
10
|
+
defineConfig,
|
|
11
|
+
validateConfig
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/site-config/index.ts"],
|
|
4
|
+
"sourcesContent": ["import type { ZappieSiteConfig } from \"./types\";\n\n/**\n * Return your site configuration unchanged with TypeScript checking.\n * Use validateConfig to check values at runtime.\n *\n * @example\n * ```ts\n * export default defineConfig({ store: \"my-store\", theme: \"./theme.json\" });\n * ```\n */\nexport function defineConfig(config: ZappieSiteConfig): ZappieSiteConfig {\n return config;\n}\n\nexport { DEFAULT_BUDGETS, GLOBAL_PACKAGE_ALLOWLIST } from \"./types\";\nexport type { ConfigIssue, ConfigValidation, ZappieSiteConfig } from \"./types\";\nexport { validateConfig } from \"./validate\";\n"],
|
|
5
|
+
"mappings": ";AAeA,SAAS,iBAAiB,gCAAgC;AAE1D,SAAS,sBAAsB;AANxB,SAAS,aAAa,QAA4C;AACvE,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// src/config.ts
|
|
2
|
+
import { ZappieError } from "./errors.js";
|
|
3
|
+
var API_VERSION = "2026-10-01";
|
|
4
|
+
function validateConfig(config, secret = false) {
|
|
5
|
+
if (!config.store?.trim()) {
|
|
6
|
+
throw new ZappieError("invalid_request", "A storefront slug is required");
|
|
7
|
+
}
|
|
8
|
+
if (secret && typeof window !== "undefined") {
|
|
9
|
+
throw new ZappieError(
|
|
10
|
+
"invalid_request",
|
|
11
|
+
"Secret keys cannot be used in a browser"
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
const pattern = secret ? /^sk_(test|live)_.+$/ : /^pk_(test|live)_.+$/;
|
|
15
|
+
const match = pattern.exec(config.key);
|
|
16
|
+
if (!match) {
|
|
17
|
+
throw new ZappieError(
|
|
18
|
+
"invalid_request",
|
|
19
|
+
secret ? "A secret sk_test_ or sk_live_ key is required" : "Use a publishable pk_test_ or pk_live_ key; secret keys are never accepted by createZappie"
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
return match[1];
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
API_VERSION,
|
|
26
|
+
validateConfig
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/config.ts"],
|
|
4
|
+
"sourcesContent": ["import { ZappieError } from \"./errors\";\nimport type { Transport } from \"./transport/types\";\n/** Release-pinned REST contract version, independent of the package version. */\nexport const API_VERSION = \"2026-10-01\";\n/** A storage adapter you can supply to save carts. */\nexport interface StorageLike {\n getItem(key: string): string | null;\n setItem(key: string, value: string): void;\n removeItem(key: string): void;\n /** Provide length and key to let the SDK remove expired carts for this store. */\n readonly length?: number;\n key?(index: number): string | null;\n}\n/** Settings for your storefront client. Each client keeps its own credentials and caches. */\nexport type ZappieConfig = {\n store: string;\n key: string;\n branch?: string;\n transport?: Transport;\n baseUrl?: string;\n version?: string;\n fetch?: typeof fetch;\n storage?: StorageLike;\n telemetry?: boolean;\n cart?: { ttl?: number; storageScope?: string };\n};\nexport function validateConfig(config: ZappieConfig, secret = false) {\n if (!config.store?.trim()) {\n throw new ZappieError(\"invalid_request\", \"A storefront slug is required\");\n }\n if (secret && typeof window !== \"undefined\") {\n throw new ZappieError(\n \"invalid_request\",\n \"Secret keys cannot be used in a browser\",\n );\n }\n const pattern = secret ? /^sk_(test|live)_.+$/ : /^pk_(test|live)_.+$/;\n const match = pattern.exec(config.key);\n if (!match) {\n throw new ZappieError(\n \"invalid_request\",\n secret\n ? \"A secret sk_test_ or sk_live_ key is required\"\n : \"Use a publishable pk_test_ or pk_live_ key; secret keys are never accepted by createZappie\",\n );\n }\n return match[1] as \"test\" | \"live\";\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAS,mBAAmB;AAGrB,IAAM,cAAc;AAuBpB,SAAS,eAAe,QAAsB,SAAS,OAAO;AACnE,MAAI,CAAC,OAAO,OAAO,KAAK,GAAG;AACzB,UAAM,IAAI,YAAY,mBAAmB,+BAA+B;AAAA,EAC1E;AACA,MAAI,UAAU,OAAO,WAAW,aAAa;AAC3C,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACA,QAAM,UAAU,SAAS,wBAAwB;AACjD,QAAM,QAAQ,QAAQ,KAAK,OAAO,GAAG;AACrC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR;AAAA,MACA,SACI,kDACA;AAAA,IACN;AAAA,EACF;AACA,SAAO,MAAM,CAAC;AAChB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// src/customer/client.ts
|
|
2
|
+
import { apiError, requestWithRetry } from "../internal/customer-http.js";
|
|
3
|
+
import { CustomerError } from "./error.js";
|
|
4
|
+
import { currentPath, safeReturnTo, signIn, signOut } from "./navigation.js";
|
|
5
|
+
import { createCustomerRequest } from "./request.js";
|
|
6
|
+
import { watchOrder } from "./watch-order.js";
|
|
7
|
+
var DEFAULT_CUSTOMER_BASE = "/_zappie/api";
|
|
8
|
+
var DEFAULT_SESSION_PATH = "/_zappie/session";
|
|
9
|
+
function same(left, right) {
|
|
10
|
+
return left?.id === right?.id && left?.given_name === right?.given_name && left?.phone_masked === right?.phone_masked;
|
|
11
|
+
}
|
|
12
|
+
function createCustomer(options = {}) {
|
|
13
|
+
const base = (options.customerBase ?? DEFAULT_CUSTOMER_BASE).replace(
|
|
14
|
+
/\/+$/,
|
|
15
|
+
""
|
|
16
|
+
);
|
|
17
|
+
const sessionPath = options.sessionPath ?? DEFAULT_SESSION_PATH;
|
|
18
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
19
|
+
let customer = options.initialCustomer ?? null;
|
|
20
|
+
let state = options.initialCustomer === void 0 ? "unknown" : customer ? "authenticated" : "anonymous";
|
|
21
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
22
|
+
const update = (next, nextState) => {
|
|
23
|
+
if (state === nextState && same(customer, next)) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
state = nextState;
|
|
27
|
+
customer = next;
|
|
28
|
+
globalThis.__zappieEmit?.("auth:changed", { state, customer });
|
|
29
|
+
for (const listener of listeners) {
|
|
30
|
+
listener(state, customer);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
const request = createCustomerRequest(base, fetcher, () => {
|
|
34
|
+
update(null, "anonymous");
|
|
35
|
+
});
|
|
36
|
+
const readOrder = (id, signal) => request(`/me/orders/${encodeURIComponent(id)}`, {
|
|
37
|
+
method: "GET",
|
|
38
|
+
...signal ? { signal } : {}
|
|
39
|
+
});
|
|
40
|
+
let pending;
|
|
41
|
+
const check = async () => {
|
|
42
|
+
const response = await requestWithRetry(
|
|
43
|
+
fetcher,
|
|
44
|
+
sessionPath,
|
|
45
|
+
{ method: "GET", cache: "no-store" },
|
|
46
|
+
"Could not check the customer session"
|
|
47
|
+
);
|
|
48
|
+
if (!response.ok) {
|
|
49
|
+
const value = await apiError(
|
|
50
|
+
response,
|
|
51
|
+
`The session service answered ${response.status}`
|
|
52
|
+
);
|
|
53
|
+
throw new CustomerError(
|
|
54
|
+
response.status,
|
|
55
|
+
value.apiCode,
|
|
56
|
+
value.message,
|
|
57
|
+
value.param,
|
|
58
|
+
value.issues
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
const body = await response.json();
|
|
62
|
+
const next = body.customer ?? null;
|
|
63
|
+
update(next, next ? "authenticated" : "anonymous");
|
|
64
|
+
return next;
|
|
65
|
+
};
|
|
66
|
+
const refresh = () => {
|
|
67
|
+
pending ?? (pending = check().finally(() => {
|
|
68
|
+
pending = void 0;
|
|
69
|
+
}));
|
|
70
|
+
return pending;
|
|
71
|
+
};
|
|
72
|
+
const recheck = () => {
|
|
73
|
+
if (typeof document === "undefined" || document.visibilityState === "visible") {
|
|
74
|
+
void refresh().catch(() => void 0);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
if (typeof document !== "undefined") {
|
|
78
|
+
document.addEventListener("visibilitychange", recheck);
|
|
79
|
+
}
|
|
80
|
+
if (typeof window !== "undefined") {
|
|
81
|
+
window.addEventListener("pageshow", recheck);
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
get state() {
|
|
85
|
+
return state;
|
|
86
|
+
},
|
|
87
|
+
get customer() {
|
|
88
|
+
return customer;
|
|
89
|
+
},
|
|
90
|
+
session: refresh,
|
|
91
|
+
/** Stops the visibility and back/forward-cache re-checks and drops listeners. */
|
|
92
|
+
dispose() {
|
|
93
|
+
if (typeof document !== "undefined") {
|
|
94
|
+
document.removeEventListener("visibilitychange", recheck);
|
|
95
|
+
}
|
|
96
|
+
if (typeof window !== "undefined") {
|
|
97
|
+
window.removeEventListener("pageshow", recheck);
|
|
98
|
+
}
|
|
99
|
+
listeners.clear();
|
|
100
|
+
},
|
|
101
|
+
onChange(listener) {
|
|
102
|
+
listeners.add(listener);
|
|
103
|
+
return () => {
|
|
104
|
+
listeners.delete(listener);
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
signIn(returnTo) {
|
|
108
|
+
signIn(safeReturnTo(returnTo ?? currentPath()));
|
|
109
|
+
},
|
|
110
|
+
signOut() {
|
|
111
|
+
signOut("/_zappie/logout");
|
|
112
|
+
},
|
|
113
|
+
profile: () => request("/me", { method: "GET" }),
|
|
114
|
+
async addresses() {
|
|
115
|
+
const result = await request(
|
|
116
|
+
"/me/addresses",
|
|
117
|
+
{ method: "GET" }
|
|
118
|
+
);
|
|
119
|
+
return result.addresses;
|
|
120
|
+
},
|
|
121
|
+
addAddress: (body) => request("/me/addresses", {
|
|
122
|
+
method: "POST",
|
|
123
|
+
headers: { "Content-Type": "application/json" },
|
|
124
|
+
body: JSON.stringify(body)
|
|
125
|
+
}),
|
|
126
|
+
removeAddress: (id) => request(`/me/addresses/${encodeURIComponent(id)}`, {
|
|
127
|
+
method: "DELETE"
|
|
128
|
+
}),
|
|
129
|
+
orders(options2 = {}) {
|
|
130
|
+
const query = new URLSearchParams();
|
|
131
|
+
if (options2.limit !== void 0) {
|
|
132
|
+
query.set("limit", String(options2.limit));
|
|
133
|
+
}
|
|
134
|
+
if (options2.cursor !== void 0) {
|
|
135
|
+
query.set("cursor", options2.cursor);
|
|
136
|
+
}
|
|
137
|
+
const suffix = query.size > 0 ? `?${query}` : "";
|
|
138
|
+
return request(`/me/orders${suffix}`, { method: "GET" });
|
|
139
|
+
},
|
|
140
|
+
order: (id) => readOrder(id),
|
|
141
|
+
watchOrder(id, watchOptions) {
|
|
142
|
+
return watchOrder(base, id, readOrder, watchOptions);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
export {
|
|
147
|
+
createCustomer
|
|
148
|
+
};
|
|
149
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/customer/client.ts"],
|
|
4
|
+
"sourcesContent": ["import { apiError, requestWithRetry } from \"../internal/customer-http\";\nimport { CustomerError } from \"./error\";\nimport { currentPath, safeReturnTo, signIn, signOut } from \"./navigation\";\nimport { createCustomerRequest } from \"./request\";\nimport type {\n AuthState,\n CreateAddress,\n CustomerClientOptions,\n CustomerListener,\n CustomerOrder,\n CustomerProfile,\n OrdersPage,\n SavedAddress,\n SessionCustomer,\n WatchOrderOptions,\n} from \"./types\";\nimport { watchOrder } from \"./watch-order\";\n\nconst DEFAULT_CUSTOMER_BASE = \"/_zappie/api\";\nconst DEFAULT_SESSION_PATH = \"/_zappie/session\";\n\nfunction same(\n left: SessionCustomer | null,\n right: SessionCustomer | null,\n): boolean {\n return (\n left?.id === right?.id &&\n left?.given_name === right?.given_name &&\n left?.phone_masked === right?.phone_masked\n );\n}\n\n/**\n * Create a client for customer sessions, saved addresses and orders.\n * Browser visibility and pageshow events refresh the session. Call dispose when you stop using the client.\n *\n * @param options - Endpoint overrides, fetch implementation and optional initial customer.\n * @returns A customer client with session subscriptions and sign-in and sign-out navigation.\n */\nexport function createCustomer(options: CustomerClientOptions = {}) {\n const base = (options.customerBase ?? DEFAULT_CUSTOMER_BASE).replace(\n /\\/+$/,\n \"\",\n );\n const sessionPath = options.sessionPath ?? DEFAULT_SESSION_PATH;\n const fetcher = options.fetch ?? globalThis.fetch;\n let customer = options.initialCustomer ?? null;\n let state: AuthState =\n options.initialCustomer === undefined\n ? \"unknown\"\n : customer\n ? \"authenticated\"\n : \"anonymous\";\n const listeners = new Set<CustomerListener>();\n const update = (next: SessionCustomer | null, nextState: AuthState) => {\n if (state === nextState && same(customer, next)) {\n return;\n }\n state = nextState;\n customer = next;\n globalThis.__zappieEmit?.(\"auth:changed\", { state, customer });\n for (const listener of listeners) {\n listener(state, customer);\n }\n };\n const request = createCustomerRequest(base, fetcher, () => {\n update(null, \"anonymous\");\n });\n const readOrder = (id: string, signal?: AbortSignal) =>\n request<CustomerOrder>(`/me/orders/${encodeURIComponent(id)}`, {\n method: \"GET\",\n ...(signal ? { signal } : {}),\n });\n let pending: Promise<SessionCustomer | null> | undefined;\n const check = async (): Promise<SessionCustomer | null> => {\n const response = await requestWithRetry(\n fetcher,\n sessionPath,\n { method: \"GET\", cache: \"no-store\" },\n \"Could not check the customer session\",\n );\n if (!response.ok) {\n const value = await apiError(\n response,\n `The session service answered ${response.status}`,\n );\n throw new CustomerError(\n response.status,\n value.apiCode,\n value.message,\n value.param,\n value.issues,\n );\n }\n const body = (await response.json()) as {\n customer?: SessionCustomer | null;\n };\n const next = body.customer ?? null;\n update(next, next ? \"authenticated\" : \"anonymous\");\n return next;\n };\n // Overlapping checks share one request, so a slower stale answer can't land last.\n const refresh = (): Promise<SessionCustomer | null> => {\n pending ??= check().finally(() => {\n pending = undefined;\n });\n return pending;\n };\n const recheck = () => {\n if (\n typeof document === \"undefined\" ||\n document.visibilityState === \"visible\"\n ) {\n void refresh().catch(() => undefined);\n }\n };\n if (typeof document !== \"undefined\") {\n document.addEventListener(\"visibilitychange\", recheck);\n }\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"pageshow\", recheck);\n }\n return {\n get state() {\n return state;\n },\n get customer() {\n return customer;\n },\n session: refresh,\n /** Stops the visibility and back/forward-cache re-checks and drops listeners. */\n dispose() {\n if (typeof document !== \"undefined\") {\n document.removeEventListener(\"visibilitychange\", recheck);\n }\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"pageshow\", recheck);\n }\n listeners.clear();\n },\n onChange(listener: CustomerListener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n signIn(returnTo?: string) {\n signIn(safeReturnTo(returnTo ?? currentPath()));\n },\n signOut() {\n signOut(\"/_zappie/logout\");\n },\n profile: () => request<CustomerProfile>(\"/me\", { method: \"GET\" }),\n async addresses() {\n const result = await request<{ addresses: SavedAddress[] }>(\n \"/me/addresses\",\n { method: \"GET\" },\n );\n return result.addresses;\n },\n addAddress: (body: CreateAddress) =>\n request<SavedAddress>(\"/me/addresses\", {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n }),\n removeAddress: (id: string) =>\n request<void>(`/me/addresses/${encodeURIComponent(id)}`, {\n method: \"DELETE\",\n }),\n orders(options: { cursor?: string; limit?: number } = {}) {\n const query = new URLSearchParams();\n if (options.limit !== undefined) {\n query.set(\"limit\", String(options.limit));\n }\n if (options.cursor !== undefined) {\n query.set(\"cursor\", options.cursor);\n }\n const suffix = query.size > 0 ? `?${query}` : \"\";\n return request<OrdersPage>(`/me/orders${suffix}`, { method: \"GET\" });\n },\n order: (id: string) => readOrder(id),\n watchOrder(id: string, watchOptions: WatchOrderOptions) {\n return watchOrder(base, id, readOrder, watchOptions);\n },\n };\n}\n\n/**\n * The session, profile, address and order operations returned by createCustomer.\n */\nexport type CustomerClient = ReturnType<typeof createCustomer>;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["options"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// src/customer/error.ts
|
|
2
|
+
import { stableErrorCode } from "../internal/customer-http.js";
|
|
3
|
+
import { ZappieError } from "./sdk.js";
|
|
4
|
+
var CustomerError = class extends ZappieError {
|
|
5
|
+
constructor(status, apiCode, message, param, issues) {
|
|
6
|
+
super(stableErrorCode(status), message, {
|
|
7
|
+
status,
|
|
8
|
+
retryable: status === 429 || status >= 500,
|
|
9
|
+
...param !== void 0 ? { param } : {}
|
|
10
|
+
});
|
|
11
|
+
this.apiCode = apiCode;
|
|
12
|
+
if (issues !== void 0) {
|
|
13
|
+
this.issues = issues;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
export {
|
|
18
|
+
CustomerError
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/customer/error.ts"],
|
|
4
|
+
"sourcesContent": ["import { stableErrorCode } from \"../internal/customer-http\";\nimport { ZappieError } from \"./sdk\";\n\n/**\n * A customer API failure with its HTTP status, API code and optional validation issues.\n * Statuses 429 and 5xx are marked retryable.\n */\nexport class CustomerError extends ZappieError {\n readonly issues?: unknown;\n\n constructor(\n status: number,\n readonly apiCode: string,\n message: string,\n param?: string,\n issues?: unknown,\n ) {\n super(stableErrorCode(status), message, {\n status,\n retryable: status === 429 || status >= 500,\n ...(param !== undefined ? { param } : {}),\n });\n if (issues !== undefined) {\n this.issues = issues;\n }\n }\n}\n"],
|
|
5
|
+
"mappings": ";AAAA,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAMrB,IAAM,gBAAN,cAA4B,YAAY;AAAA,EAG7C,YACE,QACS,SACT,SACA,OACA,QACA;AACA,UAAM,gBAAgB,MAAM,GAAG,SAAS;AAAA,MACtC;AAAA,MACA,WAAW,WAAW,OAAO,UAAU;AAAA,MACvC,GAAI,UAAU,SAAY,EAAE,MAAM,IAAI,CAAC;AAAA,IACzC,CAAC;AATQ;AAUT,QAAI,WAAW,QAAW;AACxB,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/customer/index.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// src/customer/index.ts
|
|
2
|
+
import { createCustomer } from "./client.js";
|
|
3
|
+
import { CustomerError } from "./error.js";
|
|
4
|
+
export {
|
|
5
|
+
CustomerError,
|
|
6
|
+
createCustomer
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=index.js.map
|