@01.software/sdk 0.32.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 +43 -20
- package/dist/client.cjs +31 -2
- 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 +31 -2
- package/dist/client.js.map +1 -1
- package/dist/{collection-client-DPGXnhoF.d.ts → collection-client-B6SlhzIP.d.ts} +3 -3
- package/dist/{collection-client-CORhppPb.d.cts → collection-client-De6eKW1J.d.cts} +3 -3
- package/dist/{const-Brk2Ff0q.d.cts → const-DwmSDeWq.d.ts} +2 -2
- package/dist/{const-DcY2_z9O.d.ts → const-sPR2IkCe.d.cts} +2 -2
- package/dist/index.cjs +256 -90
- 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 +256 -90
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-DVK1QCeU.d.cts → payload-types-dkeQyrDC.d.cts} +1562 -1436
- package/dist/{payload-types-DVK1QCeU.d.ts → payload-types-dkeQyrDC.d.ts} +1562 -1436
- package/dist/query.cjs.map +1 -1
- package/dist/query.d.cts +9 -9
- package/dist/query.d.ts +9 -9
- package/dist/query.js.map +1 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/server.cjs +37 -6
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +7 -7
- package/dist/server.d.ts +7 -7
- package/dist/server.js +37 -6
- package/dist/server.js.map +1 -1
- package/dist/{types-ByMrR_Z_.d.cts → types-B3YT092I.d.cts} +1 -1
- package/dist/{types-CYMSBkJC.d.ts → types-BHh0YLmq.d.ts} +27 -10
- package/dist/{types-CAkWqIr6.d.cts → types-BZKxss8Y.d.cts} +27 -10
- package/dist/{types-DUPC7Xn6.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 +94 -0
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +82 -7
- package/dist/webhook.d.ts +82 -7
- package/dist/webhook.js +94 -0
- package/dist/webhook.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -168,8 +168,9 @@ const preview = await server.preview.detail(
|
|
|
168
168
|
```
|
|
169
169
|
|
|
170
170
|
For product pages, `server.commerce.product.previewDetail({ id }, {
|
|
171
|
-
previewToken })` returns the
|
|
172
|
-
|
|
171
|
+
previewToken })` returns the raw product detail payload for the saved
|
|
172
|
+
draft/unpublished record addressed by the preview token. `detail()` wraps the
|
|
173
|
+
published storefront payload in a `{ found, product | reason }` result.
|
|
173
174
|
|
|
174
175
|
## Getting product detail
|
|
175
176
|
|
|
@@ -179,19 +180,33 @@ The recommended way to fetch a single product is the shaped helper:
|
|
|
179
180
|
import { createClient } from '@01.software/sdk'
|
|
180
181
|
|
|
181
182
|
const client = createClient({
|
|
182
|
-
publishableKey:
|
|
183
|
+
publishableKey: '<publishable-key>',
|
|
183
184
|
})
|
|
184
185
|
|
|
185
|
-
const
|
|
186
|
+
const result = await client.commerce.product.detail({
|
|
186
187
|
slug: 'every-peach-tee',
|
|
187
188
|
})
|
|
188
|
-
if (!
|
|
189
|
-
return notFound()
|
|
189
|
+
if (!result.found) {
|
|
190
|
+
return notFound()
|
|
190
191
|
}
|
|
192
|
+
|
|
193
|
+
const { product } = result
|
|
191
194
|
// product: { product, variants, options, brand, categories, tags, images, videos, listing }
|
|
192
195
|
```
|
|
193
196
|
|
|
194
|
-
`detail()` returns `
|
|
197
|
+
`detail()` returns `ProductDetailResult`, a discriminated union:
|
|
198
|
+
`{ found: true, product: ProductDetail } | { found: false, reason }`. The
|
|
199
|
+
`reason` value is one of `not_found`, `not_published`, or
|
|
200
|
+
`feature_disabled`, so storefronts can choose between a standard 404, preview
|
|
201
|
+
CTA, or feature gating UI. Permission/auth errors, including 403 tenant
|
|
202
|
+
mismatches, still throw
|
|
203
|
+
typed `SDKError` subclasses and preserve request IDs through the existing
|
|
204
|
+
`lastRequestId` / `onRequestId` path.
|
|
205
|
+
|
|
206
|
+
The successful product payload exposes inventory rollups without sentinel
|
|
207
|
+
values: `product.totalInventory` is the tracked stock sum across non-unlimited
|
|
208
|
+
variants, `null` when no variants are tracked, and
|
|
209
|
+
`product.hasUnlimitedVariant` signals whether any variant is unlimited.
|
|
195
210
|
|
|
196
211
|
### Product selection helpers
|
|
197
212
|
|
|
@@ -291,12 +306,12 @@ coexist without being interpreted as selection state.
|
|
|
291
306
|
inspect grouped variant fields without a follow-up fetch. The by-ids response
|
|
292
307
|
also returns `missing: string[]` for requested product IDs that were not found,
|
|
293
308
|
not published, or not accessible; `docs` preserve the input `productIds` order
|
|
294
|
-
for returned products. The
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
emit `swatches: []`;
|
|
299
|
-
directly.
|
|
309
|
+
for returned products. The helper populates optional `representativeVariant`, a
|
|
310
|
+
PDP-seeded `href`, representative media (`product.thumbnail` -> first
|
|
311
|
+
`product.images` -> representative variant media -> `null`), an aggregated price
|
|
312
|
+
range across all option-value groups, and a `swatches[]` array derived from
|
|
313
|
+
groups when there is more than one. Single-group products emit `swatches: []`;
|
|
314
|
+
storefronts that disagree can read `item.groups` directly.
|
|
300
315
|
|
|
301
316
|
```ts
|
|
302
317
|
import {
|
|
@@ -309,9 +324,10 @@ const cards: ProductListingCard[] = response.docs.map((item) =>
|
|
|
309
324
|
)
|
|
310
325
|
```
|
|
311
326
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
327
|
+
The card href seeds the same representative variant that the PDP resolves by
|
|
328
|
+
default through `resolveProductSelection(detail)`. Each swatch carries a
|
|
329
|
+
hint-only option-value href (`?opt.<optionId>=<valueId>`); the detail page
|
|
330
|
+
resolves it through `resolveProductSelection(detail, { search })`.
|
|
315
331
|
|
|
316
332
|
## Advanced: direct Payload queries (escape hatch)
|
|
317
333
|
|
|
@@ -401,10 +417,11 @@ export const revalidate = 60 // ISR — adjust per page freshness need
|
|
|
401
417
|
|
|
402
418
|
export default async function ProductPage({ params }) {
|
|
403
419
|
const client = createClient({
|
|
404
|
-
publishableKey:
|
|
420
|
+
publishableKey: '<publishable-key>',
|
|
405
421
|
})
|
|
406
|
-
const
|
|
407
|
-
if (!
|
|
422
|
+
const result = await client.commerce.product.detail({ slug: params.slug })
|
|
423
|
+
if (!result.found) return notFound()
|
|
424
|
+
const { product } = result
|
|
408
425
|
// ...
|
|
409
426
|
}
|
|
410
427
|
```
|
|
@@ -739,7 +756,13 @@ await server.commerce.orders.updateTransaction({ pgPaymentId, status, paymentMet
|
|
|
739
756
|
// Returns
|
|
740
757
|
await server.commerce.orders.createReturn({ orderNumber, returnItems, refundAmount, reason? })
|
|
741
758
|
await server.commerce.orders.updateReturn({ returnId, status })
|
|
742
|
-
await server.commerce.orders.returnWithRefund({
|
|
759
|
+
await server.commerce.orders.returnWithRefund({
|
|
760
|
+
orderNumber,
|
|
761
|
+
returnItems: [{ orderItem, quantity, restockingFee? }],
|
|
762
|
+
refundAmount,
|
|
763
|
+
returnShippingFee?,
|
|
764
|
+
pgPaymentId,
|
|
765
|
+
})
|
|
743
766
|
```
|
|
744
767
|
|
|
745
768
|
### Commerce Discounts / Shipping
|
package/dist/client.cjs
CHANGED
|
@@ -1375,6 +1375,30 @@ var CartApi = class {
|
|
|
1375
1375
|
}
|
|
1376
1376
|
};
|
|
1377
1377
|
|
|
1378
|
+
// src/core/api/product-api.ts
|
|
1379
|
+
var PRODUCT_DETAIL_UNAVAILABLE_REASONS = /* @__PURE__ */ new Set([
|
|
1380
|
+
"not_found",
|
|
1381
|
+
"not_published",
|
|
1382
|
+
"feature_disabled"
|
|
1383
|
+
]);
|
|
1384
|
+
function isRecord(value) {
|
|
1385
|
+
return typeof value === "object" && value !== null;
|
|
1386
|
+
}
|
|
1387
|
+
function readProductDetailUnavailableReason(value) {
|
|
1388
|
+
if (!isRecord(value)) return void 0;
|
|
1389
|
+
const directReason = value.reason ?? value.code;
|
|
1390
|
+
if (typeof directReason === "string" && PRODUCT_DETAIL_UNAVAILABLE_REASONS.has(directReason)) {
|
|
1391
|
+
return directReason;
|
|
1392
|
+
}
|
|
1393
|
+
return readProductDetailUnavailableReason(value.body);
|
|
1394
|
+
}
|
|
1395
|
+
function productDetailResultFromError(error) {
|
|
1396
|
+
if (!(error instanceof SDKError) || error.status !== 404) return void 0;
|
|
1397
|
+
const reason = readProductDetailUnavailableReason(error.details);
|
|
1398
|
+
if (!reason) return void 0;
|
|
1399
|
+
return { found: false, reason };
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1378
1402
|
// src/core/commerce/commerce-client.ts
|
|
1379
1403
|
var CommerceClient = class {
|
|
1380
1404
|
constructor(options) {
|
|
@@ -1409,9 +1433,14 @@ var CommerceClient = class {
|
|
|
1409
1433
|
listingGroups: (params) => execute("/api/products/listing-groups", params),
|
|
1410
1434
|
detail: async (params) => {
|
|
1411
1435
|
try {
|
|
1412
|
-
|
|
1436
|
+
const product = await execute(
|
|
1437
|
+
"/api/products/detail",
|
|
1438
|
+
params
|
|
1439
|
+
);
|
|
1440
|
+
return { found: true, product };
|
|
1413
1441
|
} catch (err) {
|
|
1414
|
-
|
|
1442
|
+
const notFoundResult = productDetailResultFromError(err);
|
|
1443
|
+
if (notFoundResult) return notFoundResult;
|
|
1415
1444
|
throw err;
|
|
1416
1445
|
}
|
|
1417
1446
|
}
|