@01.software/cli 0.10.6 → 0.11.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/dist/mcp/.01-cli-mcp-build.json +1 -1
- package/dist/mcp/{chunk-2ULP5WQH.js → chunk-3TIDAOYP.js} +147 -43
- package/dist/mcp/chunk-3TIDAOYP.js.map +1 -0
- package/dist/mcp/http.js +1 -1
- package/dist/mcp/stdio.js +1 -1
- package/dist/mcp/vercel.js +146 -42
- package/package.json +2 -2
- package/dist/mcp/chunk-2ULP5WQH.js.map +0 -1
package/dist/mcp/http.js
CHANGED
package/dist/mcp/stdio.js
CHANGED
package/dist/mcp/vercel.js
CHANGED
|
@@ -760,14 +760,14 @@ var TOOL_POLICY_MANIFEST = {
|
|
|
760
760
|
category: "mutation-order",
|
|
761
761
|
oauthScope: MCP_SCOPES.write,
|
|
762
762
|
consoleRole: "tenant-admin",
|
|
763
|
-
consoleSurface: "POST /api/checkout",
|
|
763
|
+
consoleSurface: "POST /api/orders/checkout",
|
|
764
764
|
annotationPolicy: DESTRUCTIVE_NON_IDEMPOTENT_MUTATION_ANNOTATION
|
|
765
765
|
},
|
|
766
766
|
"create-order": {
|
|
767
767
|
category: "mutation-order",
|
|
768
768
|
oauthScope: MCP_SCOPES.write,
|
|
769
769
|
consoleRole: "tenant-admin",
|
|
770
|
-
consoleSurface: "POST /api/orders",
|
|
770
|
+
consoleSurface: "POST /api/orders/create",
|
|
771
771
|
annotationPolicy: DESTRUCTIVE_NON_IDEMPOTENT_MUTATION_ANNOTATION
|
|
772
772
|
},
|
|
773
773
|
"confirm-payment": {
|
|
@@ -782,7 +782,7 @@ var TOOL_POLICY_MANIFEST = {
|
|
|
782
782
|
category: "mutation-order",
|
|
783
783
|
oauthScope: MCP_SCOPES.write,
|
|
784
784
|
consoleRole: "tenant-admin",
|
|
785
|
-
consoleSurface: "
|
|
785
|
+
consoleSurface: "POST /api/orders/update",
|
|
786
786
|
annotationPolicy: DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION,
|
|
787
787
|
exemptionReason: REASON_IDEMPOTENT_DESTRUCTIVE_UPDATE
|
|
788
788
|
},
|
|
@@ -791,14 +791,14 @@ var TOOL_POLICY_MANIFEST = {
|
|
|
791
791
|
category: "mutation-fulfillment",
|
|
792
792
|
oauthScope: MCP_SCOPES.write,
|
|
793
793
|
consoleRole: "tenant-admin",
|
|
794
|
-
consoleSurface: "POST /api/orders/
|
|
794
|
+
consoleSurface: "POST /api/orders/create-fulfillment",
|
|
795
795
|
annotationPolicy: NON_DESTRUCTIVE_MUTATION_ANNOTATION
|
|
796
796
|
},
|
|
797
797
|
"update-fulfillment": {
|
|
798
798
|
category: "mutation-fulfillment",
|
|
799
799
|
oauthScope: MCP_SCOPES.write,
|
|
800
800
|
consoleRole: "tenant-admin",
|
|
801
|
-
consoleSurface: "
|
|
801
|
+
consoleSurface: "POST /api/orders/update-fulfillment",
|
|
802
802
|
annotationPolicy: DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION,
|
|
803
803
|
exemptionReason: REASON_IDEMPOTENT_DESTRUCTIVE_UPDATE
|
|
804
804
|
},
|
|
@@ -807,14 +807,14 @@ var TOOL_POLICY_MANIFEST = {
|
|
|
807
807
|
category: "mutation-return",
|
|
808
808
|
oauthScope: MCP_SCOPES.write,
|
|
809
809
|
consoleRole: "tenant-admin",
|
|
810
|
-
consoleSurface: "POST /api/returns",
|
|
810
|
+
consoleSurface: "POST /api/returns/create",
|
|
811
811
|
annotationPolicy: DESTRUCTIVE_NON_IDEMPOTENT_MUTATION_ANNOTATION
|
|
812
812
|
},
|
|
813
813
|
"update-return": {
|
|
814
814
|
category: "mutation-return",
|
|
815
815
|
oauthScope: MCP_SCOPES.write,
|
|
816
816
|
consoleRole: "tenant-admin",
|
|
817
|
-
consoleSurface: "
|
|
817
|
+
consoleSurface: "POST /api/returns/update",
|
|
818
818
|
annotationPolicy: DESTRUCTIVE_IDEMPOTENT_MUTATION_ANNOTATION,
|
|
819
819
|
exemptionReason: REASON_IDEMPOTENT_DESTRUCTIVE_UPDATE
|
|
820
820
|
},
|
|
@@ -822,7 +822,7 @@ var TOOL_POLICY_MANIFEST = {
|
|
|
822
822
|
category: "mutation-return",
|
|
823
823
|
oauthScope: MCP_SCOPES.write,
|
|
824
824
|
consoleRole: "tenant-admin",
|
|
825
|
-
consoleSurface: "POST /api/returns/
|
|
825
|
+
consoleSurface: "POST /api/returns/return-refund",
|
|
826
826
|
annotationPolicy: DESTRUCTIVE_NON_IDEMPOTENT_MUTATION_ANNOTATION
|
|
827
827
|
},
|
|
828
828
|
// ── Transaction mutations (mcp:write, tenant-admin) ──
|
|
@@ -830,7 +830,7 @@ var TOOL_POLICY_MANIFEST = {
|
|
|
830
830
|
category: "mutation-transaction",
|
|
831
831
|
oauthScope: MCP_SCOPES.write,
|
|
832
832
|
consoleRole: "tenant-admin",
|
|
833
|
-
consoleSurface: "
|
|
833
|
+
consoleSurface: "POST /api/transactions/update",
|
|
834
834
|
annotationPolicy: DESTRUCTIVE_NON_IDEMPOTENT_MUTATION_ANNOTATION
|
|
835
835
|
},
|
|
836
836
|
// ── Field-config mutations (mcp:write, tenant-admin) ──
|
|
@@ -1430,12 +1430,12 @@ var schema5 = {
|
|
|
1430
1430
|
"delivered",
|
|
1431
1431
|
"confirmed"
|
|
1432
1432
|
]).describe(
|
|
1433
|
-
"New order status.
|
|
1433
|
+
"New operator-driven order status. The schema keeps SDK status values for compatibility, but the Console update endpoint rejects server-derived statuses (paid, canceled, returned, refunded); those must be set by payment/refund flows, and return-related statuses must be set via Return endpoints."
|
|
1434
1434
|
)
|
|
1435
1435
|
};
|
|
1436
1436
|
var metadata5 = {
|
|
1437
1437
|
name: "update-order",
|
|
1438
|
-
description: "Update order status.
|
|
1438
|
+
description: "Update operator-driven order status. Console accepts transitions such as paid\u2192preparing/shipped/delivered/confirmed and rejects server-derived payment/refund statuses such as paid, canceled, returned, and refunded; the MCP schema keeps SDK status values for compatibility.",
|
|
1439
1439
|
annotations: {
|
|
1440
1440
|
title: "Update order status",
|
|
1441
1441
|
readOnlyHint: false,
|
|
@@ -1689,12 +1689,12 @@ import { z as z11 } from "zod";
|
|
|
1689
1689
|
var schema12 = {
|
|
1690
1690
|
returnId: z11.string().min(1).describe("Return ID (required)"),
|
|
1691
1691
|
status: z11.enum(["processing", "approved", "rejected", "completed"]).describe(
|
|
1692
|
-
"New return status (required).
|
|
1692
|
+
"New operator-driven return status (required). The schema keeps SDK status values for compatibility, but Console accepts only requested\u2192processing/rejected and processing\u2192approved/rejected here; completed is server-derived and must be set by return-with-refund."
|
|
1693
1693
|
)
|
|
1694
1694
|
};
|
|
1695
1695
|
var metadata12 = {
|
|
1696
1696
|
name: "update-return",
|
|
1697
|
-
description: "Update return status with FSM validation.
|
|
1697
|
+
description: "Update operator-driven return status with FSM validation. Rejection can restore the order flow; completion and inventory restoration are handled by return-with-refund after provider-verified refund, while the MCP schema keeps SDK status values for compatibility.",
|
|
1698
1698
|
annotations: {
|
|
1699
1699
|
title: "Update return status",
|
|
1700
1700
|
readOnlyHint: false,
|
|
@@ -1708,7 +1708,10 @@ async function updateReturn({
|
|
|
1708
1708
|
}) {
|
|
1709
1709
|
try {
|
|
1710
1710
|
const client = getClient();
|
|
1711
|
-
const result = await client.commerce.orders.updateReturn({
|
|
1711
|
+
const result = await client.commerce.orders.updateReturn({
|
|
1712
|
+
returnId,
|
|
1713
|
+
status
|
|
1714
|
+
});
|
|
1712
1715
|
return toolSuccess({ data: result });
|
|
1713
1716
|
} catch (error) {
|
|
1714
1717
|
return toolError(error);
|
|
@@ -1719,7 +1722,7 @@ async function updateReturn({
|
|
|
1719
1722
|
var schema13 = ReturnWithRefundSchema.shape;
|
|
1720
1723
|
var metadata13 = {
|
|
1721
1724
|
name: "return-with-refund",
|
|
1722
|
-
description: "Combined return + refund operation. Creates return, restores stock,
|
|
1725
|
+
description: "Combined provider-verified return + refund operation. Creates a completed return, restores eligible stock, records the refund transaction, and advances the order to the returned state.",
|
|
1723
1726
|
annotations: {
|
|
1724
1727
|
title: "Return with refund",
|
|
1725
1728
|
readOnlyHint: false,
|
|
@@ -1733,6 +1736,7 @@ async function returnWithRefund({
|
|
|
1733
1736
|
reasonDetail,
|
|
1734
1737
|
returnItems,
|
|
1735
1738
|
refundAmount,
|
|
1739
|
+
returnShippingFee,
|
|
1736
1740
|
pgPaymentId,
|
|
1737
1741
|
paymentKey,
|
|
1738
1742
|
refundReceiptUrl
|
|
@@ -1745,6 +1749,7 @@ async function returnWithRefund({
|
|
|
1745
1749
|
reasonDetail,
|
|
1746
1750
|
returnItems,
|
|
1747
1751
|
refundAmount,
|
|
1752
|
+
returnShippingFee,
|
|
1748
1753
|
pgPaymentId,
|
|
1749
1754
|
paymentKey,
|
|
1750
1755
|
refundReceiptUrl
|
|
@@ -2045,7 +2050,7 @@ var schema23 = {
|
|
|
2045
2050
|
};
|
|
2046
2051
|
var metadata23 = {
|
|
2047
2052
|
name: "product-detail",
|
|
2048
|
-
description: "Fetch full product detail by slug or id. Returns one resolver-ready product with variants, option slugs, option value slugs/media, brand, categories, tags, images, videos, and listing rollup, or
|
|
2053
|
+
description: "Fetch full product detail by slug or id. Returns one resolver-ready product with variants, option slugs, option value slugs/media, brand, categories, tags, images, videos, and listing rollup, or found:false with a reason if missing/unpublished/feature disabled. Permission/auth errors still throw.",
|
|
2049
2054
|
annotations: {
|
|
2050
2055
|
title: "Get product detail",
|
|
2051
2056
|
readOnlyHint: true,
|
|
@@ -3675,8 +3680,9 @@ You can perform the "${goal}" task by following the patterns above.
|
|
|
3675
3680
|
### Product detail page (slug-based)
|
|
3676
3681
|
|
|
3677
3682
|
\`\`\`typescript
|
|
3678
|
-
const
|
|
3679
|
-
if (!
|
|
3683
|
+
const result = await client.commerce.product.detail({ slug })
|
|
3684
|
+
if (!result.found) return notFound()
|
|
3685
|
+
const product = result.product
|
|
3680
3686
|
// product: { product, variants, options, brand, categories, tags, images, videos, listing }
|
|
3681
3687
|
\`\`\`
|
|
3682
3688
|
|
|
@@ -3912,12 +3918,13 @@ const order = await client.commerce.orders.checkout({
|
|
|
3912
3918
|
1. **Create Return** \u2192 \`create-return\` tool
|
|
3913
3919
|
- Order must be \`delivered\` or \`confirmed\`
|
|
3914
3920
|
- Specify returnItems and refundAmount
|
|
3915
|
-
-
|
|
3921
|
+
- Operator transitions: requested \u2192 processing/rejected, processing \u2192 approved/rejected
|
|
3922
|
+
- \`completed\` is server-derived and requires \`return-with-refund\`
|
|
3916
3923
|
|
|
3917
3924
|
### Option B: Return + Refund (atomic, recommended)
|
|
3918
3925
|
1. **Return with Refund** \u2192 \`return-with-refund\` tool
|
|
3919
3926
|
- Handles return + stock restoration + transaction update in one call
|
|
3920
|
-
-
|
|
3927
|
+
- Sets the return to \`completed\` after provider-verified refund
|
|
3921
3928
|
- Requires pgPaymentId and paymentKey for provider-verified refund
|
|
3922
3929
|
|
|
3923
3930
|
### Key Points
|
|
@@ -3933,8 +3940,9 @@ await client.commerce.orders.returnWithRefund({
|
|
|
3933
3940
|
orderNumber: 'ORD-240101-001',
|
|
3934
3941
|
reason: 'defective',
|
|
3935
3942
|
reasonDetail: 'Product arrived damaged',
|
|
3936
|
-
returnItems: [{ orderItem: 'oi-id', quantity: 1 }],
|
|
3943
|
+
returnItems: [{ orderItem: 'oi-id', quantity: 1, restockingFee: 500 }],
|
|
3937
3944
|
refundAmount: 29900,
|
|
3945
|
+
returnShippingFee: 1500,
|
|
3938
3946
|
pgPaymentId: 'pay_xxx',
|
|
3939
3947
|
paymentKey: 'payment_key_xxx'
|
|
3940
3948
|
})
|
|
@@ -5541,12 +5549,12 @@ const ret = await client.commerce.orders.createReturn({
|
|
|
5541
5549
|
\`\`\`
|
|
5542
5550
|
|
|
5543
5551
|
### updateReturn()
|
|
5544
|
-
Update return status.
|
|
5552
|
+
Update operator-driven return status. \`completed\` is server-derived and must go through \`returnWithRefund()\`.
|
|
5545
5553
|
|
|
5546
5554
|
\`\`\`typescript
|
|
5547
5555
|
const ret = await client.commerce.orders.updateReturn({
|
|
5548
5556
|
returnId: 'return-id',
|
|
5549
|
-
status: 'processing', // processing | approved |
|
|
5557
|
+
status: 'processing', // processing | approved | rejected
|
|
5550
5558
|
})
|
|
5551
5559
|
\`\`\`
|
|
5552
5560
|
|
|
@@ -5559,9 +5567,10 @@ const result = await client.commerce.orders.returnWithRefund({
|
|
|
5559
5567
|
reason?: 'defective',
|
|
5560
5568
|
reasonDetail?: 'Screen cracked on arrival',
|
|
5561
5569
|
returnItems: [
|
|
5562
|
-
{ orderItem: 'order-item-id', quantity: 1 }
|
|
5570
|
+
{ orderItem: 'order-item-id', quantity: 1, restockingFee?: 500 }
|
|
5563
5571
|
],
|
|
5564
5572
|
refundAmount: 29900,
|
|
5573
|
+
returnShippingFee?: 1500,
|
|
5565
5574
|
pgPaymentId: 'provider-payment-id', // required
|
|
5566
5575
|
paymentKey: 'provider-payment-key', // required for provider refund
|
|
5567
5576
|
refundReceiptUrl?: 'https://...',
|
|
@@ -6196,11 +6205,11 @@ var metadata49 = {
|
|
|
6196
6205
|
function handler18() {
|
|
6197
6206
|
return `# Webhooks
|
|
6198
6207
|
|
|
6199
|
-
The platform dispatches HMAC-SHA256 signed webhook events to
|
|
6208
|
+
The platform dispatches HMAC-SHA256 signed webhook events to registered URLs. Tenant developers own routing inside their webhook handler.
|
|
6200
6209
|
|
|
6201
6210
|
## Webhook Handling
|
|
6202
6211
|
|
|
6203
|
-
Use the SDK \`handleWebhook\` helper to verify signatures. For customer auth events, use \`createCustomerAuthWebhookHandler
|
|
6212
|
+
Use the SDK \`handleWebhook\` helper to verify signatures. For customer auth events, use \`createCustomerAuthWebhookHandler\`; for semantic events, use SDK guards before reading event-specific fields.
|
|
6204
6213
|
|
|
6205
6214
|
\`\`\`typescript
|
|
6206
6215
|
import { handleWebhook, createCustomerAuthWebhookHandler } from '@01.software/sdk/webhook'
|
|
@@ -6253,28 +6262,119 @@ export async function POST(request: Request) {
|
|
|
6253
6262
|
}
|
|
6254
6263
|
\`\`\`
|
|
6255
6264
|
|
|
6265
|
+
## Commerce Notification Handler Example
|
|
6266
|
+
|
|
6267
|
+
\`\`\`typescript
|
|
6268
|
+
import {
|
|
6269
|
+
handleWebhook,
|
|
6270
|
+
isCommerceNotificationWebhookEvent,
|
|
6271
|
+
} from '@01.software/sdk/webhook'
|
|
6272
|
+
|
|
6273
|
+
function getWebhookSecret(): string {
|
|
6274
|
+
const secret = process.env.WEBHOOK_SECRET
|
|
6275
|
+
if (!secret) throw new Error('WEBHOOK_SECRET is required')
|
|
6276
|
+
return secret
|
|
6277
|
+
}
|
|
6278
|
+
|
|
6279
|
+
export async function POST(request: Request) {
|
|
6280
|
+
return handleWebhook(request, async (event) => {
|
|
6281
|
+
if (!isCommerceNotificationWebhookEvent(event)) return
|
|
6282
|
+
|
|
6283
|
+
const idempotencyKey = \`\${event.notification.intentId}:\${event.notification.dedupeKey}\`
|
|
6284
|
+
const processed = await processOnce(idempotencyKey, async () => {
|
|
6285
|
+
if (event.notification.event === 'orderPaid') {
|
|
6286
|
+
const orderId = event.notification.orderId ?? event.data.orderId
|
|
6287
|
+
if (orderId) await updateOrderWorkflow(orderId)
|
|
6288
|
+
}
|
|
6289
|
+
|
|
6290
|
+
if (event.notification.event === 'fulfillmentShipped') {
|
|
6291
|
+
const fulfillmentId =
|
|
6292
|
+
event.notification.fulfillmentId ?? event.data.fulfillmentId
|
|
6293
|
+
if (fulfillmentId) await updateFulfillmentWorkflow(fulfillmentId)
|
|
6294
|
+
}
|
|
6295
|
+
})
|
|
6296
|
+
|
|
6297
|
+
if (!processed) return
|
|
6298
|
+
}, {
|
|
6299
|
+
secret: getWebhookSecret(),
|
|
6300
|
+
})
|
|
6301
|
+
}
|
|
6302
|
+
\`\`\`
|
|
6303
|
+
|
|
6304
|
+
Back \`processOnce()\` with durable storage such as a database unique key or queue idempotency store; do not use process-local memory for webhook idempotency.
|
|
6305
|
+
|
|
6306
|
+
## Headless Commerce Email Workers
|
|
6307
|
+
|
|
6308
|
+
For tenant-owned transactional email, use \`commerce.notification\` as the trigger and build a signed worker with \`createCommerceEmailWebhookHandler()\`. 01.software owns event timing, delivery retries, signing, and idempotency signals; the tenant worker owns template rendering, provider credentials, extra order/customer fetches via \`createServerClient\`, and final delivery through a tenant provider such as Resend.
|
|
6309
|
+
|
|
6310
|
+
Use \`getCommerceNotificationIdempotencyKey(event)\` or the \`idempotencyKey\` passed by \`createCommerceEmailWebhookHandler()\`, then guard provider sends with durable \`processOnce(idempotencyKey, ...)\` storage. The webhook payload is PII-light and is not enough for recipient data, so fetch recipient/template context with server SDK credentials. In the v1 headless path, do not store tenant ESP secrets in 01.software and do not ask 01.software to send directly through the tenant provider.
|
|
6311
|
+
|
|
6256
6312
|
## Webhook Payload Structure
|
|
6257
6313
|
|
|
6258
6314
|
All webhook events share this envelope:
|
|
6259
6315
|
|
|
6260
6316
|
\`\`\`typescript
|
|
6261
6317
|
{
|
|
6262
|
-
collection: string,
|
|
6263
|
-
operation: string,
|
|
6264
|
-
data: object,
|
|
6318
|
+
collection: string,
|
|
6319
|
+
operation: string,
|
|
6320
|
+
data: object,
|
|
6321
|
+
eventType?: string,
|
|
6322
|
+
change?: object,
|
|
6323
|
+
notification?: object,
|
|
6324
|
+
timestamp?: string,
|
|
6325
|
+
deliveryId?: string,
|
|
6265
6326
|
}
|
|
6266
6327
|
\`\`\`
|
|
6267
6328
|
|
|
6268
6329
|
## Event Types
|
|
6269
6330
|
|
|
6331
|
+
### Commerce Notification
|
|
6332
|
+
|
|
6333
|
+
V1 commerce notification webhooks use \`eventType: "commerce.notification"\` and \`operation: "notification"\`. The public SDK exports \`COMMERCE_NOTIFICATION_EVENT_TYPE\`, \`COMMERCE_NOTIFICATION_OPERATION\`, commerce notification types, and \`isCommerceNotificationWebhookEvent()\` from \`@01.software/sdk/webhook\`.
|
|
6334
|
+
|
|
6335
|
+
Canonical example (public operational identifiers only; no PII, payment/provider fields, metadata, tracking number, or tracking URL):
|
|
6336
|
+
|
|
6337
|
+
\`\`\`json
|
|
6338
|
+
{
|
|
6339
|
+
"eventType": "commerce.notification",
|
|
6340
|
+
"collection": "orders",
|
|
6341
|
+
"operation": "notification",
|
|
6342
|
+
"data": {
|
|
6343
|
+
"orderId": "order_123",
|
|
6344
|
+
"orderNumber": "ORD-1001",
|
|
6345
|
+
"status": "paid",
|
|
6346
|
+
"totalAmount": 5000,
|
|
6347
|
+
"currency": "KRW"
|
|
6348
|
+
},
|
|
6349
|
+
"notification": {
|
|
6350
|
+
"event": "orderPaid",
|
|
6351
|
+
"intentId": "intent_123",
|
|
6352
|
+
"dedupeKey": "orderPaid:order_123",
|
|
6353
|
+
"orderId": "order_123"
|
|
6354
|
+
},
|
|
6355
|
+
"timestamp": "2026-05-29T00:00:00.000Z",
|
|
6356
|
+
"deliveryId": "delivery_attempt_123"
|
|
6357
|
+
}
|
|
6358
|
+
\`\`\`
|
|
6359
|
+
|
|
6360
|
+
Use \`notification.intentId\` plus \`notification.dedupeKey\` for semantic idempotency. \`deliveryId\` is per delivery attempt / observability and may not be stable across semantic retries.
|
|
6361
|
+
Some normalized deliveries may include \`data.source\` or \`change\` metadata, but handlers should treat those fields as optional. Route from \`notification.orderId\`, \`notification.fulfillmentId\`, \`notification.returnId\`, or the matching typed \`data.*Id\` field.
|
|
6362
|
+
|
|
6363
|
+
V1 source subscription semantics:
|
|
6364
|
+
|
|
6365
|
+
- \`orderPaid\` and \`orderDelivered\` are delivered through \`orders\`-scoped endpoints.
|
|
6366
|
+
- \`fulfillmentShipped\` is delivered through \`fulfillments\`-scoped endpoints.
|
|
6367
|
+
- \`returnRequested\` and \`returnCompleted\` are delivered through \`returns\`-scoped endpoints.
|
|
6368
|
+
- Empty, unscoped, and all-collection endpoints do not receive v1 semantic commerce notifications.
|
|
6369
|
+
|
|
6270
6370
|
### Collection Order Changed
|
|
6271
6371
|
|
|
6272
6372
|
Admin Panel manual ordering is delivered as a semantic collection update:
|
|
6273
6373
|
|
|
6274
6374
|
- \`operation\` remains \`"update"\` for compatibility.
|
|
6275
6375
|
- \`eventType\` is \`"collection.orderChanged"\`.
|
|
6276
|
-
- \`change.scope\` identifies collection-level ordering versus join ordering.
|
|
6277
6376
|
- SDK handlers should use \`isOrderChangedWebhookEvent()\` from \`@01.software/sdk/webhook\`.
|
|
6377
|
+
- \`change.scope\` identifies collection-level ordering versus join ordering.
|
|
6278
6378
|
- Route on public semantics such as \`change.scope.collection\`, \`change.scope.field\`, and \`change.moved.id\`.
|
|
6279
6379
|
- Do not branch on hidden Payload order fields or private backing collections; diagnostic fields may still be present.
|
|
6280
6380
|
- Customer group member ordering is currently unsupported and does not emit a semantic order-change webhook.
|
|
@@ -6324,8 +6424,8 @@ Dispatched when a customer calls \`client.customer.forgotPassword(email)\`.
|
|
|
6324
6424
|
customerId: string,
|
|
6325
6425
|
email: string,
|
|
6326
6426
|
name: string,
|
|
6327
|
-
resetPasswordToken: string,
|
|
6328
|
-
resetPasswordExpiresAt: string,
|
|
6427
|
+
resetPasswordToken: string,
|
|
6428
|
+
resetPasswordExpiresAt: string,
|
|
6329
6429
|
}
|
|
6330
6430
|
}
|
|
6331
6431
|
\`\`\`
|
|
@@ -6340,11 +6440,13 @@ async function sendPasswordResetEmail(data: {
|
|
|
6340
6440
|
resetPasswordToken: string
|
|
6341
6441
|
resetPasswordExpiresAt: string
|
|
6342
6442
|
}) {
|
|
6343
|
-
const resetUrl =
|
|
6443
|
+
const resetUrl = new URL('https://yourstore.com/reset-password')
|
|
6444
|
+
resetUrl.searchParams.set('token', data.resetPasswordToken)
|
|
6445
|
+
|
|
6344
6446
|
await emailService.send({
|
|
6345
6447
|
to: data.email,
|
|
6346
6448
|
subject: 'Reset your password',
|
|
6347
|
-
body: \`Reset link (expires \${data.resetPasswordExpiresAt}): \${resetUrl}\`,
|
|
6449
|
+
body: \`Reset link (expires \${data.resetPasswordExpiresAt}): \${resetUrl.toString()}\`,
|
|
6348
6450
|
})
|
|
6349
6451
|
}
|
|
6350
6452
|
\`\`\`
|
|
@@ -6355,7 +6457,7 @@ Failed webhook deliveries are queued with automatic retries. Ensure your handler
|
|
|
6355
6457
|
|
|
6356
6458
|
## Webhook Configuration
|
|
6357
6459
|
|
|
6358
|
-
Configure webhook URLs in the 01.software console under Tenant Settings > Webhooks. Multiple URLs can be registered;
|
|
6460
|
+
Configure webhook URLs in the 01.software console under Tenant Settings > Webhooks. Multiple URLs can be registered; scoped endpoints receive events for their configured source collection.`;
|
|
6359
6461
|
}
|
|
6360
6462
|
|
|
6361
6463
|
// src/resources/(docs)/product-detail.ts
|
|
@@ -6383,8 +6485,8 @@ const client = createClient({
|
|
|
6383
6485
|
})
|
|
6384
6486
|
|
|
6385
6487
|
const detail = await client.commerce.product.detail({ slug: 'my-product' })
|
|
6386
|
-
if (!detail) return notFound()
|
|
6387
|
-
const selection = resolveProductSelection(detail, {
|
|
6488
|
+
if (!detail.found) return notFound()
|
|
6489
|
+
const selection = resolveProductSelection(detail.product, {
|
|
6388
6490
|
search: '?opt.option-color=color-black',
|
|
6389
6491
|
})
|
|
6390
6492
|
// selection.selectedVariant, selection.price, selection.stock, selection.media
|
|
@@ -6435,18 +6537,20 @@ export default async function ProductPage({ params }: { params: { slug: string }
|
|
|
6435
6537
|
publishableKey: process.env.NEXT_PUBLIC_SOFTWARE_PUBLISHABLE_KEY!,
|
|
6436
6538
|
})
|
|
6437
6539
|
const detail = await client.commerce.product.detail({ slug: params.slug })
|
|
6438
|
-
if (!detail) return notFound()
|
|
6439
|
-
return <ProductView detail={detail} />
|
|
6540
|
+
if (!detail.found) return notFound()
|
|
6541
|
+
return <ProductView detail={detail.product} />
|
|
6440
6542
|
}
|
|
6441
6543
|
\`\`\`
|
|
6442
6544
|
|
|
6443
|
-
## The \`
|
|
6545
|
+
## The \`ProductDetailResult\` return contract
|
|
6546
|
+
|
|
6547
|
+
The endpoint returns 404 for \`not_found\`, \`not_published\`, or \`feature_disabled\`. The SDK maps those product-detail 404s to \`{ found: false, reason }\` so consumer UIs can render a standard 404, preview CTA, or feature-gating UI. Permission/auth errors, including 403 tenant mismatches, still throw typed SDK errors.
|
|
6444
6548
|
|
|
6445
|
-
|
|
6549
|
+
Successful product payloads expose inventory rollups without sentinel values: \`product.totalInventory\` is the tracked stock sum across non-unlimited variants, \`null\` when no variants are tracked, and \`product.hasUnlimitedVariant\` signals whether any variant is unlimited.
|
|
6446
6550
|
|
|
6447
6551
|
## Backend correlation
|
|
6448
6552
|
|
|
6449
|
-
Log \`client.lastRequestId\` against backend logs \u2014 the endpoint records the exact 404
|
|
6553
|
+
Log \`client.lastRequestId\` against backend logs \u2014 the endpoint records the exact 404 reason alongside the request ID.`;
|
|
6450
6554
|
}
|
|
6451
6555
|
|
|
6452
6556
|
// src/server.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@01.software/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "CLI tool for 01.software platform",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"commander": "^14.0.3",
|
|
23
23
|
"picocolors": "^1.1.1",
|
|
24
24
|
"zod": "^4.4.3",
|
|
25
|
-
"@01.software/sdk": "^0.
|
|
25
|
+
"@01.software/sdk": "^0.33.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/node": "^22.19.18",
|