@blob-solutions/vcr-am-sdk 0.14.0 → 0.16.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,50 @@
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.16.0] — 2026-07-10
6
+
7
+ ### Added
8
+
9
+ - **`RegisterSaleInput.comment?: string`** — an optional merchant-internal note on a sale, e.g. an external payment reference for reconciliation. Max 500 characters; the server strips control characters and trims surrounding whitespace, and normalizes an empty result to "no comment". It is purely internal: it is **never** printed on the buyer's receipt and **never** sent to the tax authority (SRC). Omit the field (or send an empty string) for no comment.
10
+
11
+ ```ts
12
+ await vcr.registerSale({
13
+ cashier: { id: 1 },
14
+ items: [{ offer: { id: 5 }, department: { id: 1 }, quantity: "1", price: "4000", unit: "pc" }],
15
+ amount: { cash: "4000" },
16
+ comment: "Stripe pi_3Qc...",
17
+ });
18
+ ```
19
+
20
+ - **`SaleDetail.comment: string | null`** — `getSale(id)` now returns the sale's comment (or `null` when none was set), so an integration can read back the reference it attached.
21
+
22
+ ## [0.15.0] — 2026-07-09
23
+
24
+ Fixes the foreign-currency request contract, which 0.14.0 modeled incorrectly, and closes the last two gaps against `/api/v1` (`autoSettle` and `GET /exchange-rate`).
25
+
26
+ ### Fixed — foreign-currency contract (breaking, but 0.14.0's shape never worked)
27
+
28
+ - **Removed `RegisterSaleInput.currencyConversion` and the `CurrencyConversionInput` type.** The API never accepted a top-level `currencyConversion` block — `POST /sales` silently stripped it, so a "foreign-currency" sale sent via 0.14.0 was fiscalized with no HO-234-N conversion trail at all. The real contract is **per-item**: set `SaleItem.currency` (ISO 4217, e.g. `"USD"`) and denominate that item's `price` in the foreign currency; VCR converts every line to AMD server-side at the previous-business-day CBA rate. All foreign-priced items in one sale must share one currency, and mixing AMD with foreign lines is rejected.
29
+
30
+ ```diff
31
+ - items: [{ offer: { id: 5 }, department: { id: 1 }, quantity: "1", price: "4000", unit: "pc" }],
32
+ - currencyConversion: { currency: "USD", ratePerUnit: "400", rateDate: "2026-07-07", lines: [{ foreignUnitPrice: "10" }] },
33
+ - amount: { cash: "4000" },
34
+ + items: [{ offer: { id: 5 }, department: { id: 1 }, quantity: "1", price: "10", currency: "USD", unit: "pc" }],
35
+ + autoSettle: { tender: "cash" },
36
+ ```
37
+
38
+ ### Added
39
+
40
+ - `SaleItem.currency?: string` — per-item ISO 4217 input currency (see above). Omit or `"AMD"` for a native AMD line.
41
+ - `RegisterSaleInput.autoSettle?: { tender: "cash" | "nonCash" }` — derived-total payment: VCR computes the AMD cart total and charges the whole of it to one tender. A sale now carries **exactly one** of `amount` (explicit AMD) or `autoSettle`; the types enforce the XOR, mirroring the server's cross-field validation. The essential companion to foreign-currency sales, where the AMD total is not knowable client-side. New exported types `AutoSettle`, `SalePayment`.
42
+ - `getExchangeRate({ currency })` — wraps `GET /exchange-rate`. Previews the AMD conversion rate VCR would apply to a foreign-currency sale registered now (CBA mid-market rate, previous business day, HO-234-N). Read-only; rejects `AMD`. New type `ExchangeRate`, new schema `exchangeRateResponseSchema`.
43
+
44
+ ### Changed
45
+
46
+ - `RegisterSaleInput.amount` is no longer required on its own — it is one arm of the `amount` / `autoSettle` union. Existing `{ ..., amount }` call sites are unaffected.
47
+ - Dev tooling patch bumps (`@tsconfig/node24`, `@tsconfig/strictest`, `vite`). No change to the published package. TypeScript 7, pnpm 11, and `@types/node` 26 are available but intentionally deferred (kept aligned with the platform monorepo, which pins TypeScript 5.9).
48
+
5
49
  ## [0.14.0] — 2026-07-08
6
50
 
7
51
  Closes the drift that had accumulated against `/api/v1` since 0.13.0. Everything here is additive — no call-site changes required.
package/README.md CHANGED
@@ -125,23 +125,25 @@ const refund = await vcr.registerSaleRefund({
125
125
  });
126
126
  ```
127
127
 
128
+ **Payment: `amount` or `autoSettle`.** A sale settles by *exactly one* of these — never both (the types enforce it):
129
+
130
+ - `amount` — explicit AMD per tender (`{ cash?, nonCash?, prepayment?, compensation? }`), as in the quick-start.
131
+ - `autoSettle: { tender: "cash" | "nonCash" }` — VCR computes the AMD cart total and charges the whole of it to that one tender. Zero-tap: you don't sum the cart yourself, and it's the only sane option for a foreign-currency sale (you can't know the AMD total up front).
132
+
133
+ **Comment** (optional): pass `comment` to attach a merchant-internal note to the sale — typically an external payment reference for reconciliation (`comment: "Stripe pi_3Qc..."`). Max 500 characters; the server strips control characters and trims whitespace. It is purely internal — never printed on the buyer's receipt and never sent to the tax authority — and `getSale(id)` reads it back as `SaleDetail.comment`.
134
+
128
135
  **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
136
 
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.
137
+ **Foreign-currency sales** (HO-234-N): set `currency` on each item and price that item in the foreign currency. VCR converts every line to AMD server-side at the previous-business-day CBA mid-market rate; the fiscal receipt is always AMD. All foreign-priced items in one sale must share the same currency, and mixing AMD with foreign lines is rejected. Preview the rate first with [`getExchangeRate`](#exchange-rate).
131
138
 
132
139
  ```typescript
133
140
  await vcr.registerSale({
134
141
  cashier: { id: 1 },
135
142
  items: [
136
- { offer: { id: 5 }, department: { id: 1 }, quantity: "1", price: "4000", unit: "pc" },
143
+ // price is in USD; VCR converts to AMD.
144
+ { offer: { id: 5 }, department: { id: 1 }, quantity: "1", price: "10", currency: "USD", unit: "pc" },
137
145
  ],
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" },
146
+ autoSettle: { tender: "cash" }, // AMD total is server-derived
145
147
  buyer: { type: "individual" },
146
148
  });
147
149
  ```
@@ -212,6 +214,20 @@ const matches = await vcr.searchClassifier({
212
214
  });
213
215
  ```
214
216
 
217
+ ### Exchange rate
218
+
219
+ | Method | Endpoint | Returns |
220
+ | ----------------------------------- | -------------------- | -------------- |
221
+ | `getExchangeRate({ currency })` | `GET /exchange-rate` | `ExchangeRate` |
222
+
223
+ Previews the AMD conversion rate VCR would apply to a foreign-currency sale registered now — the CBA mid-market rate published on the previous business day (HO-234-N). Read-only; it does not fiscalize anything. `currency` is a 3-letter ISO 4217 code (case-insensitive); `AMD` is rejected.
224
+
225
+ ```typescript
226
+ const rate = await vcr.getExchangeRate({ currency: "USD" });
227
+ // { currency: "USD", ratePerUnit: 397.12, amount: 1, rateDate: "2026-07-08", ... }
228
+ const amdEquivalent = Number(usdPrice) * rate.ratePerUnit;
229
+ ```
230
+
215
231
  ## Error handling
216
232
 
217
233
  All SDK errors derive from `VCRError`. Catch the base class for a single handler, or narrow on the specific subclass.
@@ -262,7 +278,7 @@ The whole request flow — connection, body read, schema parse — is bounded by
262
278
 
263
279
  ## Idempotency and retries
264
280
 
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`).
281
+ **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`, `getExchangeRate`).
266
282
 
267
283
  ## Browser usage
268
284
 
package/lib/index.cjs CHANGED
@@ -155,6 +155,21 @@ var createDepartmentResponseSchema = zod.z.object({
155
155
  message: zod.z.string(),
156
156
  department: zod.z.number().int().nonnegative()
157
157
  });
158
+ var exchangeRateResponseSchema = zod.z.object({
159
+ /** ISO 4217 code, uppercased (echoes the requested currency). */
160
+ currency: zod.z.string(),
161
+ /** AMD per one unit of `currency` (CBA rate / amount). */
162
+ ratePerUnit: zod.z.number(),
163
+ /** CBA multi-lot multiplier (1, 100, 1000, ...). */
164
+ amount: zod.z.number().int(),
165
+ /** Yerevan date whose rate was applied — the previous business day. */
166
+ rateDate: zod.z.string(),
167
+ /** Yerevan calendar date the rate resolves for (server time). */
168
+ saleDate: zod.z.string(),
169
+ /** Legal rule version applied (e.g. "HO-234-N"). */
170
+ ruleVersion: zod.z.string(),
171
+ source: zod.z.literal("CBA")
172
+ });
158
173
  var whoamiResponseSchema = zod.z.object({
159
174
  vcrId: zod.z.number().int().nonnegative(),
160
175
  // `null` until the VCR is activated (freshly-imported registers have no CRN).
@@ -255,6 +270,7 @@ var saleDetailResponseSchema = zod.z.object({
255
270
  id: zod.z.number().int().nonnegative(),
256
271
  createdAt: isoDateTimeSchema,
257
272
  buyerTin: zod.z.string().nullable(),
273
+ comment: zod.z.string().nullable(),
258
274
  cashAmount: zod.z.number(),
259
275
  nonCashAmount: zod.z.number(),
260
276
  prepaymentAmount: zod.z.number(),
@@ -585,6 +601,23 @@ var VCRClient = class {
585
601
  searchClassifierCategory(query, type, language, options = {}) {
586
602
  return this.searchClassifier({ query, type, language }, options);
587
603
  }
604
+ // ─── Exchange rate ────────────────────────────────────────────────────────
605
+ /**
606
+ * Preview the AMD conversion rate VCR would apply to a foreign-currency sale
607
+ * registered now — the CBA mid-market rate published on the previous business
608
+ * day (Tax Code art. 16, HO-234-N). Use it to show a buyer the AMD equivalent
609
+ * before charging. The sale itself is converted server-side from each item's
610
+ * `currency` + `price` (see {@link RegisterSaleInput}); this endpoint is a
611
+ * read-only preview and does not fiscalize anything.
612
+ *
613
+ * `currency` is a 3-letter ISO 4217 code, case-insensitive. `AMD` is rejected
614
+ * (it is the native receipt currency and needs no conversion).
615
+ */
616
+ getExchangeRate(input, options = {}) {
617
+ return this.#json("GET", "/exchange-rate", exchangeRateResponseSchema, void 0, options, {
618
+ currency: input.currency
619
+ });
620
+ }
588
621
  // ─── Internal ─────────────────────────────────────────────────────────────
589
622
  #json(method, path, schema, body, options, query) {
590
623
  const url = query === void 0 ? `${this.#baseUrl}${path}` : appendQuery(`${this.#baseUrl}${path}`, query);
@@ -635,6 +668,7 @@ exports.createOfferResponseSchema = createOfferResponseSchema;
635
668
  exports.customerPrepaymentBalanceResponseSchema = customerPrepaymentBalanceResponseSchema;
636
669
  exports.departmentListItemSchema = departmentListItemSchema;
637
670
  exports.departmentListResponseSchema = departmentListResponseSchema;
671
+ exports.exchangeRateResponseSchema = exchangeRateResponseSchema;
638
672
  exports.offerListItemSchema = offerListItemSchema;
639
673
  exports.offerListResponseSchema = offerListResponseSchema;
640
674
  exports.prepaymentDetailResponseSchema = prepaymentDetailResponseSchema;
package/lib/index.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/errors.ts","../src/schemas.ts","../src/fetch.ts","../src/client.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["export const unitsKeys = [\n \"pc\",\n \"unit\",\n \"set\",\n \"box\",\n \"pack\",\n \"case\",\n \"hr\",\n \"sess\",\n \"proj\",\n \"sub\",\n \"kg\",\n \"l\",\n \"m\",\n \"g\",\n \"ml\",\n \"cm\",\n \"bottle\",\n \"can\",\n \"jar\",\n \"bag\",\n \"m2\",\n \"dozen\",\n \"pair\",\n \"mm\",\n \"roll\",\n \"tube\",\n \"km\",\n \"ton\",\n \"m3\",\n \"pallet\",\n \"other\",\n] as const;\n\nexport const AVAILABLE_LANGUAGES = [\"hy\", \"ru\", \"en\"] as const;\n\nexport const REFUND_REASONS = [\n \"customer_request\",\n \"defective_goods\",\n \"wrong_goods\",\n \"cashier_error\",\n \"duplicate_receipt\",\n \"other\",\n] as const;\n\nexport const TAX_REGIMES = [\"vat\", \"vat_exempt\", \"turnover_tax\", \"micro_enterprise\"] as const;\n\nexport const DEFAULT_API_URL = \"https://vcr.am/api/v1\";\nexport const DEFAULT_TIMEOUT_MS = 30_000;\n","import type { z } from \"zod\";\n\nexport type ApiErrorIssue = {\n path: Array<string | number>;\n message: string;\n code: string;\n};\n\nexport type ApiErrorBody = {\n error: string;\n issues?: Array<ApiErrorIssue>;\n /**\n * Server-generated correlation ID, present on unexpected 5xx responses.\n * Include it when reporting the issue to support so the matching log entry\n * and Sentry event can be located.\n */\n requestId?: string;\n};\n\n/**\n * Base class for every error thrown by the SDK.\n * Catch this if you want a single catch-all.\n */\nexport abstract class VCRError extends Error {\n abstract readonly kind: string;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = new.target.name;\n }\n}\n\n/**\n * Server returned a non-2xx response with a parseable JSON error body.\n * Mirrors the unified `{ error, issues? }` envelope from /api/v1.\n */\nexport class VCRApiError extends VCRError {\n readonly kind = \"api\" as const;\n\n constructor(\n readonly status: number,\n readonly body: ApiErrorBody,\n readonly url: string,\n ) {\n super(`VCR API ${status}: ${body.error}`);\n }\n}\n\n/**\n * Server returned a non-2xx response that did not match the error envelope,\n * or a 2xx response whose body did not match the expected schema.\n */\nexport class VCRValidationError extends VCRError {\n readonly kind = \"validation\" as const;\n\n constructor(\n message: string,\n readonly status: number,\n readonly url: string,\n readonly issues: z.ZodIssue[],\n readonly raw: unknown,\n ) {\n super(message);\n }\n}\n\n/**\n * Network-level failure: DNS, connection refused, timeout, abort.\n * The request never produced a parseable HTTP response.\n */\nexport class VCRNetworkError extends VCRError {\n readonly kind = \"network\" as const;\n\n constructor(\n message: string,\n readonly url: string,\n options: { cause: unknown },\n ) {\n super(message, options);\n }\n}\n","import { z } from \"zod\";\n\nimport { AVAILABLE_LANGUAGES, TAX_REGIMES, unitsKeys } from \"./constants\";\n\nexport const apiErrorBodySchema = z.object({\n error: z.string(),\n issues: z\n .array(\n z.object({\n path: z.array(z.union([z.string(), z.number()])),\n message: z.string(),\n code: z.string(),\n }),\n )\n .optional(),\n // Server-generated correlation ID present on unexpected 5xx responses.\n // Kept lenient (plain string, not `.uuid()`) so a malformed value can never\n // make the error envelope fail to parse and mask the real API error.\n requestId: z.string().optional(),\n});\n\nconst isoDateTimeSchema = z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/, \"Invalid ISO datetime\");\n\n// Detail responses use Prisma's `Language` enum, which is wider than\n// AVAILABLE_LANGUAGES — it also includes \"multi\" for cross-language content.\nconst detailLanguageSchema = z.enum([...AVAILABLE_LANGUAGES, \"multi\"]);\n\nconst localizationEntrySchema = z.object({\n id: z.number().int(),\n language: detailLanguageSchema,\n content: z.string(),\n});\n\nconst offerTypeSchema = z.enum([\"product\", \"service\"]);\nconst unitSchema = z.enum(unitsKeys);\nconst taxRegimeSchema = z.enum(TAX_REGIMES);\nconst discountTypeSchema = z.enum([\"percent\", \"price\", \"total\"]).nullable();\nconst additionalDiscountTypeSchema = z.enum([\"percent\", \"total\"]).nullable();\n\n// ─── Action responses ────────────────────────────────────────────────────────\n\nexport const registerSaleResponseSchema = z.object({\n urlId: z.string(),\n saleId: z.number().int().nonnegative(),\n crn: z.string(),\n srcReceiptId: z.number().int().nonnegative(),\n fiscal: z.string(),\n});\n\nexport const registerSaleRefundResponseSchema = z.object({\n urlId: z.string(),\n saleRefundId: z.number().int().nonnegative(),\n crn: z.string().nullable(),\n receiptId: z.number().int().nonnegative(),\n fiscal: z.string().nullable(),\n});\n\nexport const registerPrepaymentResponseSchema = z.object({\n urlId: z.string(),\n prepaymentId: z.number().int().nonnegative(),\n crn: z.string().nullable(),\n receiptId: z.number().int().nonnegative(),\n fiscal: z.string().nullable(),\n});\n\nexport const registerPrepaymentRefundResponseSchema = z.object({\n urlId: z.string(),\n prepaymentRefundId: z.number().int().nonnegative(),\n crn: z.string().nullable(),\n receiptId: z.number().int().nonnegative(),\n fiscal: z.string().nullable(),\n});\n\nexport const createOfferResponseSchema = z.object({\n offerId: z.number().int().nonnegative(),\n});\n\nexport const createCashierResponseSchema = z.object({\n id: z.number().int().nonnegative(),\n deskId: z.string(),\n});\n\nexport const createDepartmentResponseSchema = z.object({\n message: z.string(),\n department: z.number().int().nonnegative(),\n});\n\n// ─── Account ──────────────────────────────────────────────────────────────────\n\nexport const whoamiResponseSchema = z.object({\n vcrId: z.number().int().nonnegative(),\n // `null` until the VCR is activated (freshly-imported registers have no CRN).\n crn: z.string().nullable(),\n mode: z.enum([\"production\", \"sandbox\"]),\n tradingPlatformName: z.string(),\n businessEntity: z.object({\n tin: z.string(),\n name: z.string(),\n }),\n});\n\n// ─── List & search ──────────────────────────────────────────────────────────\n\nconst cashierNameLocalizationSchema = z.object({\n language: z.enum([...AVAILABLE_LANGUAGES, \"multi\"]),\n content: z.string(),\n});\n\nexport const cashierListItemSchema = z.object({\n deskId: z.string(),\n internalId: z.number().int().nonnegative(),\n name: z.record(z.string(), cashierNameLocalizationSchema),\n});\n\nexport const cashierListResponseSchema = z.array(cashierListItemSchema);\n\nexport const departmentListItemSchema = z.object({\n internalId: z.number().int().nonnegative(),\n externalId: z.string().nullable(),\n taxRegime: taxRegimeSchema,\n // Map from language code -> { language, content }, matching the wire\n // format produced by makeLocalizationObject on the server. May be empty\n // for legacy departments created before titles were mandatory.\n title: z.record(z.string(), localizationEntrySchema),\n});\n\nexport const departmentListResponseSchema = z.array(departmentListItemSchema);\n\nexport const classifierSearchItemSchema = z.object({\n code: z.string(),\n // Optional: server may emit `{ code }` without `title` when the classifier\n // entry exists in fuse but lacks a translation in the requested language.\n title: z.string().optional(),\n});\n\nexport const classifierSearchResponseSchema = z.array(classifierSearchItemSchema);\n\n// Offer list/detail rows carry their title as an array of localization\n// entries (matching the detail endpoints), NOT the language-keyed record used\n// by the cashier / department lists.\nexport const offerListItemSchema = z.object({\n id: z.number().int().nonnegative(),\n externalId: z.string().nullable(),\n type: offerTypeSchema,\n classifierCode: z.string(),\n // Server types this as a plain string (not the unit enum) to stay faithful\n // to whatever is stored; mirror it so a legacy unit can never fail parsing.\n defaultMeasureUnit: z.string(),\n defaultDepartment: z.object({ internalId: z.number().int().nonnegative() }),\n title: z.array(localizationEntrySchema),\n archivedAt: isoDateTimeSchema.nullable(),\n createdAt: isoDateTimeSchema,\n});\n\nexport const offerListResponseSchema = z.array(offerListItemSchema);\n\n// ─── Detail responses ───────────────────────────────────────────────────────\n//\n// Mirror the `pick + extend` shape produced by serializeForWire on the server.\n// Decimal columns (Prisma) arrive as numbers (z.number()), bigint as numeric\n// strings, and dates as ISO strings — matching the prisma-zod-generator output\n// the server validates against before responding.\n\nconst receiptPickSchema = z.object({\n srcId: z.number().int(),\n time: z.string().regex(/^\\d+$/, \"Invalid bigint string\"),\n tin: z.string(),\n fiscal: z.string().nullable(),\n sn: z.string(),\n address: z.string().nullable(),\n total: z.number(),\n taxpayer: z.string(),\n change: z.number(),\n});\n\nconst cashierPickSchema = z.object({\n internalId: z.number().int().nonnegative(),\n deskId: z.string(),\n name: z.array(localizationEntrySchema),\n});\n\nconst departmentPickSchema = z.object({\n internalId: z.number().int().nonnegative(),\n taxRegime: taxRegimeSchema,\n title: z.array(localizationEntrySchema),\n});\n\nconst offerPickSchema = z.object({\n type: offerTypeSchema,\n classifierCode: z.string(),\n title: z.array(localizationEntrySchema),\n});\n\nconst saleItemPickSchema = z.object({\n srcId: z.number().int(),\n quantity: z.number(),\n price: z.number(),\n unit: unitSchema,\n discount: z.number().nullable(),\n discountType: discountTypeSchema,\n additionalDiscount: z.number().nullable(),\n additionalDiscountType: additionalDiscountTypeSchema,\n department: departmentPickSchema,\n offer: offerPickSchema,\n});\n\nconst saleRefundPickSchema = z.object({\n nonCashAmount: z.number(),\n cashAmount: z.number(),\n receipt: receiptPickSchema.nullable(),\n items: z.array(z.object({ quantity: z.number() })),\n});\n\nexport const saleDetailResponseSchema = z.object({\n id: z.number().int().nonnegative(),\n createdAt: isoDateTimeSchema,\n buyerTin: z.string().nullable(),\n cashAmount: z.number(),\n nonCashAmount: z.number(),\n prepaymentAmount: z.number(),\n compensationAmount: z.number(),\n receipt: receiptPickSchema.nullable(),\n refunds: z.array(saleRefundPickSchema),\n cashier: cashierPickSchema,\n items: z.array(saleItemPickSchema),\n});\n\nconst prepaymentRefundPickSchema = z.object({\n nonCashAmount: z.number(),\n cashAmount: z.number(),\n receipt: receiptPickSchema.nullable(),\n});\n\n// `open` — remaining > 0; can still be applied or refunded.\n// `consumed` — fully applied to subsequent sales.\n// `refunded` — a PrepaymentRefund row exists (always full per AM Annex 3 §29).\nexport const prepaymentStateSchema = z.enum([\"open\", \"consumed\", \"refunded\"]);\n\nexport const prepaymentDetailResponseSchema = z.object({\n id: z.number().int().nonnegative(),\n createdAt: isoDateTimeSchema,\n buyerTin: z.string().nullable(),\n cashAmount: z.number(),\n nonCashAmount: z.number(),\n receipt: receiptPickSchema.nullable(),\n refund: prepaymentRefundPickSchema.nullable(),\n cashier: cashierPickSchema,\n /** SUM(amount) across all ledger rows for this prepayment. */\n remaining: z.number(),\n state: prepaymentStateSchema,\n});\n\nexport const prepaymentListItemSchema = z.object({\n id: z.number().int().nonnegative(),\n createdAt: isoDateTimeSchema,\n buyerTin: z.string().nullable(),\n cashAmount: z.number(),\n nonCashAmount: z.number(),\n remaining: z.number(),\n state: prepaymentStateSchema,\n});\n\nexport const prepaymentListResponseSchema = z.array(prepaymentListItemSchema);\n\nconst customerOpenPrepaymentSchema = z.object({\n prepaymentId: z.number().int().nonnegative(),\n createdAt: isoDateTimeSchema,\n cashAmount: z.number(),\n nonCashAmount: z.number(),\n buyerTin: z.string().nullable(),\n remaining: z.number(),\n});\n\nexport const customerPrepaymentBalanceResponseSchema = z.object({\n entityId: z.number().int().nonnegative(),\n customerRef: z.string(),\n /** Total remaining across all open prepayments matching customerRef. */\n balance: z.number(),\n /** FIFO-ordered open prepayments contributing to the balance. */\n openPrepayments: z.array(customerOpenPrepaymentSchema),\n});\n\n// ─── Inferred types ─────────────────────────────────────────────────────────\n\nexport type RegisterSaleResponse = z.infer<typeof registerSaleResponseSchema>;\nexport type RegisterSaleRefundResponse = z.infer<typeof registerSaleRefundResponseSchema>;\nexport type RegisterPrepaymentResponse = z.infer<typeof registerPrepaymentResponseSchema>;\nexport type RegisterPrepaymentRefundResponse = z.infer<\n typeof registerPrepaymentRefundResponseSchema\n>;\nexport type CreateOfferResponse = z.infer<typeof createOfferResponseSchema>;\nexport type CreateCashierResponse = z.infer<typeof createCashierResponseSchema>;\nexport type CreateDepartmentResponse = z.infer<typeof createDepartmentResponseSchema>;\nexport type CashierListItem = z.infer<typeof cashierListItemSchema>;\nexport type ClassifierSearchItem = z.infer<typeof classifierSearchItemSchema>;\nexport type Whoami = z.infer<typeof whoamiResponseSchema>;\nexport type OfferListItem = z.infer<typeof offerListItemSchema>;\nexport type SaleDetail = z.infer<typeof saleDetailResponseSchema>;\nexport type PrepaymentDetail = z.infer<typeof prepaymentDetailResponseSchema>;\nexport type PrepaymentListItem = z.infer<typeof prepaymentListItemSchema>;\nexport type PrepaymentState = z.infer<typeof prepaymentStateSchema>;\nexport type CustomerPrepaymentBalance = z.infer<typeof customerPrepaymentBalanceResponseSchema>;\nexport type DepartmentListItem = z.infer<typeof departmentListItemSchema>;\n","import type { z } from \"zod\";\n\nimport { type ApiErrorBody, VCRApiError, VCRNetworkError, VCRValidationError } from \"./errors\";\nimport { apiErrorBodySchema } from \"./schemas\";\n\nexport type RequestOptions = {\n signal?: AbortSignal;\n /** Override per-request timeout in ms. `null` disables the timeout. */\n timeoutMs?: number | null;\n};\n\nexport type FetchInit = {\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n url: string;\n apiKey: string;\n body?: unknown;\n fetchImpl: typeof fetch;\n defaultTimeoutMs: number | null;\n} & RequestOptions;\n\nexport async function requestJson<TSchema extends z.ZodTypeAny>(\n schema: TSchema,\n init: FetchInit,\n): Promise<z.infer<TSchema>> {\n const { url, method, apiKey, body, fetchImpl, signal: externalSignal } = init;\n\n const effectiveTimeout = init.timeoutMs === undefined ? init.defaultTimeoutMs : init.timeoutMs;\n\n const timeoutController = effectiveTimeout !== null ? new AbortController() : undefined;\n const timeoutHandle =\n timeoutController !== undefined && effectiveTimeout !== null\n ? setTimeout(() => timeoutController.abort(new Error(\"Request timeout\")), effectiveTimeout)\n : undefined;\n\n const signal = mergeSignals(externalSignal, timeoutController?.signal);\n\n const headers: Record<string, string> = {\n \"x-api-key\": apiKey,\n accept: \"application/json\",\n };\n\n const requestInit: RequestInit = { method, headers };\n if (body !== undefined) {\n headers[\"content-type\"] = \"application/json\";\n requestInit.body = JSON.stringify(body);\n }\n if (signal !== undefined) {\n requestInit.signal = signal;\n }\n\n // The whole flow — connect, body read, parse — must be bounded by the same\n // timeout. Clearing the timer earlier (e.g. after fetch resolves) leaves\n // body reading and parsing unprotected against slow/hanging servers.\n try {\n let response: Response;\n let rawText: string;\n try {\n response = await fetchImpl(url, requestInit);\n rawText = await response.text();\n } catch (cause) {\n throw new VCRNetworkError(\n cause instanceof Error ? cause.message : \"Network request failed\",\n url,\n { cause },\n );\n }\n\n const rawJson = rawText.length === 0 ? undefined : safeJsonParse(rawText);\n\n if (!response.ok) {\n throw buildApiError(response.status, rawJson, url);\n }\n\n const parsed = schema.safeParse(rawJson);\n if (!parsed.success) {\n throw new VCRValidationError(\n `VCR response did not match expected schema for ${method} ${url}`,\n response.status,\n url,\n parsed.error.issues,\n rawJson,\n );\n }\n\n return parsed.data;\n } finally {\n if (timeoutHandle !== undefined) {\n clearTimeout(timeoutHandle);\n }\n }\n}\n\nfunction buildApiError(\n status: number,\n rawJson: unknown,\n url: string,\n): VCRApiError | VCRValidationError {\n const parsed = apiErrorBodySchema.safeParse(rawJson);\n if (parsed.success) {\n const body: ApiErrorBody = {\n error: parsed.data.error,\n ...(parsed.data.issues !== undefined && { issues: parsed.data.issues }),\n ...(parsed.data.requestId !== undefined && { requestId: parsed.data.requestId }),\n };\n return new VCRApiError(status, body, url);\n }\n\n return new VCRValidationError(\n `VCR returned ${status} but the error body did not match the expected envelope`,\n status,\n url,\n parsed.error.issues,\n rawJson,\n );\n}\n\nfunction safeJsonParse(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction mergeSignals(...signals: ReadonlyArray<AbortSignal | undefined>): AbortSignal | undefined {\n const present = signals.filter((signal): signal is AbortSignal => signal !== undefined);\n if (present.length === 0) {\n return undefined;\n }\n return AbortSignal.any(present);\n}\n","import type { z } from \"zod\";\nimport { DEFAULT_API_URL, DEFAULT_TIMEOUT_MS } from \"./constants\";\nimport { type RequestOptions, requestJson } from \"./fetch\";\nimport {\n type CashierListItem,\n type ClassifierSearchItem,\n type CreateCashierResponse,\n type CreateDepartmentResponse,\n type CreateOfferResponse,\n type CustomerPrepaymentBalance,\n cashierListResponseSchema,\n classifierSearchResponseSchema,\n createCashierResponseSchema,\n createDepartmentResponseSchema,\n createOfferResponseSchema,\n customerPrepaymentBalanceResponseSchema,\n type DepartmentListItem,\n departmentListResponseSchema,\n type OfferListItem,\n offerListItemSchema,\n offerListResponseSchema,\n type PrepaymentDetail,\n type PrepaymentListItem,\n type PrepaymentState,\n prepaymentDetailResponseSchema,\n prepaymentListResponseSchema,\n type RegisterPrepaymentRefundResponse,\n type RegisterPrepaymentResponse,\n type RegisterSaleRefundResponse,\n type RegisterSaleResponse,\n registerPrepaymentRefundResponseSchema,\n registerPrepaymentResponseSchema,\n registerSaleRefundResponseSchema,\n registerSaleResponseSchema,\n type SaleDetail,\n saleDetailResponseSchema,\n type Whoami,\n whoamiResponseSchema,\n} from \"./schemas\";\nimport type {\n ClassifierType,\n CreateCashierInput,\n CreateDepartmentInput,\n CreateOfferInput,\n Language,\n ListOffersFilter,\n RegisterPrepaymentInput,\n RegisterPrepaymentRefundInput,\n RegisterSaleInput,\n RegisterSaleRefundInput,\n SearchClassifierInput,\n UpdateOfferInput,\n} from \"./types\";\n\nexport type ListPrepaymentsFilter = {\n /** Exact-match filter against ledger.customerRef (TIN / phone / email). */\n customerRef?: string;\n /**\n * Filter by derived lifecycle state. `all` (the default) returns every\n * prepayment; the other values filter to a single lifecycle stage.\n */\n state?: PrepaymentState | \"all\";\n};\n\nexport type VCRClientOptions = {\n /** Base URL for the VCR API. Defaults to https://vcr.am/api/v1. */\n baseUrl?: string;\n /** Custom fetch implementation. Defaults to the global `fetch`. */\n fetch?: typeof fetch;\n /** Default request timeout in ms. Pass `null` to disable. Default 30s. */\n timeoutMs?: number | null;\n};\n\ntype Method = \"GET\" | \"POST\" | \"PATCH\";\n\nexport class VCRClient {\n readonly #apiKey: string;\n readonly #baseUrl: string;\n readonly #fetch: typeof fetch;\n readonly #defaultTimeoutMs: number | null;\n\n constructor(apiKey: string, options: VCRClientOptions = {}) {\n if (apiKey.length === 0) {\n throw new Error(\"VCRClient requires a non-empty apiKey\");\n }\n this.#apiKey = apiKey;\n this.#baseUrl = stripTrailingSlash(options.baseUrl ?? DEFAULT_API_URL);\n\n const candidate = options.fetch ?? globalThis.fetch;\n if (typeof candidate !== \"function\") {\n throw new Error(\n \"No fetch implementation available. Provide options.fetch or use a runtime that exposes a global fetch.\",\n );\n }\n // Only bind the global fetch, which on some runtimes requires `this ===\n // globalThis`. A user-supplied fetch keeps its own `this` so wrappers\n // (e.g. class methods, fetch with closure state) keep working.\n this.#fetch = options.fetch === undefined ? candidate.bind(globalThis) : candidate;\n\n this.#defaultTimeoutMs =\n options.timeoutMs === undefined ? DEFAULT_TIMEOUT_MS : options.timeoutMs;\n }\n\n // ─── Account ──────────────────────────────────────────────────────────────\n\n /**\n * Resolve which VCR the calling API key belongs to. Returns the register's\n * identity, its `mode` (`production` / `sandbox`), and the owning business\n * entity. Works on freshly-imported VCRs that have not been activated yet\n * (in which case `crn` is `null`) — handy as a cheap SDK health-check and to\n * tell production keys apart from sandbox ones.\n */\n whoami(options: RequestOptions = {}): Promise<Whoami> {\n return this.#json(\"GET\", \"/whoami\", whoamiResponseSchema, undefined, options);\n }\n\n // ─── Sales ─────────────────────────────────────────────────────────────────\n\n registerSale(\n data: RegisterSaleInput,\n options: RequestOptions = {},\n ): Promise<RegisterSaleResponse> {\n return this.#json(\"POST\", \"/sales\", registerSaleResponseSchema, data, options);\n }\n\n getSale(saleId: number, options: RequestOptions = {}): Promise<SaleDetail> {\n assertNonNegativeInt(saleId, \"saleId\");\n return this.#json(\"GET\", `/sales/${saleId}`, saleDetailResponseSchema, undefined, options);\n }\n\n registerSaleRefund(\n data: RegisterSaleRefundInput,\n options: RequestOptions = {},\n ): Promise<RegisterSaleRefundResponse> {\n return this.#json(\"POST\", \"/sales/refund\", registerSaleRefundResponseSchema, data, options);\n }\n\n // ─── Prepayments ──────────────────────────────────────────────────────────\n\n registerPrepayment(\n data: RegisterPrepaymentInput,\n options: RequestOptions = {},\n ): Promise<RegisterPrepaymentResponse> {\n return this.#json(\"POST\", \"/prepayments\", registerPrepaymentResponseSchema, data, options);\n }\n\n getPrepayment(prepaymentId: number, options: RequestOptions = {}): Promise<PrepaymentDetail> {\n assertNonNegativeInt(prepaymentId, \"prepaymentId\");\n return this.#json(\n \"GET\",\n `/prepayments/${prepaymentId}`,\n prepaymentDetailResponseSchema,\n undefined,\n options,\n );\n }\n\n registerPrepaymentRefund(\n data: RegisterPrepaymentRefundInput,\n options: RequestOptions = {},\n ): Promise<RegisterPrepaymentRefundResponse> {\n return this.#json(\n \"POST\",\n \"/prepayments/refund\",\n registerPrepaymentRefundResponseSchema,\n data,\n options,\n );\n }\n\n /**\n * List prepayments registered through the calling VCR. Server caps the\n * response at 500 rows; for larger sets, narrow with `customerRef` or\n * paginate by `id` outside the SDK.\n *\n * `remaining` and `state` are derived from the ledger — call this whenever\n * you want a current snapshot rather than caching the result.\n */\n listPrepayments(\n filter: ListPrepaymentsFilter = {},\n options: RequestOptions = {},\n ): Promise<PrepaymentListItem[]> {\n const query: Record<string, string> = {};\n if (filter.customerRef !== undefined) query[\"customerRef\"] = filter.customerRef;\n if (filter.state !== undefined) query[\"state\"] = filter.state;\n return this.#json(\n \"GET\",\n \"/prepayments\",\n prepaymentListResponseSchema,\n undefined,\n options,\n Object.keys(query).length > 0 ? query : undefined,\n );\n }\n\n /**\n * Get a customer's open prepayment balance scoped to the BusinessEntity\n * that owns the calling VCR's API key. Because the ledger is entity-scoped,\n * the result reflects deposits made through any VCR belonging to the same\n * entity — merchants who run more than one VCR see a single wallet.\n *\n * `customerRef` is matched exactly against the ledger — typically a TIN,\n * normalized E.164 phone, or lowercased email. Use whichever identifier the\n * customer gave at deposit time; identities are not auto-merged across\n * different ref types.\n */\n getCustomerPrepaymentBalance(\n input: { customerRef: string },\n options: RequestOptions = {},\n ): Promise<CustomerPrepaymentBalance> {\n return this.#json(\n \"GET\",\n \"/prepayments/balance\",\n customerPrepaymentBalanceResponseSchema,\n undefined,\n options,\n { customerRef: input.customerRef },\n );\n }\n\n // ─── Cashiers ─────────────────────────────────────────────────────────────\n\n listCashiers(options: RequestOptions = {}): Promise<CashierListItem[]> {\n return this.#json(\"GET\", \"/cashiers\", cashierListResponseSchema, undefined, options);\n }\n\n createCashier(\n data: CreateCashierInput,\n options: RequestOptions = {},\n ): Promise<CreateCashierResponse> {\n return this.#json(\"POST\", \"/cashiers\", createCashierResponseSchema, data, options);\n }\n\n // ─── Offers / Departments ─────────────────────────────────────────────────\n\n createOffer(data: CreateOfferInput, options: RequestOptions = {}): Promise<CreateOfferResponse> {\n return this.#json(\"POST\", \"/offers\", createOfferResponseSchema, data, options);\n }\n\n /**\n * List offers belonging to the calling VCR. Server caps the response at 500\n * rows; narrow with `externalId` / `type` for larger catalogs. Archived\n * offers are excluded unless `includeArchived` is set.\n *\n * A common use is checking whether an offer already exists (by `externalId`)\n * before creating it.\n */\n listOffers(\n filter: ListOffersFilter = {},\n options: RequestOptions = {},\n ): Promise<OfferListItem[]> {\n const query: Record<string, string> = {};\n if (filter.externalId !== undefined) query[\"externalId\"] = filter.externalId;\n if (filter.type !== undefined) query[\"type\"] = filter.type;\n if (filter.includeArchived !== undefined) {\n query[\"includeArchived\"] = filter.includeArchived ? \"true\" : \"false\";\n }\n return this.#json(\n \"GET\",\n \"/offers\",\n offerListResponseSchema,\n undefined,\n options,\n Object.keys(query).length > 0 ? query : undefined,\n );\n }\n\n getOffer(offerId: number, options: RequestOptions = {}): Promise<OfferListItem> {\n assertNonNegativeInt(offerId, \"offerId\");\n return this.#json(\"GET\", `/offers/${offerId}`, offerListItemSchema, undefined, options);\n }\n\n /**\n * Rename an offer's title. Affects only future receipts — already-issued\n * receipts keep the title they were created with, and the SRC fiscal record\n * is unchanged. Missing `en`/`ru` are filled per `localizationStrategy`,\n * exactly as on offer creation. Returns the updated offer.\n */\n updateOffer(\n offerId: number,\n data: UpdateOfferInput,\n options: RequestOptions = {},\n ): Promise<OfferListItem> {\n assertNonNegativeInt(offerId, \"offerId\");\n return this.#json(\"PATCH\", `/offers/${offerId}`, offerListItemSchema, data, options);\n }\n\n createDepartment(\n data: CreateDepartmentInput,\n options: RequestOptions = {},\n ): Promise<CreateDepartmentResponse> {\n return this.#json(\"POST\", \"/departments\", createDepartmentResponseSchema, data, options);\n }\n\n /**\n * List departments configured on the calling VCR — `internalId`,\n * `externalId`, `taxRegime`, and the localized `title`. Mirrors the\n * dashboard catalog: only departments confirmed by the tax service are\n * returned, so the `internalId` field is safe to reference from a sale\n * item's `department.id`.\n */\n listDepartments(options: RequestOptions = {}): Promise<DepartmentListItem[]> {\n return this.#json(\"GET\", \"/departments\", departmentListResponseSchema, undefined, options);\n }\n\n // ─── Classifier search ────────────────────────────────────────────────────\n\n searchClassifier(\n input: SearchClassifierInput,\n options: RequestOptions = {},\n ): Promise<ClassifierSearchItem[]> {\n return this.#json(\n \"GET\",\n \"/searchByClassifier\",\n classifierSearchResponseSchema,\n undefined,\n options,\n { query: input.query, type: input.type, language: input.language },\n );\n }\n\n /**\n * @deprecated Use {@link searchClassifier} with an options object. Will be\n * removed in 1.0. The new signature accepts `{ query, type, language }` so\n * future params can be added without breaking the call site.\n */\n searchClassifierCategory(\n query: string,\n type: ClassifierType,\n language: Language,\n options: RequestOptions = {},\n ): Promise<ClassifierSearchItem[]> {\n return this.searchClassifier({ query, type, language }, options);\n }\n\n // ─── Internal ─────────────────────────────────────────────────────────────\n\n #json<TSchema extends z.ZodTypeAny>(\n method: Method,\n path: string,\n schema: TSchema,\n body: unknown,\n options: RequestOptions,\n query?: Record<string, string>,\n ): Promise<z.infer<TSchema>> {\n const url =\n query === undefined\n ? `${this.#baseUrl}${path}`\n : appendQuery(`${this.#baseUrl}${path}`, query);\n\n return requestJson(schema, {\n method,\n url,\n apiKey: this.#apiKey,\n ...(body !== undefined && { body }),\n fetchImpl: this.#fetch,\n defaultTimeoutMs: this.#defaultTimeoutMs,\n ...options,\n });\n }\n}\n\nfunction appendQuery(url: string, query: Record<string, string>): string {\n const u = new URL(url);\n for (const [key, value] of Object.entries(query)) {\n u.searchParams.set(key, value);\n }\n return u.toString();\n}\n\nfunction stripTrailingSlash(url: string): string {\n return url.endsWith(\"/\") ? url.slice(0, -1) : url;\n}\n\nfunction assertNonNegativeInt(value: number, name: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(`${name} must be a non-negative integer (got ${value})`);\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/errors.ts","../src/schemas.ts","../src/fetch.ts","../src/client.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["export const unitsKeys = [\n \"pc\",\n \"unit\",\n \"set\",\n \"box\",\n \"pack\",\n \"case\",\n \"hr\",\n \"sess\",\n \"proj\",\n \"sub\",\n \"kg\",\n \"l\",\n \"m\",\n \"g\",\n \"ml\",\n \"cm\",\n \"bottle\",\n \"can\",\n \"jar\",\n \"bag\",\n \"m2\",\n \"dozen\",\n \"pair\",\n \"mm\",\n \"roll\",\n \"tube\",\n \"km\",\n \"ton\",\n \"m3\",\n \"pallet\",\n \"other\",\n] as const;\n\nexport const AVAILABLE_LANGUAGES = [\"hy\", \"ru\", \"en\"] as const;\n\nexport const REFUND_REASONS = [\n \"customer_request\",\n \"defective_goods\",\n \"wrong_goods\",\n \"cashier_error\",\n \"duplicate_receipt\",\n \"other\",\n] as const;\n\nexport const TAX_REGIMES = [\"vat\", \"vat_exempt\", \"turnover_tax\", \"micro_enterprise\"] as const;\n\nexport const DEFAULT_API_URL = \"https://vcr.am/api/v1\";\nexport const DEFAULT_TIMEOUT_MS = 30_000;\n","import type { z } from \"zod\";\n\nexport type ApiErrorIssue = {\n path: Array<string | number>;\n message: string;\n code: string;\n};\n\nexport type ApiErrorBody = {\n error: string;\n issues?: Array<ApiErrorIssue>;\n /**\n * Server-generated correlation ID, present on unexpected 5xx responses.\n * Include it when reporting the issue to support so the matching log entry\n * and Sentry event can be located.\n */\n requestId?: string;\n};\n\n/**\n * Base class for every error thrown by the SDK.\n * Catch this if you want a single catch-all.\n */\nexport abstract class VCRError extends Error {\n abstract readonly kind: string;\n\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = new.target.name;\n }\n}\n\n/**\n * Server returned a non-2xx response with a parseable JSON error body.\n * Mirrors the unified `{ error, issues? }` envelope from /api/v1.\n */\nexport class VCRApiError extends VCRError {\n readonly kind = \"api\" as const;\n\n constructor(\n readonly status: number,\n readonly body: ApiErrorBody,\n readonly url: string,\n ) {\n super(`VCR API ${status}: ${body.error}`);\n }\n}\n\n/**\n * Server returned a non-2xx response that did not match the error envelope,\n * or a 2xx response whose body did not match the expected schema.\n */\nexport class VCRValidationError extends VCRError {\n readonly kind = \"validation\" as const;\n\n constructor(\n message: string,\n readonly status: number,\n readonly url: string,\n readonly issues: z.ZodIssue[],\n readonly raw: unknown,\n ) {\n super(message);\n }\n}\n\n/**\n * Network-level failure: DNS, connection refused, timeout, abort.\n * The request never produced a parseable HTTP response.\n */\nexport class VCRNetworkError extends VCRError {\n readonly kind = \"network\" as const;\n\n constructor(\n message: string,\n readonly url: string,\n options: { cause: unknown },\n ) {\n super(message, options);\n }\n}\n","import { z } from \"zod\";\n\nimport { AVAILABLE_LANGUAGES, TAX_REGIMES, unitsKeys } from \"./constants\";\n\nexport const apiErrorBodySchema = z.object({\n error: z.string(),\n issues: z\n .array(\n z.object({\n path: z.array(z.union([z.string(), z.number()])),\n message: z.string(),\n code: z.string(),\n }),\n )\n .optional(),\n // Server-generated correlation ID present on unexpected 5xx responses.\n // Kept lenient (plain string, not `.uuid()`) so a malformed value can never\n // make the error envelope fail to parse and mask the real API error.\n requestId: z.string().optional(),\n});\n\nconst isoDateTimeSchema = z\n .string()\n .regex(/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/, \"Invalid ISO datetime\");\n\n// Detail responses use Prisma's `Language` enum, which is wider than\n// AVAILABLE_LANGUAGES — it also includes \"multi\" for cross-language content.\nconst detailLanguageSchema = z.enum([...AVAILABLE_LANGUAGES, \"multi\"]);\n\nconst localizationEntrySchema = z.object({\n id: z.number().int(),\n language: detailLanguageSchema,\n content: z.string(),\n});\n\nconst offerTypeSchema = z.enum([\"product\", \"service\"]);\nconst unitSchema = z.enum(unitsKeys);\nconst taxRegimeSchema = z.enum(TAX_REGIMES);\nconst discountTypeSchema = z.enum([\"percent\", \"price\", \"total\"]).nullable();\nconst additionalDiscountTypeSchema = z.enum([\"percent\", \"total\"]).nullable();\n\n// ─── Action responses ────────────────────────────────────────────────────────\n\nexport const registerSaleResponseSchema = z.object({\n urlId: z.string(),\n saleId: z.number().int().nonnegative(),\n crn: z.string(),\n srcReceiptId: z.number().int().nonnegative(),\n fiscal: z.string(),\n});\n\nexport const registerSaleRefundResponseSchema = z.object({\n urlId: z.string(),\n saleRefundId: z.number().int().nonnegative(),\n crn: z.string().nullable(),\n receiptId: z.number().int().nonnegative(),\n fiscal: z.string().nullable(),\n});\n\nexport const registerPrepaymentResponseSchema = z.object({\n urlId: z.string(),\n prepaymentId: z.number().int().nonnegative(),\n crn: z.string().nullable(),\n receiptId: z.number().int().nonnegative(),\n fiscal: z.string().nullable(),\n});\n\nexport const registerPrepaymentRefundResponseSchema = z.object({\n urlId: z.string(),\n prepaymentRefundId: z.number().int().nonnegative(),\n crn: z.string().nullable(),\n receiptId: z.number().int().nonnegative(),\n fiscal: z.string().nullable(),\n});\n\nexport const createOfferResponseSchema = z.object({\n offerId: z.number().int().nonnegative(),\n});\n\nexport const createCashierResponseSchema = z.object({\n id: z.number().int().nonnegative(),\n deskId: z.string(),\n});\n\nexport const createDepartmentResponseSchema = z.object({\n message: z.string(),\n department: z.number().int().nonnegative(),\n});\n\n// ─── Exchange rate ────────────────────────────────────────────────────────────\n\n// Mirrors the server's ExchangeRate response. `rateDate` / `saleDate` are kept\n// as plain strings (not a date-format regex) so a wire value can never make the\n// response fail to parse — the server already guarantees `YYYY-MM-DD`.\nexport const exchangeRateResponseSchema = z.object({\n /** ISO 4217 code, uppercased (echoes the requested currency). */\n currency: z.string(),\n /** AMD per one unit of `currency` (CBA rate / amount). */\n ratePerUnit: z.number(),\n /** CBA multi-lot multiplier (1, 100, 1000, ...). */\n amount: z.number().int(),\n /** Yerevan date whose rate was applied — the previous business day. */\n rateDate: z.string(),\n /** Yerevan calendar date the rate resolves for (server time). */\n saleDate: z.string(),\n /** Legal rule version applied (e.g. \"HO-234-N\"). */\n ruleVersion: z.string(),\n source: z.literal(\"CBA\"),\n});\n\n// ─── Account ──────────────────────────────────────────────────────────────────\n\nexport const whoamiResponseSchema = z.object({\n vcrId: z.number().int().nonnegative(),\n // `null` until the VCR is activated (freshly-imported registers have no CRN).\n crn: z.string().nullable(),\n mode: z.enum([\"production\", \"sandbox\"]),\n tradingPlatformName: z.string(),\n businessEntity: z.object({\n tin: z.string(),\n name: z.string(),\n }),\n});\n\n// ─── List & search ──────────────────────────────────────────────────────────\n\nconst cashierNameLocalizationSchema = z.object({\n language: z.enum([...AVAILABLE_LANGUAGES, \"multi\"]),\n content: z.string(),\n});\n\nexport const cashierListItemSchema = z.object({\n deskId: z.string(),\n internalId: z.number().int().nonnegative(),\n name: z.record(z.string(), cashierNameLocalizationSchema),\n});\n\nexport const cashierListResponseSchema = z.array(cashierListItemSchema);\n\nexport const departmentListItemSchema = z.object({\n internalId: z.number().int().nonnegative(),\n externalId: z.string().nullable(),\n taxRegime: taxRegimeSchema,\n // Map from language code -> { language, content }, matching the wire\n // format produced by makeLocalizationObject on the server. May be empty\n // for legacy departments created before titles were mandatory.\n title: z.record(z.string(), localizationEntrySchema),\n});\n\nexport const departmentListResponseSchema = z.array(departmentListItemSchema);\n\nexport const classifierSearchItemSchema = z.object({\n code: z.string(),\n // Optional: server may emit `{ code }` without `title` when the classifier\n // entry exists in fuse but lacks a translation in the requested language.\n title: z.string().optional(),\n});\n\nexport const classifierSearchResponseSchema = z.array(classifierSearchItemSchema);\n\n// Offer list/detail rows carry their title as an array of localization\n// entries (matching the detail endpoints), NOT the language-keyed record used\n// by the cashier / department lists.\nexport const offerListItemSchema = z.object({\n id: z.number().int().nonnegative(),\n externalId: z.string().nullable(),\n type: offerTypeSchema,\n classifierCode: z.string(),\n // Server types this as a plain string (not the unit enum) to stay faithful\n // to whatever is stored; mirror it so a legacy unit can never fail parsing.\n defaultMeasureUnit: z.string(),\n defaultDepartment: z.object({ internalId: z.number().int().nonnegative() }),\n title: z.array(localizationEntrySchema),\n archivedAt: isoDateTimeSchema.nullable(),\n createdAt: isoDateTimeSchema,\n});\n\nexport const offerListResponseSchema = z.array(offerListItemSchema);\n\n// ─── Detail responses ───────────────────────────────────────────────────────\n//\n// Mirror the `pick + extend` shape produced by serializeForWire on the server.\n// Decimal columns (Prisma) arrive as numbers (z.number()), bigint as numeric\n// strings, and dates as ISO strings — matching the prisma-zod-generator output\n// the server validates against before responding.\n\nconst receiptPickSchema = z.object({\n srcId: z.number().int(),\n time: z.string().regex(/^\\d+$/, \"Invalid bigint string\"),\n tin: z.string(),\n fiscal: z.string().nullable(),\n sn: z.string(),\n address: z.string().nullable(),\n total: z.number(),\n taxpayer: z.string(),\n change: z.number(),\n});\n\nconst cashierPickSchema = z.object({\n internalId: z.number().int().nonnegative(),\n deskId: z.string(),\n name: z.array(localizationEntrySchema),\n});\n\nconst departmentPickSchema = z.object({\n internalId: z.number().int().nonnegative(),\n taxRegime: taxRegimeSchema,\n title: z.array(localizationEntrySchema),\n});\n\nconst offerPickSchema = z.object({\n type: offerTypeSchema,\n classifierCode: z.string(),\n title: z.array(localizationEntrySchema),\n});\n\nconst saleItemPickSchema = z.object({\n srcId: z.number().int(),\n quantity: z.number(),\n price: z.number(),\n unit: unitSchema,\n discount: z.number().nullable(),\n discountType: discountTypeSchema,\n additionalDiscount: z.number().nullable(),\n additionalDiscountType: additionalDiscountTypeSchema,\n department: departmentPickSchema,\n offer: offerPickSchema,\n});\n\nconst saleRefundPickSchema = z.object({\n nonCashAmount: z.number(),\n cashAmount: z.number(),\n receipt: receiptPickSchema.nullable(),\n items: z.array(z.object({ quantity: z.number() })),\n});\n\nexport const saleDetailResponseSchema = z.object({\n id: z.number().int().nonnegative(),\n createdAt: isoDateTimeSchema,\n buyerTin: z.string().nullable(),\n comment: z.string().nullable(),\n cashAmount: z.number(),\n nonCashAmount: z.number(),\n prepaymentAmount: z.number(),\n compensationAmount: z.number(),\n receipt: receiptPickSchema.nullable(),\n refunds: z.array(saleRefundPickSchema),\n cashier: cashierPickSchema,\n items: z.array(saleItemPickSchema),\n});\n\nconst prepaymentRefundPickSchema = z.object({\n nonCashAmount: z.number(),\n cashAmount: z.number(),\n receipt: receiptPickSchema.nullable(),\n});\n\n// `open` — remaining > 0; can still be applied or refunded.\n// `consumed` — fully applied to subsequent sales.\n// `refunded` — a PrepaymentRefund row exists (always full per AM Annex 3 §29).\nexport const prepaymentStateSchema = z.enum([\"open\", \"consumed\", \"refunded\"]);\n\nexport const prepaymentDetailResponseSchema = z.object({\n id: z.number().int().nonnegative(),\n createdAt: isoDateTimeSchema,\n buyerTin: z.string().nullable(),\n cashAmount: z.number(),\n nonCashAmount: z.number(),\n receipt: receiptPickSchema.nullable(),\n refund: prepaymentRefundPickSchema.nullable(),\n cashier: cashierPickSchema,\n /** SUM(amount) across all ledger rows for this prepayment. */\n remaining: z.number(),\n state: prepaymentStateSchema,\n});\n\nexport const prepaymentListItemSchema = z.object({\n id: z.number().int().nonnegative(),\n createdAt: isoDateTimeSchema,\n buyerTin: z.string().nullable(),\n cashAmount: z.number(),\n nonCashAmount: z.number(),\n remaining: z.number(),\n state: prepaymentStateSchema,\n});\n\nexport const prepaymentListResponseSchema = z.array(prepaymentListItemSchema);\n\nconst customerOpenPrepaymentSchema = z.object({\n prepaymentId: z.number().int().nonnegative(),\n createdAt: isoDateTimeSchema,\n cashAmount: z.number(),\n nonCashAmount: z.number(),\n buyerTin: z.string().nullable(),\n remaining: z.number(),\n});\n\nexport const customerPrepaymentBalanceResponseSchema = z.object({\n entityId: z.number().int().nonnegative(),\n customerRef: z.string(),\n /** Total remaining across all open prepayments matching customerRef. */\n balance: z.number(),\n /** FIFO-ordered open prepayments contributing to the balance. */\n openPrepayments: z.array(customerOpenPrepaymentSchema),\n});\n\n// ─── Inferred types ─────────────────────────────────────────────────────────\n\nexport type RegisterSaleResponse = z.infer<typeof registerSaleResponseSchema>;\nexport type RegisterSaleRefundResponse = z.infer<typeof registerSaleRefundResponseSchema>;\nexport type RegisterPrepaymentResponse = z.infer<typeof registerPrepaymentResponseSchema>;\nexport type RegisterPrepaymentRefundResponse = z.infer<\n typeof registerPrepaymentRefundResponseSchema\n>;\nexport type CreateOfferResponse = z.infer<typeof createOfferResponseSchema>;\nexport type CreateCashierResponse = z.infer<typeof createCashierResponseSchema>;\nexport type CreateDepartmentResponse = z.infer<typeof createDepartmentResponseSchema>;\nexport type CashierListItem = z.infer<typeof cashierListItemSchema>;\nexport type ClassifierSearchItem = z.infer<typeof classifierSearchItemSchema>;\nexport type Whoami = z.infer<typeof whoamiResponseSchema>;\nexport type OfferListItem = z.infer<typeof offerListItemSchema>;\nexport type SaleDetail = z.infer<typeof saleDetailResponseSchema>;\nexport type PrepaymentDetail = z.infer<typeof prepaymentDetailResponseSchema>;\nexport type PrepaymentListItem = z.infer<typeof prepaymentListItemSchema>;\nexport type PrepaymentState = z.infer<typeof prepaymentStateSchema>;\nexport type CustomerPrepaymentBalance = z.infer<typeof customerPrepaymentBalanceResponseSchema>;\nexport type DepartmentListItem = z.infer<typeof departmentListItemSchema>;\nexport type ExchangeRate = z.infer<typeof exchangeRateResponseSchema>;\n","import type { z } from \"zod\";\n\nimport { type ApiErrorBody, VCRApiError, VCRNetworkError, VCRValidationError } from \"./errors\";\nimport { apiErrorBodySchema } from \"./schemas\";\n\nexport type RequestOptions = {\n signal?: AbortSignal;\n /** Override per-request timeout in ms. `null` disables the timeout. */\n timeoutMs?: number | null;\n};\n\nexport type FetchInit = {\n method: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\n url: string;\n apiKey: string;\n body?: unknown;\n fetchImpl: typeof fetch;\n defaultTimeoutMs: number | null;\n} & RequestOptions;\n\nexport async function requestJson<TSchema extends z.ZodTypeAny>(\n schema: TSchema,\n init: FetchInit,\n): Promise<z.infer<TSchema>> {\n const { url, method, apiKey, body, fetchImpl, signal: externalSignal } = init;\n\n const effectiveTimeout = init.timeoutMs === undefined ? init.defaultTimeoutMs : init.timeoutMs;\n\n const timeoutController = effectiveTimeout !== null ? new AbortController() : undefined;\n const timeoutHandle =\n timeoutController !== undefined && effectiveTimeout !== null\n ? setTimeout(() => timeoutController.abort(new Error(\"Request timeout\")), effectiveTimeout)\n : undefined;\n\n const signal = mergeSignals(externalSignal, timeoutController?.signal);\n\n const headers: Record<string, string> = {\n \"x-api-key\": apiKey,\n accept: \"application/json\",\n };\n\n const requestInit: RequestInit = { method, headers };\n if (body !== undefined) {\n headers[\"content-type\"] = \"application/json\";\n requestInit.body = JSON.stringify(body);\n }\n if (signal !== undefined) {\n requestInit.signal = signal;\n }\n\n // The whole flow — connect, body read, parse — must be bounded by the same\n // timeout. Clearing the timer earlier (e.g. after fetch resolves) leaves\n // body reading and parsing unprotected against slow/hanging servers.\n try {\n let response: Response;\n let rawText: string;\n try {\n response = await fetchImpl(url, requestInit);\n rawText = await response.text();\n } catch (cause) {\n throw new VCRNetworkError(\n cause instanceof Error ? cause.message : \"Network request failed\",\n url,\n { cause },\n );\n }\n\n const rawJson = rawText.length === 0 ? undefined : safeJsonParse(rawText);\n\n if (!response.ok) {\n throw buildApiError(response.status, rawJson, url);\n }\n\n const parsed = schema.safeParse(rawJson);\n if (!parsed.success) {\n throw new VCRValidationError(\n `VCR response did not match expected schema for ${method} ${url}`,\n response.status,\n url,\n parsed.error.issues,\n rawJson,\n );\n }\n\n return parsed.data;\n } finally {\n if (timeoutHandle !== undefined) {\n clearTimeout(timeoutHandle);\n }\n }\n}\n\nfunction buildApiError(\n status: number,\n rawJson: unknown,\n url: string,\n): VCRApiError | VCRValidationError {\n const parsed = apiErrorBodySchema.safeParse(rawJson);\n if (parsed.success) {\n const body: ApiErrorBody = {\n error: parsed.data.error,\n ...(parsed.data.issues !== undefined && { issues: parsed.data.issues }),\n ...(parsed.data.requestId !== undefined && { requestId: parsed.data.requestId }),\n };\n return new VCRApiError(status, body, url);\n }\n\n return new VCRValidationError(\n `VCR returned ${status} but the error body did not match the expected envelope`,\n status,\n url,\n parsed.error.issues,\n rawJson,\n );\n}\n\nfunction safeJsonParse(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return text;\n }\n}\n\nfunction mergeSignals(...signals: ReadonlyArray<AbortSignal | undefined>): AbortSignal | undefined {\n const present = signals.filter((signal): signal is AbortSignal => signal !== undefined);\n if (present.length === 0) {\n return undefined;\n }\n return AbortSignal.any(present);\n}\n","import type { z } from \"zod\";\nimport { DEFAULT_API_URL, DEFAULT_TIMEOUT_MS } from \"./constants\";\nimport { type RequestOptions, requestJson } from \"./fetch\";\nimport {\n type CashierListItem,\n type ClassifierSearchItem,\n type CreateCashierResponse,\n type CreateDepartmentResponse,\n type CreateOfferResponse,\n type CustomerPrepaymentBalance,\n cashierListResponseSchema,\n classifierSearchResponseSchema,\n createCashierResponseSchema,\n createDepartmentResponseSchema,\n createOfferResponseSchema,\n customerPrepaymentBalanceResponseSchema,\n type DepartmentListItem,\n departmentListResponseSchema,\n type ExchangeRate,\n exchangeRateResponseSchema,\n type OfferListItem,\n offerListItemSchema,\n offerListResponseSchema,\n type PrepaymentDetail,\n type PrepaymentListItem,\n type PrepaymentState,\n prepaymentDetailResponseSchema,\n prepaymentListResponseSchema,\n type RegisterPrepaymentRefundResponse,\n type RegisterPrepaymentResponse,\n type RegisterSaleRefundResponse,\n type RegisterSaleResponse,\n registerPrepaymentRefundResponseSchema,\n registerPrepaymentResponseSchema,\n registerSaleRefundResponseSchema,\n registerSaleResponseSchema,\n type SaleDetail,\n saleDetailResponseSchema,\n type Whoami,\n whoamiResponseSchema,\n} from \"./schemas\";\nimport type {\n ClassifierType,\n CreateCashierInput,\n CreateDepartmentInput,\n CreateOfferInput,\n Language,\n ListOffersFilter,\n RegisterPrepaymentInput,\n RegisterPrepaymentRefundInput,\n RegisterSaleInput,\n RegisterSaleRefundInput,\n SearchClassifierInput,\n UpdateOfferInput,\n} from \"./types\";\n\nexport type ListPrepaymentsFilter = {\n /** Exact-match filter against ledger.customerRef (TIN / phone / email). */\n customerRef?: string;\n /**\n * Filter by derived lifecycle state. `all` (the default) returns every\n * prepayment; the other values filter to a single lifecycle stage.\n */\n state?: PrepaymentState | \"all\";\n};\n\nexport type VCRClientOptions = {\n /** Base URL for the VCR API. Defaults to https://vcr.am/api/v1. */\n baseUrl?: string;\n /** Custom fetch implementation. Defaults to the global `fetch`. */\n fetch?: typeof fetch;\n /** Default request timeout in ms. Pass `null` to disable. Default 30s. */\n timeoutMs?: number | null;\n};\n\ntype Method = \"GET\" | \"POST\" | \"PATCH\";\n\nexport class VCRClient {\n readonly #apiKey: string;\n readonly #baseUrl: string;\n readonly #fetch: typeof fetch;\n readonly #defaultTimeoutMs: number | null;\n\n constructor(apiKey: string, options: VCRClientOptions = {}) {\n if (apiKey.length === 0) {\n throw new Error(\"VCRClient requires a non-empty apiKey\");\n }\n this.#apiKey = apiKey;\n this.#baseUrl = stripTrailingSlash(options.baseUrl ?? DEFAULT_API_URL);\n\n const candidate = options.fetch ?? globalThis.fetch;\n if (typeof candidate !== \"function\") {\n throw new Error(\n \"No fetch implementation available. Provide options.fetch or use a runtime that exposes a global fetch.\",\n );\n }\n // Only bind the global fetch, which on some runtimes requires `this ===\n // globalThis`. A user-supplied fetch keeps its own `this` so wrappers\n // (e.g. class methods, fetch with closure state) keep working.\n this.#fetch = options.fetch === undefined ? candidate.bind(globalThis) : candidate;\n\n this.#defaultTimeoutMs =\n options.timeoutMs === undefined ? DEFAULT_TIMEOUT_MS : options.timeoutMs;\n }\n\n // ─── Account ──────────────────────────────────────────────────────────────\n\n /**\n * Resolve which VCR the calling API key belongs to. Returns the register's\n * identity, its `mode` (`production` / `sandbox`), and the owning business\n * entity. Works on freshly-imported VCRs that have not been activated yet\n * (in which case `crn` is `null`) — handy as a cheap SDK health-check and to\n * tell production keys apart from sandbox ones.\n */\n whoami(options: RequestOptions = {}): Promise<Whoami> {\n return this.#json(\"GET\", \"/whoami\", whoamiResponseSchema, undefined, options);\n }\n\n // ─── Sales ─────────────────────────────────────────────────────────────────\n\n registerSale(\n data: RegisterSaleInput,\n options: RequestOptions = {},\n ): Promise<RegisterSaleResponse> {\n return this.#json(\"POST\", \"/sales\", registerSaleResponseSchema, data, options);\n }\n\n getSale(saleId: number, options: RequestOptions = {}): Promise<SaleDetail> {\n assertNonNegativeInt(saleId, \"saleId\");\n return this.#json(\"GET\", `/sales/${saleId}`, saleDetailResponseSchema, undefined, options);\n }\n\n registerSaleRefund(\n data: RegisterSaleRefundInput,\n options: RequestOptions = {},\n ): Promise<RegisterSaleRefundResponse> {\n return this.#json(\"POST\", \"/sales/refund\", registerSaleRefundResponseSchema, data, options);\n }\n\n // ─── Prepayments ──────────────────────────────────────────────────────────\n\n registerPrepayment(\n data: RegisterPrepaymentInput,\n options: RequestOptions = {},\n ): Promise<RegisterPrepaymentResponse> {\n return this.#json(\"POST\", \"/prepayments\", registerPrepaymentResponseSchema, data, options);\n }\n\n getPrepayment(prepaymentId: number, options: RequestOptions = {}): Promise<PrepaymentDetail> {\n assertNonNegativeInt(prepaymentId, \"prepaymentId\");\n return this.#json(\n \"GET\",\n `/prepayments/${prepaymentId}`,\n prepaymentDetailResponseSchema,\n undefined,\n options,\n );\n }\n\n registerPrepaymentRefund(\n data: RegisterPrepaymentRefundInput,\n options: RequestOptions = {},\n ): Promise<RegisterPrepaymentRefundResponse> {\n return this.#json(\n \"POST\",\n \"/prepayments/refund\",\n registerPrepaymentRefundResponseSchema,\n data,\n options,\n );\n }\n\n /**\n * List prepayments registered through the calling VCR. Server caps the\n * response at 500 rows; for larger sets, narrow with `customerRef` or\n * paginate by `id` outside the SDK.\n *\n * `remaining` and `state` are derived from the ledger — call this whenever\n * you want a current snapshot rather than caching the result.\n */\n listPrepayments(\n filter: ListPrepaymentsFilter = {},\n options: RequestOptions = {},\n ): Promise<PrepaymentListItem[]> {\n const query: Record<string, string> = {};\n if (filter.customerRef !== undefined) query[\"customerRef\"] = filter.customerRef;\n if (filter.state !== undefined) query[\"state\"] = filter.state;\n return this.#json(\n \"GET\",\n \"/prepayments\",\n prepaymentListResponseSchema,\n undefined,\n options,\n Object.keys(query).length > 0 ? query : undefined,\n );\n }\n\n /**\n * Get a customer's open prepayment balance scoped to the BusinessEntity\n * that owns the calling VCR's API key. Because the ledger is entity-scoped,\n * the result reflects deposits made through any VCR belonging to the same\n * entity — merchants who run more than one VCR see a single wallet.\n *\n * `customerRef` is matched exactly against the ledger — typically a TIN,\n * normalized E.164 phone, or lowercased email. Use whichever identifier the\n * customer gave at deposit time; identities are not auto-merged across\n * different ref types.\n */\n getCustomerPrepaymentBalance(\n input: { customerRef: string },\n options: RequestOptions = {},\n ): Promise<CustomerPrepaymentBalance> {\n return this.#json(\n \"GET\",\n \"/prepayments/balance\",\n customerPrepaymentBalanceResponseSchema,\n undefined,\n options,\n { customerRef: input.customerRef },\n );\n }\n\n // ─── Cashiers ─────────────────────────────────────────────────────────────\n\n listCashiers(options: RequestOptions = {}): Promise<CashierListItem[]> {\n return this.#json(\"GET\", \"/cashiers\", cashierListResponseSchema, undefined, options);\n }\n\n createCashier(\n data: CreateCashierInput,\n options: RequestOptions = {},\n ): Promise<CreateCashierResponse> {\n return this.#json(\"POST\", \"/cashiers\", createCashierResponseSchema, data, options);\n }\n\n // ─── Offers / Departments ─────────────────────────────────────────────────\n\n createOffer(data: CreateOfferInput, options: RequestOptions = {}): Promise<CreateOfferResponse> {\n return this.#json(\"POST\", \"/offers\", createOfferResponseSchema, data, options);\n }\n\n /**\n * List offers belonging to the calling VCR. Server caps the response at 500\n * rows; narrow with `externalId` / `type` for larger catalogs. Archived\n * offers are excluded unless `includeArchived` is set.\n *\n * A common use is checking whether an offer already exists (by `externalId`)\n * before creating it.\n */\n listOffers(\n filter: ListOffersFilter = {},\n options: RequestOptions = {},\n ): Promise<OfferListItem[]> {\n const query: Record<string, string> = {};\n if (filter.externalId !== undefined) query[\"externalId\"] = filter.externalId;\n if (filter.type !== undefined) query[\"type\"] = filter.type;\n if (filter.includeArchived !== undefined) {\n query[\"includeArchived\"] = filter.includeArchived ? \"true\" : \"false\";\n }\n return this.#json(\n \"GET\",\n \"/offers\",\n offerListResponseSchema,\n undefined,\n options,\n Object.keys(query).length > 0 ? query : undefined,\n );\n }\n\n getOffer(offerId: number, options: RequestOptions = {}): Promise<OfferListItem> {\n assertNonNegativeInt(offerId, \"offerId\");\n return this.#json(\"GET\", `/offers/${offerId}`, offerListItemSchema, undefined, options);\n }\n\n /**\n * Rename an offer's title. Affects only future receipts — already-issued\n * receipts keep the title they were created with, and the SRC fiscal record\n * is unchanged. Missing `en`/`ru` are filled per `localizationStrategy`,\n * exactly as on offer creation. Returns the updated offer.\n */\n updateOffer(\n offerId: number,\n data: UpdateOfferInput,\n options: RequestOptions = {},\n ): Promise<OfferListItem> {\n assertNonNegativeInt(offerId, \"offerId\");\n return this.#json(\"PATCH\", `/offers/${offerId}`, offerListItemSchema, data, options);\n }\n\n createDepartment(\n data: CreateDepartmentInput,\n options: RequestOptions = {},\n ): Promise<CreateDepartmentResponse> {\n return this.#json(\"POST\", \"/departments\", createDepartmentResponseSchema, data, options);\n }\n\n /**\n * List departments configured on the calling VCR — `internalId`,\n * `externalId`, `taxRegime`, and the localized `title`. Mirrors the\n * dashboard catalog: only departments confirmed by the tax service are\n * returned, so the `internalId` field is safe to reference from a sale\n * item's `department.id`.\n */\n listDepartments(options: RequestOptions = {}): Promise<DepartmentListItem[]> {\n return this.#json(\"GET\", \"/departments\", departmentListResponseSchema, undefined, options);\n }\n\n // ─── Classifier search ────────────────────────────────────────────────────\n\n searchClassifier(\n input: SearchClassifierInput,\n options: RequestOptions = {},\n ): Promise<ClassifierSearchItem[]> {\n return this.#json(\n \"GET\",\n \"/searchByClassifier\",\n classifierSearchResponseSchema,\n undefined,\n options,\n { query: input.query, type: input.type, language: input.language },\n );\n }\n\n /**\n * @deprecated Use {@link searchClassifier} with an options object. Will be\n * removed in 1.0. The new signature accepts `{ query, type, language }` so\n * future params can be added without breaking the call site.\n */\n searchClassifierCategory(\n query: string,\n type: ClassifierType,\n language: Language,\n options: RequestOptions = {},\n ): Promise<ClassifierSearchItem[]> {\n return this.searchClassifier({ query, type, language }, options);\n }\n\n // ─── Exchange rate ────────────────────────────────────────────────────────\n\n /**\n * Preview the AMD conversion rate VCR would apply to a foreign-currency sale\n * registered now — the CBA mid-market rate published on the previous business\n * day (Tax Code art. 16, HO-234-N). Use it to show a buyer the AMD equivalent\n * before charging. The sale itself is converted server-side from each item's\n * `currency` + `price` (see {@link RegisterSaleInput}); this endpoint is a\n * read-only preview and does not fiscalize anything.\n *\n * `currency` is a 3-letter ISO 4217 code, case-insensitive. `AMD` is rejected\n * (it is the native receipt currency and needs no conversion).\n */\n getExchangeRate(\n input: { currency: string },\n options: RequestOptions = {},\n ): Promise<ExchangeRate> {\n return this.#json(\"GET\", \"/exchange-rate\", exchangeRateResponseSchema, undefined, options, {\n currency: input.currency,\n });\n }\n\n // ─── Internal ─────────────────────────────────────────────────────────────\n\n #json<TSchema extends z.ZodTypeAny>(\n method: Method,\n path: string,\n schema: TSchema,\n body: unknown,\n options: RequestOptions,\n query?: Record<string, string>,\n ): Promise<z.infer<TSchema>> {\n const url =\n query === undefined\n ? `${this.#baseUrl}${path}`\n : appendQuery(`${this.#baseUrl}${path}`, query);\n\n return requestJson(schema, {\n method,\n url,\n apiKey: this.#apiKey,\n ...(body !== undefined && { body }),\n fetchImpl: this.#fetch,\n defaultTimeoutMs: this.#defaultTimeoutMs,\n ...options,\n });\n }\n}\n\nfunction appendQuery(url: string, query: Record<string, string>): string {\n const u = new URL(url);\n for (const [key, value] of Object.entries(query)) {\n u.searchParams.set(key, value);\n }\n return u.toString();\n}\n\nfunction stripTrailingSlash(url: string): string {\n return url.endsWith(\"/\") ? url.slice(0, -1) : url;\n}\n\nfunction assertNonNegativeInt(value: number, name: string): void {\n if (!Number.isInteger(value) || value < 0) {\n throw new Error(`${name} must be a non-negative integer (got ${value})`);\n }\n}\n"]}
package/lib/index.d.cts CHANGED
@@ -45,6 +45,15 @@ declare const createDepartmentResponseSchema: z.ZodObject<{
45
45
  message: z.ZodString;
46
46
  department: z.ZodNumber;
47
47
  }, z.core.$strip>;
48
+ declare const exchangeRateResponseSchema: z.ZodObject<{
49
+ currency: z.ZodString;
50
+ ratePerUnit: z.ZodNumber;
51
+ amount: z.ZodNumber;
52
+ rateDate: z.ZodString;
53
+ saleDate: z.ZodString;
54
+ ruleVersion: z.ZodString;
55
+ source: z.ZodLiteral<"CBA">;
56
+ }, z.core.$strip>;
48
57
  declare const whoamiResponseSchema: z.ZodObject<{
49
58
  vcrId: z.ZodNumber;
50
59
  crn: z.ZodNullable<z.ZodString>;
@@ -186,6 +195,7 @@ declare const saleDetailResponseSchema: z.ZodObject<{
186
195
  id: z.ZodNumber;
187
196
  createdAt: z.ZodString;
188
197
  buyerTin: z.ZodNullable<z.ZodString>;
198
+ comment: z.ZodNullable<z.ZodString>;
189
199
  cashAmount: z.ZodNumber;
190
200
  nonCashAmount: z.ZodNumber;
191
201
  prepaymentAmount: z.ZodNumber;
@@ -433,6 +443,7 @@ type PrepaymentListItem = z.infer<typeof prepaymentListItemSchema>;
433
443
  type PrepaymentState = z.infer<typeof prepaymentStateSchema>;
434
444
  type CustomerPrepaymentBalance = z.infer<typeof customerPrepaymentBalanceResponseSchema>;
435
445
  type DepartmentListItem = z.infer<typeof departmentListItemSchema>;
446
+ type ExchangeRate = z.infer<typeof exchangeRateResponseSchema>;
436
447
 
437
448
  declare const unitsKeys: readonly ["pc", "unit", "set", "box", "pack", "case", "hr", "sess", "proj", "sub", "kg", "l", "m", "g", "ml", "cm", "bottle", "can", "jar", "bag", "m2", "dozen", "pair", "mm", "roll", "tube", "km", "ton", "m3", "pallet", "other"];
438
449
  declare const AVAILABLE_LANGUAGES: readonly ["hy", "ru", "en"];
@@ -527,7 +538,27 @@ type SaleItem = {
527
538
  offer: Offer;
528
539
  department: DepartmentInput;
529
540
  quantity: string;
541
+ /**
542
+ * Unit price. AMD by default. When {@link SaleItem.currency} is set to a
543
+ * non-AMD code, this value is denominated in that foreign currency and VCR
544
+ * converts it to AMD server-side at the authoritative CBA rate — never send
545
+ * a pre-converted AMD figure alongside a `currency`.
546
+ */
530
547
  price: string;
548
+ /**
549
+ * Optional ISO 4217 input currency for foreign-currency sales (HO-234-N,
550
+ * server-side conversion). Omit — or set to `"AMD"` — for a native AMD line.
551
+ *
552
+ * When set to a non-AMD code (e.g. `"USD"`, `"RUB"`), `price` is read in that
553
+ * currency and VCR converts every line to AMD at the previous-business-day
554
+ * CBA mid-market rate; the fiscal receipt is always issued in AMD. All
555
+ * foreign-priced items in one sale MUST share the same currency — mixing two
556
+ * currencies, or AMD and foreign lines, in a single sale is rejected. Pair
557
+ * with `autoSettle` (see {@link RegisterSaleInput}) so you don't have to know
558
+ * the AMD total up front, and preview the applied rate via
559
+ * {@link VCRClient.getExchangeRate}. Normalized to uppercase server-side.
560
+ */
561
+ currency?: string;
531
562
  unit: Unit;
532
563
  discounts?: Discounts;
533
564
  totalAmountTolerance?: string;
@@ -537,27 +568,6 @@ type SaleItem = {
537
568
  */
538
569
  emarks?: string[];
539
570
  };
540
- /**
541
- * Foreign-currency input trail (HO-234-N). Present only when the sale was
542
- * entered in a non-AMD currency; omit it entirely for native-AMD sales.
543
- *
544
- * The AMD `price` values in `items[]` remain the authoritative fiscal figures.
545
- * This block carries the raw foreign inputs plus the CBA rate the client used;
546
- * the server re-resolves the previous-business-day rate and rejects the sale
547
- * if the supplied rate is stale.
548
- */
549
- type CurrencyConversionInput = {
550
- /** 3-letter ISO 4217 code (normalized to uppercase server-side). Not AMD. */
551
- currency: string;
552
- /** AMD per one unit of `currency` (CBA rate / amount). */
553
- ratePerUnit: string;
554
- /** Rate date in `YYYY-MM-DD` (CBA previous business day). */
555
- rateDate: string;
556
- /** Per-line foreign unit prices, index-aligned to `items[]`. At least one. */
557
- lines: Array<{
558
- foreignUnitPrice: string;
559
- }>;
560
- };
561
571
  type SaleAmount = RequireAtLeastOne<{
562
572
  prepayment?: string;
563
573
  compensation?: string;
@@ -594,17 +604,44 @@ type LegalEntityBuyer = BuyerContact & {
594
604
  receipt?: SendReceiptToBuyer;
595
605
  };
596
606
  type Buyer = IndividualBuyer | LegalEntityBuyer;
607
+ /**
608
+ * Derived-total payment: name a single tender and VCR settles the whole
609
+ * server-computed AMD cart total on it. Only `cash` / `nonCash` — `prepayment`
610
+ * and `compensation` are ledger draws that must be stated explicitly via
611
+ * {@link SaleAmount}. Ideal for foreign-currency sales (the AMD total isn't
612
+ * known client-side) or any sale that would rather not sum the cart itself.
613
+ */
614
+ type AutoSettle = {
615
+ tender: "cash" | "nonCash";
616
+ };
617
+ /** Explicit AMD amount per tender. Mutually exclusive with `autoSettle`. */
618
+ type PayByAmount = {
619
+ amount: SaleAmount;
620
+ autoSettle?: never;
621
+ };
622
+ /** VCR derives the AMD total onto one tender. Mutually exclusive with `amount`. */
623
+ type PayByAutoSettle = {
624
+ autoSettle: AutoSettle;
625
+ amount?: never;
626
+ };
627
+ /**
628
+ * A sale settles EITHER by explicit `amount` OR by `autoSettle` — exactly one,
629
+ * never both. The `never` guards make passing both a compile error, mirroring
630
+ * the server's cross-field validation.
631
+ */
632
+ type SalePayment = PayByAmount | PayByAutoSettle;
597
633
  type RegisterSaleInput = {
598
634
  cashier: CashierId;
599
635
  items: SaleItem[];
636
+ buyer: Buyer;
600
637
  /**
601
- * Optional foreign-currency input. Absent => native-AMD sale, byte-identical
602
- * to the pre-existing behaviour. See {@link CurrencyConversionInput}.
638
+ * Optional merchant-internal note, e.g. an external payment reference. Max
639
+ * 500 characters; control characters are stripped and surrounding whitespace
640
+ * trimmed server-side. It is purely internal: never printed on the buyer's
641
+ * receipt and never sent to the tax authority (SRC).
603
642
  */
604
- currencyConversion?: CurrencyConversionInput;
605
- amount: SaleAmount;
606
- buyer: Buyer;
607
- };
643
+ comment?: string;
644
+ } & SalePayment;
608
645
  /** @deprecated Use {@link RegisterSaleInput} instead. Will be removed in 1.0. */
609
646
  type SaleData = RegisterSaleInput;
610
647
  type ClassifierType = "product" | "service";
@@ -807,6 +844,20 @@ declare class VCRClient {
807
844
  * future params can be added without breaking the call site.
808
845
  */
809
846
  searchClassifierCategory(query: string, type: ClassifierType, language: Language, options?: RequestOptions): Promise<ClassifierSearchItem[]>;
847
+ /**
848
+ * Preview the AMD conversion rate VCR would apply to a foreign-currency sale
849
+ * registered now — the CBA mid-market rate published on the previous business
850
+ * day (Tax Code art. 16, HO-234-N). Use it to show a buyer the AMD equivalent
851
+ * before charging. The sale itself is converted server-side from each item's
852
+ * `currency` + `price` (see {@link RegisterSaleInput}); this endpoint is a
853
+ * read-only preview and does not fiscalize anything.
854
+ *
855
+ * `currency` is a 3-letter ISO 4217 code, case-insensitive. `AMD` is rejected
856
+ * (it is the native receipt currency and needs no conversion).
857
+ */
858
+ getExchangeRate(input: {
859
+ currency: string;
860
+ }, options?: RequestOptions): Promise<ExchangeRate>;
810
861
  }
811
862
 
812
863
  type ApiErrorIssue = {
@@ -869,4 +920,4 @@ declare class VCRNetworkError extends VCRError {
869
920
  });
870
921
  }
871
922
 
872
- export { AVAILABLE_LANGUAGES, type ApiErrorBody, type ApiErrorIssue, type Buyer, type CashierId, type CashierListItem, type ClassifierSearchItem, type ClassifierType, type CreateCashierInput, type CreateCashierResponse, type CreateDepartmentInput, type CreateDepartmentResponse, type CreateOfferInput, type CreateOfferInputProduct, type CreateOfferInputService, type CreateOfferResponse, type CreateOfferTitle, type CurrencyConversionInput, type CustomerPrepaymentBalance, DEFAULT_API_URL, DEFAULT_TIMEOUT_MS, type DepartmentInput, type DepartmentListItem, type Discounts, type Language, type LegacyOfferTitle, type ListOffersFilter, type ListPrepaymentsFilter, type LocalizedName, type NewOffer, type Offer, type OfferListItem, type OfferTitle, type PrepaymentAmount, type PrepaymentDetail, type PrepaymentListItem, type PrepaymentState, REFUND_REASONS, type RefundAmount, type RefundItemInput, type RefundReason, type RegisterPrepaymentInput, type RegisterPrepaymentRefundInput, type RegisterPrepaymentRefundResponse, type RegisterPrepaymentResponse, type RegisterSaleInput, type RegisterSaleRefundInput, type RegisterSaleRefundResponse, type RegisterSaleResponse, type RequestOptions, type SaleAmount, type SaleData, type SaleDetail, type SaleItem, type SearchClassifierInput, type SendReceiptToBuyer, TAX_REGIMES, type TaxRegime, type Unit, type UpdateOfferInput, VCRApiError, VCRClient, type VCRClientOptions, VCRError, VCRNetworkError, VCRValidationError, type Whoami, cashierListItemSchema, cashierListResponseSchema, classifierSearchItemSchema, classifierSearchResponseSchema, createCashierResponseSchema, createDepartmentResponseSchema, createOfferResponseSchema, customerPrepaymentBalanceResponseSchema, departmentListItemSchema, departmentListResponseSchema, offerListItemSchema, offerListResponseSchema, prepaymentDetailResponseSchema, prepaymentListItemSchema, prepaymentListResponseSchema, prepaymentStateSchema, registerPrepaymentRefundResponseSchema, registerPrepaymentResponseSchema, registerSaleRefundResponseSchema, registerSaleResponseSchema, saleDetailResponseSchema, unitsKeys, whoamiResponseSchema };
923
+ export { AVAILABLE_LANGUAGES, type ApiErrorBody, type ApiErrorIssue, type AutoSettle, type Buyer, type CashierId, type CashierListItem, type ClassifierSearchItem, type ClassifierType, type CreateCashierInput, type CreateCashierResponse, type CreateDepartmentInput, type CreateDepartmentResponse, type CreateOfferInput, type CreateOfferInputProduct, type CreateOfferInputService, type CreateOfferResponse, type CreateOfferTitle, type CustomerPrepaymentBalance, DEFAULT_API_URL, DEFAULT_TIMEOUT_MS, type DepartmentInput, type DepartmentListItem, type Discounts, type ExchangeRate, type Language, type LegacyOfferTitle, type ListOffersFilter, type ListPrepaymentsFilter, type LocalizedName, type NewOffer, type Offer, type OfferListItem, type OfferTitle, type PrepaymentAmount, type PrepaymentDetail, type PrepaymentListItem, type PrepaymentState, REFUND_REASONS, type RefundAmount, type RefundItemInput, type RefundReason, type RegisterPrepaymentInput, type RegisterPrepaymentRefundInput, type RegisterPrepaymentRefundResponse, type RegisterPrepaymentResponse, type RegisterSaleInput, type RegisterSaleRefundInput, type RegisterSaleRefundResponse, type RegisterSaleResponse, type RequestOptions, type SaleAmount, type SaleData, type SaleDetail, type SaleItem, type SalePayment, type SearchClassifierInput, type SendReceiptToBuyer, TAX_REGIMES, type TaxRegime, type Unit, type UpdateOfferInput, VCRApiError, VCRClient, type VCRClientOptions, VCRError, VCRNetworkError, VCRValidationError, type Whoami, cashierListItemSchema, cashierListResponseSchema, classifierSearchItemSchema, classifierSearchResponseSchema, createCashierResponseSchema, createDepartmentResponseSchema, createOfferResponseSchema, customerPrepaymentBalanceResponseSchema, departmentListItemSchema, departmentListResponseSchema, exchangeRateResponseSchema, offerListItemSchema, offerListResponseSchema, prepaymentDetailResponseSchema, prepaymentListItemSchema, prepaymentListResponseSchema, prepaymentStateSchema, registerPrepaymentRefundResponseSchema, registerPrepaymentResponseSchema, registerSaleRefundResponseSchema, registerSaleResponseSchema, saleDetailResponseSchema, unitsKeys, whoamiResponseSchema };