@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
|
@@ -247,6 +247,42 @@ test('parseCheckoutPayload rejects invalid customer and shipping fields', () =>
|
|
|
247
247
|
)
|
|
248
248
|
})
|
|
249
249
|
|
|
250
|
+
test('parseCheckoutPayload accepts missing shipping fields when the cart requires no shipping', () => {
|
|
251
|
+
assert.deepEqual(
|
|
252
|
+
parseCheckoutPayload(
|
|
253
|
+
{
|
|
254
|
+
customerSnapshot: {
|
|
255
|
+
name: 'Ada',
|
|
256
|
+
email: 'ada@example.test',
|
|
257
|
+
phone: '010',
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
{ requiresShipping: false },
|
|
261
|
+
),
|
|
262
|
+
{
|
|
263
|
+
customerSnapshot: {
|
|
264
|
+
name: 'Ada',
|
|
265
|
+
email: 'ada@example.test',
|
|
266
|
+
phone: '010',
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
)
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
test('parseCheckoutPayload still requires shipping fields by default', () => {
|
|
273
|
+
assert.throws(
|
|
274
|
+
() =>
|
|
275
|
+
parseCheckoutPayload({
|
|
276
|
+
customerSnapshot: {
|
|
277
|
+
name: 'Ada',
|
|
278
|
+
email: 'ada@example.test',
|
|
279
|
+
phone: '010',
|
|
280
|
+
},
|
|
281
|
+
}),
|
|
282
|
+
/shippingAddress/,
|
|
283
|
+
)
|
|
284
|
+
})
|
|
285
|
+
|
|
250
286
|
test('startCheckout converts the server cart then requests payment with the cart total', async () => {
|
|
251
287
|
const order = makePendingOrder({ totalAmount: 99000 })
|
|
252
288
|
let requestedAmount = 0
|
|
@@ -333,13 +369,18 @@ test('startCheckout surfaces a failed payment request', async () => {
|
|
|
333
369
|
|
|
334
370
|
test('checkout error status preserves SDK authorization failures', () => {
|
|
335
371
|
assert.equal(
|
|
336
|
-
getCheckoutErrorStatus(
|
|
372
|
+
getCheckoutErrorStatus(
|
|
373
|
+
Object.assign(new Error('Forbidden'), { status: 403 }),
|
|
374
|
+
),
|
|
337
375
|
403,
|
|
338
376
|
)
|
|
339
377
|
})
|
|
340
378
|
|
|
341
379
|
test('checkout error status maps payload validation failures to bad request', () => {
|
|
342
|
-
assert.equal(
|
|
380
|
+
assert.equal(
|
|
381
|
+
getCheckoutErrorStatus(new Error('valid email is required')),
|
|
382
|
+
400,
|
|
383
|
+
)
|
|
343
384
|
})
|
|
344
385
|
|
|
345
386
|
test('mock payment provider stores payments independently from mock commerce orders', async () => {
|
|
@@ -369,6 +410,60 @@ test('mock payment provider stores payments independently from mock commerce ord
|
|
|
369
410
|
clearMockPaymentStore()
|
|
370
411
|
})
|
|
371
412
|
|
|
413
|
+
test('README documents the server-cart architecture, not removed local stores', async () => {
|
|
414
|
+
const readFile = await import('node:fs/promises')
|
|
415
|
+
const readme = await readFile.readFile(
|
|
416
|
+
new URL('../README.md', import.meta.url),
|
|
417
|
+
'utf8',
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
assert.match(readme, /Server-authoritative cart/i)
|
|
421
|
+
assert.match(readme, /commerce\.cart\.\*/)
|
|
422
|
+
assert.match(readme, /HttpOnly cart cookie/i)
|
|
423
|
+
assert.match(readme, /cartToken/)
|
|
424
|
+
assert.match(
|
|
425
|
+
readme,
|
|
426
|
+
/client\s+JavaScript receives rendered cart views but never owns the authoritative cart\s+or token/i,
|
|
427
|
+
)
|
|
428
|
+
assert.match(
|
|
429
|
+
readme,
|
|
430
|
+
/no cart contents are persisted in localStorage/i,
|
|
431
|
+
)
|
|
432
|
+
assert.match(readme, /orders\.checkout\(\{ cartId \}\)/)
|
|
433
|
+
assert.match(readme, /orders\.getByPaymentId/i)
|
|
434
|
+
assert.match(
|
|
435
|
+
readme,
|
|
436
|
+
/mock adapter emulates the server cart and checkout flow in memory/i,
|
|
437
|
+
)
|
|
438
|
+
assert.match(readme, /zero-backend demos/i)
|
|
439
|
+
assert.match(readme, /\/api\/checkout\/payment-return/)
|
|
440
|
+
assert.match(readme, /tampered redirect amount/i)
|
|
441
|
+
assert.match(readme, /PG-verified amount/i)
|
|
442
|
+
assert.match(readme, /Success-page\s+reconciliation/i)
|
|
443
|
+
assert.match(readme, /orders\.confirmPayment/i)
|
|
444
|
+
const removedLocalCartText = new RegExp(
|
|
445
|
+
['Local persisted cart', ' with Zustand'].join(' state'),
|
|
446
|
+
'i',
|
|
447
|
+
)
|
|
448
|
+
const removedMockOrderIndex = new RegExp(
|
|
449
|
+
['\\.mock', 'orders\\.json'].join('-'),
|
|
450
|
+
'i',
|
|
451
|
+
)
|
|
452
|
+
const removedSoftwareOrderIndex = new RegExp(
|
|
453
|
+
['\\.software', 'orders\\.json'].join('-'),
|
|
454
|
+
'i',
|
|
455
|
+
)
|
|
456
|
+
const removedLegacyCheckoutCall = new RegExp(
|
|
457
|
+
['orders', 'create'].join('\\.'),
|
|
458
|
+
'i',
|
|
459
|
+
)
|
|
460
|
+
|
|
461
|
+
assert.doesNotMatch(readme, removedLocalCartText)
|
|
462
|
+
assert.doesNotMatch(readme, removedMockOrderIndex)
|
|
463
|
+
assert.doesNotMatch(readme, removedSoftwareOrderIndex)
|
|
464
|
+
assert.doesNotMatch(readme, removedLegacyCheckoutCall)
|
|
465
|
+
})
|
|
466
|
+
|
|
372
467
|
test('software adapter maps SDK product detail responses into storefront product detail', () => {
|
|
373
468
|
const detail = mapSoftwareProductDetail({
|
|
374
469
|
product: {
|
|
@@ -1028,7 +1123,10 @@ test('software adapter threads the SDK checkout → confirm round-trip', async (
|
|
|
1028
1123
|
|
|
1029
1124
|
// Before placement, a by-payment lookup 404s and resolves to null.
|
|
1030
1125
|
assert.equal(
|
|
1031
|
-
await provider.getOrderByPaymentId({
|
|
1126
|
+
await provider.getOrderByPaymentId({
|
|
1127
|
+
paymentId: 'pay_x',
|
|
1128
|
+
provider: 'mock',
|
|
1129
|
+
}),
|
|
1032
1130
|
null,
|
|
1033
1131
|
)
|
|
1034
1132
|
|
|
@@ -1050,10 +1148,9 @@ test('software adapter threads the SDK checkout → confirm round-trip', async (
|
|
|
1050
1148
|
assert.equal(pending.order.displayStatus, 'pending')
|
|
1051
1149
|
assert.equal(pending.amount, 53000)
|
|
1052
1150
|
assert.match(pending.paymentId, /^pay_/)
|
|
1053
|
-
// The buyer address is
|
|
1054
|
-
//
|
|
1055
|
-
assert.ok(calls.includes(
|
|
1056
|
-
assert.ok(calls.includes(`checkout:cart_1:${orderNumber}`))
|
|
1151
|
+
// The buyer address is passed to checkout with the cart capability token so
|
|
1152
|
+
// Console can persist context and price shipping atomically.
|
|
1153
|
+
assert.ok(calls.includes(`checkout:cart_1:tok_1:04524:${orderNumber}`))
|
|
1057
1154
|
assert.equal(orderNumbers[0], orderNumber)
|
|
1058
1155
|
|
|
1059
1156
|
// Confirm with the minted payment id + provider-verified amount → placed paid
|
|
@@ -1114,10 +1211,6 @@ function makeFakeSdkClient(): {
|
|
|
1114
1211
|
async find() {
|
|
1115
1212
|
return { docs: [] }
|
|
1116
1213
|
},
|
|
1117
|
-
async update(id) {
|
|
1118
|
-
calls.push(`${slug}.update:${id}`)
|
|
1119
|
-
return {}
|
|
1120
|
-
},
|
|
1121
1214
|
}),
|
|
1122
1215
|
},
|
|
1123
1216
|
commerce: {
|
|
@@ -1151,7 +1244,9 @@ function makeFakeSdkClient(): {
|
|
|
1151
1244
|
},
|
|
1152
1245
|
orders: {
|
|
1153
1246
|
async checkout(params) {
|
|
1154
|
-
calls.push(
|
|
1247
|
+
calls.push(
|
|
1248
|
+
`checkout:${params.cartId}:${params.cartToken}:${params.shippingAddress?.postalCode}:${params.orderNumber}`,
|
|
1249
|
+
)
|
|
1155
1250
|
orderNumbers.push(params.orderNumber)
|
|
1156
1251
|
return {
|
|
1157
1252
|
id: 'ord_pending',
|
package/dist/file-ops.js
CHANGED
|
File without changes
|
package/dist/init.js
CHANGED
|
File without changes
|
package/dist/templates.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@01.software/init",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Initialize 01.software SDK in your project (Next.js, React, Vanilla JS, Node.js, Edge)",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -32,29 +32,28 @@
|
|
|
32
32
|
"engines": {
|
|
33
33
|
"node": ">=18.0.0"
|
|
34
34
|
},
|
|
35
|
-
"scripts": {
|
|
36
|
-
"build": "tsup && node scripts/copy-create-app-templates.mjs",
|
|
37
|
-
"dev": "tsup --watch",
|
|
38
|
-
"check-types": "tsc --noEmit",
|
|
39
|
-
"check-snippets": "tsc --project tsconfig.fixture.json --noEmit",
|
|
40
|
-
"test": "pnpm run build && node --test tests/**/*.test.mjs",
|
|
41
|
-
"prepublishOnly": "pnpm run check-types && pnpm run build",
|
|
42
|
-
"release:dev": "node ../../scripts/publish.js dev init",
|
|
43
|
-
"release:local": "node ../../scripts/publish.js local init"
|
|
44
|
-
},
|
|
45
35
|
"dependencies": {
|
|
46
36
|
"picocolors": "^1.1.1",
|
|
47
37
|
"prompts": "^2.4.2"
|
|
48
38
|
},
|
|
49
39
|
"devDependencies": {
|
|
50
|
-
"@
|
|
51
|
-
"@types/node": "catalog:node22",
|
|
40
|
+
"@types/node": "^22.19.18",
|
|
52
41
|
"@types/prompts": "^2.4.9",
|
|
53
|
-
"tsup": "
|
|
54
|
-
"typescript": "
|
|
42
|
+
"tsup": "^8.5.1",
|
|
43
|
+
"typescript": "5.7.3",
|
|
44
|
+
"@01.software/sdk": "^0.43.0"
|
|
55
45
|
},
|
|
56
46
|
"author": "<office@01.works>",
|
|
57
47
|
"publishConfig": {
|
|
58
48
|
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsup && node scripts/copy-create-app-templates.mjs",
|
|
52
|
+
"dev": "tsup --watch",
|
|
53
|
+
"check-types": "tsc --noEmit",
|
|
54
|
+
"check-snippets": "tsc --project tsconfig.fixture.json --noEmit",
|
|
55
|
+
"test": "pnpm run build && node --test tests/**/*.test.mjs",
|
|
56
|
+
"release:dev": "node ../../scripts/publish.js dev init",
|
|
57
|
+
"release:local": "node ../../scripts/publish.js local init"
|
|
59
58
|
}
|
|
60
|
-
}
|
|
59
|
+
}
|