@01.software/init 0.10.0 → 0.10.1
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/ai-docs.js +0 -0
- package/dist/chunk-4LHYICUL.js +0 -0
- package/dist/chunk-NJ4X7VNK.js +0 -0
- package/dist/chunk-Q6MSORYN.js +0 -0
- package/dist/chunk-STM4DKVZ.js +0 -0
- package/dist/chunk-WDWJ73KP.js +0 -0
- package/dist/create-app-templates/ecommerce/CHANGELOG.md +18 -0
- package/dist/create-app-templates/ecommerce/README.md +31 -16
- package/dist/create-app-templates/ecommerce/components/cart/cart-content.tsx +23 -13
- package/dist/create-app-templates/ecommerce/components/checkout/checkout-form.tsx +145 -105
- package/dist/create-app-templates/ecommerce/lib/cart/server-cart.ts +45 -6
- package/dist/create-app-templates/ecommerce/lib/checkout/parse-checkout-payload.ts +49 -39
- package/dist/create-app-templates/ecommerce/lib/checkout/start-checkout.ts +12 -2
- package/dist/create-app-templates/ecommerce/lib/checkout/types.ts +5 -2
- package/dist/create-app-templates/ecommerce/lib/commerce/adapters/mock.ts +134 -124
- package/dist/create-app-templates/ecommerce/lib/commerce/adapters/software.ts +69 -52
- package/dist/create-app-templates/ecommerce/lib/commerce/types.ts +139 -137
- package/dist/create-app-templates/ecommerce/package.json +2 -2
- package/dist/create-app-templates/ecommerce/tests/customer-cart.test.ts +18 -9
- package/dist/create-app-templates/ecommerce/tests/domain.test.ts +107 -12
- package/dist/file-ops.js +0 -0
- package/dist/init.js +0 -0
- package/dist/templates.js +0 -0
- package/package.json +15 -16
|
@@ -49,6 +49,7 @@ type CartItemDoc = {
|
|
|
49
49
|
quantity?: number | null
|
|
50
50
|
unitPrice?: number | null
|
|
51
51
|
discountedTotalPrice?: number | null
|
|
52
|
+
requiresShipping?: boolean | null
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
type CartDoc = {
|
|
@@ -127,7 +128,6 @@ export type SoftwareSdkClientLike = {
|
|
|
127
128
|
where?: unknown
|
|
128
129
|
joins?: boolean
|
|
129
130
|
}) => Promise<{ docs: unknown[]; totalDocs?: number }>
|
|
130
|
-
update: (id: string, data: Record<string, unknown>) => Promise<unknown>
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
commerce: {
|
|
@@ -171,8 +171,17 @@ export type SoftwareSdkClientLike = {
|
|
|
171
171
|
orders: {
|
|
172
172
|
checkout: (params: {
|
|
173
173
|
cartId: string
|
|
174
|
+
cartToken?: string
|
|
174
175
|
orderNumber: string
|
|
175
176
|
customerSnapshot: CustomerSnapshotInput
|
|
177
|
+
shippingAddress?: {
|
|
178
|
+
recipientName: string
|
|
179
|
+
phone: string
|
|
180
|
+
postalCode: string
|
|
181
|
+
address: string
|
|
182
|
+
detailAddress: string
|
|
183
|
+
deliveryMessage?: string
|
|
184
|
+
}
|
|
176
185
|
idempotencyKey?: string
|
|
177
186
|
}) => Promise<OrderDoc>
|
|
178
187
|
confirmPaymentReturningOrder: (params: {
|
|
@@ -372,28 +381,12 @@ export function buildSoftwareCommerceProvider(
|
|
|
372
381
|
if (!cartId || lines.length === 0) {
|
|
373
382
|
throw new Error('Cart is empty')
|
|
374
383
|
}
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
// policy (postalCode-driven zone surcharge recompute is owned by the
|
|
382
|
-
// Console cart shipping-authority work, not the template).
|
|
383
|
-
await client.collections.from('carts').update(cartId, {
|
|
384
|
-
email: input.customerSnapshot.email,
|
|
385
|
-
shippingAddress: {
|
|
386
|
-
recipientName: input.shippingAddress.recipientName,
|
|
387
|
-
phone: input.shippingAddress.phone,
|
|
388
|
-
postalCode: input.shippingAddress.postalCode,
|
|
389
|
-
address: input.shippingAddress.address,
|
|
390
|
-
detailAddress: input.shippingAddress.detailAddress,
|
|
391
|
-
deliveryMessage: input.shippingAddress.deliveryMessage ?? '',
|
|
392
|
-
},
|
|
393
|
-
...(input.shippingAddress.deliveryMessage
|
|
394
|
-
? { customerNote: input.shippingAddress.deliveryMessage }
|
|
395
|
-
: {}),
|
|
396
|
-
})
|
|
384
|
+
const hasShippableItems = lines.some(
|
|
385
|
+
(item) => item.requiresShipping !== false,
|
|
386
|
+
)
|
|
387
|
+
if (hasShippableItems && !input.shippingAddress) {
|
|
388
|
+
throw new Error('Shipping address is required')
|
|
389
|
+
}
|
|
397
390
|
|
|
398
391
|
const orderNumber = generateOrderNumber()
|
|
399
392
|
// pgPaymentId is minted template-side AFTER checkout (the design's "mint
|
|
@@ -407,12 +400,25 @@ export function buildSoftwareCommerceProvider(
|
|
|
407
400
|
|
|
408
401
|
const placed = await client.commerce.orders.checkout({
|
|
409
402
|
cartId,
|
|
403
|
+
cartToken: input.cartToken,
|
|
410
404
|
orderNumber,
|
|
411
405
|
customerSnapshot: {
|
|
412
406
|
name: input.customerSnapshot.name,
|
|
413
407
|
email: input.customerSnapshot.email,
|
|
414
408
|
phone: input.customerSnapshot.phone,
|
|
415
409
|
},
|
|
410
|
+
...(input.shippingAddress
|
|
411
|
+
? {
|
|
412
|
+
shippingAddress: {
|
|
413
|
+
recipientName: input.shippingAddress.recipientName,
|
|
414
|
+
phone: input.shippingAddress.phone,
|
|
415
|
+
postalCode: input.shippingAddress.postalCode,
|
|
416
|
+
address: input.shippingAddress.address,
|
|
417
|
+
detailAddress: input.shippingAddress.detailAddress,
|
|
418
|
+
deliveryMessage: input.shippingAddress.deliveryMessage,
|
|
419
|
+
},
|
|
420
|
+
}
|
|
421
|
+
: {}),
|
|
416
422
|
idempotencyKey: `checkout-${orderNumber}`,
|
|
417
423
|
})
|
|
418
424
|
|
|
@@ -420,7 +426,9 @@ export function buildSoftwareCommerceProvider(
|
|
|
420
426
|
fallbackOrderNumber: orderNumber,
|
|
421
427
|
contact: {
|
|
422
428
|
customerSnapshot: input.customerSnapshot,
|
|
423
|
-
|
|
429
|
+
...(input.shippingAddress
|
|
430
|
+
? { shippingAddress: input.shippingAddress }
|
|
431
|
+
: {}),
|
|
424
432
|
},
|
|
425
433
|
})
|
|
426
434
|
|
|
@@ -566,6 +574,9 @@ export function buildSoftwareCommerceProvider(
|
|
|
566
574
|
quantity,
|
|
567
575
|
unitAmount,
|
|
568
576
|
lineAmount,
|
|
577
|
+
...(item.requiresShipping !== undefined
|
|
578
|
+
? { requiresShipping: item.requiresShipping }
|
|
579
|
+
: {}),
|
|
569
580
|
productTitle: summary?.title ?? 'Product',
|
|
570
581
|
variantTitle: variant?.title,
|
|
571
582
|
image: variant?.images[0] ?? summary?.image ?? null,
|
|
@@ -635,7 +646,9 @@ function createSoftwareCustomerProvider(token: string): CommerceProvider {
|
|
|
635
646
|
* client. Logged-in `createCart()` therefore mints a **customer-bound** cart
|
|
636
647
|
* (the JWT auto-binds `customer`), never a guest cart.
|
|
637
648
|
*/
|
|
638
|
-
export function createSoftwareCustomerCartProvider(
|
|
649
|
+
export function createSoftwareCustomerCartProvider(
|
|
650
|
+
token: string,
|
|
651
|
+
): CartProvider {
|
|
639
652
|
return createSoftwareCustomerProvider(token)
|
|
640
653
|
}
|
|
641
654
|
|
|
@@ -758,7 +771,7 @@ function mapOrder(
|
|
|
758
771
|
fallbackOrderNumber?: string
|
|
759
772
|
contact?: {
|
|
760
773
|
customerSnapshot: Order['customerSnapshot']
|
|
761
|
-
shippingAddress
|
|
774
|
+
shippingAddress?: Order['shippingAddress']
|
|
762
775
|
}
|
|
763
776
|
} = {},
|
|
764
777
|
): Order {
|
|
@@ -805,32 +818,36 @@ function mapOrder(
|
|
|
805
818
|
opts.contact?.customerSnapshot.phone ??
|
|
806
819
|
'',
|
|
807
820
|
},
|
|
808
|
-
shippingAddress
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
821
|
+
...(order.shippingAddress || opts.contact?.shippingAddress
|
|
822
|
+
? {
|
|
823
|
+
shippingAddress: {
|
|
824
|
+
recipientName:
|
|
825
|
+
order.shippingAddress?.recipientName ??
|
|
826
|
+
opts.contact?.shippingAddress?.recipientName ??
|
|
827
|
+
'',
|
|
828
|
+
phone:
|
|
829
|
+
order.shippingAddress?.phone ??
|
|
830
|
+
opts.contact?.shippingAddress?.phone ??
|
|
831
|
+
'',
|
|
832
|
+
postalCode:
|
|
833
|
+
order.shippingAddress?.postalCode ??
|
|
834
|
+
opts.contact?.shippingAddress?.postalCode ??
|
|
835
|
+
'',
|
|
836
|
+
address:
|
|
837
|
+
order.shippingAddress?.address ??
|
|
838
|
+
opts.contact?.shippingAddress?.address ??
|
|
839
|
+
'',
|
|
840
|
+
detailAddress:
|
|
841
|
+
order.shippingAddress?.detailAddress ??
|
|
842
|
+
opts.contact?.shippingAddress?.detailAddress ??
|
|
843
|
+
'',
|
|
844
|
+
deliveryMessage:
|
|
845
|
+
order.shippingAddress?.deliveryMessage ??
|
|
846
|
+
opts.contact?.shippingAddress?.deliveryMessage ??
|
|
847
|
+
'',
|
|
848
|
+
},
|
|
849
|
+
}
|
|
850
|
+
: {}),
|
|
834
851
|
subtotalAmount: order.subtotalAmount ?? 0,
|
|
835
852
|
shippingAmount: order.shippingAmount ?? 0,
|
|
836
853
|
totalAmount: order.totalAmount ?? 0,
|
|
@@ -1,63 +1,64 @@
|
|
|
1
1
|
export type CommerceImage = {
|
|
2
|
-
url: string
|
|
3
|
-
alt?: string
|
|
4
|
-
width?: number
|
|
5
|
-
height?: number
|
|
6
|
-
}
|
|
2
|
+
url: string
|
|
3
|
+
alt?: string
|
|
4
|
+
width?: number
|
|
5
|
+
height?: number
|
|
6
|
+
}
|
|
7
7
|
|
|
8
8
|
export type Product = {
|
|
9
|
-
id: string
|
|
10
|
-
slug: string
|
|
11
|
-
title: string
|
|
12
|
-
description?: string
|
|
13
|
-
thumbnail?: CommerceImage | null
|
|
14
|
-
images: CommerceImage[]
|
|
15
|
-
status:
|
|
16
|
-
}
|
|
9
|
+
id: string
|
|
10
|
+
slug: string
|
|
11
|
+
title: string
|
|
12
|
+
description?: string
|
|
13
|
+
thumbnail?: CommerceImage | null
|
|
14
|
+
images: CommerceImage[]
|
|
15
|
+
status: 'draft' | 'published' | 'archived'
|
|
16
|
+
}
|
|
17
17
|
|
|
18
18
|
export type ProductDetail = {
|
|
19
|
-
product: Product
|
|
20
|
-
variants: ProductVariant[]
|
|
21
|
-
options: ProductOption[]
|
|
22
|
-
}
|
|
19
|
+
product: Product
|
|
20
|
+
variants: ProductVariant[]
|
|
21
|
+
options: ProductOption[]
|
|
22
|
+
}
|
|
23
23
|
|
|
24
24
|
export type ProductOption = {
|
|
25
|
-
id: string
|
|
26
|
-
slug: string
|
|
27
|
-
title: string
|
|
28
|
-
values: ProductOptionValue[]
|
|
29
|
-
}
|
|
25
|
+
id: string
|
|
26
|
+
slug: string
|
|
27
|
+
title: string
|
|
28
|
+
values: ProductOptionValue[]
|
|
29
|
+
}
|
|
30
30
|
|
|
31
31
|
export type ProductOptionValue = {
|
|
32
|
-
id: string
|
|
33
|
-
slug: string
|
|
34
|
-
value: string
|
|
35
|
-
}
|
|
32
|
+
id: string
|
|
33
|
+
slug: string
|
|
34
|
+
value: string
|
|
35
|
+
}
|
|
36
36
|
|
|
37
37
|
export type ProductVariantOptionValue = {
|
|
38
|
-
optionId: string
|
|
39
|
-
valueId: string
|
|
40
|
-
valueSlug: string
|
|
41
|
-
value: string
|
|
42
|
-
}
|
|
38
|
+
optionId: string
|
|
39
|
+
valueId: string
|
|
40
|
+
valueSlug: string
|
|
41
|
+
value: string
|
|
42
|
+
}
|
|
43
43
|
|
|
44
44
|
export type ProductVariant = {
|
|
45
|
-
id: string
|
|
46
|
-
productId: string
|
|
47
|
-
title?: string
|
|
48
|
-
sku?: string
|
|
49
|
-
price: number
|
|
50
|
-
stock: number
|
|
51
|
-
reservedStock: number
|
|
52
|
-
isUnlimited: boolean
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
45
|
+
id: string
|
|
46
|
+
productId: string
|
|
47
|
+
title?: string
|
|
48
|
+
sku?: string
|
|
49
|
+
price: number
|
|
50
|
+
stock: number
|
|
51
|
+
reservedStock: number
|
|
52
|
+
isUnlimited: boolean
|
|
53
|
+
requiresShipping?: boolean | null
|
|
54
|
+
optionValues: ProductVariantOptionValue[]
|
|
55
|
+
images: CommerceImage[]
|
|
56
|
+
}
|
|
56
57
|
|
|
57
58
|
export type CartLine = {
|
|
58
|
-
variantId: string
|
|
59
|
-
quantity: number
|
|
60
|
-
}
|
|
59
|
+
variantId: string
|
|
60
|
+
quantity: number
|
|
61
|
+
}
|
|
61
62
|
|
|
62
63
|
/**
|
|
63
64
|
* Reference used to add a line to the server cart. The catalog identity
|
|
@@ -65,11 +66,11 @@ export type CartLine = {
|
|
|
65
66
|
* cart, not the browser, owns price and stock.
|
|
66
67
|
*/
|
|
67
68
|
export type CartItemRef = {
|
|
68
|
-
productId: string
|
|
69
|
-
variantId: string
|
|
70
|
-
optionId?: string
|
|
71
|
-
quantity: number
|
|
72
|
-
}
|
|
69
|
+
productId: string
|
|
70
|
+
variantId: string
|
|
71
|
+
optionId?: string
|
|
72
|
+
quantity: number
|
|
73
|
+
}
|
|
73
74
|
|
|
74
75
|
/**
|
|
75
76
|
* A single line of the server cart, enriched with catalog display fields so the
|
|
@@ -77,16 +78,17 @@ export type CartItemRef = {
|
|
|
77
78
|
* handle used by update/remove.
|
|
78
79
|
*/
|
|
79
80
|
export type CartItemView = {
|
|
80
|
-
cartItemId: string
|
|
81
|
-
productId: string
|
|
82
|
-
variantId: string
|
|
83
|
-
quantity: number
|
|
84
|
-
unitAmount: number
|
|
85
|
-
lineAmount: number
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
81
|
+
cartItemId: string
|
|
82
|
+
productId: string
|
|
83
|
+
variantId: string
|
|
84
|
+
quantity: number
|
|
85
|
+
unitAmount: number
|
|
86
|
+
lineAmount: number
|
|
87
|
+
requiresShipping?: boolean | null
|
|
88
|
+
productTitle: string
|
|
89
|
+
variantTitle?: string
|
|
90
|
+
image?: CommerceImage | null
|
|
91
|
+
}
|
|
90
92
|
|
|
91
93
|
/**
|
|
92
94
|
* The server cart projected for the storefront. `id` is the cart's DB id used
|
|
@@ -96,95 +98,95 @@ export type CartItemView = {
|
|
|
96
98
|
* computed and stored by the Console cart).
|
|
97
99
|
*/
|
|
98
100
|
export type CartView = {
|
|
99
|
-
id: string
|
|
100
|
-
currency: string
|
|
101
|
-
subtotalAmount: number
|
|
102
|
-
shippingAmount: number
|
|
103
|
-
discountAmount: number
|
|
104
|
-
totalAmount: number
|
|
105
|
-
discountCode?: string
|
|
106
|
-
items: CartItemView[]
|
|
107
|
-
}
|
|
101
|
+
id: string
|
|
102
|
+
currency: string
|
|
103
|
+
subtotalAmount: number
|
|
104
|
+
shippingAmount: number
|
|
105
|
+
discountAmount: number
|
|
106
|
+
totalAmount: number
|
|
107
|
+
discountCode?: string
|
|
108
|
+
items: CartItemView[]
|
|
109
|
+
}
|
|
108
110
|
|
|
109
111
|
export type ShippingPolicy = {
|
|
110
|
-
currency: string
|
|
111
|
-
baseAmount: number
|
|
112
|
-
freeAboveAmount?: number
|
|
113
|
-
}
|
|
112
|
+
currency: string
|
|
113
|
+
baseAmount: number
|
|
114
|
+
freeAboveAmount?: number
|
|
115
|
+
}
|
|
114
116
|
|
|
115
117
|
export type PricedOrderLine = CartLine & {
|
|
116
|
-
unitAmount: number
|
|
117
|
-
lineAmount: number
|
|
118
|
-
variant: ProductVariant
|
|
119
|
-
}
|
|
118
|
+
unitAmount: number
|
|
119
|
+
lineAmount: number
|
|
120
|
+
variant: ProductVariant
|
|
121
|
+
}
|
|
120
122
|
|
|
121
123
|
export type PricedOrder = {
|
|
122
|
-
currency: string
|
|
123
|
-
lines: PricedOrderLine[]
|
|
124
|
-
subtotalAmount: number
|
|
125
|
-
shippingAmount: number
|
|
126
|
-
totalAmount: number
|
|
127
|
-
}
|
|
124
|
+
currency: string
|
|
125
|
+
lines: PricedOrderLine[]
|
|
126
|
+
subtotalAmount: number
|
|
127
|
+
shippingAmount: number
|
|
128
|
+
totalAmount: number
|
|
129
|
+
}
|
|
128
130
|
|
|
129
131
|
export type StockCheckLine = CartLine & {
|
|
130
|
-
availableQuantity: number | null
|
|
131
|
-
ok: boolean
|
|
132
|
-
reason?:
|
|
133
|
-
}
|
|
132
|
+
availableQuantity: number | null
|
|
133
|
+
ok: boolean
|
|
134
|
+
reason?: 'variant_not_found' | 'insufficient_stock'
|
|
135
|
+
}
|
|
134
136
|
|
|
135
137
|
export type StockCheckResult = {
|
|
136
|
-
ok: boolean
|
|
137
|
-
lines: StockCheckLine[]
|
|
138
|
-
}
|
|
138
|
+
ok: boolean
|
|
139
|
+
lines: StockCheckLine[]
|
|
140
|
+
}
|
|
139
141
|
|
|
140
142
|
export type CustomerSnapshot = {
|
|
141
|
-
name: string
|
|
142
|
-
email: string
|
|
143
|
-
phone: string
|
|
144
|
-
}
|
|
143
|
+
name: string
|
|
144
|
+
email: string
|
|
145
|
+
phone: string
|
|
146
|
+
}
|
|
145
147
|
|
|
146
148
|
export type ShippingAddress = {
|
|
147
|
-
recipientName: string
|
|
148
|
-
phone: string
|
|
149
|
-
postalCode: string
|
|
150
|
-
address: string
|
|
151
|
-
detailAddress: string
|
|
152
|
-
deliveryMessage?: string
|
|
153
|
-
}
|
|
149
|
+
recipientName: string
|
|
150
|
+
phone: string
|
|
151
|
+
postalCode: string
|
|
152
|
+
address: string
|
|
153
|
+
detailAddress: string
|
|
154
|
+
deliveryMessage?: string
|
|
155
|
+
}
|
|
154
156
|
|
|
155
157
|
export type OrderItem = {
|
|
156
|
-
variantId: string
|
|
157
|
-
productTitle: string
|
|
158
|
-
variantTitle?: string
|
|
159
|
-
quantity: number
|
|
160
|
-
unitAmount: number
|
|
161
|
-
lineAmount: number
|
|
162
|
-
}
|
|
158
|
+
variantId: string
|
|
159
|
+
productTitle: string
|
|
160
|
+
variantTitle?: string
|
|
161
|
+
quantity: number
|
|
162
|
+
unitAmount: number
|
|
163
|
+
lineAmount: number
|
|
164
|
+
}
|
|
163
165
|
|
|
164
166
|
export type PaymentTransaction = {
|
|
165
|
-
paymentId: string
|
|
166
|
-
provider: string
|
|
167
|
-
status:
|
|
168
|
-
amount: number
|
|
169
|
-
}
|
|
167
|
+
paymentId: string
|
|
168
|
+
provider: string
|
|
169
|
+
status: 'pending' | 'paid' | 'failed' | 'canceled'
|
|
170
|
+
amount: number
|
|
171
|
+
}
|
|
170
172
|
|
|
171
173
|
export type Order = {
|
|
172
|
-
id: string
|
|
173
|
-
orderNumber: string
|
|
174
|
-
displayStatus:
|
|
175
|
-
items: OrderItem[]
|
|
176
|
-
customerSnapshot: CustomerSnapshot
|
|
177
|
-
shippingAddress
|
|
178
|
-
subtotalAmount: number
|
|
179
|
-
shippingAmount: number
|
|
180
|
-
totalAmount: number
|
|
181
|
-
transactions: PaymentTransaction[]
|
|
182
|
-
}
|
|
174
|
+
id: string
|
|
175
|
+
orderNumber: string
|
|
176
|
+
displayStatus: 'pending' | 'paid' | 'canceled'
|
|
177
|
+
items: OrderItem[]
|
|
178
|
+
customerSnapshot: CustomerSnapshot
|
|
179
|
+
shippingAddress?: ShippingAddress
|
|
180
|
+
subtotalAmount: number
|
|
181
|
+
shippingAmount: number
|
|
182
|
+
totalAmount: number
|
|
183
|
+
transactions: PaymentTransaction[]
|
|
184
|
+
}
|
|
183
185
|
|
|
184
186
|
export type ProductListResult = {
|
|
185
|
-
products: ProductDetail[]
|
|
186
|
-
total: number
|
|
187
|
-
}
|
|
187
|
+
products: ProductDetail[]
|
|
188
|
+
total: number
|
|
189
|
+
}
|
|
188
190
|
|
|
189
191
|
/**
|
|
190
192
|
* Checkout input. The cart contents live server-side (addressed by `cartToken`
|
|
@@ -192,15 +194,15 @@ export type ProductListResult = {
|
|
|
192
194
|
* snapshot. No client-supplied lines or totals — the cart is the quote.
|
|
193
195
|
*/
|
|
194
196
|
export type CheckoutCartInput = {
|
|
195
|
-
cartToken: string
|
|
196
|
-
customerSnapshot: CustomerSnapshot
|
|
197
|
-
shippingAddress
|
|
198
|
-
}
|
|
197
|
+
cartToken: string
|
|
198
|
+
customerSnapshot: CustomerSnapshot
|
|
199
|
+
shippingAddress?: ShippingAddress
|
|
200
|
+
}
|
|
199
201
|
|
|
200
202
|
export type CreatePendingOrderResult = {
|
|
201
|
-
order: Order
|
|
202
|
-
paymentId: string
|
|
203
|
-
paymentName: string
|
|
204
|
-
amount: number
|
|
205
|
-
currency: string
|
|
206
|
-
}
|
|
203
|
+
order: Order
|
|
204
|
+
paymentId: string
|
|
205
|
+
paymentName: string
|
|
206
|
+
amount: number
|
|
207
|
+
currency: string
|
|
208
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ecommerce",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"check-types": "next typegen && tsc --noEmit"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@01.software/sdk": "^0.
|
|
15
|
+
"@01.software/sdk": "^0.43.0",
|
|
16
16
|
"@portone/browser-sdk": "^0.1.8",
|
|
17
17
|
"@portone/server-sdk": "^0.19.0",
|
|
18
18
|
"@tosspayments/tosspayments-sdk": "^2.7.0",
|
|
@@ -254,8 +254,14 @@ function fakeCheckoutSdkClient(calls: string[]) {
|
|
|
254
254
|
},
|
|
255
255
|
},
|
|
256
256
|
orders: {
|
|
257
|
-
async checkout(params: {
|
|
258
|
-
|
|
257
|
+
async checkout(params: {
|
|
258
|
+
cartId: string;
|
|
259
|
+
cartToken?: string;
|
|
260
|
+
shippingAddress?: { postalCode?: string };
|
|
261
|
+
}) {
|
|
262
|
+
calls.push(
|
|
263
|
+
`commerce.orders.checkout:${params.cartId}:${params.cartToken ?? ""}:${params.shippingAddress?.postalCode ?? ""}`,
|
|
264
|
+
);
|
|
259
265
|
if (params.cartId === "cart_other") {
|
|
260
266
|
throw Object.assign(new Error("Forbidden"), { status: 403 });
|
|
261
267
|
}
|
|
@@ -287,10 +293,6 @@ function fakeCheckoutSdkClient(calls: string[]) {
|
|
|
287
293
|
calls.push(`collections.${slug}.find`);
|
|
288
294
|
return { docs: [] };
|
|
289
295
|
},
|
|
290
|
-
async update(id: string) {
|
|
291
|
-
calls.push(`collections.${slug}.update:${id}`);
|
|
292
|
-
return {};
|
|
293
|
-
},
|
|
294
296
|
};
|
|
295
297
|
},
|
|
296
298
|
},
|
|
@@ -322,8 +324,11 @@ test("customer checkout provider: own cart checks out through the bound SDK clie
|
|
|
322
324
|
|
|
323
325
|
assert.equal(pending.order.orderNumber, "ORD-1");
|
|
324
326
|
assert.ok(calls.includes("commerce.cart.get:cart_owned_token"));
|
|
325
|
-
assert.ok(
|
|
326
|
-
|
|
327
|
+
assert.ok(
|
|
328
|
+
calls.includes(
|
|
329
|
+
"commerce.orders.checkout:cart_owned:cart_owned_token:04524",
|
|
330
|
+
),
|
|
331
|
+
);
|
|
327
332
|
});
|
|
328
333
|
|
|
329
334
|
test("customer checkout provider: another customer's cart is rejected by the SDK boundary", async () => {
|
|
@@ -352,7 +357,11 @@ test("customer checkout provider: another customer's cart is rejected by the SDK
|
|
|
352
357
|
Object.assign(new Error("Forbidden"), { status: 403 }),
|
|
353
358
|
);
|
|
354
359
|
|
|
355
|
-
assert.ok(
|
|
360
|
+
assert.ok(
|
|
361
|
+
calls.includes(
|
|
362
|
+
"commerce.orders.checkout:cart_other:cart_other_token:04524",
|
|
363
|
+
),
|
|
364
|
+
);
|
|
356
365
|
});
|
|
357
366
|
|
|
358
367
|
// ---- logout clears both the session JWT and the cart cookie ---------------
|