sinfactura-types 1.10.577 → 1.10.579
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/auth.d.ts +10 -25
- package/dist/auth.js +3 -17
- package/dist/cjs/auth.js +3 -17
- package/dist/cjs/kitRecipe.js +14 -8
- package/dist/cjs/order.js +6 -3
- package/dist/cjs/roles.js +18 -9
- package/dist/cjs/terminal.js +3 -2
- package/dist/cjs/user.js +4 -3
- package/dist/kitRecipe.d.ts +14 -8
- package/dist/kitRecipe.js +14 -8
- package/dist/order.d.ts +14 -4
- package/dist/order.js +6 -3
- package/dist/product.d.ts +16 -0
- package/dist/roles.d.ts +22 -12
- package/dist/roles.js +17 -8
- package/dist/terminal.d.ts +12 -10
- package/dist/terminal.js +3 -2
- package/dist/user.d.ts +12 -7
- package/dist/user.js +4 -3
- package/dist/userActivity.d.ts +4 -3
- package/package.json +1 -1
package/dist/auth.d.ts
CHANGED
|
@@ -12,8 +12,7 @@ declare global {
|
|
|
12
12
|
* ignored. Treated as ABSENT while the server's `PASSKEY_STEP_UP` flag is
|
|
13
13
|
* off, so a client ahead of the flag gets `REQUIRES_2FA` again, never a
|
|
14
14
|
* wrong-code refusal. Operator `mode: 'login'` only — the storefront
|
|
15
|
-
* customer login
|
|
16
|
-
* same body type but do not accept it.
|
|
15
|
+
* customer login reads the same body type but does not accept it.
|
|
17
16
|
*/
|
|
18
17
|
passkeyAssertion?: PasskeyAssertion;
|
|
19
18
|
/** reCAPTCHA v3 token — required only after a `CAPTCHA_REQUIRED` login rejection; otherwise omit. */
|
|
@@ -522,8 +521,8 @@ declare global {
|
|
|
522
521
|
* on. ⚠️ A property of the DOOR, not of the account, which is what makes it
|
|
523
522
|
* different from `disabled`: the same row may be refused here and sign in
|
|
524
523
|
* successfully at another mode, so it must never be rendered as "this
|
|
525
|
-
* account is blocked". Emitted by `login`, `social
|
|
526
|
-
*
|
|
524
|
+
* account is blocked". Emitted by `login`, `social` and
|
|
525
|
+
* `magic-link-verify`.
|
|
527
526
|
*/
|
|
528
527
|
type LoginOutcome = 'success' | 'wrong_password' | 'disabled' | 'blocked' | 'requires_2fa' | 'wrong_totp' | 'totp_replay' | 'wrong_passkey' | 'totp_locked' | 'enrollment_required'
|
|
529
528
|
/**
|
|
@@ -970,10 +969,10 @@ declare global {
|
|
|
970
969
|
/** The session making this very request. Exactly one row carries `true`. */
|
|
971
970
|
current: boolean;
|
|
972
971
|
/**
|
|
973
|
-
*
|
|
974
|
-
*
|
|
975
|
-
*
|
|
976
|
-
*
|
|
972
|
+
* @deprecated Never written. It once marked a Cloud Print agent's
|
|
973
|
+
* password-login session; print agents now pair instead of logging in as a
|
|
974
|
+
* user, so the api no longer sets it. Kept so a consumer that
|
|
975
|
+
* still reads `client === 'printer'` compiles — the test is simply never true.
|
|
977
976
|
*/
|
|
978
977
|
client?: 'printer';
|
|
979
978
|
}
|
|
@@ -1362,25 +1361,12 @@ export type RefreshErrorCode = (typeof REFRESH_ERROR_CODES)[number];
|
|
|
1362
1361
|
* there is nothing to re-submit: no code the user can type will satisfy it, so
|
|
1363
1362
|
* a client that renders the six-digit prompt for this member builds a dead
|
|
1364
1363
|
* end. The only move that succeeds is enrolment. Emitted by
|
|
1365
|
-
* `auth/helpers/mandatory2fa.ts` from its
|
|
1366
|
-
* `_social.ts
|
|
1367
|
-
* NOT enrolment: that mode reaches the code only for an account holding a
|
|
1368
|
-
* PRINTER role *and* an operator role, and enrolling then earns
|
|
1369
|
-
* `TWO_FA_NOT_SUPPORTED` instead. Show `body.message`, which names the real
|
|
1370
|
-
* fix (a PRINTER-only service user), rather than a generic enrol prompt.
|
|
1364
|
+
* `auth/helpers/mandatory2fa.ts` from its opt-in callers — `_login.ts`,
|
|
1365
|
+
* `_social.ts`, `_refresh.ts` and `terminal/_activation.ts`.
|
|
1371
1366
|
* ⚠️ NOT emitted from `_magicLinkVerify.ts`, `_verifyPassword.ts` or
|
|
1372
1367
|
* `impersonation/_post.ts` — those three deliberately do not opt in, so the
|
|
1373
1368
|
* mandate cannot brick account recovery or incident response.
|
|
1374
1369
|
*
|
|
1375
|
-
* ⚠️ `ENROLLMENT_REQUIRED` is spelled exactly that, with no `PRINTER` substring —
|
|
1376
|
-
* however natural a surface-prefixed sibling looks, and this constrains any future
|
|
1377
|
-
* rename too. A released Cloud Print agent substring-matches on `PRINTER` in the
|
|
1378
|
-
* error code for an unrelated client-side condition; api `_printer.ts:196-198`
|
|
1379
|
-
* documents this, and it is why the code emitted there is `TWO_FA_NOT_SUPPORTED`
|
|
1380
|
-
* rather than anything clearer. A `PRINTER_ENROLLMENT_REQUIRED` would silently trip
|
|
1381
|
-
* that branch in every deployed agent, and the failure would surface in the agent,
|
|
1382
|
-
* never in our logs.
|
|
1383
|
-
*
|
|
1384
1370
|
* The GRACE-window half of the same obligation is not an error at all — the login
|
|
1385
1371
|
* succeeds and the body carries `AuthUser.mustEnroll2fa` / `enrollBy`.
|
|
1386
1372
|
*/
|
|
@@ -1440,8 +1426,7 @@ export declare const LOGIN_ERROR_CODES: readonly ["WRONG_CREDENTIALS", "ACCOUNT_
|
|
|
1440
1426
|
*
|
|
1441
1427
|
* ⚠️ `ENROLLMENT_REQUIRED` is not here: it belongs to `STEP_UP_ERROR_CODES`,
|
|
1442
1428
|
* because the second factor did not FAIL — there is no factor to fail yet. See
|
|
1443
|
-
* that tuple for it
|
|
1444
|
-
* it may be spelled.
|
|
1429
|
+
* that tuple for it.
|
|
1445
1430
|
*/
|
|
1446
1431
|
export declare const LOGIN_2FA_ERROR_CODES: readonly ["INVALID_2FA_CODE", "2FA_LOCKED"];
|
|
1447
1432
|
export type Login2faErrorCode = (typeof LOGIN_2FA_ERROR_CODES)[number];
|
package/dist/auth.js
CHANGED
|
@@ -193,25 +193,12 @@ export const REFRESH_ERROR_CODES = [
|
|
|
193
193
|
* there is nothing to re-submit: no code the user can type will satisfy it, so
|
|
194
194
|
* a client that renders the six-digit prompt for this member builds a dead
|
|
195
195
|
* end. The only move that succeeds is enrolment. Emitted by
|
|
196
|
-
* `auth/helpers/mandatory2fa.ts` from its
|
|
197
|
-
* `_social.ts
|
|
198
|
-
* NOT enrolment: that mode reaches the code only for an account holding a
|
|
199
|
-
* PRINTER role *and* an operator role, and enrolling then earns
|
|
200
|
-
* `TWO_FA_NOT_SUPPORTED` instead. Show `body.message`, which names the real
|
|
201
|
-
* fix (a PRINTER-only service user), rather than a generic enrol prompt.
|
|
196
|
+
* `auth/helpers/mandatory2fa.ts` from its opt-in callers — `_login.ts`,
|
|
197
|
+
* `_social.ts`, `_refresh.ts` and `terminal/_activation.ts`.
|
|
202
198
|
* ⚠️ NOT emitted from `_magicLinkVerify.ts`, `_verifyPassword.ts` or
|
|
203
199
|
* `impersonation/_post.ts` — those three deliberately do not opt in, so the
|
|
204
200
|
* mandate cannot brick account recovery or incident response.
|
|
205
201
|
*
|
|
206
|
-
* ⚠️ `ENROLLMENT_REQUIRED` is spelled exactly that, with no `PRINTER` substring —
|
|
207
|
-
* however natural a surface-prefixed sibling looks, and this constrains any future
|
|
208
|
-
* rename too. A released Cloud Print agent substring-matches on `PRINTER` in the
|
|
209
|
-
* error code for an unrelated client-side condition; api `_printer.ts:196-198`
|
|
210
|
-
* documents this, and it is why the code emitted there is `TWO_FA_NOT_SUPPORTED`
|
|
211
|
-
* rather than anything clearer. A `PRINTER_ENROLLMENT_REQUIRED` would silently trip
|
|
212
|
-
* that branch in every deployed agent, and the failure would surface in the agent,
|
|
213
|
-
* never in our logs.
|
|
214
|
-
*
|
|
215
202
|
* The GRACE-window half of the same obligation is not an error at all — the login
|
|
216
203
|
* succeeds and the body carries `AuthUser.mustEnroll2fa` / `enrollBy`.
|
|
217
204
|
*/
|
|
@@ -279,8 +266,7 @@ export const LOGIN_ERROR_CODES = [
|
|
|
279
266
|
*
|
|
280
267
|
* ⚠️ `ENROLLMENT_REQUIRED` is not here: it belongs to `STEP_UP_ERROR_CODES`,
|
|
281
268
|
* because the second factor did not FAIL — there is no factor to fail yet. See
|
|
282
|
-
* that tuple for it
|
|
283
|
-
* it may be spelled.
|
|
269
|
+
* that tuple for it.
|
|
284
270
|
*/
|
|
285
271
|
export const LOGIN_2FA_ERROR_CODES = ['INVALID_2FA_CODE', '2FA_LOCKED'];
|
|
286
272
|
/**
|
package/dist/cjs/auth.js
CHANGED
|
@@ -196,25 +196,12 @@ exports.REFRESH_ERROR_CODES = [
|
|
|
196
196
|
* there is nothing to re-submit: no code the user can type will satisfy it, so
|
|
197
197
|
* a client that renders the six-digit prompt for this member builds a dead
|
|
198
198
|
* end. The only move that succeeds is enrolment. Emitted by
|
|
199
|
-
* `auth/helpers/mandatory2fa.ts` from its
|
|
200
|
-
* `_social.ts
|
|
201
|
-
* NOT enrolment: that mode reaches the code only for an account holding a
|
|
202
|
-
* PRINTER role *and* an operator role, and enrolling then earns
|
|
203
|
-
* `TWO_FA_NOT_SUPPORTED` instead. Show `body.message`, which names the real
|
|
204
|
-
* fix (a PRINTER-only service user), rather than a generic enrol prompt.
|
|
199
|
+
* `auth/helpers/mandatory2fa.ts` from its opt-in callers — `_login.ts`,
|
|
200
|
+
* `_social.ts`, `_refresh.ts` and `terminal/_activation.ts`.
|
|
205
201
|
* ⚠️ NOT emitted from `_magicLinkVerify.ts`, `_verifyPassword.ts` or
|
|
206
202
|
* `impersonation/_post.ts` — those three deliberately do not opt in, so the
|
|
207
203
|
* mandate cannot brick account recovery or incident response.
|
|
208
204
|
*
|
|
209
|
-
* ⚠️ `ENROLLMENT_REQUIRED` is spelled exactly that, with no `PRINTER` substring —
|
|
210
|
-
* however natural a surface-prefixed sibling looks, and this constrains any future
|
|
211
|
-
* rename too. A released Cloud Print agent substring-matches on `PRINTER` in the
|
|
212
|
-
* error code for an unrelated client-side condition; api `_printer.ts:196-198`
|
|
213
|
-
* documents this, and it is why the code emitted there is `TWO_FA_NOT_SUPPORTED`
|
|
214
|
-
* rather than anything clearer. A `PRINTER_ENROLLMENT_REQUIRED` would silently trip
|
|
215
|
-
* that branch in every deployed agent, and the failure would surface in the agent,
|
|
216
|
-
* never in our logs.
|
|
217
|
-
*
|
|
218
205
|
* The GRACE-window half of the same obligation is not an error at all — the login
|
|
219
206
|
* succeeds and the body carries `AuthUser.mustEnroll2fa` / `enrollBy`.
|
|
220
207
|
*/
|
|
@@ -282,8 +269,7 @@ exports.LOGIN_ERROR_CODES = [
|
|
|
282
269
|
*
|
|
283
270
|
* ⚠️ `ENROLLMENT_REQUIRED` is not here: it belongs to `STEP_UP_ERROR_CODES`,
|
|
284
271
|
* because the second factor did not FAIL — there is no factor to fail yet. See
|
|
285
|
-
* that tuple for it
|
|
286
|
-
* it may be spelled.
|
|
272
|
+
* that tuple for it.
|
|
287
273
|
*/
|
|
288
274
|
exports.LOGIN_2FA_ERROR_CODES = ['INVALID_2FA_CODE', '2FA_LOCKED'];
|
|
289
275
|
/**
|
package/dist/cjs/kitRecipe.js
CHANGED
|
@@ -12,19 +12,25 @@
|
|
|
12
12
|
* the sale consumes the recipe's components from stock, and the line freezes the
|
|
13
13
|
* recipe it consumed (`OrderLine.kit`). Cancelling or returning that line gives
|
|
14
14
|
* back exactly the frozen components, whatever the recipe says later. Every
|
|
15
|
-
* other channel (
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* other channel (service, marketplace, quote conversion) refuses an active kit
|
|
16
|
+
* with the shared `409 PRODUCT_NOT_AVAILABLE`, with stock control on or off,
|
|
17
|
+
* and it cannot be linked to or reactivated on MercadoLibre. Retiring the
|
|
18
|
+
* recipe makes it an ordinary product again.
|
|
19
|
+
*
|
|
20
|
+
* A shopper never sees the recipe: the storefront reads `Product.isKit` and the
|
|
21
|
+
* kit's `stock`, which the shopper projection derives from its components.
|
|
19
22
|
*/
|
|
20
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
24
|
exports.KIT_COMPONENT_MAX_QUANTITY = exports.KIT_RECIPE_MAX_COMPONENTS = exports.KIT_SALE_CHANNELS = void 0;
|
|
22
25
|
/**
|
|
23
|
-
* The channels that sell a kit by consuming its components
|
|
24
|
-
*
|
|
25
|
-
* app
|
|
26
|
+
* The channels that sell a kit by consuming its components:
|
|
27
|
+
*
|
|
28
|
+
* - `counter` — the operator basket and `POST /orders`, which the app's POS and
|
|
29
|
+
* the mobile app share;
|
|
30
|
+
* - `storefront` — the shopper cart and the web checkout. Its WhatsApp catalogue
|
|
31
|
+
* and order drafts still leave kits out.
|
|
26
32
|
*/
|
|
27
|
-
exports.KIT_SALE_CHANNELS = ['counter'];
|
|
33
|
+
exports.KIT_SALE_CHANNELS = ['counter', 'storefront'];
|
|
28
34
|
/**
|
|
29
35
|
* Most components one recipe names. A save commits the kit, its new revision and
|
|
30
36
|
* every component's usage row in ONE transaction, so this is bounded by
|
package/dist/cjs/order.js
CHANGED
|
@@ -251,9 +251,12 @@ exports.orderFulfilmentProgress = orderFulfilmentProgress;
|
|
|
251
251
|
* `mode: 'deposit-refund'`, see `OrderDepositRefundRequest`. Nothing was
|
|
252
252
|
* written. `DEPOSIT_ALREADY_REFUNDED`'s `data` carries
|
|
253
253
|
* `OrderDepositRefundManualData` when the refund on the ledger was non-cash.
|
|
254
|
-
* - `KIT_RECIPE_CHANGED` · 409 — a
|
|
255
|
-
* saved again or retired after the sale read it;
|
|
256
|
-
* Nothing was written; re-read the
|
|
254
|
+
* - `KIT_RECIPE_CHANGED` · 409 — a sale of a kit (counter or storefront
|
|
255
|
+
* checkout) whose recipe was saved again or retired after the sale read it;
|
|
256
|
+
* `data.productIds` names the kits. Nothing was written; re-read the cart and
|
|
257
|
+
* retry. On the storefront a recipe that moved before the sale read it is
|
|
258
|
+
* refused before the coupon is redeemed, while one saved as the order commits
|
|
259
|
+
* is refused after it, like every other refusal at commit.
|
|
257
260
|
* - `ORDER_HAS_KIT_LINES` · 409 — `mode: 'edit'` on an order holding a kit line
|
|
258
261
|
* (`CartLine.kit`). Cancel or return the order instead. Nothing was written.
|
|
259
262
|
*
|
package/dist/cjs/roles.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.USER_ROLES = void 0;
|
|
3
|
+
exports.PRINT_AGENT_ROLE = exports.USER_ROLES = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* The staff role vocabulary — the single published source of truth for what
|
|
6
6
|
* may appear in `User.roles`.
|
|
@@ -15,9 +15,8 @@ exports.USER_ROLES = void 0;
|
|
|
15
15
|
*
|
|
16
16
|
* ⚠️ **`User.roles` is a delimited STRING, not one of these.** The wire shape
|
|
17
17
|
* is a space- or comma-separated list, so a claim can legitimately carry more
|
|
18
|
-
* than one token (`'USER
|
|
19
|
-
*
|
|
20
|
-
* TOKENS, never the whole attribute. Split before comparing, and compare
|
|
18
|
+
* than one token (`'USER ADMIN'`). This tuple types the TOKENS, never the
|
|
19
|
+
* whole attribute. Split before comparing, and compare
|
|
21
20
|
* exact tokens: a bare `String#includes` is a SUBSTRING test, so a future
|
|
22
21
|
* `MANAGER_READONLY` would silently satisfy a `MANAGER` gate.
|
|
23
22
|
*
|
|
@@ -28,14 +27,18 @@ exports.USER_ROLES = void 0;
|
|
|
28
27
|
* to this vocabulary would let a customer role be *assigned to staff*, which
|
|
29
28
|
* no gate anywhere expects.
|
|
30
29
|
*
|
|
30
|
+
* ⚠️ **`PRINTER` is not here either — it is not a person's role.** It is the
|
|
31
|
+
* machine marker a PAIRED Cloud Print agent's token carries
|
|
32
|
+
* (`PRINT_AGENT_ROLE` below), and no `User` row may hold it: every login door
|
|
33
|
+
* refuses a row that does, and every gate refuses a `PRINTER` token that does
|
|
34
|
+
* not also carry the agent's `printAgentId` claim.
|
|
35
|
+
*
|
|
31
36
|
* ⚠️ **Order is not precedence.** This is the assignable set, listed
|
|
32
37
|
* least-privileged first for readability. Audit attribution uses its own
|
|
33
|
-
* priority order
|
|
34
|
-
* machine identity has to win attribution because it already wins the
|
|
35
|
-
* authorization decision. Do not derive one from the other.
|
|
38
|
+
* priority order. Do not derive one from the other.
|
|
36
39
|
*/
|
|
37
40
|
/*
|
|
38
|
-
* ⚠️ **`ACCOUNTANT` is a RESTRICTED role
|
|
41
|
+
* ⚠️ **`ACCOUNTANT` is a RESTRICTED role — not a rung on a ladder.**
|
|
39
42
|
* It is the tenant's accountant: a read-only fiscal login that reaches the
|
|
40
43
|
* fiscal-book report modes (`invoices`, `supplier-invoices`, `libro-iva-digital`,
|
|
41
44
|
* `iva-simple-apertura`) and the `GET /invoices` reads, and is refused
|
|
@@ -44,4 +47,10 @@ exports.USER_ROLES = void 0;
|
|
|
44
47
|
* separately. Unrelated to the reserved `UserPermissions.accountant` capability
|
|
45
48
|
* key, which nothing reads.
|
|
46
49
|
*/
|
|
47
|
-
exports.USER_ROLES = ['USER', 'ADMIN', 'SUPERVISOR', 'MANAGER', '
|
|
50
|
+
exports.USER_ROLES = ['USER', 'ADMIN', 'SUPERVISOR', 'MANAGER', 'ACCOUNTANT'];
|
|
51
|
+
/**
|
|
52
|
+
* The role a paired Cloud Print agent's session token carries — a machine
|
|
53
|
+
* marker, never a person's role. Minted only by `POST
|
|
54
|
+
* /terminal/print-agents/session`, always beside a `printAgentId` claim.
|
|
55
|
+
*/
|
|
56
|
+
exports.PRINT_AGENT_ROLE = 'PRINTER';
|
package/dist/cjs/terminal.js
CHANGED
|
@@ -137,8 +137,9 @@ exports.TERMINAL_PAIRING_KINDS = ['terminal', 'print-agent'];
|
|
|
137
137
|
* - `PRINT_AGENT_NOT_FOUND` · 404 — revoke: no such agent in the caller's
|
|
138
138
|
* store (another store's agent answers the same).
|
|
139
139
|
* - `AGENT_ID_BOUND` · 409 — pair: the install `agentId` is bound to a live
|
|
140
|
-
* paired agent
|
|
141
|
-
*
|
|
140
|
+
* paired agent and the code was not minted to replace it (`replacesAgentId`);
|
|
141
|
+
* a binding left by a pre-pairing PRINTER user holds the id for nobody, so a
|
|
142
|
+
* normal code rebinds it. Or it is bound and the code was minted to replace a
|
|
142
143
|
* DIFFERENT id, or its binding changed during the pairing. Nothing is
|
|
143
144
|
* consumed.
|
|
144
145
|
*/
|
package/dist/cjs/user.js
CHANGED
|
@@ -6,9 +6,10 @@ exports.USER_DIRECTORY_KEYS = void 0;
|
|
|
6
6
|
* below-admin reader of the store's staff list receives instead of the row.
|
|
7
7
|
*
|
|
8
8
|
* ⚠️ An ALLOW-LIST, and the whole point. Name a colleague, tell a disabled or
|
|
9
|
-
*
|
|
10
|
-
* a
|
|
11
|
-
* `
|
|
9
|
+
* legacy PRINTER row (a pre-pairing print-agent user, a non-person) apart —
|
|
10
|
+
* that is what a picker, a "finalised by" label or a technician filter needs.
|
|
11
|
+
* Contact data (`email`, `phone`), `permissions`, `notifications`, `totp` and
|
|
12
|
+
* every key added to `User` later are OUT until
|
|
12
13
|
* someone adds them here, deliberately. Data minimisation (Ley 25.326): a
|
|
13
14
|
* cashier has no need for a colleague's address.
|
|
14
15
|
*
|
package/dist/kitRecipe.d.ts
CHANGED
|
@@ -11,17 +11,23 @@
|
|
|
11
11
|
* the sale consumes the recipe's components from stock, and the line freezes the
|
|
12
12
|
* recipe it consumed (`OrderLine.kit`). Cancelling or returning that line gives
|
|
13
13
|
* back exactly the frozen components, whatever the recipe says later. Every
|
|
14
|
-
* other channel (
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* other channel (service, marketplace, quote conversion) refuses an active kit
|
|
15
|
+
* with the shared `409 PRODUCT_NOT_AVAILABLE`, with stock control on or off,
|
|
16
|
+
* and it cannot be linked to or reactivated on MercadoLibre. Retiring the
|
|
17
|
+
* recipe makes it an ordinary product again.
|
|
18
|
+
*
|
|
19
|
+
* A shopper never sees the recipe: the storefront reads `Product.isKit` and the
|
|
20
|
+
* kit's `stock`, which the shopper projection derives from its components.
|
|
18
21
|
*/
|
|
19
22
|
/**
|
|
20
|
-
* The channels that sell a kit by consuming its components
|
|
21
|
-
*
|
|
22
|
-
* app
|
|
23
|
+
* The channels that sell a kit by consuming its components:
|
|
24
|
+
*
|
|
25
|
+
* - `counter` — the operator basket and `POST /orders`, which the app's POS and
|
|
26
|
+
* the mobile app share;
|
|
27
|
+
* - `storefront` — the shopper cart and the web checkout. Its WhatsApp catalogue
|
|
28
|
+
* and order drafts still leave kits out.
|
|
23
29
|
*/
|
|
24
|
-
export declare const KIT_SALE_CHANNELS: readonly ["counter"];
|
|
30
|
+
export declare const KIT_SALE_CHANNELS: readonly ["counter", "storefront"];
|
|
25
31
|
/**
|
|
26
32
|
* Most components one recipe names. A save commits the kit, its new revision and
|
|
27
33
|
* every component's usage row in ONE transaction, so this is bounded by
|
package/dist/kitRecipe.js
CHANGED
|
@@ -11,17 +11,23 @@
|
|
|
11
11
|
* the sale consumes the recipe's components from stock, and the line freezes the
|
|
12
12
|
* recipe it consumed (`OrderLine.kit`). Cancelling or returning that line gives
|
|
13
13
|
* back exactly the frozen components, whatever the recipe says later. Every
|
|
14
|
-
* other channel (
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
14
|
+
* other channel (service, marketplace, quote conversion) refuses an active kit
|
|
15
|
+
* with the shared `409 PRODUCT_NOT_AVAILABLE`, with stock control on or off,
|
|
16
|
+
* and it cannot be linked to or reactivated on MercadoLibre. Retiring the
|
|
17
|
+
* recipe makes it an ordinary product again.
|
|
18
|
+
*
|
|
19
|
+
* A shopper never sees the recipe: the storefront reads `Product.isKit` and the
|
|
20
|
+
* kit's `stock`, which the shopper projection derives from its components.
|
|
18
21
|
*/
|
|
19
22
|
/**
|
|
20
|
-
* The channels that sell a kit by consuming its components
|
|
21
|
-
*
|
|
22
|
-
* app
|
|
23
|
+
* The channels that sell a kit by consuming its components:
|
|
24
|
+
*
|
|
25
|
+
* - `counter` — the operator basket and `POST /orders`, which the app's POS and
|
|
26
|
+
* the mobile app share;
|
|
27
|
+
* - `storefront` — the shopper cart and the web checkout. Its WhatsApp catalogue
|
|
28
|
+
* and order drafts still leave kits out.
|
|
23
29
|
*/
|
|
24
|
-
export const KIT_SALE_CHANNELS = ['counter'];
|
|
30
|
+
export const KIT_SALE_CHANNELS = ['counter', 'storefront'];
|
|
25
31
|
/**
|
|
26
32
|
* Most components one recipe names. A save commits the kit, its new revision and
|
|
27
33
|
* every component's usage row in ONE transaction, so this is bounded by
|
package/dist/order.d.ts
CHANGED
|
@@ -2082,7 +2082,14 @@ declare global {
|
|
|
2082
2082
|
province: string;
|
|
2083
2083
|
};
|
|
2084
2084
|
}
|
|
2085
|
-
/**
|
|
2085
|
+
/**
|
|
2086
|
+
* One product a sale asked for more of than is on hand.
|
|
2087
|
+
*
|
|
2088
|
+
* On the operator surfaces a kit's short component is named itself. The
|
|
2089
|
+
* storefront checkout never names a component: it reports the KIT, with
|
|
2090
|
+
* `requested` the kit units ordered and `available` the kit units the short
|
|
2091
|
+
* components still make.
|
|
2092
|
+
*/
|
|
2086
2093
|
interface StockShortfall {
|
|
2087
2094
|
productId: string;
|
|
2088
2095
|
requested: number;
|
|
@@ -2305,9 +2312,12 @@ export declare const orderFulfilmentProgress: (order: OrderFulfilmentProgressInp
|
|
|
2305
2312
|
* `mode: 'deposit-refund'`, see `OrderDepositRefundRequest`. Nothing was
|
|
2306
2313
|
* written. `DEPOSIT_ALREADY_REFUNDED`'s `data` carries
|
|
2307
2314
|
* `OrderDepositRefundManualData` when the refund on the ledger was non-cash.
|
|
2308
|
-
* - `KIT_RECIPE_CHANGED` · 409 — a
|
|
2309
|
-
* saved again or retired after the sale read it;
|
|
2310
|
-
* Nothing was written; re-read the
|
|
2315
|
+
* - `KIT_RECIPE_CHANGED` · 409 — a sale of a kit (counter or storefront
|
|
2316
|
+
* checkout) whose recipe was saved again or retired after the sale read it;
|
|
2317
|
+
* `data.productIds` names the kits. Nothing was written; re-read the cart and
|
|
2318
|
+
* retry. On the storefront a recipe that moved before the sale read it is
|
|
2319
|
+
* refused before the coupon is redeemed, while one saved as the order commits
|
|
2320
|
+
* is refused after it, like every other refusal at commit.
|
|
2311
2321
|
* - `ORDER_HAS_KIT_LINES` · 409 — `mode: 'edit'` on an order holding a kit line
|
|
2312
2322
|
* (`CartLine.kit`). Cancel or return the order instead. Nothing was written.
|
|
2313
2323
|
*
|
package/dist/order.js
CHANGED
|
@@ -244,9 +244,12 @@ export const orderFulfilmentProgress = (order) => {
|
|
|
244
244
|
* `mode: 'deposit-refund'`, see `OrderDepositRefundRequest`. Nothing was
|
|
245
245
|
* written. `DEPOSIT_ALREADY_REFUNDED`'s `data` carries
|
|
246
246
|
* `OrderDepositRefundManualData` when the refund on the ledger was non-cash.
|
|
247
|
-
* - `KIT_RECIPE_CHANGED` · 409 — a
|
|
248
|
-
* saved again or retired after the sale read it;
|
|
249
|
-
* Nothing was written; re-read the
|
|
247
|
+
* - `KIT_RECIPE_CHANGED` · 409 — a sale of a kit (counter or storefront
|
|
248
|
+
* checkout) whose recipe was saved again or retired after the sale read it;
|
|
249
|
+
* `data.productIds` names the kits. Nothing was written; re-read the cart and
|
|
250
|
+
* retry. On the storefront a recipe that moved before the sale read it is
|
|
251
|
+
* refused before the coupon is redeemed, while one saved as the order commits
|
|
252
|
+
* is refused after it, like every other refusal at commit.
|
|
250
253
|
* - `ORDER_HAS_KIT_LINES` · 409 — `mode: 'edit'` on an order holding a kit line
|
|
251
254
|
* (`CartLine.kit`). Cancel or return the order instead. Nothing was written.
|
|
252
255
|
*
|
package/dist/product.d.ts
CHANGED
|
@@ -680,6 +680,22 @@ declare global {
|
|
|
680
680
|
* never in a shopper projection.
|
|
681
681
|
*/
|
|
682
682
|
kitRecipe?: ProductKitRecipePointer;
|
|
683
|
+
/**
|
|
684
|
+
* SHOPPER PROJECTION ONLY, derived and never stored: `true` while
|
|
685
|
+
* `kitRecipe` is active. The recipe itself never reaches a shopper.
|
|
686
|
+
*
|
|
687
|
+
* On a kit, the shopper projection's `stock` is the kit units its
|
|
688
|
+
* components make right now — the smallest `floor(component stock ÷ units
|
|
689
|
+
* per kit)`, a missing component reading `0`, from the online depósito on
|
|
690
|
+
* a store booking stock per depósito — never the kit row's own figure,
|
|
691
|
+
* which no sale moves. A frame announcing a component's stock does not
|
|
692
|
+
* re-announce the kits using it, so the figure can lag until the next read;
|
|
693
|
+
* the checkout judges the components themselves.
|
|
694
|
+
*
|
|
695
|
+
* Present only on a payload that carries the kit pointer: a partial frame
|
|
696
|
+
* without it says nothing about whether the product is a kit.
|
|
697
|
+
*/
|
|
698
|
+
isKit?: boolean;
|
|
683
699
|
model?: string;
|
|
684
700
|
seoTitle?: string;
|
|
685
701
|
seoDescription?: string;
|
package/dist/roles.d.ts
CHANGED
|
@@ -12,9 +12,8 @@
|
|
|
12
12
|
*
|
|
13
13
|
* ⚠️ **`User.roles` is a delimited STRING, not one of these.** The wire shape
|
|
14
14
|
* is a space- or comma-separated list, so a claim can legitimately carry more
|
|
15
|
-
* than one token (`'USER
|
|
16
|
-
*
|
|
17
|
-
* TOKENS, never the whole attribute. Split before comparing, and compare
|
|
15
|
+
* than one token (`'USER ADMIN'`). This tuple types the TOKENS, never the
|
|
16
|
+
* whole attribute. Split before comparing, and compare
|
|
18
17
|
* exact tokens: a bare `String#includes` is a SUBSTRING test, so a future
|
|
19
18
|
* `MANAGER_READONLY` would silently satisfy a `MANAGER` gate.
|
|
20
19
|
*
|
|
@@ -25,20 +24,31 @@
|
|
|
25
24
|
* to this vocabulary would let a customer role be *assigned to staff*, which
|
|
26
25
|
* no gate anywhere expects.
|
|
27
26
|
*
|
|
27
|
+
* ⚠️ **`PRINTER` is not here either — it is not a person's role.** It is the
|
|
28
|
+
* machine marker a PAIRED Cloud Print agent's token carries
|
|
29
|
+
* (`PRINT_AGENT_ROLE` below), and no `User` row may hold it: every login door
|
|
30
|
+
* refuses a row that does, and every gate refuses a `PRINTER` token that does
|
|
31
|
+
* not also carry the agent's `printAgentId` claim.
|
|
32
|
+
*
|
|
28
33
|
* ⚠️ **Order is not precedence.** This is the assignable set, listed
|
|
29
34
|
* least-privileged first for readability. Audit attribution uses its own
|
|
30
|
-
* priority order
|
|
31
|
-
* machine identity has to win attribution because it already wins the
|
|
32
|
-
* authorization decision. Do not derive one from the other.
|
|
35
|
+
* priority order. Do not derive one from the other.
|
|
33
36
|
*/
|
|
34
|
-
export declare const USER_ROLES: readonly ["USER", "ADMIN", "SUPERVISOR", "MANAGER", "
|
|
37
|
+
export declare const USER_ROLES: readonly ["USER", "ADMIN", "SUPERVISOR", "MANAGER", "ACCOUNTANT"];
|
|
35
38
|
/** One assignable staff role token. See `USER_ROLES` for why this is not the shape of `User.roles`. */
|
|
36
39
|
export type UserRole = (typeof USER_ROLES)[number];
|
|
37
40
|
/**
|
|
38
|
-
*
|
|
41
|
+
* The role a paired Cloud Print agent's session token carries — a machine
|
|
42
|
+
* marker, never a person's role. Minted only by `POST
|
|
43
|
+
* /terminal/print-agents/session`, always beside a `printAgentId` claim.
|
|
44
|
+
*/
|
|
45
|
+
export declare const PRINT_AGENT_ROLE: "PRINTER";
|
|
46
|
+
/**
|
|
47
|
+
* Every role string an authenticated principal can present: staff, the paired
|
|
48
|
+
* print agent or a shopper.
|
|
39
49
|
*
|
|
40
|
-
* `CUSTOMER`
|
|
41
|
-
* reader that classifies an incoming token needs
|
|
42
|
-
* assigns a staff role must not.
|
|
50
|
+
* `PRINTER` and `CUSTOMER` are included here and excluded from `USER_ROLES` on
|
|
51
|
+
* purpose: a reader that classifies an incoming token needs them, and a writer
|
|
52
|
+
* that assigns a staff role must not.
|
|
43
53
|
*/
|
|
44
|
-
export type PrincipalRole = UserRole | 'CUSTOMER';
|
|
54
|
+
export type PrincipalRole = UserRole | typeof PRINT_AGENT_ROLE | 'CUSTOMER';
|
package/dist/roles.js
CHANGED
|
@@ -12,9 +12,8 @@
|
|
|
12
12
|
*
|
|
13
13
|
* ⚠️ **`User.roles` is a delimited STRING, not one of these.** The wire shape
|
|
14
14
|
* is a space- or comma-separated list, so a claim can legitimately carry more
|
|
15
|
-
* than one token (`'USER
|
|
16
|
-
*
|
|
17
|
-
* TOKENS, never the whole attribute. Split before comparing, and compare
|
|
15
|
+
* than one token (`'USER ADMIN'`). This tuple types the TOKENS, never the
|
|
16
|
+
* whole attribute. Split before comparing, and compare
|
|
18
17
|
* exact tokens: a bare `String#includes` is a SUBSTRING test, so a future
|
|
19
18
|
* `MANAGER_READONLY` would silently satisfy a `MANAGER` gate.
|
|
20
19
|
*
|
|
@@ -25,14 +24,18 @@
|
|
|
25
24
|
* to this vocabulary would let a customer role be *assigned to staff*, which
|
|
26
25
|
* no gate anywhere expects.
|
|
27
26
|
*
|
|
27
|
+
* ⚠️ **`PRINTER` is not here either — it is not a person's role.** It is the
|
|
28
|
+
* machine marker a PAIRED Cloud Print agent's token carries
|
|
29
|
+
* (`PRINT_AGENT_ROLE` below), and no `User` row may hold it: every login door
|
|
30
|
+
* refuses a row that does, and every gate refuses a `PRINTER` token that does
|
|
31
|
+
* not also carry the agent's `printAgentId` claim.
|
|
32
|
+
*
|
|
28
33
|
* ⚠️ **Order is not precedence.** This is the assignable set, listed
|
|
29
34
|
* least-privileged first for readability. Audit attribution uses its own
|
|
30
|
-
* priority order
|
|
31
|
-
* machine identity has to win attribution because it already wins the
|
|
32
|
-
* authorization decision. Do not derive one from the other.
|
|
35
|
+
* priority order. Do not derive one from the other.
|
|
33
36
|
*/
|
|
34
37
|
/*
|
|
35
|
-
* ⚠️ **`ACCOUNTANT` is a RESTRICTED role
|
|
38
|
+
* ⚠️ **`ACCOUNTANT` is a RESTRICTED role — not a rung on a ladder.**
|
|
36
39
|
* It is the tenant's accountant: a read-only fiscal login that reaches the
|
|
37
40
|
* fiscal-book report modes (`invoices`, `supplier-invoices`, `libro-iva-digital`,
|
|
38
41
|
* `iva-simple-apertura`) and the `GET /invoices` reads, and is refused
|
|
@@ -41,4 +44,10 @@
|
|
|
41
44
|
* separately. Unrelated to the reserved `UserPermissions.accountant` capability
|
|
42
45
|
* key, which nothing reads.
|
|
43
46
|
*/
|
|
44
|
-
export const USER_ROLES = ['USER', 'ADMIN', 'SUPERVISOR', 'MANAGER', '
|
|
47
|
+
export const USER_ROLES = ['USER', 'ADMIN', 'SUPERVISOR', 'MANAGER', 'ACCOUNTANT'];
|
|
48
|
+
/**
|
|
49
|
+
* The role a paired Cloud Print agent's session token carries — a machine
|
|
50
|
+
* marker, never a person's role. Minted only by `POST
|
|
51
|
+
* /terminal/print-agents/session`, always beside a `printAgentId` claim.
|
|
52
|
+
*/
|
|
53
|
+
export const PRINT_AGENT_ROLE = 'PRINTER';
|
package/dist/terminal.d.ts
CHANGED
|
@@ -46,8 +46,9 @@ declare global {
|
|
|
46
46
|
* Must exist, else `404 AGENT_ID_NOT_FOUND` and no code is minted. The
|
|
47
47
|
* agent that redeems the code with this exact `agentId` gets the id; a
|
|
48
48
|
* paired agent that held it is revoked by that pairing. Without it, a
|
|
49
|
-
* redeem naming an id bound to a LIVE agent
|
|
50
|
-
* `409 AGENT_ID_BOUND`; an id whose binding names a revoked paired agent
|
|
49
|
+
* redeem naming an id bound to a LIVE paired agent is refused
|
|
50
|
+
* `409 AGENT_ID_BOUND`; an id whose binding names a revoked paired agent,
|
|
51
|
+
* or a pre-pairing PRINTER user (no door admits one any more), is free and
|
|
51
52
|
* needs none. Same charset as `PrintAgentPairRequest.agentId`.
|
|
52
53
|
*/
|
|
53
54
|
replacesAgentId?: string;
|
|
@@ -121,12 +122,12 @@ declare global {
|
|
|
121
122
|
/**
|
|
122
123
|
* The agent's INSTALL id. Its printers and routing rules are keyed by it.
|
|
123
124
|
* An id nothing holds yet — or one whose binding names a revoked paired
|
|
124
|
-
* agent, when the code was minted for no
|
|
125
|
-
* print agent. A code minted with
|
|
126
|
-
* id bound to a LIVE agent
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
125
|
+
* agent or a pre-pairing PRINTER user, when the code was minted for no
|
|
126
|
+
* install id — is bound to the new print agent. A code minted with
|
|
127
|
+
* `replacesAgentId` pairs only that id. An id bound to a LIVE paired agent
|
|
128
|
+
* moves to it only when the code was minted with that id as
|
|
129
|
+
* `replacesAgentId` (the admin's decision); otherwise the pair is refused
|
|
130
|
+
* `409 AGENT_ID_BOUND` and the code stays unconsumed. Omit on a fresh
|
|
130
131
|
* install to bind on first use.
|
|
131
132
|
*/
|
|
132
133
|
agentId?: string;
|
|
@@ -513,8 +514,9 @@ export type TerminalPairingKind = (typeof TERMINAL_PAIRING_KINDS)[number];
|
|
|
513
514
|
* - `PRINT_AGENT_NOT_FOUND` · 404 — revoke: no such agent in the caller's
|
|
514
515
|
* store (another store's agent answers the same).
|
|
515
516
|
* - `AGENT_ID_BOUND` · 409 — pair: the install `agentId` is bound to a live
|
|
516
|
-
* paired agent
|
|
517
|
-
*
|
|
517
|
+
* paired agent and the code was not minted to replace it (`replacesAgentId`);
|
|
518
|
+
* a binding left by a pre-pairing PRINTER user holds the id for nobody, so a
|
|
519
|
+
* normal code rebinds it. Or it is bound and the code was minted to replace a
|
|
518
520
|
* DIFFERENT id, or its binding changed during the pairing. Nothing is
|
|
519
521
|
* consumed.
|
|
520
522
|
*/
|
package/dist/terminal.js
CHANGED
|
@@ -134,8 +134,9 @@ export const TERMINAL_PAIRING_KINDS = ['terminal', 'print-agent'];
|
|
|
134
134
|
* - `PRINT_AGENT_NOT_FOUND` · 404 — revoke: no such agent in the caller's
|
|
135
135
|
* store (another store's agent answers the same).
|
|
136
136
|
* - `AGENT_ID_BOUND` · 409 — pair: the install `agentId` is bound to a live
|
|
137
|
-
* paired agent
|
|
138
|
-
*
|
|
137
|
+
* paired agent and the code was not minted to replace it (`replacesAgentId`);
|
|
138
|
+
* a binding left by a pre-pairing PRINTER user holds the id for nobody, so a
|
|
139
|
+
* normal code rebinds it. Or it is bound and the code was minted to replace a
|
|
139
140
|
* DIFFERENT id, or its binding changed during the pairing. Nothing is
|
|
140
141
|
* consumed.
|
|
141
142
|
*/
|
package/dist/user.d.ts
CHANGED
|
@@ -4,9 +4,10 @@ import type { NotificationTypeEnum } from './notification.ts';
|
|
|
4
4
|
* below-admin reader of the store's staff list receives instead of the row.
|
|
5
5
|
*
|
|
6
6
|
* ⚠️ An ALLOW-LIST, and the whole point. Name a colleague, tell a disabled or
|
|
7
|
-
*
|
|
8
|
-
* a
|
|
9
|
-
* `
|
|
7
|
+
* legacy PRINTER row (a pre-pairing print-agent user, a non-person) apart —
|
|
8
|
+
* that is what a picker, a "finalised by" label or a technician filter needs.
|
|
9
|
+
* Contact data (`email`, `phone`), `permissions`, `notifications`, `totp` and
|
|
10
|
+
* every key added to `User` later are OUT until
|
|
10
11
|
* someone adds them here, deliberately. Data minimisation (Ley 25.326): a
|
|
11
12
|
* cashier has no need for a colleague's address.
|
|
12
13
|
*
|
|
@@ -41,7 +42,8 @@ declare global {
|
|
|
41
42
|
* fallback; never assume a name.
|
|
42
43
|
*
|
|
43
44
|
* Read `roles` with exact-token matching, as on `User.roles` — it is how a
|
|
44
|
-
* picker leaves out a print-agent
|
|
45
|
+
* picker leaves out a legacy PRINTER row (a pre-pairing print-agent user
|
|
46
|
+
* that can no longer log in).
|
|
45
47
|
*/
|
|
46
48
|
type UserDirectoryEntry = Pick<User, Exclude<UserDirectoryKey, 'fullName'>> & Partial<Pick<User, 'fullName'>>;
|
|
47
49
|
/**
|
|
@@ -101,9 +103,12 @@ declare global {
|
|
|
101
103
|
* Always read `roles`; never the alias.
|
|
102
104
|
*
|
|
103
105
|
* ⚠️ A space- or comma-DELIMITED list, not a single role — a claim can
|
|
104
|
-
* legitimately carry more than one token (`'USER
|
|
105
|
-
*
|
|
106
|
-
*
|
|
106
|
+
* legitimately carry more than one token (`'USER ADMIN'`). Every token a
|
|
107
|
+
* write can GRANT today is a member of the published `USER_ROLES` tuple. A
|
|
108
|
+
* LEGACY row may still carry `PRINTER` — a pre-pairing print-agent user that
|
|
109
|
+
* every login door now refuses, which an edit preserves but never grants.
|
|
110
|
+
* Treat it as a non-person, never as a print agent (those are paired, not
|
|
111
|
+
* users). Split and
|
|
107
112
|
* compare EXACT tokens, never `String#includes`, which is a substring
|
|
108
113
|
* test that would let a future `MANAGER_READONLY` satisfy a `MANAGER`
|
|
109
114
|
* gate. It stays typed `string` rather than ```${UserRole}``` because
|
package/dist/user.js
CHANGED
|
@@ -3,9 +3,10 @@
|
|
|
3
3
|
* below-admin reader of the store's staff list receives instead of the row.
|
|
4
4
|
*
|
|
5
5
|
* ⚠️ An ALLOW-LIST, and the whole point. Name a colleague, tell a disabled or
|
|
6
|
-
*
|
|
7
|
-
* a
|
|
8
|
-
* `
|
|
6
|
+
* legacy PRINTER row (a pre-pairing print-agent user, a non-person) apart —
|
|
7
|
+
* that is what a picker, a "finalised by" label or a technician filter needs.
|
|
8
|
+
* Contact data (`email`, `phone`), `permissions`, `notifications`, `totp` and
|
|
9
|
+
* every key added to `User` later are OUT until
|
|
9
10
|
* someone adds them here, deliberately. Data minimisation (Ley 25.326): a
|
|
10
11
|
* cashier has no need for a colleague's address.
|
|
11
12
|
*
|
package/dist/userActivity.d.ts
CHANGED
|
@@ -1303,7 +1303,7 @@ declare global {
|
|
|
1303
1303
|
agent_id?: string;
|
|
1304
1304
|
/**
|
|
1305
1305
|
* The binding this pairing replaced, as stored — the raw `boundUserId`,
|
|
1306
|
-
* NOT a bare user id: `{storeId}#USR…` for a PRINTER user, or
|
|
1306
|
+
* NOT a bare user id: `{storeId}#USR…` for a pre-pairing PRINTER user (legacy rows only), or
|
|
1307
1307
|
* `{storeId}#PAG…` for a paired agent — one this pairing revoked (a
|
|
1308
1308
|
* sibling `Print Agent Revoked` row), or, with `rebind_via: 'dead-agent'`,
|
|
1309
1309
|
* one already revoked or aged out (no sibling row). Absent on a fresh
|
|
@@ -1313,8 +1313,9 @@ declare global {
|
|
|
1313
1313
|
/**
|
|
1314
1314
|
* Why a bound install id moved, beside `previous_bound_user_id`:
|
|
1315
1315
|
* `'replaces-agent-id'` — the code's minting admin named it;
|
|
1316
|
-
* `'dead-agent'` — the binding
|
|
1317
|
-
*
|
|
1316
|
+
* `'dead-agent'` — the binding held the id for nobody, so no admin named
|
|
1317
|
+
* it: it named a revoked (or aged-out) paired agent, or no paired agent at
|
|
1318
|
+
* all (a pre-pairing PRINTER user's `{storeId}#USR…`).
|
|
1318
1319
|
*/
|
|
1319
1320
|
rebind_via?: 'replaces-agent-id' | 'dead-agent';
|
|
1320
1321
|
}
|