@01.software/sdk 0.21.0 → 0.23.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.
@@ -0,0 +1,2057 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/server.ts
21
+ var server_exports = {};
22
+ __export(server_exports, {
23
+ CollectionClient: () => CollectionClient,
24
+ CommunityClient: () => CommunityClient,
25
+ ModerationApi: () => ModerationApi,
26
+ ServerClient: () => ServerClient,
27
+ ServerCollectionClient: () => ServerCollectionClient,
28
+ ServerCommerceClient: () => ServerCommerceClient,
29
+ createServerClient: () => createServerClient
30
+ });
31
+ module.exports = __toCommonJS(server_exports);
32
+
33
+ // src/utils/types.ts
34
+ var resolveRelation = (ref) => {
35
+ if (typeof ref === "string" || typeof ref === "number" || ref === null || ref === void 0)
36
+ return null;
37
+ return ref;
38
+ };
39
+
40
+ // src/core/metadata/index.ts
41
+ function extractSeo(doc) {
42
+ const seo = doc.seo ?? {};
43
+ const og = seo.openGraph ?? {};
44
+ return {
45
+ title: seo.title ?? doc.title ?? null,
46
+ description: seo.description ?? null,
47
+ noIndex: seo.noIndex ?? null,
48
+ canonical: seo.canonical ?? null,
49
+ openGraph: {
50
+ title: og.title ?? null,
51
+ description: og.description ?? null,
52
+ image: og.image ?? null
53
+ }
54
+ };
55
+ }
56
+ function generateMetadata(input, options) {
57
+ const title = input.title ?? void 0;
58
+ const description = input.description ?? void 0;
59
+ const ogTitle = input.openGraph?.title ?? title;
60
+ const ogDescription = input.openGraph?.description ?? description;
61
+ const image = resolveMetaImage(input.openGraph?.image);
62
+ return {
63
+ title,
64
+ description,
65
+ ...input.noIndex && { robots: { index: false, follow: false } },
66
+ ...input.canonical && { alternates: { canonical: input.canonical } },
67
+ openGraph: {
68
+ ...ogTitle && { title: ogTitle },
69
+ ...ogDescription && { description: ogDescription },
70
+ ...options?.siteName && { siteName: options.siteName },
71
+ ...image && { images: [image] }
72
+ },
73
+ twitter: {
74
+ card: image ? "summary_large_image" : "summary",
75
+ ...ogTitle && { title: ogTitle },
76
+ ...ogDescription && { description: ogDescription },
77
+ ...image && { images: [image.url] }
78
+ }
79
+ };
80
+ }
81
+ function resolveMetaImage(ref) {
82
+ const image = resolveRelation(ref);
83
+ if (!image) return null;
84
+ const sized = image.sizes?.["1536"];
85
+ const url = sized?.url || image.url;
86
+ if (!url) return null;
87
+ const width = sized?.url ? sized.width : image.width;
88
+ const height = sized?.url ? sized.height : image.height;
89
+ return {
90
+ url,
91
+ ...width && { width },
92
+ ...height && { height },
93
+ ...image.alt && { alt: image.alt }
94
+ };
95
+ }
96
+
97
+ // src/core/collection/query-builder.ts
98
+ var CollectionQueryBuilder = class {
99
+ constructor(api, collection) {
100
+ this.api = api;
101
+ this.collection = collection;
102
+ }
103
+ /**
104
+ * Find documents (list query)
105
+ * GET /api/{collection}
106
+ * @returns Payload CMS find response with docs array and pagination
107
+ */
108
+ async find(options) {
109
+ return this.api.requestFind(
110
+ `/api/${String(this.collection)}`,
111
+ options
112
+ );
113
+ }
114
+ /**
115
+ * Find document by ID
116
+ * GET /api/{collection}/{id}
117
+ * @returns Document object directly (no wrapper)
118
+ */
119
+ async findById(id, options) {
120
+ return this.api.requestFindById(
121
+ `/api/${String(this.collection)}/${String(id)}`,
122
+ options
123
+ );
124
+ }
125
+ /**
126
+ * Create a new document
127
+ * POST /api/{collection}
128
+ * @returns Payload CMS mutation response with doc and message
129
+ */
130
+ async create(data, options) {
131
+ const endpoint = `/api/${String(this.collection)}`;
132
+ if (options?.file) {
133
+ return this.api.requestCreateWithFile(
134
+ endpoint,
135
+ data,
136
+ options.file,
137
+ options.filename
138
+ );
139
+ }
140
+ return this.api.requestCreate(endpoint, data);
141
+ }
142
+ /**
143
+ * Update a document by ID
144
+ * PATCH /api/{collection}/{id}
145
+ * @returns Payload CMS mutation response with doc and message
146
+ */
147
+ async update(id, data, options) {
148
+ const endpoint = `/api/${String(this.collection)}/${String(id)}`;
149
+ if (options?.file) {
150
+ return this.api.requestUpdateWithFile(
151
+ endpoint,
152
+ data,
153
+ options.file,
154
+ options.filename
155
+ );
156
+ }
157
+ return this.api.requestUpdate(endpoint, data);
158
+ }
159
+ /**
160
+ * Count documents
161
+ * GET /api/{collection}/count
162
+ * @returns Count response with totalDocs
163
+ */
164
+ async count(options) {
165
+ return this.api.requestCount(
166
+ `/api/${String(this.collection)}/count`,
167
+ options
168
+ );
169
+ }
170
+ /**
171
+ * Find first matching document and return its Next.js Metadata.
172
+ * Applies depth: 1 (SEO image populate) and limit: 1 automatically.
173
+ * @returns Metadata or null if no document matches
174
+ */
175
+ async findMetadata(options, metadataOptions) {
176
+ const { docs } = await this.find({ ...options, limit: 1, depth: 1 });
177
+ const doc = docs[0];
178
+ if (!doc) return null;
179
+ return generateMetadata(
180
+ extractSeo(doc),
181
+ metadataOptions
182
+ );
183
+ }
184
+ /**
185
+ * Find document by ID and return its Next.js Metadata.
186
+ * Applies depth: 1 (SEO image populate) automatically.
187
+ * @returns Metadata (throws on 404)
188
+ */
189
+ async findMetadataById(id, metadataOptions) {
190
+ const doc = await this.findById(id, { depth: 1 });
191
+ return generateMetadata(
192
+ extractSeo(doc),
193
+ metadataOptions
194
+ );
195
+ }
196
+ /**
197
+ * Update multiple documents (bulk update)
198
+ * PATCH /api/{collection}
199
+ * @returns Payload CMS find response with updated docs
200
+ */
201
+ async updateMany(where, data) {
202
+ return this.api.requestUpdateMany(
203
+ `/api/${String(this.collection)}`,
204
+ { where, data }
205
+ );
206
+ }
207
+ /**
208
+ * Delete a document by ID
209
+ * DELETE /api/{collection}/{id}
210
+ * @returns Deleted document object directly (no wrapper)
211
+ */
212
+ async remove(id) {
213
+ return this.api.requestDelete(
214
+ `/api/${String(this.collection)}/${String(id)}`
215
+ );
216
+ }
217
+ /**
218
+ * Delete multiple documents (bulk delete)
219
+ * DELETE /api/{collection}
220
+ * @returns Payload CMS find response with deleted docs
221
+ */
222
+ async removeMany(where) {
223
+ return this.api.requestDeleteMany(
224
+ `/api/${String(this.collection)}`,
225
+ { where }
226
+ );
227
+ }
228
+ };
229
+ var ServerCollectionQueryBuilder = class extends CollectionQueryBuilder {
230
+ };
231
+
232
+ // src/core/collection/http-client.ts
233
+ var import_qs_esm = require("qs-esm");
234
+
235
+ // src/core/internal/errors/index.ts
236
+ var SDKError = class extends Error {
237
+ constructor(code, message, status, details, userMessage, suggestion, requestId) {
238
+ super(message);
239
+ this.name = "SDKError";
240
+ this.code = code;
241
+ this.status = status;
242
+ this.details = details;
243
+ this.userMessage = userMessage;
244
+ this.suggestion = suggestion;
245
+ this.requestId = requestId;
246
+ if (Error.captureStackTrace) {
247
+ Error.captureStackTrace(this, new.target);
248
+ }
249
+ }
250
+ getUserMessage() {
251
+ return this.userMessage || this.message;
252
+ }
253
+ toJSON() {
254
+ return {
255
+ name: this.name,
256
+ code: this.code,
257
+ message: this.message,
258
+ status: this.status,
259
+ details: this.details,
260
+ userMessage: this.userMessage,
261
+ suggestion: this.suggestion,
262
+ ...this.requestId !== void 0 && { requestId: this.requestId }
263
+ };
264
+ }
265
+ };
266
+ var NetworkError = class extends SDKError {
267
+ constructor(message, status, details, userMessage, suggestion) {
268
+ super("NETWORK_ERROR", message, status, details, userMessage, suggestion);
269
+ this.name = "NetworkError";
270
+ }
271
+ };
272
+ var ValidationError = class extends SDKError {
273
+ constructor(message, details, userMessage, suggestion, status = 400) {
274
+ super("VALIDATION_ERROR", message, status, details, userMessage, suggestion);
275
+ this.name = "ValidationError";
276
+ }
277
+ };
278
+ var ApiError = class extends SDKError {
279
+ constructor(message, status, details, userMessage, suggestion) {
280
+ super("API_ERROR", message, status, details, userMessage, suggestion);
281
+ this.name = "ApiError";
282
+ }
283
+ };
284
+ var ConfigError = class extends SDKError {
285
+ constructor(message, details, userMessage, suggestion) {
286
+ super("CONFIG_ERROR", message, void 0, details, userMessage, suggestion);
287
+ this.name = "ConfigError";
288
+ }
289
+ };
290
+ var TimeoutError = class extends SDKError {
291
+ constructor(message = "Request timed out.", details, userMessage, suggestion) {
292
+ super("TIMEOUT_ERROR", message, 408, details, userMessage, suggestion);
293
+ this.name = "TimeoutError";
294
+ }
295
+ };
296
+ var UsageLimitError = class extends SDKError {
297
+ constructor(message, usage, details, userMessage, suggestion) {
298
+ super("USAGE_LIMIT_ERROR", message, 429, details, userMessage, suggestion);
299
+ this.name = "UsageLimitError";
300
+ this.usage = usage;
301
+ }
302
+ toJSON() {
303
+ return {
304
+ ...super.toJSON(),
305
+ usage: this.usage
306
+ };
307
+ }
308
+ };
309
+ var AuthError = class extends SDKError {
310
+ constructor(message, details, userMessage, suggestion, requestId) {
311
+ super("auth_error", message, 401, details, userMessage, suggestion, requestId);
312
+ this.name = "AuthError";
313
+ }
314
+ };
315
+ var PermissionError = class extends SDKError {
316
+ constructor(message, details, userMessage, suggestion, requestId) {
317
+ super("permission_error", message, 403, details, userMessage, suggestion, requestId);
318
+ this.name = "PermissionError";
319
+ }
320
+ };
321
+ var NotFoundError = class extends SDKError {
322
+ constructor(message, details, userMessage, suggestion, requestId) {
323
+ super("not_found", message, 404, details, userMessage, suggestion, requestId);
324
+ this.name = "NotFoundError";
325
+ }
326
+ };
327
+ var ConflictError = class extends SDKError {
328
+ constructor(message, details, userMessage, suggestion, requestId) {
329
+ super("conflict", message, 409, details, userMessage, suggestion, requestId);
330
+ this.name = "ConflictError";
331
+ }
332
+ };
333
+ var RateLimitError = class extends SDKError {
334
+ constructor(message, retryAfter, details, userMessage, suggestion, requestId) {
335
+ super("rate_limit_exceeded", message, 429, details, userMessage, suggestion, requestId);
336
+ this.name = "RateLimitError";
337
+ this.retryAfter = retryAfter;
338
+ }
339
+ };
340
+ var createNetworkError = (message, status, details, userMessage, suggestion) => new NetworkError(message, status, details, userMessage, suggestion);
341
+ var createValidationError = (message, details, userMessage, suggestion, status) => new ValidationError(message, details, userMessage, suggestion, status);
342
+ var createApiError = (message, status, details, userMessage, suggestion) => new ApiError(message, status, details, userMessage, suggestion);
343
+ var createConfigError = (message, details, userMessage, suggestion) => new ConfigError(message, details, userMessage, suggestion);
344
+ var createTimeoutError = (message, details, userMessage, suggestion) => new TimeoutError(message, details, userMessage, suggestion);
345
+ var createUsageLimitError = (message, usage, details, userMessage, suggestion) => new UsageLimitError(message, usage, details, userMessage, suggestion);
346
+ var createAuthError = (message, details, userMessage, suggestion, requestId) => new AuthError(message, details, userMessage, suggestion, requestId);
347
+ var createPermissionError = (message, details, userMessage, suggestion, requestId) => new PermissionError(message, details, userMessage, suggestion, requestId);
348
+ var createNotFoundError = (message, details, userMessage, suggestion, requestId) => new NotFoundError(message, details, userMessage, suggestion, requestId);
349
+ var createConflictError = (message, details, userMessage, suggestion, requestId) => new ConflictError(message, details, userMessage, suggestion, requestId);
350
+ var createRateLimitError = (message, retryAfter, details, userMessage, suggestion, requestId) => new RateLimitError(message, retryAfter, details, userMessage, suggestion, requestId);
351
+
352
+ // src/core/internal/utils/credentials.ts
353
+ function requirePublishableKeyForSecret(apiName, publishableKey, secretKey) {
354
+ if (secretKey && !publishableKey) {
355
+ throw createConfigError(
356
+ `publishableKey is required for ${apiName} when secretKey is used. It is sent as X-Publishable-Key for tenant routing, rate limiting, and quota enforcement.`
357
+ );
358
+ }
359
+ return publishableKey ?? "";
360
+ }
361
+
362
+ // src/core/client/types.ts
363
+ function resolveApiUrl() {
364
+ if (typeof process !== "undefined" && process.env) {
365
+ const envUrl = process.env.SOFTWARE_API_URL || process.env.NEXT_PUBLIC_SOFTWARE_API_URL;
366
+ if (envUrl) {
367
+ return envUrl.replace(/\/$/, "");
368
+ }
369
+ }
370
+ return "https://api.01.software";
371
+ }
372
+
373
+ // src/core/internal/utils/http.ts
374
+ var DEFAULT_TIMEOUT = 3e4;
375
+ var DEFAULT_RETRYABLE_STATUSES = [408, 429, 500, 502, 503, 504];
376
+ var NON_RETRYABLE_STATUSES = [400, 401, 403, 404, 409, 422];
377
+ var SAFE_METHODS = ["GET", "HEAD", "OPTIONS"];
378
+ function debugLog(debug, type, message, data) {
379
+ if (!debug) return;
380
+ const shouldLog = debug === true || type === "request" && debug.logRequests || type === "response" && debug.logResponses || type === "error" && debug.logErrors;
381
+ if (shouldLog) {
382
+ console.group(`[SDK ${type.toUpperCase()}] ${message}`);
383
+ if (data) console.log(data);
384
+ console.groupEnd();
385
+ }
386
+ }
387
+ function getErrorSuggestion(status) {
388
+ if (status === 400) return "The request data failed validation. Check field values and types.";
389
+ if (status === 401) return "Please check your authentication credentials.";
390
+ if (status === 403) return "Access denied. Check your credentials or permissions.";
391
+ if (status === 404) return "The requested resource was not found.";
392
+ if (status === 422) return "The request data failed validation.";
393
+ if (status >= 500) return "A server error occurred. Please try again later.";
394
+ return void 0;
395
+ }
396
+ async function parseErrorBody(response) {
397
+ const fallback = {
398
+ errorMessage: `HTTP ${response.status}: ${response.statusText}`,
399
+ userMessage: `Request failed (status: ${response.status})`
400
+ };
401
+ try {
402
+ const body = await response.json();
403
+ const reason = typeof body.reason === "string" ? body.reason : typeof body.code === "string" ? body.code : void 0;
404
+ if (body.errors && Array.isArray(body.errors)) {
405
+ const fieldErrors = [];
406
+ for (const e of body.errors) {
407
+ if (e.data?.errors && Array.isArray(e.data.errors) && e.data.errors.length > 0) {
408
+ for (const fe of e.data.errors) {
409
+ fieldErrors.push({
410
+ field: fe.path || fe.field,
411
+ message: fe.message
412
+ });
413
+ }
414
+ } else if (e.field || e.message) {
415
+ fieldErrors.push({ field: e.field, message: e.message });
416
+ }
417
+ }
418
+ const details = (fieldErrors.length > 0 ? fieldErrors : body.errors).map(
419
+ (e) => e.field ? `${e.field}: ${e.message}` : e.message
420
+ ).filter(Boolean).join("; ");
421
+ if (details) {
422
+ return {
423
+ errorMessage: `HTTP ${response.status}: ${details}`,
424
+ userMessage: details,
425
+ reason,
426
+ body,
427
+ errors: fieldErrors.length > 0 ? fieldErrors : body.errors
428
+ };
429
+ }
430
+ }
431
+ if (typeof body.error === "string") {
432
+ return {
433
+ errorMessage: `HTTP ${response.status}: ${body.error}`,
434
+ userMessage: body.error,
435
+ reason,
436
+ body
437
+ };
438
+ }
439
+ if (body.message) {
440
+ return {
441
+ errorMessage: `HTTP ${response.status}: ${body.message}`,
442
+ userMessage: body.message,
443
+ reason,
444
+ body
445
+ };
446
+ }
447
+ return { ...fallback, reason, body };
448
+ } catch {
449
+ return fallback;
450
+ }
451
+ }
452
+ async function delay(ms) {
453
+ return new Promise((resolve) => setTimeout(resolve, ms));
454
+ }
455
+ function attachRequestId(err, id) {
456
+ if (id) err.requestId = id;
457
+ return err;
458
+ }
459
+ function createHttpStatusError(status, parsed, details, requestId) {
460
+ const errorDetails = {
461
+ ...details,
462
+ ...parsed.errors && { errors: parsed.errors },
463
+ ...parsed.body && { body: parsed.body }
464
+ };
465
+ const suggestion = getErrorSuggestion(status);
466
+ if (status === 400 || status === 422) {
467
+ return attachRequestId(
468
+ createValidationError(
469
+ parsed.errorMessage,
470
+ errorDetails,
471
+ parsed.userMessage,
472
+ suggestion,
473
+ status
474
+ ),
475
+ requestId
476
+ );
477
+ }
478
+ if (status === 401) {
479
+ return attachRequestId(
480
+ createAuthError(
481
+ parsed.errorMessage,
482
+ errorDetails,
483
+ parsed.userMessage,
484
+ suggestion
485
+ ),
486
+ requestId
487
+ );
488
+ }
489
+ if (status === 403) {
490
+ return attachRequestId(
491
+ createPermissionError(
492
+ parsed.errorMessage,
493
+ errorDetails,
494
+ parsed.userMessage,
495
+ suggestion
496
+ ),
497
+ requestId
498
+ );
499
+ }
500
+ if (status === 404) {
501
+ return attachRequestId(
502
+ createNotFoundError(
503
+ parsed.errorMessage,
504
+ errorDetails,
505
+ parsed.userMessage,
506
+ suggestion
507
+ ),
508
+ requestId
509
+ );
510
+ }
511
+ if (status === 409) {
512
+ return attachRequestId(
513
+ createConflictError(
514
+ parsed.errorMessage,
515
+ errorDetails,
516
+ parsed.userMessage,
517
+ suggestion
518
+ ),
519
+ requestId
520
+ );
521
+ }
522
+ return attachRequestId(
523
+ createNetworkError(
524
+ parsed.errorMessage,
525
+ status,
526
+ errorDetails,
527
+ parsed.userMessage,
528
+ suggestion
529
+ ),
530
+ requestId
531
+ );
532
+ }
533
+ async function httpFetch(url, options) {
534
+ const {
535
+ publishableKey,
536
+ secretKey,
537
+ customerToken,
538
+ timeout = DEFAULT_TIMEOUT,
539
+ debug,
540
+ retry,
541
+ onUnauthorized,
542
+ ...requestInit
543
+ } = options || {};
544
+ const baseUrl = resolveApiUrl();
545
+ const retryConfig = {
546
+ maxRetries: retry?.maxRetries ?? 3,
547
+ retryableStatuses: retry?.retryableStatuses ?? DEFAULT_RETRYABLE_STATUSES,
548
+ retryDelay: retry?.retryDelay ?? ((attempt) => Math.min(1e3 * 2 ** attempt, 1e4))
549
+ };
550
+ let authToken;
551
+ if (secretKey) {
552
+ authToken = secretKey;
553
+ } else if (customerToken) {
554
+ authToken = customerToken;
555
+ }
556
+ let lastError;
557
+ let hasRetried401 = false;
558
+ for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt++) {
559
+ try {
560
+ const headers = new Headers(requestInit.headers);
561
+ if (publishableKey) {
562
+ headers.set("X-Publishable-Key", publishableKey);
563
+ }
564
+ if (authToken) {
565
+ headers.set("Authorization", `Bearer ${authToken}`);
566
+ }
567
+ if (!headers.has("Content-Type") && requestInit.body && !(requestInit.body instanceof FormData)) {
568
+ headers.set("Content-Type", "application/json");
569
+ }
570
+ const redactedHeaders = Object.fromEntries(headers.entries());
571
+ if (redactedHeaders["authorization"]) {
572
+ const token = redactedHeaders["authorization"];
573
+ redactedHeaders["authorization"] = token.length > 20 ? `Bearer ...****${token.slice(-8)}` : "****";
574
+ }
575
+ debugLog(debug, "request", url, {
576
+ method: requestInit.method || "GET",
577
+ headers: redactedHeaders,
578
+ attempt: attempt + 1
579
+ });
580
+ const controller = new AbortController();
581
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
582
+ const response = await fetch(`${baseUrl}${url}`, {
583
+ ...requestInit,
584
+ headers,
585
+ signal: controller.signal
586
+ });
587
+ clearTimeout(timeoutId);
588
+ const requestId = response.headers.get("x-request-id") ?? void 0;
589
+ debugLog(debug, "response", url, {
590
+ status: response.status,
591
+ statusText: response.statusText,
592
+ headers: Object.fromEntries(response.headers.entries())
593
+ });
594
+ if (!response.ok) {
595
+ if (response.status === 429 && response.headers.get("X-Usage-Limit")) {
596
+ const limit = parseInt(
597
+ response.headers.get("X-Usage-Limit") || "0",
598
+ 10
599
+ );
600
+ const current = parseInt(
601
+ response.headers.get("X-Usage-Current") || "0",
602
+ 10
603
+ );
604
+ const remaining = parseInt(
605
+ response.headers.get("X-Usage-Remaining") || "0",
606
+ 10
607
+ );
608
+ throw attachRequestId(
609
+ createUsageLimitError(
610
+ `Monthly API usage limit exceeded (${current.toLocaleString()}/${limit.toLocaleString()})`,
611
+ { limit, current, remaining },
612
+ { url, method: requestInit.method || "GET", attempt: attempt + 1 },
613
+ "Monthly API call limit exceeded. Please upgrade your plan.",
614
+ "Upgrade your tenant plan to increase the monthly API call limit."
615
+ ),
616
+ requestId
617
+ );
618
+ }
619
+ const parsed = await parseErrorBody(response);
620
+ if (response.status === 401 && onUnauthorized && customerToken && !hasRetried401 && parsed.reason === "token_expired") {
621
+ hasRetried401 = true;
622
+ try {
623
+ const newToken = await onUnauthorized();
624
+ if (newToken) {
625
+ authToken = newToken;
626
+ continue;
627
+ }
628
+ } catch {
629
+ }
630
+ }
631
+ const details = {
632
+ url,
633
+ method: requestInit.method || "GET",
634
+ attempt: attempt + 1
635
+ };
636
+ if (NON_RETRYABLE_STATUSES.includes(response.status)) {
637
+ throw createHttpStatusError(
638
+ response.status,
639
+ parsed,
640
+ details,
641
+ requestId
642
+ );
643
+ }
644
+ const error = attachRequestId(
645
+ createNetworkError(
646
+ parsed.errorMessage,
647
+ response.status,
648
+ details,
649
+ parsed.userMessage,
650
+ getErrorSuggestion(response.status)
651
+ ),
652
+ requestId
653
+ );
654
+ const method = (requestInit.method || "GET").toUpperCase();
655
+ if (attempt < retryConfig.maxRetries && SAFE_METHODS.includes(method) && retryConfig.retryableStatuses.includes(response.status)) {
656
+ lastError = error;
657
+ const retryDelay = retryConfig.retryDelay(attempt);
658
+ debugLog(debug, "error", `Retrying in ${retryDelay}ms...`, error);
659
+ await delay(retryDelay);
660
+ continue;
661
+ }
662
+ throw error;
663
+ }
664
+ return response;
665
+ } catch (error) {
666
+ debugLog(debug, "error", url, error);
667
+ const method = (requestInit.method || "GET").toUpperCase();
668
+ const isSafe = SAFE_METHODS.includes(method);
669
+ if (error instanceof Error && error.name === "AbortError") {
670
+ const timeoutError = createTimeoutError(
671
+ `Request timed out after ${timeout}ms.`,
672
+ { url, timeout, attempt: attempt + 1 },
673
+ "The request timed out.",
674
+ "Please check your network connection or try again later."
675
+ );
676
+ if (isSafe && attempt < retryConfig.maxRetries) {
677
+ lastError = timeoutError;
678
+ await delay(retryConfig.retryDelay(attempt));
679
+ continue;
680
+ }
681
+ throw timeoutError;
682
+ }
683
+ if (error instanceof TypeError) {
684
+ const networkError = createNetworkError(
685
+ "Network connection failed.",
686
+ void 0,
687
+ { url, originalError: error.message, attempt: attempt + 1 },
688
+ "Network connection failed.",
689
+ "Please check your internet connection and try again."
690
+ );
691
+ if (isSafe && attempt < retryConfig.maxRetries) {
692
+ lastError = networkError;
693
+ await delay(retryConfig.retryDelay(attempt));
694
+ continue;
695
+ }
696
+ throw networkError;
697
+ }
698
+ if (error instanceof NetworkError || error instanceof TimeoutError) {
699
+ if (isSafe && attempt < retryConfig.maxRetries && error.status && !NON_RETRYABLE_STATUSES.includes(error.status) && retryConfig.retryableStatuses.includes(error.status)) {
700
+ lastError = error;
701
+ await delay(retryConfig.retryDelay(attempt));
702
+ continue;
703
+ }
704
+ throw error;
705
+ }
706
+ if (error instanceof SDKError) {
707
+ throw error;
708
+ }
709
+ const unknownError = createNetworkError(
710
+ error instanceof Error ? error.message : "An unknown network error occurred.",
711
+ void 0,
712
+ { url, originalError: error, attempt: attempt + 1 },
713
+ "An unknown error occurred.",
714
+ "Please try again later."
715
+ );
716
+ if (isSafe && attempt < retryConfig.maxRetries) {
717
+ lastError = unknownError;
718
+ await delay(retryConfig.retryDelay(attempt));
719
+ continue;
720
+ }
721
+ throw unknownError;
722
+ }
723
+ }
724
+ throw lastError ?? new NetworkError("Request failed after retries");
725
+ }
726
+
727
+ // src/core/collection/http-client.ts
728
+ var HttpClient = class {
729
+ constructor(publishableKey, secretKey, getCustomerToken, onUnauthorized, onRequestId) {
730
+ this.publishableKey = requirePublishableKeyForSecret(
731
+ "CollectionClient",
732
+ publishableKey,
733
+ secretKey
734
+ );
735
+ this.secretKey = secretKey;
736
+ this.getCustomerToken = getCustomerToken;
737
+ this.onUnauthorized = onUnauthorized;
738
+ this.onRequestId = onRequestId;
739
+ }
740
+ get defaultOptions() {
741
+ const opts = {
742
+ publishableKey: this.publishableKey,
743
+ secretKey: this.secretKey
744
+ };
745
+ const token = this.getCustomerToken?.();
746
+ if (token) {
747
+ opts.customerToken = token;
748
+ if (this.onUnauthorized) {
749
+ opts.onUnauthorized = this.onUnauthorized;
750
+ }
751
+ }
752
+ return opts;
753
+ }
754
+ async fetchWithTracking(url, opts) {
755
+ try {
756
+ const response = await httpFetch(url, opts);
757
+ this.onRequestId?.(response.headers.get("x-request-id") ?? null);
758
+ return response;
759
+ } catch (err) {
760
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
761
+ this.onRequestId?.(id);
762
+ throw err;
763
+ }
764
+ }
765
+ buildUrl(endpoint, options) {
766
+ if (!options) return endpoint;
767
+ const queryString = (0, import_qs_esm.stringify)(options, { addQueryPrefix: true });
768
+ return queryString ? `${endpoint}${queryString}` : endpoint;
769
+ }
770
+ assertJsonResponse(response) {
771
+ const contentType = response.headers.get("content-type");
772
+ if (!contentType?.includes("application/json")) {
773
+ throw createApiError("Response is not in JSON format.", response.status, {
774
+ contentType
775
+ });
776
+ }
777
+ }
778
+ /**
779
+ * Parse Payload CMS find response (list query)
780
+ * Returns native Payload response structure
781
+ */
782
+ async parseFindResponse(response) {
783
+ const contentType = response.headers.get("content-type");
784
+ try {
785
+ this.assertJsonResponse(response);
786
+ const jsonData = await response.json();
787
+ if (jsonData.docs === void 0) {
788
+ throw createApiError("Invalid find response.", response.status, {
789
+ jsonData
790
+ });
791
+ }
792
+ return {
793
+ docs: jsonData.docs,
794
+ totalDocs: jsonData.totalDocs ?? 0,
795
+ limit: jsonData.limit || 20,
796
+ totalPages: jsonData.totalPages ?? 0,
797
+ page: jsonData.page || 1,
798
+ pagingCounter: jsonData.pagingCounter || 1,
799
+ hasPrevPage: jsonData.hasPrevPage ?? false,
800
+ hasNextPage: jsonData.hasNextPage ?? false,
801
+ prevPage: jsonData.prevPage ?? null,
802
+ nextPage: jsonData.nextPage ?? null
803
+ };
804
+ } catch (error) {
805
+ if (error instanceof SDKError) throw error;
806
+ throw createApiError("Failed to parse response.", response.status, {
807
+ contentType,
808
+ error: error instanceof Error ? error.message : error
809
+ });
810
+ }
811
+ }
812
+ /**
813
+ * Parse Payload CMS mutation response (create/update)
814
+ * Returns native Payload response structure
815
+ */
816
+ async parseMutationResponse(response) {
817
+ const contentType = response.headers.get("content-type");
818
+ try {
819
+ this.assertJsonResponse(response);
820
+ const jsonData = await response.json();
821
+ if (jsonData.doc === void 0) {
822
+ throw createApiError("Invalid mutation response.", response.status, {
823
+ jsonData
824
+ });
825
+ }
826
+ return {
827
+ message: jsonData.message || "",
828
+ doc: jsonData.doc,
829
+ errors: jsonData.errors
830
+ };
831
+ } catch (error) {
832
+ if (error instanceof SDKError) throw error;
833
+ throw createApiError("Failed to parse response.", response.status, {
834
+ contentType,
835
+ error: error instanceof Error ? error.message : error
836
+ });
837
+ }
838
+ }
839
+ /**
840
+ * Parse Payload CMS document response (findById/delete)
841
+ * Returns document directly without wrapper
842
+ */
843
+ async parseDocumentResponse(response) {
844
+ const contentType = response.headers.get("content-type");
845
+ try {
846
+ this.assertJsonResponse(response);
847
+ const jsonData = await response.json();
848
+ return jsonData;
849
+ } catch (error) {
850
+ if (error instanceof SDKError) throw error;
851
+ throw createApiError("Failed to parse response.", response.status, {
852
+ contentType,
853
+ error: error instanceof Error ? error.message : error
854
+ });
855
+ }
856
+ }
857
+ };
858
+
859
+ // src/core/collection/collection-client.ts
860
+ function buildPayloadFormData(data, file, filename) {
861
+ const formData = new FormData();
862
+ formData.append("file", file, filename);
863
+ if (data != null) {
864
+ formData.append("_payload", JSON.stringify(data));
865
+ }
866
+ return formData;
867
+ }
868
+ var CollectionClient = class extends HttpClient {
869
+ from(collection) {
870
+ return new CollectionQueryBuilder(this, collection);
871
+ }
872
+ // ============================================================================
873
+ // Payload-native methods
874
+ // ============================================================================
875
+ /**
876
+ * Find documents (list query)
877
+ * GET /api/{collection}
878
+ */
879
+ async requestFind(endpoint, options) {
880
+ const url = this.buildUrl(endpoint, options);
881
+ const response = await this.fetchWithTracking(url, {
882
+ ...this.defaultOptions,
883
+ method: "GET"
884
+ });
885
+ return this.parseFindResponse(response);
886
+ }
887
+ /**
888
+ * Find-like response from a custom endpoint
889
+ * POST /api/...custom-endpoint
890
+ */
891
+ async requestFindEndpoint(endpoint, data) {
892
+ const response = await this.fetchWithTracking(endpoint, {
893
+ ...this.defaultOptions,
894
+ method: "POST",
895
+ body: data ? JSON.stringify(data) : void 0
896
+ });
897
+ return this.parseFindResponse(response);
898
+ }
899
+ /**
900
+ * Find document by ID
901
+ * GET /api/{collection}/{id}
902
+ */
903
+ async requestFindById(endpoint, options) {
904
+ const url = this.buildUrl(endpoint, options);
905
+ const response = await this.fetchWithTracking(url, {
906
+ ...this.defaultOptions,
907
+ method: "GET"
908
+ });
909
+ return this.parseDocumentResponse(response);
910
+ }
911
+ /**
912
+ * Create document
913
+ * POST /api/{collection}
914
+ */
915
+ async requestCreate(endpoint, data) {
916
+ const response = await this.fetchWithTracking(endpoint, {
917
+ ...this.defaultOptions,
918
+ method: "POST",
919
+ body: data ? JSON.stringify(data) : void 0
920
+ });
921
+ return this.parseMutationResponse(response);
922
+ }
923
+ /**
924
+ * Update document
925
+ * PATCH /api/{collection}/{id}
926
+ */
927
+ async requestUpdate(endpoint, data) {
928
+ const response = await this.fetchWithTracking(endpoint, {
929
+ ...this.defaultOptions,
930
+ method: "PATCH",
931
+ body: data ? JSON.stringify(data) : void 0
932
+ });
933
+ return this.parseMutationResponse(response);
934
+ }
935
+ /**
936
+ * Count documents
937
+ * GET /api/{collection}/count
938
+ */
939
+ async requestCount(endpoint, options) {
940
+ const url = this.buildUrl(endpoint, options);
941
+ const response = await this.fetchWithTracking(url, {
942
+ ...this.defaultOptions,
943
+ method: "GET"
944
+ });
945
+ return this.parseDocumentResponse(response);
946
+ }
947
+ /**
948
+ * Update multiple documents (bulk update)
949
+ * PATCH /api/{collection}
950
+ */
951
+ async requestUpdateMany(endpoint, data) {
952
+ const response = await this.fetchWithTracking(endpoint, {
953
+ ...this.defaultOptions,
954
+ method: "PATCH",
955
+ body: JSON.stringify(data)
956
+ });
957
+ return this.parseFindResponse(response);
958
+ }
959
+ /**
960
+ * Delete document
961
+ * DELETE /api/{collection}/{id}
962
+ */
963
+ async requestDelete(endpoint) {
964
+ const response = await this.fetchWithTracking(endpoint, {
965
+ ...this.defaultOptions,
966
+ method: "DELETE"
967
+ });
968
+ return this.parseDocumentResponse(response);
969
+ }
970
+ /**
971
+ * Delete multiple documents (bulk delete)
972
+ * DELETE /api/{collection}
973
+ */
974
+ async requestDeleteMany(endpoint, data) {
975
+ const response = await this.fetchWithTracking(endpoint, {
976
+ ...this.defaultOptions,
977
+ method: "DELETE",
978
+ body: JSON.stringify(data)
979
+ });
980
+ return this.parseFindResponse(response);
981
+ }
982
+ /**
983
+ * Create document with file upload
984
+ * POST /api/{collection} (multipart/form-data)
985
+ */
986
+ async requestCreateWithFile(endpoint, data, file, filename) {
987
+ const response = await this.fetchWithTracking(endpoint, {
988
+ ...this.defaultOptions,
989
+ method: "POST",
990
+ body: buildPayloadFormData(data, file, filename)
991
+ });
992
+ return this.parseMutationResponse(response);
993
+ }
994
+ /**
995
+ * Update document with file upload
996
+ * PATCH /api/{collection}/{id} (multipart/form-data)
997
+ */
998
+ async requestUpdateWithFile(endpoint, data, file, filename) {
999
+ const response = await this.fetchWithTracking(endpoint, {
1000
+ ...this.defaultOptions,
1001
+ method: "PATCH",
1002
+ body: buildPayloadFormData(data, file, filename)
1003
+ });
1004
+ return this.parseMutationResponse(response);
1005
+ }
1006
+ };
1007
+ var ServerCollectionClient = class extends CollectionClient {
1008
+ from(collection) {
1009
+ return new ServerCollectionQueryBuilder(this, collection);
1010
+ }
1011
+ };
1012
+
1013
+ // src/core/api/parse-response.ts
1014
+ async function parseApiResponse(response, endpoint) {
1015
+ let data;
1016
+ try {
1017
+ data = await response.json();
1018
+ } catch {
1019
+ throw createApiError(
1020
+ `Invalid JSON response from ${endpoint}`,
1021
+ response.status,
1022
+ void 0,
1023
+ "Server returned an invalid response.",
1024
+ "Check if the API endpoint is available."
1025
+ );
1026
+ }
1027
+ if (data.error) {
1028
+ const errorMessage = typeof data.error === "string" ? data.error : "Unknown API error";
1029
+ const reason = typeof data.reason === "string" ? data.reason : void 0;
1030
+ const requestId = response.headers.get("x-request-id") ?? void 0;
1031
+ const retryAfterRaw = response.headers.get("Retry-After");
1032
+ const retryAfter = retryAfterRaw ? parseInt(retryAfterRaw, 10) || void 0 : void 0;
1033
+ if (reason === "validation_failed") {
1034
+ throw attachRequestId(createValidationError(errorMessage, data, errorMessage), requestId);
1035
+ }
1036
+ if (reason === "token_expired" || reason === "token_invalid" || reason === "key_invalid" || reason === "key_revoked") {
1037
+ throw attachRequestId(createAuthError(errorMessage, data, errorMessage), requestId);
1038
+ }
1039
+ if (reason === "forbidden") {
1040
+ throw attachRequestId(createPermissionError(errorMessage, data, errorMessage), requestId);
1041
+ }
1042
+ if (reason === "rate_limit_exceeded") {
1043
+ throw attachRequestId(createRateLimitError(errorMessage, retryAfter, data, errorMessage), requestId);
1044
+ }
1045
+ if (reason === "not_found") {
1046
+ throw attachRequestId(createNotFoundError(errorMessage, data, errorMessage), requestId);
1047
+ }
1048
+ if (reason === "conflict") {
1049
+ throw attachRequestId(createConflictError(errorMessage, data, errorMessage), requestId);
1050
+ }
1051
+ throw attachRequestId(
1052
+ createApiError(errorMessage, response.status, data, errorMessage, "An error occurred while processing the request."),
1053
+ requestId
1054
+ );
1055
+ }
1056
+ return data;
1057
+ }
1058
+
1059
+ // src/core/community/community-client.ts
1060
+ var CommunityClient = class {
1061
+ constructor(options) {
1062
+ this.publishableKey = requirePublishableKeyForSecret(
1063
+ "CommunityClient",
1064
+ options.publishableKey,
1065
+ options.secretKey
1066
+ );
1067
+ this.secretKey = options.secretKey;
1068
+ this.customerToken = options.customerToken;
1069
+ this.onUnauthorized = options.onUnauthorized;
1070
+ this.onRequestId = options.onRequestId;
1071
+ }
1072
+ buildQuery(params) {
1073
+ if (!params) return "";
1074
+ const entries = Object.entries(params).filter((e) => e[1] !== void 0).map(([k, v]) => [k, String(v)]);
1075
+ return entries.length ? `?${new URLSearchParams(entries).toString()}` : "";
1076
+ }
1077
+ async execute(endpoint, method, body) {
1078
+ const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1079
+ try {
1080
+ const response = await httpFetch(endpoint, {
1081
+ method,
1082
+ publishableKey: this.publishableKey,
1083
+ secretKey: this.secretKey,
1084
+ customerToken: token ?? void 0,
1085
+ ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1086
+ ...body !== void 0 && { body: JSON.stringify(body) }
1087
+ });
1088
+ this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1089
+ return parseApiResponse(response, endpoint);
1090
+ } catch (err) {
1091
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
1092
+ this.onRequestId?.(id);
1093
+ throw err;
1094
+ }
1095
+ }
1096
+ createPost(params) {
1097
+ return this.execute("/api/posts", "POST", params);
1098
+ }
1099
+ getMyPosts(params) {
1100
+ return this.execute(
1101
+ `/api/posts/my${this.buildQuery(params)}`,
1102
+ "GET"
1103
+ );
1104
+ }
1105
+ getTrending(params) {
1106
+ return this.execute(
1107
+ `/api/posts/trending${this.buildQuery(params)}`,
1108
+ "GET"
1109
+ );
1110
+ }
1111
+ incrementView(params) {
1112
+ return this.execute(
1113
+ `/api/posts/${params.postId}/view`,
1114
+ "POST"
1115
+ );
1116
+ }
1117
+ reportPost(params) {
1118
+ const { postId, ...body } = params;
1119
+ return this.execute(
1120
+ `/api/posts/${postId}/report`,
1121
+ "POST",
1122
+ body
1123
+ );
1124
+ }
1125
+ // Comments
1126
+ createComment(params) {
1127
+ const { postId, parentId, body: commentBody } = params;
1128
+ const body = { post: postId, body: commentBody };
1129
+ if (parentId !== void 0) {
1130
+ body.parent = parentId;
1131
+ }
1132
+ return this.execute("/api/comments", "POST", body);
1133
+ }
1134
+ listComments(params) {
1135
+ const { postId, page, limit, rootComment } = params;
1136
+ const urlParams = new URLSearchParams();
1137
+ urlParams.set("where[post][equals]", postId);
1138
+ urlParams.set("sort", "-createdAt");
1139
+ if (limit !== void 0) urlParams.set("limit", String(limit));
1140
+ if (page !== void 0) urlParams.set("page", String(page));
1141
+ if (rootComment !== void 0) urlParams.set("where[rootComment][equals]", rootComment);
1142
+ return this.execute(
1143
+ `/api/comments?${urlParams.toString()}`,
1144
+ "GET"
1145
+ );
1146
+ }
1147
+ updateComment(params) {
1148
+ const { commentId, body } = params;
1149
+ return this.execute(
1150
+ `/api/comments/${commentId}`,
1151
+ "PATCH",
1152
+ { body }
1153
+ );
1154
+ }
1155
+ deleteComment(params) {
1156
+ return this.execute(
1157
+ `/api/comments/${params.commentId}`,
1158
+ "DELETE"
1159
+ );
1160
+ }
1161
+ reportComment(params) {
1162
+ const { commentId, ...body } = params;
1163
+ return this.execute(
1164
+ `/api/comments/${commentId}/report`,
1165
+ "POST",
1166
+ body
1167
+ );
1168
+ }
1169
+ // Reactions
1170
+ addReaction(params) {
1171
+ const { postId, type } = params;
1172
+ return this.execute("/api/reactions", "POST", {
1173
+ post: postId,
1174
+ type
1175
+ });
1176
+ }
1177
+ removeReaction(params) {
1178
+ const { postId, type } = params;
1179
+ return this.execute(
1180
+ `/api/posts/${postId}/react?type=${encodeURIComponent(type)}`,
1181
+ "DELETE"
1182
+ );
1183
+ }
1184
+ addCommentReaction(params) {
1185
+ const { commentId, type } = params;
1186
+ return this.execute("/api/reactions", "POST", {
1187
+ comment: commentId,
1188
+ type
1189
+ });
1190
+ }
1191
+ removeCommentReaction(params) {
1192
+ const { commentId, type } = params;
1193
+ return this.execute(
1194
+ `/api/comments/${commentId}/react?type=${encodeURIComponent(type)}`,
1195
+ "DELETE"
1196
+ );
1197
+ }
1198
+ getReactionSummary(params) {
1199
+ return this.execute(
1200
+ `/api/posts/${params.postId}/reactions`,
1201
+ "GET"
1202
+ );
1203
+ }
1204
+ getReactionTypes() {
1205
+ return this.execute(
1206
+ "/api/reaction-types?limit=100",
1207
+ "GET"
1208
+ );
1209
+ }
1210
+ // Bookmarks
1211
+ addBookmark(params) {
1212
+ return this.execute("/api/bookmarks", "POST", {
1213
+ post: params.postId
1214
+ });
1215
+ }
1216
+ removeBookmark(params) {
1217
+ return this.execute(
1218
+ `/api/posts/${params.postId}/bookmark`,
1219
+ "DELETE"
1220
+ );
1221
+ }
1222
+ getMyBookmarks(params) {
1223
+ return this.execute(
1224
+ `/api/bookmarks/my${this.buildQuery(params)}`,
1225
+ "GET"
1226
+ );
1227
+ }
1228
+ };
1229
+
1230
+ // src/core/api/base-api.ts
1231
+ var BaseApi = class {
1232
+ constructor(apiName, options) {
1233
+ if (!options.secretKey) {
1234
+ throw createConfigError(`secretKey is required for ${apiName}.`);
1235
+ }
1236
+ this.publishableKey = requirePublishableKeyForSecret(
1237
+ apiName,
1238
+ options.publishableKey,
1239
+ options.secretKey
1240
+ );
1241
+ this.secretKey = options.secretKey;
1242
+ this.onRequestId = options.onRequestId;
1243
+ }
1244
+ async request(endpoint, body, options) {
1245
+ const method = options?.method ?? "POST";
1246
+ try {
1247
+ const response = await httpFetch(endpoint, {
1248
+ method,
1249
+ publishableKey: this.publishableKey,
1250
+ secretKey: this.secretKey,
1251
+ ...body !== void 0 && { body: JSON.stringify(body) },
1252
+ ...options?.headers && { headers: options.headers }
1253
+ });
1254
+ this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1255
+ return parseApiResponse(response, endpoint);
1256
+ } catch (err) {
1257
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
1258
+ this.onRequestId?.(id);
1259
+ throw err;
1260
+ }
1261
+ }
1262
+ };
1263
+
1264
+ // src/core/community/moderation-api.ts
1265
+ var ModerationApi = class extends BaseApi {
1266
+ constructor(options) {
1267
+ super("ModerationApi", options);
1268
+ }
1269
+ banCustomer(params) {
1270
+ return this.request("/api/community-bans/ban", params);
1271
+ }
1272
+ unbanCustomer(params) {
1273
+ return this.request("/api/community-bans/unban", params);
1274
+ }
1275
+ };
1276
+
1277
+ // src/core/api/cart-api.ts
1278
+ var CartApi = class {
1279
+ constructor(options) {
1280
+ if (!options.secretKey && !options.customerToken) {
1281
+ throw createConfigError(
1282
+ "Either secretKey or customerToken is required for CartApi."
1283
+ );
1284
+ }
1285
+ this.publishableKey = requirePublishableKeyForSecret(
1286
+ "CartApi",
1287
+ options.publishableKey,
1288
+ options.secretKey
1289
+ );
1290
+ this.secretKey = options.secretKey;
1291
+ this.customerToken = options.customerToken;
1292
+ this.onUnauthorized = options.onUnauthorized;
1293
+ this.onRequestId = options.onRequestId;
1294
+ }
1295
+ async execute(endpoint, method, body) {
1296
+ const token = typeof this.customerToken === "function" ? this.customerToken() : this.customerToken;
1297
+ try {
1298
+ const response = await httpFetch(endpoint, {
1299
+ method,
1300
+ publishableKey: this.publishableKey,
1301
+ secretKey: this.secretKey,
1302
+ customerToken: token ?? void 0,
1303
+ ...token && this.onUnauthorized && { onUnauthorized: this.onUnauthorized },
1304
+ ...body !== void 0 && { body: JSON.stringify(body) }
1305
+ });
1306
+ this.onRequestId?.(response.headers.get("x-request-id") ?? null);
1307
+ return parseApiResponse(response, endpoint);
1308
+ } catch (err) {
1309
+ const id = err instanceof SDKError ? err.requestId ?? null : null;
1310
+ this.onRequestId?.(id);
1311
+ throw err;
1312
+ }
1313
+ }
1314
+ getCart(cartId) {
1315
+ return this.execute(`/api/carts/${cartId}`, "GET");
1316
+ }
1317
+ addItem(params) {
1318
+ return this.execute("/api/carts/add-item", "POST", params);
1319
+ }
1320
+ updateItem(params) {
1321
+ return this.execute("/api/carts/update-item", "POST", params);
1322
+ }
1323
+ removeItem(params) {
1324
+ return this.execute(
1325
+ "/api/carts/remove-item",
1326
+ "POST",
1327
+ params
1328
+ );
1329
+ }
1330
+ applyDiscount(params) {
1331
+ return this.execute("/api/carts/apply-discount", "POST", params);
1332
+ }
1333
+ removeDiscount(params) {
1334
+ return this.execute("/api/carts/remove-discount", "POST", params);
1335
+ }
1336
+ clearCart(params) {
1337
+ return this.execute(
1338
+ "/api/carts/clear",
1339
+ "POST",
1340
+ params
1341
+ );
1342
+ }
1343
+ };
1344
+
1345
+ // src/core/api/product-api.ts
1346
+ var ProductApi = class extends BaseApi {
1347
+ constructor(options) {
1348
+ super("ProductApi", options);
1349
+ }
1350
+ /**
1351
+ * Check point-in-time stock availability for one or more product variants.
1352
+ * Results reflect available stock at the moment of the call and are not guaranteed
1353
+ * to remain available by the time an order is placed.
1354
+ */
1355
+ stockCheck(params) {
1356
+ return this.request("/api/products/stock-check", params);
1357
+ }
1358
+ listingGroups(params) {
1359
+ return this.request(
1360
+ "/api/products/listing-groups",
1361
+ params
1362
+ );
1363
+ }
1364
+ };
1365
+
1366
+ // src/core/api/discount-api.ts
1367
+ var DiscountApi = class extends BaseApi {
1368
+ constructor(options) {
1369
+ super("DiscountApi", options);
1370
+ }
1371
+ validate(params) {
1372
+ return this.request("/api/discounts/validate", params);
1373
+ }
1374
+ };
1375
+
1376
+ // src/core/api/shipping-api.ts
1377
+ var ShippingApi = class extends BaseApi {
1378
+ constructor(options) {
1379
+ super("ShippingApi", options);
1380
+ }
1381
+ calculate(params) {
1382
+ return this.request("/api/shipping-policies/calculate", params);
1383
+ }
1384
+ };
1385
+
1386
+ // src/core/api/order-api.ts
1387
+ var OrderApi = class extends BaseApi {
1388
+ constructor(options) {
1389
+ super("OrderApi", options);
1390
+ }
1391
+ createOrder(params) {
1392
+ return this.request("/api/orders/create", params);
1393
+ }
1394
+ updateOrder(params) {
1395
+ return this.request("/api/orders/update", params);
1396
+ }
1397
+ updateTransaction(params) {
1398
+ return this.request("/api/transactions/update", params);
1399
+ }
1400
+ checkout(params) {
1401
+ return this.request("/api/orders/checkout", params);
1402
+ }
1403
+ createFulfillment(params) {
1404
+ return this.request("/api/orders/create-fulfillment", params);
1405
+ }
1406
+ updateFulfillment(params) {
1407
+ return this.request("/api/orders/update-fulfillment", params);
1408
+ }
1409
+ bulkImportFulfillments(params) {
1410
+ return this.request(
1411
+ "/api/orders/bulk-import-fulfillments",
1412
+ params
1413
+ );
1414
+ }
1415
+ returnWithRefund(params) {
1416
+ return this.request(
1417
+ "/api/returns/return-refund",
1418
+ params
1419
+ );
1420
+ }
1421
+ createReturn(params) {
1422
+ return this.request("/api/returns/create", params);
1423
+ }
1424
+ updateReturn(params) {
1425
+ return this.request("/api/returns/update", params);
1426
+ }
1427
+ };
1428
+
1429
+ // src/core/commerce/server-commerce-client.ts
1430
+ var ServerCommerceClient = class {
1431
+ constructor(options) {
1432
+ const publishableKey = requirePublishableKeyForSecret(
1433
+ "ServerCommerceClient",
1434
+ options.publishableKey,
1435
+ options.secretKey
1436
+ );
1437
+ const serverOptions = {
1438
+ publishableKey,
1439
+ secretKey: options.secretKey,
1440
+ onRequestId: options.onRequestId
1441
+ };
1442
+ const productApi = new ProductApi(serverOptions);
1443
+ const cartApi = new CartApi(serverOptions);
1444
+ const discountApi = new DiscountApi(serverOptions);
1445
+ const shippingApi = new ShippingApi(serverOptions);
1446
+ const orderApi = new OrderApi(serverOptions);
1447
+ this.product = {
1448
+ stockCheck: productApi.stockCheck.bind(productApi),
1449
+ listingGroups: productApi.listingGroups.bind(productApi)
1450
+ };
1451
+ this.cart = {
1452
+ get: cartApi.getCart.bind(cartApi),
1453
+ addItem: cartApi.addItem.bind(cartApi),
1454
+ updateItem: cartApi.updateItem.bind(cartApi),
1455
+ removeItem: cartApi.removeItem.bind(cartApi),
1456
+ applyDiscount: cartApi.applyDiscount.bind(cartApi),
1457
+ removeDiscount: cartApi.removeDiscount.bind(cartApi),
1458
+ clear: cartApi.clearCart.bind(cartApi)
1459
+ };
1460
+ this.orders = {
1461
+ checkout: orderApi.checkout.bind(orderApi),
1462
+ create: orderApi.createOrder.bind(orderApi),
1463
+ update: orderApi.updateOrder.bind(orderApi),
1464
+ updateTransaction: orderApi.updateTransaction.bind(orderApi),
1465
+ createFulfillment: orderApi.createFulfillment.bind(orderApi),
1466
+ updateFulfillment: orderApi.updateFulfillment.bind(orderApi),
1467
+ bulkImportFulfillments: orderApi.bulkImportFulfillments.bind(orderApi),
1468
+ createReturn: orderApi.createReturn.bind(orderApi),
1469
+ updateReturn: orderApi.updateReturn.bind(orderApi),
1470
+ returnWithRefund: orderApi.returnWithRefund.bind(orderApi)
1471
+ };
1472
+ this.discounts = {
1473
+ validate: discountApi.validate.bind(discountApi)
1474
+ };
1475
+ this.shipping = {
1476
+ calculate: shippingApi.calculate.bind(shippingApi)
1477
+ };
1478
+ }
1479
+ };
1480
+
1481
+ // src/core/query/get-query-client.ts
1482
+ var import_react_query = require("@tanstack/react-query");
1483
+ function makeQueryClient() {
1484
+ return new import_react_query.QueryClient({
1485
+ defaultOptions: {
1486
+ queries: {
1487
+ // Infinite staleTime: server-fetched data persists until explicitly invalidated.
1488
+ // For browser clients needing fresher data, override per-query:
1489
+ // useQuery({ ..., staleTime: 5 * 60 * 1000 })
1490
+ staleTime: Number.POSITIVE_INFINITY,
1491
+ refetchOnWindowFocus: false
1492
+ },
1493
+ dehydrate: {
1494
+ shouldDehydrateQuery: (query) => (0, import_react_query.defaultShouldDehydrateQuery)(query) || query.state.status === "pending",
1495
+ shouldRedactErrors: () => false
1496
+ }
1497
+ }
1498
+ });
1499
+ }
1500
+ var browserQueryClient;
1501
+ function getQueryClient() {
1502
+ if (import_react_query.isServer) {
1503
+ return makeQueryClient();
1504
+ }
1505
+ if (!browserQueryClient) {
1506
+ browserQueryClient = makeQueryClient();
1507
+ }
1508
+ return browserQueryClient;
1509
+ }
1510
+
1511
+ // src/core/query/query-hooks.ts
1512
+ var import_react_query4 = require("@tanstack/react-query");
1513
+
1514
+ // src/core/query/collection-hooks.ts
1515
+ var import_react_query2 = require("@tanstack/react-query");
1516
+
1517
+ // src/core/query/query-keys.ts
1518
+ function collectionKeys(collection) {
1519
+ return {
1520
+ all: [collection],
1521
+ lists: () => [collection, "list"],
1522
+ list: (options) => [collection, "list", options],
1523
+ details: () => [collection, "detail"],
1524
+ detail: (id, options) => [collection, "detail", id, options],
1525
+ infinites: () => [collection, "infinite"],
1526
+ infinite: (options) => [collection, "infinite", options]
1527
+ };
1528
+ }
1529
+ var customerKeys = {
1530
+ all: ["customer"],
1531
+ me: () => ["customer", "me"]
1532
+ };
1533
+ var productKeys = {
1534
+ listingGroups: (options) => ["products", "listing-groups", "list", options],
1535
+ listingGroupsInfinite: (options) => ["products", "listing-groups", "infinite", options]
1536
+ };
1537
+
1538
+ // src/core/query/collection-hooks.ts
1539
+ var DEFAULT_PAGE_SIZE = 20;
1540
+ var CollectionHooks = class {
1541
+ constructor(queryClient, collectionClient) {
1542
+ this.queryClient = queryClient;
1543
+ this.collectionClient = collectionClient;
1544
+ }
1545
+ // ===== useQuery =====
1546
+ useQuery(params, options) {
1547
+ const { collection, options: queryOptions } = params;
1548
+ const { placeholderData, ...restOptions } = options ?? {};
1549
+ return (0, import_react_query2.useQuery)({
1550
+ queryKey: collectionKeys(collection).list(queryOptions),
1551
+ queryFn: async () => {
1552
+ return await this.collectionClient.from(collection).find(queryOptions);
1553
+ },
1554
+ ...restOptions,
1555
+ // NonFunctionGuard<T> incompatible with generic union types — safe cast
1556
+ ...placeholderData !== void 0 && {
1557
+ placeholderData
1558
+ }
1559
+ });
1560
+ }
1561
+ // ===== useSuspenseQuery =====
1562
+ useSuspenseQuery(params, options) {
1563
+ const { collection, options: queryOptions } = params;
1564
+ return (0, import_react_query2.useSuspenseQuery)({
1565
+ queryKey: collectionKeys(collection).list(queryOptions),
1566
+ queryFn: async () => {
1567
+ return await this.collectionClient.from(collection).find(queryOptions);
1568
+ },
1569
+ ...options
1570
+ });
1571
+ }
1572
+ // ===== useQueryById =====
1573
+ useQueryById(params, options) {
1574
+ const { collection, id, options: queryOptions } = params;
1575
+ const { placeholderData, ...restOptions } = options ?? {};
1576
+ return (0, import_react_query2.useQuery)({
1577
+ queryKey: collectionKeys(collection).detail(id, queryOptions),
1578
+ queryFn: async () => {
1579
+ return await this.collectionClient.from(collection).findById(id, queryOptions);
1580
+ },
1581
+ ...restOptions,
1582
+ // NonFunctionGuard<T> incompatible with generic union types — safe cast
1583
+ ...placeholderData !== void 0 && {
1584
+ placeholderData
1585
+ }
1586
+ });
1587
+ }
1588
+ // ===== useSuspenseQueryById =====
1589
+ useSuspenseQueryById(params, options) {
1590
+ const { collection, id, options: queryOptions } = params;
1591
+ return (0, import_react_query2.useSuspenseQuery)({
1592
+ queryKey: collectionKeys(collection).detail(id, queryOptions),
1593
+ queryFn: async () => {
1594
+ return await this.collectionClient.from(collection).findById(id, queryOptions);
1595
+ },
1596
+ ...options
1597
+ });
1598
+ }
1599
+ // ===== useInfiniteQuery =====
1600
+ useInfiniteQuery(params, options) {
1601
+ const {
1602
+ collection,
1603
+ options: queryOptions,
1604
+ pageSize = DEFAULT_PAGE_SIZE
1605
+ } = params;
1606
+ return (0, import_react_query2.useInfiniteQuery)({
1607
+ queryKey: collectionKeys(collection).infinite(queryOptions),
1608
+ queryFn: async ({ pageParam }) => {
1609
+ const response = await this.collectionClient.from(collection).find({ ...queryOptions, page: pageParam, limit: pageSize });
1610
+ return response;
1611
+ },
1612
+ initialPageParam: 1,
1613
+ getNextPageParam: (lastPage) => {
1614
+ return lastPage.hasNextPage ? lastPage.nextPage : void 0;
1615
+ },
1616
+ ...options
1617
+ });
1618
+ }
1619
+ // ===== useSuspenseInfiniteQuery =====
1620
+ useSuspenseInfiniteQuery(params, options) {
1621
+ const {
1622
+ collection,
1623
+ options: queryOptions,
1624
+ pageSize = DEFAULT_PAGE_SIZE
1625
+ } = params;
1626
+ return (0, import_react_query2.useSuspenseInfiniteQuery)({
1627
+ queryKey: collectionKeys(collection).infinite(queryOptions),
1628
+ queryFn: async ({ pageParam }) => {
1629
+ const response = await this.collectionClient.from(collection).find({ ...queryOptions, page: pageParam, limit: pageSize });
1630
+ return response;
1631
+ },
1632
+ initialPageParam: 1,
1633
+ getNextPageParam: (lastPage) => {
1634
+ return lastPage.hasNextPage ? lastPage.nextPage : void 0;
1635
+ },
1636
+ ...options
1637
+ });
1638
+ }
1639
+ // ===== prefetchQuery =====
1640
+ async prefetchQuery(params, options) {
1641
+ const { collection, options: queryOptions } = params;
1642
+ return this.queryClient.prefetchQuery({
1643
+ queryKey: collectionKeys(collection).list(queryOptions),
1644
+ queryFn: async () => {
1645
+ return await this.collectionClient.from(collection).find(queryOptions);
1646
+ },
1647
+ ...options
1648
+ });
1649
+ }
1650
+ // ===== prefetchQueryById =====
1651
+ async prefetchQueryById(params, options) {
1652
+ const { collection, id, options: queryOptions } = params;
1653
+ return this.queryClient.prefetchQuery({
1654
+ queryKey: collectionKeys(collection).detail(id, queryOptions),
1655
+ queryFn: async () => {
1656
+ return await this.collectionClient.from(collection).findById(id, queryOptions);
1657
+ },
1658
+ ...options
1659
+ });
1660
+ }
1661
+ // ===== prefetchInfiniteQuery =====
1662
+ async prefetchInfiniteQuery(params, options) {
1663
+ const {
1664
+ collection,
1665
+ options: queryOptions,
1666
+ pageSize = DEFAULT_PAGE_SIZE
1667
+ } = params;
1668
+ return this.queryClient.prefetchInfiniteQuery({
1669
+ queryKey: collectionKeys(collection).infinite(queryOptions),
1670
+ queryFn: async ({ pageParam }) => {
1671
+ const response = await this.collectionClient.from(collection).find({ ...queryOptions, page: pageParam, limit: pageSize });
1672
+ return response;
1673
+ },
1674
+ initialPageParam: 1,
1675
+ getNextPageParam: (lastPage) => {
1676
+ return lastPage.hasNextPage ? lastPage.nextPage : void 0;
1677
+ },
1678
+ pages: options?.pages ?? 1,
1679
+ staleTime: options?.staleTime
1680
+ });
1681
+ }
1682
+ // ===== Mutation Hooks =====
1683
+ useCreate(params, options) {
1684
+ const { collection } = params;
1685
+ return (0, import_react_query2.useMutation)({
1686
+ mutationFn: async (variables) => {
1687
+ return await this.collectionClient.from(collection).create(
1688
+ variables.data,
1689
+ variables.file ? { file: variables.file, filename: variables.filename } : void 0
1690
+ );
1691
+ },
1692
+ onSuccess: (data) => {
1693
+ this.queryClient.invalidateQueries({
1694
+ queryKey: collectionKeys(collection).all
1695
+ });
1696
+ options?.onSuccess?.(data);
1697
+ },
1698
+ onError: options?.onError,
1699
+ onSettled: options?.onSettled
1700
+ });
1701
+ }
1702
+ useUpdate(params, options) {
1703
+ const { collection } = params;
1704
+ return (0, import_react_query2.useMutation)({
1705
+ mutationFn: async (variables) => {
1706
+ return await this.collectionClient.from(collection).update(
1707
+ variables.id,
1708
+ variables.data,
1709
+ variables.file ? { file: variables.file, filename: variables.filename } : void 0
1710
+ );
1711
+ },
1712
+ onSuccess: (data) => {
1713
+ this.queryClient.invalidateQueries({
1714
+ queryKey: collectionKeys(collection).all
1715
+ });
1716
+ options?.onSuccess?.(data);
1717
+ },
1718
+ onError: options?.onError,
1719
+ onSettled: options?.onSettled
1720
+ });
1721
+ }
1722
+ useRemove(params, options) {
1723
+ const { collection } = params;
1724
+ return (0, import_react_query2.useMutation)({
1725
+ mutationFn: async (id) => {
1726
+ return await this.collectionClient.from(collection).remove(id);
1727
+ },
1728
+ onSuccess: (data) => {
1729
+ this.queryClient.invalidateQueries({
1730
+ queryKey: collectionKeys(collection).all
1731
+ });
1732
+ options?.onSuccess?.(data);
1733
+ },
1734
+ onError: options?.onError,
1735
+ onSettled: options?.onSettled
1736
+ });
1737
+ }
1738
+ // ===== Cache Utilities =====
1739
+ invalidateQueries(collection, type) {
1740
+ const queryKey = type ? [collection, type] : [collection];
1741
+ return this.queryClient.invalidateQueries({ queryKey });
1742
+ }
1743
+ getQueryData(collection, type, idOrOptions, options) {
1744
+ if (type === "list") {
1745
+ return this.queryClient.getQueryData(
1746
+ collectionKeys(collection).list(idOrOptions)
1747
+ );
1748
+ }
1749
+ return this.queryClient.getQueryData(
1750
+ collectionKeys(collection).detail(idOrOptions, options)
1751
+ );
1752
+ }
1753
+ setQueryData(collection, type, dataOrId, dataOrOptions, options) {
1754
+ if (type === "list") {
1755
+ this.queryClient.setQueryData(
1756
+ collectionKeys(collection).list(dataOrOptions),
1757
+ dataOrId
1758
+ );
1759
+ } else {
1760
+ this.queryClient.setQueryData(
1761
+ collectionKeys(collection).detail(dataOrId, options),
1762
+ dataOrOptions
1763
+ );
1764
+ }
1765
+ }
1766
+ };
1767
+
1768
+ // src/core/query/customer-hooks.ts
1769
+ var import_react_query3 = require("@tanstack/react-query");
1770
+ function createMutation(mutationFn, callbacks, onSuccessExtra) {
1771
+ return (0, import_react_query3.useMutation)({
1772
+ mutationFn,
1773
+ onSuccess: (data) => {
1774
+ onSuccessExtra?.(data);
1775
+ callbacks?.onSuccess?.(data);
1776
+ },
1777
+ onError: callbacks?.onError,
1778
+ onSettled: callbacks?.onSettled
1779
+ });
1780
+ }
1781
+ var CustomerHooks = class {
1782
+ constructor(queryClient, customerAuth) {
1783
+ this.invalidateMe = () => {
1784
+ this.queryClient.invalidateQueries({ queryKey: customerKeys.me() });
1785
+ };
1786
+ this.queryClient = queryClient;
1787
+ this.customerAuth = customerAuth;
1788
+ }
1789
+ ensureCustomerAuth() {
1790
+ if (!this.customerAuth) {
1791
+ throw createConfigError(
1792
+ "Customer hooks require Client. Use createClient() instead of createServerClient()."
1793
+ );
1794
+ }
1795
+ return this.customerAuth;
1796
+ }
1797
+ // ===== useCustomerMe =====
1798
+ useCustomerMe(options) {
1799
+ return (0, import_react_query3.useQuery)({
1800
+ queryKey: customerKeys.me(),
1801
+ queryFn: async () => {
1802
+ return await this.ensureCustomerAuth().me();
1803
+ },
1804
+ ...options,
1805
+ enabled: (options?.enabled ?? true) && !!this.customerAuth?.isAuthenticated()
1806
+ });
1807
+ }
1808
+ // ===== Mutations =====
1809
+ useCustomerLogin(options) {
1810
+ return createMutation(
1811
+ (data) => this.ensureCustomerAuth().login(data),
1812
+ options,
1813
+ this.invalidateMe
1814
+ );
1815
+ }
1816
+ useCustomerRegister(options) {
1817
+ return createMutation(
1818
+ (data) => this.ensureCustomerAuth().register(data),
1819
+ options
1820
+ );
1821
+ }
1822
+ useCustomerLogout(options) {
1823
+ return (0, import_react_query3.useMutation)({
1824
+ mutationFn: async () => {
1825
+ this.ensureCustomerAuth().logout();
1826
+ },
1827
+ onSuccess: () => {
1828
+ this.queryClient.removeQueries({ queryKey: customerKeys.all });
1829
+ options?.onSuccess?.();
1830
+ },
1831
+ onError: options?.onError,
1832
+ onSettled: options?.onSettled
1833
+ });
1834
+ }
1835
+ useCustomerForgotPassword(options) {
1836
+ return createMutation(
1837
+ (email) => this.ensureCustomerAuth().forgotPassword(email).then(() => {
1838
+ }),
1839
+ options
1840
+ );
1841
+ }
1842
+ useCustomerResetPassword(options) {
1843
+ return createMutation(
1844
+ (data) => this.ensureCustomerAuth().resetPassword(data.token, data.password).then(() => {
1845
+ }),
1846
+ options
1847
+ );
1848
+ }
1849
+ useCustomerRefreshToken(options) {
1850
+ return createMutation(
1851
+ () => this.ensureCustomerAuth().refreshToken(),
1852
+ options,
1853
+ this.invalidateMe
1854
+ );
1855
+ }
1856
+ useCustomerUpdateProfile(options) {
1857
+ return createMutation(
1858
+ (data) => this.ensureCustomerAuth().updateProfile(data),
1859
+ options,
1860
+ this.invalidateMe
1861
+ );
1862
+ }
1863
+ useCustomerChangePassword(options) {
1864
+ return createMutation(
1865
+ (data) => this.ensureCustomerAuth().changePassword(data.currentPassword, data.newPassword).then(() => {
1866
+ }),
1867
+ options
1868
+ );
1869
+ }
1870
+ // ===== Customer Cache Utilities =====
1871
+ invalidateCustomerQueries() {
1872
+ return this.queryClient.invalidateQueries({ queryKey: customerKeys.all });
1873
+ }
1874
+ getCustomerData() {
1875
+ return this.queryClient.getQueryData(customerKeys.me());
1876
+ }
1877
+ setCustomerData(data) {
1878
+ this.queryClient.setQueryData(customerKeys.me(), data);
1879
+ }
1880
+ };
1881
+
1882
+ // src/core/query/query-hooks.ts
1883
+ var QueryHooks = class extends CollectionHooks {
1884
+ constructor(queryClient, collectionClient, customerAuth) {
1885
+ super(queryClient, collectionClient);
1886
+ // --- Customer hooks delegation ---
1887
+ this.useCustomerMe = (...args) => this._customer.useCustomerMe(...args);
1888
+ this.useCustomerLogin = (...args) => this._customer.useCustomerLogin(...args);
1889
+ this.useCustomerRegister = (...args) => this._customer.useCustomerRegister(...args);
1890
+ this.useCustomerLogout = (...args) => this._customer.useCustomerLogout(...args);
1891
+ this.useCustomerForgotPassword = (...args) => this._customer.useCustomerForgotPassword(...args);
1892
+ this.useCustomerResetPassword = (...args) => this._customer.useCustomerResetPassword(...args);
1893
+ this.useCustomerRefreshToken = (...args) => this._customer.useCustomerRefreshToken(...args);
1894
+ this.useCustomerUpdateProfile = (...args) => this._customer.useCustomerUpdateProfile(...args);
1895
+ this.useCustomerChangePassword = (...args) => this._customer.useCustomerChangePassword(...args);
1896
+ // --- Customer cache delegation ---
1897
+ this.invalidateCustomerQueries = () => this._customer.invalidateCustomerQueries();
1898
+ this.getCustomerData = () => this._customer.getCustomerData();
1899
+ this.setCustomerData = (data) => this._customer.setCustomerData(data);
1900
+ this._customer = new CustomerHooks(queryClient, customerAuth);
1901
+ }
1902
+ useProductListingGroupsQuery(params, options) {
1903
+ const queryOptions = params.options;
1904
+ const { placeholderData, ...restOptions } = options ?? {};
1905
+ return (0, import_react_query4.useQuery)({
1906
+ queryKey: productKeys.listingGroups(queryOptions),
1907
+ queryFn: async () => this.collectionClient.requestFindEndpoint(
1908
+ "/api/products/listing-groups/query",
1909
+ { options: queryOptions }
1910
+ ),
1911
+ ...restOptions,
1912
+ ...placeholderData !== void 0 && {
1913
+ placeholderData
1914
+ }
1915
+ });
1916
+ }
1917
+ useSuspenseProductListingGroupsQuery(params, options) {
1918
+ const queryOptions = params.options;
1919
+ return (0, import_react_query4.useSuspenseQuery)({
1920
+ queryKey: productKeys.listingGroups(queryOptions),
1921
+ queryFn: async () => this.collectionClient.requestFindEndpoint(
1922
+ "/api/products/listing-groups/query",
1923
+ { options: queryOptions }
1924
+ ),
1925
+ ...options
1926
+ });
1927
+ }
1928
+ useInfiniteProductListingGroupsQuery(params, options) {
1929
+ const {
1930
+ options: queryOptions,
1931
+ pageSize = 20
1932
+ } = params;
1933
+ return (0, import_react_query4.useInfiniteQuery)({
1934
+ queryKey: productKeys.listingGroupsInfinite(queryOptions),
1935
+ queryFn: async ({ pageParam }) => this.collectionClient.requestFindEndpoint(
1936
+ "/api/products/listing-groups/query",
1937
+ {
1938
+ options: { ...queryOptions, page: pageParam, limit: pageSize }
1939
+ }
1940
+ ),
1941
+ initialPageParam: 1,
1942
+ getNextPageParam: (lastPage) => lastPage.hasNextPage ? lastPage.nextPage : void 0,
1943
+ ...options
1944
+ });
1945
+ }
1946
+ useSuspenseInfiniteProductListingGroupsQuery(params, options) {
1947
+ const {
1948
+ options: queryOptions,
1949
+ pageSize = 20
1950
+ } = params;
1951
+ return (0, import_react_query4.useSuspenseInfiniteQuery)({
1952
+ queryKey: productKeys.listingGroupsInfinite(queryOptions),
1953
+ queryFn: async ({ pageParam }) => this.collectionClient.requestFindEndpoint(
1954
+ "/api/products/listing-groups/query",
1955
+ {
1956
+ options: { ...queryOptions, page: pageParam, limit: pageSize }
1957
+ }
1958
+ ),
1959
+ initialPageParam: 1,
1960
+ getNextPageParam: (lastPage) => lastPage.hasNextPage ? lastPage.nextPage : void 0,
1961
+ ...options
1962
+ });
1963
+ }
1964
+ async prefetchProductListingGroupsQuery(params, options) {
1965
+ const queryOptions = params.options;
1966
+ return this.queryClient.prefetchQuery({
1967
+ queryKey: productKeys.listingGroups(queryOptions),
1968
+ queryFn: async () => this.collectionClient.requestFindEndpoint(
1969
+ "/api/products/listing-groups/query",
1970
+ { options: queryOptions }
1971
+ ),
1972
+ ...options
1973
+ });
1974
+ }
1975
+ async prefetchInfiniteProductListingGroupsQuery(params, options) {
1976
+ const {
1977
+ options: queryOptions,
1978
+ pageSize = 20
1979
+ } = params;
1980
+ return this.queryClient.prefetchInfiniteQuery({
1981
+ queryKey: productKeys.listingGroupsInfinite(queryOptions),
1982
+ queryFn: async ({ pageParam }) => this.collectionClient.requestFindEndpoint(
1983
+ "/api/products/listing-groups/query",
1984
+ {
1985
+ options: { ...queryOptions, page: pageParam, limit: pageSize }
1986
+ }
1987
+ ),
1988
+ initialPageParam: 1,
1989
+ getNextPageParam: (lastPage) => lastPage.hasNextPage ? lastPage.nextPage : void 0,
1990
+ pages: options?.pages ?? 1,
1991
+ staleTime: options?.staleTime
1992
+ });
1993
+ }
1994
+ };
1995
+
1996
+ // src/core/client/client.server.ts
1997
+ var ServerClient = class {
1998
+ constructor(options) {
1999
+ this.lastRequestId = null;
2000
+ if (typeof window !== "undefined") {
2001
+ throw createConfigError(
2002
+ "ServerClient must not be used in a browser environment. This risks exposing your secretKey in client bundles. Use createClient() for browser code instead."
2003
+ );
2004
+ }
2005
+ if (!options.secretKey) {
2006
+ throw createConfigError("secretKey is required.");
2007
+ }
2008
+ if (!options.publishableKey) {
2009
+ throw createConfigError(
2010
+ "publishableKey is required. It is used for rate limiting and monthly quota enforcement via the X-Publishable-Key header. Get it from Console > Settings > API Keys."
2011
+ );
2012
+ }
2013
+ this.config = { ...options, publishableKey: options.publishableKey };
2014
+ const metadata = {
2015
+ timestamp: Date.now(),
2016
+ userAgent: "Node.js"
2017
+ };
2018
+ this.state = { metadata };
2019
+ const onRequestId = (id) => {
2020
+ this.lastRequestId = id;
2021
+ };
2022
+ const serverOptions = {
2023
+ publishableKey: this.config.publishableKey,
2024
+ secretKey: this.config.secretKey,
2025
+ onRequestId
2026
+ };
2027
+ this.commerce = new ServerCommerceClient(serverOptions);
2028
+ const communityClient = new CommunityClient(serverOptions);
2029
+ const moderationApi = new ModerationApi(serverOptions);
2030
+ this.community = Object.assign(communityClient, {
2031
+ moderation: {
2032
+ banCustomer: moderationApi.banCustomer.bind(moderationApi),
2033
+ unbanCustomer: moderationApi.unbanCustomer.bind(moderationApi)
2034
+ }
2035
+ });
2036
+ this.collections = new ServerCollectionClient(
2037
+ this.config.publishableKey,
2038
+ this.config.secretKey,
2039
+ void 0,
2040
+ void 0,
2041
+ onRequestId
2042
+ );
2043
+ this.queryClient = getQueryClient();
2044
+ this.query = new QueryHooks(this.queryClient, this.collections);
2045
+ }
2046
+ getState() {
2047
+ return { ...this.state };
2048
+ }
2049
+ getConfig() {
2050
+ const { secretKey: _, ...safeConfig } = this.config;
2051
+ return safeConfig;
2052
+ }
2053
+ };
2054
+ function createServerClient(options) {
2055
+ return new ServerClient(options);
2056
+ }
2057
+ //# sourceMappingURL=server.cjs.map