@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.
@@ -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(Object.assign(new Error('Forbidden'), { status: 403 })),
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(getCheckoutErrorStatus(new Error('valid email is required')), 400)
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({ paymentId: 'pay_x', provider: 'mock' }),
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 persisted to the cart before checkout, and checkout is
1054
- // called with the cart id + generated order number.
1055
- assert.ok(calls.includes('carts.update:cart_1'))
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(`checkout:${params.cartId}:${params.orderNumber}`)
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.0",
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
- "@01.software/sdk": "workspace:^",
51
- "@types/node": "catalog:node22",
40
+ "@types/node": "^22.19.18",
52
41
  "@types/prompts": "^2.4.9",
53
- "tsup": "catalog:",
54
- "typescript": "catalog:"
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
+ }