platform-types 1.10.835 → 1.10.837
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/cjs/customer.js +4 -1
- package/dist/cjs/guestOrderStatus.js +21 -8
- package/dist/cjs/store.js +64 -2
- package/dist/cjs/subscription.js +1 -0
- package/dist/customer.d.ts +60 -2
- package/dist/customer.js +2 -0
- package/dist/guestOrderStatus.d.ts +49 -7
- package/dist/guestOrderStatus.js +20 -7
- package/dist/paymentAttempt.d.ts +12 -0
- package/dist/print.d.ts +18 -0
- package/dist/store.d.ts +139 -3
- package/dist/store.js +62 -1
- package/dist/subscription.d.ts +2 -2
- package/dist/subscription.js +1 -0
- package/package.json +1 -1
package/dist/cjs/customer.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CUSTOMER_DISCOUNT_MAX = exports.CUSTOMER_ACQUISITION_CHANNELS = exports.CUSTOMER_LIFECYCLE_STAGES = exports.CUSTOMER_KINDS = void 0;
|
|
3
|
+
exports.isWhatsappNoticesOptedIn = exports.CUSTOMER_DISCOUNT_MAX = exports.CUSTOMER_ACQUISITION_CHANNELS = exports.CUSTOMER_LIFECYCLE_STAGES = exports.CUSTOMER_KINDS = void 0;
|
|
4
4
|
exports.CUSTOMER_KINDS = ['person', 'company'];
|
|
5
5
|
exports.CUSTOMER_LIFECYCLE_STAGES = ['lead', 'active', 'inactive'];
|
|
6
6
|
exports.CUSTOMER_ACQUISITION_CHANNELS = ['storefront', 'pos', 'marketplace', 'import', 'manual'];
|
|
@@ -11,3 +11,6 @@ exports.CUSTOMER_ACQUISITION_CHANNELS = ['storefront', 'pos', 'marketplace', 'im
|
|
|
11
11
|
* `discount` unchanged (or omits it) still saves.
|
|
12
12
|
*/
|
|
13
13
|
exports.CUSTOMER_DISCOUNT_MAX = 50;
|
|
14
|
+
/** Whether `notices` records a standing transactional WhatsApp opt-in: `optIn` present and `optOut` absent. */
|
|
15
|
+
const isWhatsappNoticesOptedIn = (notices) => notices?.optIn !== undefined && notices.optOut === undefined;
|
|
16
|
+
exports.isWhatsappNoticesOptedIn = isWhatsappNoticesOptedIn;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Guest order status link — the
|
|
4
|
-
*
|
|
5
|
-
* link to the address stored on the order.
|
|
3
|
+
* Guest order status link — the page a buyer with no account opens from the
|
|
4
|
+
* order email (`/pedido/{token}`), the one consent it can give there, and the
|
|
5
|
+
* route that mails a fresh link to the address stored on the order.
|
|
6
6
|
*
|
|
7
|
-
* The token (`gs1.…`) is a bearer credential over exactly ONE order
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* The token (`gs1.…`) is a bearer credential over exactly ONE order. It
|
|
8
|
+
* authorises the read and exactly ONE write: the transactional WhatsApp consent
|
|
9
|
+
* grant for the order's own customer in that store
|
|
10
|
+
* (`POST /orders/status/whatsapp-opt-in`, {@link GuestOrderWhatsappOptInRequest}).
|
|
11
|
+
* Nothing else — no cart write, payment, cancellation, withdrawal or export.
|
|
12
|
+
* Both routes authorise it identically. It carries no expiry; it is refused
|
|
13
|
+
* once the order was delivered (or cancelled) more than `guestStatusLinkDaysAfterDelivery` days ago — unless a
|
|
11
14
|
* purchase withdrawal on it is not final or a refund on it is not closed — and
|
|
12
15
|
* every earlier link dies when a recovery or an operator revokes it.
|
|
13
16
|
*
|
|
@@ -16,7 +19,7 @@
|
|
|
16
19
|
* code mailed to the order's address, so the token still authorises none.
|
|
17
20
|
*/
|
|
18
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.GUEST_ORDER_STATUS_LINK_TEMPLATE = exports.GUEST_ORDER_STATUS_ERROR_CODES = void 0;
|
|
22
|
+
exports.GUEST_ORDER_STATUS_LINK_TEMPLATE = exports.GUEST_ORDER_WHATSAPP_OPT_IN_ERROR_CODES = exports.GUEST_ORDER_STATUS_ERROR_CODES = void 0;
|
|
20
23
|
/**
|
|
21
24
|
* The refusals the guest status routes answer themselves.
|
|
22
25
|
*
|
|
@@ -28,5 +31,15 @@ exports.GUEST_ORDER_STATUS_LINK_TEMPLATE = exports.GUEST_ORDER_STATUS_ERROR_CODE
|
|
|
28
31
|
* `POST /orders/status/recover`.
|
|
29
32
|
*/
|
|
30
33
|
exports.GUEST_ORDER_STATUS_ERROR_CODES = ['GUEST_STATUS_TOKEN_INVALID'];
|
|
34
|
+
/**
|
|
35
|
+
* The refusals `POST /orders/status/whatsapp-opt-in` answers itself, past the
|
|
36
|
+
* token (which refuses `GUEST_STATUS_TOKEN_INVALID` exactly as the read does).
|
|
37
|
+
*
|
|
38
|
+
* - WHATSAPP_OPT_IN_UNAVAILABLE (409): the offer does not hold for this order —
|
|
39
|
+
* the store's messaging is unavailable, the order is cancelled, delivered or
|
|
40
|
+
* disabled, carries no phone, or its customer row is no longer live. Nothing
|
|
41
|
+
* is written. One code for every reason.
|
|
42
|
+
*/
|
|
43
|
+
exports.GUEST_ORDER_WHATSAPP_OPT_IN_ERROR_CODES = ['WHATSAPP_OPT_IN_UNAVAILABLE'];
|
|
31
44
|
/** The transactional email template that mails a guest their (new) status link. */
|
|
32
45
|
exports.GUEST_ORDER_STATUS_LINK_TEMPLATE = 'guest-order-status-link';
|
package/dist/cjs/store.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CHANGE_OF_MIND_WINDOW_SOURCE = exports.CHANGE_OF_MIND_RETURN_DAYS_MAX = exports.CHANGE_OF_MIND_REFUND_AS = exports.CHANGE_OF_MIND_RETURN_SHIPPING_PAYERS = exports.STORE_PATCH_ERROR_CODES = exports.STORE_MODULE_ERROR_CODES = exports.isStoreModuleOn = exports.isStoreModuleKey = exports.STORE_MODULE_KEYS = exports.STOREFRONT_METHOD_KINDS = exports.STORE_ONBOARDING_REVIEW_AREAS = exports.CUSTOM_DOMAIN_ROW_LIMIT = exports.CUSTOM_DOMAIN_SLOT_LIMIT = void 0;
|
|
3
|
+
exports.resolveStoreMessaging = exports.STORE_MESSAGING_SIGNATURE_MAX = exports.STORE_MESSAGING_DEFAULTS = exports.STORE_MESSAGE_NOTICES = exports.CHANGE_OF_MIND_WINDOW_SOURCE = exports.CHANGE_OF_MIND_RETURN_DAYS_MAX = exports.CHANGE_OF_MIND_REFUND_AS = exports.CHANGE_OF_MIND_RETURN_SHIPPING_PAYERS = exports.STORE_PATCH_ERROR_CODES = exports.STORE_MODULE_ERROR_CODES = exports.isStoreModuleOn = exports.isStoreModuleKey = exports.STORE_MODULE_KEYS = exports.STOREFRONT_METHOD_KINDS = exports.STORE_ONBOARDING_REVIEW_AREAS = exports.CUSTOM_DOMAIN_ROW_LIMIT = exports.CUSTOM_DOMAIN_SLOT_LIMIT = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* How many custom-domain rows a store may hold that count: one active domain
|
|
6
6
|
* and one spare, so a replacement can be verified and provisioned before the
|
|
@@ -112,13 +112,14 @@ exports.STORE_MODULE_ERROR_CODES = [
|
|
|
112
112
|
* Role refusals, `403` — a plain USER writing a privileged section. Each is
|
|
113
113
|
* judged before any other check on that section:
|
|
114
114
|
* - `STORE_CONFIG_FORBIDDEN` — any privileged `config` leaf (`modules`,
|
|
115
|
-
* `stock`, `priceDecimals`, `changePrice`, `mandatory2fa`, …).
|
|
115
|
+
* `stock`, `priceDecimals`, `changePrice`, `mandatory2fa`, `autoPrint`, …).
|
|
116
116
|
* - `STORE_ECOMMERCE_FORBIDDEN` — any `ecommerce` block.
|
|
117
117
|
* - `STORE_FISCAL_FIELD_FORBIDDEN` — a fiscal field of the store.
|
|
118
118
|
* - `STORE_JURISDICTION_FORBIDDEN` — `jurisdiction`.
|
|
119
119
|
* - `AFIP_RELACION_FLAG_FORBIDDEN` — `afip.wscdcEnabled` / `afip.fceEnabled`.
|
|
120
120
|
* - `FX_TABLE_FORBIDDEN` — the `currencies` exchange-rate table.
|
|
121
121
|
* - `FX_AUTO_UPDATE_FORBIDDEN` — `fxAutoUpdate`.
|
|
122
|
+
* - `STORE_MESSAGING_FORBIDDEN` — the `messaging` customer-messaging settings.
|
|
122
123
|
*
|
|
123
124
|
* Request refusals, `400`:
|
|
124
125
|
* - `FIELD_NOT_WRITABLE_HERE` — a field written through `POST /store`, not
|
|
@@ -197,6 +198,7 @@ exports.STORE_PATCH_ERROR_CODES = [
|
|
|
197
198
|
'NET_PLUS_IVA_REQUIRES_RI',
|
|
198
199
|
'DATA_FISCAL_URL_INVALID',
|
|
199
200
|
'STORE_PUBLIC_HOST_MISSING',
|
|
201
|
+
'STORE_MESSAGING_FORBIDDEN',
|
|
200
202
|
'FORBIDDEN',
|
|
201
203
|
'STORE_NOT_FOUND',
|
|
202
204
|
];
|
|
@@ -208,3 +210,63 @@ exports.CHANGE_OF_MIND_REFUND_AS = ['refund', 'store-credit'];
|
|
|
208
210
|
exports.CHANGE_OF_MIND_RETURN_DAYS_MAX = 365;
|
|
209
211
|
/** The source of a change-of-mind deadline: the store's own setting, not a statutory row. */
|
|
210
212
|
exports.CHANGE_OF_MIND_WINDOW_SOURCE = 'store:changeOfMindReturns';
|
|
213
|
+
/**
|
|
214
|
+
* Every `StoreMessageNotice`, in the order the settings screen lists them —
|
|
215
|
+
* the keys `Store.integrations.messaging` switches. `UncoveredStoreMessageNotices`
|
|
216
|
+
* fails `typecheck` naming a notice the union gains and this tuple lacks.
|
|
217
|
+
*/
|
|
218
|
+
exports.STORE_MESSAGE_NOTICES = [
|
|
219
|
+
'orderReady',
|
|
220
|
+
'orderShipped',
|
|
221
|
+
'serviceOrderReceived',
|
|
222
|
+
'serviceOrderQuoted',
|
|
223
|
+
'serviceOrderApproved',
|
|
224
|
+
'serviceOrderReady',
|
|
225
|
+
'serviceOrderCancelled',
|
|
226
|
+
'serviceOrderReturnedUnrepaired',
|
|
227
|
+
'serviceOrderAbandoned',
|
|
228
|
+
'serviceOrderOnHold',
|
|
229
|
+
'serviceOrderResumed',
|
|
230
|
+
'appointmentReminder',
|
|
231
|
+
'paymentReminder',
|
|
232
|
+
];
|
|
233
|
+
/**
|
|
234
|
+
* What an ABSENT `messaging` key reads: status notices and appointment
|
|
235
|
+
* reminders on, payment reminders off, the SMS fallback on.
|
|
236
|
+
*/
|
|
237
|
+
exports.STORE_MESSAGING_DEFAULTS = {
|
|
238
|
+
orderReady: true,
|
|
239
|
+
orderShipped: true,
|
|
240
|
+
serviceOrderReceived: true,
|
|
241
|
+
serviceOrderQuoted: true,
|
|
242
|
+
serviceOrderApproved: true,
|
|
243
|
+
serviceOrderReady: true,
|
|
244
|
+
serviceOrderCancelled: true,
|
|
245
|
+
serviceOrderReturnedUnrepaired: true,
|
|
246
|
+
serviceOrderAbandoned: true,
|
|
247
|
+
serviceOrderOnHold: true,
|
|
248
|
+
serviceOrderResumed: true,
|
|
249
|
+
appointmentReminder: true,
|
|
250
|
+
paymentReminder: false,
|
|
251
|
+
smsFallback: true,
|
|
252
|
+
};
|
|
253
|
+
/** The firma cap — the same one `sms.signature` has. */
|
|
254
|
+
exports.STORE_MESSAGING_SIGNATURE_MAX = 80;
|
|
255
|
+
/**
|
|
256
|
+
* Every switch of a store's messaging settings, decided: per key, the stored
|
|
257
|
+
* boolean, else its `STORE_MESSAGING_DEFAULTS` value (a stored non-boolean
|
|
258
|
+
* reads as absent). `signature` falls back to `sms.signature` only when
|
|
259
|
+
* `messaging.signature` is absent; a stored `''` is kept and means no firma.
|
|
260
|
+
*/
|
|
261
|
+
const resolveStoreMessaging = (integrations) => {
|
|
262
|
+
const leaf = integrations?.messaging;
|
|
263
|
+
const resolved = { ...exports.STORE_MESSAGING_DEFAULTS };
|
|
264
|
+
for (const key of [...exports.STORE_MESSAGE_NOTICES, 'smsFallback']) {
|
|
265
|
+
const stored = leaf?.[key];
|
|
266
|
+
if (typeof stored === 'boolean')
|
|
267
|
+
resolved[key] = stored;
|
|
268
|
+
}
|
|
269
|
+
const signature = typeof leaf?.signature === 'string' ? leaf.signature : integrations?.sms?.signature;
|
|
270
|
+
return typeof signature === 'string' ? { ...resolved, signature } : resolved;
|
|
271
|
+
};
|
|
272
|
+
exports.resolveStoreMessaging = resolveStoreMessaging;
|
package/dist/cjs/subscription.js
CHANGED
package/dist/customer.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ export declare const CUSTOMER_ACQUISITION_CHANNELS: readonly ["storefront", "pos
|
|
|
8
8
|
* `discount` unchanged (or omits it) still saves.
|
|
9
9
|
*/
|
|
10
10
|
export declare const CUSTOMER_DISCOUNT_MAX = 50;
|
|
11
|
+
/** Whether `notices` records a standing transactional WhatsApp opt-in: `optIn` present and `optOut` absent. */
|
|
12
|
+
export declare const isWhatsappNoticesOptedIn: (notices: CustomerWhatsappNotices | undefined) => boolean;
|
|
11
13
|
declare global {
|
|
12
14
|
/** Exact identity matches within the token's store; no stored identity fields are returned. */
|
|
13
15
|
interface CustomerDuplicateCandidate {
|
|
@@ -95,8 +97,62 @@ declare global {
|
|
|
95
97
|
/** Per-customer, not per-channel — one unsubscribe link covers every channel. */
|
|
96
98
|
unsubscribeToken?: string;
|
|
97
99
|
}
|
|
98
|
-
/**
|
|
99
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Where a transactional WhatsApp grant or withdrawal was given:
|
|
102
|
+
* `back-office` (staff, `POST /customers`), `storefront-post-purchase` (the
|
|
103
|
+
* one-tap offer after an order is placed — the signed-in banner through web
|
|
104
|
+
* `POST /user` with `whatsappOptInOrigin: 'post-purchase'`, or a guest's
|
|
105
|
+
* `POST /orders/status/whatsapp-opt-in`) and `storefront-profile` (the
|
|
106
|
+
* shopper's own profile toggle, web `POST /user`).
|
|
107
|
+
*/
|
|
108
|
+
type WhatsappNoticeSource = 'back-office' | 'storefront-post-purchase' | 'storefront-profile';
|
|
109
|
+
/**
|
|
110
|
+
* Provenance of one transactional WhatsApp grant or withdrawal.
|
|
111
|
+
* Server-written only. Carries NO phone number and NO IP, unlike
|
|
112
|
+
* `ChannelConsentStamp` (deliberately not extended), and not who acted.
|
|
113
|
+
*/
|
|
114
|
+
interface WhatsappNoticeStamp {
|
|
115
|
+
/** ms epoch. */
|
|
116
|
+
ts: number;
|
|
117
|
+
source: WhatsappNoticeSource;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* `Customer.whatsappNotices`: the customer's consent to the store's
|
|
121
|
+
* transactional WhatsApp notices (order and service-order status,
|
|
122
|
+
* reminders). Per customer per store, since the CUSTOMER row is
|
|
123
|
+
* store-scoped. Separate from `CustomerMarketing`, and never marketing
|
|
124
|
+
* consent.
|
|
125
|
+
*
|
|
126
|
+
* Opted in ⇔ `optIn` present AND `optOut` absent; read it through
|
|
127
|
+
* `isWhatsappNoticesOptedIn`. A grant SETs `optIn` and REMOVEs `optOut`; a
|
|
128
|
+
* withdrawal SETs `optOut` and keeps `optIn`. Resending the current state
|
|
129
|
+
* changes nothing and does not re-stamp; a withdrawal from a customer who
|
|
130
|
+
* never opted in is recorded. Not a history: it holds the latest grant and
|
|
131
|
+
* the latest withdrawal only. ⚠️ Absent is NOT consent.
|
|
132
|
+
*/
|
|
133
|
+
interface CustomerWhatsappNotices {
|
|
134
|
+
optIn?: WhatsappNoticeStamp;
|
|
135
|
+
optOut?: WhatsappNoticeStamp;
|
|
136
|
+
}
|
|
137
|
+
/** Write shape: `whatsappNotices` is server-owned, and `whatsappOptIn` is the directive that moves it. */
|
|
138
|
+
type CustomerUpsertInput = Partial<Omit<Customer, 'whatsappNotices'>> & PhotoUploadControls & {
|
|
139
|
+
/**
|
|
140
|
+
* `POST /customers` (source `back-office`) and web `POST /user` (source
|
|
141
|
+
* `storefront-profile`): `true` grants, `false` withdraws, absent changes
|
|
142
|
+
* nothing. Never stored. Staff MAY grant, because this is not marketing
|
|
143
|
+
* consent. A storefront grant acts only while `Store.messagingAvailable`
|
|
144
|
+
* holds and is otherwise dropped; a withdrawal always acts.
|
|
145
|
+
*/
|
|
146
|
+
whatsappOptIn?: boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Web `POST /user` only: `'post-purchase'` names the grant as the one-tap
|
|
149
|
+
* offer after an order (`whatsappOptInOffer` on the order read), so the
|
|
150
|
+
* stamp's source is `storefront-post-purchase` instead of
|
|
151
|
+
* `storefront-profile`. A directive, never stored, and ignored unless
|
|
152
|
+
* `whatsappOptIn` is `true`.
|
|
153
|
+
*/
|
|
154
|
+
whatsappOptInOrigin?: 'post-purchase';
|
|
155
|
+
};
|
|
100
156
|
/**
|
|
101
157
|
* The query string of the customers LIST read — `GET /customers` with no
|
|
102
158
|
* `customerId`, `list` or `email`. Every present filter AND-composes: a row is
|
|
@@ -568,6 +624,8 @@ declare global {
|
|
|
568
624
|
*/
|
|
569
625
|
mergeBalanceCarried?: boolean;
|
|
570
626
|
marketing?: CustomerMarketing;
|
|
627
|
+
/** Transactional WhatsApp consent for this store — see `CustomerWhatsappNotices`. Server-written. */
|
|
628
|
+
whatsappNotices?: CustomerWhatsappNotices;
|
|
571
629
|
/** Optional notification mail only; transactional mail cannot be disabled. */
|
|
572
630
|
notificationPreferences?: CustomerNotificationPreferences;
|
|
573
631
|
minBuy?: number;
|
package/dist/customer.js
CHANGED
|
@@ -8,3 +8,5 @@ export const CUSTOMER_ACQUISITION_CHANNELS = ['storefront', 'pos', 'marketplace'
|
|
|
8
8
|
* `discount` unchanged (or omits it) still saves.
|
|
9
9
|
*/
|
|
10
10
|
export const CUSTOMER_DISCOUNT_MAX = 50;
|
|
11
|
+
/** Whether `notices` records a standing transactional WhatsApp opt-in: `optIn` present and `optOut` absent. */
|
|
12
|
+
export const isWhatsappNoticesOptedIn = (notices) => notices?.optIn !== undefined && notices.optOut === undefined;
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Guest order status link — the
|
|
3
|
-
*
|
|
4
|
-
* link to the address stored on the order.
|
|
2
|
+
* Guest order status link — the page a buyer with no account opens from the
|
|
3
|
+
* order email (`/pedido/{token}`), the one consent it can give there, and the
|
|
4
|
+
* route that mails a fresh link to the address stored on the order.
|
|
5
5
|
*
|
|
6
|
-
* The token (`gs1.…`) is a bearer credential over exactly ONE order
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* The token (`gs1.…`) is a bearer credential over exactly ONE order. It
|
|
7
|
+
* authorises the read and exactly ONE write: the transactional WhatsApp consent
|
|
8
|
+
* grant for the order's own customer in that store
|
|
9
|
+
* (`POST /orders/status/whatsapp-opt-in`, {@link GuestOrderWhatsappOptInRequest}).
|
|
10
|
+
* Nothing else — no cart write, payment, cancellation, withdrawal or export.
|
|
11
|
+
* Both routes authorise it identically. It carries no expiry; it is refused
|
|
12
|
+
* once the order was delivered (or cancelled) more than `guestStatusLinkDaysAfterDelivery` days ago — unless a
|
|
10
13
|
* purchase withdrawal on it is not final or a refund on it is not closed — and
|
|
11
14
|
* every earlier link dies when a recovery or an operator revokes it.
|
|
12
15
|
*
|
|
@@ -26,6 +29,17 @@
|
|
|
26
29
|
*/
|
|
27
30
|
export declare const GUEST_ORDER_STATUS_ERROR_CODES: readonly ["GUEST_STATUS_TOKEN_INVALID"];
|
|
28
31
|
export type GuestOrderStatusErrorCode = (typeof GUEST_ORDER_STATUS_ERROR_CODES)[number];
|
|
32
|
+
/**
|
|
33
|
+
* The refusals `POST /orders/status/whatsapp-opt-in` answers itself, past the
|
|
34
|
+
* token (which refuses `GUEST_STATUS_TOKEN_INVALID` exactly as the read does).
|
|
35
|
+
*
|
|
36
|
+
* - WHATSAPP_OPT_IN_UNAVAILABLE (409): the offer does not hold for this order —
|
|
37
|
+
* the store's messaging is unavailable, the order is cancelled, delivered or
|
|
38
|
+
* disabled, carries no phone, or its customer row is no longer live. Nothing
|
|
39
|
+
* is written. One code for every reason.
|
|
40
|
+
*/
|
|
41
|
+
export declare const GUEST_ORDER_WHATSAPP_OPT_IN_ERROR_CODES: readonly ["WHATSAPP_OPT_IN_UNAVAILABLE"];
|
|
42
|
+
export type GuestOrderWhatsappOptInErrorCode = (typeof GUEST_ORDER_WHATSAPP_OPT_IN_ERROR_CODES)[number];
|
|
29
43
|
/** The transactional email template that mails a guest their (new) status link. */
|
|
30
44
|
export declare const GUEST_ORDER_STATUS_LINK_TEMPLATE: "guest-order-status-link";
|
|
31
45
|
declare global {
|
|
@@ -115,6 +129,17 @@ declare global {
|
|
|
115
129
|
returnRequests?: OrderReturnRequestView[];
|
|
116
130
|
/** Whether a return request can be opened now. Absent only when the return requests could not be read whole. */
|
|
117
131
|
returnRequestEligibility?: OrderReturnRequestEligibility;
|
|
132
|
+
/**
|
|
133
|
+
* Present, and `true`, only when the post-purchase «Avisarme por WhatsApp
|
|
134
|
+
* sobre este pedido» may be offered: the store's messaging is available
|
|
135
|
+
* (`Store.messagingAvailable`), the order is not cancelled, delivered or
|
|
136
|
+
* disabled, it carries a phone (its customer's or the guest contact's),
|
|
137
|
+
* and its customer row is live and NOT opted in
|
|
138
|
+
* (`Customer.whatsappNotices`). Accept it with
|
|
139
|
+
* `POST /orders/status/whatsapp-opt-in`. Carries no phone. Absent too when
|
|
140
|
+
* the offer could not be computed — the read never fails for it.
|
|
141
|
+
*/
|
|
142
|
+
whatsappOptInOffer?: true;
|
|
118
143
|
contact: {
|
|
119
144
|
/** The stored address, masked (e.g. `j***@d***.com`). */
|
|
120
145
|
emailMasked: string;
|
|
@@ -131,4 +156,21 @@ declare global {
|
|
|
131
156
|
orderId: string;
|
|
132
157
|
email: string;
|
|
133
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* `POST /orders/status/whatsapp-opt-in` body (strict): the guest status token
|
|
161
|
+
* of the order whose post-purchase WhatsApp offer (`whatsappOptInOffer`) is
|
|
162
|
+
* accepted. The token is authorised exactly as `GET /orders/status` does it
|
|
163
|
+
* (one `401 GUEST_STATUS_TOKEN_INVALID` for every refusal; a malformed body
|
|
164
|
+
* too). Then the grant: `200` {@link GuestOrderWhatsappOptInResult} when the
|
|
165
|
+
* customer is now opted in — freshly stamped `{ ts, source:
|
|
166
|
+
* 'storefront-post-purchase' }`, or already opted in (nothing written, never
|
|
167
|
+
* re-stamped) — else `409 WHATSAPP_OPT_IN_UNAVAILABLE`, nothing written.
|
|
168
|
+
*/
|
|
169
|
+
interface GuestOrderWhatsappOptInRequest {
|
|
170
|
+
token: string;
|
|
171
|
+
}
|
|
172
|
+
/** `data` of a `200` `POST /orders/status/whatsapp-opt-in`. */
|
|
173
|
+
interface GuestOrderWhatsappOptInResult {
|
|
174
|
+
whatsappNoticesOptedIn: true;
|
|
175
|
+
}
|
|
134
176
|
}
|
package/dist/guestOrderStatus.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Guest order status link — the
|
|
3
|
-
*
|
|
4
|
-
* link to the address stored on the order.
|
|
2
|
+
* Guest order status link — the page a buyer with no account opens from the
|
|
3
|
+
* order email (`/pedido/{token}`), the one consent it can give there, and the
|
|
4
|
+
* route that mails a fresh link to the address stored on the order.
|
|
5
5
|
*
|
|
6
|
-
* The token (`gs1.…`) is a bearer credential over exactly ONE order
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* The token (`gs1.…`) is a bearer credential over exactly ONE order. It
|
|
7
|
+
* authorises the read and exactly ONE write: the transactional WhatsApp consent
|
|
8
|
+
* grant for the order's own customer in that store
|
|
9
|
+
* (`POST /orders/status/whatsapp-opt-in`, {@link GuestOrderWhatsappOptInRequest}).
|
|
10
|
+
* Nothing else — no cart write, payment, cancellation, withdrawal or export.
|
|
11
|
+
* Both routes authorise it identically. It carries no expiry; it is refused
|
|
12
|
+
* once the order was delivered (or cancelled) more than `guestStatusLinkDaysAfterDelivery` days ago — unless a
|
|
10
13
|
* purchase withdrawal on it is not final or a refund on it is not closed — and
|
|
11
14
|
* every earlier link dies when a recovery or an operator revokes it.
|
|
12
15
|
*
|
|
@@ -25,5 +28,15 @@
|
|
|
25
28
|
* `POST /orders/status/recover`.
|
|
26
29
|
*/
|
|
27
30
|
export const GUEST_ORDER_STATUS_ERROR_CODES = ['GUEST_STATUS_TOKEN_INVALID'];
|
|
31
|
+
/**
|
|
32
|
+
* The refusals `POST /orders/status/whatsapp-opt-in` answers itself, past the
|
|
33
|
+
* token (which refuses `GUEST_STATUS_TOKEN_INVALID` exactly as the read does).
|
|
34
|
+
*
|
|
35
|
+
* - WHATSAPP_OPT_IN_UNAVAILABLE (409): the offer does not hold for this order —
|
|
36
|
+
* the store's messaging is unavailable, the order is cancelled, delivered or
|
|
37
|
+
* disabled, carries no phone, or its customer row is no longer live. Nothing
|
|
38
|
+
* is written. One code for every reason.
|
|
39
|
+
*/
|
|
40
|
+
export const GUEST_ORDER_WHATSAPP_OPT_IN_ERROR_CODES = ['WHATSAPP_OPT_IN_UNAVAILABLE'];
|
|
28
41
|
/** The transactional email template that mails a guest their (new) status link. */
|
|
29
42
|
export const GUEST_ORDER_STATUS_LINK_TEMPLATE = 'guest-order-status-link';
|
package/dist/paymentAttempt.d.ts
CHANGED
|
@@ -145,6 +145,18 @@ declare global {
|
|
|
145
145
|
returnRequests?: OrderReturnRequestView[];
|
|
146
146
|
/** Whether a return request can be opened now. Absent only when the return requests could not be read whole. */
|
|
147
147
|
returnRequestEligibility?: OrderReturnRequestEligibility;
|
|
148
|
+
/**
|
|
149
|
+
* Point read (`?orderId=`) only, never the list. Present, and `true`, only
|
|
150
|
+
* when the post-purchase «Avisarme por WhatsApp sobre este pedido» may be
|
|
151
|
+
* offered: the store's messaging is available (`Store.messagingAvailable`),
|
|
152
|
+
* the order is not cancelled, delivered or disabled, it carries a phone
|
|
153
|
+
* (`customer.phone` or the guest contact's), and the order's customer row
|
|
154
|
+
* is live and NOT opted in (`Customer.whatsappNotices`). Accept it with web
|
|
155
|
+
* `POST /user` `{ whatsappOptIn: true, whatsappOptInOrigin: 'post-purchase' }`.
|
|
156
|
+
* Carries no phone. Absent too when the offer could not be computed — the
|
|
157
|
+
* order read never fails for it.
|
|
158
|
+
*/
|
|
159
|
+
whatsappOptInOffer?: true;
|
|
148
160
|
};
|
|
149
161
|
/**
|
|
150
162
|
* `data` of an `orderPaymentAttempt` socket frame, sent to the order's own
|
package/dist/print.d.ts
CHANGED
|
@@ -560,8 +560,26 @@ declare global {
|
|
|
560
560
|
* sorted and joined by `+`; an agent `ACK_FAILED` can classify to `PRINTER_PAUSED` /
|
|
561
561
|
* `NO_PRINTER_ASSIGNED` / `PRINTER_NOT_FOUND`. Unrecognised agent
|
|
562
562
|
* text stays in `detail` only, so absence of a code does NOT mean success.
|
|
563
|
+
*
|
|
564
|
+
* An automatic job (`Store.config.autoPrint`) adds three BE-side codes on
|
|
565
|
+
* `error`: `PRINT_QUEUE_EXPIRED` — it was held for want of a connected
|
|
566
|
+
* agent and its `heldUntil` passed — `AUTO_PRINT_SOURCE_GONE` — the
|
|
567
|
+
* order or invoice it was printing no longer exists when it was replayed —
|
|
568
|
+
* and `AUTO_PRINT_NO_LONGER_ELIGIBLE` — at replay it no longer passed the
|
|
569
|
+
* checks it was minted under (the store's switch for its event is off, the
|
|
570
|
+
* order was cancelled or its ready / delivered mark cleared, the factura is
|
|
571
|
+
* a credit note), so it was never sent.
|
|
572
|
+
* A HELD job is `queued` with `NO_PRINTER_CONNECTED` and `heldUntil`.
|
|
563
573
|
*/
|
|
564
574
|
errorCode?: string;
|
|
575
|
+
/**
|
|
576
|
+
* ms epoch until which an automatic job with no connected agent is HELD —
|
|
577
|
+
* present only while the summary is `queued` waiting for an agent. The
|
|
578
|
+
* job is replayed when an agent of the store registers its printers, and
|
|
579
|
+
* ends `error` / `PRINT_QUEUE_EXPIRED` once this passes. Every later
|
|
580
|
+
* transition removes it. A manual print is never held.
|
|
581
|
+
*/
|
|
582
|
+
heldUntil?: number;
|
|
565
583
|
}
|
|
566
584
|
/**
|
|
567
585
|
* `data` payload of the server → agent `printers_active` WSS frame,
|
package/dist/store.d.ts
CHANGED
|
@@ -87,6 +87,28 @@ declare global {
|
|
|
87
87
|
/** MercadoLibre orders. */
|
|
88
88
|
mercadolibre?: string;
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* The automatic-print switches — see `Store.config.autoPrint`. Every switch is
|
|
92
|
+
* OFF unless it is `true`: an absent leaf, an absent key and `false` all mean
|
|
93
|
+
* "do not print this automatically".
|
|
94
|
+
*/
|
|
95
|
+
interface StoreAutoPrintConfig {
|
|
96
|
+
/** A factura authorised by ARCA (CAE, CAEA stamp, or the pending drain settling it). Credit notes never. */
|
|
97
|
+
invoiceAuthorized?: boolean;
|
|
98
|
+
/** A new order, per sales channel. A `service` channel order has no switch. */
|
|
99
|
+
orderCreated?: {
|
|
100
|
+
/** `POST /orders` on the App, including a presupuesto conversion. */
|
|
101
|
+
counter?: boolean;
|
|
102
|
+
/** The public storefront checkout. */
|
|
103
|
+
storefront?: boolean;
|
|
104
|
+
/** An order imported from MercadoLibre. */
|
|
105
|
+
meli?: boolean;
|
|
106
|
+
};
|
|
107
|
+
/** An order marked ready (its `readyAt` moving from unset to set). */
|
|
108
|
+
orderReady?: boolean;
|
|
109
|
+
/** The shipping tag, when an order with a delivery address is marked delivered. */
|
|
110
|
+
deliveryTag?: boolean;
|
|
111
|
+
}
|
|
90
112
|
/**
|
|
91
113
|
* One store-wide module a store can switch off for every user — the
|
|
92
114
|
* catalogue is the shared `domain/STORE_MODULES.md`. Enumerable at runtime as
|
|
@@ -276,7 +298,8 @@ declare global {
|
|
|
276
298
|
* Platform switch for store-paid customer messaging (SMS today). `false`
|
|
277
299
|
* or absent: no store-paid message is sent, and the app hides every store
|
|
278
300
|
* messaging surface. App-only (`forwardToTenants: 'app'`), so absent from
|
|
279
|
-
* the storefront's unauthenticated response
|
|
301
|
+
* the storefront's unauthenticated response: the storefront reads
|
|
302
|
+
* `Store.messagingAvailable` instead, which folds this switch in.
|
|
280
303
|
*/
|
|
281
304
|
tenantMessagingEnabled?: boolean;
|
|
282
305
|
}
|
|
@@ -612,6 +635,16 @@ declare global {
|
|
|
612
635
|
* first such removal. No request body may set it.
|
|
613
636
|
*/
|
|
614
637
|
adminRemovalGeneration?: number;
|
|
638
|
+
/**
|
|
639
|
+
* Web `GET /store` only, always a boolean on a 200: `true` when the
|
|
640
|
+
* `tenantMessagingEnabled` platform global is on and at least one
|
|
641
|
+
* `StoreMessageNotice` resolves on (`resolveStoreMessaging`). Computed when
|
|
642
|
+
* the route is read, never stored or writable. Not on `stores` frames or the
|
|
643
|
+
* preview frame, where absent reads `false`. Checkout hides «Avisarme por
|
|
644
|
+
* WhatsApp» when it is `false`, and a storefront opt-in sent while it is
|
|
645
|
+
* `false` is dropped.
|
|
646
|
+
*/
|
|
647
|
+
messagingAvailable?: boolean;
|
|
615
648
|
storeId: string;
|
|
616
649
|
createdAt: number;
|
|
617
650
|
/** Unix ms — BE-stamped on every `POST`/`PATCH /store` write. Always present on written rows. */
|
|
@@ -1135,6 +1168,24 @@ declare global {
|
|
|
1135
1168
|
* whatever this holds.
|
|
1136
1169
|
*/
|
|
1137
1170
|
channelWarehouses?: StoreChannelWarehouses;
|
|
1171
|
+
/**
|
|
1172
|
+
* Automatic printing — which events print a document with no operator
|
|
1173
|
+
* pressing «Imprimir». Written through `PATCH /store` `config` at the
|
|
1174
|
+
* PRIVILEGED tier (ADMIN/SUPERVISOR/MANAGER; a plain USER is refused
|
|
1175
|
+
* `STORE_CONFIG_FORBIDDEN`). No plan gate.
|
|
1176
|
+
*
|
|
1177
|
+
* ⚠️ The merge REPLACES the whole leaf, like every other `config` leaf: a
|
|
1178
|
+
* body carrying `autoPrint: { orderReady: true }` switches every other
|
|
1179
|
+
* event off. Send the full leaf.
|
|
1180
|
+
*
|
|
1181
|
+
* An automatic job fans out exactly as «Imprimir» does (the store's print
|
|
1182
|
+
* rules decide). When no print agent is connected it is HELD as `queued`
|
|
1183
|
+
* with `heldUntil` on its `PrintJobSummary`, replayed when an agent of the
|
|
1184
|
+
* store registers, and ended `error` / `PRINT_QUEUE_EXPIRED` at the end
|
|
1185
|
+
* of the store's Buenos Aires day or 12 h after the event, whichever is
|
|
1186
|
+
* first. Absent means nothing prints automatically.
|
|
1187
|
+
*/
|
|
1188
|
+
autoPrint?: StoreAutoPrintConfig;
|
|
1138
1189
|
/**
|
|
1139
1190
|
* Store-wide module switches — see `StoreModules`. Written through
|
|
1140
1191
|
* `PATCH /store` `config` at the PRIVILEGED tier (ADMIN/SUPERVISOR/MANAGER;
|
|
@@ -1377,7 +1428,15 @@ declare global {
|
|
|
1377
1428
|
interface StoreIntegrations {
|
|
1378
1429
|
afip?: Afip;
|
|
1379
1430
|
mercadopago?: Mercadopago;
|
|
1431
|
+
/**
|
|
1432
|
+
* Per-store SMS entitlement and firma. Kept READABLE for migration: the
|
|
1433
|
+
* app writes `messaging` instead, and `PATCH /store` still accepts `sms`
|
|
1434
|
+
* for builds that have not moved. `messaging` never reads `sms.enabled`;
|
|
1435
|
+
* it falls back to `sms.signature` only while its own `signature` is absent.
|
|
1436
|
+
*/
|
|
1380
1437
|
sms?: SmsIntegration;
|
|
1438
|
+
/** The store's customer-messaging settings — see `StoreMessagingIntegration`. */
|
|
1439
|
+
messaging?: StoreMessagingIntegration;
|
|
1381
1440
|
gmail?: Gmail;
|
|
1382
1441
|
mercadolibre?: Mercadolibre;
|
|
1383
1442
|
tiendanube?: Tiendanube;
|
|
@@ -1387,6 +1446,37 @@ declare global {
|
|
|
1387
1446
|
enabled?: boolean;
|
|
1388
1447
|
signature?: string;
|
|
1389
1448
|
}
|
|
1449
|
+
/**
|
|
1450
|
+
* One store-paid customer message a store switches on or off — one of
|
|
1451
|
+
* `STORE_MESSAGE_NOTICES`. Each maps to exactly one notice the api emits.
|
|
1452
|
+
* `orderShipped` covers dispatch (shipped and delivered); `serviceOrderQuoted`
|
|
1453
|
+
* covers the quote-sent notice and the `quoted` status fallback alike.
|
|
1454
|
+
*/
|
|
1455
|
+
type StoreMessageNotice = 'orderReady' | 'orderShipped' | 'serviceOrderReceived' | 'serviceOrderQuoted' | 'serviceOrderApproved' | 'serviceOrderReady' | 'serviceOrderCancelled' | 'serviceOrderReturnedUnrepaired' | 'serviceOrderAbandoned' | 'serviceOrderOnHold' | 'serviceOrderResumed' | 'appointmentReminder' | 'paymentReminder';
|
|
1456
|
+
/**
|
|
1457
|
+
* `Store.integrations.messaging`. Written by `PATCH /store` only (ADMIN,
|
|
1458
|
+
* SUPERVISOR, MANAGER; a PRINTER claim is refused), merged key by key, so a
|
|
1459
|
+
* body naming one switch leaves the others as stored. An absent key reads
|
|
1460
|
+
* its `STORE_MESSAGING_DEFAULTS` value: status notices and appointment
|
|
1461
|
+
* reminders on, payment reminders off, `smsFallback` on. Read it through
|
|
1462
|
+
* `resolveStoreMessaging`, never off the raw keys. Sending is gated by the
|
|
1463
|
+
* `tenantMessagingEnabled` platform global as well.
|
|
1464
|
+
*/
|
|
1465
|
+
interface StoreMessagingIntegration extends Partial<Record<StoreMessageNotice, boolean>> {
|
|
1466
|
+
/** «Si WhatsApp falla, enviar por SMS». The SMS goes out only on a WhatsApp `failed`/`undelivered` status. */
|
|
1467
|
+
smsFallback?: boolean;
|
|
1468
|
+
/**
|
|
1469
|
+
* Firma, at most 80 characters after trimming (the cap `sms.signature`
|
|
1470
|
+
* has). Absent falls back to `sms.signature`; `''` means no firma.
|
|
1471
|
+
*/
|
|
1472
|
+
signature?: string;
|
|
1473
|
+
}
|
|
1474
|
+
/** `resolveStoreMessaging`'s answer: every switch decided. */
|
|
1475
|
+
interface ResolvedStoreMessaging extends Record<StoreMessageNotice, boolean> {
|
|
1476
|
+
smsFallback: boolean;
|
|
1477
|
+
/** Absent when neither `messaging.signature` nor `sms.signature` is stored. */
|
|
1478
|
+
signature?: string;
|
|
1479
|
+
}
|
|
1390
1480
|
interface Gmail {
|
|
1391
1481
|
connected?: boolean;
|
|
1392
1482
|
senderEmail?: string;
|
|
@@ -1922,6 +2012,13 @@ declare global {
|
|
|
1922
2012
|
* still broadcasts the row as it stands.
|
|
1923
2013
|
*/
|
|
1924
2014
|
onboardingReviewAdd?: StoreOnboardingReviewArea[];
|
|
2015
|
+
/**
|
|
2016
|
+
* `PATCH /store` only (the closed `POST /store` refuses it
|
|
2017
|
+
* `FIELD_NOT_WRITABLE_HERE`). Merged key by key over the stored leaf; an
|
|
2018
|
+
* undeclared key is a 400. A plain USER is refused 403
|
|
2019
|
+
* `STORE_MESSAGING_FORBIDDEN`.
|
|
2020
|
+
*/
|
|
2021
|
+
messaging?: StoreMessagingIntegration;
|
|
1925
2022
|
}
|
|
1926
2023
|
/**
|
|
1927
2024
|
* How the storefront offers a `paymentMethods` row — one of
|
|
@@ -2592,13 +2689,14 @@ export type StoreModuleRefusalBody = {
|
|
|
2592
2689
|
* Role refusals, `403` — a plain USER writing a privileged section. Each is
|
|
2593
2690
|
* judged before any other check on that section:
|
|
2594
2691
|
* - `STORE_CONFIG_FORBIDDEN` — any privileged `config` leaf (`modules`,
|
|
2595
|
-
* `stock`, `priceDecimals`, `changePrice`, `mandatory2fa`, …).
|
|
2692
|
+
* `stock`, `priceDecimals`, `changePrice`, `mandatory2fa`, `autoPrint`, …).
|
|
2596
2693
|
* - `STORE_ECOMMERCE_FORBIDDEN` — any `ecommerce` block.
|
|
2597
2694
|
* - `STORE_FISCAL_FIELD_FORBIDDEN` — a fiscal field of the store.
|
|
2598
2695
|
* - `STORE_JURISDICTION_FORBIDDEN` — `jurisdiction`.
|
|
2599
2696
|
* - `AFIP_RELACION_FLAG_FORBIDDEN` — `afip.wscdcEnabled` / `afip.fceEnabled`.
|
|
2600
2697
|
* - `FX_TABLE_FORBIDDEN` — the `currencies` exchange-rate table.
|
|
2601
2698
|
* - `FX_AUTO_UPDATE_FORBIDDEN` — `fxAutoUpdate`.
|
|
2699
|
+
* - `STORE_MESSAGING_FORBIDDEN` — the `messaging` customer-messaging settings.
|
|
2602
2700
|
*
|
|
2603
2701
|
* Request refusals, `400`:
|
|
2604
2702
|
* - `FIELD_NOT_WRITABLE_HERE` — a field written through `POST /store`, not
|
|
@@ -2654,7 +2752,7 @@ export type StoreModuleRefusalBody = {
|
|
|
2654
2752
|
* checks, the display-currency lock, the storefront fence) are not listed
|
|
2655
2753
|
* either. Cross-cutting refusals: check `GATING_ERROR_CODES` as well.
|
|
2656
2754
|
*/
|
|
2657
|
-
export declare const STORE_PATCH_ERROR_CODES: readonly ["STORE_CONFIG_FORBIDDEN", "STORE_ECOMMERCE_FORBIDDEN", "STORE_FISCAL_FIELD_FORBIDDEN", "STORE_JURISDICTION_FORBIDDEN", "AFIP_RELACION_FLAG_FORBIDDEN", "FX_TABLE_FORBIDDEN", "FX_AUTO_UPDATE_FORBIDDEN", "FIELD_NOT_WRITABLE_HERE", "AFIP_POINT_OF_SALE_NOT_CLEARABLE", "CURRENCY_CATALOG_ID_UNKNOWN", "ARS_RATE_MUST_BE_ONE", "CURRENCY_RATE_ABOVE_CEILING", "FX_CATALOG_ID_UNKNOWN", "FX_SOURCE_ID_UNKNOWN", "DISPLAY_CURRENCY_NOT_INVOICEABLE", "PRODUCT_CURRENCY_NOT_INVOICEABLE", "PRICE_LIST_NOT_FOUND", "DELIVERY_FEE_INVALID", "WHOLESALE_LIST_REQUIRED", "NET_PLUS_IVA_REQUIRES_RI", "DATA_FISCAL_URL_INVALID", "STORE_PUBLIC_HOST_MISSING", "FORBIDDEN", "STORE_NOT_FOUND"];
|
|
2755
|
+
export declare const STORE_PATCH_ERROR_CODES: readonly ["STORE_CONFIG_FORBIDDEN", "STORE_ECOMMERCE_FORBIDDEN", "STORE_FISCAL_FIELD_FORBIDDEN", "STORE_JURISDICTION_FORBIDDEN", "AFIP_RELACION_FLAG_FORBIDDEN", "FX_TABLE_FORBIDDEN", "FX_AUTO_UPDATE_FORBIDDEN", "FIELD_NOT_WRITABLE_HERE", "AFIP_POINT_OF_SALE_NOT_CLEARABLE", "CURRENCY_CATALOG_ID_UNKNOWN", "ARS_RATE_MUST_BE_ONE", "CURRENCY_RATE_ABOVE_CEILING", "FX_CATALOG_ID_UNKNOWN", "FX_SOURCE_ID_UNKNOWN", "DISPLAY_CURRENCY_NOT_INVOICEABLE", "PRODUCT_CURRENCY_NOT_INVOICEABLE", "PRICE_LIST_NOT_FOUND", "DELIVERY_FEE_INVALID", "WHOLESALE_LIST_REQUIRED", "NET_PLUS_IVA_REQUIRES_RI", "DATA_FISCAL_URL_INVALID", "STORE_PUBLIC_HOST_MISSING", "STORE_MESSAGING_FORBIDDEN", "FORBIDDEN", "STORE_NOT_FOUND"];
|
|
2658
2756
|
export type StorePatchErrorCode = (typeof STORE_PATCH_ERROR_CODES)[number];
|
|
2659
2757
|
/** Who pays the return shipping under a store's change-of-mind policy. */
|
|
2660
2758
|
export declare const CHANGE_OF_MIND_RETURN_SHIPPING_PAYERS: readonly ["merchant", "shopper"];
|
|
@@ -2676,3 +2774,41 @@ declare global {
|
|
|
2676
2774
|
refundAs: ChangeOfMindRefundAs;
|
|
2677
2775
|
}
|
|
2678
2776
|
}
|
|
2777
|
+
/**
|
|
2778
|
+
* Every `StoreMessageNotice`, in the order the settings screen lists them —
|
|
2779
|
+
* the keys `Store.integrations.messaging` switches. `UncoveredStoreMessageNotices`
|
|
2780
|
+
* fails `typecheck` naming a notice the union gains and this tuple lacks.
|
|
2781
|
+
*/
|
|
2782
|
+
export declare const STORE_MESSAGE_NOTICES: readonly ["orderReady", "orderShipped", "serviceOrderReceived", "serviceOrderQuoted", "serviceOrderApproved", "serviceOrderReady", "serviceOrderCancelled", "serviceOrderReturnedUnrepaired", "serviceOrderAbandoned", "serviceOrderOnHold", "serviceOrderResumed", "appointmentReminder", "paymentReminder"];
|
|
2783
|
+
type AssertNoUncoveredStoreMessageNotice<T extends never> = T;
|
|
2784
|
+
export type UncoveredStoreMessageNotices = AssertNoUncoveredStoreMessageNotice<Exclude<StoreMessageNotice, (typeof STORE_MESSAGE_NOTICES)[number]>>;
|
|
2785
|
+
/**
|
|
2786
|
+
* What an ABSENT `messaging` key reads: status notices and appointment
|
|
2787
|
+
* reminders on, payment reminders off, the SMS fallback on.
|
|
2788
|
+
*/
|
|
2789
|
+
export declare const STORE_MESSAGING_DEFAULTS: {
|
|
2790
|
+
readonly orderReady: true;
|
|
2791
|
+
readonly orderShipped: true;
|
|
2792
|
+
readonly serviceOrderReceived: true;
|
|
2793
|
+
readonly serviceOrderQuoted: true;
|
|
2794
|
+
readonly serviceOrderApproved: true;
|
|
2795
|
+
readonly serviceOrderReady: true;
|
|
2796
|
+
readonly serviceOrderCancelled: true;
|
|
2797
|
+
readonly serviceOrderReturnedUnrepaired: true;
|
|
2798
|
+
readonly serviceOrderAbandoned: true;
|
|
2799
|
+
readonly serviceOrderOnHold: true;
|
|
2800
|
+
readonly serviceOrderResumed: true;
|
|
2801
|
+
readonly appointmentReminder: true;
|
|
2802
|
+
readonly paymentReminder: false;
|
|
2803
|
+
readonly smsFallback: true;
|
|
2804
|
+
};
|
|
2805
|
+
/** The firma cap — the same one `sms.signature` has. */
|
|
2806
|
+
export declare const STORE_MESSAGING_SIGNATURE_MAX = 80;
|
|
2807
|
+
/**
|
|
2808
|
+
* Every switch of a store's messaging settings, decided: per key, the stored
|
|
2809
|
+
* boolean, else its `STORE_MESSAGING_DEFAULTS` value (a stored non-boolean
|
|
2810
|
+
* reads as absent). `signature` falls back to `sms.signature` only when
|
|
2811
|
+
* `messaging.signature` is absent; a stored `''` is kept and means no firma.
|
|
2812
|
+
*/
|
|
2813
|
+
export declare const resolveStoreMessaging: (integrations: Pick<StoreIntegrations, "messaging" | "sms"> | undefined) => ResolvedStoreMessaging;
|
|
2814
|
+
export {};
|
package/dist/store.js
CHANGED
|
@@ -107,13 +107,14 @@ export const STORE_MODULE_ERROR_CODES = [
|
|
|
107
107
|
* Role refusals, `403` — a plain USER writing a privileged section. Each is
|
|
108
108
|
* judged before any other check on that section:
|
|
109
109
|
* - `STORE_CONFIG_FORBIDDEN` — any privileged `config` leaf (`modules`,
|
|
110
|
-
* `stock`, `priceDecimals`, `changePrice`, `mandatory2fa`, …).
|
|
110
|
+
* `stock`, `priceDecimals`, `changePrice`, `mandatory2fa`, `autoPrint`, …).
|
|
111
111
|
* - `STORE_ECOMMERCE_FORBIDDEN` — any `ecommerce` block.
|
|
112
112
|
* - `STORE_FISCAL_FIELD_FORBIDDEN` — a fiscal field of the store.
|
|
113
113
|
* - `STORE_JURISDICTION_FORBIDDEN` — `jurisdiction`.
|
|
114
114
|
* - `AFIP_RELACION_FLAG_FORBIDDEN` — `afip.wscdcEnabled` / `afip.fceEnabled`.
|
|
115
115
|
* - `FX_TABLE_FORBIDDEN` — the `currencies` exchange-rate table.
|
|
116
116
|
* - `FX_AUTO_UPDATE_FORBIDDEN` — `fxAutoUpdate`.
|
|
117
|
+
* - `STORE_MESSAGING_FORBIDDEN` — the `messaging` customer-messaging settings.
|
|
117
118
|
*
|
|
118
119
|
* Request refusals, `400`:
|
|
119
120
|
* - `FIELD_NOT_WRITABLE_HERE` — a field written through `POST /store`, not
|
|
@@ -192,6 +193,7 @@ export const STORE_PATCH_ERROR_CODES = [
|
|
|
192
193
|
'NET_PLUS_IVA_REQUIRES_RI',
|
|
193
194
|
'DATA_FISCAL_URL_INVALID',
|
|
194
195
|
'STORE_PUBLIC_HOST_MISSING',
|
|
196
|
+
'STORE_MESSAGING_FORBIDDEN',
|
|
195
197
|
'FORBIDDEN',
|
|
196
198
|
'STORE_NOT_FOUND',
|
|
197
199
|
];
|
|
@@ -203,3 +205,62 @@ export const CHANGE_OF_MIND_REFUND_AS = ['refund', 'store-credit'];
|
|
|
203
205
|
export const CHANGE_OF_MIND_RETURN_DAYS_MAX = 365;
|
|
204
206
|
/** The source of a change-of-mind deadline: the store's own setting, not a statutory row. */
|
|
205
207
|
export const CHANGE_OF_MIND_WINDOW_SOURCE = 'store:changeOfMindReturns';
|
|
208
|
+
/**
|
|
209
|
+
* Every `StoreMessageNotice`, in the order the settings screen lists them —
|
|
210
|
+
* the keys `Store.integrations.messaging` switches. `UncoveredStoreMessageNotices`
|
|
211
|
+
* fails `typecheck` naming a notice the union gains and this tuple lacks.
|
|
212
|
+
*/
|
|
213
|
+
export const STORE_MESSAGE_NOTICES = [
|
|
214
|
+
'orderReady',
|
|
215
|
+
'orderShipped',
|
|
216
|
+
'serviceOrderReceived',
|
|
217
|
+
'serviceOrderQuoted',
|
|
218
|
+
'serviceOrderApproved',
|
|
219
|
+
'serviceOrderReady',
|
|
220
|
+
'serviceOrderCancelled',
|
|
221
|
+
'serviceOrderReturnedUnrepaired',
|
|
222
|
+
'serviceOrderAbandoned',
|
|
223
|
+
'serviceOrderOnHold',
|
|
224
|
+
'serviceOrderResumed',
|
|
225
|
+
'appointmentReminder',
|
|
226
|
+
'paymentReminder',
|
|
227
|
+
];
|
|
228
|
+
/**
|
|
229
|
+
* What an ABSENT `messaging` key reads: status notices and appointment
|
|
230
|
+
* reminders on, payment reminders off, the SMS fallback on.
|
|
231
|
+
*/
|
|
232
|
+
export const STORE_MESSAGING_DEFAULTS = {
|
|
233
|
+
orderReady: true,
|
|
234
|
+
orderShipped: true,
|
|
235
|
+
serviceOrderReceived: true,
|
|
236
|
+
serviceOrderQuoted: true,
|
|
237
|
+
serviceOrderApproved: true,
|
|
238
|
+
serviceOrderReady: true,
|
|
239
|
+
serviceOrderCancelled: true,
|
|
240
|
+
serviceOrderReturnedUnrepaired: true,
|
|
241
|
+
serviceOrderAbandoned: true,
|
|
242
|
+
serviceOrderOnHold: true,
|
|
243
|
+
serviceOrderResumed: true,
|
|
244
|
+
appointmentReminder: true,
|
|
245
|
+
paymentReminder: false,
|
|
246
|
+
smsFallback: true,
|
|
247
|
+
};
|
|
248
|
+
/** The firma cap — the same one `sms.signature` has. */
|
|
249
|
+
export const STORE_MESSAGING_SIGNATURE_MAX = 80;
|
|
250
|
+
/**
|
|
251
|
+
* Every switch of a store's messaging settings, decided: per key, the stored
|
|
252
|
+
* boolean, else its `STORE_MESSAGING_DEFAULTS` value (a stored non-boolean
|
|
253
|
+
* reads as absent). `signature` falls back to `sms.signature` only when
|
|
254
|
+
* `messaging.signature` is absent; a stored `''` is kept and means no firma.
|
|
255
|
+
*/
|
|
256
|
+
export const resolveStoreMessaging = (integrations) => {
|
|
257
|
+
const leaf = integrations?.messaging;
|
|
258
|
+
const resolved = { ...STORE_MESSAGING_DEFAULTS };
|
|
259
|
+
for (const key of [...STORE_MESSAGE_NOTICES, 'smsFallback']) {
|
|
260
|
+
const stored = leaf?.[key];
|
|
261
|
+
if (typeof stored === 'boolean')
|
|
262
|
+
resolved[key] = stored;
|
|
263
|
+
}
|
|
264
|
+
const signature = typeof leaf?.signature === 'string' ? leaf.signature : integrations?.sms?.signature;
|
|
265
|
+
return typeof signature === 'string' ? { ...resolved, signature } : resolved;
|
|
266
|
+
};
|
package/dist/subscription.d.ts
CHANGED
|
@@ -100,7 +100,7 @@ declare global {
|
|
|
100
100
|
* exhausts this union (a `switch`, a `Record<FeatureKey, …>`) still has to
|
|
101
101
|
* handle the new member in the same change.
|
|
102
102
|
*/
|
|
103
|
-
type FeatureKey = 'maxOrdersMonth' | 'maxInvoicesMonth' | 'maxProducts' | 'maxUsers' | 'maxCustomers' | 'maxWarehouses' | 'priceListsMax' | 'webhooks' | 'afipInvoicing' | 'suppliers' | 'domesticPayments' | 'stripePayments' | 'cashManagement' | 'importExport' | 'advancedReports' | 'customBranding' | 'prioritySupport' | 'aiFeatures' | 'mobileApp' | 'customDomain' | 'advancedPricing' | 'marketplaceChannels' | 'storefront' | 'loyalty' | 'marketing' | 'mandatory2fa';
|
|
103
|
+
type FeatureKey = 'maxOrdersMonth' | 'maxInvoicesMonth' | 'maxProducts' | 'maxUsers' | 'maxCustomers' | 'maxWarehouses' | 'priceListsMax' | 'webhooks' | 'monthlyMessageAllowance' | 'afipInvoicing' | 'suppliers' | 'domesticPayments' | 'stripePayments' | 'cashManagement' | 'importExport' | 'advancedReports' | 'customBranding' | 'prioritySupport' | 'aiFeatures' | 'mobileApp' | 'customDomain' | 'advancedPricing' | 'marketplaceChannels' | 'storefront' | 'loyalty' | 'marketing' | 'mandatory2fa';
|
|
104
104
|
/** Resolved entitlements for a specific tenant (matrix + overrides applied). */
|
|
105
105
|
type ResolvedEntitlements = Record<FeatureKey, Entitlement>;
|
|
106
106
|
/**
|
|
@@ -1238,7 +1238,7 @@ export declare const isPaidPlanTier: (value: unknown) => value is PaidPlanTier;
|
|
|
1238
1238
|
* metered / lifetime cap PASSES THROUGH — a new cap silently unbounded.
|
|
1239
1239
|
* Checklist: `docs/PLANS_AND_ENTITLEMENTS.md` in the api repo.
|
|
1240
1240
|
*/
|
|
1241
|
-
export declare const FEATURE_KEYS: readonly ["afipInvoicing", "suppliers", "advancedReports", "cashManagement", "importExport", "domesticPayments", "stripePayments", "aiFeatures", "mobileApp", "customBranding", "customDomain", "prioritySupport", "advancedPricing", "marketplaceChannels", "storefront", "loyalty", "marketing", "mandatory2fa", "maxUsers", "maxProducts", "maxCustomers", "maxWarehouses", "priceListsMax", "webhooks", "maxOrdersMonth", "maxInvoicesMonth"];
|
|
1241
|
+
export declare const FEATURE_KEYS: readonly ["afipInvoicing", "suppliers", "advancedReports", "cashManagement", "importExport", "domesticPayments", "stripePayments", "aiFeatures", "mobileApp", "customBranding", "customDomain", "prioritySupport", "advancedPricing", "marketplaceChannels", "storefront", "loyalty", "marketing", "mandatory2fa", "maxUsers", "maxProducts", "maxCustomers", "maxWarehouses", "priceListsMax", "webhooks", "maxOrdersMonth", "maxInvoicesMonth", "monthlyMessageAllowance"];
|
|
1242
1242
|
type AssertNoUncoveredFeatureKey<T extends never> = T;
|
|
1243
1243
|
export type UncoveredFeatureKeys = AssertNoUncoveredFeatureKey<Exclude<FeatureKey, (typeof FEATURE_KEYS)[number]>>;
|
|
1244
1244
|
export {};
|
package/dist/subscription.js
CHANGED