@blob-solutions/vcr-am-sdk 0.18.0 → 0.20.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,48 @@
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
+ ## [Unreleased]
6
+
7
+ ## [0.20.0] — 2026-11-04
8
+
9
+ Lets a sale name the prepayment it spends, and returns what is left of a used one. Also the first published release of the 0.19.0 changes below: that version was never tagged, so it did not reach npm.
10
+
11
+ ### Added
12
+
13
+ - **`prepaymentId`** on `registerSale`. Names the prepayment `amount.prepayment` is spent from, so offsetting one order cannot use up another order's prepayment. A prepayment that cannot cover the amount refuses the sale with a `400` and nothing saved.
14
+ - **`returnRemainder`** on `registerPrepaymentRefund`. Returns all that sales left of a partly used prepayment, split the way it was paid. Without it such a refund is still refused with a `409`; if sales used everything the answer is a `400`.
15
+
16
+ ### Security
17
+
18
+ - **`zod` floor raised to 4.6.7**, past [GHSA-mrhx-c7xc-m3w5](https://github.com/advisories/GHSA-mrhx-c7xc-m3w5): oversized constrained collections could exhaust memory during validation.
19
+
20
+ ## [0.19.0] — 2026-09-24
21
+
22
+ Tells you whether to send a failed request again.
23
+
24
+ ### Added
25
+
26
+ - **`pending.mayResubmit`** on the error handle. VCR's own retry of a document the tax authority never received is now opt-in and off by default, so a `502` no longer implies "we will finish this for you" — and if you assume it does, the sale is never fiscalized.
27
+
28
+ `true` means SRC registered nothing and nothing will send it from VCR's side: resubmitting is how the document gets fiscalized. `false` means the document is still VCR's to settle — SRC may hold it already, or VCR will send it again — and a second POST risks a duplicate fiscal receipt, so poll `statusUrl` instead. Always `false` on a `409`: the same payload earns the same rejection.
29
+
30
+ ```ts
31
+ try {
32
+ await vcr.registerSale(sale);
33
+ } catch (error) {
34
+ if (error instanceof VcrApiException && error.body.pending?.mayResubmit) {
35
+ await retryLater(sale); // SRC has nothing; it is yours to send
36
+ }
37
+ // otherwise poll error.body.pending.statusUrl — do not resend
38
+ }
39
+ ```
40
+
41
+ Optional, because a VCR older than this field does not send it. Absent reads as `false`, which is what those servers did.
42
+
43
+ ### Changed
44
+
45
+ - `srcStatus: "needs_decision"` no longer means only "the 24-hour retry window closed". With late fiscalization off — the default — a document reaches it as soon as an attempt fails, because nothing is coming to resend it.
46
+
5
47
  ## [0.18.0] — 2026-08-28
6
48
 
7
49
  Stops making integrators guess a department id.
package/README.md CHANGED
@@ -299,7 +299,8 @@ Rules:
299
299
  - Same key, same body -> the original response, with an `Idempotent-Replay: true` header.
300
300
  - Same key, different body -> `422`. Use one key per distinct operation.
301
301
  - Same key while the first call is still running -> `409`. Retry shortly, with the same key.
302
- - Keys are scoped per register and per endpoint, and are retained for 24 hours.
302
+ - Same key after the server rejected the body on validation -> the key was never spent. The request did not reach the operation, so fix the field and retry with the same key.
303
+ - Keys are scoped per register and per endpoint, and stay replayable for 30 days.
303
304
 
304
305
  Reads (`whoami`, `getSale`, `getPrepayment`, `listPrepayments`, `listCashiers`, `listOffers`, `getOffer`, `listDepartments`, `searchClassifier`, `getExchangeRate`) are always safe to repeat and need no key.
305
306
 
package/lib/index.cjs CHANGED
@@ -103,16 +103,19 @@ var apiErrorBodySchema = zod.z.object({
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
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.
106
+ // Present on a 502 (SRC unreachable) and on a 409 that reports an SRC
107
+ // business rejection. Either way the document was persisted: its presence
108
+ // means the request was NOT lost. `mayResubmit` says what to do about it.
108
109
  //
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.
110
+ // `type` is deliberately a plain string rather than an enum, and
111
+ // `mayResubmit` optional for the same reason: a server that adds a pending
112
+ // resource type — or one older than the field — must not make the whole
113
+ // error envelope fail to parse, which would mask the real API error.
112
114
  pending: zod.z.object({
113
115
  type: zod.z.string(),
114
116
  id: zod.z.number(),
115
- statusUrl: zod.z.string()
117
+ statusUrl: zod.z.string(),
118
+ mayResubmit: zod.z.boolean().optional()
116
119
  }).optional()
117
120
  });
118
121
  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");
@@ -132,28 +135,35 @@ var registerSaleResponseSchema = zod.z.object({
132
135
  saleId: zod.z.number().int().nonnegative(),
133
136
  crn: zod.z.string(),
134
137
  srcReceiptId: zod.z.number().int().nonnegative(),
135
- fiscal: zod.z.string()
138
+ fiscal: zod.z.string(),
139
+ receiptUrl: zod.z.string().optional()
136
140
  });
137
141
  var registerSaleRefundResponseSchema = zod.z.object({
138
142
  urlId: zod.z.string(),
139
143
  saleRefundId: zod.z.number().int().nonnegative(),
140
144
  crn: zod.z.string().nullable(),
141
145
  receiptId: zod.z.number().int().nonnegative(),
142
- fiscal: zod.z.string().nullable()
146
+ fiscal: zod.z.string().nullable(),
147
+ /** Null under the same condition that leaves `crn` null. */
148
+ receiptUrl: zod.z.string().nullish()
143
149
  });
144
150
  var registerPrepaymentResponseSchema = zod.z.object({
145
151
  urlId: zod.z.string(),
146
152
  prepaymentId: zod.z.number().int().nonnegative(),
147
153
  crn: zod.z.string().nullable(),
148
154
  receiptId: zod.z.number().int().nonnegative(),
149
- fiscal: zod.z.string().nullable()
155
+ fiscal: zod.z.string().nullable(),
156
+ /** Null under the same condition that leaves `crn` null. */
157
+ receiptUrl: zod.z.string().nullish()
150
158
  });
151
159
  var registerPrepaymentRefundResponseSchema = zod.z.object({
152
160
  urlId: zod.z.string(),
153
161
  prepaymentRefundId: zod.z.number().int().nonnegative(),
154
162
  crn: zod.z.string().nullable(),
155
163
  receiptId: zod.z.number().int().nonnegative(),
156
- fiscal: zod.z.string().nullable()
164
+ fiscal: zod.z.string().nullable(),
165
+ /** Null under the same condition that leaves `crn` null. */
166
+ receiptUrl: zod.z.string().nullish()
157
167
  });
158
168
  var createOfferResponseSchema = zod.z.object({
159
169
  offerId: zod.z.number().int().nonnegative()
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\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"]}
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 despite the error. Its presence means the request\n * was NOT lost, so never resend blindly — read `mayResubmit` first.\n *\n * Present on two statuses:\n *\n * - **502** — SRC was unreachable. What to do next is `mayResubmit`.\n * - **409** — SRC answered and refused the document on business grounds (for\n * example 196, the cash register is not activated at SRC). `mayResubmit` is\n * always false here: the same payload earns the same refusal. Read the SRC\n * code in `error`, fix the cause, then send the corrected document.\n */\nexport type PendingResource = {\n /**\n * Which collection `id` belongs to: `\"sale\"`, `\"prepayment\"`, or\n * `\"sale_refund\"`. Deliberately a plain string — a server that adds a type\n * must not break parsing in an older SDK.\n */\n type: string;\n id: number;\n /**\n * Path to poll for the outcome, e.g. `/api/v1/sales/5122`. For\n * `\"sale_refund\"` this is the PARENT SALE: find your refund by `id` in the\n * response's `refunds` array.\n */\n statusUrl: string;\n /**\n * Whether sending this exact request again is safe.\n *\n * `false` — the document is still VCR's to settle: SRC may have registered\n * it already, or VCR will submit it again for you. Resending risks a second\n * fiscal receipt for one sale. Poll `statusUrl` instead.\n *\n * `true` — SRC registered nothing and VCR will not send it again (the\n * merchant has late fiscalization off, which is the default). Nothing\n * further happens server-side; resubmitting is how the document gets\n * fiscalized.\n *\n * Absent when the server predates the field. Treat that as `false` — the\n * conservative reading, and what those servers did.\n */\n mayResubmit?: boolean;\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 (SRC unreachable) and on a 409 that reports an SRC\n // business rejection. Either way the document was persisted: its presence\n // means the request was NOT lost. `mayResubmit` says what to do about it.\n //\n // `type` is deliberately a plain string rather than an enum, and\n // `mayResubmit` optional for the same reason: a server that adds a pending\n // resource type — or one older than the field — must not make the whole\n // error envelope fail to parse, 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 mayResubmit: z.boolean().optional(),\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\n/**\n * Public receipt page for the buyer — safe to email, print as a QR, or put on\n * an order-confirmation page: it carries no account access. The page picks the\n * reader's own language.\n *\n * Optional, and deliberately so: the field was added to the API after this\n * schema shipped, and a client that required it would fail to parse a\n * perfectly good receipt from a server that predates it. A convenience field\n * must never be the reason a fiscal call errors. It is always present from\n * vcr.am today; build it yourself from `crn` and `urlId` if you need a\n * fallback.\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 receiptUrl: z.string().optional(),\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 /** Null under the same condition that leaves `crn` null. */\n receiptUrl: z.string().nullish(),\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 /** Null under the same condition that leaves `crn` null. */\n receiptUrl: z.string().nullish(),\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 /** Null under the same condition that leaves `crn` null. */\n receiptUrl: z.string().nullish(),\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 any response that carried a `pending`\n * handle (502 or 409).\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, and VCR still owns the document: it\n * may already be registered there, or VCR is going to send it again. Do NOT\n * resend.\n * - `needs_decision` — nothing is going to submit this document on its own.\n * Either the merchant has late fiscalization off (the default), in which\n * case SRC registered nothing and it is yours to send again, or the 24h\n * automatic window closed. The `502` that created it told you which via\n * `pending.mayResubmit`; if you no longer have that response, check the\n * document before acting rather than resending blind.\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 or a 409 that\n * carried a `pending` handle produces a duplicate fiscal receipt, which can\n * 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
@@ -10,8 +10,9 @@ type RequestOptions = {
10
10
  * `registerPrepaymentRefund`). Retrying a request that carries the same key
11
11
  * returns the original response instead of registering a second document.
12
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.
13
+ * Strongly recommended. Without it, retrying after a 502 or a 409 that
14
+ * carried a `pending` handle produces a duplicate fiscal receipt, which can
15
+ * only be undone by issuing a refund.
15
16
  *
16
17
  * The SDK deliberately does not generate this for you: the value must stay
17
18
  * **stable across your retries**, so it has to come from something you own —
@@ -20,12 +21,25 @@ type RequestOptions = {
20
21
  idempotencyKey?: string;
21
22
  };
22
23
 
24
+ /**
25
+ * Public receipt page for the buyer — safe to email, print as a QR, or put on
26
+ * an order-confirmation page: it carries no account access. The page picks the
27
+ * reader's own language.
28
+ *
29
+ * Optional, and deliberately so: the field was added to the API after this
30
+ * schema shipped, and a client that required it would fail to parse a
31
+ * perfectly good receipt from a server that predates it. A convenience field
32
+ * must never be the reason a fiscal call errors. It is always present from
33
+ * vcr.am today; build it yourself from `crn` and `urlId` if you need a
34
+ * fallback.
35
+ */
23
36
  declare const registerSaleResponseSchema: z.ZodObject<{
24
37
  urlId: z.ZodString;
25
38
  saleId: z.ZodNumber;
26
39
  crn: z.ZodString;
27
40
  srcReceiptId: z.ZodNumber;
28
41
  fiscal: z.ZodString;
42
+ receiptUrl: z.ZodOptional<z.ZodString>;
29
43
  }, z.core.$strip>;
30
44
  declare const registerSaleRefundResponseSchema: z.ZodObject<{
31
45
  urlId: z.ZodString;
@@ -33,6 +47,7 @@ declare const registerSaleRefundResponseSchema: z.ZodObject<{
33
47
  crn: z.ZodNullable<z.ZodString>;
34
48
  receiptId: z.ZodNumber;
35
49
  fiscal: z.ZodNullable<z.ZodString>;
50
+ receiptUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
36
51
  }, z.core.$strip>;
37
52
  declare const registerPrepaymentResponseSchema: z.ZodObject<{
38
53
  urlId: z.ZodString;
@@ -40,6 +55,7 @@ declare const registerPrepaymentResponseSchema: z.ZodObject<{
40
55
  crn: z.ZodNullable<z.ZodString>;
41
56
  receiptId: z.ZodNumber;
42
57
  fiscal: z.ZodNullable<z.ZodString>;
58
+ receiptUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
43
59
  }, z.core.$strip>;
44
60
  declare const registerPrepaymentRefundResponseSchema: z.ZodObject<{
45
61
  urlId: z.ZodString;
@@ -47,6 +63,7 @@ declare const registerPrepaymentRefundResponseSchema: z.ZodObject<{
47
63
  crn: z.ZodNullable<z.ZodString>;
48
64
  receiptId: z.ZodNumber;
49
65
  fiscal: z.ZodNullable<z.ZodString>;
66
+ receiptUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
50
67
  }, z.core.$strip>;
51
68
  declare const createOfferResponseSchema: z.ZodObject<{
52
69
  offerId: z.ZodNumber;
@@ -207,14 +224,21 @@ declare const offerListResponseSchema: z.ZodArray<z.ZodObject<{
207
224
  }, z.core.$strip>>;
208
225
  /**
209
226
  * 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.
227
+ * log. This is the field to poll after any response that carried a `pending`
228
+ * handle (502 or 409).
211
229
  *
212
230
  * - `accepted` — SRC registered it. Terminal and final; a fiscal receipt exists.
213
231
  * - `rejected` — SRC refused the document itself. Terminal: resending the same
214
232
  * 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.
233
+ * - `pending` — no answer from SRC yet, and VCR still owns the document: it
234
+ * may already be registered there, or VCR is going to send it again. Do NOT
235
+ * resend.
236
+ * - `needs_decision` — nothing is going to submit this document on its own.
237
+ * Either the merchant has late fiscalization off (the default), in which
238
+ * case SRC registered nothing and it is yours to send again, or the 24h
239
+ * automatic window closed. The `502` that created it told you which via
240
+ * `pending.mayResubmit`; if you no longer have that response, check the
241
+ * document before acting rather than resending blind.
218
242
  *
219
243
  * A plain enum rather than a boolean because "not accepted" spans three very
220
244
  * different situations, and the one that matters most (`pending`) is the one
@@ -683,11 +707,19 @@ type AutoSettle = {
683
707
  type PayByAmount = {
684
708
  amount: SaleAmount;
685
709
  autoSettle?: never;
710
+ /**
711
+ * The prepayment `amount.prepayment` is spent from. Without it the sale
712
+ * consumes the oldest open prepayments, which for a buyer with no TIN means
713
+ * anyone's. A prepayment that cannot cover the amount refuses the sale with
714
+ * a `400` and nothing saved.
715
+ */
716
+ prepaymentId?: number;
686
717
  };
687
718
  /** VCR derives the AMD total onto one tender. Mutually exclusive with `amount`. */
688
719
  type PayByAutoSettle = {
689
720
  autoSettle: AutoSettle;
690
721
  amount?: never;
722
+ prepaymentId?: never;
691
723
  };
692
724
  /**
693
725
  * A sale settles EITHER by explicit `amount` OR by `autoSettle` — exactly one,
@@ -745,6 +777,11 @@ type RegisterPrepaymentInput = {
745
777
  type RegisterPrepaymentRefundInput = {
746
778
  cashier: CashierId;
747
779
  prepaymentId: number;
780
+ /**
781
+ * Return all that sales left of the prepayment. Without it, a prepayment a
782
+ * sale has used is refused. There is no amount: the rest cannot stay behind.
783
+ */
784
+ returnRemainder?: true;
748
785
  receipt?: SendReceiptToBuyer;
749
786
  reason?: RefundReason;
750
787
  reasonNote?: string;
@@ -931,19 +968,47 @@ type ApiErrorIssue = {
931
968
  code: string;
932
969
  };
933
970
  /**
934
- * A document VCR persisted and queued for automatic resubmission to SRC.
971
+ * A document VCR persisted despite the error. Its presence means the request
972
+ * was NOT lost, so never resend blindly — read `mayResubmit` first.
935
973
  *
936
- * Present on a 502 when SRC was merely unreachable. It means the request was
937
- * NOT lost: VCR owns the work and a background sweep usually completes it
938
- * within minutes. Poll `statusUrl` to find out; do NOT resend the request,
939
- * which would produce a second fiscal receipt.
974
+ * Present on two statuses:
975
+ *
976
+ * - **502** — SRC was unreachable. What to do next is `mayResubmit`.
977
+ * - **409** — SRC answered and refused the document on business grounds (for
978
+ * example 196, the cash register is not activated at SRC). `mayResubmit` is
979
+ * always false here: the same payload earns the same refusal. Read the SRC
980
+ * code in `error`, fix the cause, then send the corrected document.
940
981
  */
941
982
  type PendingResource = {
942
- /** Which collection `id` belongs to, e.g. `"sale"` or `"prepayment"`. */
983
+ /**
984
+ * Which collection `id` belongs to: `"sale"`, `"prepayment"`, or
985
+ * `"sale_refund"`. Deliberately a plain string — a server that adds a type
986
+ * must not break parsing in an older SDK.
987
+ */
943
988
  type: string;
944
989
  id: number;
945
- /** Path to poll for the outcome, e.g. `/api/v1/sales/5122`. */
990
+ /**
991
+ * Path to poll for the outcome, e.g. `/api/v1/sales/5122`. For
992
+ * `"sale_refund"` this is the PARENT SALE: find your refund by `id` in the
993
+ * response's `refunds` array.
994
+ */
946
995
  statusUrl: string;
996
+ /**
997
+ * Whether sending this exact request again is safe.
998
+ *
999
+ * `false` — the document is still VCR's to settle: SRC may have registered
1000
+ * it already, or VCR will submit it again for you. Resending risks a second
1001
+ * fiscal receipt for one sale. Poll `statusUrl` instead.
1002
+ *
1003
+ * `true` — SRC registered nothing and VCR will not send it again (the
1004
+ * merchant has late fiscalization off, which is the default). Nothing
1005
+ * further happens server-side; resubmitting is how the document gets
1006
+ * fiscalized.
1007
+ *
1008
+ * Absent when the server predates the field. Treat that as `false` — the
1009
+ * conservative reading, and what those servers did.
1010
+ */
1011
+ mayResubmit?: boolean;
947
1012
  };
948
1013
  type ApiErrorBody = {
949
1014
  error: string;