@asteby/storefront 0.9.0 → 0.10.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 CHANGED
@@ -65,6 +65,30 @@ const me = storefront.withCustomerToken(token) // sends X-Customer-Token
65
65
  await me.customer.orders()
66
66
  ```
67
67
 
68
+ Stores that also offer email + password accounts ask what the store supports and
69
+ then use the password routes (the `StorefrontError` codes are `unauthorized` for
70
+ wrong credentials or codes, `conflict` for an email already registered and
71
+ `rate_limited` for too many attempts):
72
+
73
+ ```ts
74
+ const caps = await storefront.customer.capabilities()
75
+ // { password: boolean, email_verification: boolean, otp_channels: ('email' | 'whatsapp')[] }
76
+
77
+ const res = await storefront.customer.register({ email, password, first_name, last_name })
78
+ const session =
79
+ res.status === 'created'
80
+ ? res.session // no verification required: already signed in
81
+ : await storefront.customer.verifyRegistration({ email, code }) // code from the email
82
+
83
+ const again = await storefront.customer.loginWithPassword({ email, password })
84
+
85
+ // Signed-in buyer sets or changes the password (current_password when it already has one):
86
+ await storefront.customer.setPassword({ password, current_password }, { customerToken: session.token })
87
+
88
+ // Forgot password: requestOtp({ email }) emails a code, then
89
+ await storefront.customer.resetPassword({ email, code, password })
90
+ ```
91
+
68
92
  Checkout always sends an `Idempotency-Key` (generated with
69
93
  `crypto.randomUUID()` unless you pass `{ idempotencyKey }`):
70
94
 
@@ -118,6 +142,14 @@ Mock behaviour:
118
142
  - Checkout: returns a fake order and a `redirect_url`, decrements stock and
119
143
  honours `Idempotency-Key`.
120
144
  - Buyer: OTP code `000000`; seed customer `cliente@example.com` with one order.
145
+ - Password accounts: `customer.capabilities()` is configurable
146
+ (`createMockStorefront({ customerCapabilities })`, default
147
+ `{ password: true, email_verification: true, otp_channels: ['email'] }`).
148
+ `register` answers `verification_required` and the code is `000000`; accounts
149
+ live in memory (passwords of 10-128 characters); `409` for a registered email,
150
+ `401` for wrong credentials/codes, `429` after `maxLoginAttempts` (5) failed
151
+ logins, `403` when `password` is disabled. The seed customer has no password
152
+ until `setPassword` (or `resetPassword` with the OTP code).
121
153
  - Content: theme tokens, `home` page (hero, product_grid, collection_list,
122
154
  rich_text, faq), `main` and `footer` menus, legal pages (`terminos`,
123
155
  `privacidad`, `devoluciones`) and two articles. `?preview=` returns a draft.
@@ -291,7 +323,7 @@ over language) and `hreflangLinks` for per-market SEO.
291
323
  Resources: `shop.get`, `products.list/get/recommendations`,
292
324
  `collections.list/get`, `stock.get`,
293
325
  `carts.create/get/addLines/updateLines/removeLines/setDiscountCodes/setBuyer/setShippingAddress/deliveryOptions/setDelivery/checkout`,
294
- `customer.requestOtp/createSession/get/orders/order/requestReturn/requestInvoice/addresses.{list,create,update,delete}`,
326
+ `customer.requestOtp/createSession/capabilities/register/verifyRegistration/loginWithPassword/setPassword/resetPassword/get/orders/order/requestReturn/requestInvoice/addresses.{list,create,update,delete}`,
295
327
  `content.theme/page/menu/articles/article`. Every method takes a last
296
328
  `options` argument: `{ cache, signal, next, headers, timeoutMs, customerToken, clientIp }`
297
329
  (plus `idempotencyKey` on writes and `preview` on pages/articles); unknown keys
package/dist/index.cjs CHANGED
@@ -382,6 +382,24 @@ function createStorefrontClient(config) {
382
382
  requestOtp: (identifier, options) => write("POST", "/storefront/customer/otp", identifier, options),
383
383
  /** Exchanges the code for a buyer session (`token` goes in `customerToken`). */
384
384
  createSession: (input, options) => write("POST", "/storefront/customer/session", input, options),
385
+ /** What the store supports (password login, email verification, OTP channels). Drives which forms to show. */
386
+ capabilities: (options) => get("/storefront/customer/capabilities", void 0, options),
387
+ /**
388
+ * Creates an account with email + password. `verification_required` (202): a code was emailed, finish with
389
+ * `verifyRegistration`. `created` (201): the account exists and `session` is ready. `409` when the email is taken.
390
+ */
391
+ register: async (input, options) => {
392
+ const res = await write("POST", "/storefront/customer/register", input, options);
393
+ return res && "token" in res ? { status: "created", session: res } : { status: "verification_required" };
394
+ },
395
+ /** Confirms the emailed registration code and returns the new buyer session. */
396
+ verifyRegistration: (input, options) => write("POST", "/storefront/customer/register/verify", input, options),
397
+ /** Email + password login. `401` for wrong credentials. */
398
+ loginWithPassword: (input, options) => write("POST", "/storefront/customer/login", input, options),
399
+ /** Sets or changes the password of the signed-in buyer (`options.customerToken`, or a `withCustomerToken` client). */
400
+ setPassword: (input, options) => write("PUT", "/storefront/customer/password", input, options),
401
+ /** Resets a forgotten password with the code from `requestOtp({ email })`. */
402
+ resetPassword: (input, options) => write("POST", "/storefront/customer/password/reset", input, options),
385
403
  get: (options) => get("/storefront/customer", void 0, options),
386
404
  orders: (params, options) => get("/storefront/customer/orders", params, options),
387
405
  /** `null` when the order does not exist or belongs to someone else. */