@blob-solutions/vcr-am-sdk 0.15.0 → 0.17.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,53 @@
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.17.0] — 2026-08-28
6
+
7
+ Makes a `502` from an unreachable tax service recoverable. Until now the SDK told you the call failed but gave you no way to learn whether the document survived, and the only obvious response — retry — was the one that creates a duplicate fiscal receipt.
8
+
9
+ ### Added
10
+
11
+ - **`ApiErrorBody.pending?: PendingResource`** — a `502` raised because SRC was unreachable now carries `{ type, id, statusUrl }`. It means the document **was** persisted and queued for automatic resubmission: do not resend it. Previously the SDK dropped the field, because the error envelope parses with a non-strict `z.object` and unknown keys are silently stripped.
12
+
13
+ ```ts
14
+ try {
15
+ await vcr.registerSale(sale);
16
+ } catch (error) {
17
+ if (error instanceof VCRApiError && error.body.pending !== undefined) {
18
+ await queue.push(error.body.pending); // nothing was lost
19
+ return;
20
+ }
21
+ throw error;
22
+ }
23
+ ```
24
+
25
+ `type` is a plain string rather than an enum on purpose: if the server adds a pending resource type an older SDK does not know about, an enum would fail the whole envelope and mask the real API error.
26
+
27
+ - **`RequestOptions.idempotencyKey?: string`** — sends an `Idempotency-Key` header on document-creating calls. Same key and same body replays the original response verbatim (with `Idempotent-Replay: true`) instead of creating a second document; same key with a different body is a `422`; same key while the first call is still in flight is a `409`. Keys are scoped per register and per endpoint and retained for 24 hours.
28
+
29
+ The SDK deliberately does **not** generate the key. It only helps if the value is stable across your retries, so it has to come from something you own — an order id, a job id — never a fresh UUID per call.
30
+
31
+ - **`SaleDetail.srcStatus` / `PrepaymentDetail.srcStatus`** (and the exported `SrcStatus` type) — where the document stands with SRC: `accepted`, `rejected`, `pending`, or `needs_decision`. This is what closes the loop after a `pending` 502: read the document back and check this field rather than resending.
32
+
33
+ `pending` and `rejected` are genuinely different outcomes — the first means VCR still owns the retry and you must not resend, the second means SRC refused the payload and resending it unchanged gets the same answer.
34
+
35
+ ## [0.16.0] — 2026-07-10
36
+
37
+ ### Added
38
+
39
+ - **`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.
40
+
41
+ ```ts
42
+ await vcr.registerSale({
43
+ cashier: { id: 1 },
44
+ items: [{ offer: { id: 5 }, department: { id: 1 }, quantity: "1", price: "4000", unit: "pc" }],
45
+ amount: { cash: "4000" },
46
+ comment: "Stripe pi_3Qc...",
47
+ });
48
+ ```
49
+
50
+ - **`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.
51
+
5
52
  ## [0.15.0] — 2026-07-09
6
53
 
7
54
  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`).
package/README.md CHANGED
@@ -28,6 +28,7 @@ Official TypeScript / JavaScript SDK for the [VCR.AM](https://vcr.am) Virtual Ca
28
28
  - [Error handling](#error-handling)
29
29
  - [Cancellation and timeouts](#cancellation-and-timeouts)
30
30
  - [Idempotency and retries](#idempotency-and-retries)
31
+ - [When the tax service is unreachable](#when-the-tax-service-is-unreachable)
31
32
  - [Browser usage](#browser-usage)
32
33
  - [Development](#development)
33
34
  - [Versioning](#versioning)
@@ -130,6 +131,8 @@ const refund = await vcr.registerSaleRefund({
130
131
  - `amount` — explicit AMD per tender (`{ cash?, nonCash?, prepayment?, compensation? }`), as in the quick-start.
131
132
  - `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
 
134
+ **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`.
135
+
133
136
  **eMark codes** (marked goods, Govt Decision 1976-N) go on each sale item as `emarks: string[]`; the same codes are echoed on refund items.
134
137
 
135
138
  **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).
@@ -276,7 +279,67 @@ The whole request flow — connection, body read, schema parse — is bounded by
276
279
 
277
280
  ## Idempotency and retries
278
281
 
279
- **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`).
282
+ **The SDK does not retry.** This is intentional: a blind retry of `registerSale` can double-fiscalize a receipt, and a duplicate fiscal receipt is a real tax document — it cannot be deleted, only refunded.
283
+
284
+ To retry a document-creating call safely, pass `idempotencyKey`:
285
+
286
+ ```typescript
287
+ await vcr.registerSale(sale, { idempotencyKey: `order-${order.id}` });
288
+ ```
289
+
290
+ The key makes the retry a replay: the original response comes back verbatim and nothing new is created. This covers the case that bites hardest — a 502 from an unreachable tax service, where the sale **was** saved on our side and a naive retry would register a second one.
291
+
292
+ The SDK deliberately does not generate the key for you. It only helps if the value stays **stable across your retries**, so it has to come from something you own — an order id, a job id — not a fresh UUID per call.
293
+
294
+ Rules:
295
+
296
+ - Same key, same body -> the original response, with an `Idempotent-Replay: true` header.
297
+ - Same key, different body -> `422`. Use one key per distinct operation.
298
+ - Same key while the first call is still running -> `409`. Retry shortly, with the same key.
299
+ - Keys are scoped per register and per endpoint, and are retained for 24 hours.
300
+
301
+ Reads (`whoami`, `getSale`, `getPrepayment`, `listPrepayments`, `listCashiers`, `listOffers`, `getOffer`, `listDepartments`, `searchClassifier`, `getExchangeRate`) are always safe to repeat and need no key.
302
+
303
+ ## When the tax service is unreachable
304
+
305
+ A `502` does **not** always mean nothing happened. When SRC was merely unreachable, VCR still saved the document and queued it for automatic resubmission — the error then carries a `pending` handle, and resending would fiscalize a second receipt.
306
+
307
+ ```typescript
308
+ import { VCRApiError } from "@blob-solutions/vcr-am-sdk";
309
+
310
+ try {
311
+ await vcr.registerSale(sale, { idempotencyKey: `order-${order.id}` });
312
+ } catch (error) {
313
+ if (error instanceof VCRApiError && error.body.pending !== undefined) {
314
+ const { type, id } = error.body.pending;
315
+ // Nothing was lost. Record the id and check back later; do not resend.
316
+ await queue.push({ type, id });
317
+ return;
318
+ }
319
+ throw error;
320
+ }
321
+ ```
322
+
323
+ `pending` absent on an error means nothing was created, and the call can be repeated normally.
324
+
325
+ To find out how a queued document ended up, read it back and check `srcStatus`:
326
+
327
+ ```typescript
328
+ const sale = await vcr.getSale(id);
329
+
330
+ switch (sale.srcStatus) {
331
+ case "accepted":
332
+ return markFiscalized(sale.receipt);
333
+ case "pending":
334
+ return checkAgainLater(); // VCR is still retrying; do not resend
335
+ case "rejected":
336
+ return escalate("SRC refused the document — the payload has to change");
337
+ case "needs_decision":
338
+ return escalate("automatic retries gave up after 24h");
339
+ }
340
+ ```
341
+
342
+ Most queued documents clear within minutes. `pending` is the state that most looks like failure and most must not be treated as one — resending is the one action that turns a recoverable outage into a duplicate tax document.
280
343
 
281
344
  ## Browser usage
282
345
 
package/lib/index.cjs CHANGED
@@ -102,7 +102,18 @@ var apiErrorBodySchema = zod.z.object({
102
102
  // Server-generated correlation ID present on unexpected 5xx responses.
103
103
  // Kept lenient (plain string, not `.uuid()`) so a malformed value can never
104
104
  // make the error envelope fail to parse and mask the real API error.
105
- requestId: zod.z.string().optional()
105
+ requestId: zod.z.string().optional(),
106
+ // Present on a 502 when the document was persisted and queued for automatic
107
+ // resubmission to SRC. Its presence means the request was NOT lost.
108
+ //
109
+ // `type` is deliberately a plain string rather than an enum: a server that
110
+ // adds a new pending resource type must not make the whole error envelope
111
+ // fail to parse in an older SDK, which would mask the real API error.
112
+ pending: zod.z.object({
113
+ type: zod.z.string(),
114
+ id: zod.z.number(),
115
+ statusUrl: zod.z.string()
116
+ }).optional()
106
117
  });
107
118
  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");
108
119
  var detailLanguageSchema = zod.z.enum([...AVAILABLE_LANGUAGES, "multi"]);
@@ -266,10 +277,13 @@ var saleRefundPickSchema = zod.z.object({
266
277
  receipt: receiptPickSchema.nullable(),
267
278
  items: zod.z.array(zod.z.object({ quantity: zod.z.number() }))
268
279
  });
280
+ var srcStatusSchema = zod.z.enum(["accepted", "rejected", "pending", "needs_decision"]);
269
281
  var saleDetailResponseSchema = zod.z.object({
270
282
  id: zod.z.number().int().nonnegative(),
271
283
  createdAt: isoDateTimeSchema,
284
+ srcStatus: srcStatusSchema,
272
285
  buyerTin: zod.z.string().nullable(),
286
+ comment: zod.z.string().nullable(),
273
287
  cashAmount: zod.z.number(),
274
288
  nonCashAmount: zod.z.number(),
275
289
  prepaymentAmount: zod.z.number(),
@@ -288,6 +302,7 @@ var prepaymentStateSchema = zod.z.enum(["open", "consumed", "refunded"]);
288
302
  var prepaymentDetailResponseSchema = zod.z.object({
289
303
  id: zod.z.number().int().nonnegative(),
290
304
  createdAt: isoDateTimeSchema,
305
+ srcStatus: srcStatusSchema,
291
306
  buyerTin: zod.z.string().nullable(),
292
307
  cashAmount: zod.z.number(),
293
308
  nonCashAmount: zod.z.number(),
@@ -336,6 +351,9 @@ async function requestJson(schema, init) {
336
351
  "x-api-key": apiKey,
337
352
  accept: "application/json"
338
353
  };
354
+ if (init.idempotencyKey !== void 0) {
355
+ headers["idempotency-key"] = init.idempotencyKey;
356
+ }
339
357
  const requestInit = { method, headers };
340
358
  if (body !== void 0) {
341
359
  headers["content-type"] = "application/json";
@@ -679,6 +697,7 @@ exports.registerPrepaymentResponseSchema = registerPrepaymentResponseSchema;
679
697
  exports.registerSaleRefundResponseSchema = registerSaleRefundResponseSchema;
680
698
  exports.registerSaleResponseSchema = registerSaleResponseSchema;
681
699
  exports.saleDetailResponseSchema = saleDetailResponseSchema;
700
+ exports.srcStatusSchema = srcStatusSchema;
682
701
  exports.unitsKeys = unitsKeys;
683
702
  exports.whoamiResponseSchema = whoamiResponseSchema;
684
703
  //# sourceMappingURL=index.cjs.map
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// ─── 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 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"]}
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\n/**\n * A document VCR persisted and queued for automatic resubmission to SRC.\n *\n * Present on a 502 when SRC was merely unreachable. It means the request was\n * NOT lost: VCR owns the work and a background sweep usually completes it\n * within minutes. Poll `statusUrl` to find out; do NOT resend the request,\n * which would produce a second fiscal receipt.\n */\nexport type PendingResource = {\n /** Which collection `id` belongs to, e.g. `\"sale\"` or `\"prepayment\"`. */\n type: string;\n id: number;\n /** Path to poll for the outcome, e.g. `/api/v1/sales/5122`. */\n statusUrl: 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 * Set when the request was persisted despite the error. Its absence on an\n * error means nothing was created.\n */\n pending?: PendingResource;\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 // Present on a 502 when the document was persisted and queued for automatic\n // resubmission to SRC. Its presence means the request was NOT lost.\n //\n // `type` is deliberately a plain string rather than an enum: a server that\n // adds a new pending resource type must not make the whole error envelope\n // fail to parse in an older SDK, which would mask the real API error.\n pending: z\n .object({\n type: z.string(),\n id: z.number(),\n statusUrl: z.string(),\n })\n .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\n/**\n * Where a document stands with the tax authority, derived from its submission\n * log. This is the field to poll after a 502 that carried a `pending` handle.\n *\n * - `accepted` — SRC registered it. Terminal and final; a fiscal receipt exists.\n * - `rejected` — SRC refused the document itself. Terminal: resending the same\n * payload gets the same refusal, so something has to change.\n * - `pending` — no answer from SRC yet. VCR owns the retry; do NOT resend.\n * - `needs_decision` — the automatic retry window (24h) closed without an\n * answer. Still not resendable blind — check the document before acting.\n *\n * A plain enum rather than a boolean because \"not accepted\" spans three very\n * different situations, and the one that matters most (`pending`) is the one\n * that looks like failure but must not be treated as one.\n */\nexport const srcStatusSchema = z.enum([\"accepted\", \"rejected\", \"pending\", \"needs_decision\"]);\n\nexport const saleDetailResponseSchema = z.object({\n id: z.number().int().nonnegative(),\n createdAt: isoDateTimeSchema,\n srcStatus: srcStatusSchema,\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 srcStatus: srcStatusSchema,\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 SrcStatus = z.infer<typeof srcStatusSchema>;\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 * Opt-in replay protection for the document-creating endpoints\n * (`registerSale`, `registerSaleRefund`, `registerPrepayment`,\n * `registerPrepaymentRefund`). Retrying a request that carries the same key\n * returns the original response instead of registering a second document.\n *\n * Strongly recommended. Without it, retrying after a 502 produces a\n * duplicate fiscal receipt, which can only be undone by issuing a refund.\n *\n * The SDK deliberately does not generate this for you: the value must stay\n * **stable across your retries**, so it has to come from something you own —\n * typically your order id (`order-4821`) — not from a fresh UUID per call.\n */\n idempotencyKey?: string;\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 if (init.idempotencyKey !== undefined) {\n headers[\"idempotency-key\"] = init.idempotencyKey;\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
@@ -4,6 +4,20 @@ type RequestOptions = {
4
4
  signal?: AbortSignal;
5
5
  /** Override per-request timeout in ms. `null` disables the timeout. */
6
6
  timeoutMs?: number | null;
7
+ /**
8
+ * Opt-in replay protection for the document-creating endpoints
9
+ * (`registerSale`, `registerSaleRefund`, `registerPrepayment`,
10
+ * `registerPrepaymentRefund`). Retrying a request that carries the same key
11
+ * returns the original response instead of registering a second document.
12
+ *
13
+ * Strongly recommended. Without it, retrying after a 502 produces a
14
+ * duplicate fiscal receipt, which can only be undone by issuing a refund.
15
+ *
16
+ * The SDK deliberately does not generate this for you: the value must stay
17
+ * **stable across your retries**, so it has to come from something you own —
18
+ * typically your order id (`order-4821`) — not from a fresh UUID per call.
19
+ */
20
+ idempotencyKey?: string;
7
21
  };
8
22
 
9
23
  declare const registerSaleResponseSchema: z.ZodObject<{
@@ -191,10 +205,38 @@ declare const offerListResponseSchema: z.ZodArray<z.ZodObject<{
191
205
  archivedAt: z.ZodNullable<z.ZodString>;
192
206
  createdAt: z.ZodString;
193
207
  }, z.core.$strip>>;
208
+ /**
209
+ * Where a document stands with the tax authority, derived from its submission
210
+ * log. This is the field to poll after a 502 that carried a `pending` handle.
211
+ *
212
+ * - `accepted` — SRC registered it. Terminal and final; a fiscal receipt exists.
213
+ * - `rejected` — SRC refused the document itself. Terminal: resending the same
214
+ * payload gets the same refusal, so something has to change.
215
+ * - `pending` — no answer from SRC yet. VCR owns the retry; do NOT resend.
216
+ * - `needs_decision` — the automatic retry window (24h) closed without an
217
+ * answer. Still not resendable blind — check the document before acting.
218
+ *
219
+ * A plain enum rather than a boolean because "not accepted" spans three very
220
+ * different situations, and the one that matters most (`pending`) is the one
221
+ * that looks like failure but must not be treated as one.
222
+ */
223
+ declare const srcStatusSchema: z.ZodEnum<{
224
+ pending: "pending";
225
+ accepted: "accepted";
226
+ rejected: "rejected";
227
+ needs_decision: "needs_decision";
228
+ }>;
194
229
  declare const saleDetailResponseSchema: z.ZodObject<{
195
230
  id: z.ZodNumber;
196
231
  createdAt: z.ZodString;
232
+ srcStatus: z.ZodEnum<{
233
+ pending: "pending";
234
+ accepted: "accepted";
235
+ rejected: "rejected";
236
+ needs_decision: "needs_decision";
237
+ }>;
197
238
  buyerTin: z.ZodNullable<z.ZodString>;
239
+ comment: z.ZodNullable<z.ZodString>;
198
240
  cashAmount: z.ZodNumber;
199
241
  nonCashAmount: z.ZodNumber;
200
242
  prepaymentAmount: z.ZodNumber;
@@ -336,6 +378,12 @@ declare const prepaymentStateSchema: z.ZodEnum<{
336
378
  declare const prepaymentDetailResponseSchema: z.ZodObject<{
337
379
  id: z.ZodNumber;
338
380
  createdAt: z.ZodString;
381
+ srcStatus: z.ZodEnum<{
382
+ pending: "pending";
383
+ accepted: "accepted";
384
+ rejected: "rejected";
385
+ needs_decision: "needs_decision";
386
+ }>;
339
387
  buyerTin: z.ZodNullable<z.ZodString>;
340
388
  cashAmount: z.ZodNumber;
341
389
  nonCashAmount: z.ZodNumber;
@@ -436,6 +484,7 @@ type CashierListItem = z.infer<typeof cashierListItemSchema>;
436
484
  type ClassifierSearchItem = z.infer<typeof classifierSearchItemSchema>;
437
485
  type Whoami = z.infer<typeof whoamiResponseSchema>;
438
486
  type OfferListItem = z.infer<typeof offerListItemSchema>;
487
+ type SrcStatus = z.infer<typeof srcStatusSchema>;
439
488
  type SaleDetail = z.infer<typeof saleDetailResponseSchema>;
440
489
  type PrepaymentDetail = z.infer<typeof prepaymentDetailResponseSchema>;
441
490
  type PrepaymentListItem = z.infer<typeof prepaymentListItemSchema>;
@@ -633,6 +682,13 @@ type RegisterSaleInput = {
633
682
  cashier: CashierId;
634
683
  items: SaleItem[];
635
684
  buyer: Buyer;
685
+ /**
686
+ * Optional merchant-internal note, e.g. an external payment reference. Max
687
+ * 500 characters; control characters are stripped and surrounding whitespace
688
+ * trimmed server-side. It is purely internal: never printed on the buyer's
689
+ * receipt and never sent to the tax authority (SRC).
690
+ */
691
+ comment?: string;
636
692
  } & SalePayment;
637
693
  /** @deprecated Use {@link RegisterSaleInput} instead. Will be removed in 1.0. */
638
694
  type SaleData = RegisterSaleInput;
@@ -857,6 +913,21 @@ type ApiErrorIssue = {
857
913
  message: string;
858
914
  code: string;
859
915
  };
916
+ /**
917
+ * A document VCR persisted and queued for automatic resubmission to SRC.
918
+ *
919
+ * Present on a 502 when SRC was merely unreachable. It means the request was
920
+ * NOT lost: VCR owns the work and a background sweep usually completes it
921
+ * within minutes. Poll `statusUrl` to find out; do NOT resend the request,
922
+ * which would produce a second fiscal receipt.
923
+ */
924
+ type PendingResource = {
925
+ /** Which collection `id` belongs to, e.g. `"sale"` or `"prepayment"`. */
926
+ type: string;
927
+ id: number;
928
+ /** Path to poll for the outcome, e.g. `/api/v1/sales/5122`. */
929
+ statusUrl: string;
930
+ };
860
931
  type ApiErrorBody = {
861
932
  error: string;
862
933
  issues?: Array<ApiErrorIssue>;
@@ -866,6 +937,11 @@ type ApiErrorBody = {
866
937
  * and Sentry event can be located.
867
938
  */
868
939
  requestId?: string;
940
+ /**
941
+ * Set when the request was persisted despite the error. Its absence on an
942
+ * error means nothing was created.
943
+ */
944
+ pending?: PendingResource;
869
945
  };
870
946
  /**
871
947
  * Base class for every error thrown by the SDK.
@@ -912,4 +988,4 @@ declare class VCRNetworkError extends VCRError {
912
988
  });
913
989
  }
914
990
 
915
- 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 };
991
+ 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 PendingResource, 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, type SrcStatus, 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, srcStatusSchema, unitsKeys, whoamiResponseSchema };