@blob-solutions/vcr-am-sdk 0.11.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,46 @@
2
2
 
3
3
  All notable changes to `@blob-solutions/vcr-am-sdk`. The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project follows [Semantic Versioning](https://semver.org/).
4
4
 
5
+ ## [0.14.0] — 2026-07-08
6
+
7
+ Closes the drift that had accumulated against `/api/v1` since 0.13.0. Everything here is additive — no call-site changes required.
8
+
9
+ ### Added
10
+
11
+ - `whoami()` — wraps `GET /whoami`. Returns `{ vcrId, crn, mode, tradingPlatformName, businessEntity }`, where `mode` is `"production"` / `"sandbox"` and `crn` is `null` for imported-but-not-yet-activated VCRs. Useful as a cheap SDK health-check and for telling production keys apart from sandbox ones. New type `Whoami`, new schema `whoamiResponseSchema`.
12
+ - `listOffers({ externalId?, type?, includeArchived? })` — wraps `GET /offers`. Returns up to 500 `OfferListItem[]`. Check whether an offer already exists (by `externalId`) before creating it.
13
+ - `getOffer(id)` — wraps `GET /offers/{id}`. Returns a single `OfferListItem`.
14
+ - `updateOffer(id, { title })` — wraps `PATCH /offers/{id}`. Renames an offer's title going forward; already-issued receipts and the SRC fiscal record are unchanged. Accepts the canonical `OfferTitle` (`localized` / `universal`).
15
+ - New types `OfferListItem`, `ListOffersFilter`, `UpdateOfferInput`, `CurrencyConversionInput`; new schemas `offerListItemSchema`, `offerListResponseSchema`.
16
+ - `RegisterSaleInput.currencyConversion?` — foreign-currency sales (HO-234-N). Enter the sale in USD/EUR/RUB etc.; VCR converts to AMD at the previous-business-day CBA rate and rejects a stale rate. The AMD `price` values in `items[]` stay authoritative.
17
+ - `SaleItem.emarks?: string[]` — per-line eMark codes for marked goods (Govt Decision 1976-N). Previously only refund items could carry eMarks.
18
+ - `Offer` (sale-item offer) gained the by-internal-id reference shape `{ id: number }`, alongside the existing new-offer and `{ externalId }` shapes.
19
+ - `VCRApiError.body.requestId` — the server's 5xx correlation ID is now preserved instead of being stripped. Include it when contacting support.
20
+
21
+ ### Changed
22
+
23
+ - `CreateOfferInput.title` now also accepts the canonical `OfferTitle` shape (`{ type: "localized" | "universal", ... }`), unifying it with inline sale offers and `updateOffer`, and unlocking `universal` (brand-name) titles. The legacy `{ value, localizationStrategy }` shape (now typed as `LegacyOfferTitle`) still works but is **deprecated** — the server plans to drop it.
24
+ - Dependency refresh: `zod` `^4.4.1` → `^4.4.3`. Dev tooling bumped (`vite` `^8.0.10` → `^8.1.3`, clearing two Windows-only dev-server advisories; `@biomejs/biome`, `vitest`, `@vitest/coverage-v8`, `publint`, `@arethetypeswrong/cli`). An `esbuild` `>=0.28.1` override clears a low-severity build-time advisory. None of these ship in the published package.
25
+
26
+ ## [0.13.0] — 2026-05-27
27
+
28
+ ### Added
29
+
30
+ - `listDepartments()` — wraps `GET /departments`. Returns `DepartmentListItem[]` with `internalId`, `externalId`, `taxRegime`, and the localized `title`. Only departments confirmed by the tax service are included, so each `internalId` is safe to reference from a sale item's `department.id`. Closes the gap where the SDK could create departments but not list them.
31
+ - New exported types: `DepartmentListItem`. New exported schemas: `departmentListItemSchema`, `departmentListResponseSchema`.
32
+
33
+ ## [0.12.0] — 2026-05-26
34
+
35
+ ### Added
36
+
37
+ - `listPrepayments({ customerRef?, state? })` — wraps `GET /prepayments`. Returns up to 500 rows; each item carries the ledger-derived `remaining` and `state` (`open` / `consumed` / `refunded`). `state: "all"` is accepted as an explicit no-op filter.
38
+ - `getCustomerPrepaymentBalance({ customerRef })` — wraps `GET /prepayments/balance`. Returns the open balance for that customer, scoped to the BusinessEntity that owns the calling VCR's API key, plus the FIFO-ordered list of contributing open prepayments.
39
+ - New exported types: `PrepaymentListItem`, `PrepaymentState`, `CustomerPrepaymentBalance`, `ListPrepaymentsFilter`. New exported schemas: `prepaymentListItemSchema`, `prepaymentListResponseSchema`, `prepaymentStateSchema`, `customerPrepaymentBalanceResponseSchema`.
40
+
41
+ ### Changed
42
+
43
+ - `PrepaymentDetail` (the `getPrepayment` response) now includes `remaining: number` and `state: PrepaymentState`. The server has been sending these since the ledger landed; the SDK schema is catching up. Strictly additive — existing consumers keep working.
44
+
5
45
  ## [0.11.0] — 2026-05-13
6
46
 
7
47
  ### Breaking
package/README.md CHANGED
@@ -19,6 +19,7 @@ Official TypeScript / JavaScript SDK for the [VCR.AM](https://vcr.am) Virtual Ca
19
19
  - [Quick start](#quick-start)
20
20
  - [Configuration](#configuration)
21
21
  - [API reference](#api-reference)
22
+ - [Account](#account)
22
23
  - [Sales](#sales)
23
24
  - [Prepayments](#prepayments)
24
25
  - [Cashiers](#cashiers)
@@ -93,6 +94,19 @@ await vcr.registerSale(sale, {
93
94
 
94
95
  Every method returns a typed, schema-validated response and accepts an optional `RequestOptions` (`{ signal?, timeoutMs? }`) as its last argument.
95
96
 
97
+ ### Account
98
+
99
+ | Method | Endpoint | Returns |
100
+ | ------------ | ------------- | -------- |
101
+ | `whoami()` | `GET /whoami` | `Whoami` |
102
+
103
+ `whoami()` resolves which VCR the API key belongs to and whether it is a `production` or `sandbox` key — a cheap health-check. It works on freshly-imported registers that have not been activated yet (`crn` is `null` in that case).
104
+
105
+ ```typescript
106
+ const me = await vcr.whoami();
107
+ console.log(me.vcrId, me.mode, me.businessEntity.tin);
108
+ ```
109
+
96
110
  ### Sales
97
111
 
98
112
  | Method | Endpoint | Returns |
@@ -111,13 +125,38 @@ const refund = await vcr.registerSaleRefund({
111
125
  });
112
126
  ```
113
127
 
128
+ **eMark codes** (marked goods, Govt Decision 1976-N) go on each sale item as `emarks: string[]`; the same codes are echoed on refund items.
129
+
130
+ **Foreign-currency sales** (HO-234-N): pass a `currencyConversion` block alongside the AMD `items`. VCR re-resolves the previous-business-day CBA rate and rejects the sale if the rate you sent is stale. The AMD `price` values in `items[]` remain the authoritative fiscal figures.
131
+
132
+ ```typescript
133
+ await vcr.registerSale({
134
+ cashier: { id: 1 },
135
+ items: [
136
+ { offer: { id: 5 }, department: { id: 1 }, quantity: "1", price: "4000", unit: "pc" },
137
+ ],
138
+ currencyConversion: {
139
+ currency: "USD", // ISO 4217; not AMD
140
+ ratePerUnit: "400", // AMD per 1 USD (CBA, previous business day)
141
+ rateDate: "2026-07-07", // YYYY-MM-DD
142
+ lines: [{ foreignUnitPrice: "10" }], // index-aligned to items[]
143
+ },
144
+ amount: { cash: "4000" },
145
+ buyer: { type: "individual" },
146
+ });
147
+ ```
148
+
114
149
  ### Prepayments
115
150
 
116
- | Method | Endpoint | Returns |
117
- | --------------------------------- | ------------------------- | ------------------------------------ |
118
- | `registerPrepayment(input)` | `POST /prepayments` | `RegisterPrepaymentResponse` |
119
- | `getPrepayment(id)` | `GET /prepayments/{id}` | `PrepaymentDetail` |
120
- | `registerPrepaymentRefund(input)` | `POST /prepayments/refund`| `RegisterPrepaymentRefundResponse` |
151
+ | Method | Endpoint | Returns |
152
+ | ------------------------------------------ | ---------------------------- | ---------------------------------- |
153
+ | `registerPrepayment(input)` | `POST /prepayments` | `RegisterPrepaymentResponse` |
154
+ | `getPrepayment(id)` | `GET /prepayments/{id}` | `PrepaymentDetail` |
155
+ | `registerPrepaymentRefund(input)` | `POST /prepayments/refund` | `RegisterPrepaymentRefundResponse` |
156
+ | `listPrepayments(filter?)` | `GET /prepayments` | `PrepaymentListItem[]` |
157
+ | `getCustomerPrepaymentBalance({ ... })` | `GET /prepayments/balance` | `CustomerPrepaymentBalance` |
158
+
159
+ `listPrepayments({ customerRef?, state? })` returns up to 500 rows, each carrying the ledger-derived `remaining` and `state` (`open` / `consumed` / `refunded`). `getCustomerPrepaymentBalance({ customerRef })` returns the customer's open balance, scoped to the business entity that owns the calling VCR's key.
121
160
 
122
161
  ### Cashiers
123
162
 
@@ -138,10 +177,30 @@ const cashier = await vcr.createCashier({
138
177
 
139
178
  ### Offers and departments
140
179
 
141
- | Method | Endpoint | Returns |
142
- | ------------------------- | -------------------- | --------------------------- |
143
- | `createOffer(input)` | `POST /offers` | `CreateOfferResponse` |
144
- | `createDepartment(input)` | `POST /departments` | `CreateDepartmentResponse` |
180
+ | Method | Endpoint | Returns |
181
+ | ---------------------------- | -------------------- | -------------------------- |
182
+ | `createOffer(input)` | `POST /offers` | `CreateOfferResponse` |
183
+ | `listOffers(filter?)` | `GET /offers` | `OfferListItem[]` |
184
+ | `getOffer(id)` | `GET /offers/{id}` | `OfferListItem` |
185
+ | `updateOffer(id, { title })` | `PATCH /offers/{id}` | `OfferListItem` |
186
+ | `createDepartment(input)` | `POST /departments` | `CreateDepartmentResponse` |
187
+ | `listDepartments()` | `GET /departments` | `DepartmentListItem[]` |
188
+
189
+ `listOffers({ externalId?, type?, includeArchived? })` is handy for checking whether an offer already exists (by `externalId`) before creating it. `updateOffer` renames an offer's title going forward — already-issued receipts are unchanged. Offer titles use the canonical `OfferTitle` shape (`{ type: "localized" | "universal", ... }`); `createOffer` also still accepts the deprecated legacy `{ value, localizationStrategy }` shape.
190
+
191
+ ```typescript
192
+ const [existing] = await vcr.listOffers({ externalId: "sku-coffee" });
193
+ if (existing === undefined) {
194
+ await vcr.createOffer({
195
+ type: "product",
196
+ classifierCode: "0901",
197
+ title: { type: "localized", content: { hy: "Սուրճ" }, localizationStrategy: "translation" },
198
+ defaultMeasureUnit: "pc",
199
+ defaultDepartment: { id: 1 },
200
+ externalId: "sku-coffee",
201
+ });
202
+ }
203
+ ```
145
204
 
146
205
  ### Classifier search
147
206
 
@@ -203,7 +262,7 @@ The whole request flow — connection, body read, schema parse — is bounded by
203
262
 
204
263
  ## Idempotency and retries
205
264
 
206
- **The SDK does not retry.** This is intentional. The fiscal API does not currently support idempotency keys, so retrying a `registerSale` after a network blip can double-fiscalize a receipt. Implement application-level retry only on operations you have confirmed are safe to repeat (typically reads: `getSale`, `getPrepayment`, `listCashiers`, `searchClassifier`).
265
+ **The SDK does not retry.** This is intentional. The fiscal API does not currently support idempotency keys, so retrying a `registerSale` after a network blip can double-fiscalize a receipt. Implement application-level retry only on operations you have confirmed are safe to repeat (typically reads: `whoami`, `getSale`, `getPrepayment`, `listPrepayments`, `listCashiers`, `listOffers`, `getOffer`, `listDepartments`, `searchClassifier`).
207
266
 
208
267
  ## Browser usage
209
268
 
package/lib/index.cjs CHANGED
@@ -98,7 +98,11 @@ var apiErrorBodySchema = zod.z.object({
98
98
  message: zod.z.string(),
99
99
  code: zod.z.string()
100
100
  })
101
- ).optional()
101
+ ).optional(),
102
+ // Server-generated correlation ID present on unexpected 5xx responses.
103
+ // Kept lenient (plain string, not `.uuid()`) so a malformed value can never
104
+ // make the error envelope fail to parse and mask the real API error.
105
+ requestId: zod.z.string().optional()
102
106
  });
103
107
  var isoDateTimeSchema = zod.z.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/, "Invalid ISO datetime");
104
108
  var detailLanguageSchema = zod.z.enum([...AVAILABLE_LANGUAGES, "multi"]);
@@ -151,6 +155,17 @@ var createDepartmentResponseSchema = zod.z.object({
151
155
  message: zod.z.string(),
152
156
  department: zod.z.number().int().nonnegative()
153
157
  });
158
+ var whoamiResponseSchema = zod.z.object({
159
+ vcrId: zod.z.number().int().nonnegative(),
160
+ // `null` until the VCR is activated (freshly-imported registers have no CRN).
161
+ crn: zod.z.string().nullable(),
162
+ mode: zod.z.enum(["production", "sandbox"]),
163
+ tradingPlatformName: zod.z.string(),
164
+ businessEntity: zod.z.object({
165
+ tin: zod.z.string(),
166
+ name: zod.z.string()
167
+ })
168
+ });
154
169
  var cashierNameLocalizationSchema = zod.z.object({
155
170
  language: zod.z.enum([...AVAILABLE_LANGUAGES, "multi"]),
156
171
  content: zod.z.string()
@@ -161,6 +176,16 @@ var cashierListItemSchema = zod.z.object({
161
176
  name: zod.z.record(zod.z.string(), cashierNameLocalizationSchema)
162
177
  });
163
178
  var cashierListResponseSchema = zod.z.array(cashierListItemSchema);
179
+ var departmentListItemSchema = zod.z.object({
180
+ internalId: zod.z.number().int().nonnegative(),
181
+ externalId: zod.z.string().nullable(),
182
+ taxRegime: taxRegimeSchema,
183
+ // Map from language code -> { language, content }, matching the wire
184
+ // format produced by makeLocalizationObject on the server. May be empty
185
+ // for legacy departments created before titles were mandatory.
186
+ title: zod.z.record(zod.z.string(), localizationEntrySchema)
187
+ });
188
+ var departmentListResponseSchema = zod.z.array(departmentListItemSchema);
164
189
  var classifierSearchItemSchema = zod.z.object({
165
190
  code: zod.z.string(),
166
191
  // Optional: server may emit `{ code }` without `title` when the classifier
@@ -168,6 +193,20 @@ var classifierSearchItemSchema = zod.z.object({
168
193
  title: zod.z.string().optional()
169
194
  });
170
195
  var classifierSearchResponseSchema = zod.z.array(classifierSearchItemSchema);
196
+ var offerListItemSchema = zod.z.object({
197
+ id: zod.z.number().int().nonnegative(),
198
+ externalId: zod.z.string().nullable(),
199
+ type: offerTypeSchema,
200
+ classifierCode: zod.z.string(),
201
+ // Server types this as a plain string (not the unit enum) to stay faithful
202
+ // to whatever is stored; mirror it so a legacy unit can never fail parsing.
203
+ defaultMeasureUnit: zod.z.string(),
204
+ defaultDepartment: zod.z.object({ internalId: zod.z.number().int().nonnegative() }),
205
+ title: zod.z.array(localizationEntrySchema),
206
+ archivedAt: isoDateTimeSchema.nullable(),
207
+ createdAt: isoDateTimeSchema
208
+ });
209
+ var offerListResponseSchema = zod.z.array(offerListItemSchema);
171
210
  var receiptPickSchema = zod.z.object({
172
211
  srcId: zod.z.number().int(),
173
212
  time: zod.z.string().regex(/^\d+$/, "Invalid bigint string"),
@@ -230,6 +269,7 @@ var prepaymentRefundPickSchema = zod.z.object({
230
269
  cashAmount: zod.z.number(),
231
270
  receipt: receiptPickSchema.nullable()
232
271
  });
272
+ var prepaymentStateSchema = zod.z.enum(["open", "consumed", "refunded"]);
233
273
  var prepaymentDetailResponseSchema = zod.z.object({
234
274
  id: zod.z.number().int().nonnegative(),
235
275
  createdAt: isoDateTimeSchema,
@@ -238,7 +278,36 @@ var prepaymentDetailResponseSchema = zod.z.object({
238
278
  nonCashAmount: zod.z.number(),
239
279
  receipt: receiptPickSchema.nullable(),
240
280
  refund: prepaymentRefundPickSchema.nullable(),
241
- cashier: cashierPickSchema
281
+ cashier: cashierPickSchema,
282
+ /** SUM(amount) across all ledger rows for this prepayment. */
283
+ remaining: zod.z.number(),
284
+ state: prepaymentStateSchema
285
+ });
286
+ var prepaymentListItemSchema = zod.z.object({
287
+ id: zod.z.number().int().nonnegative(),
288
+ createdAt: isoDateTimeSchema,
289
+ buyerTin: zod.z.string().nullable(),
290
+ cashAmount: zod.z.number(),
291
+ nonCashAmount: zod.z.number(),
292
+ remaining: zod.z.number(),
293
+ state: prepaymentStateSchema
294
+ });
295
+ var prepaymentListResponseSchema = zod.z.array(prepaymentListItemSchema);
296
+ var customerOpenPrepaymentSchema = zod.z.object({
297
+ prepaymentId: zod.z.number().int().nonnegative(),
298
+ createdAt: isoDateTimeSchema,
299
+ cashAmount: zod.z.number(),
300
+ nonCashAmount: zod.z.number(),
301
+ buyerTin: zod.z.string().nullable(),
302
+ remaining: zod.z.number()
303
+ });
304
+ var customerPrepaymentBalanceResponseSchema = zod.z.object({
305
+ entityId: zod.z.number().int().nonnegative(),
306
+ customerRef: zod.z.string(),
307
+ /** Total remaining across all open prepayments matching customerRef. */
308
+ balance: zod.z.number(),
309
+ /** FIFO-ordered open prepayments contributing to the balance. */
310
+ openPrepayments: zod.z.array(customerOpenPrepaymentSchema)
242
311
  });
243
312
 
244
313
  // src/fetch.ts
@@ -299,7 +368,8 @@ function buildApiError(status, rawJson, url) {
299
368
  if (parsed.success) {
300
369
  const body = {
301
370
  error: parsed.data.error,
302
- ...parsed.data.issues !== void 0 && { issues: parsed.data.issues }
371
+ ...parsed.data.issues !== void 0 && { issues: parsed.data.issues },
372
+ ...parsed.data.requestId !== void 0 && { requestId: parsed.data.requestId }
303
373
  };
304
374
  return new VCRApiError(status, body, url);
305
375
  }
@@ -347,6 +417,17 @@ var VCRClient = class {
347
417
  this.#fetch = options.fetch === void 0 ? candidate.bind(globalThis) : candidate;
348
418
  this.#defaultTimeoutMs = options.timeoutMs === void 0 ? DEFAULT_TIMEOUT_MS : options.timeoutMs;
349
419
  }
420
+ // ─── Account ──────────────────────────────────────────────────────────────
421
+ /**
422
+ * Resolve which VCR the calling API key belongs to. Returns the register's
423
+ * identity, its `mode` (`production` / `sandbox`), and the owning business
424
+ * entity. Works on freshly-imported VCRs that have not been activated yet
425
+ * (in which case `crn` is `null`) — handy as a cheap SDK health-check and to
426
+ * tell production keys apart from sandbox ones.
427
+ */
428
+ whoami(options = {}) {
429
+ return this.#json("GET", "/whoami", whoamiResponseSchema, void 0, options);
430
+ }
350
431
  // ─── Sales ─────────────────────────────────────────────────────────────────
351
432
  registerSale(data, options = {}) {
352
433
  return this.#json("POST", "/sales", registerSaleResponseSchema, data, options);
@@ -381,6 +462,48 @@ var VCRClient = class {
381
462
  options
382
463
  );
383
464
  }
465
+ /**
466
+ * List prepayments registered through the calling VCR. Server caps the
467
+ * response at 500 rows; for larger sets, narrow with `customerRef` or
468
+ * paginate by `id` outside the SDK.
469
+ *
470
+ * `remaining` and `state` are derived from the ledger — call this whenever
471
+ * you want a current snapshot rather than caching the result.
472
+ */
473
+ listPrepayments(filter = {}, options = {}) {
474
+ const query = {};
475
+ if (filter.customerRef !== void 0) query["customerRef"] = filter.customerRef;
476
+ if (filter.state !== void 0) query["state"] = filter.state;
477
+ return this.#json(
478
+ "GET",
479
+ "/prepayments",
480
+ prepaymentListResponseSchema,
481
+ void 0,
482
+ options,
483
+ Object.keys(query).length > 0 ? query : void 0
484
+ );
485
+ }
486
+ /**
487
+ * Get a customer's open prepayment balance scoped to the BusinessEntity
488
+ * that owns the calling VCR's API key. Because the ledger is entity-scoped,
489
+ * the result reflects deposits made through any VCR belonging to the same
490
+ * entity — merchants who run more than one VCR see a single wallet.
491
+ *
492
+ * `customerRef` is matched exactly against the ledger — typically a TIN,
493
+ * normalized E.164 phone, or lowercased email. Use whichever identifier the
494
+ * customer gave at deposit time; identities are not auto-merged across
495
+ * different ref types.
496
+ */
497
+ getCustomerPrepaymentBalance(input, options = {}) {
498
+ return this.#json(
499
+ "GET",
500
+ "/prepayments/balance",
501
+ customerPrepaymentBalanceResponseSchema,
502
+ void 0,
503
+ options,
504
+ { customerRef: input.customerRef }
505
+ );
506
+ }
384
507
  // ─── Cashiers ─────────────────────────────────────────────────────────────
385
508
  listCashiers(options = {}) {
386
509
  return this.#json("GET", "/cashiers", cashierListResponseSchema, void 0, options);
@@ -392,9 +515,57 @@ var VCRClient = class {
392
515
  createOffer(data, options = {}) {
393
516
  return this.#json("POST", "/offers", createOfferResponseSchema, data, options);
394
517
  }
518
+ /**
519
+ * List offers belonging to the calling VCR. Server caps the response at 500
520
+ * rows; narrow with `externalId` / `type` for larger catalogs. Archived
521
+ * offers are excluded unless `includeArchived` is set.
522
+ *
523
+ * A common use is checking whether an offer already exists (by `externalId`)
524
+ * before creating it.
525
+ */
526
+ listOffers(filter = {}, options = {}) {
527
+ const query = {};
528
+ if (filter.externalId !== void 0) query["externalId"] = filter.externalId;
529
+ if (filter.type !== void 0) query["type"] = filter.type;
530
+ if (filter.includeArchived !== void 0) {
531
+ query["includeArchived"] = filter.includeArchived ? "true" : "false";
532
+ }
533
+ return this.#json(
534
+ "GET",
535
+ "/offers",
536
+ offerListResponseSchema,
537
+ void 0,
538
+ options,
539
+ Object.keys(query).length > 0 ? query : void 0
540
+ );
541
+ }
542
+ getOffer(offerId, options = {}) {
543
+ assertNonNegativeInt(offerId, "offerId");
544
+ return this.#json("GET", `/offers/${offerId}`, offerListItemSchema, void 0, options);
545
+ }
546
+ /**
547
+ * Rename an offer's title. Affects only future receipts — already-issued
548
+ * receipts keep the title they were created with, and the SRC fiscal record
549
+ * is unchanged. Missing `en`/`ru` are filled per `localizationStrategy`,
550
+ * exactly as on offer creation. Returns the updated offer.
551
+ */
552
+ updateOffer(offerId, data, options = {}) {
553
+ assertNonNegativeInt(offerId, "offerId");
554
+ return this.#json("PATCH", `/offers/${offerId}`, offerListItemSchema, data, options);
555
+ }
395
556
  createDepartment(data, options = {}) {
396
557
  return this.#json("POST", "/departments", createDepartmentResponseSchema, data, options);
397
558
  }
559
+ /**
560
+ * List departments configured on the calling VCR — `internalId`,
561
+ * `externalId`, `taxRegime`, and the localized `title`. Mirrors the
562
+ * dashboard catalog: only departments confirmed by the tax service are
563
+ * returned, so the `internalId` field is safe to reference from a sale
564
+ * item's `department.id`.
565
+ */
566
+ listDepartments(options = {}) {
567
+ return this.#json("GET", "/departments", departmentListResponseSchema, void 0, options);
568
+ }
398
569
  // ─── Classifier search ────────────────────────────────────────────────────
399
570
  searchClassifier(input, options = {}) {
400
571
  return this.#json(
@@ -461,12 +632,21 @@ exports.classifierSearchResponseSchema = classifierSearchResponseSchema;
461
632
  exports.createCashierResponseSchema = createCashierResponseSchema;
462
633
  exports.createDepartmentResponseSchema = createDepartmentResponseSchema;
463
634
  exports.createOfferResponseSchema = createOfferResponseSchema;
635
+ exports.customerPrepaymentBalanceResponseSchema = customerPrepaymentBalanceResponseSchema;
636
+ exports.departmentListItemSchema = departmentListItemSchema;
637
+ exports.departmentListResponseSchema = departmentListResponseSchema;
638
+ exports.offerListItemSchema = offerListItemSchema;
639
+ exports.offerListResponseSchema = offerListResponseSchema;
464
640
  exports.prepaymentDetailResponseSchema = prepaymentDetailResponseSchema;
641
+ exports.prepaymentListItemSchema = prepaymentListItemSchema;
642
+ exports.prepaymentListResponseSchema = prepaymentListResponseSchema;
643
+ exports.prepaymentStateSchema = prepaymentStateSchema;
465
644
  exports.registerPrepaymentRefundResponseSchema = registerPrepaymentRefundResponseSchema;
466
645
  exports.registerPrepaymentResponseSchema = registerPrepaymentResponseSchema;
467
646
  exports.registerSaleRefundResponseSchema = registerSaleRefundResponseSchema;
468
647
  exports.registerSaleResponseSchema = registerSaleResponseSchema;
469
648
  exports.saleDetailResponseSchema = saleDetailResponseSchema;
470
649
  exports.unitsKeys = unitsKeys;
650
+ exports.whoamiResponseSchema = whoamiResponseSchema;
471
651
  //# sourceMappingURL=index.cjs.map
472
652
  //# sourceMappingURL=index.cjs.map