@01.software/sdk 0.31.0 → 0.33.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 +128 -47
- package/dist/analytics/react.cjs.map +1 -1
- package/dist/analytics/react.js.map +1 -1
- package/dist/analytics.cjs.map +1 -1
- package/dist/analytics.js.map +1 -1
- package/dist/client.cjs +41 -48
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +6 -6
- package/dist/client.d.ts +6 -6
- package/dist/client.js +41 -48
- package/dist/client.js.map +1 -1
- package/dist/{collection-client-ByzY3hWK.d.ts → collection-client-B6SlhzIP.d.ts} +3 -3
- package/dist/{collection-client-DFXXz0vk.d.cts → collection-client-De6eKW1J.d.cts} +3 -3
- package/dist/{const-AytzliEu.d.cts → const-DwmSDeWq.d.ts} +2 -2
- package/dist/{const-BGCP-OJL.d.ts → const-sPR2IkCe.d.cts} +2 -2
- package/dist/index.cjs +310 -133
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +310 -133
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-Wa4-eC6x.d.cts → payload-types-dkeQyrDC.d.cts} +1572 -1440
- package/dist/{payload-types-Wa4-eC6x.d.ts → payload-types-dkeQyrDC.d.ts} +1572 -1440
- package/dist/query.cjs.map +1 -1
- package/dist/query.d.cts +20 -20
- package/dist/query.d.ts +20 -20
- package/dist/query.js.map +1 -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.map +1 -1
- package/dist/server.cjs +70 -6
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +100 -8
- package/dist/server.d.ts +100 -8
- package/dist/server.js +70 -6
- package/dist/server.js.map +1 -1
- package/dist/{types-CmLG-7RL.d.cts → types-B3YT092I.d.cts} +1 -1
- package/dist/{types-BX2mqDf6.d.ts → types-BHh0YLmq.d.ts} +63 -13
- package/dist/{types-DChFjQGz.d.cts → types-BZKxss8Y.d.cts} +63 -13
- package/dist/{types-CVA10VC-.d.ts → types-Cel_4L9t.d.ts} +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.cjs +142 -1
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +149 -5
- package/dist/webhook.d.ts +149 -5
- package/dist/webhook.js +142 -1
- package/dist/webhook.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { D as DebugConfig, R as RetryConfig, A as ApiQueryOptions, P as PayloadFindResponse, g as PayloadMutationResponse } from './types-
|
|
1
|
+
import { D as DebugConfig, R as RetryConfig, A as ApiQueryOptions, P as PayloadFindResponse, g as PayloadMutationResponse } from './types-BHh0YLmq.js';
|
|
2
2
|
import { GenerateMetadataOptions, Metadata } from './metadata.js';
|
|
3
|
-
import { c as ServerCollection, P as PublicCollection } from './const-
|
|
4
|
-
import { C as CollectionType } from './types-
|
|
3
|
+
import { c as ServerCollection, P as PublicCollection } from './const-DwmSDeWq.js';
|
|
4
|
+
import { C as CollectionType } from './types-Cel_4L9t.js';
|
|
5
5
|
|
|
6
6
|
interface FetchOptions extends RequestInit {
|
|
7
7
|
apiUrl?: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { D as DebugConfig, R as RetryConfig, A as ApiQueryOptions, P as PayloadFindResponse, g as PayloadMutationResponse } from './types-
|
|
1
|
+
import { D as DebugConfig, R as RetryConfig, A as ApiQueryOptions, P as PayloadFindResponse, g as PayloadMutationResponse } from './types-BZKxss8Y.cjs';
|
|
2
2
|
import { GenerateMetadataOptions, Metadata } from './metadata.cjs';
|
|
3
|
-
import { c as ServerCollection, P as PublicCollection } from './const-
|
|
4
|
-
import { C as CollectionType } from './types-
|
|
3
|
+
import { c as ServerCollection, P as PublicCollection } from './const-sPR2IkCe.cjs';
|
|
4
|
+
import { C as CollectionType } from './types-B3YT092I.cjs';
|
|
5
5
|
|
|
6
6
|
interface FetchOptions extends RequestInit {
|
|
7
7
|
apiUrl?: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { e as Config } from './payload-types-
|
|
1
|
+
import { e as Config } from './payload-types-dkeQyrDC.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Collection type derived from Payload Config.
|
|
@@ -9,7 +9,7 @@ type Collection = keyof Config['collections'];
|
|
|
9
9
|
* Internal collections that should not be exposed via SDK.
|
|
10
10
|
* Includes Payload system collections and admin-only collections.
|
|
11
11
|
*/
|
|
12
|
-
declare const INTERNAL_COLLECTIONS: readonly ["users", "payload-kv", "payload-locked-documents", "payload-preferences", "payload-migrations", "payload-folders", "field-configs", "system-media", "track-assets", "audiences", "email-logs", "api-usage", "tenant-analytics-daily", "tenant-web-analytics-config", "analytics-event-schemas", "subscriptions", "billing-history", "inventory-reservations", "product-collection-items", "order-status-logs", "api-keys", "personal-access-tokens", "tenant-entitlements", "tenant-purge-jobs", "direct-upload-sessions", "webhook-events", "webhook-deliveries", "audit-logs", "plans", "webhooks", "event-registrations"];
|
|
12
|
+
declare const INTERNAL_COLLECTIONS: readonly ["users", "payload-kv", "payload-locked-documents", "payload-preferences", "payload-migrations", "payload-folders", "field-configs", "system-media", "track-assets", "audiences", "email-logs", "api-usage", "tenant-analytics-daily", "tenant-web-analytics-config", "analytics-event-schemas", "subscriptions", "billing-history", "inventory-reservations", "commerce-notification-intents", "product-collection-items", "order-status-logs", "api-keys", "personal-access-tokens", "tenant-entitlements", "tenant-purge-jobs", "direct-upload-sessions", "webhook-events", "webhook-deliveries", "audit-logs", "plans", "webhooks", "event-registrations"];
|
|
13
13
|
/**
|
|
14
14
|
* Array of all public collection names for runtime use (e.g., Zod enum validation).
|
|
15
15
|
* This is the single source of truth for which collections are publicly accessible via SDK.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { e as Config } from './payload-types-
|
|
1
|
+
import { e as Config } from './payload-types-dkeQyrDC.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Collection type derived from Payload Config.
|
|
@@ -9,7 +9,7 @@ type Collection = keyof Config['collections'];
|
|
|
9
9
|
* Internal collections that should not be exposed via SDK.
|
|
10
10
|
* Includes Payload system collections and admin-only collections.
|
|
11
11
|
*/
|
|
12
|
-
declare const INTERNAL_COLLECTIONS: readonly ["users", "payload-kv", "payload-locked-documents", "payload-preferences", "payload-migrations", "payload-folders", "field-configs", "system-media", "track-assets", "audiences", "email-logs", "api-usage", "tenant-analytics-daily", "tenant-web-analytics-config", "analytics-event-schemas", "subscriptions", "billing-history", "inventory-reservations", "product-collection-items", "order-status-logs", "api-keys", "personal-access-tokens", "tenant-entitlements", "tenant-purge-jobs", "direct-upload-sessions", "webhook-events", "webhook-deliveries", "audit-logs", "plans", "webhooks", "event-registrations"];
|
|
12
|
+
declare const INTERNAL_COLLECTIONS: readonly ["users", "payload-kv", "payload-locked-documents", "payload-preferences", "payload-migrations", "payload-folders", "field-configs", "system-media", "track-assets", "audiences", "email-logs", "api-usage", "tenant-analytics-daily", "tenant-web-analytics-config", "analytics-event-schemas", "subscriptions", "billing-history", "inventory-reservations", "commerce-notification-intents", "product-collection-items", "order-status-logs", "api-keys", "personal-access-tokens", "tenant-entitlements", "tenant-purge-jobs", "direct-upload-sessions", "webhook-events", "webhook-deliveries", "audit-logs", "plans", "webhooks", "event-registrations"];
|
|
13
13
|
/**
|
|
14
14
|
* Array of all public collection names for runtime use (e.g., Zod enum validation).
|
|
15
15
|
* This is the single source of truth for which collections are publicly accessible via SDK.
|
package/dist/index.cjs
CHANGED
|
@@ -24,6 +24,9 @@ __export(src_exports, {
|
|
|
24
24
|
AuthError: () => AuthError,
|
|
25
25
|
BaseApi: () => BaseApi,
|
|
26
26
|
COLLECTIONS: () => COLLECTIONS,
|
|
27
|
+
COMMERCE_NOTIFICATION_EVENTS: () => COMMERCE_NOTIFICATION_EVENTS,
|
|
28
|
+
COMMERCE_NOTIFICATION_EVENT_TYPE: () => COMMERCE_NOTIFICATION_EVENT_TYPE,
|
|
29
|
+
COMMERCE_NOTIFICATION_OPERATION: () => COMMERCE_NOTIFICATION_OPERATION,
|
|
27
30
|
CUSTOMER_PASSWORD_RESET_OPERATION: () => CUSTOMER_PASSWORD_RESET_OPERATION,
|
|
28
31
|
CartApi: () => CartApi,
|
|
29
32
|
CommerceClient: () => CommerceClient,
|
|
@@ -38,6 +41,7 @@ __export(src_exports, {
|
|
|
38
41
|
INTERNAL_COLLECTIONS: () => INTERNAL_COLLECTIONS,
|
|
39
42
|
NetworkError: () => NetworkError,
|
|
40
43
|
NotFoundError: () => NotFoundError,
|
|
44
|
+
ORDER_CHANGED_EVENT_TYPE: () => ORDER_CHANGED_EVENT_TYPE,
|
|
41
45
|
OrderApi: () => OrderApi,
|
|
42
46
|
PermissionError: () => PermissionError,
|
|
43
47
|
ProductApi: () => ProductApi,
|
|
@@ -61,6 +65,7 @@ __export(src_exports, {
|
|
|
61
65
|
createAnalytics: () => createAnalytics,
|
|
62
66
|
createAuthError: () => createAuthError,
|
|
63
67
|
createClient: () => createClient2,
|
|
68
|
+
createCommerceEmailWebhookHandler: () => createCommerceEmailWebhookHandler,
|
|
64
69
|
createConflictError: () => createConflictError,
|
|
65
70
|
createCustomerAuthWebhookHandler: () => createCustomerAuthWebhookHandler,
|
|
66
71
|
createNotFoundError: () => createNotFoundError,
|
|
@@ -68,9 +73,11 @@ __export(src_exports, {
|
|
|
68
73
|
createProductSelectionCodec: () => createProductSelectionCodec,
|
|
69
74
|
createRateLimitError: () => createRateLimitError,
|
|
70
75
|
createTypedWebhookHandler: () => createTypedWebhookHandler,
|
|
76
|
+
defineCommerceEmailConfig: () => defineCommerceEmailConfig,
|
|
71
77
|
formatOrderName: () => formatOrderName,
|
|
72
78
|
generateOrderNumber: () => generateOrderNumber,
|
|
73
79
|
getAvailableOptionValues: () => getAvailableOptionValues,
|
|
80
|
+
getCommerceNotificationIdempotencyKey: () => getCommerceNotificationIdempotencyKey,
|
|
74
81
|
getImageLqip: () => getImageLqip,
|
|
75
82
|
getImagePalette: () => getImagePalette,
|
|
76
83
|
getImagePlaceholderStyle: () => getImagePlaceholderStyle,
|
|
@@ -86,12 +93,14 @@ __export(src_exports, {
|
|
|
86
93
|
handleWebhook: () => handleWebhook,
|
|
87
94
|
isApiError: () => isApiError,
|
|
88
95
|
isAuthError: () => isAuthError,
|
|
96
|
+
isCommerceNotificationWebhookEvent: () => isCommerceNotificationWebhookEvent,
|
|
89
97
|
isConfigError: () => isConfigError,
|
|
90
98
|
isConflictError: () => isConflictError,
|
|
91
99
|
isCustomerPasswordResetWebhookEvent: () => isCustomerPasswordResetWebhookEvent,
|
|
92
100
|
isGoneError: () => isGoneError,
|
|
93
101
|
isNetworkError: () => isNetworkError,
|
|
94
102
|
isNotFoundError: () => isNotFoundError,
|
|
103
|
+
isOrderChangedWebhookEvent: () => isOrderChangedWebhookEvent,
|
|
95
104
|
isPermissionError: () => isPermissionError,
|
|
96
105
|
isRateLimitError: () => isRateLimitError,
|
|
97
106
|
isSDKError: () => isSDKError,
|
|
@@ -100,6 +109,8 @@ __export(src_exports, {
|
|
|
100
109
|
isUsageLimitError: () => isUsageLimitError,
|
|
101
110
|
isValidWebhookEvent: () => isValidWebhookEvent,
|
|
102
111
|
isValidationError: () => isValidationError,
|
|
112
|
+
isWebhookCollection: () => isWebhookCollection,
|
|
113
|
+
isWebhookOperation: () => isWebhookOperation,
|
|
103
114
|
normalizeProductSelection: () => normalizeProductSelection,
|
|
104
115
|
normalizeProductSelectionFromMatrix: () => normalizeProductSelectionFromMatrix,
|
|
105
116
|
normalizeSelectedValueIds: () => normalizeSelectedValueIds,
|
|
@@ -1340,7 +1351,7 @@ var CustomerAuth = class {
|
|
|
1340
1351
|
);
|
|
1341
1352
|
return data.customer ?? null;
|
|
1342
1353
|
} catch (error) {
|
|
1343
|
-
if (error instanceof
|
|
1354
|
+
if (error instanceof SDKError && error.status === 401) {
|
|
1344
1355
|
this.setToken(null);
|
|
1345
1356
|
return null;
|
|
1346
1357
|
}
|
|
@@ -1435,51 +1446,15 @@ var CustomerAuth = class {
|
|
|
1435
1446
|
if (!headers.has("Content-Type") && init.body) {
|
|
1436
1447
|
headers.set("Content-Type", "application/json");
|
|
1437
1448
|
}
|
|
1438
|
-
const
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
} catch (error) {
|
|
1448
|
-
clearTimeout(timeoutId);
|
|
1449
|
-
if (error instanceof Error && error.name === "AbortError") {
|
|
1450
|
-
throw new TimeoutError(`Request timed out after ${DEFAULT_TIMEOUT2}ms`, {
|
|
1451
|
-
url: path,
|
|
1452
|
-
timeout: DEFAULT_TIMEOUT2
|
|
1453
|
-
});
|
|
1454
|
-
}
|
|
1455
|
-
throw new NetworkError(
|
|
1456
|
-
error instanceof Error ? error.message : "Network request failed",
|
|
1457
|
-
void 0,
|
|
1458
|
-
{ url: path },
|
|
1459
|
-
"Network connection failed.",
|
|
1460
|
-
"Please check your internet connection and try again."
|
|
1461
|
-
);
|
|
1462
|
-
}
|
|
1463
|
-
clearTimeout(timeoutId);
|
|
1464
|
-
if (!res.ok) {
|
|
1465
|
-
const body = await res.json().catch(() => ({}));
|
|
1466
|
-
throw new ApiError(
|
|
1467
|
-
body.error || `HTTP ${res.status}`,
|
|
1468
|
-
res.status,
|
|
1469
|
-
body.details,
|
|
1470
|
-
body.error
|
|
1471
|
-
);
|
|
1472
|
-
}
|
|
1473
|
-
try {
|
|
1474
|
-
return await res.json();
|
|
1475
|
-
} catch {
|
|
1476
|
-
throw new ApiError(
|
|
1477
|
-
"Invalid JSON response from server",
|
|
1478
|
-
res.status,
|
|
1479
|
-
void 0,
|
|
1480
|
-
"INVALID_RESPONSE"
|
|
1481
|
-
);
|
|
1482
|
-
}
|
|
1449
|
+
const response = await httpFetch(path, {
|
|
1450
|
+
...init,
|
|
1451
|
+
apiUrl: this.baseUrl,
|
|
1452
|
+
publishableKey: this.publishableKey,
|
|
1453
|
+
headers,
|
|
1454
|
+
timeout: DEFAULT_TIMEOUT2,
|
|
1455
|
+
retry: { maxRetries: 0 }
|
|
1456
|
+
});
|
|
1457
|
+
return parseApiResponse(response, path);
|
|
1483
1458
|
}
|
|
1484
1459
|
};
|
|
1485
1460
|
|
|
@@ -1560,6 +1535,117 @@ var CartApi = class {
|
|
|
1560
1535
|
}
|
|
1561
1536
|
};
|
|
1562
1537
|
|
|
1538
|
+
// src/core/api/base-api.ts
|
|
1539
|
+
var BaseApi = class {
|
|
1540
|
+
constructor(apiName, options) {
|
|
1541
|
+
if (!options.secretKey) {
|
|
1542
|
+
throw createConfigError(`secretKey is required for ${apiName}.`);
|
|
1543
|
+
}
|
|
1544
|
+
this.publishableKey = requirePublishableKeyForSecret(
|
|
1545
|
+
apiName,
|
|
1546
|
+
options.publishableKey,
|
|
1547
|
+
options.secretKey
|
|
1548
|
+
);
|
|
1549
|
+
this.secretKey = options.secretKey;
|
|
1550
|
+
this.apiUrl = options.apiUrl;
|
|
1551
|
+
this.onRequestId = options.onRequestId;
|
|
1552
|
+
}
|
|
1553
|
+
async request(endpoint, body, options) {
|
|
1554
|
+
const method = options?.method ?? "POST";
|
|
1555
|
+
try {
|
|
1556
|
+
const response = await httpFetch(endpoint, {
|
|
1557
|
+
method,
|
|
1558
|
+
apiUrl: this.apiUrl,
|
|
1559
|
+
publishableKey: this.publishableKey,
|
|
1560
|
+
secretKey: this.secretKey,
|
|
1561
|
+
...body !== void 0 && { body: JSON.stringify(body) },
|
|
1562
|
+
...options?.headers && { headers: options.headers }
|
|
1563
|
+
});
|
|
1564
|
+
this.onRequestId?.(response.headers.get("x-request-id") ?? null);
|
|
1565
|
+
return parseApiResponse(response, endpoint);
|
|
1566
|
+
} catch (err) {
|
|
1567
|
+
const id = err instanceof SDKError ? err.requestId ?? null : null;
|
|
1568
|
+
this.onRequestId?.(id);
|
|
1569
|
+
throw err;
|
|
1570
|
+
}
|
|
1571
|
+
}
|
|
1572
|
+
};
|
|
1573
|
+
|
|
1574
|
+
// src/core/api/product-api.ts
|
|
1575
|
+
var PRODUCT_DETAIL_UNAVAILABLE_REASONS = /* @__PURE__ */ new Set([
|
|
1576
|
+
"not_found",
|
|
1577
|
+
"not_published",
|
|
1578
|
+
"feature_disabled"
|
|
1579
|
+
]);
|
|
1580
|
+
function isRecord(value) {
|
|
1581
|
+
return typeof value === "object" && value !== null;
|
|
1582
|
+
}
|
|
1583
|
+
function readProductDetailUnavailableReason(value) {
|
|
1584
|
+
if (!isRecord(value)) return void 0;
|
|
1585
|
+
const directReason = value.reason ?? value.code;
|
|
1586
|
+
if (typeof directReason === "string" && PRODUCT_DETAIL_UNAVAILABLE_REASONS.has(directReason)) {
|
|
1587
|
+
return directReason;
|
|
1588
|
+
}
|
|
1589
|
+
return readProductDetailUnavailableReason(value.body);
|
|
1590
|
+
}
|
|
1591
|
+
function productDetailResultFromError(error) {
|
|
1592
|
+
if (!(error instanceof SDKError) || error.status !== 404) return void 0;
|
|
1593
|
+
const reason = readProductDetailUnavailableReason(error.details);
|
|
1594
|
+
if (!reason) return void 0;
|
|
1595
|
+
return { found: false, reason };
|
|
1596
|
+
}
|
|
1597
|
+
var ProductApi = class extends BaseApi {
|
|
1598
|
+
constructor(options) {
|
|
1599
|
+
super("ProductApi", options);
|
|
1600
|
+
}
|
|
1601
|
+
/**
|
|
1602
|
+
* Check point-in-time stock availability for one or more product variants.
|
|
1603
|
+
* Results reflect available stock at the moment of the call and are not guaranteed
|
|
1604
|
+
* to remain available by the time an order is placed.
|
|
1605
|
+
*/
|
|
1606
|
+
stockCheck(params) {
|
|
1607
|
+
return this.request("/api/products/stock-check", params);
|
|
1608
|
+
}
|
|
1609
|
+
listingGroups(params) {
|
|
1610
|
+
return this.request(
|
|
1611
|
+
"/api/products/listing-groups",
|
|
1612
|
+
params
|
|
1613
|
+
);
|
|
1614
|
+
}
|
|
1615
|
+
/**
|
|
1616
|
+
* Fetch full product detail by slug or id.
|
|
1617
|
+
* Returns a discriminated result so storefronts can distinguish missing,
|
|
1618
|
+
* unpublished, and feature-disabled products.
|
|
1619
|
+
*
|
|
1620
|
+
* Only product-detail 404 responses carrying one of those allowlisted reasons
|
|
1621
|
+
* are mapped to `{ found: false, reason }`. Unknown or uncoded 404s, plus
|
|
1622
|
+
* permission/auth errors such as tenant mismatch, continue to throw typed SDK
|
|
1623
|
+
* errors instead of being collapsed into a storefront absence result.
|
|
1624
|
+
*/
|
|
1625
|
+
async detail(params) {
|
|
1626
|
+
try {
|
|
1627
|
+
const product = await this.request(
|
|
1628
|
+
"/api/products/detail",
|
|
1629
|
+
params
|
|
1630
|
+
);
|
|
1631
|
+
return { found: true, product };
|
|
1632
|
+
} catch (err) {
|
|
1633
|
+
const notFoundResult = productDetailResultFromError(err);
|
|
1634
|
+
if (notFoundResult) return notFoundResult;
|
|
1635
|
+
throw err;
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
/**
|
|
1639
|
+
* Atomically create or update a product together with its options,
|
|
1640
|
+
* option-values, and variants in a single transaction. Mirrors Shopify's
|
|
1641
|
+
* `productSet` shape and is the canonical write path for the MCP
|
|
1642
|
+
* `product-upsert` tool.
|
|
1643
|
+
*/
|
|
1644
|
+
upsert(params) {
|
|
1645
|
+
return this.request("/api/products/upsert", params);
|
|
1646
|
+
}
|
|
1647
|
+
};
|
|
1648
|
+
|
|
1563
1649
|
// src/core/commerce/commerce-client.ts
|
|
1564
1650
|
var CommerceClient = class {
|
|
1565
1651
|
constructor(options) {
|
|
@@ -1594,9 +1680,14 @@ var CommerceClient = class {
|
|
|
1594
1680
|
listingGroups: (params) => execute("/api/products/listing-groups", params),
|
|
1595
1681
|
detail: async (params) => {
|
|
1596
1682
|
try {
|
|
1597
|
-
|
|
1683
|
+
const product = await execute(
|
|
1684
|
+
"/api/products/detail",
|
|
1685
|
+
params
|
|
1686
|
+
);
|
|
1687
|
+
return { found: true, product };
|
|
1598
1688
|
} catch (err) {
|
|
1599
|
-
|
|
1689
|
+
const notFoundResult = productDetailResultFromError(err);
|
|
1690
|
+
if (notFoundResult) return notFoundResult;
|
|
1600
1691
|
throw err;
|
|
1601
1692
|
}
|
|
1602
1693
|
}
|
|
@@ -1688,42 +1779,6 @@ function createClient(options) {
|
|
|
1688
1779
|
return new Client(options);
|
|
1689
1780
|
}
|
|
1690
1781
|
|
|
1691
|
-
// src/core/api/base-api.ts
|
|
1692
|
-
var BaseApi = class {
|
|
1693
|
-
constructor(apiName, options) {
|
|
1694
|
-
if (!options.secretKey) {
|
|
1695
|
-
throw createConfigError(`secretKey is required for ${apiName}.`);
|
|
1696
|
-
}
|
|
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;
|
|
1723
|
-
}
|
|
1724
|
-
}
|
|
1725
|
-
};
|
|
1726
|
-
|
|
1727
1782
|
// src/core/api/order-api.ts
|
|
1728
1783
|
var OrderApi = class extends BaseApi {
|
|
1729
1784
|
constructor(options) {
|
|
@@ -1756,7 +1811,7 @@ var OrderApi = class extends BaseApi {
|
|
|
1756
1811
|
}
|
|
1757
1812
|
bulkImportFulfillments(params) {
|
|
1758
1813
|
return this.request(
|
|
1759
|
-
"/api/
|
|
1814
|
+
"/api/fulfillments/bulk-import",
|
|
1760
1815
|
params
|
|
1761
1816
|
);
|
|
1762
1817
|
}
|
|
@@ -1794,58 +1849,144 @@ var ShippingApi = class extends BaseApi {
|
|
|
1794
1849
|
}
|
|
1795
1850
|
};
|
|
1796
1851
|
|
|
1797
|
-
// src/core/api/product-api.ts
|
|
1798
|
-
var ProductApi = class extends BaseApi {
|
|
1799
|
-
constructor(options) {
|
|
1800
|
-
super("ProductApi", options);
|
|
1801
|
-
}
|
|
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);
|
|
1809
|
-
}
|
|
1810
|
-
listingGroups(params) {
|
|
1811
|
-
return this.request(
|
|
1812
|
-
"/api/products/listing-groups",
|
|
1813
|
-
params
|
|
1814
|
-
);
|
|
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);
|
|
1838
|
-
}
|
|
1839
|
-
};
|
|
1840
|
-
|
|
1841
1852
|
// src/core/webhook/index.ts
|
|
1853
|
+
var ORDER_CHANGED_EVENT_TYPE = "collection.orderChanged";
|
|
1854
|
+
var COMMERCE_NOTIFICATION_EVENT_TYPE = "commerce.notification";
|
|
1842
1855
|
function isValidWebhookEvent(data) {
|
|
1843
1856
|
if (typeof data !== "object" || data === null) return false;
|
|
1844
1857
|
const obj = data;
|
|
1845
1858
|
return typeof obj.collection === "string" && typeof obj.operation === "string" && obj.operation.length > 0 && typeof obj.data === "object" && obj.data !== null;
|
|
1846
1859
|
}
|
|
1860
|
+
var COMMERCE_NOTIFICATION_OPERATION = "notification";
|
|
1861
|
+
var COMMERCE_NOTIFICATION_EVENTS = [
|
|
1862
|
+
"orderPaid",
|
|
1863
|
+
"fulfillmentShipped",
|
|
1864
|
+
"orderDelivered",
|
|
1865
|
+
"returnRequested",
|
|
1866
|
+
"returnCompleted"
|
|
1867
|
+
];
|
|
1868
|
+
function isStringOrNumber(value) {
|
|
1869
|
+
return typeof value === "string" || typeof value === "number";
|
|
1870
|
+
}
|
|
1871
|
+
function isWebhookOrderScope(value) {
|
|
1872
|
+
if (!isRecord2(value)) return false;
|
|
1873
|
+
if (value.kind === "collection") {
|
|
1874
|
+
return typeof value.collection === "string";
|
|
1875
|
+
}
|
|
1876
|
+
if (value.kind === "join") {
|
|
1877
|
+
return typeof value.collection === "string" && typeof value.field === "string" && isStringOrNumber(value.id);
|
|
1878
|
+
}
|
|
1879
|
+
return false;
|
|
1880
|
+
}
|
|
1881
|
+
function isWebhookOrderMoved(value) {
|
|
1882
|
+
if (!isRecord2(value)) return false;
|
|
1883
|
+
return typeof value.collection === "string" && isStringOrNumber(value.id) && (value.relatedCollection === void 0 || typeof value.relatedCollection === "string") && (value.relatedId === void 0 || isStringOrNumber(value.relatedId));
|
|
1884
|
+
}
|
|
1885
|
+
function hasOptionalOrderValue(value, key) {
|
|
1886
|
+
return value[key] === void 0 || value[key] === null || typeof value[key] === "string";
|
|
1887
|
+
}
|
|
1888
|
+
function isWebhookOrderChange(value) {
|
|
1889
|
+
if (!isRecord2(value)) return false;
|
|
1890
|
+
return value.type === "order" && value.source === "payload-orderable" && (value.orderableFieldName === void 0 || typeof value.orderableFieldName === "string") && hasOptionalOrderValue(value, "previousOrder") && hasOptionalOrderValue(value, "nextOrder") && isWebhookOrderScope(value.scope) && isWebhookOrderMoved(value.moved);
|
|
1891
|
+
}
|
|
1892
|
+
function isCommerceNotificationEventName(value) {
|
|
1893
|
+
return typeof value === "string" && COMMERCE_NOTIFICATION_EVENTS.includes(value);
|
|
1894
|
+
}
|
|
1895
|
+
function isCommerceNotificationSourceCollection(value) {
|
|
1896
|
+
return value === "orders" || value === "fulfillments" || value === "returns";
|
|
1897
|
+
}
|
|
1898
|
+
function isCommerceNotificationData(value) {
|
|
1899
|
+
if (!isRecord2(value)) return false;
|
|
1900
|
+
if (value.source !== void 0 && (!isRecord2(value.source) || !isCommerceNotificationSourceCollection(value.source.collection) || !isStringOrNumber(value.source.id))) {
|
|
1901
|
+
return false;
|
|
1902
|
+
}
|
|
1903
|
+
return (value.orderId === void 0 || isStringOrNumber(value.orderId)) && (value.orderNumber === void 0 || typeof value.orderNumber === "string") && (value.status === void 0 || typeof value.status === "string") && (value.totalAmount === void 0 || typeof value.totalAmount === "number") && (value.currency === void 0 || typeof value.currency === "string") && (value.fulfillmentId === void 0 || isStringOrNumber(value.fulfillmentId)) && (value.fulfillmentStatus === void 0 || typeof value.fulfillmentStatus === "string") && (value.shippedAt === void 0 || typeof value.shippedAt === "string") && (value.returnId === void 0 || isStringOrNumber(value.returnId)) && (value.returnStatus === void 0 || typeof value.returnStatus === "string") && (value.refundAmount === void 0 || typeof value.refundAmount === "number") && (value.completedAt === void 0 || typeof value.completedAt === "string");
|
|
1904
|
+
}
|
|
1905
|
+
function isCommerceNotification(value) {
|
|
1906
|
+
if (!isRecord2(value)) return false;
|
|
1907
|
+
return isCommerceNotificationEventName(value.event) && typeof value.intentId === "string" && value.intentId.length > 0 && typeof value.dedupeKey === "string" && value.dedupeKey.length > 0 && (value.orderId === void 0 || typeof value.orderId === "string") && (value.fulfillmentId === void 0 || typeof value.fulfillmentId === "string") && (value.returnId === void 0 || typeof value.returnId === "string");
|
|
1908
|
+
}
|
|
1909
|
+
function isWebhookCommerceNotificationChange(value) {
|
|
1910
|
+
if (!isRecord2(value)) return false;
|
|
1911
|
+
return value.type === "notification" && value.source === "commerce-notifications" && isCommerceNotificationEventName(value.event) && isCommerceNotificationSourceCollection(value.sourceCollection) && isStringOrNumber(value.sourceId);
|
|
1912
|
+
}
|
|
1913
|
+
function matchesOptionalId(actual, expected) {
|
|
1914
|
+
return actual === void 0 || expected === void 0 || actual === expected;
|
|
1915
|
+
}
|
|
1916
|
+
function isOrderChangedWebhookEvent(event) {
|
|
1917
|
+
if (!isValidWebhookEvent(event) || event.operation !== "update" || event.eventType !== ORDER_CHANGED_EVENT_TYPE || !isWebhookOrderChange(event.change)) {
|
|
1918
|
+
return false;
|
|
1919
|
+
}
|
|
1920
|
+
if (event.collection !== event.change.scope.collection) {
|
|
1921
|
+
return false;
|
|
1922
|
+
}
|
|
1923
|
+
if (event.change.scope.kind === "collection" && event.change.moved.collection !== event.change.scope.collection) {
|
|
1924
|
+
return false;
|
|
1925
|
+
}
|
|
1926
|
+
return true;
|
|
1927
|
+
}
|
|
1928
|
+
function isCommerceNotificationWebhookEvent(event) {
|
|
1929
|
+
if (!isValidWebhookEvent(event) || event.operation !== COMMERCE_NOTIFICATION_OPERATION || event.eventType !== COMMERCE_NOTIFICATION_EVENT_TYPE || !isCommerceNotificationData(event.data) || !isCommerceNotification(event.notification)) {
|
|
1930
|
+
return false;
|
|
1931
|
+
}
|
|
1932
|
+
const notification = event.notification;
|
|
1933
|
+
const data = event.data;
|
|
1934
|
+
const change = event.change;
|
|
1935
|
+
const sourceCollection = data.source?.collection ?? event.collection;
|
|
1936
|
+
const sourceId = data.source?.id;
|
|
1937
|
+
if (!isCommerceNotificationSourceCollection(sourceCollection)) return false;
|
|
1938
|
+
if (data.source !== void 0 && event.collection !== data.source.collection) {
|
|
1939
|
+
return false;
|
|
1940
|
+
}
|
|
1941
|
+
if (change !== void 0) {
|
|
1942
|
+
if (!isWebhookCommerceNotificationChange(change)) return false;
|
|
1943
|
+
if (change.sourceCollection !== sourceCollection) return false;
|
|
1944
|
+
if (change.event !== notification.event) return false;
|
|
1945
|
+
if (!matchesOptionalId(change.sourceId, sourceId)) return false;
|
|
1946
|
+
}
|
|
1947
|
+
const changeSourceId = isWebhookCommerceNotificationChange(change) ? change.sourceId : void 0;
|
|
1948
|
+
if (notification.event === "orderPaid" || notification.event === "orderDelivered") {
|
|
1949
|
+
return sourceCollection === "orders" && typeof notification.orderId === "string" && notification.orderId.length > 0 && matchesOptionalId(data.orderId, sourceId) && matchesOptionalId(notification.orderId, sourceId) && matchesOptionalId(data.orderId, notification.orderId) && matchesOptionalId(changeSourceId, data.orderId ?? notification.orderId);
|
|
1950
|
+
}
|
|
1951
|
+
if (notification.event === "fulfillmentShipped") {
|
|
1952
|
+
return sourceCollection === "fulfillments" && matchesOptionalId(data.fulfillmentId, sourceId) && typeof notification.fulfillmentId === "string" && notification.fulfillmentId.length > 0 && matchesOptionalId(notification.fulfillmentId, sourceId) && matchesOptionalId(data.fulfillmentId, notification.fulfillmentId) && matchesOptionalId(changeSourceId, notification.fulfillmentId);
|
|
1953
|
+
}
|
|
1954
|
+
if (notification.event === "returnRequested" || notification.event === "returnCompleted") {
|
|
1955
|
+
return sourceCollection === "returns" && matchesOptionalId(data.returnId, sourceId) && typeof notification.returnId === "string" && notification.returnId.length > 0 && matchesOptionalId(notification.returnId, sourceId) && matchesOptionalId(data.returnId, notification.returnId) && matchesOptionalId(changeSourceId, notification.returnId);
|
|
1956
|
+
}
|
|
1957
|
+
return false;
|
|
1958
|
+
}
|
|
1959
|
+
function getCommerceNotificationIdempotencyKey(event) {
|
|
1960
|
+
return `${event.notification.intentId}:${event.notification.dedupeKey}`;
|
|
1961
|
+
}
|
|
1962
|
+
function defineCommerceEmailConfig(config) {
|
|
1963
|
+
return config;
|
|
1964
|
+
}
|
|
1965
|
+
function createCommerceEmailWebhookHandler(handlers) {
|
|
1966
|
+
return async (event) => {
|
|
1967
|
+
if (!isCommerceNotificationWebhookEvent(event)) {
|
|
1968
|
+
await handlers.unhandled?.(event);
|
|
1969
|
+
return;
|
|
1970
|
+
}
|
|
1971
|
+
const handler = handlers[event.notification.event];
|
|
1972
|
+
if (!handler) {
|
|
1973
|
+
await handlers.unhandled?.(event);
|
|
1974
|
+
return;
|
|
1975
|
+
}
|
|
1976
|
+
await handler({
|
|
1977
|
+
event,
|
|
1978
|
+
idempotencyKey: getCommerceNotificationIdempotencyKey(event)
|
|
1979
|
+
});
|
|
1980
|
+
};
|
|
1981
|
+
}
|
|
1982
|
+
function isWebhookCollection(event, collection) {
|
|
1983
|
+
return isValidWebhookEvent(event) && event.collection === collection;
|
|
1984
|
+
}
|
|
1985
|
+
function isWebhookOperation(event, operation) {
|
|
1986
|
+
return isValidWebhookEvent(event) && event.operation === operation;
|
|
1987
|
+
}
|
|
1847
1988
|
var CUSTOMER_PASSWORD_RESET_OPERATION = "password-reset";
|
|
1848
|
-
function
|
|
1989
|
+
function isRecord2(value) {
|
|
1849
1990
|
return typeof value === "object" && value !== null;
|
|
1850
1991
|
}
|
|
1851
1992
|
function hasString(value, key) {
|
|
@@ -1855,7 +1996,7 @@ function hasStringOrNumber(value, key) {
|
|
|
1855
1996
|
return typeof value[key] === "string" || typeof value[key] === "number";
|
|
1856
1997
|
}
|
|
1857
1998
|
function isCustomerPasswordResetWebhookEvent(event) {
|
|
1858
|
-
if (event.collection !== "customers" || event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION || !
|
|
1999
|
+
if (event.collection !== "customers" || event.operation !== CUSTOMER_PASSWORD_RESET_OPERATION || !isRecord2(event.data)) {
|
|
1859
2000
|
return false;
|
|
1860
2001
|
}
|
|
1861
2002
|
return hasStringOrNumber(event.data, "customerId") && hasString(event.data, "email") && hasString(event.data, "name") && hasString(event.data, "resetPasswordToken") && hasString(event.data, "resetPasswordExpiresAt");
|
|
@@ -1975,6 +2116,7 @@ var INTERNAL_COLLECTIONS = [
|
|
|
1975
2116
|
"subscriptions",
|
|
1976
2117
|
"billing-history",
|
|
1977
2118
|
"inventory-reservations",
|
|
2119
|
+
"commerce-notification-intents",
|
|
1978
2120
|
"product-collection-items",
|
|
1979
2121
|
"order-status-logs",
|
|
1980
2122
|
"api-keys",
|
|
@@ -3207,7 +3349,14 @@ function buildProductListingProjection(product, variants) {
|
|
|
3207
3349
|
function buildProductListingCard(item, options = {}) {
|
|
3208
3350
|
const product = item.product;
|
|
3209
3351
|
const groups = item.groups;
|
|
3210
|
-
const
|
|
3352
|
+
const variants = getProductListingCardVariants(item);
|
|
3353
|
+
const projectedListing = buildProductListingProjection(product, variants);
|
|
3354
|
+
const selectionHintVariant = getRelationID(product.listing?.selectionHintVariant) ?? projectedListing.selectionHintVariant;
|
|
3355
|
+
const representativeVariant = findListingCardRepresentativeVariant(
|
|
3356
|
+
variants,
|
|
3357
|
+
selectionHintVariant
|
|
3358
|
+
);
|
|
3359
|
+
const primaryImage = firstMedia(product.thumbnail) ?? firstMedia(product.images ?? null) ?? firstMedia(representativeVariant?.thumbnail) ?? firstMedia(representativeVariant?.images) ?? firstMedia(product.listing?.primaryImage) ?? firstMedia(projectedListing.primaryImage) ?? null;
|
|
3211
3360
|
const priceRange = aggregateListingPriceRange(groups);
|
|
3212
3361
|
const availableForSale = groups.some(
|
|
3213
3362
|
(group) => group.listing.availableForSale
|
|
@@ -3215,14 +3364,42 @@ function buildProductListingCard(item, options = {}) {
|
|
|
3215
3364
|
const swatches = groups.length > 1 ? groups.map((group) => buildListingSwatch(product, group, options)) : [];
|
|
3216
3365
|
return {
|
|
3217
3366
|
id: String(product.id),
|
|
3218
|
-
href: buildProductHref(
|
|
3367
|
+
href: buildProductHref(
|
|
3368
|
+
{ slug: product.slug },
|
|
3369
|
+
{ listing: { selectionHintVariant } },
|
|
3370
|
+
options
|
|
3371
|
+
),
|
|
3219
3372
|
title: product.title,
|
|
3373
|
+
representativeVariant,
|
|
3220
3374
|
primaryImage,
|
|
3221
3375
|
priceRange,
|
|
3222
3376
|
availableForSale,
|
|
3223
3377
|
swatches
|
|
3224
3378
|
};
|
|
3225
3379
|
}
|
|
3380
|
+
function getProductListingCardVariants(item) {
|
|
3381
|
+
const productVariants = item.product.variants?.docs;
|
|
3382
|
+
if (Array.isArray(productVariants) && productVariants.length > 0) {
|
|
3383
|
+
return productVariants;
|
|
3384
|
+
}
|
|
3385
|
+
const variants = [];
|
|
3386
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3387
|
+
for (const group of item.groups) {
|
|
3388
|
+
for (const variant of group.variants) {
|
|
3389
|
+
const id = getRelationID(variant.id);
|
|
3390
|
+
if (id && seen.has(id)) continue;
|
|
3391
|
+
if (id) seen.add(id);
|
|
3392
|
+
variants.push(variant);
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
return variants;
|
|
3396
|
+
}
|
|
3397
|
+
function findListingCardRepresentativeVariant(variants, representativeVariantId) {
|
|
3398
|
+
if (representativeVariantId == null) return null;
|
|
3399
|
+
return variants.find(
|
|
3400
|
+
(variant) => getRelationID(variant.id) === representativeVariantId
|
|
3401
|
+
) ?? null;
|
|
3402
|
+
}
|
|
3226
3403
|
function aggregateListingPriceRange(groups) {
|
|
3227
3404
|
const minPrice = minOfNullable(groups.map((g) => g.listing.minPrice));
|
|
3228
3405
|
const maxPrice = maxOfNullable(groups.map((g) => g.listing.maxPrice));
|