platform-types 1.10.765 → 1.10.767
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/account.d.ts +70 -6
- package/dist/cjs/notification.js +9 -1
- package/dist/cjs/order.js +17 -1
- package/dist/invoice.d.ts +26 -0
- package/dist/notification.d.ts +57 -1
- package/dist/notification.js +8 -0
- package/dist/order.d.ts +71 -2
- package/dist/order.js +17 -1
- package/package.json +1 -1
package/dist/account.d.ts
CHANGED
|
@@ -324,8 +324,11 @@ declare global {
|
|
|
324
324
|
* `DATE_RANGE_INCOMPLETE`) before format (`DATE_MALFORMED`) before semantics
|
|
325
325
|
* (`DATE_RANGE_INVERTED`, `DATE_RANGE_TOO_WIDE`).
|
|
326
326
|
*
|
|
327
|
-
* ⚠️ The storefront twin
|
|
328
|
-
*
|
|
327
|
+
* ⚠️ The storefront twin reads no `from`/`to`, having no store-wide branch
|
|
328
|
+
* to window. Its `GET /account` returns `DATE_MALFORMED` (for `date` or
|
|
329
|
+
* `until`) and `DATE_RANGE_INVERTED` (`until` before `date`). The storefront
|
|
330
|
+
* `GET /orders` and `GET /invoices` return the same two codes, for `until`
|
|
331
|
+
* only (see {@link WebOrdersQuery}, {@link WebInvoicesQuery}).
|
|
329
332
|
*/
|
|
330
333
|
type AccountDateRangeError = 'DATE_AND_RANGE_EXCLUSIVE' | 'DATE_RANGE_INCOMPLETE' | 'DATE_MALFORMED' | 'DATE_RANGE_INVERTED' | 'DATE_RANGE_TOO_WIDE';
|
|
331
334
|
/**
|
|
@@ -345,13 +348,15 @@ declare global {
|
|
|
345
348
|
* - `INVALID_CURSOR` — **400.** The `?startKey=` did not decode, or decoded to
|
|
346
349
|
* a cursor for another store or another customer, one whose own key sits
|
|
347
350
|
* outside the statement's key range at either end, or one whose pins do not
|
|
348
|
-
* hold. ⚠️ **There are
|
|
351
|
+
* hold. ⚠️ **There are THREE pins.** `balanceDate` must not be absent,
|
|
349
352
|
* non-numeric or raised past the cursor's own key; `date` must EQUAL the
|
|
350
353
|
* `?date=` of the request spending the cursor, because it is the boundary
|
|
351
354
|
* both statement reads are split on — changing it mid-walk would read the
|
|
352
355
|
* same rows through a different filter and silently skip or repeat every row
|
|
353
|
-
* the move crossed
|
|
354
|
-
*
|
|
356
|
+
* the move crossed; and `until` must EQUAL the request's `?until=`, or the
|
|
357
|
+
* open-end sentinel `99991231` when the request sends none (a cursor minted
|
|
358
|
+
* before `until` existed carries no such pin and is refused once). A client
|
|
359
|
+
* that wants a different window starts a new walk with no cursor. ⚠️ Never
|
|
355
360
|
* "restart from page one" on this: a client cannot tell a silent restart
|
|
356
361
|
* from a legitimate first page, so a paging loop re-reads from the top and
|
|
357
362
|
* appends every row twice. Discard the cursor and ask the user.
|
|
@@ -367,6 +372,56 @@ declare global {
|
|
|
367
372
|
* computes no sum.
|
|
368
373
|
*/
|
|
369
374
|
type AccountStatementError = 'INVALID_CURSOR' | 'CUSTOMER_LEDGER_TRUNCATED';
|
|
375
|
+
/**
|
|
376
|
+
* How the storefront statement PDF (`GET /account?mode=pdf`) can REFUSE,
|
|
377
|
+
* beyond {@link AccountDateRangeError} (same window validation as the JSON
|
|
378
|
+
* page) and `CUSTOMER_LEDGER_TRUNCATED` (the same 503 envelope). Neither
|
|
379
|
+
* prints a partial PDF — a statement with missing rows prints wrong running
|
|
380
|
+
* balances.
|
|
381
|
+
*
|
|
382
|
+
* - `ACCOUNT_STATEMENT_PDF_TOO_LONG` — **422.** More movements than one PDF
|
|
383
|
+
* prints (3000), the server's drain budget ran out before the walk ended,
|
|
384
|
+
* or too little time was left to render before the 29 s gateway ceiling.
|
|
385
|
+
* The shopper fixes it by narrowing `date`/`until`; no operator ERROR row.
|
|
386
|
+
* - `ACCOUNT_STATEMENT_PDF_INCOMPLETE` — **503.** Rows are missing that no
|
|
387
|
+
* cursor can fetch (the JSON page's `incomplete`), the store's ledger
|
|
388
|
+
* currency could not be read, or (defensively — no path to it is known) a
|
|
389
|
+
* cursor the server's own drain minted was refused on resume. The shopper cannot fix it. The operator sees one
|
|
390
|
+
* deduplicated ERROR row per cause per customer per day
|
|
391
|
+
* (`ACCOUNT_STATEMENT_PDF_INCOMPLETE#{cause}#{customerId}`) — except the
|
|
392
|
+
* legacy bare-row cut, already recorded as
|
|
393
|
+
* `ACCOUNT_BARE_ROWS_TRUNCATED#{customerId}` by the statement read itself.
|
|
394
|
+
* Expected, not a crash: a client should not report it as an exception.
|
|
395
|
+
*/
|
|
396
|
+
type AccountStatementPdfError = 'ACCOUNT_STATEMENT_PDF_TOO_LONG' | 'ACCOUNT_STATEMENT_PDF_INCOMPLETE';
|
|
397
|
+
/**
|
|
398
|
+
* The query string of the storefront `GET /account` (CUSTOMER token). The
|
|
399
|
+
* customer is the token's, never a query value.
|
|
400
|
+
*
|
|
401
|
+
* An EMPTY value is the same as an absent one.
|
|
402
|
+
*/
|
|
403
|
+
interface WebAccountQuery {
|
|
404
|
+
/**
|
|
405
|
+
* `YYYYMMDD`, Buenos Aires. The opening-balance boundary: "Saldo anterior"
|
|
406
|
+
* is the balance before midnight of this day, and movements WRITTEN from
|
|
407
|
+
* then on are listed. Defaults to today. Every front end sends `19700101`
|
|
408
|
+
* for the whole ledger.
|
|
409
|
+
*/
|
|
410
|
+
date?: string;
|
|
411
|
+
/** The previous page's `LastEvaluatedKey`. See {@link AccountStatementPaging}. */
|
|
412
|
+
startKey?: string;
|
|
413
|
+
/**
|
|
414
|
+
* `YYYYMMDD`, Buenos Aires, INCLUSIVE: movements written through
|
|
415
|
+
* 23:59:59.999 of this day are listed, later ones are not. Absent means
|
|
416
|
+
* open-ended. It bounds only the listed half — the opening balance is
|
|
417
|
+
* unchanged — so the closing figure is the balance as of the end of `until`.
|
|
418
|
+
* Rows are windowed by when they were WRITTEN (`createdAt`), as for `date`.
|
|
419
|
+
* `400 DATE_MALFORMED` if not a real calendar day; `400 DATE_RANGE_INVERTED`
|
|
420
|
+
* if before `date` (`until === date` is one day). No span cap. Pinned in the
|
|
421
|
+
* cursor: repeat it on every page.
|
|
422
|
+
*/
|
|
423
|
+
until?: string;
|
|
424
|
+
}
|
|
370
425
|
/**
|
|
371
426
|
* How a customer statement PAGES.
|
|
372
427
|
*
|
|
@@ -386,11 +441,20 @@ declare global {
|
|
|
386
441
|
* - It also pins `date`, so **every page of one walk must be requested with
|
|
387
442
|
* the same `?date=`**. A different one is `400 INVALID_CURSOR`, not a
|
|
388
443
|
* re-anchored page: `date` is the boundary both reads are split on.
|
|
444
|
+
* - And it pins `until` (storefront only), so **every page of one walk
|
|
445
|
+
* repeats the same `?until=`** — or none, on every page. A change is
|
|
446
|
+
* `400 INVALID_CURSOR`.
|
|
389
447
|
* - ⚠️ **A page may be EMPTY and still carry a cursor.** The listing read has
|
|
390
448
|
* a page budget and a wall-clock budget, and it can spend either on rows the
|
|
391
|
-
* `
|
|
449
|
+
* `createdAt` filter discards before it matches anything. An empty page beside a
|
|
392
450
|
* `LastEvaluatedKey` means "keep paging", never "drained" — the cursor's
|
|
393
451
|
* ABSENCE is the only end-of-walk signal.
|
|
452
|
+
* - ⚠️ **`?mode=pdf` does not page.** The storefront `GET /account?mode=pdf`
|
|
453
|
+
* drains the whole window server-side from page one (`?startKey=` is
|
|
454
|
+
* ignored) and answers `{ data: 'data:application/pdf;base64,…' }` — the
|
|
455
|
+
* envelope of the order and invoice PDFs — or one of
|
|
456
|
+
* {@link AccountStatementPdfError}. Any other `mode`, absent included, is
|
|
457
|
+
* the JSON page described here.
|
|
394
458
|
* - A cursor is bound to its STORE and its CUSTOMER and cannot be spent
|
|
395
459
|
* against either another. It is **not** bound to the surface: an
|
|
396
460
|
* operator-minted cursor is spendable on the storefront and vice versa,
|
package/dist/cjs/notification.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NotificationTypeEnum = void 0;
|
|
3
|
+
exports.WEB_NOTIFICATIONS_MAX_LIMIT = exports.CUSTOMER_NOTIFICATION_TYPES = exports.NotificationTypeEnum = void 0;
|
|
4
4
|
// Canonical notification taxonomy and keys for legacy/type × channel preferences.
|
|
5
5
|
// Indexed producers resolve candidates through `getNotificationSubscribers`:
|
|
6
6
|
// legacy opt-ins and explicit channel maps remain source data on USER rows.
|
|
@@ -200,3 +200,11 @@ var NotificationTypeEnum;
|
|
|
200
200
|
*/
|
|
201
201
|
NotificationTypeEnum["PAYMENT_ATTEMPT_RESOLUTION"] = "PAYMENT_ATTEMPT_RESOLUTION";
|
|
202
202
|
})(NotificationTypeEnum || (exports.NotificationTypeEnum = NotificationTypeEnum = {}));
|
|
203
|
+
/**
|
|
204
|
+
* The notification types a CUSTOMER bell can carry today; each links through
|
|
205
|
+
* `orderId`. Adding one means a new {@link CustomerNotification} member with its
|
|
206
|
+
* own link field — the storefront maps type → route from this list.
|
|
207
|
+
*/
|
|
208
|
+
exports.CUSTOMER_NOTIFICATION_TYPES = [NotificationTypeEnum.ORDER];
|
|
209
|
+
/** Web `GET /notifications` page ceiling and default (`?Limit=`). */
|
|
210
|
+
exports.WEB_NOTIFICATIONS_MAX_LIMIT = 500;
|
package/dist/cjs/order.js
CHANGED
|
@@ -372,12 +372,26 @@ exports.orderFulfilmentProgress = orderFulfilmentProgress;
|
|
|
372
372
|
* Storefront checkout carries `data: {}` and refuses before the cart read.
|
|
373
373
|
*
|
|
374
374
|
* Storefront checkout business refusals. None allocates an order
|
|
375
|
-
* id, redeems a coupon or writes an order; none is logged as an error
|
|
375
|
+
* id, redeems a coupon or writes an order; none is logged as an error —
|
|
376
|
+
* except `CART_CHANGED_SINCE_CONFIRM` refused at commit, as its entry says:
|
|
376
377
|
* - `DELIVERY_METHOD_NOT_FOUND` · 400 — `deliveryMethod` is not in the store's
|
|
377
378
|
* delivery catalogue, including an absent/empty catalogue. `data: {}`;
|
|
378
379
|
* refused before reading the cart.
|
|
379
380
|
* - `ORDER_INVALID_CART` · 400 — the normalized cart has no finite numeric
|
|
380
381
|
* `totals.grandTotal`. `data: {}`; refused before repricing/allocation.
|
|
382
|
+
* - `CART_CHANGED_SINCE_CONFIRM` · 409 — the body sent `expectedCartId` /
|
|
383
|
+
* `expectedCartVersion` and the stored cart is not the cart the shopper
|
|
384
|
+
* confirmed (gone, replaced by another `cartId`, or at another `version`);
|
|
385
|
+
* `data` is `CartChangedSinceConfirmData` and carries no cart. Distinct from
|
|
386
|
+
* `ORDER_INVALID_CART` (a non-finite total) and from the operator's
|
|
387
|
+
* `CART_REVISION_STALE` / `CART_VERSION_*` (whose `data.basket` keeps
|
|
388
|
+
* `cost`). Decided at TWO points: right after the server's cart read, with
|
|
389
|
+
* nothing written and nothing logged; and at the commit, when the cart moved
|
|
390
|
+
* between the read and the write — then no order committed, but the order id
|
|
391
|
+
* allocated before the commit is consumed, a coupon redeemed before the
|
|
392
|
+
* commit is not released, and an ERROR row is logged.
|
|
393
|
+
* Re-read the cart and confirm again under a new `Idempotency-Key`; on
|
|
394
|
+
* `currentCartVersion: null` check the shopper's orders first.
|
|
381
395
|
* - `ORDER_BELOW_MINIMUM_PURCHASE` · 400 — after repricing has confirmed the
|
|
382
396
|
* cart, its grand total is below a finite positive `Number(customer.minBuy)`.
|
|
383
397
|
* Equality passes. `data: OrderBelowMinimumPurchaseData` carries minBuy,
|
|
@@ -638,6 +652,8 @@ exports.ORDER_ERROR_CODES = [
|
|
|
638
652
|
'DELIVERY_METHOD_NOT_FOUND',
|
|
639
653
|
'ORDER_BELOW_MINIMUM_PURCHASE',
|
|
640
654
|
'ORDER_INVALID_CART',
|
|
655
|
+
// The storefront's confirmed-cart pin (`StorefrontOrderCreateRequest.expectedCartId` / `expectedCartVersion`).
|
|
656
|
+
'CART_CHANGED_SINCE_CONFIRM',
|
|
641
657
|
'EMAIL_VERIFICATION_REQUIRED',
|
|
642
658
|
'ACCOUNT_DISABLED',
|
|
643
659
|
'CUSTOMER_ACCESS_PENDING',
|
package/dist/invoice.d.ts
CHANGED
|
@@ -54,6 +54,32 @@ declare global {
|
|
|
54
54
|
/** The AUTHORITATIVE amount, as declared — never re-derived from `baseImp × alic`. */
|
|
55
55
|
importe: number;
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* The query string of the storefront `GET /invoices` (CUSTOMER token): the
|
|
59
|
+
* shopper's own authorized invoices, newest first. The customer is the
|
|
60
|
+
* token's, never a query value.
|
|
61
|
+
*/
|
|
62
|
+
interface WebInvoicesQuery {
|
|
63
|
+
/**
|
|
64
|
+
* `YYYYMMDD` lower bound on the voucher's `dated`, inclusive. Defaults to
|
|
65
|
+
* one Buenos Aires calendar month before today, the day clamped to that
|
|
66
|
+
* month's last day (31 Mar → 28/29 Feb). Shape-checked only.
|
|
67
|
+
*/
|
|
68
|
+
since?: string;
|
|
69
|
+
/** Rows READ per page, 1–1000 (default 1000). A page may come back short or empty beside a cursor. */
|
|
70
|
+
Limit?: string;
|
|
71
|
+
/** The previous page's `LastEvaluatedKey` (a raw sort key, not pinned to `since`/`until`). */
|
|
72
|
+
offSet?: string;
|
|
73
|
+
/**
|
|
74
|
+
* `YYYYMMDD` upper bound on `dated`, INCLUSIVE. Absent or empty means
|
|
75
|
+
* open-ended. `400 DATE_MALFORMED` if not a real calendar day;
|
|
76
|
+
* `400 DATE_RANGE_INVERTED` if before `since`. A tight window makes short
|
|
77
|
+
* and empty pages beside a cursor more frequent — the cursor stays the only
|
|
78
|
+
* keep-paging signal. Changing it mid-walk re-filters the remaining rows;
|
|
79
|
+
* restart the walk instead.
|
|
80
|
+
*/
|
|
81
|
+
until?: string;
|
|
82
|
+
}
|
|
57
83
|
interface Invoice extends CurrencyRateProvenance {
|
|
58
84
|
storeId: string;
|
|
59
85
|
invoiceId: string;
|
package/dist/notification.d.ts
CHANGED
|
@@ -179,6 +179,14 @@ export declare enum NotificationTypeEnum {
|
|
|
179
179
|
*/
|
|
180
180
|
PAYMENT_ATTEMPT_RESOLUTION = "PAYMENT_ATTEMPT_RESOLUTION"
|
|
181
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* The notification types a CUSTOMER bell can carry today; each links through
|
|
184
|
+
* `orderId`. Adding one means a new {@link CustomerNotification} member with its
|
|
185
|
+
* own link field — the storefront maps type → route from this list.
|
|
186
|
+
*/
|
|
187
|
+
export declare const CUSTOMER_NOTIFICATION_TYPES: readonly [NotificationTypeEnum.ORDER];
|
|
188
|
+
/** Web `GET /notifications` page ceiling and default (`?Limit=`). */
|
|
189
|
+
export declare const WEB_NOTIFICATIONS_MAX_LIMIT = 500;
|
|
182
190
|
declare global {
|
|
183
191
|
type CustomerNotificationPreferences = Partial<Record<'reminder-scheduled' | 'appointment-reminder', {
|
|
184
192
|
email: boolean;
|
|
@@ -241,6 +249,7 @@ declare global {
|
|
|
241
249
|
createdAt: number;
|
|
242
250
|
type: NotificationTypeEnum;
|
|
243
251
|
title: string;
|
|
252
|
+
/** `ORDER` links through `orderId` on both audiences (operator and customer). */
|
|
244
253
|
orderId?: string;
|
|
245
254
|
productId?: string;
|
|
246
255
|
lotId?: string;
|
|
@@ -305,7 +314,8 @@ declare global {
|
|
|
305
314
|
};
|
|
306
315
|
/**
|
|
307
316
|
* `GET /notifications` body on the operator host — the caller's own
|
|
308
|
-
* notifications, newest first, projected through an allow-list.
|
|
317
|
+
* notifications, newest first, projected through an allow-list. Operator
|
|
318
|
+
* host only; the web leg is {@link WebGetNotificationsResponse}.
|
|
309
319
|
*
|
|
310
320
|
* ⚠️ There is no `hasMore` on this leg: the ABSENCE of `LastEvaluatedKey` is
|
|
311
321
|
* the end of the list. A client that waits for a `hasMore: false` never stops
|
|
@@ -337,6 +347,52 @@ declare global {
|
|
|
337
347
|
hasMore: boolean;
|
|
338
348
|
};
|
|
339
349
|
}
|
|
350
|
+
type CustomerNotificationType = (typeof CUSTOMER_NOTIFICATION_TYPES)[number];
|
|
351
|
+
/**
|
|
352
|
+
* The customer projection: what web `GET`/`POST /notifications` and the
|
|
353
|
+
* customer socket carry — the stored row minus the operator-only pointers.
|
|
354
|
+
* A union keyed on `type`; `ORDER` is its only member today.
|
|
355
|
+
*/
|
|
356
|
+
type CustomerNotification = Omit<NotificationInterface, 'cartRef' | 'pendingCustomerRef' | 'TableName' | 'type' | 'orderId'> & {
|
|
357
|
+
type: NotificationTypeEnum.ORDER;
|
|
358
|
+
/** Set on every customer row: the order the bell is about. */
|
|
359
|
+
orderId: string;
|
|
360
|
+
};
|
|
361
|
+
/**
|
|
362
|
+
* Web `GET /notifications`: the caller's own rows, newest first by
|
|
363
|
+
* `createdAt`. An `offSet` outside the caller's own key range is
|
|
364
|
+
* `400 INVALID_CURSOR`; one inside it resumes from that position, whether
|
|
365
|
+
* or not a row with that id still exists.
|
|
366
|
+
*/
|
|
367
|
+
interface WebGetNotificationsResponse {
|
|
368
|
+
message: string;
|
|
369
|
+
data: CustomerNotification[];
|
|
370
|
+
/** The last row's `notificationId`; send it back as `?offSet=`. Absent = end of list. */
|
|
371
|
+
LastEvaluatedKey?: string;
|
|
372
|
+
}
|
|
373
|
+
/** Web `POST /notifications` (single, or `all: true`). */
|
|
374
|
+
interface WebPostNotificationsResponse {
|
|
375
|
+
message: string;
|
|
376
|
+
data: CustomerNotification[];
|
|
377
|
+
/** `all: true` only. */
|
|
378
|
+
updatedCount?: number;
|
|
379
|
+
/** `all: true` only — `true` means call again. */
|
|
380
|
+
hasMore?: boolean;
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Customer socket frames, action `notifications`: one row as it is now
|
|
384
|
+
* stored (its `read` is the stored value, so a mark-unread reads `false`), or
|
|
385
|
+
* the mark-all summary.
|
|
386
|
+
*/
|
|
387
|
+
type CustomerNotificationFrame = CustomerNotification | {
|
|
388
|
+
storeId: string;
|
|
389
|
+
customerId: string;
|
|
390
|
+
bulkRead: true;
|
|
391
|
+
updatedCount: number;
|
|
392
|
+
hasMore: boolean;
|
|
393
|
+
/** Every row this call marked read (their `notificationId`); patch these, no refetch needed. */
|
|
394
|
+
notificationIds: string[];
|
|
395
|
+
};
|
|
340
396
|
/**
|
|
341
397
|
* What the outbound seam (`notify()`) knew about one call the moment its
|
|
342
398
|
* transport returned. It is never a delivery receipt: `enqueued` and
|
package/dist/notification.js
CHANGED
|
@@ -197,3 +197,11 @@ export var NotificationTypeEnum;
|
|
|
197
197
|
*/
|
|
198
198
|
NotificationTypeEnum["PAYMENT_ATTEMPT_RESOLUTION"] = "PAYMENT_ATTEMPT_RESOLUTION";
|
|
199
199
|
})(NotificationTypeEnum || (NotificationTypeEnum = {}));
|
|
200
|
+
/**
|
|
201
|
+
* The notification types a CUSTOMER bell can carry today; each links through
|
|
202
|
+
* `orderId`. Adding one means a new {@link CustomerNotification} member with its
|
|
203
|
+
* own link field — the storefront maps type → route from this list.
|
|
204
|
+
*/
|
|
205
|
+
export const CUSTOMER_NOTIFICATION_TYPES = [NotificationTypeEnum.ORDER];
|
|
206
|
+
/** Web `GET /notifications` page ceiling and default (`?Limit=`). */
|
|
207
|
+
export const WEB_NOTIFICATIONS_MAX_LIMIT = 500;
|
package/dist/order.d.ts
CHANGED
|
@@ -435,6 +435,24 @@ declare global {
|
|
|
435
435
|
province?: string;
|
|
436
436
|
phone?: string;
|
|
437
437
|
}
|
|
438
|
+
/**
|
|
439
|
+
* The query string of the storefront `GET /orders` (CUSTOMER token). The
|
|
440
|
+
* customer is the token's, never a query value.
|
|
441
|
+
*/
|
|
442
|
+
interface WebOrdersQuery {
|
|
443
|
+
/** `YYYYMMDD` lower bound on `deliveredDate`, inclusive. Defaults to today (Buenos Aires). */
|
|
444
|
+
date?: string;
|
|
445
|
+
/** A point read of one of the caller's own orders; `date`/`until` are ignored. */
|
|
446
|
+
orderId?: string;
|
|
447
|
+
/**
|
|
448
|
+
* `YYYYMMDD` upper bound on `deliveredDate`, INCLUSIVE. Absent or empty
|
|
449
|
+
* means open-ended. `400 DATE_MALFORMED` if not a real calendar day;
|
|
450
|
+
* `400 DATE_RANGE_INVERTED` if before `date` (so send both — `date`
|
|
451
|
+
* defaults to today). ⚠️ It never hides PENDING orders: they carry no
|
|
452
|
+
* delivery day to window and are always returned, whatever the window.
|
|
453
|
+
*/
|
|
454
|
+
until?: string;
|
|
455
|
+
}
|
|
438
456
|
interface Order extends CurrencyRateProvenance, CurrencyRateFreshness {
|
|
439
457
|
storeId: string;
|
|
440
458
|
orderId: string;
|
|
@@ -2137,6 +2155,24 @@ declare global {
|
|
|
2137
2155
|
*/
|
|
2138
2156
|
basket: Cart | null;
|
|
2139
2157
|
}
|
|
2158
|
+
/**
|
|
2159
|
+
* `data` of the storefront's `409 CART_CHANGED_SINCE_CONFIRM` — a web
|
|
2160
|
+
* `POST /orders` that sent {@link StorefrontOrderCreateRequest.expectedCartId}
|
|
2161
|
+
* or {@link StorefrontOrderCreateRequest.expectedCartVersion} against a cart
|
|
2162
|
+
* that is no longer the one the shopper confirmed. It carries no cart: re-read
|
|
2163
|
+
* it (`GET /basket`) and confirm again under a NEW `Idempotency-Key`.
|
|
2164
|
+
*/
|
|
2165
|
+
interface CartChangedSinceConfirmData {
|
|
2166
|
+
/**
|
|
2167
|
+
* The confirmed cart's stored `version` as the server now reads it — a
|
|
2168
|
+
* row with no stored `version` reads as `0`. `null` when the confirmed cart
|
|
2169
|
+
* is no longer the stored cart: it is gone, or a different cart replaced
|
|
2170
|
+
* it. ⚠️ On `null` the order may already exist (the confirmed cart is
|
|
2171
|
+
* deleted by its own checkout), so check the shopper's orders before
|
|
2172
|
+
* letting them retry.
|
|
2173
|
+
*/
|
|
2174
|
+
currentCartVersion: number | null;
|
|
2175
|
+
}
|
|
2140
2176
|
/**
|
|
2141
2177
|
* `data` of `409 CART_CUSTOMER_MISMATCH` — a create that sent
|
|
2142
2178
|
* {@link CreateOrderRequest.expectedCartVersion} for a cart that carries a
|
|
@@ -2358,6 +2394,25 @@ declare global {
|
|
|
2358
2394
|
};
|
|
2359
2395
|
/** Persist `deliveryAddress` as the customer's default. Directive only, never stored. */
|
|
2360
2396
|
saveAsDefault?: boolean;
|
|
2397
|
+
/**
|
|
2398
|
+
* The `cartId` of the cart the shopper confirmed (`CART` + 6-10 digits).
|
|
2399
|
+
* Omit it ONLY when that cart had none (a legacy cart). ⚠️ Compared
|
|
2400
|
+
* together with {@link expectedCartVersion} as ONE cart identity: a body
|
|
2401
|
+
* sending the version without this field means "the cart I confirmed had
|
|
2402
|
+
* no `cartId`", so a stored cart that has one is refused. A checkout
|
|
2403
|
+
* deletes its cart and the next add mints a NEW `cartId` at `version: 1`,
|
|
2404
|
+
* so a version alone does not identify a cart — always send this when the
|
|
2405
|
+
* rendered cart has one. A mismatch is `409 CART_CHANGED_SINCE_CONFIRM`.
|
|
2406
|
+
*/
|
|
2407
|
+
expectedCartId?: string;
|
|
2408
|
+
/**
|
|
2409
|
+
* The `version` of the cart the shopper confirmed, an integer ≥ 1. Omit it
|
|
2410
|
+
* when that cart had none. Refused `409 CART_CHANGED_SINCE_CONFIRM` when
|
|
2411
|
+
* the stored cart's version (absent reads as `0`) differs, and re-asserted
|
|
2412
|
+
* at the commit, so a write between the server's read and the order
|
|
2413
|
+
* transaction refuses too.
|
|
2414
|
+
*/
|
|
2415
|
+
expectedCartVersion?: number;
|
|
2361
2416
|
}
|
|
2362
2417
|
interface ZebraTag {
|
|
2363
2418
|
orderId: string;
|
|
@@ -2730,12 +2785,26 @@ export declare const orderFulfilmentProgress: (order: OrderFulfilmentProgressInp
|
|
|
2730
2785
|
* Storefront checkout carries `data: {}` and refuses before the cart read.
|
|
2731
2786
|
*
|
|
2732
2787
|
* Storefront checkout business refusals. None allocates an order
|
|
2733
|
-
* id, redeems a coupon or writes an order; none is logged as an error
|
|
2788
|
+
* id, redeems a coupon or writes an order; none is logged as an error —
|
|
2789
|
+
* except `CART_CHANGED_SINCE_CONFIRM` refused at commit, as its entry says:
|
|
2734
2790
|
* - `DELIVERY_METHOD_NOT_FOUND` · 400 — `deliveryMethod` is not in the store's
|
|
2735
2791
|
* delivery catalogue, including an absent/empty catalogue. `data: {}`;
|
|
2736
2792
|
* refused before reading the cart.
|
|
2737
2793
|
* - `ORDER_INVALID_CART` · 400 — the normalized cart has no finite numeric
|
|
2738
2794
|
* `totals.grandTotal`. `data: {}`; refused before repricing/allocation.
|
|
2795
|
+
* - `CART_CHANGED_SINCE_CONFIRM` · 409 — the body sent `expectedCartId` /
|
|
2796
|
+
* `expectedCartVersion` and the stored cart is not the cart the shopper
|
|
2797
|
+
* confirmed (gone, replaced by another `cartId`, or at another `version`);
|
|
2798
|
+
* `data` is `CartChangedSinceConfirmData` and carries no cart. Distinct from
|
|
2799
|
+
* `ORDER_INVALID_CART` (a non-finite total) and from the operator's
|
|
2800
|
+
* `CART_REVISION_STALE` / `CART_VERSION_*` (whose `data.basket` keeps
|
|
2801
|
+
* `cost`). Decided at TWO points: right after the server's cart read, with
|
|
2802
|
+
* nothing written and nothing logged; and at the commit, when the cart moved
|
|
2803
|
+
* between the read and the write — then no order committed, but the order id
|
|
2804
|
+
* allocated before the commit is consumed, a coupon redeemed before the
|
|
2805
|
+
* commit is not released, and an ERROR row is logged.
|
|
2806
|
+
* Re-read the cart and confirm again under a new `Idempotency-Key`; on
|
|
2807
|
+
* `currentCartVersion: null` check the shopper's orders first.
|
|
2739
2808
|
* - `ORDER_BELOW_MINIMUM_PURCHASE` · 400 — after repricing has confirmed the
|
|
2740
2809
|
* cart, its grand total is below a finite positive `Number(customer.minBuy)`.
|
|
2741
2810
|
* Equality passes. `data: OrderBelowMinimumPurchaseData` carries minBuy,
|
|
@@ -2873,6 +2942,6 @@ export declare const orderFulfilmentProgress: (order: OrderFulfilmentProgressInp
|
|
|
2873
2942
|
* `SUBSCRIPTION_READONLY`) sit on the order CREATE leg only: an edit is not a new
|
|
2874
2943
|
* order, so `bareOrderPostHandler` routes past `requireMetered` entirely.
|
|
2875
2944
|
*/
|
|
2876
|
-
export declare const ORDER_ERROR_CODES: readonly ["ORDER_COST_DENOMINATION_UNKNOWN", "SERVICE_ORDER_DELIVERY_MANAGED", "ORDER_NOT_FOUND", "ORDER_LOCKED", "ORDER_NOT_READY", "ORDER_DELIVERED_ANOTHER_DAY", "ORDER_DELIVERY_STATE_UNCHANGED", "ORDER_ILLEGAL_TRANSITION", "ORDER_VERSION_CONFLICT", "CUSTOMER_NOT_FOUND", "CUSTOMER_MERGED", "ORDER_HAS_NO_CUSTOMER", "CUSTOMER_ANONYMIZED", "FX_CONVERSION_UNAVAILABLE", "ROLE_FORBIDDEN", "ORDER_CANCELLED", "PAYMENT_SETTLED_ON_ANOTHER_ORDER", "ORDER_HAS_SHIPMENTS", "ORDER_HAS_RETURNS", "SHIPMENT_QUANTITY_EXCEEDED", "SHIPMENT_LINE_MISMATCH", "SHIPMENT_NOT_FOUND", "SHIPMENT_LIMIT_REACHED", "SHIPMENT_TOO_LARGE", "ORDER_FULFILMENT_EXTERNAL", "SHIPMENT_FAILED", "ADMIN_REQUIRED", "IDEMPOTENCY_KEY_REQUIRED", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSE", "IDEMPOTENCY_IN_PROGRESS", "IDEMPOTENCY_LOCK_CONTENTION", "IDEMPOTENCY_KEY_FAILED", "IDEMPOTENT_RESPONSE_NOT_CACHED", "ORDER_CANCELLATION_NOT_PROTECTED", "ORDER_CANCELLATION_COMMITTED", "ORDER_CANCELLATION_LOCKED", "ORDER_CANCELLATION_TOO_LARGE", "ORDER_CANCELLATION_FAILED", "SALE_LEDGER_RETRACTION_REFUSED", "SALE_LEDGER_ROW_NOT_OWNED", "PRODUCT_NOT_FOUND", "PRODUCT_SALE_LIMIT_EXCEEDED", "PRODUCT_SALE_LIMIT_INVALID", "DEPOSIT_SOURCE_NOT_ALLOWED", "DEPOSIT_CURRENCY_MISMATCH", "DEPOSIT_EXCEEDS_TOTAL", "DEPOSIT_FREEZE_REQUIRES_INVOICE", "DEPOSIT_FREEZE_INVOICE_PENDING", "DEPOSIT_CHARACTERIZATION_CONFLICT", "DEPOSIT_FREEZE_INVOICE_NOT_QUALIFYING", "DEPOSIT_INVOICED_ORDER_MUST_FREEZE", "DEPOSIT_FROZEN_ORDER_MUST_FREEZE", "DEPOSIT_REFERENCE_IS_LINKED_PAYMENT", "DEPOSIT_DUPLICATE_REFERENCE", "TILL_TENDER_REQUIRES_DEPOSIT", "PAYMENT_REFERENCED_BY_DEPOSIT", "ORDER_HAS_UNREFUNDED_DEPOSIT", "ORDER_PRICE_FROZEN", "DEPOSIT_NOT_FOUND", "DEPOSIT_ALREADY_REFUNDED", "UNIT_QUANTITY_NOT_WHOLE", "UNIT_REVISION_STALE", "UNIT_QUANTITY_UNREPRESENTABLE", "KIT_RECIPE_CHANGED", "CART_PROMOTION_UNAVAILABLE", "ORDER_HAS_KIT_LINES", "ORDER_TARGET_REQUIRED", "ORDER_SOURCE_CONFLICT", "ORDER_CUSTOMER_REQUIRED", "BASKET_EMPTY", "BASKET_CHANGED_DURING_CHECKOUT", "CART_VERSION_CREATE_ONLY", "CART_VERSION_REQUIRES_CART_ID", "CART_REVISION_STALE", "CART_CUSTOMER_MISMATCH", "COUNTER_SALE_CREATE_ONLY", "SOLD_AT_CREATE_ONLY", "SOLD_AT_IN_FUTURE", "ORDER_TENDER_CREATE_ONLY", "CREDIT_OVERRIDE_CREATE_ONLY", "ON_ACCOUNT_CREATE_ONLY", "ON_ACCOUNT_WITH_TENDERS", "TENDERS_REQUIRE_COUNTER_SALE", "LINES_REQUIRE_COUNTER_SALE", "PRODUCT_COST_UNKNOWN", "PRICE_CHANGE_DISABLED", "LINE_DISCOUNT_EXCEEDS_MAX", "CUSTOMER_DISABLED", "SHIFT_NOT_AVAILABLE", "SOLD_AT_OUTSIDE_SHIFT", "ORDER_CURRENCY_NOT_SUBSCRIBED", "PAYMENT_METHODS_NOT_CONFIGURED", "PAYMENT_METHOD_NOT_FOUND", "PAYMENT_METHOD_UNAVAILABLE", "CART_PRICES_CHANGED", "ORDER_ID_COLLISION", "DELIVERY_METHOD_NOT_FOUND", "ORDER_BELOW_MINIMUM_PURCHASE", "ORDER_INVALID_CART", "EMAIL_VERIFICATION_REQUIRED", "ACCOUNT_DISABLED", "CUSTOMER_ACCESS_PENDING", "CUSTOMER_ACCESS_REJECTED", "CURRENCY_MISMATCH", "SHIFT_NOT_OPEN", "ORDER_DISCOUNT_AFTER_INVOICE", "ORDER_DISCOUNT_ON_SERVICE_ORDER", "ORDER_DISCOUNT_ON_MARKETPLACE_ORDER", "ORDER_INVOICE_METHOD_OUTSTANDING_FACTURA", "ORDER_SERVICE_PERIOD_AFTER_INVOICE", "ORDER_ATTEMPT_COMMITTED", "ORDER_ATTEMPT_ABANDONED", "ORDER_ATTEMPT_KEY_EXPIRED", "ORDER_ATTEMPT_KEY_SCOPE_MISMATCH", "ORDER_COMPLETION_ATTEMPT_COMMITTED", "ORDER_COMPLETION_ATTEMPT_ABANDONED"];
|
|
2945
|
+
export declare const ORDER_ERROR_CODES: readonly ["ORDER_COST_DENOMINATION_UNKNOWN", "SERVICE_ORDER_DELIVERY_MANAGED", "ORDER_NOT_FOUND", "ORDER_LOCKED", "ORDER_NOT_READY", "ORDER_DELIVERED_ANOTHER_DAY", "ORDER_DELIVERY_STATE_UNCHANGED", "ORDER_ILLEGAL_TRANSITION", "ORDER_VERSION_CONFLICT", "CUSTOMER_NOT_FOUND", "CUSTOMER_MERGED", "ORDER_HAS_NO_CUSTOMER", "CUSTOMER_ANONYMIZED", "FX_CONVERSION_UNAVAILABLE", "ROLE_FORBIDDEN", "ORDER_CANCELLED", "PAYMENT_SETTLED_ON_ANOTHER_ORDER", "ORDER_HAS_SHIPMENTS", "ORDER_HAS_RETURNS", "SHIPMENT_QUANTITY_EXCEEDED", "SHIPMENT_LINE_MISMATCH", "SHIPMENT_NOT_FOUND", "SHIPMENT_LIMIT_REACHED", "SHIPMENT_TOO_LARGE", "ORDER_FULFILMENT_EXTERNAL", "SHIPMENT_FAILED", "ADMIN_REQUIRED", "IDEMPOTENCY_KEY_REQUIRED", "INVALID_IDEMPOTENCY_KEY", "IDEMPOTENCY_KEY_REUSE", "IDEMPOTENCY_IN_PROGRESS", "IDEMPOTENCY_LOCK_CONTENTION", "IDEMPOTENCY_KEY_FAILED", "IDEMPOTENT_RESPONSE_NOT_CACHED", "ORDER_CANCELLATION_NOT_PROTECTED", "ORDER_CANCELLATION_COMMITTED", "ORDER_CANCELLATION_LOCKED", "ORDER_CANCELLATION_TOO_LARGE", "ORDER_CANCELLATION_FAILED", "SALE_LEDGER_RETRACTION_REFUSED", "SALE_LEDGER_ROW_NOT_OWNED", "PRODUCT_NOT_FOUND", "PRODUCT_SALE_LIMIT_EXCEEDED", "PRODUCT_SALE_LIMIT_INVALID", "DEPOSIT_SOURCE_NOT_ALLOWED", "DEPOSIT_CURRENCY_MISMATCH", "DEPOSIT_EXCEEDS_TOTAL", "DEPOSIT_FREEZE_REQUIRES_INVOICE", "DEPOSIT_FREEZE_INVOICE_PENDING", "DEPOSIT_CHARACTERIZATION_CONFLICT", "DEPOSIT_FREEZE_INVOICE_NOT_QUALIFYING", "DEPOSIT_INVOICED_ORDER_MUST_FREEZE", "DEPOSIT_FROZEN_ORDER_MUST_FREEZE", "DEPOSIT_REFERENCE_IS_LINKED_PAYMENT", "DEPOSIT_DUPLICATE_REFERENCE", "TILL_TENDER_REQUIRES_DEPOSIT", "PAYMENT_REFERENCED_BY_DEPOSIT", "ORDER_HAS_UNREFUNDED_DEPOSIT", "ORDER_PRICE_FROZEN", "DEPOSIT_NOT_FOUND", "DEPOSIT_ALREADY_REFUNDED", "UNIT_QUANTITY_NOT_WHOLE", "UNIT_REVISION_STALE", "UNIT_QUANTITY_UNREPRESENTABLE", "KIT_RECIPE_CHANGED", "CART_PROMOTION_UNAVAILABLE", "ORDER_HAS_KIT_LINES", "ORDER_TARGET_REQUIRED", "ORDER_SOURCE_CONFLICT", "ORDER_CUSTOMER_REQUIRED", "BASKET_EMPTY", "BASKET_CHANGED_DURING_CHECKOUT", "CART_VERSION_CREATE_ONLY", "CART_VERSION_REQUIRES_CART_ID", "CART_REVISION_STALE", "CART_CUSTOMER_MISMATCH", "COUNTER_SALE_CREATE_ONLY", "SOLD_AT_CREATE_ONLY", "SOLD_AT_IN_FUTURE", "ORDER_TENDER_CREATE_ONLY", "CREDIT_OVERRIDE_CREATE_ONLY", "ON_ACCOUNT_CREATE_ONLY", "ON_ACCOUNT_WITH_TENDERS", "TENDERS_REQUIRE_COUNTER_SALE", "LINES_REQUIRE_COUNTER_SALE", "PRODUCT_COST_UNKNOWN", "PRICE_CHANGE_DISABLED", "LINE_DISCOUNT_EXCEEDS_MAX", "CUSTOMER_DISABLED", "SHIFT_NOT_AVAILABLE", "SOLD_AT_OUTSIDE_SHIFT", "ORDER_CURRENCY_NOT_SUBSCRIBED", "PAYMENT_METHODS_NOT_CONFIGURED", "PAYMENT_METHOD_NOT_FOUND", "PAYMENT_METHOD_UNAVAILABLE", "CART_PRICES_CHANGED", "ORDER_ID_COLLISION", "DELIVERY_METHOD_NOT_FOUND", "ORDER_BELOW_MINIMUM_PURCHASE", "ORDER_INVALID_CART", "CART_CHANGED_SINCE_CONFIRM", "EMAIL_VERIFICATION_REQUIRED", "ACCOUNT_DISABLED", "CUSTOMER_ACCESS_PENDING", "CUSTOMER_ACCESS_REJECTED", "CURRENCY_MISMATCH", "SHIFT_NOT_OPEN", "ORDER_DISCOUNT_AFTER_INVOICE", "ORDER_DISCOUNT_ON_SERVICE_ORDER", "ORDER_DISCOUNT_ON_MARKETPLACE_ORDER", "ORDER_INVOICE_METHOD_OUTSTANDING_FACTURA", "ORDER_SERVICE_PERIOD_AFTER_INVOICE", "ORDER_ATTEMPT_COMMITTED", "ORDER_ATTEMPT_ABANDONED", "ORDER_ATTEMPT_KEY_EXPIRED", "ORDER_ATTEMPT_KEY_SCOPE_MISMATCH", "ORDER_COMPLETION_ATTEMPT_COMMITTED", "ORDER_COMPLETION_ATTEMPT_ABANDONED"];
|
|
2877
2946
|
export type OrderErrorCode = (typeof ORDER_ERROR_CODES)[number];
|
|
2878
2947
|
export {};
|
package/dist/order.js
CHANGED
|
@@ -365,12 +365,26 @@ export const orderFulfilmentProgress = (order) => {
|
|
|
365
365
|
* Storefront checkout carries `data: {}` and refuses before the cart read.
|
|
366
366
|
*
|
|
367
367
|
* Storefront checkout business refusals. None allocates an order
|
|
368
|
-
* id, redeems a coupon or writes an order; none is logged as an error
|
|
368
|
+
* id, redeems a coupon or writes an order; none is logged as an error —
|
|
369
|
+
* except `CART_CHANGED_SINCE_CONFIRM` refused at commit, as its entry says:
|
|
369
370
|
* - `DELIVERY_METHOD_NOT_FOUND` · 400 — `deliveryMethod` is not in the store's
|
|
370
371
|
* delivery catalogue, including an absent/empty catalogue. `data: {}`;
|
|
371
372
|
* refused before reading the cart.
|
|
372
373
|
* - `ORDER_INVALID_CART` · 400 — the normalized cart has no finite numeric
|
|
373
374
|
* `totals.grandTotal`. `data: {}`; refused before repricing/allocation.
|
|
375
|
+
* - `CART_CHANGED_SINCE_CONFIRM` · 409 — the body sent `expectedCartId` /
|
|
376
|
+
* `expectedCartVersion` and the stored cart is not the cart the shopper
|
|
377
|
+
* confirmed (gone, replaced by another `cartId`, or at another `version`);
|
|
378
|
+
* `data` is `CartChangedSinceConfirmData` and carries no cart. Distinct from
|
|
379
|
+
* `ORDER_INVALID_CART` (a non-finite total) and from the operator's
|
|
380
|
+
* `CART_REVISION_STALE` / `CART_VERSION_*` (whose `data.basket` keeps
|
|
381
|
+
* `cost`). Decided at TWO points: right after the server's cart read, with
|
|
382
|
+
* nothing written and nothing logged; and at the commit, when the cart moved
|
|
383
|
+
* between the read and the write — then no order committed, but the order id
|
|
384
|
+
* allocated before the commit is consumed, a coupon redeemed before the
|
|
385
|
+
* commit is not released, and an ERROR row is logged.
|
|
386
|
+
* Re-read the cart and confirm again under a new `Idempotency-Key`; on
|
|
387
|
+
* `currentCartVersion: null` check the shopper's orders first.
|
|
374
388
|
* - `ORDER_BELOW_MINIMUM_PURCHASE` · 400 — after repricing has confirmed the
|
|
375
389
|
* cart, its grand total is below a finite positive `Number(customer.minBuy)`.
|
|
376
390
|
* Equality passes. `data: OrderBelowMinimumPurchaseData` carries minBuy,
|
|
@@ -631,6 +645,8 @@ export const ORDER_ERROR_CODES = [
|
|
|
631
645
|
'DELIVERY_METHOD_NOT_FOUND',
|
|
632
646
|
'ORDER_BELOW_MINIMUM_PURCHASE',
|
|
633
647
|
'ORDER_INVALID_CART',
|
|
648
|
+
// The storefront's confirmed-cart pin (`StorefrontOrderCreateRequest.expectedCartId` / `expectedCartVersion`).
|
|
649
|
+
'CART_CHANGED_SINCE_CONFIRM',
|
|
634
650
|
'EMAIL_VERIFICATION_REQUIRED',
|
|
635
651
|
'ACCOUNT_DISABLED',
|
|
636
652
|
'CUSTOMER_ACCESS_PENDING',
|