@01.software/sdk 0.29.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +331 -77
- package/dist/analytics/react.cjs +4 -1
- package/dist/analytics/react.cjs.map +1 -1
- package/dist/analytics/react.js +4 -1
- package/dist/analytics/react.js.map +1 -1
- package/dist/analytics.cjs +4 -1
- package/dist/analytics.cjs.map +1 -1
- package/dist/analytics.js +4 -1
- package/dist/analytics.js.map +1 -1
- package/dist/client.cjs +1541 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +28 -0
- package/dist/client.d.ts +28 -0
- package/dist/client.js +1518 -0
- package/dist/client.js.map +1 -0
- package/dist/collection-client-ByzY3hWK.d.ts +218 -0
- package/dist/collection-client-DFXXz0vk.d.cts +218 -0
- package/dist/{const-DAjQYNuM.d.ts → const-AytzliEu.d.cts} +5 -7
- package/dist/{const-Dsixdi6z.d.cts → const-BGCP-OJL.d.ts} +5 -7
- package/dist/index-BGEhoDUs.d.cts +106 -0
- package/dist/index-BGEhoDUs.d.ts +106 -0
- package/dist/index.cjs +1006 -1615
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -115
- package/dist/index.d.ts +11 -115
- package/dist/index.js +932 -1559
- package/dist/index.js.map +1 -1
- package/dist/metadata.cjs +91 -0
- package/dist/metadata.cjs.map +1 -0
- package/dist/metadata.d.cts +58 -0
- package/dist/metadata.d.ts +58 -0
- package/dist/metadata.js +68 -0
- package/dist/metadata.js.map +1 -0
- package/dist/{payload-types-Ci-ZA7aM.d.cts → payload-types-Wa4-eC6x.d.cts} +794 -532
- package/dist/{payload-types-Ci-ZA7aM.d.ts → payload-types-Wa4-eC6x.d.ts} +794 -532
- package/dist/query.cjs +1841 -0
- package/dist/query.cjs.map +1 -0
- package/dist/query.d.cts +244 -0
- package/dist/query.d.ts +244 -0
- package/dist/query.js +1836 -0
- package/dist/query.js.map +1 -0
- package/dist/realtime.cjs +4 -1
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/realtime.js +4 -1
- package/dist/realtime.js.map +1 -1
- package/dist/{server-BINWywT8.d.cts → server-CrsPyqEc.d.cts} +14 -31
- package/dist/{server-BINWywT8.d.ts → server-CrsPyqEc.d.ts} +14 -31
- package/dist/server.cjs +430 -846
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +137 -7
- package/dist/server.d.ts +137 -7
- package/dist/server.js +430 -864
- package/dist/server.js.map +1 -1
- package/dist/{server-Cv0Q4dPQ.d.ts → types-BX2mqDf6.d.ts} +270 -743
- package/dist/{types-BWq_WlbB.d.ts → types-CVA10VC-.d.ts} +6 -2
- package/dist/{types-zKjATmDK.d.cts → types-CmLG-7RL.d.cts} +6 -2
- package/dist/{server-C0C8dtms.d.cts → types-DChFjQGz.d.cts} +270 -743
- package/dist/ui/canvas/server.cjs +7 -6
- package/dist/ui/canvas/server.cjs.map +1 -1
- package/dist/ui/canvas/server.d.cts +1 -3
- package/dist/ui/canvas/server.d.ts +1 -3
- package/dist/ui/canvas/server.js +7 -6
- package/dist/ui/canvas/server.js.map +1 -1
- package/dist/ui/canvas.cjs +11 -10
- package/dist/ui/canvas.cjs.map +1 -1
- package/dist/ui/canvas.d.cts +29 -6
- package/dist/ui/canvas.d.ts +29 -6
- package/dist/ui/canvas.js +11 -10
- package/dist/ui/canvas.js.map +1 -1
- package/dist/ui/form.d.cts +1 -1
- package/dist/ui/form.d.ts +1 -1
- package/dist/ui/video.d.cts +1 -1
- package/dist/ui/video.d.ts +1 -1
- package/dist/webhook.d.cts +3 -3
- package/dist/webhook.d.ts +3 -3
- package/package.json +84 -15
package/dist/index.cjs
CHANGED
|
@@ -26,61 +26,48 @@ __export(src_exports, {
|
|
|
26
26
|
COLLECTIONS: () => COLLECTIONS,
|
|
27
27
|
CUSTOMER_PASSWORD_RESET_OPERATION: () => CUSTOMER_PASSWORD_RESET_OPERATION,
|
|
28
28
|
CartApi: () => CartApi,
|
|
29
|
-
Client: () => Client,
|
|
30
|
-
CollectionClient: () => CollectionClient,
|
|
31
|
-
CollectionHooks: () => CollectionHooks,
|
|
32
|
-
CollectionQueryBuilder: () => CollectionQueryBuilder,
|
|
33
29
|
CommerceClient: () => CommerceClient,
|
|
34
30
|
CommunityClient: () => CommunityClient,
|
|
35
31
|
ConfigError: () => ConfigError,
|
|
36
32
|
ConflictError: () => ConflictError,
|
|
37
33
|
CustomerAuth: () => CustomerAuth,
|
|
38
|
-
CustomerHooks: () => CustomerHooks,
|
|
39
34
|
CustomerNamespace: () => CustomerNamespace,
|
|
40
35
|
DiscountApi: () => DiscountApi,
|
|
41
36
|
GoneError: () => GoneError,
|
|
42
37
|
IMAGE_SIZES: () => IMAGE_SIZES,
|
|
43
38
|
INTERNAL_COLLECTIONS: () => INTERNAL_COLLECTIONS,
|
|
44
|
-
ModerationApi: () => ModerationApi,
|
|
45
39
|
NetworkError: () => NetworkError,
|
|
46
40
|
NotFoundError: () => NotFoundError,
|
|
47
41
|
OrderApi: () => OrderApi,
|
|
48
42
|
PermissionError: () => PermissionError,
|
|
49
43
|
ProductApi: () => ProductApi,
|
|
50
44
|
ProductSelectionCodecError: () => ProductSelectionCodecError,
|
|
51
|
-
QueryHooks: () => QueryHooks,
|
|
52
45
|
RateLimitError: () => RateLimitError,
|
|
53
|
-
ReadOnlyCollectionClient: () => ReadOnlyCollectionClient,
|
|
54
46
|
RealtimeConnection: () => RealtimeConnection,
|
|
55
47
|
SDKError: () => SDKError,
|
|
56
48
|
SERVER_COLLECTIONS: () => SERVER_COLLECTIONS,
|
|
57
49
|
SERVER_ONLY_COLLECTIONS: () => SERVER_ONLY_COLLECTIONS,
|
|
58
|
-
ServerClient: () => ServerClient,
|
|
59
|
-
ServerCollectionClient: () => ServerCollectionClient,
|
|
60
|
-
ServerCollectionQueryBuilder: () => ServerCollectionQueryBuilder,
|
|
61
|
-
ServerCommerceClient: () => ServerCommerceClient,
|
|
62
50
|
ServiceUnavailableError: () => ServiceUnavailableError,
|
|
63
51
|
ShippingApi: () => ShippingApi,
|
|
64
52
|
TimeoutError: () => TimeoutError,
|
|
65
53
|
UsageLimitError: () => UsageLimitError,
|
|
66
54
|
ValidationError: () => ValidationError,
|
|
55
|
+
buildProductHref: () => buildProductHref,
|
|
56
|
+
buildProductListingCard: () => buildProductListingCard,
|
|
67
57
|
buildProductListingGroupsByOption: () => buildProductListingGroupsByOption,
|
|
68
58
|
buildProductListingProjection: () => buildProductListingProjection,
|
|
69
59
|
buildProductOptionMatrix: () => buildProductOptionMatrix,
|
|
70
60
|
buildProductOptionMatrixFromDetail: () => buildProductOptionMatrixFromDetail,
|
|
71
|
-
collectionKeys: () => collectionKeys,
|
|
72
61
|
createAnalytics: () => createAnalytics,
|
|
73
62
|
createAuthError: () => createAuthError,
|
|
74
|
-
createClient: () =>
|
|
63
|
+
createClient: () => createClient2,
|
|
75
64
|
createConflictError: () => createConflictError,
|
|
76
65
|
createCustomerAuthWebhookHandler: () => createCustomerAuthWebhookHandler,
|
|
77
66
|
createNotFoundError: () => createNotFoundError,
|
|
78
67
|
createPermissionError: () => createPermissionError,
|
|
79
68
|
createProductSelectionCodec: () => createProductSelectionCodec,
|
|
80
69
|
createRateLimitError: () => createRateLimitError,
|
|
81
|
-
createServerClient: () => createServerClient,
|
|
82
70
|
createTypedWebhookHandler: () => createTypedWebhookHandler,
|
|
83
|
-
customerKeys: () => customerKeys,
|
|
84
71
|
formatOrderName: () => formatOrderName,
|
|
85
72
|
generateOrderNumber: () => generateOrderNumber,
|
|
86
73
|
getAvailableOptionValues: () => getAvailableOptionValues,
|
|
@@ -89,7 +76,7 @@ __export(src_exports, {
|
|
|
89
76
|
getImagePlaceholderStyle: () => getImagePlaceholderStyle,
|
|
90
77
|
getImageSrcSet: () => getImageSrcSet,
|
|
91
78
|
getImageUrl: () => getImageUrl,
|
|
92
|
-
|
|
79
|
+
getProductSelectionImages: () => getProductSelectionImages,
|
|
93
80
|
getSelectedValueByOptionId: () => getSelectedValueByOptionId,
|
|
94
81
|
getVideoGif: () => getVideoGif,
|
|
95
82
|
getVideoMp4Url: () => getVideoMp4Url,
|
|
@@ -114,255 +101,17 @@ __export(src_exports, {
|
|
|
114
101
|
isValidWebhookEvent: () => isValidWebhookEvent,
|
|
115
102
|
isValidationError: () => isValidationError,
|
|
116
103
|
normalizeProductSelection: () => normalizeProductSelection,
|
|
104
|
+
normalizeProductSelectionFromMatrix: () => normalizeProductSelectionFromMatrix,
|
|
117
105
|
normalizeSelectedValueIds: () => normalizeSelectedValueIds,
|
|
118
106
|
parseProductSelection: () => parseProductSelection,
|
|
119
|
-
productKeys: () => productKeys,
|
|
120
107
|
resolveProductSelection: () => resolveProductSelection,
|
|
108
|
+
resolveProductSelectionFromMatrix: () => resolveProductSelectionFromMatrix,
|
|
121
109
|
resolveRelation: () => resolveRelation,
|
|
122
110
|
resolveVariantForSelection: () => resolveVariantForSelection,
|
|
123
111
|
stringifyProductSelection: () => stringifyProductSelection
|
|
124
112
|
});
|
|
125
113
|
module.exports = __toCommonJS(src_exports);
|
|
126
114
|
|
|
127
|
-
// src/utils/types.ts
|
|
128
|
-
var resolveRelation = (ref) => {
|
|
129
|
-
if (typeof ref === "string" || typeof ref === "number" || ref === null || ref === void 0)
|
|
130
|
-
return null;
|
|
131
|
-
return ref;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
// src/core/metadata/index.ts
|
|
135
|
-
function extractSeo(doc) {
|
|
136
|
-
const seo = doc.seo ?? {};
|
|
137
|
-
const og = seo.openGraph ?? {};
|
|
138
|
-
return {
|
|
139
|
-
title: seo.title ?? doc.title ?? null,
|
|
140
|
-
description: seo.description ?? null,
|
|
141
|
-
noIndex: seo.noIndex ?? null,
|
|
142
|
-
canonical: seo.canonical ?? null,
|
|
143
|
-
openGraph: {
|
|
144
|
-
title: og.title ?? null,
|
|
145
|
-
description: og.description ?? null,
|
|
146
|
-
image: og.image ?? null
|
|
147
|
-
}
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
function generateMetadata(input, options) {
|
|
151
|
-
const title = input.title ?? void 0;
|
|
152
|
-
const description = input.description ?? void 0;
|
|
153
|
-
const ogTitle = input.openGraph?.title ?? title;
|
|
154
|
-
const ogDescription = input.openGraph?.description ?? description;
|
|
155
|
-
const image = resolveMetaImage(input.openGraph?.image);
|
|
156
|
-
return {
|
|
157
|
-
title,
|
|
158
|
-
description,
|
|
159
|
-
...input.noIndex && { robots: { index: false, follow: false } },
|
|
160
|
-
...input.canonical && { alternates: { canonical: input.canonical } },
|
|
161
|
-
openGraph: {
|
|
162
|
-
...ogTitle && { title: ogTitle },
|
|
163
|
-
...ogDescription && { description: ogDescription },
|
|
164
|
-
...options?.siteName && { siteName: options.siteName },
|
|
165
|
-
...image && { images: [image] }
|
|
166
|
-
},
|
|
167
|
-
twitter: {
|
|
168
|
-
card: image ? "summary_large_image" : "summary",
|
|
169
|
-
...ogTitle && { title: ogTitle },
|
|
170
|
-
...ogDescription && { description: ogDescription },
|
|
171
|
-
...image && { images: [image.url] }
|
|
172
|
-
}
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
function resolveMetaImage(ref) {
|
|
176
|
-
const image = resolveRelation(ref);
|
|
177
|
-
if (!image) return null;
|
|
178
|
-
const sized = image.sizes?.["1536"];
|
|
179
|
-
const url = sized?.url || image.url;
|
|
180
|
-
if (!url) return null;
|
|
181
|
-
const width = sized?.url ? sized.width : image.width;
|
|
182
|
-
const height = sized?.url ? sized.height : image.height;
|
|
183
|
-
return {
|
|
184
|
-
url,
|
|
185
|
-
...width && { width },
|
|
186
|
-
...height && { height },
|
|
187
|
-
...image.alt && { alt: image.alt }
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// src/core/collection/query-builder.ts
|
|
192
|
-
var ReadOnlyCollectionQueryBuilder = class {
|
|
193
|
-
constructor(api, collection) {
|
|
194
|
-
this.api = api;
|
|
195
|
-
this.collection = collection;
|
|
196
|
-
}
|
|
197
|
-
async find(options) {
|
|
198
|
-
return this.api.requestFind(
|
|
199
|
-
`/api/${String(this.collection)}`,
|
|
200
|
-
options
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
async findById(id, options) {
|
|
204
|
-
return this.api.requestFindById(
|
|
205
|
-
`/api/${String(this.collection)}/${String(id)}`,
|
|
206
|
-
options
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
async count(options) {
|
|
210
|
-
return this.api.requestCount(
|
|
211
|
-
`/api/${String(this.collection)}/count`,
|
|
212
|
-
options
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
|
-
async findMetadata(options, metadataOptions) {
|
|
216
|
-
const { docs } = await this.find({ ...options, limit: 1, depth: 1 });
|
|
217
|
-
const doc = docs[0];
|
|
218
|
-
if (!doc) return null;
|
|
219
|
-
return generateMetadata(
|
|
220
|
-
extractSeo(doc),
|
|
221
|
-
metadataOptions
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
async findMetadataById(id, metadataOptions) {
|
|
225
|
-
const doc = await this.findById(id, { depth: 1 });
|
|
226
|
-
return generateMetadata(
|
|
227
|
-
extractSeo(doc),
|
|
228
|
-
metadataOptions
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
};
|
|
232
|
-
var CollectionQueryBuilder = class {
|
|
233
|
-
constructor(api, collection) {
|
|
234
|
-
this.api = api;
|
|
235
|
-
this.collection = collection;
|
|
236
|
-
}
|
|
237
|
-
/**
|
|
238
|
-
* Find documents (list query)
|
|
239
|
-
* GET /api/{collection}
|
|
240
|
-
* @returns Payload CMS find response with docs array and pagination
|
|
241
|
-
*/
|
|
242
|
-
async find(options) {
|
|
243
|
-
return this.api.requestFind(
|
|
244
|
-
`/api/${String(this.collection)}`,
|
|
245
|
-
options
|
|
246
|
-
);
|
|
247
|
-
}
|
|
248
|
-
/**
|
|
249
|
-
* Find document by ID
|
|
250
|
-
* GET /api/{collection}/{id}
|
|
251
|
-
* @returns Document object directly (no wrapper)
|
|
252
|
-
*/
|
|
253
|
-
async findById(id, options) {
|
|
254
|
-
return this.api.requestFindById(
|
|
255
|
-
`/api/${String(this.collection)}/${String(id)}`,
|
|
256
|
-
options
|
|
257
|
-
);
|
|
258
|
-
}
|
|
259
|
-
/**
|
|
260
|
-
* Create a new document
|
|
261
|
-
* POST /api/{collection}
|
|
262
|
-
* @returns Payload CMS mutation response with doc and message
|
|
263
|
-
*/
|
|
264
|
-
async create(data, options) {
|
|
265
|
-
const endpoint = `/api/${String(this.collection)}`;
|
|
266
|
-
if (options?.file) {
|
|
267
|
-
return this.api.requestCreateWithFile(
|
|
268
|
-
endpoint,
|
|
269
|
-
data,
|
|
270
|
-
options.file,
|
|
271
|
-
options.filename
|
|
272
|
-
);
|
|
273
|
-
}
|
|
274
|
-
return this.api.requestCreate(endpoint, data);
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Update a document by ID
|
|
278
|
-
* PATCH /api/{collection}/{id}
|
|
279
|
-
* @returns Payload CMS mutation response with doc and message
|
|
280
|
-
*/
|
|
281
|
-
async update(id, data, options) {
|
|
282
|
-
const endpoint = `/api/${String(this.collection)}/${String(id)}`;
|
|
283
|
-
if (options?.file) {
|
|
284
|
-
return this.api.requestUpdateWithFile(
|
|
285
|
-
endpoint,
|
|
286
|
-
data,
|
|
287
|
-
options.file,
|
|
288
|
-
options.filename
|
|
289
|
-
);
|
|
290
|
-
}
|
|
291
|
-
return this.api.requestUpdate(endpoint, data);
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Count documents
|
|
295
|
-
* GET /api/{collection}/count
|
|
296
|
-
* @returns Count response with totalDocs
|
|
297
|
-
*/
|
|
298
|
-
async count(options) {
|
|
299
|
-
return this.api.requestCount(
|
|
300
|
-
`/api/${String(this.collection)}/count`,
|
|
301
|
-
options
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
/**
|
|
305
|
-
* Find first matching document and return its Next.js Metadata.
|
|
306
|
-
* Applies depth: 1 (SEO image populate) and limit: 1 automatically.
|
|
307
|
-
* @returns Metadata or null if no document matches
|
|
308
|
-
*/
|
|
309
|
-
async findMetadata(options, metadataOptions) {
|
|
310
|
-
const { docs } = await this.find({ ...options, limit: 1, depth: 1 });
|
|
311
|
-
const doc = docs[0];
|
|
312
|
-
if (!doc) return null;
|
|
313
|
-
return generateMetadata(
|
|
314
|
-
extractSeo(doc),
|
|
315
|
-
metadataOptions
|
|
316
|
-
);
|
|
317
|
-
}
|
|
318
|
-
/**
|
|
319
|
-
* Find document by ID and return its Next.js Metadata.
|
|
320
|
-
* Applies depth: 1 (SEO image populate) automatically.
|
|
321
|
-
* @returns Metadata (throws on 404)
|
|
322
|
-
*/
|
|
323
|
-
async findMetadataById(id, metadataOptions) {
|
|
324
|
-
const doc = await this.findById(id, { depth: 1 });
|
|
325
|
-
return generateMetadata(
|
|
326
|
-
extractSeo(doc),
|
|
327
|
-
metadataOptions
|
|
328
|
-
);
|
|
329
|
-
}
|
|
330
|
-
/**
|
|
331
|
-
* Update multiple documents (bulk update)
|
|
332
|
-
* PATCH /api/{collection}
|
|
333
|
-
* @returns Payload CMS find response with updated docs
|
|
334
|
-
*/
|
|
335
|
-
async updateMany(where, data) {
|
|
336
|
-
return this.api.requestUpdateMany(
|
|
337
|
-
`/api/${String(this.collection)}`,
|
|
338
|
-
{ where, data }
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
/**
|
|
342
|
-
* Delete a document by ID
|
|
343
|
-
* DELETE /api/{collection}/{id}
|
|
344
|
-
* @returns Deleted document object directly (no wrapper)
|
|
345
|
-
*/
|
|
346
|
-
async remove(id) {
|
|
347
|
-
return this.api.requestDelete(
|
|
348
|
-
`/api/${String(this.collection)}/${String(id)}`
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
/**
|
|
352
|
-
* Delete multiple documents (bulk delete)
|
|
353
|
-
* DELETE /api/{collection}
|
|
354
|
-
* @returns Payload CMS find response with deleted docs
|
|
355
|
-
*/
|
|
356
|
-
async removeMany(where) {
|
|
357
|
-
return this.api.requestDeleteMany(
|
|
358
|
-
`/api/${String(this.collection)}`,
|
|
359
|
-
{ where }
|
|
360
|
-
);
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
var ServerCollectionQueryBuilder = class extends CollectionQueryBuilder {
|
|
364
|
-
};
|
|
365
|
-
|
|
366
115
|
// src/core/collection/http-client.ts
|
|
367
116
|
var import_qs_esm = require("qs-esm");
|
|
368
117
|
|
|
@@ -410,8 +159,16 @@ var ValidationError = class extends SDKError {
|
|
|
410
159
|
}
|
|
411
160
|
};
|
|
412
161
|
var ApiError = class extends SDKError {
|
|
413
|
-
constructor(message, status, details, userMessage, suggestion) {
|
|
414
|
-
super(
|
|
162
|
+
constructor(message, status, details, userMessage, suggestion, requestId) {
|
|
163
|
+
super(
|
|
164
|
+
"API_ERROR",
|
|
165
|
+
message,
|
|
166
|
+
status,
|
|
167
|
+
details,
|
|
168
|
+
userMessage,
|
|
169
|
+
suggestion,
|
|
170
|
+
requestId
|
|
171
|
+
);
|
|
415
172
|
this.name = "ApiError";
|
|
416
173
|
}
|
|
417
174
|
};
|
|
@@ -462,19 +219,43 @@ var UsageLimitError = class extends SDKError {
|
|
|
462
219
|
};
|
|
463
220
|
var AuthError = class extends SDKError {
|
|
464
221
|
constructor(message, details, userMessage, suggestion, requestId) {
|
|
465
|
-
super(
|
|
222
|
+
super(
|
|
223
|
+
"auth_error",
|
|
224
|
+
message,
|
|
225
|
+
401,
|
|
226
|
+
details,
|
|
227
|
+
userMessage,
|
|
228
|
+
suggestion,
|
|
229
|
+
requestId
|
|
230
|
+
);
|
|
466
231
|
this.name = "AuthError";
|
|
467
232
|
}
|
|
468
233
|
};
|
|
469
234
|
var PermissionError = class extends SDKError {
|
|
470
235
|
constructor(message, details, userMessage, suggestion, requestId) {
|
|
471
|
-
super(
|
|
236
|
+
super(
|
|
237
|
+
"permission_error",
|
|
238
|
+
message,
|
|
239
|
+
403,
|
|
240
|
+
details,
|
|
241
|
+
userMessage,
|
|
242
|
+
suggestion,
|
|
243
|
+
requestId
|
|
244
|
+
);
|
|
472
245
|
this.name = "PermissionError";
|
|
473
246
|
}
|
|
474
247
|
};
|
|
475
248
|
var NotFoundError = class extends SDKError {
|
|
476
249
|
constructor(message, details, userMessage, suggestion, requestId) {
|
|
477
|
-
super(
|
|
250
|
+
super(
|
|
251
|
+
"not_found",
|
|
252
|
+
message,
|
|
253
|
+
404,
|
|
254
|
+
details,
|
|
255
|
+
userMessage,
|
|
256
|
+
suggestion,
|
|
257
|
+
requestId
|
|
258
|
+
);
|
|
478
259
|
this.name = "NotFoundError";
|
|
479
260
|
}
|
|
480
261
|
};
|
|
@@ -486,7 +267,15 @@ var ConflictError = class extends SDKError {
|
|
|
486
267
|
};
|
|
487
268
|
var RateLimitError = class extends SDKError {
|
|
488
269
|
constructor(message, retryAfter, details, userMessage, suggestion, requestId) {
|
|
489
|
-
super(
|
|
270
|
+
super(
|
|
271
|
+
"rate_limit_exceeded",
|
|
272
|
+
message,
|
|
273
|
+
429,
|
|
274
|
+
details,
|
|
275
|
+
userMessage,
|
|
276
|
+
suggestion,
|
|
277
|
+
requestId
|
|
278
|
+
);
|
|
490
279
|
this.name = "RateLimitError";
|
|
491
280
|
this.retryAfter = retryAfter;
|
|
492
281
|
}
|
|
@@ -535,7 +324,7 @@ function isRateLimitError(error) {
|
|
|
535
324
|
}
|
|
536
325
|
var createNetworkError = (message, status, details, userMessage, suggestion) => new NetworkError(message, status, details, userMessage, suggestion);
|
|
537
326
|
var createValidationError = (message, details, userMessage, suggestion, status) => new ValidationError(message, details, userMessage, suggestion, status);
|
|
538
|
-
var createApiError = (message, status, details, userMessage, suggestion) => new ApiError(message, status, details, userMessage, suggestion);
|
|
327
|
+
var createApiError = (message, status, details, userMessage, suggestion, requestId) => new ApiError(message, status, details, userMessage, suggestion, requestId);
|
|
539
328
|
var createConfigError = (message, details, userMessage, suggestion) => new ConfigError(message, details, userMessage, suggestion);
|
|
540
329
|
var createTimeoutError = (message, details, userMessage, suggestion) => new TimeoutError(message, details, userMessage, suggestion);
|
|
541
330
|
var createUsageLimitError = (message, usage, details, userMessage, suggestion) => new UsageLimitError(message, usage, details, userMessage, suggestion);
|
|
@@ -543,7 +332,14 @@ var createAuthError = (message, details, userMessage, suggestion, requestId) =>
|
|
|
543
332
|
var createPermissionError = (message, details, userMessage, suggestion, requestId) => new PermissionError(message, details, userMessage, suggestion, requestId);
|
|
544
333
|
var createNotFoundError = (message, details, userMessage, suggestion, requestId) => new NotFoundError(message, details, userMessage, suggestion, requestId);
|
|
545
334
|
var createConflictError = (message, details, userMessage, suggestion, requestId) => new ConflictError(message, details, userMessage, suggestion, requestId);
|
|
546
|
-
var createRateLimitError = (message, retryAfter, details, userMessage, suggestion, requestId) => new RateLimitError(
|
|
335
|
+
var createRateLimitError = (message, retryAfter, details, userMessage, suggestion, requestId) => new RateLimitError(
|
|
336
|
+
message,
|
|
337
|
+
retryAfter,
|
|
338
|
+
details,
|
|
339
|
+
userMessage,
|
|
340
|
+
suggestion,
|
|
341
|
+
requestId
|
|
342
|
+
);
|
|
547
343
|
|
|
548
344
|
// src/core/internal/utils/credentials.ts
|
|
549
345
|
function requirePublishableKeyForSecret(apiName, publishableKey, secretKey) {
|
|
@@ -556,7 +352,10 @@ function requirePublishableKeyForSecret(apiName, publishableKey, secretKey) {
|
|
|
556
352
|
}
|
|
557
353
|
|
|
558
354
|
// src/core/client/types.ts
|
|
559
|
-
function resolveApiUrl() {
|
|
355
|
+
function resolveApiUrl(apiUrl) {
|
|
356
|
+
if (apiUrl) {
|
|
357
|
+
return apiUrl.replace(/\/$/, "");
|
|
358
|
+
}
|
|
560
359
|
if (typeof process !== "undefined" && process.env) {
|
|
561
360
|
const envUrl = process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL;
|
|
562
361
|
if (envUrl) {
|
|
@@ -580,6 +379,22 @@ function debugLog(debug, type, message, data) {
|
|
|
580
379
|
console.groupEnd();
|
|
581
380
|
}
|
|
582
381
|
}
|
|
382
|
+
function redactSensitiveHeader(value) {
|
|
383
|
+
const prefix = value.toLowerCase().startsWith("bearer ") ? "Bearer " : "";
|
|
384
|
+
return value.length > 20 ? `${prefix}...****${value.slice(-8)}` : "****";
|
|
385
|
+
}
|
|
386
|
+
function redactSensitiveHeaders(headers) {
|
|
387
|
+
const redacted = Object.fromEntries(headers.entries());
|
|
388
|
+
if (redacted.authorization) {
|
|
389
|
+
redacted.authorization = redactSensitiveHeader(redacted.authorization);
|
|
390
|
+
}
|
|
391
|
+
if (redacted["x-preview-token"]) {
|
|
392
|
+
redacted["x-preview-token"] = redactSensitiveHeader(
|
|
393
|
+
redacted["x-preview-token"]
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
return redacted;
|
|
397
|
+
}
|
|
583
398
|
function getErrorSuggestion(status) {
|
|
584
399
|
if (status === 400)
|
|
585
400
|
return "The request data failed validation. Check field values and types.";
|
|
@@ -654,6 +469,12 @@ async function parseErrorBody(response) {
|
|
|
654
469
|
return fallback;
|
|
655
470
|
}
|
|
656
471
|
}
|
|
472
|
+
function getParsedErrorSuggestion(status, parsed) {
|
|
473
|
+
if (status === 403 && parsed.reason === "origin_not_allowed") {
|
|
474
|
+
return "Add the request origin to the tenant Browser API origins, then retry the browser request.";
|
|
475
|
+
}
|
|
476
|
+
return getErrorSuggestion(status);
|
|
477
|
+
}
|
|
657
478
|
async function delay(ms) {
|
|
658
479
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
659
480
|
}
|
|
@@ -667,7 +488,7 @@ function createHttpStatusError(status, parsed, details, requestId) {
|
|
|
667
488
|
...parsed.errors && { errors: parsed.errors },
|
|
668
489
|
...parsed.body && { body: parsed.body }
|
|
669
490
|
};
|
|
670
|
-
const suggestion =
|
|
491
|
+
const suggestion = getParsedErrorSuggestion(status, parsed);
|
|
671
492
|
if (status === 400 || status === 422) {
|
|
672
493
|
return attachRequestId(
|
|
673
494
|
createValidationError(
|
|
@@ -737,6 +558,7 @@ function createHttpStatusError(status, parsed, details, requestId) {
|
|
|
737
558
|
}
|
|
738
559
|
async function httpFetch(url, options) {
|
|
739
560
|
const {
|
|
561
|
+
apiUrl,
|
|
740
562
|
publishableKey,
|
|
741
563
|
secretKey,
|
|
742
564
|
customerToken,
|
|
@@ -746,7 +568,7 @@ async function httpFetch(url, options) {
|
|
|
746
568
|
onUnauthorized,
|
|
747
569
|
...requestInit
|
|
748
570
|
} = options || {};
|
|
749
|
-
const baseUrl = resolveApiUrl();
|
|
571
|
+
const baseUrl = resolveApiUrl(apiUrl);
|
|
750
572
|
const retryConfig = {
|
|
751
573
|
maxRetries: retry?.maxRetries ?? 3,
|
|
752
574
|
retryableStatuses: retry?.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES,
|
|
@@ -772,11 +594,7 @@ async function httpFetch(url, options) {
|
|
|
772
594
|
if (!headers.has("Content-Type") && requestInit.body && !(requestInit.body instanceof FormData)) {
|
|
773
595
|
headers.set("Content-Type", "application/json");
|
|
774
596
|
}
|
|
775
|
-
const redactedHeaders =
|
|
776
|
-
if (redactedHeaders["authorization"]) {
|
|
777
|
-
const token = redactedHeaders["authorization"];
|
|
778
|
-
redactedHeaders["authorization"] = token.length > 20 ? `Bearer ...****${token.slice(-8)}` : "****";
|
|
779
|
-
}
|
|
597
|
+
const redactedHeaders = redactSensitiveHeaders(headers);
|
|
780
598
|
debugLog(debug, "request", url, {
|
|
781
599
|
method: requestInit.method || "GET",
|
|
782
600
|
headers: redactedHeaders,
|
|
@@ -794,7 +612,7 @@ async function httpFetch(url, options) {
|
|
|
794
612
|
debugLog(debug, "response", url, {
|
|
795
613
|
status: response.status,
|
|
796
614
|
statusText: response.statusText,
|
|
797
|
-
headers:
|
|
615
|
+
headers: redactSensitiveHeaders(response.headers)
|
|
798
616
|
});
|
|
799
617
|
if (!response.ok) {
|
|
800
618
|
if (isUsageLimitExceededResponse(response)) {
|
|
@@ -935,7 +753,7 @@ async function httpFetch(url, options) {
|
|
|
935
753
|
|
|
936
754
|
// src/core/collection/http-client.ts
|
|
937
755
|
var HttpClient = class {
|
|
938
|
-
constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId) {
|
|
756
|
+
constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId, apiUrl) {
|
|
939
757
|
this.publishableKey = requirePublishableKeyForSecret(
|
|
940
758
|
"CollectionClient",
|
|
941
759
|
publishableKey,
|
|
@@ -945,9 +763,11 @@ var HttpClient = class {
|
|
|
945
763
|
this.getCustomerToken = getCustomerToken;
|
|
946
764
|
this.onUnauthorized = onUnauthorized;
|
|
947
765
|
this.onRequestId = onRequestId;
|
|
766
|
+
this.apiUrl = apiUrl;
|
|
948
767
|
}
|
|
949
768
|
get defaultOptions() {
|
|
950
769
|
const opts = {
|
|
770
|
+
apiUrl: this.apiUrl,
|
|
951
771
|
publishableKey: this.publishableKey,
|
|
952
772
|
secretKey: this.secretKey
|
|
953
773
|
};
|
|
@@ -1065,159 +885,113 @@ var HttpClient = class {
|
|
|
1065
885
|
}
|
|
1066
886
|
};
|
|
1067
887
|
|
|
1068
|
-
// src/
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
888
|
+
// src/utils/types.ts
|
|
889
|
+
var resolveRelation = (ref) => {
|
|
890
|
+
if (typeof ref === "string" || typeof ref === "number" || ref === null || ref === void 0)
|
|
891
|
+
return null;
|
|
892
|
+
return ref;
|
|
893
|
+
};
|
|
894
|
+
|
|
895
|
+
// src/core/metadata/index.ts
|
|
896
|
+
function extractSeo(doc) {
|
|
897
|
+
const seo = doc.seo ?? {};
|
|
898
|
+
const og = seo.openGraph ?? {};
|
|
899
|
+
return {
|
|
900
|
+
title: seo.title ?? doc.title ?? null,
|
|
901
|
+
description: seo.description ?? null,
|
|
902
|
+
noIndex: seo.noIndex ?? null,
|
|
903
|
+
canonical: seo.canonical ?? null,
|
|
904
|
+
openGraph: {
|
|
905
|
+
title: og.title ?? null,
|
|
906
|
+
description: og.description ?? null,
|
|
907
|
+
image: og.image ?? null
|
|
908
|
+
}
|
|
909
|
+
};
|
|
1076
910
|
}
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
...
|
|
1092
|
-
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
*/
|
|
1124
|
-
async requestCreate(endpoint, data) {
|
|
1125
|
-
const response = await this.fetchWithTracking(endpoint, {
|
|
1126
|
-
...this.defaultOptions,
|
|
1127
|
-
method: "POST",
|
|
1128
|
-
body: data ? JSON.stringify(data) : void 0
|
|
1129
|
-
});
|
|
1130
|
-
return this.parseMutationResponse(response);
|
|
1131
|
-
}
|
|
1132
|
-
/**
|
|
1133
|
-
* Update document
|
|
1134
|
-
* PATCH /api/{collection}/{id}
|
|
1135
|
-
*/
|
|
1136
|
-
async requestUpdate(endpoint, data) {
|
|
1137
|
-
const response = await this.fetchWithTracking(endpoint, {
|
|
1138
|
-
...this.defaultOptions,
|
|
1139
|
-
method: "PATCH",
|
|
1140
|
-
body: data ? JSON.stringify(data) : void 0
|
|
1141
|
-
});
|
|
1142
|
-
return this.parseMutationResponse(response);
|
|
1143
|
-
}
|
|
1144
|
-
/**
|
|
1145
|
-
* Count documents
|
|
1146
|
-
* GET /api/{collection}/count
|
|
1147
|
-
*/
|
|
1148
|
-
async requestCount(endpoint, options) {
|
|
1149
|
-
const url = this.buildUrl(endpoint, options);
|
|
1150
|
-
const response = await this.fetchWithTracking(url, {
|
|
1151
|
-
...this.defaultOptions,
|
|
1152
|
-
method: "GET"
|
|
1153
|
-
});
|
|
1154
|
-
return this.parseDocumentResponse(response);
|
|
1155
|
-
}
|
|
1156
|
-
/**
|
|
1157
|
-
* Update multiple documents (bulk update)
|
|
1158
|
-
* PATCH /api/{collection}
|
|
1159
|
-
*/
|
|
1160
|
-
async requestUpdateMany(endpoint, data) {
|
|
1161
|
-
const response = await this.fetchWithTracking(endpoint, {
|
|
1162
|
-
...this.defaultOptions,
|
|
1163
|
-
method: "PATCH",
|
|
1164
|
-
body: JSON.stringify(data)
|
|
1165
|
-
});
|
|
1166
|
-
return this.parseFindResponse(response);
|
|
911
|
+
function generateMetadata(input, options) {
|
|
912
|
+
const title = input.title ?? void 0;
|
|
913
|
+
const description = input.description ?? void 0;
|
|
914
|
+
const ogTitle = input.openGraph?.title ?? title;
|
|
915
|
+
const ogDescription = input.openGraph?.description ?? description;
|
|
916
|
+
const image = resolveMetaImage(input.openGraph?.image);
|
|
917
|
+
return {
|
|
918
|
+
title,
|
|
919
|
+
description,
|
|
920
|
+
...input.noIndex && { robots: { index: false, follow: false } },
|
|
921
|
+
...input.canonical && { alternates: { canonical: input.canonical } },
|
|
922
|
+
openGraph: {
|
|
923
|
+
...ogTitle && { title: ogTitle },
|
|
924
|
+
...ogDescription && { description: ogDescription },
|
|
925
|
+
...options?.siteName && { siteName: options.siteName },
|
|
926
|
+
...image && { images: [image] }
|
|
927
|
+
},
|
|
928
|
+
twitter: {
|
|
929
|
+
card: image ? "summary_large_image" : "summary",
|
|
930
|
+
...ogTitle && { title: ogTitle },
|
|
931
|
+
...ogDescription && { description: ogDescription },
|
|
932
|
+
...image && { images: [image.url] }
|
|
933
|
+
}
|
|
934
|
+
};
|
|
935
|
+
}
|
|
936
|
+
function resolveMetaImage(ref) {
|
|
937
|
+
const image = resolveRelation(ref);
|
|
938
|
+
if (!image) return null;
|
|
939
|
+
const sized = image.sizes?.["1536"];
|
|
940
|
+
const url = sized?.url || image.url;
|
|
941
|
+
if (!url) return null;
|
|
942
|
+
const width = sized?.url ? sized.width : image.width;
|
|
943
|
+
const height = sized?.url ? sized.height : image.height;
|
|
944
|
+
return {
|
|
945
|
+
url,
|
|
946
|
+
...width && { width },
|
|
947
|
+
...height && { height },
|
|
948
|
+
...image.alt && { alt: image.alt }
|
|
949
|
+
};
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
// src/core/collection/query-builder.ts
|
|
953
|
+
var ReadOnlyCollectionQueryBuilder = class {
|
|
954
|
+
constructor(api, collection) {
|
|
955
|
+
this.api = api;
|
|
956
|
+
this.collection = collection;
|
|
1167
957
|
}
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
const response = await this.fetchWithTracking(endpoint, {
|
|
1174
|
-
...this.defaultOptions,
|
|
1175
|
-
method: "DELETE"
|
|
1176
|
-
});
|
|
1177
|
-
return this.parseDocumentResponse(response);
|
|
958
|
+
async find(options) {
|
|
959
|
+
return this.api.requestFind(
|
|
960
|
+
`/api/${String(this.collection)}`,
|
|
961
|
+
options
|
|
962
|
+
);
|
|
1178
963
|
}
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
const response = await this.fetchWithTracking(endpoint, {
|
|
1185
|
-
...this.defaultOptions,
|
|
1186
|
-
method: "DELETE",
|
|
1187
|
-
body: JSON.stringify(data)
|
|
1188
|
-
});
|
|
1189
|
-
return this.parseFindResponse(response);
|
|
964
|
+
async findById(id, options) {
|
|
965
|
+
return this.api.requestFindById(
|
|
966
|
+
`/api/${String(this.collection)}/${String(id)}`,
|
|
967
|
+
options
|
|
968
|
+
);
|
|
1190
969
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
const response = await this.fetchWithTracking(endpoint, {
|
|
1197
|
-
...this.defaultOptions,
|
|
1198
|
-
method: "POST",
|
|
1199
|
-
body: buildPayloadFormData(data, file, filename)
|
|
1200
|
-
});
|
|
1201
|
-
return this.parseMutationResponse(response);
|
|
970
|
+
async count(options) {
|
|
971
|
+
return this.api.requestCount(
|
|
972
|
+
`/api/${String(this.collection)}/count`,
|
|
973
|
+
options
|
|
974
|
+
);
|
|
1202
975
|
}
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
body: buildPayloadFormData(data, file, filename)
|
|
1212
|
-
});
|
|
1213
|
-
return this.parseMutationResponse(response);
|
|
976
|
+
async findMetadata(options, metadataOptions) {
|
|
977
|
+
const { docs } = await this.find({ ...options, limit: 1, depth: 1 });
|
|
978
|
+
const doc = docs[0];
|
|
979
|
+
if (!doc) return null;
|
|
980
|
+
return generateMetadata(
|
|
981
|
+
extractSeo(doc),
|
|
982
|
+
metadataOptions
|
|
983
|
+
);
|
|
1214
984
|
}
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
985
|
+
async findMetadataById(id, metadataOptions) {
|
|
986
|
+
const doc = await this.findById(id, { depth: 1 });
|
|
987
|
+
return generateMetadata(
|
|
988
|
+
extractSeo(doc),
|
|
989
|
+
metadataOptions
|
|
990
|
+
);
|
|
1219
991
|
}
|
|
1220
992
|
};
|
|
993
|
+
|
|
994
|
+
// src/core/collection/collection-client.ts
|
|
1221
995
|
var ReadOnlyCollectionClient = class extends HttpClient {
|
|
1222
996
|
from(collection) {
|
|
1223
997
|
return new ReadOnlyCollectionQueryBuilder(this, collection);
|
|
@@ -1248,126 +1022,6 @@ var ReadOnlyCollectionClient = class extends HttpClient {
|
|
|
1248
1022
|
}
|
|
1249
1023
|
};
|
|
1250
1024
|
|
|
1251
|
-
// src/core/collection/const.ts
|
|
1252
|
-
var INTERNAL_COLLECTIONS = [
|
|
1253
|
-
"users",
|
|
1254
|
-
"payload-kv",
|
|
1255
|
-
"payload-locked-documents",
|
|
1256
|
-
"payload-preferences",
|
|
1257
|
-
"payload-migrations",
|
|
1258
|
-
"payload-folders",
|
|
1259
|
-
"field-configs",
|
|
1260
|
-
"system-media",
|
|
1261
|
-
"track-assets",
|
|
1262
|
-
"audiences",
|
|
1263
|
-
"email-logs",
|
|
1264
|
-
"api-usage",
|
|
1265
|
-
"tenant-analytics-daily",
|
|
1266
|
-
"tenant-web-analytics-config",
|
|
1267
|
-
"analytics-event-schemas",
|
|
1268
|
-
"subscriptions",
|
|
1269
|
-
"billing-history",
|
|
1270
|
-
"inventory-reservations",
|
|
1271
|
-
"order-status-logs",
|
|
1272
|
-
"api-keys",
|
|
1273
|
-
"personal-access-tokens",
|
|
1274
|
-
"tenant-entitlements",
|
|
1275
|
-
"tenant-purge-jobs",
|
|
1276
|
-
"direct-upload-sessions",
|
|
1277
|
-
"webhook-events",
|
|
1278
|
-
"webhook-deliveries",
|
|
1279
|
-
"audit-logs",
|
|
1280
|
-
"plans",
|
|
1281
|
-
"webhooks",
|
|
1282
|
-
"event-registrations"
|
|
1283
|
-
];
|
|
1284
|
-
var COLLECTIONS = [
|
|
1285
|
-
"tenants",
|
|
1286
|
-
"tenant-metadata",
|
|
1287
|
-
"tenant-logos",
|
|
1288
|
-
"products",
|
|
1289
|
-
"product-variants",
|
|
1290
|
-
"product-options",
|
|
1291
|
-
"product-option-values",
|
|
1292
|
-
"product-categories",
|
|
1293
|
-
"product-tags",
|
|
1294
|
-
"product-collections",
|
|
1295
|
-
"brands",
|
|
1296
|
-
"brand-logos",
|
|
1297
|
-
"orders",
|
|
1298
|
-
"order-items",
|
|
1299
|
-
"returns",
|
|
1300
|
-
"return-items",
|
|
1301
|
-
"fulfillments",
|
|
1302
|
-
"fulfillment-items",
|
|
1303
|
-
"transactions",
|
|
1304
|
-
"customers",
|
|
1305
|
-
"customer-profiles",
|
|
1306
|
-
"customer-profile-lists",
|
|
1307
|
-
"customer-addresses",
|
|
1308
|
-
"carts",
|
|
1309
|
-
"cart-items",
|
|
1310
|
-
"discounts",
|
|
1311
|
-
"shipping-policies",
|
|
1312
|
-
"shipping-zones",
|
|
1313
|
-
"documents",
|
|
1314
|
-
"document-categories",
|
|
1315
|
-
"document-types",
|
|
1316
|
-
"articles",
|
|
1317
|
-
"article-authors",
|
|
1318
|
-
"article-categories",
|
|
1319
|
-
"article-tags",
|
|
1320
|
-
"playlists",
|
|
1321
|
-
"playlist-categories",
|
|
1322
|
-
"playlist-tags",
|
|
1323
|
-
"tracks",
|
|
1324
|
-
"track-categories",
|
|
1325
|
-
"track-tags",
|
|
1326
|
-
"galleries",
|
|
1327
|
-
"gallery-categories",
|
|
1328
|
-
"gallery-tags",
|
|
1329
|
-
"gallery-items",
|
|
1330
|
-
"links",
|
|
1331
|
-
"link-categories",
|
|
1332
|
-
"link-tags",
|
|
1333
|
-
"canvases",
|
|
1334
|
-
"canvas-node-types",
|
|
1335
|
-
"canvas-edge-types",
|
|
1336
|
-
"canvas-categories",
|
|
1337
|
-
"canvas-tags",
|
|
1338
|
-
"canvas-nodes",
|
|
1339
|
-
"canvas-edges",
|
|
1340
|
-
"videos",
|
|
1341
|
-
"video-categories",
|
|
1342
|
-
"video-tags",
|
|
1343
|
-
"live-streams",
|
|
1344
|
-
"images",
|
|
1345
|
-
"forms",
|
|
1346
|
-
"form-submissions",
|
|
1347
|
-
// Community
|
|
1348
|
-
"posts",
|
|
1349
|
-
"comments",
|
|
1350
|
-
"reactions",
|
|
1351
|
-
"reaction-types",
|
|
1352
|
-
"bookmarks",
|
|
1353
|
-
"post-categories",
|
|
1354
|
-
// Events
|
|
1355
|
-
"event-calendars",
|
|
1356
|
-
"events",
|
|
1357
|
-
"event-categories",
|
|
1358
|
-
"event-occurrences",
|
|
1359
|
-
"event-tags"
|
|
1360
|
-
];
|
|
1361
|
-
var SERVER_ONLY_COLLECTIONS = [
|
|
1362
|
-
"customer-groups",
|
|
1363
|
-
"reports",
|
|
1364
|
-
"community-bans"
|
|
1365
|
-
];
|
|
1366
|
-
var SERVER_COLLECTIONS = [
|
|
1367
|
-
...COLLECTIONS,
|
|
1368
|
-
...SERVER_ONLY_COLLECTIONS
|
|
1369
|
-
];
|
|
1370
|
-
|
|
1371
1025
|
// src/core/api/parse-response.ts
|
|
1372
1026
|
async function parseApiResponse(response, endpoint) {
|
|
1373
1027
|
let data;
|
|
@@ -1391,7 +1045,7 @@ async function parseApiResponse(response, endpoint) {
|
|
|
1391
1045
|
if (reason === "validation_failed") {
|
|
1392
1046
|
throw attachRequestId(createValidationError(errorMessage, data, errorMessage), requestId);
|
|
1393
1047
|
}
|
|
1394
|
-
if (reason === "token_expired" || reason === "token_invalid" || reason === "key_invalid" || reason === "key_revoked") {
|
|
1048
|
+
if (reason === "token_expired" || reason === "token_invalid" || reason === "preview_token_invalid" || reason === "preview_token_required" || reason === "key_invalid" || reason === "key_revoked") {
|
|
1395
1049
|
throw attachRequestId(createAuthError(errorMessage, data, errorMessage), requestId);
|
|
1396
1050
|
}
|
|
1397
1051
|
if (reason === "forbidden") {
|
|
@@ -1423,6 +1077,7 @@ var CommunityClient = class {
|
|
|
1423
1077
|
options.secretKey
|
|
1424
1078
|
);
|
|
1425
1079
|
this.secretKey = options.secretKey;
|
|
1080
|
+
this.apiUrl = options.apiUrl;
|
|
1426
1081
|
this.customerToken = options.customerToken;
|
|
1427
1082
|
this.onUnauthorized = options.onUnauthorized;
|
|
1428
1083
|
this.onRequestId = options.onRequestId;
|
|
@@ -1437,6 +1092,7 @@ var CommunityClient = class {
|
|
|
1437
1092
|
try {
|
|
1438
1093
|
const response = await httpFetch(endpoint, {
|
|
1439
1094
|
method,
|
|
1095
|
+
apiUrl: this.apiUrl,
|
|
1440
1096
|
publishableKey: this.publishableKey,
|
|
1441
1097
|
secretKey: this.secretKey,
|
|
1442
1098
|
customerToken: token ?? void 0,
|
|
@@ -1585,53 +1241,6 @@ var CommunityClient = class {
|
|
|
1585
1241
|
}
|
|
1586
1242
|
};
|
|
1587
1243
|
|
|
1588
|
-
// src/core/api/base-api.ts
|
|
1589
|
-
var BaseApi = class {
|
|
1590
|
-
constructor(apiName, options) {
|
|
1591
|
-
if (!options.secretKey) {
|
|
1592
|
-
throw createConfigError(`secretKey is required for ${apiName}.`);
|
|
1593
|
-
}
|
|
1594
|
-
this.publishableKey = requirePublishableKeyForSecret(
|
|
1595
|
-
apiName,
|
|
1596
|
-
options.publishableKey,
|
|
1597
|
-
options.secretKey
|
|
1598
|
-
);
|
|
1599
|
-
this.secretKey = options.secretKey;
|
|
1600
|
-
this.onRequestId = options.onRequestId;
|
|
1601
|
-
}
|
|
1602
|
-
async request(endpoint, body, options) {
|
|
1603
|
-
const method = options?.method ?? "POST";
|
|
1604
|
-
try {
|
|
1605
|
-
const response = await httpFetch(endpoint, {
|
|
1606
|
-
method,
|
|
1607
|
-
publishableKey: this.publishableKey,
|
|
1608
|
-
secretKey: this.secretKey,
|
|
1609
|
-
...body !== void 0 && { body: JSON.stringify(body) },
|
|
1610
|
-
...options?.headers && { headers: options.headers }
|
|
1611
|
-
});
|
|
1612
|
-
this.onRequestId?.(response.headers.get("x-request-id") ?? null);
|
|
1613
|
-
return parseApiResponse(response, endpoint);
|
|
1614
|
-
} catch (err) {
|
|
1615
|
-
const id = err instanceof SDKError ? err.requestId ?? null : null;
|
|
1616
|
-
this.onRequestId?.(id);
|
|
1617
|
-
throw err;
|
|
1618
|
-
}
|
|
1619
|
-
}
|
|
1620
|
-
};
|
|
1621
|
-
|
|
1622
|
-
// src/core/community/moderation-api.ts
|
|
1623
|
-
var ModerationApi = class extends BaseApi {
|
|
1624
|
-
constructor(options) {
|
|
1625
|
-
super("ModerationApi", options);
|
|
1626
|
-
}
|
|
1627
|
-
banCustomer(params) {
|
|
1628
|
-
return this.request("/api/community-bans/ban", params);
|
|
1629
|
-
}
|
|
1630
|
-
unbanCustomer(params) {
|
|
1631
|
-
return this.request("/api/community-bans/unban", params);
|
|
1632
|
-
}
|
|
1633
|
-
};
|
|
1634
|
-
|
|
1635
1244
|
// src/core/customer/customer-auth.ts
|
|
1636
1245
|
var DEFAULT_TIMEOUT2 = 15e3;
|
|
1637
1246
|
function safeGetItem(key) {
|
|
@@ -1642,10 +1251,10 @@ function safeGetItem(key) {
|
|
|
1642
1251
|
}
|
|
1643
1252
|
}
|
|
1644
1253
|
var CustomerAuth = class {
|
|
1645
|
-
constructor(publishableKey, options) {
|
|
1254
|
+
constructor(publishableKey, options, apiUrl) {
|
|
1646
1255
|
this.refreshPromise = null;
|
|
1647
1256
|
this.publishableKey = publishableKey;
|
|
1648
|
-
this.baseUrl = resolveApiUrl();
|
|
1257
|
+
this.baseUrl = resolveApiUrl(apiUrl);
|
|
1649
1258
|
const persist = options?.persist ?? true;
|
|
1650
1259
|
if (persist) {
|
|
1651
1260
|
const key = typeof persist === "string" ? persist : "customer-token";
|
|
@@ -1876,8 +1485,8 @@ var CustomerAuth = class {
|
|
|
1876
1485
|
|
|
1877
1486
|
// src/core/customer/customer-namespace.ts
|
|
1878
1487
|
var CustomerNamespace = class {
|
|
1879
|
-
constructor(publishableKey, options) {
|
|
1880
|
-
this.auth = new CustomerAuth(publishableKey, options);
|
|
1488
|
+
constructor(publishableKey, options, apiUrl) {
|
|
1489
|
+
this.auth = new CustomerAuth(publishableKey, options, apiUrl);
|
|
1881
1490
|
}
|
|
1882
1491
|
};
|
|
1883
1492
|
|
|
@@ -1895,6 +1504,7 @@ var CartApi = class {
|
|
|
1895
1504
|
options.secretKey
|
|
1896
1505
|
);
|
|
1897
1506
|
this.secretKey = options.secretKey;
|
|
1507
|
+
this.apiUrl = options.apiUrl;
|
|
1898
1508
|
this.customerToken = options.customerToken;
|
|
1899
1509
|
this.onUnauthorized = options.onUnauthorized;
|
|
1900
1510
|
this.onRequestId = options.onRequestId;
|
|
@@ -1904,6 +1514,7 @@ var CartApi = class {
|
|
|
1904
1514
|
try {
|
|
1905
1515
|
const response = await httpFetch(endpoint, {
|
|
1906
1516
|
method,
|
|
1517
|
+
apiUrl: this.apiUrl,
|
|
1907
1518
|
publishableKey: this.publishableKey,
|
|
1908
1519
|
secretKey: this.secretKey,
|
|
1909
1520
|
customerToken: token ?? void 0,
|
|
@@ -1954,6 +1565,7 @@ var CommerceClient = class {
|
|
|
1954
1565
|
constructor(options) {
|
|
1955
1566
|
const cartApi = new CartApi({
|
|
1956
1567
|
publishableKey: options.publishableKey,
|
|
1568
|
+
apiUrl: options.apiUrl,
|
|
1957
1569
|
customerToken: options.customerToken,
|
|
1958
1570
|
onUnauthorized: options.onUnauthorized,
|
|
1959
1571
|
onRequestId: options.onRequestId
|
|
@@ -1963,6 +1575,7 @@ var CommerceClient = class {
|
|
|
1963
1575
|
try {
|
|
1964
1576
|
const response = await httpFetch(endpoint, {
|
|
1965
1577
|
method: "POST",
|
|
1578
|
+
apiUrl: options.apiUrl,
|
|
1966
1579
|
publishableKey: options.publishableKey,
|
|
1967
1580
|
customerToken: token ?? void 0,
|
|
1968
1581
|
...token && options.onUnauthorized && { onUnauthorized: options.onUnauthorized },
|
|
@@ -2006,730 +1619,7 @@ var CommerceClient = class {
|
|
|
2006
1619
|
};
|
|
2007
1620
|
this.shipping = {
|
|
2008
1621
|
calculate: (params) => execute("/api/shipping-policies/calculate", params)
|
|
2009
|
-
};
|
|
2010
|
-
}
|
|
2011
|
-
};
|
|
2012
|
-
|
|
2013
|
-
// src/core/api/product-api.ts
|
|
2014
|
-
var ProductApi = class extends BaseApi {
|
|
2015
|
-
constructor(options) {
|
|
2016
|
-
super("ProductApi", options);
|
|
2017
|
-
}
|
|
2018
|
-
/**
|
|
2019
|
-
* Check point-in-time stock availability for one or more product variants.
|
|
2020
|
-
* Results reflect available stock at the moment of the call and are not guaranteed
|
|
2021
|
-
* to remain available by the time an order is placed.
|
|
2022
|
-
*/
|
|
2023
|
-
stockCheck(params) {
|
|
2024
|
-
return this.request("/api/products/stock-check", params);
|
|
2025
|
-
}
|
|
2026
|
-
listingGroups(params) {
|
|
2027
|
-
return this.request(
|
|
2028
|
-
"/api/products/listing-groups",
|
|
2029
|
-
params
|
|
2030
|
-
);
|
|
2031
|
-
}
|
|
2032
|
-
/**
|
|
2033
|
-
* Fetch full product detail by slug or id.
|
|
2034
|
-
* Returns `null` on 404 regardless of reason (`not_found` / `not_published` /
|
|
2035
|
-
* `tenant_mismatch` / `feature_disabled`). For the reason behind a null,
|
|
2036
|
-
* inspect `client.lastRequestId` against backend logs.
|
|
2037
|
-
*/
|
|
2038
|
-
async detail(params) {
|
|
2039
|
-
try {
|
|
2040
|
-
return await this.request("/api/products/detail", params);
|
|
2041
|
-
} catch (err) {
|
|
2042
|
-
if (err instanceof NotFoundError) return null;
|
|
2043
|
-
throw err;
|
|
2044
|
-
}
|
|
2045
|
-
}
|
|
2046
|
-
/**
|
|
2047
|
-
* Atomically create or update a product together with its options,
|
|
2048
|
-
* option-values, and variants in a single transaction. Mirrors Shopify's
|
|
2049
|
-
* `productSet` shape and is the canonical write path for the MCP
|
|
2050
|
-
* `product-upsert` tool.
|
|
2051
|
-
*/
|
|
2052
|
-
upsert(params) {
|
|
2053
|
-
return this.request("/api/products/upsert", params);
|
|
2054
|
-
}
|
|
2055
|
-
};
|
|
2056
|
-
|
|
2057
|
-
// src/core/api/discount-api.ts
|
|
2058
|
-
var DiscountApi = class extends BaseApi {
|
|
2059
|
-
constructor(options) {
|
|
2060
|
-
super("DiscountApi", options);
|
|
2061
|
-
}
|
|
2062
|
-
validate(params) {
|
|
2063
|
-
return this.request("/api/discounts/validate", params);
|
|
2064
|
-
}
|
|
2065
|
-
};
|
|
2066
|
-
|
|
2067
|
-
// src/core/api/shipping-api.ts
|
|
2068
|
-
var ShippingApi = class extends BaseApi {
|
|
2069
|
-
constructor(options) {
|
|
2070
|
-
super("ShippingApi", options);
|
|
2071
|
-
}
|
|
2072
|
-
calculate(params) {
|
|
2073
|
-
return this.request("/api/shipping-policies/calculate", params);
|
|
2074
|
-
}
|
|
2075
|
-
};
|
|
2076
|
-
|
|
2077
|
-
// src/core/api/order-api.ts
|
|
2078
|
-
var OrderApi = class extends BaseApi {
|
|
2079
|
-
constructor(options) {
|
|
2080
|
-
super("OrderApi", options);
|
|
2081
|
-
}
|
|
2082
|
-
createOrder(params) {
|
|
2083
|
-
return this.request("/api/orders/create", params);
|
|
2084
|
-
}
|
|
2085
|
-
updateOrder(params) {
|
|
2086
|
-
return this.request("/api/orders/update", params);
|
|
2087
|
-
}
|
|
2088
|
-
updateTransaction(params) {
|
|
2089
|
-
return this.request("/api/transactions/update", params);
|
|
2090
|
-
}
|
|
2091
|
-
confirmPayment(params) {
|
|
2092
|
-
return this.request(
|
|
2093
|
-
"/api/orders/confirm-payment",
|
|
2094
|
-
params,
|
|
2095
|
-
params.providerEventId ? { headers: { "X-Idempotency-Key": params.providerEventId } } : void 0
|
|
2096
|
-
);
|
|
2097
|
-
}
|
|
2098
|
-
checkout(params) {
|
|
2099
|
-
return this.request("/api/orders/checkout", params);
|
|
2100
|
-
}
|
|
2101
|
-
createFulfillment(params) {
|
|
2102
|
-
return this.request("/api/orders/create-fulfillment", params);
|
|
2103
|
-
}
|
|
2104
|
-
updateFulfillment(params) {
|
|
2105
|
-
return this.request("/api/orders/update-fulfillment", params);
|
|
2106
|
-
}
|
|
2107
|
-
bulkImportFulfillments(params) {
|
|
2108
|
-
return this.request(
|
|
2109
|
-
"/api/orders/bulk-import-fulfillments",
|
|
2110
|
-
params
|
|
2111
|
-
);
|
|
2112
|
-
}
|
|
2113
|
-
returnWithRefund(params) {
|
|
2114
|
-
return this.request(
|
|
2115
|
-
"/api/returns/return-refund",
|
|
2116
|
-
params
|
|
2117
|
-
);
|
|
2118
|
-
}
|
|
2119
|
-
createReturn(params) {
|
|
2120
|
-
return this.request("/api/returns/create", params);
|
|
2121
|
-
}
|
|
2122
|
-
updateReturn(params) {
|
|
2123
|
-
return this.request("/api/returns/update", params);
|
|
2124
|
-
}
|
|
2125
|
-
};
|
|
2126
|
-
|
|
2127
|
-
// src/core/commerce/server-commerce-client.ts
|
|
2128
|
-
var ServerCommerceClient = class {
|
|
2129
|
-
constructor(options) {
|
|
2130
|
-
const publishableKey = requirePublishableKeyForSecret(
|
|
2131
|
-
"ServerCommerceClient",
|
|
2132
|
-
options.publishableKey,
|
|
2133
|
-
options.secretKey
|
|
2134
|
-
);
|
|
2135
|
-
const serverOptions = {
|
|
2136
|
-
publishableKey,
|
|
2137
|
-
secretKey: options.secretKey,
|
|
2138
|
-
onRequestId: options.onRequestId
|
|
2139
|
-
};
|
|
2140
|
-
const productApi = new ProductApi(serverOptions);
|
|
2141
|
-
const cartApi = new CartApi(serverOptions);
|
|
2142
|
-
const discountApi = new DiscountApi(serverOptions);
|
|
2143
|
-
const shippingApi = new ShippingApi(serverOptions);
|
|
2144
|
-
const orderApi = new OrderApi(serverOptions);
|
|
2145
|
-
this.product = {
|
|
2146
|
-
stockCheck: productApi.stockCheck.bind(productApi),
|
|
2147
|
-
listingGroups: productApi.listingGroups.bind(productApi),
|
|
2148
|
-
detail: productApi.detail.bind(productApi),
|
|
2149
|
-
upsert: productApi.upsert.bind(productApi)
|
|
2150
|
-
};
|
|
2151
|
-
this.cart = {
|
|
2152
|
-
get: cartApi.getCart.bind(cartApi),
|
|
2153
|
-
addItem: cartApi.addItem.bind(cartApi),
|
|
2154
|
-
updateItem: cartApi.updateItem.bind(cartApi),
|
|
2155
|
-
removeItem: cartApi.removeItem.bind(cartApi),
|
|
2156
|
-
applyDiscount: cartApi.applyDiscount.bind(cartApi),
|
|
2157
|
-
removeDiscount: cartApi.removeDiscount.bind(cartApi),
|
|
2158
|
-
clear: cartApi.clearCart.bind(cartApi)
|
|
2159
|
-
};
|
|
2160
|
-
this.orders = {
|
|
2161
|
-
checkout: orderApi.checkout.bind(orderApi),
|
|
2162
|
-
create: orderApi.createOrder.bind(orderApi),
|
|
2163
|
-
update: orderApi.updateOrder.bind(orderApi),
|
|
2164
|
-
updateTransaction: orderApi.updateTransaction.bind(orderApi),
|
|
2165
|
-
confirmPayment: orderApi.confirmPayment.bind(orderApi),
|
|
2166
|
-
createFulfillment: orderApi.createFulfillment.bind(orderApi),
|
|
2167
|
-
updateFulfillment: orderApi.updateFulfillment.bind(orderApi),
|
|
2168
|
-
bulkImportFulfillments: orderApi.bulkImportFulfillments.bind(orderApi),
|
|
2169
|
-
createReturn: orderApi.createReturn.bind(orderApi),
|
|
2170
|
-
updateReturn: orderApi.updateReturn.bind(orderApi),
|
|
2171
|
-
returnWithRefund: orderApi.returnWithRefund.bind(orderApi)
|
|
2172
|
-
};
|
|
2173
|
-
this.discounts = {
|
|
2174
|
-
validate: discountApi.validate.bind(discountApi)
|
|
2175
|
-
};
|
|
2176
|
-
this.shipping = {
|
|
2177
|
-
calculate: shippingApi.calculate.bind(shippingApi)
|
|
2178
|
-
};
|
|
2179
|
-
}
|
|
2180
|
-
};
|
|
2181
|
-
|
|
2182
|
-
// src/core/query/get-query-client.ts
|
|
2183
|
-
var import_react_query = require("@tanstack/react-query");
|
|
2184
|
-
function makeQueryClient() {
|
|
2185
|
-
return new import_react_query.QueryClient({
|
|
2186
|
-
defaultOptions: {
|
|
2187
|
-
queries: {
|
|
2188
|
-
// Infinite staleTime: server-fetched data persists until explicitly invalidated.
|
|
2189
|
-
// For browser clients needing fresher data, override per-query:
|
|
2190
|
-
// useQuery({ ..., staleTime: 5 * 60 * 1000 })
|
|
2191
|
-
staleTime: Number.POSITIVE_INFINITY,
|
|
2192
|
-
refetchOnWindowFocus: false
|
|
2193
|
-
},
|
|
2194
|
-
dehydrate: {
|
|
2195
|
-
shouldDehydrateQuery: (query) => (0, import_react_query.defaultShouldDehydrateQuery)(query) || query.state.status === "pending",
|
|
2196
|
-
shouldRedactErrors: () => false
|
|
2197
|
-
}
|
|
2198
|
-
}
|
|
2199
|
-
});
|
|
2200
|
-
}
|
|
2201
|
-
var browserQueryClient;
|
|
2202
|
-
function getQueryClient() {
|
|
2203
|
-
if (import_react_query.isServer) {
|
|
2204
|
-
return makeQueryClient();
|
|
2205
|
-
}
|
|
2206
|
-
if (!browserQueryClient) {
|
|
2207
|
-
browserQueryClient = makeQueryClient();
|
|
2208
|
-
}
|
|
2209
|
-
return browserQueryClient;
|
|
2210
|
-
}
|
|
2211
|
-
|
|
2212
|
-
// src/core/query/query-hooks.ts
|
|
2213
|
-
var import_react_query4 = require("@tanstack/react-query");
|
|
2214
|
-
|
|
2215
|
-
// src/core/query/collection-hooks.ts
|
|
2216
|
-
var import_react_query2 = require("@tanstack/react-query");
|
|
2217
|
-
|
|
2218
|
-
// src/core/query/query-keys.ts
|
|
2219
|
-
function collectionKeys(collection) {
|
|
2220
|
-
return {
|
|
2221
|
-
all: [collection],
|
|
2222
|
-
lists: () => [collection, "list"],
|
|
2223
|
-
list: (options) => [collection, "list", options],
|
|
2224
|
-
details: () => [collection, "detail"],
|
|
2225
|
-
detail: (id, options) => [collection, "detail", id, options],
|
|
2226
|
-
infinites: () => [collection, "infinite"],
|
|
2227
|
-
infinite: (options) => [collection, "infinite", options]
|
|
2228
|
-
};
|
|
2229
|
-
}
|
|
2230
|
-
var customerKeys = {
|
|
2231
|
-
all: ["customer"],
|
|
2232
|
-
me: () => ["customer", "me"]
|
|
2233
|
-
};
|
|
2234
|
-
var productKeys = {
|
|
2235
|
-
listingGroups: (options) => ["products", "listing-groups", "list", options],
|
|
2236
|
-
listingGroupsInfinite: (options) => ["products", "listing-groups", "infinite", options],
|
|
2237
|
-
detail: (params) => ["products", "detail", params],
|
|
2238
|
-
detailAll: () => ["products", "detail"]
|
|
2239
|
-
};
|
|
2240
|
-
|
|
2241
|
-
// src/core/query/collection-hooks.ts
|
|
2242
|
-
var PRODUCT_DETAIL_INVALIDATING_COLLECTIONS = /* @__PURE__ */ new Set([
|
|
2243
|
-
"products",
|
|
2244
|
-
"product-variants",
|
|
2245
|
-
"product-options",
|
|
2246
|
-
"product-option-values",
|
|
2247
|
-
"product-categories",
|
|
2248
|
-
"product-tags",
|
|
2249
|
-
"product-collections",
|
|
2250
|
-
"brands",
|
|
2251
|
-
"brand-logos",
|
|
2252
|
-
"images"
|
|
2253
|
-
]);
|
|
2254
|
-
var DEFAULT_PAGE_SIZE = 20;
|
|
2255
|
-
var CollectionHooks = class {
|
|
2256
|
-
constructor(queryClient, collectionClient) {
|
|
2257
|
-
this.queryClient = queryClient;
|
|
2258
|
-
this.collectionClient = collectionClient;
|
|
2259
|
-
}
|
|
2260
|
-
// ===== useQuery =====
|
|
2261
|
-
useQuery(params, options) {
|
|
2262
|
-
const { collection, options: queryOptions } = params;
|
|
2263
|
-
const { placeholderData, ...restOptions } = options ?? {};
|
|
2264
|
-
return (0, import_react_query2.useQuery)({
|
|
2265
|
-
queryKey: collectionKeys(collection).list(queryOptions),
|
|
2266
|
-
queryFn: async () => {
|
|
2267
|
-
return await this.collectionClient.from(collection).find(queryOptions);
|
|
2268
|
-
},
|
|
2269
|
-
...restOptions,
|
|
2270
|
-
// NonFunctionGuard<T> incompatible with generic union types — safe cast
|
|
2271
|
-
...placeholderData !== void 0 && {
|
|
2272
|
-
placeholderData
|
|
2273
|
-
}
|
|
2274
|
-
});
|
|
2275
|
-
}
|
|
2276
|
-
// ===== useSuspenseQuery =====
|
|
2277
|
-
useSuspenseQuery(params, options) {
|
|
2278
|
-
const { collection, options: queryOptions } = params;
|
|
2279
|
-
return (0, import_react_query2.useSuspenseQuery)({
|
|
2280
|
-
queryKey: collectionKeys(collection).list(queryOptions),
|
|
2281
|
-
queryFn: async () => {
|
|
2282
|
-
return await this.collectionClient.from(collection).find(queryOptions);
|
|
2283
|
-
},
|
|
2284
|
-
...options
|
|
2285
|
-
});
|
|
2286
|
-
}
|
|
2287
|
-
// ===== useQueryById =====
|
|
2288
|
-
useQueryById(params, options) {
|
|
2289
|
-
const { collection, id, options: queryOptions } = params;
|
|
2290
|
-
const { placeholderData, ...restOptions } = options ?? {};
|
|
2291
|
-
return (0, import_react_query2.useQuery)({
|
|
2292
|
-
queryKey: collectionKeys(collection).detail(id, queryOptions),
|
|
2293
|
-
queryFn: async () => {
|
|
2294
|
-
return await this.collectionClient.from(collection).findById(id, queryOptions);
|
|
2295
|
-
},
|
|
2296
|
-
...restOptions,
|
|
2297
|
-
// NonFunctionGuard<T> incompatible with generic union types — safe cast
|
|
2298
|
-
...placeholderData !== void 0 && {
|
|
2299
|
-
placeholderData
|
|
2300
|
-
}
|
|
2301
|
-
});
|
|
2302
|
-
}
|
|
2303
|
-
// ===== useSuspenseQueryById =====
|
|
2304
|
-
useSuspenseQueryById(params, options) {
|
|
2305
|
-
const { collection, id, options: queryOptions } = params;
|
|
2306
|
-
return (0, import_react_query2.useSuspenseQuery)({
|
|
2307
|
-
queryKey: collectionKeys(collection).detail(id, queryOptions),
|
|
2308
|
-
queryFn: async () => {
|
|
2309
|
-
return await this.collectionClient.from(collection).findById(id, queryOptions);
|
|
2310
|
-
},
|
|
2311
|
-
...options
|
|
2312
|
-
});
|
|
2313
|
-
}
|
|
2314
|
-
// ===== useInfiniteQuery =====
|
|
2315
|
-
useInfiniteQuery(params, options) {
|
|
2316
|
-
const {
|
|
2317
|
-
collection,
|
|
2318
|
-
options: queryOptions,
|
|
2319
|
-
pageSize = DEFAULT_PAGE_SIZE
|
|
2320
|
-
} = params;
|
|
2321
|
-
return (0, import_react_query2.useInfiniteQuery)({
|
|
2322
|
-
queryKey: collectionKeys(collection).infinite(queryOptions),
|
|
2323
|
-
queryFn: async ({ pageParam }) => {
|
|
2324
|
-
const response = await this.collectionClient.from(collection).find({ ...queryOptions, page: pageParam, limit: pageSize });
|
|
2325
|
-
return response;
|
|
2326
|
-
},
|
|
2327
|
-
initialPageParam: 1,
|
|
2328
|
-
getNextPageParam: (lastPage) => {
|
|
2329
|
-
return lastPage.hasNextPage ? lastPage.nextPage : void 0;
|
|
2330
|
-
},
|
|
2331
|
-
...options
|
|
2332
|
-
});
|
|
2333
|
-
}
|
|
2334
|
-
// ===== useSuspenseInfiniteQuery =====
|
|
2335
|
-
useSuspenseInfiniteQuery(params, options) {
|
|
2336
|
-
const {
|
|
2337
|
-
collection,
|
|
2338
|
-
options: queryOptions,
|
|
2339
|
-
pageSize = DEFAULT_PAGE_SIZE
|
|
2340
|
-
} = params;
|
|
2341
|
-
return (0, import_react_query2.useSuspenseInfiniteQuery)({
|
|
2342
|
-
queryKey: collectionKeys(collection).infinite(queryOptions),
|
|
2343
|
-
queryFn: async ({ pageParam }) => {
|
|
2344
|
-
const response = await this.collectionClient.from(collection).find({ ...queryOptions, page: pageParam, limit: pageSize });
|
|
2345
|
-
return response;
|
|
2346
|
-
},
|
|
2347
|
-
initialPageParam: 1,
|
|
2348
|
-
getNextPageParam: (lastPage) => {
|
|
2349
|
-
return lastPage.hasNextPage ? lastPage.nextPage : void 0;
|
|
2350
|
-
},
|
|
2351
|
-
...options
|
|
2352
|
-
});
|
|
2353
|
-
}
|
|
2354
|
-
// ===== prefetchQuery =====
|
|
2355
|
-
async prefetchQuery(params, options) {
|
|
2356
|
-
const { collection, options: queryOptions } = params;
|
|
2357
|
-
return this.queryClient.prefetchQuery({
|
|
2358
|
-
queryKey: collectionKeys(collection).list(queryOptions),
|
|
2359
|
-
queryFn: async () => {
|
|
2360
|
-
return await this.collectionClient.from(collection).find(queryOptions);
|
|
2361
|
-
},
|
|
2362
|
-
...options
|
|
2363
|
-
});
|
|
2364
|
-
}
|
|
2365
|
-
// ===== prefetchQueryById =====
|
|
2366
|
-
async prefetchQueryById(params, options) {
|
|
2367
|
-
const { collection, id, options: queryOptions } = params;
|
|
2368
|
-
return this.queryClient.prefetchQuery({
|
|
2369
|
-
queryKey: collectionKeys(collection).detail(id, queryOptions),
|
|
2370
|
-
queryFn: async () => {
|
|
2371
|
-
return await this.collectionClient.from(collection).findById(id, queryOptions);
|
|
2372
|
-
},
|
|
2373
|
-
...options
|
|
2374
|
-
});
|
|
2375
|
-
}
|
|
2376
|
-
// ===== prefetchInfiniteQuery =====
|
|
2377
|
-
async prefetchInfiniteQuery(params, options) {
|
|
2378
|
-
const {
|
|
2379
|
-
collection,
|
|
2380
|
-
options: queryOptions,
|
|
2381
|
-
pageSize = DEFAULT_PAGE_SIZE
|
|
2382
|
-
} = params;
|
|
2383
|
-
return this.queryClient.prefetchInfiniteQuery({
|
|
2384
|
-
queryKey: collectionKeys(collection).infinite(queryOptions),
|
|
2385
|
-
queryFn: async ({ pageParam }) => {
|
|
2386
|
-
const response = await this.collectionClient.from(collection).find({ ...queryOptions, page: pageParam, limit: pageSize });
|
|
2387
|
-
return response;
|
|
2388
|
-
},
|
|
2389
|
-
initialPageParam: 1,
|
|
2390
|
-
getNextPageParam: (lastPage) => {
|
|
2391
|
-
return lastPage.hasNextPage ? lastPage.nextPage : void 0;
|
|
2392
|
-
},
|
|
2393
|
-
pages: options?.pages ?? 1,
|
|
2394
|
-
staleTime: options?.staleTime
|
|
2395
|
-
});
|
|
2396
|
-
}
|
|
2397
|
-
// ===== Mutation Hooks =====
|
|
2398
|
-
useCreate(params, options) {
|
|
2399
|
-
const { collection } = params;
|
|
2400
|
-
return (0, import_react_query2.useMutation)({
|
|
2401
|
-
mutationFn: async (variables) => {
|
|
2402
|
-
return await this.collectionClient.from(collection).create(
|
|
2403
|
-
variables.data,
|
|
2404
|
-
variables.file ? { file: variables.file, filename: variables.filename } : void 0
|
|
2405
|
-
);
|
|
2406
|
-
},
|
|
2407
|
-
onSuccess: (data) => {
|
|
2408
|
-
this.queryClient.invalidateQueries({
|
|
2409
|
-
queryKey: collectionKeys(collection).all
|
|
2410
|
-
});
|
|
2411
|
-
if (PRODUCT_DETAIL_INVALIDATING_COLLECTIONS.has(collection)) {
|
|
2412
|
-
this.queryClient.invalidateQueries({ queryKey: ["products", "detail"] });
|
|
2413
|
-
}
|
|
2414
|
-
options?.onSuccess?.(data);
|
|
2415
|
-
},
|
|
2416
|
-
onError: options?.onError,
|
|
2417
|
-
onSettled: options?.onSettled
|
|
2418
|
-
});
|
|
2419
|
-
}
|
|
2420
|
-
useUpdate(params, options) {
|
|
2421
|
-
const { collection } = params;
|
|
2422
|
-
return (0, import_react_query2.useMutation)({
|
|
2423
|
-
mutationFn: async (variables) => {
|
|
2424
|
-
return await this.collectionClient.from(collection).update(
|
|
2425
|
-
variables.id,
|
|
2426
|
-
variables.data,
|
|
2427
|
-
variables.file ? { file: variables.file, filename: variables.filename } : void 0
|
|
2428
|
-
);
|
|
2429
|
-
},
|
|
2430
|
-
onSuccess: (data) => {
|
|
2431
|
-
this.queryClient.invalidateQueries({
|
|
2432
|
-
queryKey: collectionKeys(collection).all
|
|
2433
|
-
});
|
|
2434
|
-
if (PRODUCT_DETAIL_INVALIDATING_COLLECTIONS.has(collection)) {
|
|
2435
|
-
this.queryClient.invalidateQueries({ queryKey: ["products", "detail"] });
|
|
2436
|
-
}
|
|
2437
|
-
options?.onSuccess?.(data);
|
|
2438
|
-
},
|
|
2439
|
-
onError: options?.onError,
|
|
2440
|
-
onSettled: options?.onSettled
|
|
2441
|
-
});
|
|
2442
|
-
}
|
|
2443
|
-
useRemove(params, options) {
|
|
2444
|
-
const { collection } = params;
|
|
2445
|
-
return (0, import_react_query2.useMutation)({
|
|
2446
|
-
mutationFn: async (id) => {
|
|
2447
|
-
return await this.collectionClient.from(collection).remove(id);
|
|
2448
|
-
},
|
|
2449
|
-
onSuccess: (data) => {
|
|
2450
|
-
this.queryClient.invalidateQueries({
|
|
2451
|
-
queryKey: collectionKeys(collection).all
|
|
2452
|
-
});
|
|
2453
|
-
if (PRODUCT_DETAIL_INVALIDATING_COLLECTIONS.has(collection)) {
|
|
2454
|
-
this.queryClient.invalidateQueries({ queryKey: ["products", "detail"] });
|
|
2455
|
-
}
|
|
2456
|
-
options?.onSuccess?.(data);
|
|
2457
|
-
},
|
|
2458
|
-
onError: options?.onError,
|
|
2459
|
-
onSettled: options?.onSettled
|
|
2460
|
-
});
|
|
2461
|
-
}
|
|
2462
|
-
// ===== Cache Utilities =====
|
|
2463
|
-
invalidateQueries(collection, type) {
|
|
2464
|
-
const queryKey = type ? [collection, type] : [collection];
|
|
2465
|
-
return this.queryClient.invalidateQueries({ queryKey });
|
|
2466
|
-
}
|
|
2467
|
-
getQueryData(collection, type, idOrOptions, options) {
|
|
2468
|
-
if (type === "list") {
|
|
2469
|
-
return this.queryClient.getQueryData(
|
|
2470
|
-
collectionKeys(collection).list(idOrOptions)
|
|
2471
|
-
);
|
|
2472
|
-
}
|
|
2473
|
-
return this.queryClient.getQueryData(
|
|
2474
|
-
collectionKeys(collection).detail(idOrOptions, options)
|
|
2475
|
-
);
|
|
2476
|
-
}
|
|
2477
|
-
setQueryData(collection, type, dataOrId, dataOrOptions, options) {
|
|
2478
|
-
if (type === "list") {
|
|
2479
|
-
this.queryClient.setQueryData(
|
|
2480
|
-
collectionKeys(collection).list(dataOrOptions),
|
|
2481
|
-
dataOrId
|
|
2482
|
-
);
|
|
2483
|
-
} else {
|
|
2484
|
-
this.queryClient.setQueryData(
|
|
2485
|
-
collectionKeys(collection).detail(dataOrId, options),
|
|
2486
|
-
dataOrOptions
|
|
2487
|
-
);
|
|
2488
|
-
}
|
|
2489
|
-
}
|
|
2490
|
-
};
|
|
2491
|
-
|
|
2492
|
-
// src/core/query/customer-hooks.ts
|
|
2493
|
-
var import_react_query3 = require("@tanstack/react-query");
|
|
2494
|
-
function createMutation(mutationFn, callbacks, onSuccessExtra) {
|
|
2495
|
-
return (0, import_react_query3.useMutation)({
|
|
2496
|
-
mutationFn,
|
|
2497
|
-
onSuccess: (data) => {
|
|
2498
|
-
onSuccessExtra?.(data);
|
|
2499
|
-
callbacks?.onSuccess?.(data);
|
|
2500
|
-
},
|
|
2501
|
-
onError: callbacks?.onError,
|
|
2502
|
-
onSettled: callbacks?.onSettled
|
|
2503
|
-
});
|
|
2504
|
-
}
|
|
2505
|
-
var CustomerHooks = class {
|
|
2506
|
-
constructor(queryClient, customerAuth) {
|
|
2507
|
-
this.invalidateMe = () => {
|
|
2508
|
-
this.queryClient.invalidateQueries({ queryKey: customerKeys.me() });
|
|
2509
|
-
};
|
|
2510
|
-
this.queryClient = queryClient;
|
|
2511
|
-
this.customerAuth = customerAuth;
|
|
2512
|
-
}
|
|
2513
|
-
ensureCustomerAuth() {
|
|
2514
|
-
if (!this.customerAuth) {
|
|
2515
|
-
throw createConfigError(
|
|
2516
|
-
"Customer hooks require Client. Use createClient() instead of createServerClient()."
|
|
2517
|
-
);
|
|
2518
|
-
}
|
|
2519
|
-
return this.customerAuth;
|
|
2520
|
-
}
|
|
2521
|
-
// ===== useCustomerMe =====
|
|
2522
|
-
useCustomerMe(options) {
|
|
2523
|
-
return (0, import_react_query3.useQuery)({
|
|
2524
|
-
queryKey: customerKeys.me(),
|
|
2525
|
-
queryFn: async () => {
|
|
2526
|
-
return await this.ensureCustomerAuth().me();
|
|
2527
|
-
},
|
|
2528
|
-
...options,
|
|
2529
|
-
enabled: (options?.enabled ?? true) && !!this.customerAuth?.isAuthenticated()
|
|
2530
|
-
});
|
|
2531
|
-
}
|
|
2532
|
-
// ===== Mutations =====
|
|
2533
|
-
useCustomerLogin(options) {
|
|
2534
|
-
return createMutation(
|
|
2535
|
-
(data) => this.ensureCustomerAuth().login(data),
|
|
2536
|
-
options,
|
|
2537
|
-
this.invalidateMe
|
|
2538
|
-
);
|
|
2539
|
-
}
|
|
2540
|
-
useCustomerRegister(options) {
|
|
2541
|
-
return createMutation(
|
|
2542
|
-
(data) => this.ensureCustomerAuth().register(data),
|
|
2543
|
-
options
|
|
2544
|
-
);
|
|
2545
|
-
}
|
|
2546
|
-
useCustomerLogout(options) {
|
|
2547
|
-
return (0, import_react_query3.useMutation)({
|
|
2548
|
-
mutationFn: async () => {
|
|
2549
|
-
this.ensureCustomerAuth().logout();
|
|
2550
|
-
},
|
|
2551
|
-
onSuccess: () => {
|
|
2552
|
-
this.queryClient.removeQueries({ queryKey: customerKeys.all });
|
|
2553
|
-
options?.onSuccess?.();
|
|
2554
|
-
},
|
|
2555
|
-
onError: options?.onError,
|
|
2556
|
-
onSettled: options?.onSettled
|
|
2557
|
-
});
|
|
2558
|
-
}
|
|
2559
|
-
useCustomerForgotPassword(options) {
|
|
2560
|
-
return createMutation(
|
|
2561
|
-
(email) => this.ensureCustomerAuth().forgotPassword(email).then(() => {
|
|
2562
|
-
}),
|
|
2563
|
-
options
|
|
2564
|
-
);
|
|
2565
|
-
}
|
|
2566
|
-
useCustomerResetPassword(options) {
|
|
2567
|
-
return createMutation(
|
|
2568
|
-
(data) => this.ensureCustomerAuth().resetPassword(data.token, data.password).then(() => {
|
|
2569
|
-
}),
|
|
2570
|
-
options
|
|
2571
|
-
);
|
|
2572
|
-
}
|
|
2573
|
-
useCustomerRefreshToken(options) {
|
|
2574
|
-
return createMutation(
|
|
2575
|
-
() => this.ensureCustomerAuth().refreshToken(),
|
|
2576
|
-
options,
|
|
2577
|
-
this.invalidateMe
|
|
2578
|
-
);
|
|
2579
|
-
}
|
|
2580
|
-
useCustomerUpdateProfile(options) {
|
|
2581
|
-
return createMutation(
|
|
2582
|
-
(data) => this.ensureCustomerAuth().updateProfile(data),
|
|
2583
|
-
options,
|
|
2584
|
-
this.invalidateMe
|
|
2585
|
-
);
|
|
2586
|
-
}
|
|
2587
|
-
useCustomerChangePassword(options) {
|
|
2588
|
-
return createMutation(
|
|
2589
|
-
(data) => this.ensureCustomerAuth().changePassword(data.currentPassword, data.newPassword).then(() => {
|
|
2590
|
-
}),
|
|
2591
|
-
options
|
|
2592
|
-
);
|
|
2593
|
-
}
|
|
2594
|
-
// ===== Customer Cache Utilities =====
|
|
2595
|
-
invalidateCustomerQueries() {
|
|
2596
|
-
return this.queryClient.invalidateQueries({ queryKey: customerKeys.all });
|
|
2597
|
-
}
|
|
2598
|
-
getCustomerData() {
|
|
2599
|
-
return this.queryClient.getQueryData(customerKeys.me());
|
|
2600
|
-
}
|
|
2601
|
-
setCustomerData(data) {
|
|
2602
|
-
this.queryClient.setQueryData(customerKeys.me(), data);
|
|
2603
|
-
}
|
|
2604
|
-
};
|
|
2605
|
-
|
|
2606
|
-
// src/core/query/query-hooks.ts
|
|
2607
|
-
var QueryHooks = class extends CollectionHooks {
|
|
2608
|
-
constructor(queryClient, collectionClient, customerAuth, commerceClient) {
|
|
2609
|
-
super(queryClient, collectionClient);
|
|
2610
|
-
// --- Customer hooks delegation ---
|
|
2611
|
-
this.useCustomerMe = (...args) => this._customer.useCustomerMe(...args);
|
|
2612
|
-
this.useCustomerLogin = (...args) => this._customer.useCustomerLogin(...args);
|
|
2613
|
-
this.useCustomerRegister = (...args) => this._customer.useCustomerRegister(...args);
|
|
2614
|
-
this.useCustomerLogout = (...args) => this._customer.useCustomerLogout(...args);
|
|
2615
|
-
this.useCustomerForgotPassword = (...args) => this._customer.useCustomerForgotPassword(...args);
|
|
2616
|
-
this.useCustomerResetPassword = (...args) => this._customer.useCustomerResetPassword(...args);
|
|
2617
|
-
this.useCustomerRefreshToken = (...args) => this._customer.useCustomerRefreshToken(...args);
|
|
2618
|
-
this.useCustomerUpdateProfile = (...args) => this._customer.useCustomerUpdateProfile(...args);
|
|
2619
|
-
this.useCustomerChangePassword = (...args) => this._customer.useCustomerChangePassword(...args);
|
|
2620
|
-
// --- Customer cache delegation ---
|
|
2621
|
-
this.invalidateCustomerQueries = () => this._customer.invalidateCustomerQueries();
|
|
2622
|
-
this.getCustomerData = () => this._customer.getCustomerData();
|
|
2623
|
-
this.setCustomerData = (data) => this._customer.setCustomerData(data);
|
|
2624
|
-
this._customer = new CustomerHooks(queryClient, customerAuth);
|
|
2625
|
-
this._commerce = commerceClient;
|
|
2626
|
-
}
|
|
2627
|
-
useProductListingGroupsQuery(params, options) {
|
|
2628
|
-
const queryOptions = params.options;
|
|
2629
|
-
const { placeholderData, ...restOptions } = options ?? {};
|
|
2630
|
-
return (0, import_react_query4.useQuery)({
|
|
2631
|
-
queryKey: productKeys.listingGroups(queryOptions),
|
|
2632
|
-
queryFn: async () => this.collectionClient.requestFindEndpoint(
|
|
2633
|
-
"/api/products/listing-groups/query",
|
|
2634
|
-
{ options: queryOptions }
|
|
2635
|
-
),
|
|
2636
|
-
...restOptions,
|
|
2637
|
-
...placeholderData !== void 0 && {
|
|
2638
|
-
placeholderData
|
|
2639
|
-
}
|
|
2640
|
-
});
|
|
2641
|
-
}
|
|
2642
|
-
useSuspenseProductListingGroupsQuery(params, options) {
|
|
2643
|
-
const queryOptions = params.options;
|
|
2644
|
-
return (0, import_react_query4.useSuspenseQuery)({
|
|
2645
|
-
queryKey: productKeys.listingGroups(queryOptions),
|
|
2646
|
-
queryFn: async () => this.collectionClient.requestFindEndpoint(
|
|
2647
|
-
"/api/products/listing-groups/query",
|
|
2648
|
-
{ options: queryOptions }
|
|
2649
|
-
),
|
|
2650
|
-
...options
|
|
2651
|
-
});
|
|
2652
|
-
}
|
|
2653
|
-
useInfiniteProductListingGroupsQuery(params, options) {
|
|
2654
|
-
const {
|
|
2655
|
-
options: queryOptions,
|
|
2656
|
-
pageSize = 20
|
|
2657
|
-
} = params;
|
|
2658
|
-
return (0, import_react_query4.useInfiniteQuery)({
|
|
2659
|
-
queryKey: productKeys.listingGroupsInfinite(queryOptions),
|
|
2660
|
-
queryFn: async ({ pageParam }) => this.collectionClient.requestFindEndpoint(
|
|
2661
|
-
"/api/products/listing-groups/query",
|
|
2662
|
-
{
|
|
2663
|
-
options: { ...queryOptions, page: pageParam, limit: pageSize }
|
|
2664
|
-
}
|
|
2665
|
-
),
|
|
2666
|
-
initialPageParam: 1,
|
|
2667
|
-
getNextPageParam: (lastPage) => lastPage.hasNextPage ? lastPage.nextPage : void 0,
|
|
2668
|
-
...options
|
|
2669
|
-
});
|
|
2670
|
-
}
|
|
2671
|
-
useSuspenseInfiniteProductListingGroupsQuery(params, options) {
|
|
2672
|
-
const {
|
|
2673
|
-
options: queryOptions,
|
|
2674
|
-
pageSize = 20
|
|
2675
|
-
} = params;
|
|
2676
|
-
return (0, import_react_query4.useSuspenseInfiniteQuery)({
|
|
2677
|
-
queryKey: productKeys.listingGroupsInfinite(queryOptions),
|
|
2678
|
-
queryFn: async ({ pageParam }) => this.collectionClient.requestFindEndpoint(
|
|
2679
|
-
"/api/products/listing-groups/query",
|
|
2680
|
-
{
|
|
2681
|
-
options: { ...queryOptions, page: pageParam, limit: pageSize }
|
|
2682
|
-
}
|
|
2683
|
-
),
|
|
2684
|
-
initialPageParam: 1,
|
|
2685
|
-
getNextPageParam: (lastPage) => lastPage.hasNextPage ? lastPage.nextPage : void 0,
|
|
2686
|
-
...options
|
|
2687
|
-
});
|
|
2688
|
-
}
|
|
2689
|
-
async prefetchProductListingGroupsQuery(params, options) {
|
|
2690
|
-
const queryOptions = params.options;
|
|
2691
|
-
return this.queryClient.prefetchQuery({
|
|
2692
|
-
queryKey: productKeys.listingGroups(queryOptions),
|
|
2693
|
-
queryFn: async () => this.collectionClient.requestFindEndpoint(
|
|
2694
|
-
"/api/products/listing-groups/query",
|
|
2695
|
-
{ options: queryOptions }
|
|
2696
|
-
),
|
|
2697
|
-
...options
|
|
2698
|
-
});
|
|
2699
|
-
}
|
|
2700
|
-
async prefetchInfiniteProductListingGroupsQuery(params, options) {
|
|
2701
|
-
const {
|
|
2702
|
-
options: queryOptions,
|
|
2703
|
-
pageSize = 20
|
|
2704
|
-
} = params;
|
|
2705
|
-
return this.queryClient.prefetchInfiniteQuery({
|
|
2706
|
-
queryKey: productKeys.listingGroupsInfinite(queryOptions),
|
|
2707
|
-
queryFn: async ({ pageParam }) => this.collectionClient.requestFindEndpoint(
|
|
2708
|
-
"/api/products/listing-groups/query",
|
|
2709
|
-
{
|
|
2710
|
-
options: { ...queryOptions, page: pageParam, limit: pageSize }
|
|
2711
|
-
}
|
|
2712
|
-
),
|
|
2713
|
-
initialPageParam: 1,
|
|
2714
|
-
getNextPageParam: (lastPage) => lastPage.hasNextPage ? lastPage.nextPage : void 0,
|
|
2715
|
-
pages: options?.pages ?? 1,
|
|
2716
|
-
staleTime: options?.staleTime
|
|
2717
|
-
});
|
|
2718
|
-
}
|
|
2719
|
-
useProductDetail(params, options) {
|
|
2720
|
-
const discriminator = "slug" in params ? params.slug : params.id;
|
|
2721
|
-
const enabled = options?.enabled !== false && Boolean(discriminator);
|
|
2722
|
-
return (0, import_react_query4.useQuery)({
|
|
2723
|
-
queryKey: productKeys.detail(params),
|
|
2724
|
-
queryFn: () => this._commerce.product.detail(params),
|
|
2725
|
-
enabled
|
|
2726
|
-
});
|
|
2727
|
-
}
|
|
2728
|
-
useProductDetailBySlug(slug, options) {
|
|
2729
|
-
return this.useProductDetail({ slug }, options);
|
|
2730
|
-
}
|
|
2731
|
-
useProductDetailById(id, options) {
|
|
2732
|
-
return this.useProductDetail({ id }, options);
|
|
1622
|
+
};
|
|
2733
1623
|
}
|
|
2734
1624
|
};
|
|
2735
1625
|
|
|
@@ -2747,10 +1637,10 @@ var Client = class {
|
|
|
2747
1637
|
userAgent: typeof window !== "undefined" ? window.navigator?.userAgent : "Node.js"
|
|
2748
1638
|
};
|
|
2749
1639
|
this.state = { metadata };
|
|
2750
|
-
this.queryClient = getQueryClient();
|
|
2751
1640
|
this.customer = new CustomerNamespace(
|
|
2752
1641
|
this.config.publishableKey,
|
|
2753
|
-
options.customer
|
|
1642
|
+
options.customer,
|
|
1643
|
+
this.config.apiUrl
|
|
2754
1644
|
);
|
|
2755
1645
|
const onUnauthorized = async () => {
|
|
2756
1646
|
try {
|
|
@@ -2765,6 +1655,7 @@ var Client = class {
|
|
|
2765
1655
|
};
|
|
2766
1656
|
this.commerce = new CommerceClient({
|
|
2767
1657
|
publishableKey: this.config.publishableKey,
|
|
1658
|
+
apiUrl: this.config.apiUrl,
|
|
2768
1659
|
customerToken: () => this.customer.auth.getToken(),
|
|
2769
1660
|
onUnauthorized,
|
|
2770
1661
|
onRequestId,
|
|
@@ -2772,29 +1663,18 @@ var Client = class {
|
|
|
2772
1663
|
});
|
|
2773
1664
|
this.community = new CommunityClient({
|
|
2774
1665
|
publishableKey: this.config.publishableKey,
|
|
1666
|
+
apiUrl: this.config.apiUrl,
|
|
2775
1667
|
customerToken: () => this.customer.auth.getToken(),
|
|
2776
1668
|
onUnauthorized,
|
|
2777
1669
|
onRequestId
|
|
2778
1670
|
});
|
|
2779
|
-
const collectionClient = new CollectionClient(
|
|
2780
|
-
this.config.publishableKey,
|
|
2781
|
-
void 0,
|
|
2782
|
-
() => this.customer.auth.getToken(),
|
|
2783
|
-
onUnauthorized,
|
|
2784
|
-
onRequestId
|
|
2785
|
-
);
|
|
2786
1671
|
this.collections = new ReadOnlyCollectionClient(
|
|
2787
1672
|
this.config.publishableKey,
|
|
2788
1673
|
void 0,
|
|
2789
1674
|
() => this.customer.auth.getToken(),
|
|
2790
1675
|
onUnauthorized,
|
|
2791
|
-
onRequestId
|
|
2792
|
-
|
|
2793
|
-
this.query = new QueryHooks(
|
|
2794
|
-
this.queryClient,
|
|
2795
|
-
collectionClient,
|
|
2796
|
-
this.customer.auth,
|
|
2797
|
-
this.commerce
|
|
1676
|
+
onRequestId,
|
|
1677
|
+
this.config.apiUrl
|
|
2798
1678
|
);
|
|
2799
1679
|
}
|
|
2800
1680
|
getState() {
|
|
@@ -2808,210 +1688,153 @@ function createClient(options) {
|
|
|
2808
1688
|
return new Client(options);
|
|
2809
1689
|
}
|
|
2810
1690
|
|
|
2811
|
-
// src/core/
|
|
2812
|
-
var
|
|
2813
|
-
constructor(options) {
|
|
2814
|
-
this.lastRequestId = null;
|
|
2815
|
-
if (typeof window !== "undefined") {
|
|
2816
|
-
throw createConfigError(
|
|
2817
|
-
"ServerClient must not be used in a browser environment. This risks exposing your secretKey in client bundles. Use createClient() for browser code instead."
|
|
2818
|
-
);
|
|
2819
|
-
}
|
|
1691
|
+
// src/core/api/base-api.ts
|
|
1692
|
+
var BaseApi = class {
|
|
1693
|
+
constructor(apiName, options) {
|
|
2820
1694
|
if (!options.secretKey) {
|
|
2821
|
-
throw createConfigError(
|
|
1695
|
+
throw createConfigError(`secretKey is required for ${apiName}.`);
|
|
2822
1696
|
}
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
1697
|
+
this.publishableKey = requirePublishableKeyForSecret(
|
|
1698
|
+
apiName,
|
|
1699
|
+
options.publishableKey,
|
|
1700
|
+
options.secretKey
|
|
1701
|
+
);
|
|
1702
|
+
this.secretKey = options.secretKey;
|
|
1703
|
+
this.apiUrl = options.apiUrl;
|
|
1704
|
+
this.onRequestId = options.onRequestId;
|
|
1705
|
+
}
|
|
1706
|
+
async request(endpoint, body, options) {
|
|
1707
|
+
const method = options?.method ?? "POST";
|
|
1708
|
+
try {
|
|
1709
|
+
const response = await httpFetch(endpoint, {
|
|
1710
|
+
method,
|
|
1711
|
+
apiUrl: this.apiUrl,
|
|
1712
|
+
publishableKey: this.publishableKey,
|
|
1713
|
+
secretKey: this.secretKey,
|
|
1714
|
+
...body !== void 0 && { body: JSON.stringify(body) },
|
|
1715
|
+
...options?.headers && { headers: options.headers }
|
|
1716
|
+
});
|
|
1717
|
+
this.onRequestId?.(response.headers.get("x-request-id") ?? null);
|
|
1718
|
+
return parseApiResponse(response, endpoint);
|
|
1719
|
+
} catch (err) {
|
|
1720
|
+
const id = err instanceof SDKError ? err.requestId ?? null : null;
|
|
1721
|
+
this.onRequestId?.(id);
|
|
1722
|
+
throw err;
|
|
2827
1723
|
}
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
}
|
|
2850
|
-
});
|
|
2851
|
-
this.collections = new ServerCollectionClient(
|
|
2852
|
-
this.config.publishableKey,
|
|
2853
|
-
this.config.secretKey,
|
|
2854
|
-
void 0,
|
|
2855
|
-
void 0,
|
|
2856
|
-
onRequestId
|
|
1724
|
+
}
|
|
1725
|
+
};
|
|
1726
|
+
|
|
1727
|
+
// src/core/api/order-api.ts
|
|
1728
|
+
var OrderApi = class extends BaseApi {
|
|
1729
|
+
constructor(options) {
|
|
1730
|
+
super("OrderApi", options);
|
|
1731
|
+
}
|
|
1732
|
+
createOrder(params) {
|
|
1733
|
+
return this.request("/api/orders/create", params);
|
|
1734
|
+
}
|
|
1735
|
+
updateOrder(params) {
|
|
1736
|
+
return this.request("/api/orders/update", params);
|
|
1737
|
+
}
|
|
1738
|
+
updateTransaction(params) {
|
|
1739
|
+
return this.request("/api/transactions/update", params);
|
|
1740
|
+
}
|
|
1741
|
+
confirmPayment(params) {
|
|
1742
|
+
return this.request(
|
|
1743
|
+
"/api/orders/confirm-payment",
|
|
1744
|
+
params,
|
|
1745
|
+
params.providerEventId ? { headers: { "X-Idempotency-Key": params.providerEventId } } : void 0
|
|
2857
1746
|
);
|
|
2858
|
-
this.queryClient = getQueryClient();
|
|
2859
|
-
this.query = new QueryHooks(this.queryClient, this.collections, void 0, this.commerce);
|
|
2860
1747
|
}
|
|
2861
|
-
|
|
2862
|
-
return
|
|
1748
|
+
checkout(params) {
|
|
1749
|
+
return this.request("/api/orders/checkout", params);
|
|
2863
1750
|
}
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
1751
|
+
createFulfillment(params) {
|
|
1752
|
+
return this.request("/api/orders/create-fulfillment", params);
|
|
1753
|
+
}
|
|
1754
|
+
updateFulfillment(params) {
|
|
1755
|
+
return this.request("/api/orders/update-fulfillment", params);
|
|
1756
|
+
}
|
|
1757
|
+
bulkImportFulfillments(params) {
|
|
1758
|
+
return this.request(
|
|
1759
|
+
"/api/orders/bulk-import-fulfillments",
|
|
1760
|
+
params
|
|
1761
|
+
);
|
|
1762
|
+
}
|
|
1763
|
+
returnWithRefund(params) {
|
|
1764
|
+
return this.request(
|
|
1765
|
+
"/api/returns/return-refund",
|
|
1766
|
+
params
|
|
1767
|
+
);
|
|
1768
|
+
}
|
|
1769
|
+
createReturn(params) {
|
|
1770
|
+
return this.request("/api/returns/create", params);
|
|
1771
|
+
}
|
|
1772
|
+
updateReturn(params) {
|
|
1773
|
+
return this.request("/api/returns/update", params);
|
|
2867
1774
|
}
|
|
2868
1775
|
};
|
|
2869
|
-
function createServerClient(options) {
|
|
2870
|
-
return new ServerClient(options);
|
|
2871
|
-
}
|
|
2872
1776
|
|
|
2873
|
-
// src/core/
|
|
2874
|
-
var
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
var MAX_NO_TOKEN_RETRIES = 5;
|
|
2878
|
-
var RealtimeConnection = class {
|
|
2879
|
-
constructor(baseUrl, publishableKey, getToken, collections) {
|
|
2880
|
-
this.baseUrl = baseUrl;
|
|
2881
|
-
this.publishableKey = publishableKey;
|
|
2882
|
-
this.getToken = getToken;
|
|
2883
|
-
this.collections = collections;
|
|
2884
|
-
this.abortController = null;
|
|
2885
|
-
this.reconnectAttempt = 0;
|
|
2886
|
-
this.noTokenAttempts = 0;
|
|
2887
|
-
this.reconnectTimer = null;
|
|
2888
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
2889
|
-
this._connected = false;
|
|
2890
|
-
}
|
|
2891
|
-
get connected() {
|
|
2892
|
-
return this._connected;
|
|
1777
|
+
// src/core/api/discount-api.ts
|
|
1778
|
+
var DiscountApi = class extends BaseApi {
|
|
1779
|
+
constructor(options) {
|
|
1780
|
+
super("DiscountApi", options);
|
|
2893
1781
|
}
|
|
2894
|
-
|
|
2895
|
-
this.
|
|
2896
|
-
return () => this.listeners.delete(fn);
|
|
1782
|
+
validate(params) {
|
|
1783
|
+
return this.request("/api/discounts/validate", params);
|
|
2897
1784
|
}
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
|
|
2901
|
-
|
|
1785
|
+
};
|
|
1786
|
+
|
|
1787
|
+
// src/core/api/shipping-api.ts
|
|
1788
|
+
var ShippingApi = class extends BaseApi {
|
|
1789
|
+
constructor(options) {
|
|
1790
|
+
super("ShippingApi", options);
|
|
2902
1791
|
}
|
|
2903
|
-
|
|
2904
|
-
this.
|
|
2905
|
-
if (this.reconnectTimer) {
|
|
2906
|
-
clearTimeout(this.reconnectTimer);
|
|
2907
|
-
this.reconnectTimer = null;
|
|
2908
|
-
}
|
|
2909
|
-
if (this.abortController) {
|
|
2910
|
-
this.abortController.abort();
|
|
2911
|
-
this.abortController = null;
|
|
2912
|
-
}
|
|
2913
|
-
this.reconnectAttempt = 0;
|
|
2914
|
-
this.noTokenAttempts = 0;
|
|
1792
|
+
calculate(params) {
|
|
1793
|
+
return this.request("/api/shipping-policies/calculate", params);
|
|
2915
1794
|
}
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
this.abortController = null;
|
|
2923
|
-
return;
|
|
2924
|
-
}
|
|
2925
|
-
this.scheduleReconnect();
|
|
2926
|
-
return;
|
|
2927
|
-
}
|
|
2928
|
-
this.noTokenAttempts = 0;
|
|
2929
|
-
const params = this.collections?.length ? `?collections=${this.collections.join(",")}` : "";
|
|
2930
|
-
const url = `${this.baseUrl}/api/events/stream${params}`;
|
|
2931
|
-
try {
|
|
2932
|
-
const response = await fetch(url, {
|
|
2933
|
-
headers: {
|
|
2934
|
-
"X-Publishable-Key": this.publishableKey,
|
|
2935
|
-
Authorization: `Bearer ${token}`
|
|
2936
|
-
},
|
|
2937
|
-
signal
|
|
2938
|
-
});
|
|
2939
|
-
if (!response.ok) {
|
|
2940
|
-
if (response.status === 401) {
|
|
2941
|
-
this.scheduleReconnect();
|
|
2942
|
-
return;
|
|
2943
|
-
}
|
|
2944
|
-
throw new Error(`SSE connection failed: ${response.status}`);
|
|
2945
|
-
}
|
|
2946
|
-
if (!response.body) {
|
|
2947
|
-
throw new Error("SSE response has no body");
|
|
2948
|
-
}
|
|
2949
|
-
this._connected = true;
|
|
2950
|
-
this.reconnectAttempt = 0;
|
|
2951
|
-
await this.readStream(response.body, signal);
|
|
2952
|
-
} catch {
|
|
2953
|
-
if (signal.aborted) return;
|
|
2954
|
-
this._connected = false;
|
|
2955
|
-
this.scheduleReconnect();
|
|
2956
|
-
}
|
|
1795
|
+
};
|
|
1796
|
+
|
|
1797
|
+
// src/core/api/product-api.ts
|
|
1798
|
+
var ProductApi = class extends BaseApi {
|
|
1799
|
+
constructor(options) {
|
|
1800
|
+
super("ProductApi", options);
|
|
2957
1801
|
}
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
while (true) {
|
|
2966
|
-
const { done, value } = await reader.read();
|
|
2967
|
-
if (done || signal.aborted) break;
|
|
2968
|
-
buffer += decoder.decode(value, { stream: true });
|
|
2969
|
-
const lines = buffer.split("\n");
|
|
2970
|
-
buffer = lines.pop() ?? "";
|
|
2971
|
-
for (const line of lines) {
|
|
2972
|
-
if (line.startsWith("event: ")) {
|
|
2973
|
-
currentEvent = line.slice(7);
|
|
2974
|
-
} else if (line.startsWith("data: ")) {
|
|
2975
|
-
currentData += (currentData ? "\n" : "") + line.slice(6);
|
|
2976
|
-
} else if (line === "") {
|
|
2977
|
-
if (currentEvent === "collection:change" && currentData) {
|
|
2978
|
-
try {
|
|
2979
|
-
const event = JSON.parse(currentData);
|
|
2980
|
-
for (const listener of this.listeners) {
|
|
2981
|
-
try {
|
|
2982
|
-
listener(event);
|
|
2983
|
-
} catch {
|
|
2984
|
-
}
|
|
2985
|
-
}
|
|
2986
|
-
} catch {
|
|
2987
|
-
}
|
|
2988
|
-
}
|
|
2989
|
-
currentEvent = "";
|
|
2990
|
-
currentData = "";
|
|
2991
|
-
}
|
|
2992
|
-
}
|
|
2993
|
-
}
|
|
2994
|
-
} catch {
|
|
2995
|
-
} finally {
|
|
2996
|
-
reader.releaseLock();
|
|
2997
|
-
this._connected = false;
|
|
2998
|
-
if (!signal.aborted) {
|
|
2999
|
-
this.scheduleReconnect();
|
|
3000
|
-
}
|
|
3001
|
-
}
|
|
1802
|
+
/**
|
|
1803
|
+
* Check point-in-time stock availability for one or more product variants.
|
|
1804
|
+
* Results reflect available stock at the moment of the call and are not guaranteed
|
|
1805
|
+
* to remain available by the time an order is placed.
|
|
1806
|
+
*/
|
|
1807
|
+
stockCheck(params) {
|
|
1808
|
+
return this.request("/api/products/stock-check", params);
|
|
3002
1809
|
}
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
MAX_RECONNECT_DELAY
|
|
1810
|
+
listingGroups(params) {
|
|
1811
|
+
return this.request(
|
|
1812
|
+
"/api/products/listing-groups",
|
|
1813
|
+
params
|
|
3008
1814
|
);
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
1815
|
+
}
|
|
1816
|
+
/**
|
|
1817
|
+
* Fetch full product detail by slug or id.
|
|
1818
|
+
* Returns `null` on 404 regardless of reason (`not_found` / `not_published` /
|
|
1819
|
+
* `tenant_mismatch` / `feature_disabled`). For the reason behind a null,
|
|
1820
|
+
* inspect `client.lastRequestId` against backend logs.
|
|
1821
|
+
*/
|
|
1822
|
+
async detail(params) {
|
|
1823
|
+
try {
|
|
1824
|
+
return await this.request("/api/products/detail", params);
|
|
1825
|
+
} catch (err) {
|
|
1826
|
+
if (err instanceof NotFoundError) return null;
|
|
1827
|
+
throw err;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
/**
|
|
1831
|
+
* Atomically create or update a product together with its options,
|
|
1832
|
+
* option-values, and variants in a single transaction. Mirrors Shopify's
|
|
1833
|
+
* `productSet` shape and is the canonical write path for the MCP
|
|
1834
|
+
* `product-upsert` tool.
|
|
1835
|
+
*/
|
|
1836
|
+
upsert(params) {
|
|
1837
|
+
return this.request("/api/products/upsert", params);
|
|
3015
1838
|
}
|
|
3016
1839
|
};
|
|
3017
1840
|
|
|
@@ -3096,41 +1919,307 @@ async function handleWebhook(request, handler, options) {
|
|
|
3096
1919
|
{ status: 401, headers: { "Content-Type": "application/json" } }
|
|
3097
1920
|
);
|
|
3098
1921
|
}
|
|
3099
|
-
} else {
|
|
3100
|
-
console.warn(
|
|
3101
|
-
"[@01.software/sdk] Webhook signature verification is disabled. Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification."
|
|
3102
|
-
);
|
|
1922
|
+
} else {
|
|
1923
|
+
console.warn(
|
|
1924
|
+
"[@01.software/sdk] Webhook signature verification is disabled. Set { secret } in handleWebhook() options to enable HMAC-SHA256 verification."
|
|
1925
|
+
);
|
|
1926
|
+
}
|
|
1927
|
+
const body = JSON.parse(rawBody);
|
|
1928
|
+
if (!isValidWebhookEvent(body)) {
|
|
1929
|
+
return new Response(
|
|
1930
|
+
JSON.stringify({ error: "Invalid webhook event format" }),
|
|
1931
|
+
{ status: 400, headers: { "Content-Type": "application/json" } }
|
|
1932
|
+
);
|
|
1933
|
+
}
|
|
1934
|
+
await handler(body);
|
|
1935
|
+
return new Response(
|
|
1936
|
+
JSON.stringify({ success: true, message: "Webhook processed" }),
|
|
1937
|
+
{ status: 200, headers: { "Content-Type": "application/json" } }
|
|
1938
|
+
);
|
|
1939
|
+
} catch (error) {
|
|
1940
|
+
console.error("Webhook processing error:", error);
|
|
1941
|
+
return new Response(JSON.stringify({ error: "Internal server error" }), {
|
|
1942
|
+
status: 500,
|
|
1943
|
+
headers: { "Content-Type": "application/json" }
|
|
1944
|
+
});
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1947
|
+
function createTypedWebhookHandler(collection, handler) {
|
|
1948
|
+
return async (event) => {
|
|
1949
|
+
if (event.collection !== collection) {
|
|
1950
|
+
throw new Error(
|
|
1951
|
+
`Expected collection "${collection}", got "${event.collection}"`
|
|
1952
|
+
);
|
|
1953
|
+
}
|
|
1954
|
+
return handler(event);
|
|
1955
|
+
};
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
// src/core/collection/const.ts
|
|
1959
|
+
var INTERNAL_COLLECTIONS = [
|
|
1960
|
+
"users",
|
|
1961
|
+
"payload-kv",
|
|
1962
|
+
"payload-locked-documents",
|
|
1963
|
+
"payload-preferences",
|
|
1964
|
+
"payload-migrations",
|
|
1965
|
+
"payload-folders",
|
|
1966
|
+
"field-configs",
|
|
1967
|
+
"system-media",
|
|
1968
|
+
"track-assets",
|
|
1969
|
+
"audiences",
|
|
1970
|
+
"email-logs",
|
|
1971
|
+
"api-usage",
|
|
1972
|
+
"tenant-analytics-daily",
|
|
1973
|
+
"tenant-web-analytics-config",
|
|
1974
|
+
"analytics-event-schemas",
|
|
1975
|
+
"subscriptions",
|
|
1976
|
+
"billing-history",
|
|
1977
|
+
"inventory-reservations",
|
|
1978
|
+
"product-collection-items",
|
|
1979
|
+
"order-status-logs",
|
|
1980
|
+
"api-keys",
|
|
1981
|
+
"personal-access-tokens",
|
|
1982
|
+
"tenant-entitlements",
|
|
1983
|
+
"tenant-purge-jobs",
|
|
1984
|
+
"direct-upload-sessions",
|
|
1985
|
+
"webhook-events",
|
|
1986
|
+
"webhook-deliveries",
|
|
1987
|
+
"audit-logs",
|
|
1988
|
+
"plans",
|
|
1989
|
+
"webhooks",
|
|
1990
|
+
"event-registrations"
|
|
1991
|
+
];
|
|
1992
|
+
var COLLECTIONS = [
|
|
1993
|
+
"tenants",
|
|
1994
|
+
"tenant-metadata",
|
|
1995
|
+
"tenant-logos",
|
|
1996
|
+
"products",
|
|
1997
|
+
"product-variants",
|
|
1998
|
+
"product-options",
|
|
1999
|
+
"product-option-values",
|
|
2000
|
+
"product-categories",
|
|
2001
|
+
"product-tags",
|
|
2002
|
+
"product-collections",
|
|
2003
|
+
"brands",
|
|
2004
|
+
"brand-logos",
|
|
2005
|
+
"orders",
|
|
2006
|
+
"order-items",
|
|
2007
|
+
"returns",
|
|
2008
|
+
"return-items",
|
|
2009
|
+
"fulfillments",
|
|
2010
|
+
"fulfillment-items",
|
|
2011
|
+
"transactions",
|
|
2012
|
+
"customers",
|
|
2013
|
+
"customer-profiles",
|
|
2014
|
+
"customer-addresses",
|
|
2015
|
+
"carts",
|
|
2016
|
+
"cart-items",
|
|
2017
|
+
"discounts",
|
|
2018
|
+
"shipping-policies",
|
|
2019
|
+
"shipping-zones",
|
|
2020
|
+
"documents",
|
|
2021
|
+
"document-categories",
|
|
2022
|
+
"document-types",
|
|
2023
|
+
"articles",
|
|
2024
|
+
"article-authors",
|
|
2025
|
+
"article-categories",
|
|
2026
|
+
"article-tags",
|
|
2027
|
+
"playlists",
|
|
2028
|
+
"playlist-categories",
|
|
2029
|
+
"playlist-tags",
|
|
2030
|
+
"tracks",
|
|
2031
|
+
"track-categories",
|
|
2032
|
+
"track-tags",
|
|
2033
|
+
"galleries",
|
|
2034
|
+
"gallery-categories",
|
|
2035
|
+
"gallery-tags",
|
|
2036
|
+
"gallery-items",
|
|
2037
|
+
"links",
|
|
2038
|
+
"link-categories",
|
|
2039
|
+
"link-tags",
|
|
2040
|
+
"canvases",
|
|
2041
|
+
"canvas-node-types",
|
|
2042
|
+
"canvas-edge-types",
|
|
2043
|
+
"canvas-categories",
|
|
2044
|
+
"canvas-tags",
|
|
2045
|
+
"canvas-nodes",
|
|
2046
|
+
"canvas-edges",
|
|
2047
|
+
"videos",
|
|
2048
|
+
"video-categories",
|
|
2049
|
+
"video-tags",
|
|
2050
|
+
"live-streams",
|
|
2051
|
+
"images",
|
|
2052
|
+
"forms",
|
|
2053
|
+
"form-submissions",
|
|
2054
|
+
// Community
|
|
2055
|
+
"posts",
|
|
2056
|
+
"comments",
|
|
2057
|
+
"reactions",
|
|
2058
|
+
"reaction-types",
|
|
2059
|
+
"bookmarks",
|
|
2060
|
+
"post-categories",
|
|
2061
|
+
"customer-profile-lists",
|
|
2062
|
+
// Events
|
|
2063
|
+
"event-calendars",
|
|
2064
|
+
"events",
|
|
2065
|
+
"event-categories",
|
|
2066
|
+
"event-occurrences",
|
|
2067
|
+
"event-tags"
|
|
2068
|
+
];
|
|
2069
|
+
var SERVER_ONLY_COLLECTIONS = [
|
|
2070
|
+
"customer-groups",
|
|
2071
|
+
"reports",
|
|
2072
|
+
"community-bans"
|
|
2073
|
+
];
|
|
2074
|
+
var SERVER_COLLECTIONS = [
|
|
2075
|
+
...COLLECTIONS,
|
|
2076
|
+
...SERVER_ONLY_COLLECTIONS
|
|
2077
|
+
];
|
|
2078
|
+
|
|
2079
|
+
// src/core/query/realtime.ts
|
|
2080
|
+
var INITIAL_RECONNECT_DELAY = 1e3;
|
|
2081
|
+
var MAX_RECONNECT_DELAY = 3e4;
|
|
2082
|
+
var RECONNECT_BACKOFF_FACTOR = 2;
|
|
2083
|
+
var MAX_NO_TOKEN_RETRIES = 5;
|
|
2084
|
+
var RealtimeConnection = class {
|
|
2085
|
+
constructor(baseUrl, publishableKey, getToken, collections) {
|
|
2086
|
+
this.baseUrl = baseUrl;
|
|
2087
|
+
this.publishableKey = publishableKey;
|
|
2088
|
+
this.getToken = getToken;
|
|
2089
|
+
this.collections = collections;
|
|
2090
|
+
this.abortController = null;
|
|
2091
|
+
this.reconnectAttempt = 0;
|
|
2092
|
+
this.noTokenAttempts = 0;
|
|
2093
|
+
this.reconnectTimer = null;
|
|
2094
|
+
this.listeners = /* @__PURE__ */ new Set();
|
|
2095
|
+
this._connected = false;
|
|
2096
|
+
}
|
|
2097
|
+
get connected() {
|
|
2098
|
+
return this._connected;
|
|
2099
|
+
}
|
|
2100
|
+
addListener(fn) {
|
|
2101
|
+
this.listeners.add(fn);
|
|
2102
|
+
return () => this.listeners.delete(fn);
|
|
2103
|
+
}
|
|
2104
|
+
connect() {
|
|
2105
|
+
if (this.abortController) return;
|
|
2106
|
+
this.abortController = new AbortController();
|
|
2107
|
+
this.startStream(this.abortController.signal);
|
|
2108
|
+
}
|
|
2109
|
+
disconnect() {
|
|
2110
|
+
this._connected = false;
|
|
2111
|
+
if (this.reconnectTimer) {
|
|
2112
|
+
clearTimeout(this.reconnectTimer);
|
|
2113
|
+
this.reconnectTimer = null;
|
|
2114
|
+
}
|
|
2115
|
+
if (this.abortController) {
|
|
2116
|
+
this.abortController.abort();
|
|
2117
|
+
this.abortController = null;
|
|
2118
|
+
}
|
|
2119
|
+
this.reconnectAttempt = 0;
|
|
2120
|
+
this.noTokenAttempts = 0;
|
|
2121
|
+
}
|
|
2122
|
+
async startStream(signal) {
|
|
2123
|
+
const token = this.getToken();
|
|
2124
|
+
if (!token) {
|
|
2125
|
+
this.noTokenAttempts++;
|
|
2126
|
+
if (this.noTokenAttempts >= MAX_NO_TOKEN_RETRIES) {
|
|
2127
|
+
this._connected = false;
|
|
2128
|
+
this.abortController = null;
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2131
|
+
this.scheduleReconnect();
|
|
2132
|
+
return;
|
|
2133
|
+
}
|
|
2134
|
+
this.noTokenAttempts = 0;
|
|
2135
|
+
const params = this.collections?.length ? `?collections=${this.collections.join(",")}` : "";
|
|
2136
|
+
const url = `${this.baseUrl}/api/events/stream${params}`;
|
|
2137
|
+
try {
|
|
2138
|
+
const response = await fetch(url, {
|
|
2139
|
+
headers: {
|
|
2140
|
+
"X-Publishable-Key": this.publishableKey,
|
|
2141
|
+
Authorization: `Bearer ${token}`
|
|
2142
|
+
},
|
|
2143
|
+
signal
|
|
2144
|
+
});
|
|
2145
|
+
if (!response.ok) {
|
|
2146
|
+
if (response.status === 401) {
|
|
2147
|
+
this.scheduleReconnect();
|
|
2148
|
+
return;
|
|
2149
|
+
}
|
|
2150
|
+
throw new Error(`SSE connection failed: ${response.status}`);
|
|
2151
|
+
}
|
|
2152
|
+
if (!response.body) {
|
|
2153
|
+
throw new Error("SSE response has no body");
|
|
2154
|
+
}
|
|
2155
|
+
this._connected = true;
|
|
2156
|
+
this.reconnectAttempt = 0;
|
|
2157
|
+
await this.readStream(response.body, signal);
|
|
2158
|
+
} catch {
|
|
2159
|
+
if (signal.aborted) return;
|
|
2160
|
+
this._connected = false;
|
|
2161
|
+
this.scheduleReconnect();
|
|
3103
2162
|
}
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
2163
|
+
}
|
|
2164
|
+
async readStream(body, signal) {
|
|
2165
|
+
const reader = body.getReader();
|
|
2166
|
+
const decoder = new TextDecoder();
|
|
2167
|
+
let buffer = "";
|
|
2168
|
+
let currentEvent = "";
|
|
2169
|
+
let currentData = "";
|
|
2170
|
+
try {
|
|
2171
|
+
while (true) {
|
|
2172
|
+
const { done, value } = await reader.read();
|
|
2173
|
+
if (done || signal.aborted) break;
|
|
2174
|
+
buffer += decoder.decode(value, { stream: true });
|
|
2175
|
+
const lines = buffer.split("\n");
|
|
2176
|
+
buffer = lines.pop() ?? "";
|
|
2177
|
+
for (const line of lines) {
|
|
2178
|
+
if (line.startsWith("event: ")) {
|
|
2179
|
+
currentEvent = line.slice(7);
|
|
2180
|
+
} else if (line.startsWith("data: ")) {
|
|
2181
|
+
currentData += (currentData ? "\n" : "") + line.slice(6);
|
|
2182
|
+
} else if (line === "") {
|
|
2183
|
+
if (currentEvent === "collection:change" && currentData) {
|
|
2184
|
+
try {
|
|
2185
|
+
const event = JSON.parse(currentData);
|
|
2186
|
+
for (const listener of this.listeners) {
|
|
2187
|
+
try {
|
|
2188
|
+
listener(event);
|
|
2189
|
+
} catch {
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
} catch {
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
currentEvent = "";
|
|
2196
|
+
currentData = "";
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
} catch {
|
|
2201
|
+
} finally {
|
|
2202
|
+
reader.releaseLock();
|
|
2203
|
+
this._connected = false;
|
|
2204
|
+
if (!signal.aborted) {
|
|
2205
|
+
this.scheduleReconnect();
|
|
2206
|
+
}
|
|
3110
2207
|
}
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
2208
|
+
}
|
|
2209
|
+
scheduleReconnect() {
|
|
2210
|
+
if (this.reconnectTimer) return;
|
|
2211
|
+
const delay2 = Math.min(
|
|
2212
|
+
INITIAL_RECONNECT_DELAY * Math.pow(RECONNECT_BACKOFF_FACTOR, this.reconnectAttempt),
|
|
2213
|
+
MAX_RECONNECT_DELAY
|
|
3115
2214
|
);
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
});
|
|
2215
|
+
this.reconnectAttempt++;
|
|
2216
|
+
this.reconnectTimer = setTimeout(() => {
|
|
2217
|
+
this.reconnectTimer = null;
|
|
2218
|
+
this.abortController = new AbortController();
|
|
2219
|
+
this.startStream(this.abortController.signal);
|
|
2220
|
+
}, delay2);
|
|
3122
2221
|
}
|
|
3123
|
-
}
|
|
3124
|
-
function createTypedWebhookHandler(collection, handler) {
|
|
3125
|
-
return async (event) => {
|
|
3126
|
-
if (event.collection !== collection) {
|
|
3127
|
-
throw new Error(
|
|
3128
|
-
`Expected collection "${collection}", got "${event.collection}"`
|
|
3129
|
-
);
|
|
3130
|
-
}
|
|
3131
|
-
return handler(event);
|
|
3132
|
-
};
|
|
3133
|
-
}
|
|
2222
|
+
};
|
|
3134
2223
|
|
|
3135
2224
|
// src/utils/ecommerce.ts
|
|
3136
2225
|
var ProductSelectionCodecError = class extends Error {
|
|
@@ -3416,38 +2505,45 @@ function hasExplicitSelection(selection) {
|
|
|
3416
2505
|
);
|
|
3417
2506
|
}
|
|
3418
2507
|
function assignSelectedValue(matrix, selectedByOptionId, optionId, valueId) {
|
|
3419
|
-
if (valueId == null) return;
|
|
2508
|
+
if (valueId == null) return false;
|
|
3420
2509
|
const normalizedValueId = String(valueId);
|
|
3421
|
-
if (matrix.valueToOptionId.get(normalizedValueId) !== optionId) return;
|
|
2510
|
+
if (matrix.valueToOptionId.get(normalizedValueId) !== optionId) return false;
|
|
3422
2511
|
selectedByOptionId.set(optionId, normalizedValueId);
|
|
2512
|
+
return true;
|
|
3423
2513
|
}
|
|
3424
2514
|
function assignSelectedValueSlugByOptionId(matrix, selectedByOptionId, optionId, valueSlug) {
|
|
3425
|
-
if (!valueSlug) return;
|
|
2515
|
+
if (!valueSlug) return false;
|
|
3426
2516
|
const option = matrix.optionById.get(optionId);
|
|
3427
|
-
if (!option) return;
|
|
3428
|
-
const
|
|
3429
|
-
|
|
2517
|
+
if (!option) return false;
|
|
2518
|
+
const values = option.values.filter(
|
|
2519
|
+
(candidate) => candidate.slug === valueSlug
|
|
2520
|
+
);
|
|
2521
|
+
if (values.length > 1) {
|
|
2522
|
+
throw new ProductSelectionCodecError(
|
|
2523
|
+
`Ambiguous product selection value slug "${valueSlug}" for option "${optionId}". Use opt.<optionId>=<valueId>.`
|
|
2524
|
+
);
|
|
2525
|
+
}
|
|
2526
|
+
const value = values[0];
|
|
2527
|
+
if (!value) return false;
|
|
3430
2528
|
selectedByOptionId.set(optionId, value.id);
|
|
2529
|
+
return true;
|
|
3431
2530
|
}
|
|
3432
2531
|
function assignSelectedValueSlugByOptionSlug(matrix, selectedByOptionId, optionSlug, valueSlug) {
|
|
3433
|
-
if (!valueSlug) return;
|
|
2532
|
+
if (!valueSlug) return false;
|
|
3434
2533
|
const option = matrix.optionBySlug.get(optionSlug);
|
|
3435
|
-
if (!option) return;
|
|
3436
|
-
const
|
|
3437
|
-
|
|
3438
|
-
selectedByOptionId.set(option.id, value.id);
|
|
3439
|
-
}
|
|
3440
|
-
function requireValueSlug(value) {
|
|
3441
|
-
if (value.slug) return value.slug;
|
|
3442
|
-
throw new ProductSelectionCodecError(
|
|
3443
|
-
`Option value "${value.id}" does not have a slug and cannot be used in product selection URLs.`
|
|
3444
|
-
);
|
|
3445
|
-
}
|
|
3446
|
-
function requireOptionSlug(option) {
|
|
3447
|
-
if (option.slug) return option.slug;
|
|
3448
|
-
throw new ProductSelectionCodecError(
|
|
3449
|
-
`Option "${option.id}" does not have a slug and cannot be used in product selection URLs.`
|
|
2534
|
+
if (!option) return false;
|
|
2535
|
+
const values = option.values.filter(
|
|
2536
|
+
(candidate) => candidate.slug === valueSlug
|
|
3450
2537
|
);
|
|
2538
|
+
if (values.length > 1) {
|
|
2539
|
+
throw new ProductSelectionCodecError(
|
|
2540
|
+
`Ambiguous product selection value slug "${valueSlug}" for option "${optionSlug}". Use opt.<optionId>=<valueId>.`
|
|
2541
|
+
);
|
|
2542
|
+
}
|
|
2543
|
+
const value = values[0];
|
|
2544
|
+
if (!value) return false;
|
|
2545
|
+
selectedByOptionId.set(option.id, value.id);
|
|
2546
|
+
return true;
|
|
3451
2547
|
}
|
|
3452
2548
|
function toSearchParams(search) {
|
|
3453
2549
|
if (!search) return new URLSearchParams();
|
|
@@ -3471,6 +2567,15 @@ function slugLike(value) {
|
|
|
3471
2567
|
}
|
|
3472
2568
|
function assertNoAmbiguousSelectionParams(matrix, params) {
|
|
3473
2569
|
const knownSelectionKeys = /* @__PURE__ */ new Set();
|
|
2570
|
+
const hasVariantParam = params.has("variant");
|
|
2571
|
+
const hasOptionParams = Array.from(params.keys()).some(
|
|
2572
|
+
(key) => key.startsWith("opt.")
|
|
2573
|
+
);
|
|
2574
|
+
if (hasVariantParam && hasOptionParams) {
|
|
2575
|
+
throw new ProductSelectionCodecError(
|
|
2576
|
+
"Product selection URL cannot mix variant=<variantId> with opt.<optionId>=<valueId> params."
|
|
2577
|
+
);
|
|
2578
|
+
}
|
|
3474
2579
|
for (const option of matrix.options) {
|
|
3475
2580
|
knownSelectionKeys.add(slugLike(option.slug));
|
|
3476
2581
|
knownSelectionKeys.add(slugLike(option.title));
|
|
@@ -3483,12 +2588,25 @@ function assertNoAmbiguousSelectionParams(matrix, params) {
|
|
|
3483
2588
|
const optionToken = key.slice(4);
|
|
3484
2589
|
if (!optionToken || !matrix.optionBySlug.has(optionToken) && !matrix.optionById.has(optionToken)) {
|
|
3485
2590
|
throw new ProductSelectionCodecError(
|
|
3486
|
-
`Unknown product selection query parameter "${key}". Use opt.<
|
|
2591
|
+
`Unknown product selection query parameter "${key}". Use opt.<optionId>=<valueId>.`
|
|
2592
|
+
);
|
|
2593
|
+
}
|
|
2594
|
+
if (!value) {
|
|
2595
|
+
throw new ProductSelectionCodecError(
|
|
2596
|
+
`Product selection query parameter "${key}" requires a value ID or compatibility value slug.`
|
|
3487
2597
|
);
|
|
3488
2598
|
}
|
|
2599
|
+
continue;
|
|
2600
|
+
}
|
|
2601
|
+
if (key === "variant") {
|
|
3489
2602
|
if (!value) {
|
|
3490
2603
|
throw new ProductSelectionCodecError(
|
|
3491
|
-
|
|
2604
|
+
'Product selection query parameter "variant" requires a variant ID.'
|
|
2605
|
+
);
|
|
2606
|
+
}
|
|
2607
|
+
if (!getVariantSelection(matrix, value)) {
|
|
2608
|
+
throw new ProductSelectionCodecError(
|
|
2609
|
+
`Unknown product selection variant "${value}".`
|
|
3492
2610
|
);
|
|
3493
2611
|
}
|
|
3494
2612
|
continue;
|
|
@@ -3496,55 +2614,97 @@ function assertNoAmbiguousSelectionParams(matrix, params) {
|
|
|
3496
2614
|
const keyToken = slugLike(key);
|
|
3497
2615
|
if (knownSelectionKeys.has(keyToken) || value === "" && knownSelectionKeys.has(keyToken)) {
|
|
3498
2616
|
throw new ProductSelectionCodecError(
|
|
3499
|
-
`Ambiguous product selection query parameter "${key}". Use opt.<
|
|
2617
|
+
`Ambiguous product selection query parameter "${key}". Use opt.<optionId>=<valueId>.`
|
|
3500
2618
|
);
|
|
3501
2619
|
}
|
|
3502
2620
|
}
|
|
3503
2621
|
}
|
|
3504
|
-
function
|
|
2622
|
+
function emitCompatibilityOptionIdParam(options, event) {
|
|
3505
2623
|
try {
|
|
2624
|
+
if (options?.onCompatibilityOptionIdParam) {
|
|
2625
|
+
options.onCompatibilityOptionIdParam(event);
|
|
2626
|
+
return;
|
|
2627
|
+
}
|
|
3506
2628
|
options?.onLegacyOptionIdParam?.(event);
|
|
3507
2629
|
} catch {
|
|
3508
2630
|
}
|
|
3509
2631
|
}
|
|
3510
2632
|
function assignSearchSelection(matrix, selectedByOptionId, search, options) {
|
|
3511
|
-
if (!search) return;
|
|
2633
|
+
if (!search) return null;
|
|
3512
2634
|
const params = toSearchParams(search);
|
|
3513
2635
|
assertNoAmbiguousSelectionParams(matrix, params);
|
|
3514
|
-
|
|
2636
|
+
const variantParam = params.get("variant");
|
|
2637
|
+
if (variantParam != null) {
|
|
2638
|
+
const variantSelection = getVariantSelection(matrix, variantParam);
|
|
2639
|
+
if (!variantSelection) {
|
|
2640
|
+
throw new ProductSelectionCodecError(
|
|
2641
|
+
`Unknown product selection variant "${variantParam}".`
|
|
2642
|
+
);
|
|
2643
|
+
}
|
|
2644
|
+
for (const [optionId, valueId] of variantSelection.optionValueByOptionId) {
|
|
2645
|
+
selectedByOptionId.set(optionId, valueId);
|
|
2646
|
+
}
|
|
2647
|
+
return variantSelection.id;
|
|
2648
|
+
}
|
|
2649
|
+
for (const [key, valueToken] of params.entries()) {
|
|
3515
2650
|
if (!key.startsWith("opt.")) continue;
|
|
3516
2651
|
const optionToken = key.slice(4);
|
|
2652
|
+
const optionById = matrix.optionById.get(optionToken);
|
|
2653
|
+
if (optionById) {
|
|
2654
|
+
if (assignSelectedValue(
|
|
2655
|
+
matrix,
|
|
2656
|
+
selectedByOptionId,
|
|
2657
|
+
optionById.id,
|
|
2658
|
+
valueToken
|
|
2659
|
+
)) {
|
|
2660
|
+
continue;
|
|
2661
|
+
}
|
|
2662
|
+
const before = selectedByOptionId.get(optionById.id);
|
|
2663
|
+
if (assignSelectedValueSlugByOptionId(
|
|
2664
|
+
matrix,
|
|
2665
|
+
selectedByOptionId,
|
|
2666
|
+
optionById.id,
|
|
2667
|
+
valueToken
|
|
2668
|
+
) && selectedByOptionId.get(optionById.id) !== before) {
|
|
2669
|
+
emitCompatibilityOptionIdParam(options, {
|
|
2670
|
+
optionId: optionById.id,
|
|
2671
|
+
optionSlug: optionById.slug,
|
|
2672
|
+
valueSlug: valueToken,
|
|
2673
|
+
searchParam: key
|
|
2674
|
+
});
|
|
2675
|
+
continue;
|
|
2676
|
+
}
|
|
2677
|
+
throw new ProductSelectionCodecError(
|
|
2678
|
+
`Unknown product selection value "${valueToken}" for option "${optionToken}". Use opt.<optionId>=<valueId>.`
|
|
2679
|
+
);
|
|
2680
|
+
}
|
|
3517
2681
|
const optionBySlug = matrix.optionBySlug.get(optionToken);
|
|
3518
2682
|
if (optionBySlug) {
|
|
3519
|
-
assignSelectedValueSlugByOptionSlug(
|
|
2683
|
+
if (assignSelectedValueSlugByOptionSlug(
|
|
3520
2684
|
matrix,
|
|
3521
2685
|
selectedByOptionId,
|
|
3522
2686
|
optionBySlug.slug,
|
|
3523
|
-
|
|
2687
|
+
valueToken
|
|
2688
|
+
)) {
|
|
2689
|
+
continue;
|
|
2690
|
+
}
|
|
2691
|
+
if (matrix.valueById.has(valueToken)) {
|
|
2692
|
+
throw new ProductSelectionCodecError(
|
|
2693
|
+
`Unknown product selection value "${valueToken}" for option "${optionToken}". Use opt.<optionId>=<valueId>.`
|
|
2694
|
+
);
|
|
2695
|
+
}
|
|
2696
|
+
throw new ProductSelectionCodecError(
|
|
2697
|
+
`Unknown product selection value "${valueToken}" for option "${optionToken}". Use opt.<optionSlug>=<valueSlug> for compatibility URLs.`
|
|
3524
2698
|
);
|
|
3525
|
-
continue;
|
|
3526
|
-
}
|
|
3527
|
-
const legacyOption = matrix.optionById.get(optionToken);
|
|
3528
|
-
if (!legacyOption) continue;
|
|
3529
|
-
const before = selectedByOptionId.get(legacyOption.id);
|
|
3530
|
-
assignSelectedValueSlugByOptionId(
|
|
3531
|
-
matrix,
|
|
3532
|
-
selectedByOptionId,
|
|
3533
|
-
legacyOption.id,
|
|
3534
|
-
valueSlug
|
|
3535
|
-
);
|
|
3536
|
-
if (selectedByOptionId.get(legacyOption.id) !== before) {
|
|
3537
|
-
emitLegacyOptionIdParam(options, {
|
|
3538
|
-
optionId: legacyOption.id,
|
|
3539
|
-
optionSlug: legacyOption.slug,
|
|
3540
|
-
valueSlug,
|
|
3541
|
-
searchParam: key
|
|
3542
|
-
});
|
|
3543
2699
|
}
|
|
3544
2700
|
}
|
|
2701
|
+
return null;
|
|
3545
2702
|
}
|
|
3546
2703
|
function normalizeProductSelection(detail, selection = {}, options) {
|
|
3547
2704
|
const matrix = buildProductOptionMatrixFromDetail(detail);
|
|
2705
|
+
return normalizeProductSelectionFromMatrix(matrix, selection, options);
|
|
2706
|
+
}
|
|
2707
|
+
function normalizeProductSelectionFromMatrix(matrix, selection = {}, options) {
|
|
3548
2708
|
const selectedByOptionId = /* @__PURE__ */ new Map();
|
|
3549
2709
|
const variantSelection = getVariantSelection(matrix, selection.variantId);
|
|
3550
2710
|
const variantId = variantSelection?.id ?? null;
|
|
@@ -3560,7 +2720,12 @@ function normalizeProductSelection(detail, selection = {}, options) {
|
|
|
3560
2720
|
if (!optionId) continue;
|
|
3561
2721
|
selectedByOptionId.set(optionId, valueId);
|
|
3562
2722
|
}
|
|
3563
|
-
|
|
2723
|
+
const searchVariantId = assignSearchSelection(
|
|
2724
|
+
matrix,
|
|
2725
|
+
selectedByOptionId,
|
|
2726
|
+
selection.search,
|
|
2727
|
+
options
|
|
2728
|
+
);
|
|
3564
2729
|
for (const [rawOptionId, rawSelection] of Object.entries(
|
|
3565
2730
|
selection.byOptionId ?? {}
|
|
3566
2731
|
)) {
|
|
@@ -3637,7 +2802,7 @@ function normalizeProductSelection(detail, selection = {}, options) {
|
|
|
3637
2802
|
byOptionSlug,
|
|
3638
2803
|
byOptionId,
|
|
3639
2804
|
valueIds: matrix.optionIds.map((optionId) => byOptionId[optionId]).filter((valueId) => Boolean(valueId)),
|
|
3640
|
-
variantId
|
|
2805
|
+
variantId: searchVariantId ?? variantId
|
|
3641
2806
|
};
|
|
3642
2807
|
}
|
|
3643
2808
|
function parseProductSelection(detail, search, options) {
|
|
@@ -3645,15 +2810,31 @@ function parseProductSelection(detail, search, options) {
|
|
|
3645
2810
|
}
|
|
3646
2811
|
function stringifyProductSelection(detail, selection = {}, options) {
|
|
3647
2812
|
const matrix = buildProductOptionMatrixFromDetail(detail);
|
|
3648
|
-
const normalized =
|
|
2813
|
+
const normalized = normalizeProductSelectionFromMatrix(
|
|
2814
|
+
matrix,
|
|
2815
|
+
selection,
|
|
2816
|
+
options
|
|
2817
|
+
);
|
|
3649
2818
|
const params = new URLSearchParams();
|
|
2819
|
+
if (hasExplicitSelection(selection)) {
|
|
2820
|
+
const matchingVariants = getMatchingVariantEntries(matrix, normalized);
|
|
2821
|
+
const exactVariant = getExactSelectedVariantEntry(
|
|
2822
|
+
matrix,
|
|
2823
|
+
normalized,
|
|
2824
|
+
matchingVariants
|
|
2825
|
+
);
|
|
2826
|
+
if (exactVariant) {
|
|
2827
|
+
params.set("variant", exactVariant.id);
|
|
2828
|
+
return params.toString();
|
|
2829
|
+
}
|
|
2830
|
+
}
|
|
3650
2831
|
for (const optionId of matrix.optionIds) {
|
|
3651
2832
|
const valueId = normalized.byOptionId[optionId];
|
|
3652
2833
|
if (!valueId) continue;
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
params.append(`opt.${
|
|
2834
|
+
if (!matrix.optionById.has(optionId) || !matrix.valueById.has(valueId)) {
|
|
2835
|
+
continue;
|
|
2836
|
+
}
|
|
2837
|
+
params.append(`opt.${optionId}`, valueId);
|
|
3657
2838
|
}
|
|
3658
2839
|
return params.toString();
|
|
3659
2840
|
}
|
|
@@ -3718,17 +2899,21 @@ function mediaArray(values) {
|
|
|
3718
2899
|
return values.filter(isPresentMedia);
|
|
3719
2900
|
}
|
|
3720
2901
|
function buildSelectionMedia(detail, selectedVariant, matchingVariants, selectedValues) {
|
|
2902
|
+
const selectedVariantImages = mediaArray(selectedVariant?.images);
|
|
3721
2903
|
const selectedValueImages = selectedValues.flatMap(
|
|
3722
2904
|
(value) => mediaArray(value.images)
|
|
3723
2905
|
);
|
|
2906
|
+
const matchingVariantImages = matchingVariants.flatMap(
|
|
2907
|
+
(variant) => mediaArray(variant.images)
|
|
2908
|
+
);
|
|
3724
2909
|
const selectedValuePrimary = selectedValues.map((value) => firstMedia(value.thumbnail) ?? firstMedia(value.images)).find((value) => value != null) ?? null;
|
|
3725
2910
|
const selectedVariantPrimary = firstMedia(selectedVariant?.thumbnail) ?? firstMedia(selectedVariant?.images);
|
|
3726
2911
|
const matchingVariantPrimary = matchingVariants.map(
|
|
3727
2912
|
(variant) => firstMedia(variant.thumbnail) ?? firstMedia(variant.images)
|
|
3728
2913
|
).find((value) => value != null) ?? null;
|
|
3729
2914
|
const detailImages = mediaArray(detail.images);
|
|
3730
|
-
const primaryImage = selectedVariantPrimary ?? selectedValuePrimary ?? firstMedia(detail.listing.primaryImage) ??
|
|
3731
|
-
const images =
|
|
2915
|
+
const primaryImage = selectedVariantPrimary ?? selectedValuePrimary ?? matchingVariantPrimary ?? firstMedia(detail.listing.primaryImage) ?? firstMedia(detailImages);
|
|
2916
|
+
const images = selectedVariantImages.length > 0 ? selectedVariantImages : selectedValueImages.length > 0 ? selectedValueImages : matchingVariantImages.length > 0 ? matchingVariantImages : detailImages;
|
|
3732
2917
|
return {
|
|
3733
2918
|
primaryImage,
|
|
3734
2919
|
images
|
|
@@ -3754,11 +2939,39 @@ function buildSelectionStock(selectedVariant, matchingVariants) {
|
|
|
3754
2939
|
availableStock: null
|
|
3755
2940
|
};
|
|
3756
2941
|
}
|
|
3757
|
-
function
|
|
3758
|
-
const
|
|
3759
|
-
const
|
|
3760
|
-
const
|
|
3761
|
-
|
|
2942
|
+
function buildAvailableValueStock(variants) {
|
|
2943
|
+
const activeVariants = variants.filter((variant) => variant.isActive !== false);
|
|
2944
|
+
const isUnlimited = activeVariants.some((variant) => variant.isUnlimited);
|
|
2945
|
+
const availableStock = isUnlimited ? null : activeVariants.reduce(
|
|
2946
|
+
(sum, variant) => sum + Math.max(0, variant.stock - variant.reservedStock),
|
|
2947
|
+
0
|
|
2948
|
+
);
|
|
2949
|
+
return {
|
|
2950
|
+
availableForSale: activeVariants.some(isVariantAvailableForSale),
|
|
2951
|
+
isUnlimited,
|
|
2952
|
+
availableStock
|
|
2953
|
+
};
|
|
2954
|
+
}
|
|
2955
|
+
function getCandidateVariantsForValue(matrix, optionId, valueId, selectedValueIds) {
|
|
2956
|
+
const selectedByOption = getSelectedValueByOptionId(matrix, selectedValueIds);
|
|
2957
|
+
selectedByOption.set(optionId, valueId);
|
|
2958
|
+
return matrix.variants.filter(
|
|
2959
|
+
(variant) => Array.from(selectedByOption.entries()).every(
|
|
2960
|
+
([selectedOptionId, selectedValueId]) => variant.optionValueByOptionId.get(selectedOptionId) === selectedValueId
|
|
2961
|
+
)
|
|
2962
|
+
).map((variant) => variant.source);
|
|
2963
|
+
}
|
|
2964
|
+
function getResolutionContext(context) {
|
|
2965
|
+
return {
|
|
2966
|
+
images: context?.images ?? context?.detail?.images ?? [],
|
|
2967
|
+
listing: context?.listing ?? context?.detail?.listing ?? {}
|
|
2968
|
+
};
|
|
2969
|
+
}
|
|
2970
|
+
function resolveProductSelectionFromMatrix(matrix, selection = {}, options, context) {
|
|
2971
|
+
const { images, listing } = getResolutionContext(context);
|
|
2972
|
+
const effectiveSelection = hasExplicitSelection(selection) || listing.selectionHintVariant == null ? selection : { ...selection, variantId: listing.selectionHintVariant };
|
|
2973
|
+
const normalizedSelection = normalizeProductSelectionFromMatrix(
|
|
2974
|
+
matrix,
|
|
3762
2975
|
effectiveSelection,
|
|
3763
2976
|
options
|
|
3764
2977
|
);
|
|
@@ -3793,9 +3006,17 @@ function resolveProductSelection(detail, selection = {}, options) {
|
|
|
3793
3006
|
option.values.map((value) => ({
|
|
3794
3007
|
valueId: value.id,
|
|
3795
3008
|
value: value.label,
|
|
3796
|
-
slug:
|
|
3009
|
+
slug: value.slug ?? "",
|
|
3797
3010
|
selected: normalizedSelection.byOptionId[option.id] === value.id,
|
|
3798
3011
|
available: availableValueIds.has(value.id),
|
|
3012
|
+
...buildAvailableValueStock(
|
|
3013
|
+
getCandidateVariantsForValue(
|
|
3014
|
+
matrix,
|
|
3015
|
+
option.id,
|
|
3016
|
+
value.id,
|
|
3017
|
+
normalizedSelection.valueIds
|
|
3018
|
+
)
|
|
3019
|
+
),
|
|
3799
3020
|
swatchColor: value.swatchColor ?? null,
|
|
3800
3021
|
thumbnail: value.thumbnail ?? null,
|
|
3801
3022
|
images: value.images ?? null
|
|
@@ -3823,7 +3044,12 @@ function resolveProductSelection(detail, selection = {}, options) {
|
|
|
3823
3044
|
allOptionsSelected,
|
|
3824
3045
|
price: buildSelectionPrice(priceVariants),
|
|
3825
3046
|
media: buildSelectionMedia(
|
|
3826
|
-
|
|
3047
|
+
{
|
|
3048
|
+
images,
|
|
3049
|
+
listing: {
|
|
3050
|
+
primaryImage: listing.primaryImage ?? null
|
|
3051
|
+
}
|
|
3052
|
+
},
|
|
3827
3053
|
selectedVariant,
|
|
3828
3054
|
matchingVariants,
|
|
3829
3055
|
selectedValues
|
|
@@ -3831,6 +3057,100 @@ function resolveProductSelection(detail, selection = {}, options) {
|
|
|
3831
3057
|
stock: buildSelectionStock(selectedVariant, matchingVariants)
|
|
3832
3058
|
};
|
|
3833
3059
|
}
|
|
3060
|
+
function resolveProductSelection(detail, selection = {}, options) {
|
|
3061
|
+
const matrix = buildProductOptionMatrixFromDetail(detail);
|
|
3062
|
+
return resolveProductSelectionFromMatrix(matrix, selection, options, {
|
|
3063
|
+
detail
|
|
3064
|
+
});
|
|
3065
|
+
}
|
|
3066
|
+
function isProductDetailImageMedia(value) {
|
|
3067
|
+
return typeof value === "object" && value !== null;
|
|
3068
|
+
}
|
|
3069
|
+
function mediaDedupeKey(value) {
|
|
3070
|
+
if (value.id != null) return `id:${String(value.id)}`;
|
|
3071
|
+
if (value.url) return `url:${value.url}`;
|
|
3072
|
+
return null;
|
|
3073
|
+
}
|
|
3074
|
+
function getProductSelectionImages(resolution) {
|
|
3075
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3076
|
+
const images = [];
|
|
3077
|
+
const candidates = [
|
|
3078
|
+
resolution.media.primaryImage,
|
|
3079
|
+
...resolution.media.images
|
|
3080
|
+
].filter(isProductDetailImageMedia);
|
|
3081
|
+
for (const candidate of candidates) {
|
|
3082
|
+
const key = mediaDedupeKey(candidate);
|
|
3083
|
+
if (key && seen.has(key)) continue;
|
|
3084
|
+
if (key) seen.add(key);
|
|
3085
|
+
images.push(candidate);
|
|
3086
|
+
}
|
|
3087
|
+
return images;
|
|
3088
|
+
}
|
|
3089
|
+
function getProductHrefSlug(product) {
|
|
3090
|
+
if ("product" in product && product.product?.slug) {
|
|
3091
|
+
return product.product.slug;
|
|
3092
|
+
}
|
|
3093
|
+
if ("slug" in product && product.slug) return product.slug;
|
|
3094
|
+
throw new ProductSelectionCodecError(
|
|
3095
|
+
"Product slug is required to build a product href."
|
|
3096
|
+
);
|
|
3097
|
+
}
|
|
3098
|
+
function joinProductPath(basePath, slug, trailingSlash) {
|
|
3099
|
+
const base = basePath.replace(/\/+$/, "");
|
|
3100
|
+
const encodedSlug = encodeURIComponent(slug);
|
|
3101
|
+
return `${base}/${encodedSlug}${trailingSlash ? "/" : ""}`;
|
|
3102
|
+
}
|
|
3103
|
+
function getProductHrefGroupSelection(group, matrix) {
|
|
3104
|
+
if (!group) return null;
|
|
3105
|
+
if (group.variantId != null) return { variantId: group.variantId };
|
|
3106
|
+
const listingVariantId = group.listing?.selectionHintVariant;
|
|
3107
|
+
const optionId = group.optionId != null ? String(group.optionId) : group.optionSlug ? matrix?.optionBySlug.get(group.optionSlug)?.id : void 0;
|
|
3108
|
+
if (!optionId) {
|
|
3109
|
+
return listingVariantId != null ? { variantId: listingVariantId } : null;
|
|
3110
|
+
}
|
|
3111
|
+
const option = matrix?.optionById.get(optionId);
|
|
3112
|
+
const optionValueId = group.optionValueId != null ? String(group.optionValueId) : group.optionValueSlug && option ? option.values.find((value) => value.slug === group.optionValueSlug)?.id : void 0;
|
|
3113
|
+
if (!optionValueId) {
|
|
3114
|
+
return listingVariantId != null ? { variantId: listingVariantId } : null;
|
|
3115
|
+
}
|
|
3116
|
+
return { byOptionId: { [optionId]: optionValueId } };
|
|
3117
|
+
}
|
|
3118
|
+
function buildProductHref(product, group, options = {}) {
|
|
3119
|
+
const path = joinProductPath(
|
|
3120
|
+
options.basePath ?? "/products",
|
|
3121
|
+
getProductHrefSlug(product),
|
|
3122
|
+
options.trailingSlash ?? false
|
|
3123
|
+
);
|
|
3124
|
+
const params = new URLSearchParams();
|
|
3125
|
+
if (options.detail && options.selection) {
|
|
3126
|
+
const selection = stringifyProductSelection(options.detail, options.selection);
|
|
3127
|
+
return selection ? `${path}?${selection}` : path;
|
|
3128
|
+
}
|
|
3129
|
+
const groupSelection = getProductHrefGroupSelection(group, options.matrix);
|
|
3130
|
+
if (groupSelection) {
|
|
3131
|
+
if (options.detail) {
|
|
3132
|
+
const selection = stringifyProductSelection(options.detail, groupSelection);
|
|
3133
|
+
return selection ? `${path}?${selection}` : path;
|
|
3134
|
+
}
|
|
3135
|
+
if (groupSelection.variantId != null) {
|
|
3136
|
+
params.set("variant", String(groupSelection.variantId));
|
|
3137
|
+
return `${path}?${params.toString()}`;
|
|
3138
|
+
}
|
|
3139
|
+
const [selectionEntry] = Object.entries(groupSelection.byOptionId ?? {});
|
|
3140
|
+
if (selectionEntry) {
|
|
3141
|
+
const [optionId, valueId] = selectionEntry;
|
|
3142
|
+
params.set(`opt.${optionId}`, String(valueId));
|
|
3143
|
+
return `${path}?${params.toString()}`;
|
|
3144
|
+
}
|
|
3145
|
+
}
|
|
3146
|
+
if (group?.optionValueSlug) {
|
|
3147
|
+
const optionSlug = group.optionSlug ?? (group.optionId != null ? options.matrix?.optionById.get(String(group.optionId))?.slug : void 0);
|
|
3148
|
+
if (optionSlug) {
|
|
3149
|
+
params.set(`opt.${optionSlug}`, group.optionValueSlug);
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
return params.size > 0 ? `${path}?${params.toString()}` : path;
|
|
3153
|
+
}
|
|
3834
3154
|
function compareVariantOrder(a, b) {
|
|
3835
3155
|
const aOrder = Number(a._order ?? Number.MAX_SAFE_INTEGER);
|
|
3836
3156
|
const bOrder = Number(b._order ?? Number.MAX_SAFE_INTEGER);
|
|
@@ -3884,6 +3204,72 @@ function buildProductListingProjection(product, variants) {
|
|
|
3884
3204
|
availableForSale: availableVariants.length > 0
|
|
3885
3205
|
};
|
|
3886
3206
|
}
|
|
3207
|
+
function buildProductListingCard(item, options = {}) {
|
|
3208
|
+
const product = item.product;
|
|
3209
|
+
const groups = item.groups;
|
|
3210
|
+
const primaryImage = firstMedia(product.thumbnail) ?? firstMedia(product.images ?? null) ?? null;
|
|
3211
|
+
const priceRange = aggregateListingPriceRange(groups);
|
|
3212
|
+
const availableForSale = groups.some(
|
|
3213
|
+
(group) => group.listing.availableForSale
|
|
3214
|
+
);
|
|
3215
|
+
const swatches = groups.length > 1 ? groups.map((group) => buildListingSwatch(product, group, options)) : [];
|
|
3216
|
+
return {
|
|
3217
|
+
id: String(product.id),
|
|
3218
|
+
href: buildProductHref({ slug: product.slug }, void 0, options),
|
|
3219
|
+
title: product.title,
|
|
3220
|
+
primaryImage,
|
|
3221
|
+
priceRange,
|
|
3222
|
+
availableForSale,
|
|
3223
|
+
swatches
|
|
3224
|
+
};
|
|
3225
|
+
}
|
|
3226
|
+
function aggregateListingPriceRange(groups) {
|
|
3227
|
+
const minPrice = minOfNullable(groups.map((g) => g.listing.minPrice));
|
|
3228
|
+
const maxPrice = maxOfNullable(groups.map((g) => g.listing.maxPrice));
|
|
3229
|
+
const minCompareAtPrice = minOfNullable(
|
|
3230
|
+
groups.map((g) => g.listing.minCompareAtPrice)
|
|
3231
|
+
);
|
|
3232
|
+
const maxCompareAtPrice = maxOfNullable(
|
|
3233
|
+
groups.map((g) => g.listing.maxCompareAtPrice)
|
|
3234
|
+
);
|
|
3235
|
+
const isPriceRange = minPrice !== null && maxPrice !== null && minPrice !== maxPrice;
|
|
3236
|
+
return {
|
|
3237
|
+
minPrice,
|
|
3238
|
+
maxPrice,
|
|
3239
|
+
minCompareAtPrice,
|
|
3240
|
+
maxCompareAtPrice,
|
|
3241
|
+
isPriceRange
|
|
3242
|
+
};
|
|
3243
|
+
}
|
|
3244
|
+
function buildListingSwatch(product, group, options) {
|
|
3245
|
+
const thumbnail = firstMedia(group.optionValueThumbnail) ?? firstMedia(group.optionValueImages) ?? null;
|
|
3246
|
+
return {
|
|
3247
|
+
optionId: group.optionId,
|
|
3248
|
+
optionValueId: group.optionValueId,
|
|
3249
|
+
label: group.optionValueLabel,
|
|
3250
|
+
swatchColor: group.optionValueSwatchColor ?? null,
|
|
3251
|
+
thumbnail,
|
|
3252
|
+
href: buildProductHref(
|
|
3253
|
+
{ slug: product.slug },
|
|
3254
|
+
{
|
|
3255
|
+
optionId: group.optionId,
|
|
3256
|
+
optionValueId: group.optionValueId,
|
|
3257
|
+
optionValueSlug: group.optionValueSlug,
|
|
3258
|
+
listing: group.listing
|
|
3259
|
+
},
|
|
3260
|
+
options
|
|
3261
|
+
),
|
|
3262
|
+
availableForSale: group.listing.availableForSale
|
|
3263
|
+
};
|
|
3264
|
+
}
|
|
3265
|
+
function minOfNullable(values) {
|
|
3266
|
+
const numbers = values.filter((v) => v !== null);
|
|
3267
|
+
return numbers.length === 0 ? null : Math.min(...numbers);
|
|
3268
|
+
}
|
|
3269
|
+
function maxOfNullable(values) {
|
|
3270
|
+
const numbers = values.filter((v) => v !== null);
|
|
3271
|
+
return numbers.length === 0 ? null : Math.max(...numbers);
|
|
3272
|
+
}
|
|
3887
3273
|
function buildProductListingGroupsByOption(args) {
|
|
3888
3274
|
const primaryOptionId = args.primaryOptionId ?? void 0;
|
|
3889
3275
|
if (!primaryOptionId) return [];
|
|
@@ -4210,4 +3596,9 @@ function createAnalytics(config) {
|
|
|
4210
3596
|
}
|
|
4211
3597
|
};
|
|
4212
3598
|
}
|
|
3599
|
+
|
|
3600
|
+
// src/index.ts
|
|
3601
|
+
function createClient2(options) {
|
|
3602
|
+
return createClient(options);
|
|
3603
|
+
}
|
|
4213
3604
|
//# sourceMappingURL=index.cjs.map
|